Compare commits
23 Commits
0.27.13
...
docusaurus
Author | SHA1 | Date | |
---|---|---|---|
![]() |
711e8b968b | ||
![]() |
3c10cf81ee | ||
![]() |
e28bc93a0c | ||
![]() |
6d53f61608 | ||
![]() |
d154237847 | ||
![]() |
6e2d02852c | ||
![]() |
bdcf3c69c9 | ||
![]() |
37fcefb0e8 | ||
![]() |
21e231ef48 | ||
![]() |
708d7f03b4 | ||
![]() |
d9cf993f1c | ||
![]() |
f2d4dace06 | ||
![]() |
9dc53f6cd2 | ||
![]() |
7ce0874617 | ||
![]() |
fc5eb10822 | ||
![]() |
db9f5c6013 | ||
![]() |
fff2249a7c | ||
![]() |
f48a88fc72 | ||
![]() |
29f2e9f19a | ||
![]() |
d2c755c3dd | ||
![]() |
40a4ee5114 | ||
![]() |
bb8c5cd54a | ||
![]() |
2cef3465e8 |
10
.github/workflows/docs.yml
vendored
@@ -27,12 +27,16 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
cache: npm
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
apt-get update && apt-get install -y rsync nodejs npm doxygen
|
||||
npm install -g moxygen
|
||||
|
||||
- name: Build docs
|
||||
- name: Build doxygen docs
|
||||
run: |
|
||||
qmk --verbose generate-docs
|
||||
|
||||
@@ -42,5 +46,5 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
BASE_BRANCH: master
|
||||
BRANCH: gh-pages
|
||||
FOLDER: .build/docs
|
||||
FOLDER: .build/docs/build
|
||||
GIT_CONFIG_EMAIL: hello@qmk.fm
|
||||
|
5
.vscode/extensions.json
vendored
@@ -1,10 +1,11 @@
|
||||
// Suggested extensions
|
||||
{
|
||||
"recommendations": [
|
||||
"EditorConfig.EditorConfig",
|
||||
"editorconfig.editorconfig",
|
||||
"xaver.clang-format",
|
||||
"ms-vscode.cpptools",
|
||||
"bierner.github-markdown-preview",
|
||||
"donjayamanne.git-extension-pack"
|
||||
"donjayamanne.git-extension-pack",
|
||||
"kevgo.vscode-markdown-ide"
|
||||
]
|
||||
}
|
||||
|
13
Doxyfile
@@ -21,7 +21,7 @@ DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = "QMK Firmware"
|
||||
PROJECT_NUMBER = https://github.com/qmk/qmk_firmware
|
||||
PROJECT_BRIEF = "Keyboard controller firmware for Atmel AVR and ARM USB families"
|
||||
OUTPUT_DIRECTORY = .build/doxygen
|
||||
OUTPUT_DIRECTORY = docs/static
|
||||
ALLOW_UNICODE_NAMES = NO
|
||||
OUTPUT_LANGUAGE = English
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
@@ -183,7 +183,7 @@ IGNORE_PREFIX =
|
||||
# Configuration options related to disabled outputs
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
GENERATE_HTML = NO
|
||||
GENERATE_HTML = YES
|
||||
GENERATE_LATEX = NO
|
||||
GENERATE_RTF = NO
|
||||
GENERATE_MAN = NO
|
||||
@@ -191,11 +191,18 @@ GENERATE_DOCBOOK = NO
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
GENERATE_PERLMOD = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
HTML_OUTPUT = doxygen
|
||||
# HTML_FILE_EXTENSION =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
GENERATE_XML = YES
|
||||
GENERATE_XML = NO
|
||||
XML_OUTPUT = xml
|
||||
XML_PROGRAMLISTING = YES
|
||||
|
||||
|
21
builddefs/docs/.gitignore
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# Dependencies
|
||||
/node_modules
|
||||
|
||||
# Production
|
||||
/build
|
||||
/static/doxygen
|
||||
|
||||
# Generated files
|
||||
.docusaurus
|
||||
.cache-loader
|
||||
|
||||
# Misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
3
builddefs/docs/babel.config.js
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
|
||||
};
|
285
builddefs/docs/docusaurus.config.js
Normal file
@@ -0,0 +1,285 @@
|
||||
// @ts-check
|
||||
// Note: type annotations allow type checking and IDEs autocompletion
|
||||
|
||||
const lightCodeTheme = require("prism-react-renderer/themes/github");
|
||||
const darkCodeTheme = require("prism-react-renderer/themes/dracula");
|
||||
|
||||
/** @type {import('@docusaurus/types').Config} */
|
||||
const config = {
|
||||
title: "QMK Firmware",
|
||||
tagline: "The full documentation of the open-source firmware",
|
||||
favicon: "img/favicon.ico",
|
||||
url: "https://docs.qmk.fm",
|
||||
baseUrl: "/",
|
||||
organizationName: "qmk",
|
||||
projectName: "qmk_firmware",
|
||||
deploymentBranch: "gh-pages",
|
||||
onBrokenLinks: "warn",
|
||||
onBrokenMarkdownLinks: "warn",
|
||||
i18n: {
|
||||
defaultLocale: "en",
|
||||
locales: ["en"], //, 'ja', 'zh-cn'],
|
||||
},
|
||||
themes: [
|
||||
[
|
||||
"classic",
|
||||
{
|
||||
customCss: require.resolve("./src/css/custom.css"),
|
||||
}
|
||||
],
|
||||
[
|
||||
require.resolve("@easyops-cn/docusaurus-search-local"),
|
||||
{
|
||||
indexBlog: false,
|
||||
docsRouteBasePath: '/',
|
||||
searchResultLimits: 12,
|
||||
searchBarShortcut: false,
|
||||
},
|
||||
],
|
||||
],
|
||||
plugins: [
|
||||
[
|
||||
"@docusaurus/plugin-content-docs",
|
||||
{
|
||||
sidebarPath: require.resolve("./sidebars.js"),
|
||||
path: "../../docs",
|
||||
routeBasePath: "/",
|
||||
exclude: [
|
||||
"node_modules",
|
||||
"src",
|
||||
"static",
|
||||
"ja",
|
||||
"zh-cn",
|
||||
"gitbook",
|
||||
// "ChangeLog"
|
||||
],
|
||||
editUrl:
|
||||
"https://github.com/qmk/qmk_firmware/edit/master/docs/",
|
||||
},
|
||||
],
|
||||
[
|
||||
"@docusaurus/plugin-client-redirects",
|
||||
{
|
||||
// fromExtensions: ['md', 'html'],
|
||||
redirects: [
|
||||
// from index.html
|
||||
{
|
||||
from: '/adding_a_keyboard_to_qmk',
|
||||
to: '/hardware_keyboard_guidelines',
|
||||
},
|
||||
{
|
||||
from: '/build_environment_setup',
|
||||
to: '/newbs_getting_started',
|
||||
},
|
||||
{
|
||||
from: '/cli_dev_configuration',
|
||||
to: '/cli_configuration',
|
||||
},
|
||||
{
|
||||
from: '/dynamic_macros',
|
||||
to: '/feature_dynamic_macros',
|
||||
},
|
||||
{
|
||||
from: '/feature_common_shortcuts',
|
||||
to: '/feature_advanced_keycodes',
|
||||
},
|
||||
{
|
||||
from: '/glossary',
|
||||
to: '/reference_glossary',
|
||||
},
|
||||
{
|
||||
from: '/key_lock',
|
||||
to: '/feature_key_lock',
|
||||
},
|
||||
{
|
||||
from: '/make_instructions',
|
||||
to: '/getting_started_make_guide',
|
||||
},
|
||||
{
|
||||
from: ['/space_cadet_shift', '/feature_space_cadet_shift'],
|
||||
to: '/feature_space_cadet',
|
||||
},
|
||||
{
|
||||
from: '/getting_started_getting_help',
|
||||
to: '/support',
|
||||
},
|
||||
{
|
||||
from: '/tap_dance',
|
||||
to: '/feature_tap_dance',
|
||||
},
|
||||
{
|
||||
from: '/unicode',
|
||||
to: '/feature_unicode',
|
||||
},
|
||||
{
|
||||
from: '/python_development',
|
||||
to: '/cli_development',
|
||||
},
|
||||
{
|
||||
from: '/getting_started_build_tools',
|
||||
to: '/newbs_getting_started',
|
||||
},
|
||||
{
|
||||
from: '/tutorial',
|
||||
to: '/newbs',
|
||||
},
|
||||
// from redirects.json
|
||||
// {
|
||||
// from: "/adding_a_keyboard_to_qmk",
|
||||
// to: "/hardware_keyboard_guidelines"
|
||||
// },
|
||||
// {
|
||||
// from: "/build_environment_setup",
|
||||
// to: "/getting_started_build_tools"
|
||||
// },
|
||||
// {
|
||||
// from: "/dynamic_macros",
|
||||
// to: "/feature_dynamic_macros"
|
||||
// },
|
||||
// {
|
||||
// from: "/feature_common_shortcuts",
|
||||
// to: "/feature_advanced_keycodes"
|
||||
// },
|
||||
// {
|
||||
// from: "/glossary",
|
||||
// to: "/reference_glossary"
|
||||
// },
|
||||
// {
|
||||
// from: "/key_lock",
|
||||
// to: "/feature_key_lock"
|
||||
// },
|
||||
// {
|
||||
// from: "/make_instructions",
|
||||
// to: "/getting_started_make_guide"
|
||||
// },
|
||||
// {
|
||||
// from: "/porting_your_keyboard_to_qmk",
|
||||
// to: "/hardware_avr"
|
||||
// },
|
||||
// {
|
||||
// from: "/space_cadet_shift",
|
||||
// to: "/feature_space_cadet_shift"
|
||||
// },
|
||||
// {
|
||||
// from: "/tap_dance",
|
||||
// to: "/feature_tap_dance"
|
||||
// },
|
||||
// {
|
||||
// from: "/unicode",
|
||||
// to: "/feature_unicode"
|
||||
// },
|
||||
// {
|
||||
// from: "/python_development",
|
||||
// to: "/cli_development"
|
||||
// }
|
||||
],
|
||||
},
|
||||
],
|
||||
],
|
||||
|
||||
themeConfig:
|
||||
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
|
||||
({
|
||||
image: "img/qmk-social-card.jpg",
|
||||
navbar: {
|
||||
title: "QMK Firmware Docs",
|
||||
logo: {
|
||||
alt: "QMK Firmware",
|
||||
src: "img/qmk-new-light.svg",
|
||||
srcDark: "img/qmk-new-dark.svg",
|
||||
width: 32,
|
||||
height: 32,
|
||||
},
|
||||
items: [
|
||||
// {
|
||||
// type: 'localeDropdown',
|
||||
// position: 'right',
|
||||
// },
|
||||
{
|
||||
href: "https://github.com/qmk/qmk_firmware",
|
||||
label: "GitHub",
|
||||
position: "right",
|
||||
},
|
||||
],
|
||||
},
|
||||
docs: {
|
||||
sidebar: {
|
||||
autoCollapseCategories: false,
|
||||
},
|
||||
},
|
||||
footer: {
|
||||
style: "dark",
|
||||
links: [
|
||||
{
|
||||
title: "Docs",
|
||||
items: [
|
||||
{
|
||||
label: "Docs",
|
||||
to: "/",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Community",
|
||||
items: [
|
||||
{
|
||||
label: "Discord",
|
||||
href: "https://discord.gg/Uq7gcHh",
|
||||
},
|
||||
{
|
||||
label: "Reddit",
|
||||
href: "https://reddit.com/r/olkb",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "More",
|
||||
items: [
|
||||
{
|
||||
label: "GitHub",
|
||||
href: "https://github.com/qmk/qmk_firmware",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
copyright: `Copyright © ${new Date().getFullYear()} QMK. Built with Docusaurus.`,
|
||||
},
|
||||
prism: {
|
||||
theme: lightCodeTheme,
|
||||
darkTheme: darkCodeTheme,
|
||||
},
|
||||
// applied for - will fill out once we hear back
|
||||
//
|
||||
// algolia: {
|
||||
// // The application ID provided by Algolia
|
||||
// appId: 'YOUR_APP_ID',
|
||||
|
||||
// // Public API key: it is safe to commit it
|
||||
// apiKey: 'YOUR_SEARCH_API_KEY',
|
||||
|
||||
// indexName: 'YOUR_INDEX_NAME',
|
||||
|
||||
// // Optional: see doc section below
|
||||
// contextualSearch: true,
|
||||
|
||||
// // Optional: Specify domains where the navigation should occur through window.location instead on history.push. Useful when our Algolia config crawls multiple documentation sites and we want to navigate with window.location.href to them.
|
||||
// externalUrlRegex: 'external\\.com|domain\\.com',
|
||||
|
||||
// // Optional: Replace parts of the item URLs from Algolia. Useful when using the same search index for multiple deployments using a different baseUrl. You can use regexp or string in the `from` param. For example: localhost:3000 vs myCompany.com/docs
|
||||
// replaceSearchResultPathname: {
|
||||
// from: '/docs/', // or as RegExp: /\/docs\//
|
||||
// to: '/',
|
||||
// },
|
||||
|
||||
// // Optional: Algolia search parameters
|
||||
// searchParameters: {},
|
||||
|
||||
// // Optional: path for search page that enabled by default (`false` to disable it)
|
||||
// searchPagePath: 'search',
|
||||
|
||||
// //... other Algolia params
|
||||
// },
|
||||
}),
|
||||
};
|
||||
|
||||
module.exports = config;
|
12974
builddefs/docs/package-lock.json
generated
Normal file
45
builddefs/docs/package.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"name": "qmk_firmware_docs",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"docusaurus": "docusaurus",
|
||||
"start": "docusaurus start --host 0.0.0.0 --port 8936",
|
||||
"build": "docusaurus build",
|
||||
"swizzle": "docusaurus swizzle",
|
||||
"deploy": "docusaurus deploy",
|
||||
"clear": "docusaurus clear",
|
||||
"serve": "docusaurus serve --host 0.0.0.0 --port 8936",
|
||||
"write-translations": "docusaurus write-translations",
|
||||
"write-heading-ids": "docusaurus write-heading-ids"
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "2.4.0",
|
||||
"@docusaurus/plugin-client-redirects": "^2.4.0",
|
||||
"@docusaurus/preset-classic": "2.4.0",
|
||||
"@easyops-cn/docusaurus-search-local": "^0.35.0",
|
||||
"@mdx-js/react": "^1.6.22",
|
||||
"clsx": "^1.2.1",
|
||||
"prism-react-renderer": "^1.3.5",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/module-type-aliases": "2.4.0"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.5%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.14"
|
||||
}
|
||||
}
|
349
builddefs/docs/sidebars.js
Normal file
@@ -0,0 +1,349 @@
|
||||
/**
|
||||
* Creating a sidebar enables you to:
|
||||
- create an ordered group of docs
|
||||
- render a sidebar for each doc of that group
|
||||
- provide next/previous navigation
|
||||
|
||||
The sidebars can be generated from the filesystem, or explicitly defined here.
|
||||
|
||||
Create as many sidebars as you want.
|
||||
*/
|
||||
|
||||
// @ts-check
|
||||
|
||||
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
|
||||
const sidebars = {
|
||||
// By default, Docusaurus generates a sidebar from the docs folder structure
|
||||
summary: [
|
||||
{
|
||||
type: "doc",
|
||||
id: "README",
|
||||
label: "About QMK",
|
||||
},
|
||||
{
|
||||
type: "category",
|
||||
label: "Tutorial",
|
||||
link: {
|
||||
type: "doc",
|
||||
id: "newbs",
|
||||
},
|
||||
items: [
|
||||
"newbs",
|
||||
"newbs_getting_started",
|
||||
"newbs_building_firmware",
|
||||
"newbs_flashing",
|
||||
"support",
|
||||
"newbs_building_firmware_workflow",
|
||||
"newbs_learn_more_resources",
|
||||
"syllabus",
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "category",
|
||||
label: "FAQs",
|
||||
link: {
|
||||
type: "doc",
|
||||
id: "faq_general",
|
||||
},
|
||||
items: [
|
||||
"faq_general",
|
||||
"faq_build",
|
||||
"faq_misc",
|
||||
"faq_debug",
|
||||
"faq_keymap",
|
||||
"squeezing_avr",
|
||||
"reference_glossary",
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "category",
|
||||
label: "Configurator",
|
||||
link: {
|
||||
type: "doc",
|
||||
id: "newbs_building_firmware_configurator",
|
||||
},
|
||||
items: [
|
||||
"newbs_building_firmware_configurator",
|
||||
"configurator_step_by_step",
|
||||
"configurator_troubleshooting",
|
||||
"configurator_architecture",
|
||||
{
|
||||
type: "category",
|
||||
label: "QMK API",
|
||||
link: {
|
||||
type: "doc",
|
||||
id: "api_overview",
|
||||
},
|
||||
items: [
|
||||
"api_overview",
|
||||
"api_docs",
|
||||
"reference_configurator_support",
|
||||
"configurator_default_keymaps",
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "category",
|
||||
label: "CLI",
|
||||
link: {
|
||||
type: "doc",
|
||||
id: "cli",
|
||||
},
|
||||
items: [
|
||||
"cli",
|
||||
"cli_configuration",
|
||||
"cli_commands",
|
||||
"cli_tab_complete",
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
collapsed: false,
|
||||
label: "Using QMK",
|
||||
items: [
|
||||
{
|
||||
Guides: [
|
||||
"custom_quantum_functions",
|
||||
"driver_installation_zadig",
|
||||
"keymap",
|
||||
{
|
||||
"Development Environments": [
|
||||
"getting_started_docker",
|
||||
"getting_started_vagrant",
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "category",
|
||||
label: "Flashing",
|
||||
link: {
|
||||
type: "doc",
|
||||
id: "flashing",
|
||||
},
|
||||
items: ["flashing", "flashing_bootloadhid"],
|
||||
},
|
||||
{
|
||||
IDEs: ["other_eclipse", "other_vscode"],
|
||||
"Git Best Practices": [
|
||||
"newbs_git_best_practices",
|
||||
"newbs_git_using_your_master_branch",
|
||||
"newbs_git_resolving_merge_conflicts",
|
||||
"newbs_git_resynchronize_a_branch",
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"Simple Keycodes": [
|
||||
"keycodes",
|
||||
"keycodes_basic",
|
||||
"reference_keymap_extras",
|
||||
"feature_advanced_keycodes",
|
||||
"quantum_keycodes",
|
||||
"keycodes_magic",
|
||||
],
|
||||
},
|
||||
{
|
||||
"Advanced Keycodes": [
|
||||
"feature_command",
|
||||
"feature_dynamic_macros",
|
||||
"feature_grave_esc",
|
||||
"feature_leader_key",
|
||||
"mod_tap",
|
||||
"feature_macros",
|
||||
"feature_mouse_keys",
|
||||
"feature_programmable_button",
|
||||
"feature_space_cadet",
|
||||
"keycodes_us_ansi_shifted",
|
||||
],
|
||||
},
|
||||
{
|
||||
"Software Features": [
|
||||
"feature_auto_shift",
|
||||
"feature_autocorrect",
|
||||
"feature_caps_word",
|
||||
"feature_combo",
|
||||
"feature_debounce_type",
|
||||
"feature_eeprom",
|
||||
"feature_key_lock",
|
||||
"feature_key_overrides",
|
||||
"feature_layers",
|
||||
"one_shot_keys",
|
||||
"feature_os_detection",
|
||||
"feature_rawhid",
|
||||
"feature_secure",
|
||||
"feature_send_string",
|
||||
"feature_sequencer",
|
||||
"feature_swap_hands",
|
||||
"feature_tap_dance",
|
||||
"tap_hold",
|
||||
"feature_tri_layer",
|
||||
"feature_unicode",
|
||||
"feature_userspace",
|
||||
"feature_wpm",
|
||||
],
|
||||
},
|
||||
{
|
||||
"Hardware Features": [
|
||||
{
|
||||
Displays: [
|
||||
"quantum_painter",
|
||||
"quantum_painter_lvgl",
|
||||
"feature_hd44780",
|
||||
"feature_st7565",
|
||||
"feature_oled_driver",
|
||||
],
|
||||
Lighting: [
|
||||
"feature_backlight",
|
||||
"feature_led_matrix",
|
||||
"feature_rgblight",
|
||||
"feature_rgb_matrix",
|
||||
],
|
||||
},
|
||||
"feature_audio",
|
||||
"feature_bluetooth",
|
||||
"feature_bootmagic",
|
||||
"feature_converters",
|
||||
"custom_matrix",
|
||||
"feature_digitizer",
|
||||
"feature_dip_switch",
|
||||
"feature_encoders",
|
||||
"feature_haptic_feedback",
|
||||
"feature_joystick",
|
||||
"feature_led_indicators",
|
||||
"feature_midi",
|
||||
"feature_pointing_device",
|
||||
"feature_ps2_mouse",
|
||||
"feature_split_keyboard",
|
||||
"feature_stenography",
|
||||
"feature_velocikey",
|
||||
],
|
||||
},
|
||||
{
|
||||
"Keyboard Building": [
|
||||
"easy_maker",
|
||||
"porting_your_keyboard_to_qmk",
|
||||
"hand_wire",
|
||||
"isp_flashing_guide",
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: "Developing QMK",
|
||||
collapsed: false,
|
||||
items: [
|
||||
"pr_checklist",
|
||||
{
|
||||
type: "category",
|
||||
label: "Breaking Changes",
|
||||
link: {
|
||||
type: "doc",
|
||||
id: "breaking_changes",
|
||||
},
|
||||
items: [
|
||||
"breaking_changes",
|
||||
"breaking_changes_instructions",
|
||||
// "ChangeLog/20230226",
|
||||
// "breaking_changes_history",
|
||||
{
|
||||
type: 'category',
|
||||
label: "Past Breaking Changes",
|
||||
link: {
|
||||
type: 'generated-index',
|
||||
title: 'Past Breaking Changes',
|
||||
slug: '/breaking_changes/all',
|
||||
},
|
||||
items: [
|
||||
{
|
||||
type: "autogenerated",
|
||||
dirName: "ChangeLog",
|
||||
}
|
||||
]
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"C Development": [
|
||||
"arm_debugging",
|
||||
"coding_conventions_c",
|
||||
"compatible_microcontrollers",
|
||||
"hardware_drivers",
|
||||
"adc_driver",
|
||||
"audio_driver",
|
||||
"i2c_driver",
|
||||
"spi_driver",
|
||||
"ws2812_driver",
|
||||
"eeprom_driver",
|
||||
"flash_driver",
|
||||
"serial_driver",
|
||||
"uart_driver",
|
||||
"gpio_control",
|
||||
"hardware_keyboard_guidelines",
|
||||
],
|
||||
},
|
||||
{
|
||||
"Python Development": [
|
||||
"coding_conventions_python",
|
||||
"cli_development",
|
||||
],
|
||||
},
|
||||
{
|
||||
"Configurator Development": [
|
||||
{
|
||||
"QMK API": [
|
||||
"api_development_environment",
|
||||
"api_development_overview",
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"Hardware Platform Development": [
|
||||
{
|
||||
"Arm/ChibiOS": [
|
||||
"platformdev_selecting_arm_mcu",
|
||||
"platformdev_chibios_earlyinit",
|
||||
"platformdev_rp2040",
|
||||
"platformdev_proton_c",
|
||||
"platformdev_blackpill_f4x1",
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"QMK Reference": [
|
||||
"contributing",
|
||||
"translating",
|
||||
"config_options",
|
||||
"data_driven_config",
|
||||
"getting_started_make_guide",
|
||||
"documentation_best_practices",
|
||||
"documentation_templates",
|
||||
"feature_layouts",
|
||||
"unit_testing",
|
||||
"ref_functions",
|
||||
"reference_info_json",
|
||||
],
|
||||
},
|
||||
{
|
||||
"For a Deeper Understanding": [
|
||||
"how_keyboards_work",
|
||||
"how_a_matrix_works",
|
||||
"understanding_qmk",
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
label: 'Doxygen Documentation',
|
||||
// needs to be an external link to be unmanaged by docusaurus
|
||||
// other solutions: https://stackoverflow.com/a/63365741/1530201
|
||||
href: 'https://docusaurus.qmk.fm/doxygen/'
|
||||
}
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
module.exports = sidebars;
|
22
builddefs/docs/src/components/DocsifyForwarder.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
function removeHashSlash(url) {
|
||||
return url.replace(/\/#\//, '/');
|
||||
}
|
||||
|
||||
export default function DocsifyForwarder(props) {
|
||||
const history = useHistory();
|
||||
|
||||
useEffect(() => {
|
||||
const currentUrl = window.location.href;
|
||||
if (currentUrl.includes('/#/')) {
|
||||
const newUrl = removeHashSlash(currentUrl);
|
||||
window.history.replaceState({}, '', newUrl);
|
||||
const relativePath = new URL(newUrl).pathname;
|
||||
history.push(relativePath);
|
||||
}
|
||||
}, [history]);
|
||||
|
||||
return "";
|
||||
}
|
30
builddefs/docs/src/css/custom.css
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Any CSS included here will be global. The classic template
|
||||
* bundles Infima by default. Infima is a CSS framework designed to
|
||||
* work well for content-centric websites.
|
||||
*/
|
||||
|
||||
/* You can override the default Infima variables here. */
|
||||
:root {
|
||||
--ifm-color-primary: #2d6fc5;
|
||||
--ifm-color-primary-dark: #294e78;
|
||||
--ifm-color-primary-darker: #274d71;
|
||||
--ifm-color-primary-darkest: #20355d;
|
||||
--ifm-color-primary-light: #335c92;
|
||||
--ifm-color-primary-lighter: #355899;
|
||||
--ifm-color-primary-lightest: #3c60ad;
|
||||
--ifm-code-font-size: 95%;
|
||||
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* For readability concerns, you should choose a lighter palette in dark mode. */
|
||||
[data-theme='dark'] {
|
||||
--ifm-color-primary: #c26e25;
|
||||
--ifm-color-primary-dark: #af7621;
|
||||
--ifm-color-primary-darker: #a5641f;
|
||||
--ifm-color-primary-darkest: #885a1a;
|
||||
--ifm-color-primary-light: #d58229;
|
||||
--ifm-color-primary-lighter: #d88232;
|
||||
--ifm-color-primary-lightest: #dd964f;
|
||||
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
|
||||
}
|
23
builddefs/docs/src/pages/index.module.css
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* CSS files with the .module.css suffix will be treated as CSS modules
|
||||
* and scoped locally.
|
||||
*/
|
||||
|
||||
.heroBanner {
|
||||
padding: 4rem 0;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 996px) {
|
||||
.heroBanner {
|
||||
padding: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.buttons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 793 B After Width: | Height: | Size: 793 B |
15
builddefs/docs/static/img/qmk-new-dark.svg
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 281 281" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,-597.647,-5630.35)">
|
||||
<g id="qmk-new-dark" transform="matrix(0.632083,0,0,0.627831,726.192,4200.78)">
|
||||
<rect x="-203.366" y="2277" width="443" height="446" style="fill:none;"/>
|
||||
<g transform="matrix(1.58207,0,0,1.59279,-651.083,-6690.94)">
|
||||
<path d="M342,5738.86L321.5,5738.86C317.361,5738.86 314,5735.49 314,5731.36C314,5727.22 317.361,5723.86 321.5,5723.86L342,5723.86L342,5715.47C342,5700.78 353.924,5688.86 368.61,5688.86L376.567,5688.86L376.567,5668.86C376.567,5664.75 379.897,5661.42 384,5661.42C388.103,5661.42 391.433,5664.75 391.433,5668.86L391.433,5688.86L416.067,5688.86L416.067,5668.86C416.067,5664.75 419.397,5661.42 423.5,5661.42C427.603,5661.42 430.933,5664.75 430.933,5668.86L430.933,5688.86L454.567,5688.86L454.567,5668.86C454.567,5664.75 457.897,5661.42 462,5661.42C466.103,5661.42 469.433,5664.75 469.433,5668.86L469.433,5688.86L477.39,5688.86C492.076,5688.86 504,5700.78 504,5715.47L504,5723.86L524.5,5723.86C528.639,5723.86 532,5727.22 532,5731.36C532,5735.49 528.639,5738.86 524.5,5738.86L504,5738.86L504,5762.36L524.5,5762.36C528.639,5762.36 532,5765.72 532,5769.86C532,5773.99 528.639,5777.36 524.5,5777.36L504,5777.36L504,5801.86L524.5,5801.86C528.639,5801.86 532,5805.22 532,5809.36C532,5813.49 528.639,5816.86 524.5,5816.86L504,5816.86L504,5824.25C504,5838.93 492.076,5850.86 477.39,5850.86L469.5,5850.86L469.5,5871.86C469.5,5875.99 466.139,5879.36 462,5879.36C457.861,5879.36 454.5,5875.99 454.5,5871.86L454.5,5850.86L431,5850.86L431,5871.86C431,5875.99 427.639,5879.36 423.5,5879.36C419.361,5879.36 416,5875.99 416,5871.86L416,5850.86L391.5,5850.86L391.5,5871.86C391.5,5875.99 388.139,5879.36 384,5879.36C379.861,5879.36 376.5,5875.99 376.5,5871.86L376.5,5850.86L368.61,5850.86C353.924,5850.86 342,5838.93 342,5824.25L342,5816.86L321.5,5816.86C317.361,5816.86 314,5813.49 314,5809.36C314,5805.22 317.361,5801.86 321.5,5801.86L342,5801.86L342,5777.36L321.5,5777.36C317.361,5777.36 314,5773.99 314,5769.86C314,5765.72 317.361,5762.36 321.5,5762.36L342,5762.36L342,5738.86Z" style="fill:white;"/>
|
||||
</g>
|
||||
<g transform="matrix(1.58207,0,0,1.59279,-651.083,-6690.94)">
|
||||
<path d="M416.067,5800.49C402.166,5799.34 393.38,5795 387.738,5790.24C376.29,5780.57 376.567,5768.36 376.567,5768.36L376.567,5731.36C376.567,5727.25 379.897,5723.92 384,5723.92C388.103,5723.92 391.433,5727.25 391.433,5731.36L391.433,5768.36C391.434,5768.36 391.712,5774.14 397.326,5778.88C401.148,5782.1 407.068,5784.67 416.067,5785.57L416.067,5731.36C416.067,5727.25 419.397,5723.92 423.5,5723.92C427.603,5723.92 430.933,5727.25 430.933,5731.36L430.933,5785.55C439.5,5784.63 445.157,5782.11 448.818,5778.94C454.317,5774.18 454.567,5768.36 454.567,5768.36L454.567,5731.36C454.567,5727.25 457.897,5723.92 462,5723.92C466.103,5723.92 469.433,5727.25 469.433,5731.36L469.433,5768.36C469.433,5768.36 469.685,5780.53 458.55,5790.18C453.039,5794.95 444.473,5799.3 430.933,5800.48L430.933,5809.36C430.933,5813.46 427.603,5816.79 423.5,5816.79C419.397,5816.79 416.067,5813.46 416.067,5809.36L416.067,5800.49Z" style="fill:rgb(16,16,16);"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.5 KiB |
15
builddefs/docs/static/img/qmk-new-light.svg
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 281 281" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,-282.994,-5630.35)">
|
||||
<g id="qmk-new-light" transform="matrix(0.632083,0,0,0.627831,411.538,4200.78)">
|
||||
<rect x="-203.366" y="2277" width="443" height="446" style="fill:none;"/>
|
||||
<g transform="matrix(1.58207,0,0,1.59279,-651.083,-6690.94)">
|
||||
<path d="M342,5738.86L321.5,5738.86C317.361,5738.86 314,5735.49 314,5731.36C314,5727.22 317.361,5723.86 321.5,5723.86L342,5723.86L342,5715.47C342,5700.78 353.924,5688.86 368.61,5688.86L376.567,5688.86L376.567,5668.86C376.567,5664.75 379.897,5661.42 384,5661.42C388.103,5661.42 391.433,5664.75 391.433,5668.86L391.433,5688.86L416.067,5688.86L416.067,5668.86C416.067,5664.75 419.397,5661.42 423.5,5661.42C427.603,5661.42 430.933,5664.75 430.933,5668.86L430.933,5688.86L454.567,5688.86L454.567,5668.86C454.567,5664.75 457.897,5661.42 462,5661.42C466.103,5661.42 469.433,5664.75 469.433,5668.86L469.433,5688.86L477.39,5688.86C492.076,5688.86 504,5700.78 504,5715.47L504,5723.86L524.5,5723.86C528.639,5723.86 532,5727.22 532,5731.36C532,5735.49 528.639,5738.86 524.5,5738.86L504,5738.86L504,5762.36L524.5,5762.36C528.639,5762.36 532,5765.72 532,5769.86C532,5773.99 528.639,5777.36 524.5,5777.36L504,5777.36L504,5801.86L524.5,5801.86C528.639,5801.86 532,5805.22 532,5809.36C532,5813.49 528.639,5816.86 524.5,5816.86L504,5816.86L504,5824.25C504,5838.93 492.076,5850.86 477.39,5850.86L469.5,5850.86L469.5,5871.86C469.5,5875.99 466.139,5879.36 462,5879.36C457.861,5879.36 454.5,5875.99 454.5,5871.86L454.5,5850.86L431,5850.86L431,5871.86C431,5875.99 427.639,5879.36 423.5,5879.36C419.361,5879.36 416,5875.99 416,5871.86L416,5850.86L391.5,5850.86L391.5,5871.86C391.5,5875.99 388.139,5879.36 384,5879.36C379.861,5879.36 376.5,5875.99 376.5,5871.86L376.5,5850.86L368.61,5850.86C353.924,5850.86 342,5838.93 342,5824.25L342,5816.86L321.5,5816.86C317.361,5816.86 314,5813.49 314,5809.36C314,5805.22 317.361,5801.86 321.5,5801.86L342,5801.86L342,5777.36L321.5,5777.36C317.361,5777.36 314,5773.99 314,5769.86C314,5765.72 317.361,5762.36 321.5,5762.36L342,5762.36L342,5738.86Z" style="fill:rgb(16,16,16);"/>
|
||||
</g>
|
||||
<g transform="matrix(1.58207,0,0,1.59279,-651.083,-6690.94)">
|
||||
<path d="M416.067,5800.49C402.166,5799.34 393.38,5795 387.738,5790.24C376.29,5780.57 376.567,5768.36 376.567,5768.36L376.567,5731.36C376.567,5727.25 379.897,5723.92 384,5723.92C388.103,5723.92 391.433,5727.25 391.433,5731.36L391.433,5768.36C391.434,5768.36 391.712,5774.14 397.326,5778.88C401.148,5782.1 407.068,5784.67 416.067,5785.57L416.067,5731.36C416.067,5727.25 419.397,5723.92 423.5,5723.92C427.603,5723.92 430.933,5727.25 430.933,5731.36L430.933,5785.55C439.5,5784.63 445.157,5782.11 448.818,5778.94C454.317,5774.18 454.567,5768.36 454.567,5768.36L454.567,5731.36C454.567,5727.25 457.897,5723.92 462,5723.92C466.103,5723.92 469.433,5727.25 469.433,5731.36L469.433,5768.36C469.433,5768.36 469.685,5780.53 458.55,5790.18C453.039,5794.95 444.473,5799.3 430.933,5800.48L430.933,5809.36C430.933,5813.46 427.603,5816.79 423.5,5816.79C419.397,5816.79 416.067,5813.46 416.067,5809.36L416.067,5800.49Z" style="fill:white;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.5 KiB |
BIN
builddefs/docs/static/img/qmk-social-card.jpg
vendored
Normal file
After Width: | Height: | Size: 40 KiB |
@@ -236,4 +236,4 @@ Old `fn_actions` action | New QMK keycode
|
||||
`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)`<br>e.g. `ACTION_MODS_KEY(MOD_LCTL, KC_0)` | `MOD(kc)`<br>e.g. `LCTL(KC_0)`
|
||||
`ACTION_MODS_KEY(mod, kc)`<br />e.g. `ACTION_MODS_KEY(MOD_LCTL, KC_0)` | `MOD(kc)`<br />e.g. `LCTL(KC_0)`
|
||||
|
@@ -3,9 +3,9 @@
|
||||
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
|
||||
## Changes Requiring User Action {#changes-requiring-user-action}
|
||||
|
||||
### Relocated Keyboards :id=relocated-keyboards
|
||||
### Relocated Keyboards {#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))
|
||||
@@ -24,7 +24,7 @@ handwired/numbrero | flehrad/numbrero
|
||||
snagpad | flehrad/snagpad
|
||||
handwired/tradestation | flehrad/tradestation
|
||||
|
||||
### Updated Keyboard Codebases :id=keyboard-updates
|
||||
### Updated Keyboard Codebases {#keyboard-updates}
|
||||
|
||||
#### Keebio RGB wiring update ([#7754](https://github.com/qmk/qmk_firmware/pull/7754))
|
||||
|
||||
@@ -46,7 +46,7 @@ This change affects:
|
||||
* Quefrency rev1
|
||||
* Viterbi, revs. 1 and 2
|
||||
|
||||
### Changes to Core Functionality :id=core-updates
|
||||
### Changes to Core Functionality {#core-updates}
|
||||
|
||||
* Bigger Combo index ([#9318](https://github.com/qmk/qmk_firmware/pull/9318))
|
||||
|
||||
@@ -58,14 +58,14 @@ Any fork that uses `process_combo_event` needs to update the function's first ar
|
||||
* New function: `void process_combo_event(uint16_t combo_index, bool pressed)`
|
||||
|
||||
|
||||
## Core Changes :id=core-changes
|
||||
## Core Changes {#core-changes}
|
||||
|
||||
### Fixes :id=core-fixes
|
||||
### Fixes {#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
|
||||
### Additions and Enhancements {#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.
|
||||
@@ -109,7 +109,7 @@ Any fork that uses `process_combo_event` needs to update the function's first ar
|
||||
* 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
|
||||
### Clean-ups and Optimizations {#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))
|
||||
@@ -140,7 +140,7 @@ Any fork that uses `process_combo_event` needs to update the function's first ar
|
||||
* remove support for Adafruit EZ Key Bluetooth controller ([#10103](https://github.com/qmk/qmk_firmware/pull/10103))
|
||||
|
||||
|
||||
## QMK Infrastructure and Internals :id=qmk-internals
|
||||
## QMK Infrastructure and Internals {#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.
|
||||
|
@@ -3,9 +3,9 @@
|
||||
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
|
||||
## Changes Requiring User Action {#changes-requiring-user-action}
|
||||
|
||||
### Relocated Keyboards :id=relocated-keyboards
|
||||
### Relocated Keyboards {#relocated-keyboards}
|
||||
|
||||
#### Reduce Helix keyboard build variation ([#8669](https://github.com/qmk/qmk_firmware/pull/8669))
|
||||
|
||||
@@ -88,21 +88,21 @@ The Valor and Dawn60 keyboards by Xelus22 both now require their revisions to be
|
||||
| xelus/valor | xelus/valor/rev1 |
|
||||
|
||||
|
||||
### Updated Keyboard Codebases :id=keyboard-updates
|
||||
### Updated Keyboard Codebases {#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
|
||||
## Core Changes {#core-changes}
|
||||
|
||||
### Fixes :id=core-fixes
|
||||
### Fixes {#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
|
||||
### Additions and Enhancements {#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))
|
||||
@@ -119,7 +119,7 @@ The EXT65 codebase has been reworked so keymaps can be used with either revision
|
||||
* 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
|
||||
### Clean-ups and Optimizations {#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))
|
||||
@@ -129,7 +129,7 @@ The EXT65 codebase has been reworked so keymaps can be used with either revision
|
||||
* Remove references to HD44780 ([#10735](https://github.com/qmk/qmk_firmware/pull/10735))
|
||||
|
||||
|
||||
## QMK Infrastructure and Internals :id=qmk-internals
|
||||
## QMK Infrastructure and Internals {#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))
|
||||
|
@@ -1,30 +1,30 @@
|
||||
# QMK Breaking Changes - 2021 May 29 Changelog
|
||||
|
||||
## Notable Changes :id=notable-changes
|
||||
## Notable Changes {#notable-changes}
|
||||
|
||||
### RGB Matrix support for split common ([#11055](https://github.com/qmk/qmk_firmware/pull/11055)) :id=rgb-matrix-split-common
|
||||
### RGB Matrix support for split common ([#11055](https://github.com/qmk/qmk_firmware/pull/11055)) {#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
|
||||
### Teensy 3.6 support ([#12258](https://github.com/qmk/qmk_firmware/pull/12258)) {#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
|
||||
### New command: qmk console ([#12828](https://github.com/qmk/qmk_firmware/pull/12828)) {#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
|
||||
### Improved command: qmk config {#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 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)) {#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
|
||||
## Changes Requiring User Action {#changes-requiring-user-action}
|
||||
|
||||
### Updated Keyboard Codebases :id=updated-keyboard-codebases
|
||||
### Updated Keyboard Codebases {#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))
|
||||
@@ -52,7 +52,7 @@ The codebase for the [Durgod K320](https://github.com/qmk/qmk_firmware/tree/0.13
|
||||
|
||||
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
|
||||
### Bootmagic Deprecation and Refactor ([#12172](https://github.com/qmk/qmk_firmware/pull/12172)) {#bootmagic-deprecation-and-refactor}
|
||||
|
||||
QMK has decided to deprecate the full Bootmagic feature and leave Bootmagic Lite as the only remaining option.
|
||||
|
||||
@@ -68,11 +68,11 @@ This is the current planned roadmap for the behavior of `BOOTMAGIC_ENABLE`:
|
||||
- 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
|
||||
### Removal of LAYOUT_kc ([#12160](https://github.com/qmk/qmk_firmware/pull/12160)) {#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
|
||||
### Encoder callbacks are now boolean ([#12805](https://github.com/qmk/qmk_firmware/pull/12805), [#12985](https://github.com/qmk/qmk_firmware/pull/12985)) {#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.
|
||||
|
||||
@@ -127,9 +127,9 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
|
||||
}
|
||||
```
|
||||
|
||||
## Core Changes :id=core-changes
|
||||
## Core Changes {#core-changes}
|
||||
|
||||
### Fixes :id=core-fixes
|
||||
### Fixes {#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))
|
||||
@@ -147,7 +147,7 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
|
||||
* [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
|
||||
### Additions and Enhancements {#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))
|
||||
@@ -193,7 +193,7 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
|
||||
* 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
|
||||
### Clean-ups and Optimizations {#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))
|
||||
@@ -218,7 +218,7 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
|
||||
* 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
|
||||
### QMK Infrastructure and Internals {#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))
|
||||
|
@@ -1,14 +1,14 @@
|
||||
# QMK Breaking Changes - 2021 August 28 Changelog
|
||||
|
||||
## Notable Features :id=notable-features
|
||||
## Notable Features {#notable-features}
|
||||
|
||||
### Combo processing improvements ([#8591](https://github.com/qmk/qmk_firmware/pull/8591)) :id=combo-processing-improvements
|
||||
### Combo processing improvements ([#8591](https://github.com/qmk/qmk_firmware/pull/8591)) {#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
|
||||
### Key Overrides ([#11422](https://github.com/qmk/qmk_firmware/pull/11422)) {#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 <kbd>Shift+2</kbd> normally results in an <kbd>@</kbd> on US-ANSI keyboard layouts -- the new key overrides allow for adding similar functionality, but for any <kbd>modifier + key</kbd> press.
|
||||
|
||||
@@ -20,9 +20,9 @@ There's far more to describe that what lives in this changelog, so head over to
|
||||
|
||||
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
|
||||
## Changes Requiring User Action {#changes-requiring-user-action}
|
||||
|
||||
### Updated Keyboard Codebases :id=updated-keyboard-codebases
|
||||
### Updated Keyboard Codebases {#updated-keyboard-codebases}
|
||||
|
||||
The following keyboards have had their source moved within QMK:
|
||||
|
||||
@@ -69,7 +69,7 @@ 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
|
||||
### Bootmagic Full Removal ([#13846](https://github.com/qmk/qmk_firmware/pull/13846)) {#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.
|
||||
|
||||
@@ -85,7 +85,7 @@ This is the current roadmap for the behavior of `BOOTMAGIC_ENABLE`:
|
||||
- (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
|
||||
### DIP switch callbacks are now boolean ([#13399](https://github.com/qmk/qmk_firmware/pull/13399)) {#dip-switch-boolean}
|
||||
|
||||
To match the encoder change last breaking changes cycle, DIP switch callbacks now return `bool`, too.
|
||||
|
||||
@@ -149,9 +149,9 @@ bool dip_switch_update_mask_user(uint32_t state) {
|
||||
}
|
||||
```
|
||||
|
||||
## Notable core changes :id=notable-core
|
||||
## Notable core changes {#notable-core}
|
||||
|
||||
### Split transport improvements :id=split-transport-improvements
|
||||
### Split transport improvements {#split-transport-improvements}
|
||||
|
||||
Split keyboards gained a significant amount of improvements during this breaking changes cycle, specifically:
|
||||
|
||||
@@ -160,9 +160,13 @@ Split keyboards gained a significant amount of improvements during this breaking
|
||||
* 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.
|
||||
:::caution
|
||||
|
||||
### 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
|
||||
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)) {#teensy-4-x-support}
|
||||
|
||||
Updated ChibiOS and ChibiOS-Contrib, which brought in support for Teensy 4.x dev boards, running NXP i.MX1062.
|
||||
|
||||
@@ -243,7 +247,7 @@ We've added dozens of new keys to `info.json` so that you can configure more tha
|
||||
* `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
|
||||
### Codebase restructure and cleanup {#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:
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# QMK Breaking Changes - 2021 November 27 Changelog
|
||||
|
||||
## 2000 keyboards! :id=qmk-2000th-keyboard
|
||||
## 2000 keyboards! {#qmk-2000th-keyboard}
|
||||
|
||||
QMK had it's 2000th keyboard submitted during this breaking changes cycle.... and it only _just_ made the cut-off!
|
||||
|
||||
@@ -11,9 +11,9 @@ QMK had it's 2000th keyboard submitted during this breaking changes cycle.... an
|
||||
|
||||
From the whole QMK team, a major thankyou to the community for embracing QMK as your preferred keyboard firmware!
|
||||
|
||||
## Notable Features :id=notable-features
|
||||
## Notable Features {#notable-features}
|
||||
|
||||
### Expanded Pointing Device support ([#14343](https://github.com/qmk/qmk_firmware/pull/14343)) :id=expanded-pointing-device
|
||||
### Expanded Pointing Device support ([#14343](https://github.com/qmk/qmk_firmware/pull/14343)) {#expanded-pointing-device}
|
||||
|
||||
Pointing device support has been reworked and reimplemented to allow for easier integration of new peripherals.
|
||||
|
||||
@@ -33,7 +33,7 @@ QMK now has core-supplied support for the following pointing device peripherals:
|
||||
|
||||
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
|
||||
### Dynamic Tapping Term ([#11036](https://github.com/qmk/qmk_firmware/pull/11036)) {#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.
|
||||
|
||||
@@ -47,7 +47,7 @@ If you're in this stage of discovery, you can now add `DYNAMIC_TAPPING_TERM_ENAB
|
||||
|
||||
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
|
||||
### Macros in JSON keymaps ([#14374](https://github.com/qmk/qmk_firmware/pull/14374)) {#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:
|
||||
|
||||
@@ -83,9 +83,9 @@ You can now define up to 32 macros in your `keymap.json` file, as used by [QMK C
|
||||
|
||||
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
|
||||
## Changes Requiring User Action {#changes-requiring-user-action}
|
||||
|
||||
### Updated Keyboard Codebases :id=updated-keyboard-codebases
|
||||
### Updated Keyboard Codebases {#updated-keyboard-codebases}
|
||||
|
||||
The following keyboards have had their source moved within QMK:
|
||||
|
||||
@@ -104,13 +104,13 @@ The following keyboards have had their source moved within QMK:
|
||||
| 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
|
||||
### Squeezing space out of AVR ([#15243](https://github.com/qmk/qmk_firmware/pull/15243)) {#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
|
||||
### Require explicit enabling of RGB Matrix modes ([#15018](https://github.com/qmk/qmk_firmware/pull/15018)) {#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.
|
||||
|
||||
@@ -118,7 +118,7 @@ Most keyboards keep their original functionality, but over time the QMK maintain
|
||||
|
||||
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 task refactoring ([#14864](https://github.com/qmk/qmk_firmware/pull/14864)) {#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.
|
||||
|
||||
@@ -152,7 +152,7 @@ bool oled_task_kb(void) {
|
||||
}
|
||||
```
|
||||
|
||||
### Bootmagic Full Removal ([#15002](https://github.com/qmk/qmk_firmware/pull/15002)) :id=bootmagic-full-removal
|
||||
### Bootmagic Full Removal ([#15002](https://github.com/qmk/qmk_firmware/pull/15002)) {#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.
|
||||
|
||||
@@ -170,13 +170,13 @@ This is the historical timeline for the behavior of `BOOTMAGIC_ENABLE`:
|
||||
- (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
|
||||
### Remove QWIIC_DRIVERS ([#14174](https://github.com/qmk/qmk_firmware/pull/14174)) {#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
|
||||
## Notable core changes {#notable-core}
|
||||
|
||||
### New MCU Support :id=new-mcu-support
|
||||
### New MCU Support {#new-mcu-support}
|
||||
|
||||
QMK firmware picked up support for a handful of new MCU families, potentially making it a bit easier to source components.
|
||||
|
||||
@@ -187,7 +187,7 @@ QMK firmware is now no longer limited to AVR and ARM - it also picked up support
|
||||
* 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
|
||||
### EEPROM Changes {#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.
|
||||
|
||||
@@ -197,7 +197,7 @@ There were a few EEPROM-related changes that landed during this breaking changes
|
||||
* 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
|
||||
### Compilation Database {#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.
|
||||
|
||||
@@ -208,7 +208,7 @@ 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
|
||||
### Codebase restructure and cleanup {#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:
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# QMK Breaking Changes - 2022 February 26 Changelog
|
||||
|
||||
## Notable Features :id=notable-features
|
||||
## Notable Features {#notable-features}
|
||||
|
||||
### Default USB Polling rate now 1kHz ([#15352](https://github.com/qmk/qmk_firmware/pull/15352))
|
||||
|
||||
@@ -14,7 +14,7 @@ Pointing devices can now be shared across a split keyboard with support for a si
|
||||
|
||||
See the [Pointing Device](feature_pointing_device.md) documentation for further configuration options.
|
||||
|
||||
## Changes Requiring User Action :id=changes-requiring-user-action
|
||||
## Changes Requiring User Action {#changes-requiring-user-action}
|
||||
|
||||
### Legacy macro and action_function system removed ([#16025](https://github.com/qmk/qmk_firmware/pull/16025))
|
||||
|
||||
@@ -31,7 +31,7 @@ Bootloader configuration is no longer assumed. Keyboards must now set either:
|
||||
|
||||
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
|
||||
### Updated Keyboard Codebases {#updated-keyboard-codebases}
|
||||
|
||||
The following keyboards have had their source moved within QMK:
|
||||
|
||||
@@ -241,9 +241,9 @@ The following keyboards have had their source moved within QMK:
|
||||
| zinc/rev1 | 25keys/zinc/rev1 |
|
||||
| zinc/reva | 25keys/zinc/reva |
|
||||
|
||||
## Notable core changes :id=notable-core
|
||||
## Notable core changes {#notable-core}
|
||||
|
||||
### New MCU Support :id=new-mcu-support
|
||||
### New MCU Support {#new-mcu-support}
|
||||
|
||||
Building on previous cycles, QMK firmware picked up support for a couple extra MCU variants:
|
||||
|
||||
|
@@ -1,8 +1,8 @@
|
||||
# QMK Breaking Changes - 2022 May 28 Changelog
|
||||
|
||||
## Notable Features :id=notable-features
|
||||
## Notable Features {#notable-features}
|
||||
|
||||
### Caps Word ([#16588](https://github.com/qmk/qmk_firmware/pull/16588)) :id=caps-word
|
||||
### Caps Word ([#16588](https://github.com/qmk/qmk_firmware/pull/16588)) {#caps-word}
|
||||
|
||||
This is a new feature that allows for capslock-like functionality that turns itself off at the end of the word.
|
||||
|
||||
@@ -10,7 +10,7 @@ For instance, if you wish to type "QMK" without holding shift the entire time, y
|
||||
|
||||
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
|
||||
### Quantum Painter ([#10174](https://github.com/qmk/qmk_firmware/pull/10174)) {#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.
|
||||
|
||||
@@ -20,25 +20,33 @@ The QMK CLI has new commands added to be able to generate images and fonts for Q
|
||||
|
||||
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.
|
||||
:::caution
|
||||
|
||||
### Encoder Mapping ([#13286](https://github.com/qmk/qmk_firmware/pull/13286)) :id=encoder-mapping
|
||||
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)) {#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.
|
||||
:::caution
|
||||
|
||||
## Changes Requiring User Action :id=changes-requiring-user-action
|
||||
This is not yet supported by QMK Configurator. It is also unlikely to ever be supported by VIA.
|
||||
|
||||
### `RESET` => `QK_BOOT` ([#17037](https://github.com/qmk/qmk_firmware/pull/17037)) :id=reset-2-qk_boot
|
||||
:::
|
||||
|
||||
## Changes Requiring User Action {#changes-requiring-user-action}
|
||||
|
||||
### `RESET` => `QK_BOOT` ([#17037](https://github.com/qmk/qmk_firmware/pull/17037)) {#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
|
||||
### Sendstring keycode overhaul ([#16941](https://github.com/qmk/qmk_firmware/pull/16941)) {#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
|
||||
### Pillow Installation ([#17133](https://github.com/qmk/qmk_firmware/pull/17133)) {#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:
|
||||
|
||||
@@ -62,7 +70,7 @@ On Linux or WSL:
|
||||
python3 -m pip install --user --upgrade qmk
|
||||
```
|
||||
|
||||
### Updated Keyboard Codebases :id=updated-keyboard-codebases
|
||||
### Updated Keyboard Codebases {#updated-keyboard-codebases}
|
||||
|
||||
The following keyboards have had their source moved within QMK:
|
||||
|
||||
@@ -97,7 +105,7 @@ The following keyboards have had their source moved within QMK:
|
||||
|
||||
---
|
||||
|
||||
## Full changelist :id=full-changelist
|
||||
## Full changelist {#full-changelist}
|
||||
|
||||
Core:
|
||||
* Quantum Painter ([#10174](https://github.com/qmk/qmk_firmware/pull/10174))
|
||||
|
@@ -1,28 +1,28 @@
|
||||
# QMK Breaking Changes - 2022 August 27 Changelog
|
||||
|
||||
## Notable Features :id=notable-features
|
||||
## Notable Features {#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
|
||||
### 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)) {#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
|
||||
### Allow `qmk flash` to use prebuilt firmware binaries ([#16584](https://github.com/qmk/qmk_firmware/pull/16584)) {#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
|
||||
## Changes Requiring User Action {#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
|
||||
### `RESET` => `QK_BOOT` ([#17940](https://github.com/qmk/qmk_firmware/pull/17940)) {#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
|
||||
### Updated Keyboard Codebases {#updated-keyboard-codebases}
|
||||
|
||||
The following keyboards have had their source moved within QMK:
|
||||
|
||||
@@ -33,7 +33,7 @@ The following keyboards have had their source moved within QMK:
|
||||
| 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
|
||||
### Data-driven USB IDs Refactoring ([#18152](https://github.com/qmk/qmk_firmware/pull/18152)) {#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.
|
||||
|
||||
@@ -67,25 +67,25 @@ Replaced by `info.json`:
|
||||
- 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
|
||||
## Notable core changes {#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
|
||||
### 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)) {#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
|
||||
### Add cli command to import keyboard|keymap|kbfirmware ([#16668](https://github.com/qmk/qmk_firmware/pull/16668)) {#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
|
||||
### 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)) {#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
|
||||
### 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)) {#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.
|
||||
|
||||
@@ -102,7 +102,7 @@ Other related changes:
|
||||
|
||||
---
|
||||
|
||||
## Full changelist :id=full-changelist
|
||||
## Full changelist {#full-changelist}
|
||||
|
||||
Core:
|
||||
* Tentative Teensy 3.5 support ([#14420](https://github.com/qmk/qmk_firmware/pull/14420))
|
||||
|
@@ -1,14 +1,14 @@
|
||||
# QMK Breaking Changes - 2022 November 26 Changelog
|
||||
|
||||
## Notable Features :id=notable-features
|
||||
## Notable Features {#notable-features}
|
||||
|
||||
### Autocorrect ([#15699](https://github.com/qmk/qmk_firmware/pull/15699)) :id=autocorrect
|
||||
### Autocorrect ([#15699](https://github.com/qmk/qmk_firmware/pull/15699)) {#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
|
||||
## Changes Requiring User Action {#changes-requiring-user-action}
|
||||
|
||||
### Updated Keyboard Codebases :id=updated-keyboard-codebases
|
||||
### Updated Keyboard Codebases {#updated-keyboard-codebases}
|
||||
|
||||
The following keyboards have had their source moved within QMK:
|
||||
|
||||
@@ -23,7 +23,7 @@ The following keyboards have had their source moved within QMK:
|
||||
| handwired/hillside/52 | hillside/52 |
|
||||
| maple_computing/christmas_tree/V2017 | maple_computing/christmas_tree/v2017 |
|
||||
|
||||
### Keycodes refactoring :id=keycodes-overhaul-user-action
|
||||
### Keycodes refactoring {#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.
|
||||
|
||||
@@ -31,9 +31,13 @@ In most cases user keymaps in the repository have already been updated to reflec
|
||||
|
||||
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.
|
||||
:::caution
|
||||
|
||||
### Configuration Item Refactoring :id=config-refactoring
|
||||
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 {#config-refactoring}
|
||||
|
||||
A number of configuration items have been renamed for consistency.
|
||||
|
||||
@@ -66,7 +70,7 @@ Joystick configuration:
|
||||
| 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
|
||||
### Data-driven USB IDs Refactoring ([#18152](https://github.com/qmk/qmk_firmware/pull/18152)) {#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.
|
||||
|
||||
@@ -92,7 +96,7 @@ Replaced by `info.json`:
|
||||
}
|
||||
```
|
||||
|
||||
### LED Indicator callback refactoring ([#14864](https://github.com/qmk/qmk_firmware/pull/18450)) :id=led-callback-refactor
|
||||
### LED Indicator callback refactoring ([#14864](https://github.com/qmk/qmk_firmware/pull/18450)) {#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.
|
||||
|
||||
@@ -128,15 +132,15 @@ bool rgb_matrix_indicators_kb(void) {
|
||||
|
||||
The equivalent transformations should be done for LED Matrix boards.
|
||||
|
||||
### Unicode mode refactoring :id=unicode-mode-renaming
|
||||
### Unicode mode refactoring {#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
|
||||
## Notable core changes {#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
|
||||
### Keycodes refactoring {#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:
|
||||
|
||||
@@ -181,7 +185,7 @@ We aren't going to list each and every change -- they're far too numerous -- ins
|
||||
* 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
|
||||
### Board Converters {#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:
|
||||
|
||||
@@ -193,7 +197,7 @@ There was additional work in the space of board converters -- historically QMK a
|
||||
|
||||
See [Feature: Converters](feature_converters.md) for the full list of board conversions available.
|
||||
|
||||
### Pointing and Digitizer device updates :id=pointing-and-digitizer
|
||||
### Pointing and Digitizer device updates {#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!
|
||||
|
||||
@@ -207,7 +211,7 @@ Both pointing devices and digitizer got a host of updates this cycle. Inertia, a
|
||||
* 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
|
||||
## Full changelist {#full-changelist}
|
||||
|
||||
Core:
|
||||
* quantum: led: split out led_update_ports() for customization of led behaviour ([#14452](https://github.com/qmk/qmk_firmware/pull/14452))
|
||||
|
@@ -1,8 +1,8 @@
|
||||
# QMK Breaking Changes - 2023 February 26 Changelog
|
||||
|
||||
## Changes Requiring User Action :id=changes-requiring-user-action
|
||||
## Changes Requiring User Action {#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` behaviour changes ([#15741](https://github.com/qmk/qmk_firmware/pull/15741)) {#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.
|
||||
|
||||
@@ -48,7 +48,7 @@ bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {
|
||||
|
||||
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` => `QUICK_TAP_TERM` ([#17007](https://github.com/qmk/qmk_firmware/pull/17007)) {#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.
|
||||
|
||||
@@ -82,7 +82,7 @@ uint16_t get_quick_tap_term(uint16_t keycode, keyrecord_t *record) {
|
||||
|
||||
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))
|
||||
### Leader Key Rework {#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.
|
||||
|
||||
@@ -108,7 +108,7 @@ void leader_end_user(void) {
|
||||
|
||||
For more information please see the [Leader Key documentation](feature_leader_key.md).
|
||||
|
||||
### Updated Keyboard Codebases :id=updated-keyboard-codebases
|
||||
### Updated Keyboard Codebases {#updated-keyboard-codebases}
|
||||
|
||||
The following keyboards have had their source moved within QMK:
|
||||
|
||||
@@ -130,7 +130,7 @@ The following keyboards have had their source moved within QMK:
|
||||
| the_uni | stenothe_uni |
|
||||
| xelus/xs60 | xelus/xs60/soldered |
|
||||
|
||||
## Notable core changes :id=notable-core
|
||||
## Notable core changes {#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.
|
||||
|
||||
@@ -142,7 +142,7 @@ A handful of examples:
|
||||
* 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
|
||||
## Full changelist {#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))
|
||||
|
@@ -1,3 +1,5 @@
|
||||
import DocsifyForwarder from '@site/src/components/DocsifyForwarder';
|
||||
|
||||
# Quantum Mechanical Keyboard Firmware
|
||||
|
||||
## What is QMK Firmware?
|
||||
@@ -8,12 +10,20 @@ QMK (*Quantum Mechanical Keyboard*) is an open source community centered around
|
||||
|
||||
<div class="flex-container">
|
||||
|
||||
?> **Basic** [QMK Configurator](newbs_building_firmware_configurator.md) <br>
|
||||
:::tip Basic
|
||||
|
||||
[QMK Configurator](newbs_building_firmware_configurator.md) <br />
|
||||
User friendly graphical interfaces, no programming knowledge required.
|
||||
|
||||
?> **Advanced** [Use The Source](newbs.md) <br>
|
||||
:::
|
||||
|
||||
:::caution Advanced
|
||||
|
||||
[Use The Source](newbs.md) <br />
|
||||
More powerful, but harder to use.
|
||||
|
||||
:::
|
||||
|
||||
</div>
|
||||
|
||||
## Make It Yours
|
||||
@@ -35,3 +45,5 @@ There are a lot of ways you can contribute to the QMK Community. The easiest way
|
||||
* [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)
|
||||
|
||||
<DocsifyForwarder />
|
@@ -1,4 +0,0 @@
|
||||
- Translations
|
||||
- [:uk: English](/)
|
||||
- [:cn: 简体中文](/zh-cn/)
|
||||
- [:jp: 日本語](/ja/)
|
204
docs/_summary.md
@@ -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)
|
||||
* [Vagrant Guide](getting_started_vagrant.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)
|
||||
* [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/20230226.md "QMK v0.20.0 - 2023 Feb 26")
|
||||
* [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)
|
@@ -1,3 +1,8 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
sidebar_label: API Documentation
|
||||
---
|
||||
|
||||
# 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.
|
||||
@@ -67,7 +72,7 @@ Once your compile job has finished you'll check the `result` key. The value of t
|
||||
* `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
|
||||
## Constants {#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.
|
||||
|
||||
@@ -81,9 +86,17 @@ $ curl https://keyboards.develop.qmk.fm/v1/constants_metadata.json # For `develo
|
||||
{"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.
|
||||
:::caution
|
||||
|
||||
?> Only keycodes are currently published, but over time all other "externally visible" IDs are expected to appear on these endpoints.
|
||||
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.
|
||||
|
||||
:::
|
||||
|
||||
:::tip
|
||||
|
||||
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:
|
||||
```
|
||||
|
@@ -1,3 +1,8 @@
|
||||
---
|
||||
sidebar_position: 0
|
||||
sidebar_label: Overview
|
||||
---
|
||||
|
||||
# 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.
|
||||
|
@@ -1,11 +1,11 @@
|
||||
# Audio Driver :id=audio-driver
|
||||
# Audio Driver {#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
|
||||
## AVR {#avr}
|
||||
|
||||
Boards built around an Atmega32U4 can use two sets of PWM capable pins, each driving a separate speaker.
|
||||
The possible configurations are:
|
||||
@@ -23,14 +23,14 @@ AUDIO_DRIVER = pwm_hardware
|
||||
```
|
||||
|
||||
|
||||
## ARM :id=arm
|
||||
## ARM {#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<br>Tim6 | GPTD7<br>Tim7 | GPTD8<br>Tim8 | PWMD1<sup>1</sup><br>Tim1_Ch1 |
|
||||
| driver | GPTD6<br />Tim6 | GPTD7<br />Tim7 | GPTD8<br />Tim8 | PWMD1<sup>1</sup><br />Tim1_Ch1 |
|
||||
|--------------|------------------------------------------|------------------------|---------------|-------------------------------|
|
||||
| dac_basic | A4+DACD1 = :one: | A5+DACD2 = :one: | state | |
|
||||
| | A4+DACD1 = :one: + Gnd | A5+DACD2 = :two: + Gnd | state | |
|
||||
@@ -50,7 +50,7 @@ piezo speakers are marked with :one: for the first/primary and :two: for the sec
|
||||
|
||||
|
||||
|
||||
### DAC basic :id=dac-basic
|
||||
### DAC basic {#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.
|
||||
@@ -79,7 +79,11 @@ Additionally, in the board config, you'll want to make changes to enable the DAC
|
||||
#define STM32_GPT_USE_TIM8 TRUE
|
||||
```
|
||||
|
||||
?> Note: DAC1 (A4) uses TIM6, DAC2 (A5) uses TIM7, and the audio state timer uses TIM8 (configurable).
|
||||
:::tip
|
||||
|
||||
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:
|
||||
|
||||
@@ -87,7 +91,7 @@ You can also change the timer used for the overall audio state by defining the d
|
||||
#define AUDIO_STATE_TIMER GPTD9
|
||||
```
|
||||
|
||||
### DAC additive :id=dac-additive
|
||||
### DAC additive {#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.
|
||||
|
||||
@@ -149,7 +153,7 @@ There are a number of predefined quality settings that you can use, with "sane m
|
||||
```
|
||||
|
||||
|
||||
### PWM hardware :id=pwm-hardware
|
||||
### PWM hardware {#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.
|
||||
@@ -187,7 +191,7 @@ 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
|
||||
### PWM software {#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).
|
||||
@@ -199,7 +203,7 @@ You can also change the timer used for software PWM by defining the driver. For
|
||||
```
|
||||
|
||||
|
||||
### Testing Notes :id=testing-notes
|
||||
### Testing Notes {#testing-notes}
|
||||
|
||||
While not an exhaustive list, the following table provides the scenarios that have been partially validated:
|
||||
|
||||
|
@@ -1,3 +1,8 @@
|
||||
---
|
||||
sidebar_position: 0
|
||||
sidebar_label: Overview
|
||||
---
|
||||
|
||||
# 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.
|
||||
@@ -73,7 +78,7 @@ This section documents various processes we use when running the Breaking Change
|
||||
### 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 <Day of Merge> -- message `@Breaking Changes Updates` on `#qmk_firmware` in Discord:
|
||||
* Announce that master will be closed from `<2 Days Before>` to `<Day of Merge>` -- 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
|
||||
|
@@ -1,3 +1,8 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
sidebar_label: My Pull Request Was Flagged
|
||||
---
|
||||
|
||||
# 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.
|
||||
|
17
docs/cli.md
@@ -1,14 +1,19 @@
|
||||
# QMK CLI :id=qmk-cli
|
||||
---
|
||||
sidebar_position: 0
|
||||
sidebar_label: Overview
|
||||
---
|
||||
|
||||
## Overview :id=overview
|
||||
# QMK CLI {#qmk-cli}
|
||||
|
||||
## Overview {#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
|
||||
### Requirements {#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
|
||||
### Install Using Homebrew (macOS, some Linux) {#install-using-homebrew}
|
||||
|
||||
If you have installed [Homebrew](https://brew.sh) you can tap and install QMK:
|
||||
|
||||
@@ -18,7 +23,7 @@ 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
|
||||
### Install Using pip {#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:
|
||||
|
||||
@@ -28,7 +33,7 @@ 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
|
||||
### Packaging For Other Operating Systems {#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:
|
||||
|
||||
|
@@ -1,3 +1,8 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
sidebar_label: Commands
|
||||
---
|
||||
|
||||
# QMK CLI Commands
|
||||
|
||||
# User Commands
|
||||
|
@@ -1,3 +1,8 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
sidebar_label: Configuration
|
||||
---
|
||||
|
||||
# QMK CLI Configuration
|
||||
|
||||
This document explains how `qmk config` works.
|
||||
|
@@ -202,7 +202,11 @@ We use nose2, flake8, and yapf to test, lint, and format code. You can use the `
|
||||
|
||||
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.
|
||||
:::tip
|
||||
|
||||
Tip- Many editors can use yapf as a plugin to automatically format code as you type.
|
||||
|
||||
:::
|
||||
|
||||
## Testing Details
|
||||
|
||||
|
@@ -1,3 +1,8 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
sidebar_label: Tab Completion
|
||||
---
|
||||
|
||||
# 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.
|
||||
|
@@ -15,7 +15,7 @@ Most of our style follows PEP8 with some local modifications to make things less
|
||||
|
||||
# YAPF
|
||||
|
||||
You can use [yapf](https://github.com/google/yapf) to style your code. We provide a config in [setup.cfg](setup.cfg).
|
||||
You can use [yapf](https://github.com/google/yapf) to style your code. We provide a config in [setup.cfg](https://github.com/qmk/qmk_firmware/blob/master/setup.cfg).
|
||||
|
||||
# Imports
|
||||
|
||||
|
@@ -10,7 +10,11 @@ There are three main types of configuration files in QMK:
|
||||
|
||||
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.
|
||||
:::tip
|
||||
|
||||
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:
|
||||
|
||||
@@ -409,7 +413,7 @@ This is a [make](https://www.gnu.org/software/make/manual/make.html) file that i
|
||||
* `bootloadhid`
|
||||
* `usbasploader`
|
||||
|
||||
## Feature Options :id=feature-options
|
||||
## Feature Options {#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.
|
||||
|
||||
|
@@ -1,3 +1,8 @@
|
||||
---
|
||||
sidebar_position: 4
|
||||
sidebar_label: Architecture
|
||||
---
|
||||
|
||||
# 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.
|
||||
|
@@ -1,9 +1,14 @@
|
||||
# Adding Default Keymaps to QMK Configurator :id=adding-default-keymaps
|
||||
---
|
||||
sidebar_position: 2
|
||||
sidebar_label: Adding Default Keymaps
|
||||
---
|
||||
|
||||
# Adding Default Keymaps to QMK Configurator {#adding-default-keymaps}
|
||||
|
||||
This page covers how to add a default keymap for a keyboard to QMK Configurator.
|
||||
|
||||
|
||||
## Technical Information :id=technical-information
|
||||
## Technical Information {#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 <keyboard>:default` from `qmk_firmware`.
|
||||
|
||||
@@ -27,7 +32,7 @@ f14629ed1cd7c7ec9089604d64f29a99981558e8 Remove/migrate action_get_macro()s from
|
||||
In this example, `f14629ed1cd7c7ec9089604d64f29a99981558e8` is the value that should be used for `commit`.
|
||||
|
||||
|
||||
## Example :id=example
|
||||
## Example {#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`:
|
||||
|
||||
@@ -96,9 +101,9 @@ The default keymap uses the `LAYOUT_all` macro, so that will be the value of the
|
||||
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
|
||||
## Caveats {#caveats}
|
||||
|
||||
### Layers can only be referenced by number :id=layer-references
|
||||
### Layers can only be referenced by number {#layer-references}
|
||||
|
||||
A common QMK convention is to name layers using a series of `#define`s, or an `enum` statement:
|
||||
|
||||
@@ -112,11 +117,11 @@ enum layer_names {
|
||||
|
||||
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
|
||||
### No support for custom code of any kind {#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
|
||||
### Limited Support for Custom keycodes {#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`:
|
||||
|
||||
@@ -186,6 +191,6 @@ bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
|
||||
|
||||
Note the call to `process_record_user()` at the end.
|
||||
|
||||
## Additional Reading :id=additional-reading
|
||||
## Additional Reading {#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).
|
||||
|
@@ -1,3 +1,8 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
sidebar_label: Step by Step
|
||||
---
|
||||
|
||||
# QMK Configurator: Step by Step
|
||||
|
||||
This page describes the steps for building your firmware in QMK Configurator.
|
||||
@@ -6,11 +11,19 @@ This page describes the steps for building your firmware in QMK Configurator.
|
||||
|
||||
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.
|
||||
:::tip
|
||||
|
||||
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!**
|
||||
:::caution
|
||||
|
||||
**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. <!-- FIXME(skullydazed): This feels too wordy and I'm not sure we want to encourage these kinds of issues. Also, should we prompt them to bug the manufacutrer? -->
|
||||
|
||||
@@ -18,13 +31,21 @@ If your keyboard has been advertised to be powered by QMK but is not in the list
|
||||
|
||||
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`.
|
||||
:::caution
|
||||
|
||||
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.
|
||||
:::tip
|
||||
|
||||
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
|
||||
|
||||
@@ -34,18 +55,30 @@ Keycode Entry is accomplished in one of 3 ways:
|
||||
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:
|
||||
:::tip
|
||||
|
||||
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.
|
||||
:::caution
|
||||
|
||||
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.
|
||||
:::caution
|
||||
|
||||
**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
|
||||
|
||||
|
@@ -1,3 +1,8 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
sidebar_label: Troubleshooting
|
||||
---
|
||||
|
||||
# Configurator Troubleshooting
|
||||
|
||||
## My .json file is not working
|
||||
|
@@ -79,7 +79,11 @@ The kerpleplork was intermittently failing with error code 23. The root cause wa
|
||||
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.
|
||||
:::caution
|
||||
|
||||
**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
|
||||
|
||||
@@ -101,7 +105,7 @@ enum my_keycodes {
|
||||
};
|
||||
```
|
||||
|
||||
### Previewing the Documentation :id=previewing-the-documentation
|
||||
### Previewing the Documentation {#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:
|
||||
|
||||
|
@@ -1,10 +1,15 @@
|
||||
---
|
||||
sidebar_position: 0
|
||||
sidebar_label: Customizing Functionality
|
||||
---
|
||||
|
||||
# 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
|
||||
## A Word on Core vs Keyboards vs Keymap {#a-word-on-core-vs-keyboards-vs-keymap}
|
||||
|
||||
We have structured QMK as a hierarchy:
|
||||
|
||||
@@ -34,7 +39,7 @@ enum my_keycodes {
|
||||
};
|
||||
```
|
||||
|
||||
## Programming the Behavior of Any Keycode :id=programming-the-behavior-of-any-keycode
|
||||
## Programming the Behavior of Any Keycode {#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.
|
||||
|
||||
@@ -98,7 +103,11 @@ These are the three main initialization functions, listed in the order that they
|
||||
* `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.
|
||||
:::caution
|
||||
|
||||
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
|
||||
|
||||
@@ -144,7 +153,7 @@ This is useful for setting up stuff that you may need elsewhere, but isn't hardw
|
||||
* Keyboard/Revision: `void matrix_init_kb(void)`
|
||||
* Keymap: `void matrix_init_user(void)`
|
||||
|
||||
### Low-level Matrix Overrides Function Documentation :id=low-level-matrix-overrides
|
||||
### Low-level Matrix Overrides Function Documentation {#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.
|
||||
@@ -283,7 +292,7 @@ void suspend_wakeup_init_user(void) {
|
||||
* 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
|
||||
# Deferred Execution {#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.
|
||||
|
||||
@@ -305,7 +314,11 @@ The second argument `cb_arg` is the same argument passed into `defer_exec()` bel
|
||||
|
||||
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.
|
||||
:::tip
|
||||
|
||||
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
|
||||
|
||||
@@ -349,14 +362,14 @@ If registrations fail, then you can increase this value in your keyboard or keym
|
||||
#define MAX_DEFERRED_EXECUTORS 16
|
||||
```
|
||||
|
||||
# Advanced topics :id=advanced-topics
|
||||
# Advanced topics {#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 {#layer-change-code}
|
||||
|
||||
[Layer change code](feature_layers.md#layer-change-code)
|
||||
|
||||
## Persistent Configuration (EEPROM) :id=persistent-configuration-eeprom
|
||||
## Persistent Configuration (EEPROM) {#persistent-configuration-eeprom}
|
||||
|
||||
[Persistent Configuration (EEPROM)](feature_eeprom.md)
|
||||
|
@@ -75,7 +75,7 @@ Whenever QMK generates a complete `info.json` it extracts information from `conf
|
||||
|
||||
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
|
||||
### Add code to generate it {#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:
|
||||
|
||||
|
@@ -25,22 +25,38 @@ You can have styled hint blocks drawn around text to draw attention to it.
|
||||
### Important
|
||||
|
||||
```
|
||||
!> This is important
|
||||
:::caution
|
||||
|
||||
This is important
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
Renders as:
|
||||
|
||||
!> This is important
|
||||
:::caution
|
||||
|
||||
This is important
|
||||
|
||||
:::
|
||||
|
||||
### General Tips
|
||||
|
||||
```
|
||||
?> This is a helpful tip.
|
||||
:::caution
|
||||
|
||||
This is a helpful tip.
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
Renders as:
|
||||
|
||||
?> This is a helpful tip.
|
||||
:::tip
|
||||
|
||||
This is a helpful tip.
|
||||
|
||||
:::
|
||||
|
||||
|
||||
# Documenting Features
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
This page documents the templates you should use when submitting new Keymaps and Keyboards to QMK.
|
||||
|
||||
## Keymap `readme.md` Template :id=keyboard-readmemd-template
|
||||
## Keymap `readme.md` Template {#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.
|
||||
|
||||
|
@@ -1,3 +1,8 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
sidebar_label: Driver Installation with Zadig
|
||||
---
|
||||
|
||||
# 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*.
|
||||
@@ -16,7 +21,11 @@ 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!
|
||||
:::caution
|
||||
|
||||
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.
|
||||
|
||||
@@ -40,7 +49,11 @@ Right-click each entry and hit **Uninstall device**. Make sure to tick **Delete
|
||||
|
||||
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.
|
||||
:::tip
|
||||
|
||||
A full reboot of your computer may sometimes be necessary at this point, to get Windows to pick up the new driver.
|
||||
|
||||
:::
|
||||
|
||||
## Uninstallation
|
||||
|
||||
@@ -60,7 +73,11 @@ Run `pnputil /delete-driver oemXX.inf /uninstall`. This will delete the driver a
|
||||
|
||||
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`.
|
||||
:::caution
|
||||
|
||||
**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
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# EEPROM Driver Configuration :id=eeprom-driver-configuration
|
||||
# EEPROM Driver Configuration {#eeprom-driver-configuration}
|
||||
|
||||
The EEPROM driver can be swapped out depending on the needs of the keyboard, or whether extra hardware is present.
|
||||
|
||||
@@ -12,17 +12,21 @@ Driver | Description
|
||||
`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
|
||||
## Vendor Driver Configuration {#vendor-eeprom-driver-configuration}
|
||||
|
||||
#### STM32 L0/L1 Configuration :id=stm32l0l1-eeprom-driver-configuration
|
||||
#### STM32 L0/L1 Configuration {#stm32l0l1-eeprom-driver-configuration}
|
||||
|
||||
!> Resetting EEPROM using an STM32L0/L1 device takes up to 1 second for every 1kB of internal EEPROM used.
|
||||
:::caution
|
||||
|
||||
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
|
||||
## I2C Driver Configuration {#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:
|
||||
|
||||
@@ -52,9 +56,13 @@ RM24C512C EEPROM | `#define EEPROM_I2C_RM24C512C` | <https://www.sparkfun.com/p
|
||||
24LC256 EEPROM | `#define EEPROM_I2C_24LC256` | <https://www.sparkfun.com/products/525>
|
||||
MB85RC256V FRAM | `#define EEPROM_I2C_MB85RC256V` | <https://www.adafruit.com/product/1895>
|
||||
|
||||
?> 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`.
|
||||
:::tip
|
||||
|
||||
## SPI Driver Configuration :id=spi-eeprom-driver-configuration
|
||||
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 {#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:
|
||||
|
||||
@@ -66,9 +74,13 @@ Currently QMK supports 25xx-series chips over SPI. As such, requires a working s
|
||||
`#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.
|
||||
:::caution
|
||||
|
||||
## Transient Driver configuration :id=transient-eeprom-driver-configuration
|
||||
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 {#transient-eeprom-driver-configuration}
|
||||
|
||||
The only configurable item for the transient EEPROM driver is its size:
|
||||
|
||||
@@ -78,13 +90,13 @@ The only configurable item for the transient EEPROM driver is its size:
|
||||
|
||||
Default values and extended descriptions can be found in `drivers/eeprom/eeprom_transient.h`.
|
||||
|
||||
## Wear-leveling Driver Configuration :id=wear_leveling-eeprom-driver-configuration
|
||||
## Wear-leveling Driver Configuration {#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
|
||||
# Wear-leveling Configuration {#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:
|
||||
|
||||
@@ -95,9 +107,13 @@ Driver | Description
|
||||
`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.
|
||||
:::caution
|
||||
|
||||
## Wear-leveling Embedded Flash Driver Configuration :id=wear_leveling-efl-driver-configuration
|
||||
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 {#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.
|
||||
|
||||
@@ -111,9 +127,13 @@ Configurable options in your keyboard's `config.h`:
|
||||
`#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.
|
||||
:::caution
|
||||
|
||||
## Wear-leveling SPI Flash Driver Configuration :id=wear_leveling-flash_spi-driver-configuration
|
||||
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 {#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.
|
||||
|
||||
@@ -127,9 +147,13 @@ Configurable options in your keyboard's `config.h`:
|
||||
`#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.
|
||||
:::caution
|
||||
|
||||
## Wear-leveling RP2040 Driver Configuration :id=wear_leveling-rp2040-driver-configuration
|
||||
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 {#wear_leveling-rp2040-driver-configuration}
|
||||
|
||||
This driver performs writes to the same underlying storage that the RP2040 executes its code.
|
||||
|
||||
@@ -143,7 +167,7 @@ Configurable options in your keyboard's `config.h`:
|
||||
`#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
|
||||
## Wear-leveling Legacy EEPROM Emulation Driver Configuration {#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.
|
||||
|
||||
|
@@ -1,6 +1,11 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
sidebar_label: Build/Compile QMK
|
||||
---
|
||||
|
||||
# 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.
|
||||
This page covers questions about building QMK. If you haven't yet done so, you should read the [Build Environment Setup](newbs_getting_started.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).
|
||||
@@ -17,7 +22,7 @@ or just:
|
||||
|
||||
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
|
||||
### Linux `udev` Rules {#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/`.
|
||||
|
||||
|
@@ -1,8 +1,13 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
sidebar_label: Debugging QMK
|
||||
---
|
||||
|
||||
# Debugging FAQ
|
||||
|
||||
This page details various common questions people have about troubleshooting their keyboards.
|
||||
|
||||
## Debugging :id=debugging
|
||||
## Debugging {#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.
|
||||
|
||||
@@ -32,7 +37,7 @@ Prefer a terminal based solution? The [QMK CLI console command](cli_commands.md#
|
||||
|
||||
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
|
||||
## Sending Your Own Debug Messages {#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:
|
||||
|
||||
|
@@ -1,3 +1,8 @@
|
||||
---
|
||||
sidebar_position: 0
|
||||
sidebar_label: General FAQ
|
||||
---
|
||||
|
||||
# Frequently Asked Questions
|
||||
|
||||
## What is QMK?
|
||||
|
@@ -1,6 +1,11 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
sidebar_label: Troubleshooting QMK
|
||||
---
|
||||
|
||||
# Miscellaneous FAQ
|
||||
|
||||
## How do I test my keyboard? :id=testing
|
||||
## How do I test my keyboard? {#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.
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# Modifier Keys :id=modifier-keys
|
||||
# Modifier Keys {#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.
|
||||
|
||||
@@ -26,7 +26,7 @@ These allow you to combine a modifier with a keycode. When pressed, the keydown
|
||||
|
||||
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
|
||||
# Checking Modifier State {#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).
|
||||
|
||||
@@ -77,11 +77,11 @@ Similarly, in addition to `get_oneshot_mods()`, there also exists these function
|
||||
* `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
|
||||
## Examples {#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
|
||||
### Alt + Escape for Alt + Tab {#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.
|
||||
|
||||
@@ -110,7 +110,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
};
|
||||
```
|
||||
|
||||
### Shift + Backspace for Delete :id=shift-backspace-for-delete
|
||||
### Shift + Backspace for Delete {#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.
|
||||
|
||||
@@ -162,26 +162,26 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
```
|
||||
Alternatively, this can be done with [Key Overrides](feature_key_overrides?id=simple-example).
|
||||
|
||||
# Advanced topics :id=advanced-topics
|
||||
# Advanced topics {#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 {#switching-and-toggling-layers}
|
||||
|
||||
* [Layers](feature_layers.md)
|
||||
|
||||
## Mod-Tap :id=mod-tap
|
||||
## Mod-Tap {#mod-tap}
|
||||
|
||||
* [Mod-Tap](mod_tap.md)
|
||||
|
||||
## One Shot Keys :id=one-shot-keys
|
||||
## One Shot Keys {#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-configuration-options}
|
||||
|
||||
* [Tap-Hold Configuration Options](tap_hold.md)
|
||||
|
||||
## Key Overrides :id=key-overrides
|
||||
## Key Overrides {#key-overrides}
|
||||
|
||||
* [Key Overrides](feature_key_overrides.md)
|
||||
|
@@ -167,7 +167,11 @@ The available keycodes for audio are:
|
||||
|`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.
|
||||
:::caution
|
||||
|
||||
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
|
||||
|
||||
|
@@ -1,3 +1,8 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
sidebar_label: Auto Shift
|
||||
---
|
||||
|
||||
# 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
|
||||
@@ -100,7 +105,11 @@ 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!
|
||||
:::tip
|
||||
|
||||
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`:
|
||||
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
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
|
||||
## How does it work? {#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.
|
||||
|
||||
@@ -12,7 +12,7 @@ The tricky part is how to efficiently check the buffer for typos. We don’t wan
|
||||
|
||||
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
|
||||
## How do I enable Autocorrection {#how-do-i-enable-autocorrection}
|
||||
|
||||
In your `rules.mk`, add this:
|
||||
|
||||
@@ -24,7 +24,7 @@ Additionally, you will need a library for autocorrection. A small sample librar
|
||||
|
||||
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
|
||||
## Customizing autocorrect library {#customizing-autocorrect-library}
|
||||
|
||||
To provide a custom library, you need to create a text file with the corrections. For instance:
|
||||
|
||||
@@ -66,7 +66,7 @@ static const uint8_t autocorrect_data[DICTIONARY_SIZE] PROGMEM = {85, 7, 0, 23,
|
||||
0};
|
||||
```
|
||||
|
||||
### Avoiding false triggers :id=avoiding-false-triggers
|
||||
### Avoiding false triggers {#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.”
|
||||
|
||||
@@ -82,7 +82,11 @@ The solution is to set a word break : before and/or after the typo to constrain
|
||||
|
||||
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.
|
||||
:::tip
|
||||
|
||||
Unfortunately, this is limited to just english words, at this point.
|
||||
|
||||
:::
|
||||
|
||||
## Overriding Autocorrect
|
||||
|
||||
@@ -96,7 +100,7 @@ This works because the autocorrection implementation doesn’t understand hotkey
|
||||
|
||||
Additionally, you can use the `AC_TOGG` keycode to toggle the on/off status for Autocorrect.
|
||||
|
||||
### Keycodes :id=keycodes
|
||||
### Keycodes {#keycodes}
|
||||
|
||||
|Keycode |Aliases |Description |
|
||||
|-----------------------|---------|----------------------------------------------|
|
||||
@@ -110,7 +114,11 @@ Additionally, you can use the `AC_TOGG` keycode to toggle the on/off status for
|
||||
|
||||
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`.
|
||||
:::tip
|
||||
|
||||
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.
|
||||
|
||||
@@ -194,7 +202,11 @@ bool process_autocorrect_user(uint16_t *keycode, keyrecord_t *record, uint8_t *t
|
||||
}
|
||||
```
|
||||
|
||||
?> 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.
|
||||
:::tip
|
||||
|
||||
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
|
||||
|
||||
@@ -221,9 +233,17 @@ bool apply_autocorrect(uint8_t backspaces, const char *str) {
|
||||
}
|
||||
```
|
||||
|
||||
?> 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.
|
||||
:::tip
|
||||
|
||||
!> ***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`.
|
||||
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.
|
||||
|
||||
:::
|
||||
|
||||
:::caution
|
||||
|
||||
***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`:
|
||||
|
||||
@@ -248,13 +268,13 @@ Additional user callback functions to manipulate Autocorrect:
|
||||
| `autocorrect_is_enabled()` | Returns true if Autocorrect is currently on. |
|
||||
|
||||
|
||||
## Appendix: Trie binary data format :id=appendix
|
||||
## Appendix: Trie binary data format {#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
|
||||
### Encoding {#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:
|
||||
|
||||
@@ -294,7 +314,7 @@ If we were to encode this chain using the same format used for branching nodes,
|
||||
+-------+-------+-------+-------+-------+-------+
|
||||
```
|
||||
|
||||
### Decoding :id=decoding
|
||||
### Decoding {#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.
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# Backlighting :id=backlighting
|
||||
# Backlighting {#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.
|
||||
|
||||
@@ -12,7 +12,7 @@ Most keyboards have backlighting enabled by default if they support it, but if i
|
||||
BACKLIGHT_ENABLE = yes
|
||||
```
|
||||
|
||||
## Keycodes :id=keycodes
|
||||
## Keycodes {#keycodes}
|
||||
|
||||
Once enabled, the following keycodes below can be used to change the backlight level.
|
||||
|
||||
@@ -26,7 +26,7 @@ Once enabled, the following keycodes below can be used to change the backlight l
|
||||
| `QK_BACKLIGHT_DOWN` | `BL_DOWN` | Decrease the backlight level |
|
||||
| `QK_BACKLIGHT_TOGGLE_BREATHING` | `BL_BRTG` | Toggle backlight breathing |
|
||||
|
||||
## Functions :id=functions
|
||||
## Functions {#functions}
|
||||
|
||||
These functions can be used to change the backlighting in custom code:
|
||||
|
||||
@@ -50,7 +50,7 @@ If backlight breathing is enabled (see below), the following functions are also
|
||||
|`breathing_enable()` |Turns on backlight breathing |
|
||||
|`breathing_disable()`|Turns off backlight breathing |
|
||||
|
||||
## Configuration :id=configuration
|
||||
## Configuration {#configuration}
|
||||
|
||||
To select which driver to use, configure your `rules.mk` with the following:
|
||||
|
||||
@@ -76,14 +76,14 @@ To configure the backlighting, `#define` these in your `config.h`:
|
||||
|
||||
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
|
||||
### Backlight On State {#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
|
||||
### AVR Driver {#avr-driver}
|
||||
|
||||
The `pwm` driver is configured by default, however the equivalent setting within `rules.mk` would be:
|
||||
|
||||
@@ -91,7 +91,7 @@ The `pwm` driver is configured by default, however the equivalent setting within
|
||||
BACKLIGHT_DRIVER = pwm
|
||||
```
|
||||
|
||||
#### Caveats :id=avr-caveats
|
||||
#### Caveats {#avr-caveats}
|
||||
|
||||
On AVR boards, QMK automatically decides which driver to use according to the following table:
|
||||
|
||||
@@ -121,7 +121,7 @@ All other pins will use timer-assisted software PWM:
|
||||
|
||||
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
|
||||
#### Hardware PWM Implementation {#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.
|
||||
@@ -130,7 +130,7 @@ In this way `OCRxx` essentially controls the duty cycle of the LEDs, and thus th
|
||||
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
|
||||
#### Timer Assisted PWM Implementation {#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.
|
||||
@@ -139,7 +139,7 @@ In this way `OCRxx` essentially controls the duty cycle of the LEDs, and thus th
|
||||
|
||||
The breathing effect is the same as in the hardware PWM implementation.
|
||||
|
||||
### ARM Driver :id=arm-configuration
|
||||
### ARM Driver {#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:
|
||||
|
||||
@@ -147,7 +147,7 @@ While still in its early stages, ARM backlight support aims to eventually have f
|
||||
BACKLIGHT_DRIVER = pwm
|
||||
```
|
||||
|
||||
#### ChibiOS Configuration :id=arm-configuration
|
||||
#### ChibiOS Configuration {#arm-configuration}
|
||||
|
||||
The following `#define`s apply only to ARM-based keyboards:
|
||||
|
||||
@@ -159,11 +159,11 @@ The following `#define`s apply only to ARM-based keyboards:
|
||||
|
||||
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
|
||||
#### Caveats {#arm-caveats}
|
||||
|
||||
Currently only hardware PWM is supported, not timer assisted, and does not provide automatic configuration.
|
||||
|
||||
### Software PWM Driver :id=software-pwm-driver
|
||||
### Software PWM Driver {#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`:
|
||||
|
||||
@@ -171,7 +171,7 @@ In this mode, PWM is "emulated" while running other keyboard tasks. It offers ma
|
||||
BACKLIGHT_DRIVER = software
|
||||
```
|
||||
|
||||
#### Multiple Backlight Pins :id=multiple-backlight-pins
|
||||
#### Multiple Backlight Pins {#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.
|
||||
@@ -184,7 +184,7 @@ To activate multiple backlight pins, add something like this to your `config.h`,
|
||||
#define BACKLIGHT_PINS { F5, B2 }
|
||||
```
|
||||
|
||||
### Custom Driver :id=custom-driver
|
||||
### Custom Driver {#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`:
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# Bootmagic Lite :id=bootmagic-lite
|
||||
# Bootmagic Lite {#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
|
||||
|
||||
@@ -19,7 +19,11 @@ By default, these are set to 0 and 0, which is usually the "ESC" key on a majori
|
||||
|
||||
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.
|
||||
:::caution
|
||||
|
||||
Using Bootmagic Lite will **always reset** the EEPROM, so you will lose any settings that have been saved.
|
||||
|
||||
:::
|
||||
|
||||
## Split Keyboards
|
||||
|
||||
@@ -51,7 +55,11 @@ If you pick the top right key for the right half, it is `R05` on the top layout.
|
||||
#define BOOTMAGIC_LITE_COLUMN_RIGHT 4
|
||||
```
|
||||
|
||||
?> These values are not set by default.
|
||||
:::tip
|
||||
|
||||
These values are not set by default.
|
||||
|
||||
:::
|
||||
|
||||
## Advanced Bootmagic Lite
|
||||
|
||||
|
@@ -32,7 +32,7 @@ a modern alternative to Caps Lock:
|
||||
shift](#configure-which-keys-are-word-breaking).
|
||||
|
||||
|
||||
## How do I enable Caps Word :id=how-do-i-enable-caps-word
|
||||
## How do I enable Caps Word {#how-do-i-enable-caps-word}
|
||||
|
||||
In your `rules.mk`, add:
|
||||
|
||||
@@ -65,7 +65,7 @@ Next, use one the following methods to activate Caps Word:
|
||||
combo](feature_combo.md) or [tap dance](feature_tap_dance.md) or any means
|
||||
you like.
|
||||
|
||||
### Troubleshooting: Command :id=troubleshooting-command
|
||||
### Troubleshooting: Command {#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
|
||||
@@ -88,9 +88,9 @@ by defining `IS_COMMAND()` in config.h:
|
||||
```
|
||||
|
||||
|
||||
## Customizing Caps Word :id=customizing-caps-word
|
||||
## Customizing Caps Word {#customizing-caps-word}
|
||||
|
||||
### Idle timeout :id=idle-timeout
|
||||
### Idle timeout {#idle-timeout}
|
||||
|
||||
Caps Word turns off automatically if no keys are pressed for
|
||||
`CAPS_WORD_IDLE_TIMEOUT` milliseconds. The default is 5000 (5 seconds).
|
||||
@@ -104,7 +104,7 @@ 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 {#functions}
|
||||
|
||||
Functions to manipulate Caps Word:
|
||||
|
||||
@@ -116,7 +116,7 @@ Functions to manipulate 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
|
||||
### Configure which keys are "word breaking" {#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
|
||||
@@ -151,7 +151,7 @@ bool caps_word_press_user(uint16_t keycode) {
|
||||
```
|
||||
|
||||
|
||||
### Representing Caps Word state :id=representing-caps-word-state
|
||||
### Representing Caps Word state {#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
|
||||
|
@@ -395,7 +395,11 @@ In addition to the keycodes, there are a few functions that you can use to set t
|
||||
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.
|
||||
:::caution
|
||||
|
||||
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:
|
||||
|
||||
|
@@ -41,7 +41,11 @@ qmk flash -c -kb keebio/bdn9/rev1 -km default -e CONVERT_TO=proton_c
|
||||
|
||||
You can also add the same `CONVERT_TO=<target>` 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.
|
||||
:::tip
|
||||
|
||||
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
|
||||
|
||||
@@ -105,7 +109,7 @@ Converter summary:
|
||||
| `helios` | `-e CONVERT_TO=helios` | `CONVERT_TO=helios` | `#ifdef CONVERT_TO_HELIOS` |
|
||||
| `michi` | `-e CONVERT_TO=michi` | `CONVERT_TO=michi` | `#ifdef CONVERT_TO_MICHI` |
|
||||
|
||||
### Proton C :id=proton_c
|
||||
### Proton C {#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`:
|
||||
|
||||
@@ -123,7 +127,7 @@ The following defaults are based on what has been implemented for STM32 boards.
|
||||
| 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
|
||||
### Adafruit KB2040 {#kb2040}
|
||||
|
||||
The following defaults are based on what has been implemented for [RP2040](platformdev_rp2040.md) boards.
|
||||
|
||||
@@ -134,11 +138,11 @@ The following defaults are based on what has been implemented for [RP2040](platf
|
||||
| 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
|
||||
### SparkFun Pro Micro - RP2040, Blok, Bit-C PRO and Michi {#promicro_rp2040 }
|
||||
|
||||
Currently identical to [Adafruit KB2040](#kb2040).
|
||||
|
||||
### STeMCell :id=stemcell
|
||||
### STeMCell {#stemcell}
|
||||
|
||||
Feature set currently identical to [Proton C](#proton_c).
|
||||
There are two versions of STeMCell available, with different pinouts:
|
||||
@@ -157,7 +161,7 @@ The following additional flags has to be used while compiling, based on the pin
|
||||
| D1 | -e STMC_IS=yes|
|
||||
| D0 | Not needed |
|
||||
|
||||
### Bonsai C4 :id=bonsai_c4
|
||||
### Bonsai C4 {#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`:
|
||||
|
||||
@@ -167,7 +171,7 @@ The Bonsai C4 only has one on-board LED (B2), and by default, both the Pro Micro
|
||||
#define B0 PAL_LINE(GPIOA, 9)
|
||||
```
|
||||
|
||||
### RP2040 Community Edition - Elite-Pi and Helios :id=rp2040_ce
|
||||
### RP2040 Community Edition - Elite-Pi and Helios {#rp2040_ce}
|
||||
|
||||
Feature set currently identical to [Adafruit KB2040](#kb2040).
|
||||
|
||||
@@ -194,10 +198,10 @@ Converter summary:
|
||||
| `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` |
|
||||
|
||||
### STeMCell :id=stemcell_elite
|
||||
### STeMCell {#stemcell_elite}
|
||||
|
||||
Currently identical to [STeMCell](#stemcell) with support for the additional bottom row of pins.
|
||||
|
||||
### RP2040 Community Edition :id=rp2040_ce_elite
|
||||
### RP2040 Community Edition {#rp2040_ce_elite}
|
||||
|
||||
Currently identical to [RP2040 Community Edition](#rp2040_ce), with support for the additional bottom row of pins.
|
||||
|
@@ -1,3 +1,8 @@
|
||||
---
|
||||
sidebar_position: 4
|
||||
sidebar_label: Debounce API
|
||||
---
|
||||
|
||||
# Contact bounce / contact chatter
|
||||
|
||||
Mechanical switches often don't have a clean single transition between pressed and unpressed states.
|
||||
@@ -99,7 +104,11 @@ Default debounce time is 5 milliseconds and it can be changed with the following
|
||||
```
|
||||
#define DEBOUNCE 10
|
||||
```
|
||||
?> Setting `DEBOUNCE` to `0` will disable this feature.
|
||||
:::tip
|
||||
|
||||
Setting `DEBOUNCE` to `0` will disable this feature.
|
||||
|
||||
:::
|
||||
|
||||
### Debounce Method
|
||||
|
||||
@@ -118,9 +127,17 @@ Name of algorithm is one of:
|
||||
| `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.
|
||||
:::tip
|
||||
|
||||
?> `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.
|
||||
`sym_defer_g` is the default if `DEBOUNCE_TYPE` is undefined.
|
||||
|
||||
:::
|
||||
|
||||
:::tip
|
||||
|
||||
`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
|
||||
|
||||
|
@@ -1,10 +1,10 @@
|
||||
# Digitizer :id=digitizer
|
||||
# Digitizer {#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
|
||||
## Usage {#usage}
|
||||
|
||||
Add the following to your `rules.mk`:
|
||||
|
||||
@@ -12,13 +12,17 @@ Add the following to your `rules.mk`:
|
||||
DIGITIZER_ENABLE = yes
|
||||
```
|
||||
|
||||
## Positioning :id=positioning
|
||||
## Positioning {#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.
|
||||
:::tip
|
||||
|
||||
## Examples :id=examples
|
||||
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 {#examples}
|
||||
|
||||
This example simply places the cursor in the middle of the screen:
|
||||
|
||||
@@ -40,13 +44,13 @@ digitizer_flush();
|
||||
`digitizer_state` is a struct of type `digitizer_t`.
|
||||
|
||||
|
||||
## API :id=api
|
||||
## API {#api}
|
||||
|
||||
### `struct digitizer_t` :id=api-digitizer-t
|
||||
### `struct digitizer_t` {#api-digitizer-t}
|
||||
|
||||
Contains the state of the digitizer.
|
||||
|
||||
#### Members :id=api-digitizer-t-members
|
||||
#### Members {#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).
|
||||
@@ -63,7 +67,7 @@ Contains the state of the digitizer.
|
||||
|
||||
---
|
||||
|
||||
### `void digitizer_flush(void)` :id=api-digitizer-flush
|
||||
### `void digitizer_flush(void)` {#api-digitizer-flush}
|
||||
|
||||
Send the digitizer report to the host if it is marked as dirty.
|
||||
|
||||
@@ -109,7 +113,7 @@ Deassert the barrel switch, and flush the report.
|
||||
|
||||
Set the absolute X and Y position of the digitizer contact, and flush the report.
|
||||
|
||||
#### Arguments :id=api-digitizer-set-position-arguments
|
||||
#### Arguments {#api-digitizer-set-position-arguments}
|
||||
|
||||
- `float x`
|
||||
The X value of the contact position, from 0 to 1.
|
||||
|
@@ -1,3 +1,8 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
sidebar_label: Dynamic Macros
|
||||
---
|
||||
|
||||
# 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.
|
||||
@@ -24,7 +29,11 @@ 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.
|
||||
:::tip
|
||||
|
||||
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
|
||||
|
||||
|
@@ -1,3 +1,8 @@
|
||||
---
|
||||
sidebar_position: 5
|
||||
sidebar_label: EEPROM
|
||||
---
|
||||
|
||||
# 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.
|
||||
|
@@ -67,9 +67,13 @@ Additionally, if one side does not have an encoder, you can specify `{}` for the
|
||||
#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.
|
||||
:::caution
|
||||
|
||||
## Encoder map :id=encoder-map
|
||||
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 {#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`:
|
||||
|
||||
@@ -90,7 +94,11 @@ const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][2] = {
|
||||
#endif
|
||||
```
|
||||
|
||||
?> This should only be enabled at the keymap level.
|
||||
:::tip
|
||||
|
||||
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`:
|
||||
|
||||
@@ -98,13 +106,21 @@ Using encoder mapping pumps events through the normal QMK keycode processing pip
|
||||
#define ENCODER_MAP_KEY_DELAY 10
|
||||
```
|
||||
|
||||
?> By default, the encoder map delay matches the value of `TAP_CODE_DELAY`.
|
||||
:::tip
|
||||
|
||||
By default, the encoder map delay matches the value of `TAP_CODE_DELAY`.
|
||||
|
||||
:::
|
||||
|
||||
## Callbacks
|
||||
|
||||
When not using `ENCODER_MAP_ENABLE = yes`, the callback functions can be inserted into your `<keyboard>.c`:
|
||||
|
||||
?> Those who are adding new keyboard support where encoders are enabled at the keyboard level should include basic encoder functionality at the keyboard level (`<keyboard>.c`) using the `encoder_update_kb()` function, that way it works for QMK Configuator users and exists in general.
|
||||
:::tip
|
||||
|
||||
Those who are adding new keyboard support where encoders are enabled at the keyboard level should include basic encoder functionality at the keyboard level (`<keyboard>.c`) using the `encoder_update_kb()` function, that way it works for QMK Configuator users and exists in general.
|
||||
|
||||
:::
|
||||
|
||||
```c
|
||||
bool encoder_update_kb(uint8_t index, bool clockwise) {
|
||||
@@ -149,7 +165,11 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
|
||||
}
|
||||
```
|
||||
|
||||
!> If you return `true` in the keymap level `_user` function, it will allow the keyboard 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.
|
||||
:::caution
|
||||
|
||||
If you return `true` in the keymap level `_user` function, it will allow the keyboard 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
|
||||
|
||||
|
@@ -1,10 +1,10 @@
|
||||
# Joystick :id=joystick
|
||||
# Joystick {#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
|
||||
## Usage {#usage}
|
||||
|
||||
Add the following to your `rules.mk`:
|
||||
|
||||
@@ -18,7 +18,7 @@ By default the joystick driver is `analog`, but you can change this with:
|
||||
JOYSTICK_DRIVER = digital
|
||||
```
|
||||
|
||||
## Configuration :id=configuration
|
||||
## Configuration {#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`:
|
||||
|
||||
@@ -31,9 +31,13 @@ By default, two axes and eight buttons are defined, with a reported resolution o
|
||||
#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.
|
||||
:::tip
|
||||
|
||||
### Axes :id=axes
|
||||
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 {#axes}
|
||||
|
||||
When defining axes for your joystick, you must provide a definition array typically in your `keymap.c`.
|
||||
|
||||
@@ -59,7 +63,7 @@ Axes can be configured using one of the following macros:
|
||||
|
||||
The `low` and `high` values can be swapped to effectively invert the axis.
|
||||
|
||||
#### Virtual Axes :id=virtual-axes
|
||||
#### Virtual Axes {#virtual-axes}
|
||||
|
||||
The following example adjusts two virtual axes (X and Y) based on keypad presses, with `KC_P0` as a precision modifier:
|
||||
|
||||
@@ -100,7 +104,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
}
|
||||
```
|
||||
|
||||
## Keycodes :id=keycodes
|
||||
## Keycodes {#keycodes}
|
||||
|
||||
|Key |Aliases|Description|
|
||||
|-----------------------|-------|-----------|
|
||||
@@ -137,13 +141,13 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
|`QK_JOYSTICK_BUTTON_30`|`JS_30`|Button 30 |
|
||||
|`QK_JOYSTICK_BUTTON_31`|`JS_31`|Button 31 |
|
||||
|
||||
## API :id=api
|
||||
## API {#api}
|
||||
|
||||
### `struct joystick_t` :id=api-joystick-t
|
||||
### `struct joystick_t` {#api-joystick-t}
|
||||
|
||||
Contains the state of the joystick.
|
||||
|
||||
#### Members :id=api-joystick-t-members
|
||||
#### Members {#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`.
|
||||
@@ -154,11 +158,11 @@ Contains the state of the joystick.
|
||||
|
||||
---
|
||||
|
||||
### `struct joystick_config_t` :id=api-joystick-config-t
|
||||
### `struct joystick_config_t` {#api-joystick-config-t}
|
||||
|
||||
Describes a single axis.
|
||||
|
||||
#### Members :id=api-joystick-config-t-members
|
||||
#### Members {#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`.
|
||||
@@ -175,52 +179,52 @@ Describes a single axis.
|
||||
|
||||
---
|
||||
|
||||
### `void joystick_flush(void)` :id=api-joystick-flush
|
||||
### `void joystick_flush(void)` {#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
|
||||
### `void register_joystick_button(uint8_t button)` {#api-register-joystick-button}
|
||||
|
||||
Set the state of a button, and flush the report.
|
||||
|
||||
#### Arguments :id=api-register-joystick-button-arguments
|
||||
#### Arguments {#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
|
||||
### `void unregister_joystick_button(uint8_t button)` {#api-unregister-joystick-button}
|
||||
|
||||
Reset the state of a button, and flush the report.
|
||||
|
||||
#### Arguments :id=api-unregister-joystick-button-arguments
|
||||
#### Arguments {#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
|
||||
### `int16_t joystick_read_axis(uint8_t axis)` {#api-joystick-read-axis}
|
||||
|
||||
Sample and process the analog value of the given axis.
|
||||
|
||||
#### Arguments :id=api-joystick-read-axis-arguments
|
||||
#### Arguments {#api-joystick-read-axis-arguments}
|
||||
|
||||
- `uint8_t axis`
|
||||
The axis to read.
|
||||
|
||||
#### Return Value :id=api-joystick-read-axis-return
|
||||
#### Return Value {#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
|
||||
### `void joystick_set_axis(uint8_t axis, int16_t value)` {#api-joystick-set-axis}
|
||||
|
||||
Set the value of the given axis.
|
||||
|
||||
#### Arguments :id=api-joystick-set-axis-arguments
|
||||
#### Arguments {#api-joystick-set-axis-arguments}
|
||||
|
||||
- `uint8_t axis`
|
||||
The axis to set the value of.
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# Key Overrides :id=key-overrides
|
||||
# Key Overrides {#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.
|
||||
|
||||
@@ -10,13 +10,13 @@ You can use key overrides in a similar way to momentary layer/fn keys to activat
|
||||
- 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
|
||||
## Setup {#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
|
||||
## Creating Key Overrides {#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:
|
||||
|
||||
@@ -34,7 +34,7 @@ Additionally takes a bitmask `options` that specifies additional options. See `k
|
||||
|
||||
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
|
||||
## Simple Example {#simple-example}
|
||||
|
||||
This shows how the mentioned example of sending `delete` when `shift` + `backspace` are pressed is realized:
|
||||
|
||||
@@ -48,9 +48,9 @@ const key_override_t **key_overrides = (const key_override_t *[]){
|
||||
};
|
||||
```
|
||||
|
||||
## Intermediate Difficulty Examples :id=intermediate-difficulty-examples
|
||||
## Intermediate Difficulty Examples {#intermediate-difficulty-examples}
|
||||
|
||||
### Media Controls & Screen Brightness :id=media-controls-amp-screen-brightness
|
||||
### Media Controls & Screen Brightness {#media-controls-amp-screen-brightness}
|
||||
|
||||
In this example a single key is configured to control media, volume and screen brightness by using key overrides.
|
||||
|
||||
@@ -102,7 +102,7 @@ const key_override_t **key_overrides = (const key_override_t *[]){
|
||||
};
|
||||
```
|
||||
|
||||
### Flexible macOS-friendly Grave Escape :id=flexible-macos-friendly-grave-escape
|
||||
### Flexible macOS-friendly Grave Escape {#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
|
||||
@@ -121,8 +121,8 @@ const key_override_t **key_overrides = (const key_override_t *[]){
|
||||
|
||||
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
|
||||
## Advanced Examples {#advanced-examples}
|
||||
### Modifiers as Layer Keys {#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.
|
||||
|
||||
@@ -150,7 +150,7 @@ const key_override_t fn_override = {.trigger_mods = MOD_BIT(KC_RGUI) |
|
||||
.enabled = NULL};
|
||||
```
|
||||
|
||||
## Keycodes :id=keycodes
|
||||
## Keycodes {#keycodes}
|
||||
|
||||
|Keycode |Aliases |Description |
|
||||
|------------------------|---------|----------------------|
|
||||
@@ -158,7 +158,7 @@ const key_override_t fn_override = {.trigger_mods = MOD_BIT(KC_RGUI) |
|
||||
|`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
|
||||
## Reference for `key_override_t` {#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`.
|
||||
|
||||
@@ -175,7 +175,7 @@ Advanced users may need more customization than what is offered by the simple `k
|
||||
| `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
|
||||
## Reference for `ko_option_t` {#reference-for-ko_option_t}
|
||||
|
||||
Bitfield with various options controlling the behavior of a key override.
|
||||
|
||||
@@ -189,11 +189,11 @@ Bitfield with various options controlling the behavior of a key override.
|
||||
| `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
|
||||
## For Advanced Users: Inner Workings {#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
|
||||
#### Activation {#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.
|
||||
|
||||
@@ -207,11 +207,11 @@ Use the `option` member to customize which of these events are allowed to activa
|
||||
|
||||
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
|
||||
#### Deactivation {#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
|
||||
#### Key Repeat Delay {#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.
|
||||
|
||||
@@ -222,6 +222,6 @@ This applies equally to releasing a modifier: When you hold `shift`, then press
|
||||
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
|
||||
## Difference to Combos {#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.
|
||||
|
@@ -1,10 +1,10 @@
|
||||
# Layers :id=layers
|
||||
# Layers {#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
|
||||
## Switching and Toggling Layers {#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.
|
||||
|
||||
@@ -17,7 +17,7 @@ These functions allow you to activate layers in various ways. Note that layers a
|
||||
* `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
|
||||
### Caveats {#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.
|
||||
|
||||
@@ -29,11 +29,11 @@ For a similar reason, the `layer` argument of `LM()` is also limited to layers 0
|
||||
|
||||
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
|
||||
## Working with Layers {#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
|
||||
### Beginners {#beginners}
|
||||
|
||||
If you are just getting started with QMK you will want to keep everything simple. Follow these guidelines when setting up your layers:
|
||||
|
||||
@@ -41,11 +41,11 @@ If you are just getting started with QMK you will want to keep everything simple
|
||||
* 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
|
||||
### Intermediate Users {#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
|
||||
### Advanced Users {#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.
|
||||
|
||||
@@ -53,7 +53,7 @@ Layers stack on top of each other in numerical order. When determining what a ke
|
||||
|
||||
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
|
||||
## Functions {#functions}
|
||||
|
||||
There are a number of functions (and variables) related to how you can use or manipulate the layers.
|
||||
|
||||
@@ -87,7 +87,11 @@ In addition to the functions that you can call, there are a number of callback f
|
||||
| `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.
|
||||
:::tip
|
||||
|
||||
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.
|
||||
|
||||
@@ -96,7 +100,7 @@ It is also possible to check the state of a particular layer using the following
|
||||
| `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
|
||||
## Layer Change Code {#layer-change-code}
|
||||
|
||||
This runs code every time that the layers get changed. This can be useful for layer indication, or custom layer handling.
|
||||
|
||||
|
@@ -1,3 +1,7 @@
|
||||
---
|
||||
sidebar_label: Community Layouts
|
||||
---
|
||||
|
||||
# Layouts: Using a Keymap with Multiple Keyboards
|
||||
|
||||
The `layouts/` folder contains different physical key layouts that can apply to different keyboards.
|
||||
|
@@ -1,8 +1,13 @@
|
||||
# The Leader Key: A New Kind of Modifier :id=the-leader-key
|
||||
---
|
||||
sidebar_position: 3
|
||||
sidebar_label: Leader Key
|
||||
---
|
||||
|
||||
# The Leader Key: A New Kind of Modifier {#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
|
||||
## Usage {#usage}
|
||||
|
||||
Add the following to your `rules.mk`:
|
||||
|
||||
@@ -12,7 +17,7 @@ LEADER_ENABLE = yes
|
||||
|
||||
Then add the `QK_LEAD` keycode to your keymap.
|
||||
|
||||
## Callbacks :id=callbacks
|
||||
## Callbacks {#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.
|
||||
|
||||
@@ -38,9 +43,9 @@ void leader_end_user(void) {
|
||||
}
|
||||
```
|
||||
|
||||
## Basic Configuration :id=basic-configuration
|
||||
## Basic Configuration {#basic-configuration}
|
||||
|
||||
### Timeout :id=timeout
|
||||
### Timeout {#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`:
|
||||
|
||||
@@ -48,7 +53,7 @@ This is the amount of time you have to complete a sequence once the leader key h
|
||||
#define LEADER_TIMEOUT 350
|
||||
```
|
||||
|
||||
### Per-Key Timeout :id=per-key-timeout
|
||||
### Per-Key Timeout {#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).
|
||||
|
||||
@@ -72,7 +77,7 @@ if (leader_sequence_three_keys(KC_C, KC_C, KC_C)) {
|
||||
}
|
||||
```
|
||||
|
||||
### Disabling Initial Timeout :id=disabling-initial-timeout
|
||||
### Disabling Initial Timeout {#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.
|
||||
|
||||
@@ -84,7 +89,7 @@ To remove the stress this situation produces to your hands, you can disable the
|
||||
|
||||
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
|
||||
### Strict Key Processing {#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.
|
||||
|
||||
@@ -96,7 +101,7 @@ To enable this, add the following to your `config.h`:
|
||||
#define LEADER_KEY_STRICT_KEY_PROCESSING
|
||||
```
|
||||
|
||||
## Example :id=example
|
||||
## Example {#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).
|
||||
|
||||
@@ -134,62 +139,62 @@ void leader_end_user(void) {
|
||||
}
|
||||
```
|
||||
|
||||
## Keycodes :id=keycodes
|
||||
## Keycodes {#keycodes}
|
||||
|
||||
|Key |Aliases |Description |
|
||||
|-----------------------|---------|-------------------------|
|
||||
|`QK_LEADER` |`QK_LEAD`|Begin the leader sequence|
|
||||
|
||||
## API :id=api
|
||||
## API {#api}
|
||||
|
||||
### `void leader_start_user(void)` :id=api-leader-start-user
|
||||
### `void leader_start_user(void)` {#api-leader-start-user}
|
||||
|
||||
User callback, invoked when the leader sequence begins.
|
||||
|
||||
---
|
||||
|
||||
### `void leader_end_user(void)` :id=api-leader-end-user
|
||||
### `void leader_end_user(void)` {#api-leader-end-user}
|
||||
|
||||
User callback, invoked when the leader sequence ends.
|
||||
|
||||
---
|
||||
|
||||
### `void leader_start(void)` :id=api-leader-start
|
||||
### `void leader_start(void)` {#api-leader-start}
|
||||
|
||||
Begin the leader sequence, resetting the buffer and timer.
|
||||
|
||||
---
|
||||
|
||||
### `void leader_end(void)` :id=api-leader-end
|
||||
### `void leader_end(void)` {#api-leader-end}
|
||||
|
||||
End the leader sequence.
|
||||
|
||||
---
|
||||
|
||||
### `bool leader_sequence_active(void)` :id=api-leader-sequence-active
|
||||
### `bool leader_sequence_active(void)` {#api-leader-sequence-active}
|
||||
|
||||
Whether the leader sequence is active.
|
||||
|
||||
---
|
||||
|
||||
### `bool leader_sequence_add(uint16_t keycode)` :id=api-leader-sequence-add
|
||||
### `bool leader_sequence_add(uint16_t keycode)` {#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
|
||||
#### Arguments {#api-leader-sequence-add-arguments}
|
||||
|
||||
- `uint16_t keycode`
|
||||
The keycode to add.
|
||||
|
||||
#### Return Value :id=api-leader-sequence-add-return
|
||||
#### Return Value {#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
|
||||
### `bool leader_sequence_timed_out(void)` {#api-leader-sequence-timed-out}
|
||||
|
||||
Whether the leader sequence has reached the timeout.
|
||||
|
||||
@@ -197,49 +202,49 @@ 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
|
||||
### `bool leader_reset_timer(void)` {#api-leader-reset-timer}
|
||||
|
||||
Reset the leader sequence timer.
|
||||
|
||||
---
|
||||
|
||||
### `bool leader_sequence_one_key(uint16_t kc)` :id=api-leader-sequence-one-key
|
||||
### `bool leader_sequence_one_key(uint16_t kc)` {#api-leader-sequence-one-key}
|
||||
|
||||
Check the sequence buffer for the given keycode.
|
||||
|
||||
#### Arguments :id=api-leader-sequence-one-key-arguments
|
||||
#### Arguments {#api-leader-sequence-one-key-arguments}
|
||||
|
||||
- `uint16_t kc`
|
||||
The keycode to check.
|
||||
|
||||
#### Return Value :id=api-leader-sequence-one-key-return
|
||||
#### Return Value {#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
|
||||
### `bool leader_sequence_two_keys(uint16_t kc1, uint16_t kc2)` {#api-leader-sequence-two-keys}
|
||||
|
||||
Check the sequence buffer for the given keycodes.
|
||||
|
||||
#### Arguments :id=api-leader-sequence-two-keys-arguments
|
||||
#### Arguments {#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
|
||||
#### Return Value {#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
|
||||
### `bool leader_sequence_three_keys(uint16_t kc1, uint16_t kc2, uint16_t kc3)` {#api-leader-sequence-three-keys}
|
||||
|
||||
Check the sequence buffer for the given keycodes.
|
||||
|
||||
#### Arguments :id=api-leader-sequence-three-keys-arguments
|
||||
#### Arguments {#api-leader-sequence-three-keys-arguments}
|
||||
|
||||
- `uint16_t kc1`
|
||||
The first keycode to check.
|
||||
@@ -248,17 +253,17 @@ Check the sequence buffer for the given keycodes.
|
||||
- `uint16_t kc3`
|
||||
The third keycode to check.
|
||||
|
||||
#### Return Value :id=api-leader-sequence-three-keys-return
|
||||
#### Return Value {#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
|
||||
### `bool leader_sequence_four_keys(uint16_t kc1, uint16_t kc2, uint16_t kc3, uint16_t kc4)` {#api-leader-sequence-four-keys}
|
||||
|
||||
Check the sequence buffer for the given keycodes.
|
||||
|
||||
#### Arguments :id=api-leader-sequence-four-keys-arguments
|
||||
#### Arguments {#api-leader-sequence-four-keys-arguments}
|
||||
|
||||
- `uint16_t kc1`
|
||||
The first keycode to check.
|
||||
@@ -269,17 +274,17 @@ Check the sequence buffer for the given keycodes.
|
||||
- `uint16_t kc4`
|
||||
The fourth keycode to check.
|
||||
|
||||
#### Return Value :id=api-leader-sequence-four-keys-return
|
||||
#### Return Value {#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
|
||||
### `bool leader_sequence_five_keys(uint16_t kc1, uint16_t kc2, uint16_t kc3, uint16_t kc4, uint16_t kc5)` {#api-leader-sequence-five-keys}
|
||||
|
||||
Check the sequence buffer for the given keycodes.
|
||||
|
||||
#### Arguments :id=api-leader-sequence-five-keys-arguments
|
||||
#### Arguments {#api-leader-sequence-five-keys-arguments}
|
||||
|
||||
- `uint16_t kc1`
|
||||
The first keycode to check.
|
||||
@@ -292,6 +297,6 @@ Check the sequence buffer for the given keycodes.
|
||||
- `uint16_t kc5`
|
||||
The fifth keycode to check.
|
||||
|
||||
#### Return Value :id=api-leader-sequence-five-keys-return
|
||||
#### Return Value {#api-leader-sequence-five-keys-return}
|
||||
|
||||
`true` if the sequence buffer matches.
|
||||
|
@@ -1,6 +1,10 @@
|
||||
# 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.
|
||||
:::tip
|
||||
|
||||
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:
|
||||
|
||||
@@ -15,7 +19,11 @@ There are three ways to get the lock LED state:
|
||||
* 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.
|
||||
:::caution
|
||||
|
||||
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`:
|
||||
|
||||
@@ -46,7 +54,11 @@ When the configuration options do not provide enough flexibility, the following
|
||||
|
||||
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.
|
||||
:::tip
|
||||
|
||||
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
|
||||
|
||||
|
@@ -1,12 +1,12 @@
|
||||
# LED Matrix Lighting :id=led-matrix-lighting
|
||||
# LED Matrix Lighting {#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
|
||||
## Driver configuration {#driver-configuration}
|
||||
---
|
||||
### IS31FL3731 :id=is31fl3731
|
||||
### IS31FL3731 {#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`:
|
||||
|
||||
@@ -47,7 +47,11 @@ Here is an example using 2 drivers.
|
||||
#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`.
|
||||
:::caution
|
||||
|
||||
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`.
|
||||
|
||||
@@ -68,7 +72,7 @@ const is31_led PROGMEM g_is31_leds[LED_MATRIX_LED_COUNT] = {
|
||||
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
|
||||
### IS31FLCOMMON {#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`:
|
||||
|
||||
@@ -132,7 +136,11 @@ Here is an example using 2 drivers.
|
||||
#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`.
|
||||
:::caution
|
||||
|
||||
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.
|
||||
|
||||
@@ -172,7 +180,7 @@ Where LED Index is the position of the LED in the `g_is31_leds` array. The `scal
|
||||
|
||||
---
|
||||
|
||||
## Common Configuration :id=common-configuration
|
||||
## Common Configuration {#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:
|
||||
|
||||
@@ -205,7 +213,7 @@ As mentioned earlier, the center of the keyboard by default is expected to be `{
|
||||
|
||||
`// 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
|
||||
## Flags {#flags}
|
||||
|
||||
|Define |Value |Description |
|
||||
|----------------------------|------|-------------------------------------------------|
|
||||
@@ -217,7 +225,7 @@ As mentioned earlier, the center of the keyboard by default is expected to be `{
|
||||
|`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
|
||||
## Keycodes {#keycodes}
|
||||
|
||||
All LED matrix keycodes are currently shared with the [Backlight feature](feature_backlight.md).
|
||||
|
||||
@@ -230,7 +238,7 @@ All LED matrix keycodes are currently shared with the [Backlight feature](featur
|
||||
| `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
|
||||
## LED Matrix Effects {#led-matrix-effects}
|
||||
|
||||
These are the effects that are currently available:
|
||||
|
||||
@@ -281,7 +289,11 @@ You can enable a single effect by defining `ENABLE_[EFFECT_NAME]` in your `confi
|
||||
|`#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.
|
||||
:::tip
|
||||
|
||||
These modes don't require any additional defines.
|
||||
|
||||
:::
|
||||
|
||||
|Reactive Defines |Description |
|
||||
|-------------------------------------------------------|----------------------------------------------|
|
||||
@@ -295,9 +307,13 @@ You can enable a single effect by defining `ENABLE_[EFFECT_NAME]` in your `confi
|
||||
|`#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.
|
||||
:::tip
|
||||
|
||||
## Custom LED Matrix Effects :id=custom-led-matrix-effects
|
||||
These modes also require the `LED_MATRIX_KEYPRESSES` or `LED_MATRIX_KEYRELEASES` define to be available.
|
||||
|
||||
:::
|
||||
|
||||
## Custom LED Matrix Effects {#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.
|
||||
|
||||
@@ -358,7 +374,7 @@ static bool my_cool_effect2(effect_params_t* params) {
|
||||
For inspiration and examples, check out the built-in effects under `quantum/led_matrix/animations/`.
|
||||
|
||||
|
||||
## Additional `config.h` Options :id=additional-configh-options
|
||||
## Additional `config.h` Options {#additional-configh-options}
|
||||
|
||||
```c
|
||||
#define LED_MATRIX_KEYPRESSES // reacts to keypresses
|
||||
@@ -376,7 +392,7 @@ For inspiration and examples, check out the built-in effects under `quantum/led_
|
||||
// If LED_MATRIX_KEYPRESSES or LED_MATRIX_KEYRELEASES is enabled, you also will want to enable SPLIT_TRANSPORT_MIRROR
|
||||
```
|
||||
|
||||
## EEPROM storage :id=eeprom-storage
|
||||
## EEPROM storage {#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), but could be configured to use its own 32bit address with:
|
||||
|
||||
@@ -386,13 +402,13 @@ The EEPROM for it is currently shared with the RGB Matrix system (it's generally
|
||||
|
||||
Where `28` is an unused index from `eeconfig.h`.
|
||||
|
||||
### Direct Operation :id=direct-operation
|
||||
### Direct Operation {#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
|
||||
### Disable/Enable Effects {#disable-enable-effects}
|
||||
|Function |Description |
|
||||
|--------------------------------------------|-------------|
|
||||
|`led_matrix_toggle()` |Toggle effect range LEDs between on and off |
|
||||
@@ -402,7 +418,7 @@ Where `28` is an unused index from `eeconfig.h`.
|
||||
|`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
|
||||
### Change Effect Mode {#change-effect-mode}
|
||||
|Function |Description |
|
||||
|--------------------------------------------|-------------|
|
||||
|`led_matrix_mode(mode)` |Set the mode, if LED animations are enabled |
|
||||
@@ -418,7 +434,7 @@ Where `28` is an unused index from `eeconfig.h`.
|
||||
|`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
|
||||
### Change Value {#change-value}
|
||||
|Function |Description |
|
||||
|--------------------------------------------|-------------|
|
||||
|`led_matrix_increase_val()` |Increase the value for effect range LEDs. This wraps around at maximum value |
|
||||
@@ -426,7 +442,7 @@ Where `28` is an unused index from `eeconfig.h`.
|
||||
|`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
|
||||
### Query Current Status {#query-current-status}
|
||||
|Function |Description |
|
||||
|---------------------------------|---------------------------|
|
||||
|`led_matrix_is_enabled()` |Gets current on/off status |
|
||||
@@ -435,9 +451,9 @@ Where `28` is an unused index from `eeconfig.h`.
|
||||
|`led_matrix_get_speed()` |Gets current speed |
|
||||
|`led_matrix_get_suspend_state()` |Gets current suspend state |
|
||||
|
||||
## Callbacks :id=callbacks
|
||||
## Callbacks {#callbacks}
|
||||
|
||||
### Indicators :id=indicators
|
||||
### Indicators {#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
|
||||
|
@@ -2,7 +2,11 @@
|
||||
|
||||
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.
|
||||
:::caution
|
||||
|
||||
**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
|
||||
|
||||
@@ -195,7 +199,11 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
};
|
||||
```
|
||||
|
||||
?> 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.
|
||||
:::tip
|
||||
|
||||
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
|
||||
|
||||
@@ -315,7 +323,11 @@ SEND_STRING(".."SS_TAP(X_END));
|
||||
|
||||
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.
|
||||
:::tip
|
||||
|
||||
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`
|
||||
|
||||
|
@@ -87,7 +87,11 @@ bool oled_task_user(void) {
|
||||
}
|
||||
```
|
||||
|
||||
?> 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/).
|
||||
:::tip
|
||||
|
||||
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
|
||||
@@ -184,21 +188,25 @@ These configuration options should be placed in `config.h`. Example:
|
||||
|Define |Default |Description |
|
||||
|---------------------|---------------|----------------------------------------------------------------------------------------------------------------------------------------|
|
||||
|`OLED_DISPLAY_128X64`|*Not defined* |Changes the display defines for use with 128x64 displays. |
|
||||
|`OLED_DISPLAY_CUSTOM`|*Not defined* |Changes the display defines for use with custom displays.<br>Requires user to implement the below defines. |
|
||||
|`OLED_DISPLAY_CUSTOM`|*Not defined* |Changes the display defines for use with custom displays.<br />Requires user to implement the below defines. |
|
||||
|`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.<br>`(OLED_DISPLAY_HEIGHT / 8 * OLED_DISPLAY_WIDTH)`. |
|
||||
|`OLED_MATRIX_SIZE` |`512` |The local buffer size to allocate.<br />`(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.<br>`(sizeof(OLED_BLOCK_TYPE) * 8)`. |
|
||||
|`OLED_BLOCK_SIZE` |`32` |The size of each block for dirty rendering<br>`(OLED_MATRIX_SIZE / OLED_BLOCK_COUNT)`. |
|
||||
|`OLED_COM_PINS` |`COM_PINS_SEQ` |How the SSD1306 chip maps it's memory to display.<br>Options are `COM_PINS_SEQ`, `COM_PINS_ALT`, `COM_PINS_SEQ_LR`, & `COM_PINS_ALT_LR`.|
|
||||
|`OLED_BLOCK_COUNT` |`16` |The number of blocks the display is divided into for dirty rendering.<br />`(sizeof(OLED_BLOCK_TYPE) * 8)`. |
|
||||
|`OLED_BLOCK_SIZE` |`32` |The size of each block for dirty rendering<br />`(OLED_MATRIX_SIZE / OLED_BLOCK_COUNT)`. |
|
||||
|`OLED_COM_PINS` |`COM_PINS_SEQ` |How the SSD1306 chip maps it's memory to display.<br />Options are `COM_PINS_SEQ`, `COM_PINS_ALT`, `COM_PINS_SEQ_LR`, & `COM_PINS_ALT_LR`.|
|
||||
|`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
|
||||
|
||||
!> Rotation is unsupported on the SH1106.
|
||||
:::caution
|
||||
|
||||
Rotation is unsupported on the SH1106.
|
||||
|
||||
:::
|
||||
|
||||
```c
|
||||
// OLED Rotation enum values are flags
|
||||
@@ -386,7 +394,11 @@ uint8_t oled_max_chars(void);
|
||||
uint8_t oled_max_lines(void);
|
||||
```
|
||||
|
||||
!> Scrolling and rotation are unsupported on the SH1106.
|
||||
:::caution
|
||||
|
||||
Scrolling and rotation are unsupported on the SH1106.
|
||||
|
||||
:::
|
||||
|
||||
## SSD1306.h Driver Conversion Guide
|
||||
|
||||
|
@@ -29,9 +29,13 @@ enum {
|
||||
} os_variant_t;
|
||||
```
|
||||
|
||||
?> Note that it takes some time after firmware is booted to detect the OS.
|
||||
:::caution
|
||||
|
||||
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.
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# Pointing Device :id=pointing-device
|
||||
# Pointing Device {#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.
|
||||
|
||||
@@ -279,7 +279,11 @@ 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.
|
||||
:::caution
|
||||
|
||||
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
|
||||
|
||||
@@ -300,11 +304,19 @@ void pointing_device_driver_set_cpi(uint16_t cpi) {}
|
||||
| `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.
|
||||
:::caution
|
||||
|
||||
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.
|
||||
:::caution
|
||||
|
||||
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
|
||||
|
||||
@@ -321,7 +333,11 @@ The following configuration options are only available when using `SPLIT_POINTIN
|
||||
| `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.
|
||||
:::caution
|
||||
|
||||
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
|
||||
@@ -569,11 +585,15 @@ If you are having issues with pointing device drivers debug messages can be enab
|
||||
#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).
|
||||
:::tip
|
||||
|
||||
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
|
||||
# Automatic Mouse Layer {#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.
|
||||
|
||||
|
@@ -1,12 +1,16 @@
|
||||
# Programmable Button :id=programmable-button
|
||||
# Programmable Button {#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.
|
||||
:::tip
|
||||
|
||||
## Usage :id=usage
|
||||
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 {#usage}
|
||||
|
||||
Add the following to your `rules.mk`:
|
||||
|
||||
@@ -14,7 +18,7 @@ Add the following to your `rules.mk`:
|
||||
PROGRAMMABLE_BUTTON_ENABLE = yes
|
||||
```
|
||||
|
||||
## Keycodes :id=keycodes
|
||||
## Keycodes {#keycodes}
|
||||
|
||||
|Key |Aliases|Description |
|
||||
|---------------------------|-------|----------------------|
|
||||
@@ -51,94 +55,94 @@ PROGRAMMABLE_BUTTON_ENABLE = yes
|
||||
|`QK_PROGRAMMABLE_BUTTON_31`|`PB_31`|Programmable button 31|
|
||||
|`QK_PROGRAMMABLE_BUTTON_32`|`PB_32`|Programmable button 32|
|
||||
|
||||
## API :id=api
|
||||
## API {#api}
|
||||
|
||||
### `void programmable_button_clear(void)` :id=api-programmable-button-clear
|
||||
### `void programmable_button_clear(void)` {#api-programmable-button-clear}
|
||||
|
||||
Clear the programmable button report.
|
||||
|
||||
---
|
||||
|
||||
### `void programmable_button_add(uint8_t index)` :id=api-programmable-button-add
|
||||
### `void programmable_button_add(uint8_t index)` {#api-programmable-button-add}
|
||||
|
||||
Set the state of a button.
|
||||
|
||||
#### Arguments :id=api-programmable-button-add-arguments
|
||||
#### Arguments {#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
|
||||
### `void programmable_button_remove(uint8_t index)` {#api-programmable-button-remove}
|
||||
|
||||
Reset the state of a button.
|
||||
|
||||
#### Arguments :id=api-programmable-button-remove-arguments
|
||||
#### Arguments {#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
|
||||
### `void programmable_button_register(uint8_t index)` {#api-programmable-button-register}
|
||||
|
||||
Set the state of a button, and flush the report.
|
||||
|
||||
#### Arguments :id=api-programmable-button-register-arguments
|
||||
#### Arguments {#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
|
||||
### `void programmable_button_unregister(uint8_t index)` {#api-programmable-button-unregister}
|
||||
|
||||
Reset the state of a button, and flush the report.
|
||||
|
||||
#### Arguments :id=api-programmable-button-unregister-arguments
|
||||
#### Arguments {#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
|
||||
### `bool programmable_button_is_on(uint8_t index)` {#api-programmable-button-is-on}
|
||||
|
||||
Get the state of a button.
|
||||
|
||||
#### Arguments :id=api-programmable-button-is-on-arguments
|
||||
#### Arguments {#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
|
||||
#### Return Value {#api-programmable-button-is-on-return}
|
||||
|
||||
`true` if the button is pressed.
|
||||
|
||||
---
|
||||
|
||||
### `void programmable_button_flush(void)` :id=api-programmable-button-flush
|
||||
### `void programmable_button_flush(void)` {#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
|
||||
### `uint32_t programmable_button_get_report(void)` {#api-programmable-button-get-report}
|
||||
|
||||
Get the programmable button report.
|
||||
|
||||
#### Return Value :id=api-programmable-button-get-report-return
|
||||
#### Return Value {#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
|
||||
### `void programmable_button_set_report(uint32_t report)` {#api-programmable-button-set-report}
|
||||
|
||||
Set the programmable button report.
|
||||
|
||||
#### Arguments :id=api-programmable-button-set-report-arguments
|
||||
#### Arguments {#api-programmable-button-set-report-arguments}
|
||||
|
||||
- `uint32_t report`
|
||||
A bitmask of programmable button states.
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# PS/2 Mouse Support :id=ps2-mouse-support
|
||||
# PS/2 Mouse Support {#ps2-mouse-support}
|
||||
|
||||
Its possible to hook up a PS/2 mouse (for example touchpads or trackpoints) to your keyboard as a composite device.
|
||||
|
||||
@@ -6,7 +6,7 @@ To hook up a Trackpoint, you need to obtain a Trackpoint module (i.e. harvest fr
|
||||
|
||||
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
|
||||
## The Circuitry between Trackpoint and Controller {#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+.
|
||||
|
||||
@@ -24,7 +24,7 @@ MODULE 5+ --------+--+--------- PWR CONTROLLER
|
||||
```
|
||||
|
||||
|
||||
## Busywait Version :id=busywait-version
|
||||
## Busywait Version {#busywait-version}
|
||||
|
||||
Note: This is not recommended, you may encounter jerky movement or unsent inputs. Please use interrupt or USART version if possible.
|
||||
|
||||
@@ -45,7 +45,7 @@ In your keyboard config.h:
|
||||
#endif
|
||||
```
|
||||
|
||||
### Interrupt Version (AVR/ATMega32u4) :id=interrupt-version-avr
|
||||
### Interrupt Version (AVR/ATMega32u4) {#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.
|
||||
|
||||
@@ -78,7 +78,7 @@ In your keyboard config.h:
|
||||
#endif
|
||||
```
|
||||
|
||||
### Interrupt Version (ARM chibios) :id=interrupt-version-chibios
|
||||
### Interrupt Version (ARM chibios) {#interrupt-version-chibios}
|
||||
|
||||
Pretty much any two pins can be used for the (software) interrupt variant on ARM cores. The example below uses A8 for clock, and A9 for data.
|
||||
|
||||
@@ -103,7 +103,7 @@ And in the chibios specifig halconf.h:
|
||||
```
|
||||
|
||||
|
||||
### USART Version :id=usart-version
|
||||
### USART Version {#usart-version}
|
||||
|
||||
To use USART on the ATMega32u4, you have to use PD5 for clock and PD2 for data. If one of those are unavailable, you need to use interrupt version.
|
||||
|
||||
@@ -155,9 +155,9 @@ In your keyboard config.h:
|
||||
#endif
|
||||
```
|
||||
|
||||
## Additional Settings :id=additional-settings
|
||||
## Additional Settings {#additional-settings}
|
||||
|
||||
### PS/2 Mouse Features :id=ps2-mouse-features
|
||||
### PS/2 Mouse Features {#ps2-mouse-features}
|
||||
|
||||
These enable settings supported by the PS/2 mouse protocol.
|
||||
|
||||
@@ -198,7 +198,7 @@ void ps2_mouse_set_resolution(ps2_mouse_resolution_t resolution);
|
||||
void ps2_mouse_set_sample_rate(ps2_mouse_sample_rate_t sample_rate);
|
||||
```
|
||||
|
||||
### Fine Control :id=fine-control
|
||||
### Fine Control {#fine-control}
|
||||
|
||||
Use the following defines to change the sensitivity and speed of the mouse.
|
||||
Note: you can also use `ps2_mouse_set_resolution` for the same effect (not supported on most touchpads).
|
||||
@@ -209,7 +209,7 @@ Note: you can also use `ps2_mouse_set_resolution` for the same effect (not suppo
|
||||
#define PS2_MOUSE_V_MULTIPLIER 1
|
||||
```
|
||||
|
||||
### Scroll Button :id=scroll-button
|
||||
### Scroll Button {#scroll-button}
|
||||
|
||||
If you're using a trackpoint, you will likely want to be able to use it for scrolling.
|
||||
It's possible to enable a "scroll button/s" that when pressed will cause the mouse to scroll instead of moving.
|
||||
@@ -256,7 +256,7 @@ Fine control over the scrolling is supported with the following defines:
|
||||
#define PS2_MOUSE_SCROLL_DIVISOR_V 2
|
||||
```
|
||||
|
||||
### Invert Mouse buttons :id=invert-buttons
|
||||
### Invert Mouse buttons {#invert-buttons}
|
||||
|
||||
To invert the left & right buttons you can put:
|
||||
|
||||
@@ -266,7 +266,7 @@ To invert the left & right buttons you can put:
|
||||
|
||||
into config.h.
|
||||
|
||||
### Invert Mouse and Scroll Axes :id=invert-mouse-and-scroll-axes
|
||||
### Invert Mouse and Scroll Axes {#invert-mouse-and-scroll-axes}
|
||||
|
||||
To invert the X and Y axes you can put:
|
||||
|
||||
@@ -286,7 +286,7 @@ To reverse the scroll axes you can put:
|
||||
|
||||
into config.h.
|
||||
|
||||
### Rotate Mouse Axes :id=rotate-mouse-axes
|
||||
### Rotate Mouse Axes {#rotate-mouse-axes}
|
||||
|
||||
Transform the output of the device with a clockwise rotation of 90, 180, or 270
|
||||
degrees.
|
||||
@@ -305,7 +305,7 @@ be North-facing, compensate as follows:
|
||||
#define PS2_MOUSE_ROTATE 90 /* Compensate for West-facing device orientation. */
|
||||
```
|
||||
|
||||
### Debug Settings :id=debug-settings
|
||||
### Debug Settings {#debug-settings}
|
||||
|
||||
To debug the mouse, add `debug_mouse = true` or enable via bootmagic.
|
||||
|
||||
@@ -315,7 +315,7 @@ To debug the mouse, add `debug_mouse = true` or enable via bootmagic.
|
||||
#define PS2_MOUSE_DEBUG_RAW
|
||||
```
|
||||
|
||||
### Movement Hook :id=movement-hook
|
||||
### Movement Hook {#movement-hook}
|
||||
|
||||
Process mouse movement in the keymap before it is sent to the host. Example
|
||||
uses include filtering noise, adding acceleration, and automatically activating
|
||||
|
@@ -1,12 +1,12 @@
|
||||
# RGB Matrix Lighting :id=rgb-matrix-lighting
|
||||
# RGB Matrix Lighting {#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
|
||||
## Driver configuration {#driver-configuration}
|
||||
---
|
||||
### IS31FL3731 :id=is31fl3731
|
||||
### IS31FL3731 {#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`:
|
||||
|
||||
@@ -48,7 +48,11 @@ Here is an example using 2 drivers.
|
||||
#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`.
|
||||
:::caution
|
||||
|
||||
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`.
|
||||
|
||||
@@ -70,7 +74,7 @@ const is31_led PROGMEM g_is31_leds[RGB_MATRIX_LED_COUNT] = {
|
||||
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
|
||||
### IS31FL3733 {#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`:
|
||||
|
||||
@@ -134,7 +138,11 @@ Here is an example using 2 drivers.
|
||||
#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`.
|
||||
:::caution
|
||||
|
||||
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.
|
||||
|
||||
@@ -156,7 +164,7 @@ const is31_led PROGMEM g_is31_leds[RGB_MATRIX_LED_COUNT] = {
|
||||
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).
|
||||
|
||||
---
|
||||
### IS31FL3737 :id=is31fl3737
|
||||
### IS31FL3737 {#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`:
|
||||
|
||||
@@ -216,7 +224,11 @@ Here is an example using 2 drivers.
|
||||
#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`.
|
||||
:::caution
|
||||
|
||||
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 2 drivers are supported, but it would be trivial to support all 4 combinations.
|
||||
|
||||
@@ -238,7 +250,7 @@ const is31_led PROGMEM g_is31_leds[RGB_MATRIX_LED_COUNT] = {
|
||||
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
|
||||
### IS31FLCOMMON {#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`:
|
||||
|
||||
@@ -305,7 +317,11 @@ Here is an example using 2 drivers.
|
||||
#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`.
|
||||
:::caution
|
||||
|
||||
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.
|
||||
|
||||
@@ -348,7 +364,7 @@ Where LED Index is the position of the LED in the `g_is31_leds` array. The `scal
|
||||
|
||||
---
|
||||
|
||||
### WS2812 :id=ws2812
|
||||
### WS2812 {#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`:
|
||||
|
||||
@@ -366,11 +382,15 @@ Configure the hardware via your `config.h`:
|
||||
#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.
|
||||
:::tip
|
||||
|
||||
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
|
||||
### APA102 {#apa102}
|
||||
|
||||
There is basic support for APA102 based addressable LED strands. To enable it, add this to your `rules.mk`:
|
||||
|
||||
@@ -391,7 +411,7 @@ Configure the hardware via your `config.h`:
|
||||
```
|
||||
|
||||
---
|
||||
### AW20216 :id=aw20216
|
||||
### AW20216 {#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
|
||||
@@ -431,7 +451,11 @@ Here is an example using 2 drivers.
|
||||
#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`.
|
||||
:::caution
|
||||
|
||||
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 `<keyboard>.c`:
|
||||
|
||||
@@ -462,7 +486,7 @@ const aw_led PROGMEM g_aw_leds[RGB_MATRIX_LED_COUNT] = {
|
||||
|
||||
---
|
||||
|
||||
## Common Configuration :id=common-configuration
|
||||
## Common Configuration {#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:
|
||||
|
||||
@@ -495,7 +519,7 @@ As mentioned earlier, the center of the keyboard by default is expected to be `{
|
||||
|
||||
`// 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
|
||||
## Flags {#flags}
|
||||
|
||||
|Define |Value |Description |
|
||||
|----------------------------|------|-------------------------------------------------|
|
||||
@@ -508,7 +532,7 @@ As mentioned earlier, the center of the keyboard by default is expected to be `{
|
||||
|`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
|
||||
## Keycodes {#keycodes}
|
||||
|
||||
All RGB keycodes are currently shared with the RGBLIGHT system:
|
||||
|
||||
@@ -534,12 +558,20 @@ All RGB keycodes are currently shared with the RGBLIGHT 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.
|
||||
:::tip
|
||||
|
||||
`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.
|
||||
:::caution
|
||||
|
||||
## RGB Matrix Effects :id=rgb-matrix-effects
|
||||
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 {#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:
|
||||
|
||||
@@ -633,14 +665,22 @@ You can enable a single effect by defining `ENABLE_[EFFECT_NAME]` in your `confi
|
||||
|`#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.
|
||||
:::tip
|
||||
|
||||
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.
|
||||
:::tip
|
||||
|
||||
These modes also require the `RGB_MATRIX_FRAMEBUFFER_EFFECTS` define to be available.
|
||||
|
||||
:::
|
||||
|
||||
|Reactive Defines |Description |
|
||||
|------------------------------------------------------|----------------------------------------------|
|
||||
@@ -657,10 +697,14 @@ You can enable a single effect by defining `ENABLE_[EFFECT_NAME]` in your `confi
|
||||
|`#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.
|
||||
:::tip
|
||||
|
||||
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
|
||||
### RGB Matrix Effect Typing Heatmap {#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.
|
||||
|
||||
@@ -690,7 +734,7 @@ Remove the spread effect entirely.
|
||||
#define RGB_MATRIX_TYPING_HEATMAP_SLIM
|
||||
```
|
||||
|
||||
### RGB Matrix Effect Solid Reactive :id=rgb-matrix-effect-solid-reactive
|
||||
### RGB Matrix Effect Solid Reactive {#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:
|
||||
|
||||
@@ -700,11 +744,15 @@ Solid reactive effects will pulse RGB light on key presses with user configurabl
|
||||
|
||||
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
|
||||
## Custom RGB Matrix Effects {#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`.
|
||||
:::tip
|
||||
|
||||
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:
|
||||
|
||||
@@ -758,7 +806,7 @@ static bool my_cool_effect2(effect_params_t* params) {
|
||||
For inspiration and examples, check out the built-in effects under `quantum/rgb_matrix/animations/`.
|
||||
|
||||
|
||||
## Colors :id=colors
|
||||
## Colors {#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.
|
||||
|
||||
@@ -787,7 +835,7 @@ These are shorthands to popular colors. The `RGB` ones can be passed to the `set
|
||||
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
|
||||
## Additional `config.h` Options {#additional-configh-options}
|
||||
|
||||
```c
|
||||
#define RGB_MATRIX_KEYPRESSES // reacts to keypresses
|
||||
@@ -809,7 +857,7 @@ These are defined in [`color.h`](https://github.com/qmk/qmk_firmware/blob/master
|
||||
#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
|
||||
## EEPROM storage {#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), but could be configured to use its own 32bit address with:
|
||||
|
||||
@@ -819,15 +867,15 @@ The EEPROM for it is currently shared with the LED Matrix system (it's generally
|
||||
|
||||
Where `28` is an unused index from `eeconfig.h`.
|
||||
|
||||
## Functions :id=functions
|
||||
## Functions {#functions}
|
||||
|
||||
### Direct Operation :id=direct-operation
|
||||
### Direct Operation {#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
|
||||
### Disable/Enable Effects {#disable-enable-effects}
|
||||
|Function |Description |
|
||||
|--------------------------------------------|-------------|
|
||||
|`rgb_matrix_toggle()` |Toggle effect range LEDs between on and off |
|
||||
@@ -837,7 +885,7 @@ Where `28` is an unused index from `eeconfig.h`.
|
||||
|`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
|
||||
### Change Effect Mode {#change-effect-mode}
|
||||
|Function |Description |
|
||||
|--------------------------------------------|-------------|
|
||||
|`rgb_matrix_mode(mode)` |Set the mode, if RGB animations are enabled |
|
||||
@@ -854,7 +902,7 @@ Where `28` is an unused index from `eeconfig.h`.
|
||||
|`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
|
||||
### Change Color {#change-color}
|
||||
|Function |Description |
|
||||
|--------------------------------------------|-------------|
|
||||
|`rgb_matrix_increase_hue()` |Increase the hue for effect range LEDs. This wraps around at maximum hue |
|
||||
@@ -872,7 +920,7 @@ Where `28` is an unused index from `eeconfig.h`.
|
||||
|`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
|
||||
### Query Current Status {#query-current-status}
|
||||
|Function |Description |
|
||||
|---------------------------------|---------------------------|
|
||||
|`rgb_matrix_is_enabled()` |Gets current on/off status |
|
||||
@@ -884,9 +932,9 @@ Where `28` is an unused index from `eeconfig.h`.
|
||||
|`rgb_matrix_get_speed()` |Gets current speed |
|
||||
|`rgb_matrix_get_suspend_state()` |Gets current suspend state |
|
||||
|
||||
## Callbacks :id=callbacks
|
||||
## Callbacks {#callbacks}
|
||||
|
||||
### Indicators :id=indicators
|
||||
### Indicators {#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
|
||||
@@ -908,7 +956,7 @@ bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {
|
||||
}
|
||||
```
|
||||
|
||||
### Indicator Examples :id=indicator-examples
|
||||
### Indicator Examples {#indicator-examples}
|
||||
|
||||
Caps Lock indicator on alphanumeric flagged keys:
|
||||
```c
|
||||
@@ -964,9 +1012,13 @@ bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {
|
||||
}
|
||||
```
|
||||
|
||||
?> 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.
|
||||
:::tip
|
||||
|
||||
#### Examples :id=indicator-examples
|
||||
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 {#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).
|
||||
|
||||
@@ -1007,7 +1059,11 @@ bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {
|
||||
}
|
||||
```
|
||||
|
||||
?> 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.
|
||||
:::tip
|
||||
|
||||
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
|
||||
|
||||
|
@@ -22,7 +22,11 @@ On keyboards with onboard RGB LEDs, it is usually enabled by default. If it is n
|
||||
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.
|
||||
:::tip
|
||||
|
||||
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`:
|
||||
|
||||
@@ -48,9 +52,9 @@ QMK uses [Hue, Saturation, and Value](https://en.wikipedia.org/wiki/HSL_and_HSV)
|
||||
|
||||
<img src="gitbook/images/color-wheel.svg" alt="HSV Color Wheel" width="250"/>
|
||||
|
||||
Changing the **Hue** cycles around the circle.<br>
|
||||
Changing the **Saturation** moves between the inner and outer sections of the wheel, affecting the intensity of the color.<br>
|
||||
Changing the **Value** sets the overall brightness.<br>
|
||||
Changing the **Hue** cycles around the circle.<br />
|
||||
Changing the **Saturation** moves between the inner and outer sections of the wheel, affecting the intensity of the color.<br />
|
||||
Changing the **Value** sets the overall brightness.<br />
|
||||
|
||||

|
||||
|
||||
@@ -78,10 +82,18 @@ Changing the **Value** sets the overall brightness.<br>
|
||||
|`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.
|
||||
:::tip
|
||||
|
||||
`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.
|
||||
:::caution
|
||||
|
||||
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
|
||||
|
||||
@@ -144,7 +156,11 @@ Use these defines to add or remove animations from the firmware. When you are ru
|
||||
|`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.
|
||||
:::caution
|
||||
|
||||
`RGBLIGHT_ANIMATIONS` is being deprecated and animation modes should be explicitly defined.
|
||||
|
||||
:::
|
||||
|
||||
### Effect and Animation Settings
|
||||
|
||||
@@ -207,12 +223,16 @@ 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.
|
||||
:::tip
|
||||
|
||||
**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
|
||||
### Defining Lighting Layers {#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.
|
||||
|
||||
@@ -257,7 +277,7 @@ void keyboard_post_init_user(void) {
|
||||
```
|
||||
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
|
||||
### Enabling and disabling lighting layers {#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:
|
||||
@@ -280,7 +300,7 @@ layer_state_t layer_state_set_user(layer_state_t state) {
|
||||
}
|
||||
```
|
||||
|
||||
### Lighting layer blink :id=lighting-layer-blink
|
||||
### Lighting layer blink {#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
|
||||
@@ -340,7 +360,11 @@ 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.
|
||||
:::caution
|
||||
|
||||
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
|
||||
|
||||
|
@@ -2,7 +2,11 @@
|
||||
|
||||
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.
|
||||
:::tip
|
||||
|
||||
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
|
||||
|
||||
|
@@ -4,7 +4,11 @@ The Send String API is part of QMK's macro system. It allows for sequences of ke
|
||||
|
||||
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.
|
||||
:::tip
|
||||
|
||||
Unicode characters are **not** supported with this API -- see the [Unicode](feature_unicode.md) feature instead.
|
||||
|
||||
:::
|
||||
|
||||
## Usage
|
||||
|
||||
|
@@ -2,7 +2,11 @@
|
||||
|
||||
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.
|
||||
:::caution
|
||||
|
||||
**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
|
||||
|
||||
|
@@ -1,3 +1,8 @@
|
||||
---
|
||||
sidebar_position: 8
|
||||
sidebar_label: Space Cadet Shift
|
||||
---
|
||||
|
||||
# Space Cadet: The Future, Built In
|
||||
|
||||
Steve Losh described the [Space Cadet Shift](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!
|
||||
|
@@ -8,9 +8,17 @@ QMK Firmware has a generic implementation that is usable by any board, as well a
|
||||
|
||||
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.
|
||||
:::caution
|
||||
|
||||
!> 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.
|
||||
ARM split supports most QMK subsystems when using the 'serial' and 'serial_usart' drivers. I2C slave is currently unsupported.
|
||||
|
||||
:::
|
||||
|
||||
:::caution
|
||||
|
||||
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
|
||||
|
||||
@@ -45,13 +53,21 @@ Another option is to use phone cables (as in, old school RJ-11/RJ-14 cables). Ma
|
||||
|
||||
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.
|
||||
:::caution
|
||||
|
||||
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.
|
||||
:::tip
|
||||
|
||||
Note that the pin used here is actually set by `SOFT_SERIAL_PIN` below.
|
||||
|
||||
:::
|
||||
|
||||
<img alt="sk-pd0-connection-mono" src="https://user-images.githubusercontent.com/2170248/92296488-28e9ad80-ef70-11ea-98be-c40cb48a0319.JPG" width="48%"/>
|
||||
<img alt="sk-pd2-connection-mono" src="https://user-images.githubusercontent.com/2170248/92296490-2d15cb00-ef70-11ea-801f-5ace313013e6.JPG" width="48%"/>
|
||||
@@ -146,10 +162,10 @@ Next, you will have to flash the correct handedness option to the controller on
|
||||
|
||||
|Microcontroller Type|Bootloader Parameter|
|
||||
|--------------------|--------------------|
|
||||
|AVR controllers with Caterina bootloader<br>(e.g. Pro Micro)|`avrdude-split-left`<br>`avrdude-split-right`|
|
||||
|AVR controllers with the stock Amtel DFU or DFU compatible bootloader<br>(e.g. Elite-C)|`dfu-split-left`<br>`dfu-split-right`|
|
||||
|ARM controllers with a DFU compatible bootloader<br>(e.g. Proton-C)|`dfu-util-split-left`<br>`dfu-util-split-right`|
|
||||
|ARM controllers with a UF2 compatible bootloader<br>(e.g. RP2040)|`uf2-split-left`<br>`uf2-split-right`|
|
||||
|AVR controllers with Caterina bootloader<br />(e.g. Pro Micro)|`avrdude-split-left`<br />`avrdude-split-right`|
|
||||
|AVR controllers with the stock Amtel DFU or DFU compatible bootloader<br />(e.g. Elite-C)|`dfu-split-left`<br />`dfu-split-right`|
|
||||
|ARM controllers with a DFU compatible bootloader<br />(e.g. Proton-C)|`dfu-util-split-left`<br />`dfu-util-split-right`|
|
||||
|ARM controllers with a UF2 compatible bootloader<br />(e.g. RP2040)|`uf2-split-left`<br />`uf2-split-right`|
|
||||
|
||||
Example for `crkbd/rev1` keyboard with normal AVR Pro Micro MCUs, reset the left controller and run:
|
||||
```
|
||||
@@ -160,11 +176,19 @@ 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.
|
||||
:::tip
|
||||
|
||||
?> [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
|
||||
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.
|
||||
|
||||
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.
|
||||
:::
|
||||
|
||||
:::tip
|
||||
|
||||
[QMK Toolbox](https://github.com/qmk/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](https://github.com/qmk/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).
|
||||
|
||||
@@ -183,7 +207,11 @@ If the USB cable is always connected to the left side, add the following to your
|
||||
#define MASTER_LEFT
|
||||
```
|
||||
|
||||
?> If neither options are defined, the handedness defaults to `MASTER_LEFT`.
|
||||
:::tip
|
||||
|
||||
If neither options are defined, the handedness defaults to `MASTER_LEFT`.
|
||||
|
||||
:::
|
||||
|
||||
|
||||
### Communication Options
|
||||
@@ -292,7 +320,11 @@ This enables transmitting the current ST7565 on/off status to the slave side of
|
||||
|
||||
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).
|
||||
:::caution
|
||||
|
||||
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
|
||||
@@ -300,7 +332,7 @@ This enables transmitting the pointing device status to the master side of the s
|
||||
|
||||
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.
|
||||
|
||||
### Custom data sync between sides :id=custom-data-sync
|
||||
### Custom data sync between sides {#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.
|
||||
|
||||
@@ -356,7 +388,11 @@ void housekeeping_task_user(void) {
|
||||
}
|
||||
```
|
||||
|
||||
!> It is recommended that any data sync between halves happens during the master side's _housekeeping task_. This ensures timely retries should failures occur.
|
||||
:::caution
|
||||
|
||||
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:
|
||||
|
||||
@@ -411,7 +447,11 @@ This option enables synchronization of the RGB Light modes between the controlle
|
||||
|
||||
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.
|
||||
:::tip
|
||||
|
||||
This setting implies that `RGBLIGHT_SPLIT` is enabled, and will forcibly enable it, if it's not.
|
||||
|
||||
:::
|
||||
|
||||
|
||||
```c
|
||||
@@ -424,7 +464,11 @@ Without this option, the master is the half that can detect voltage on the physi
|
||||
|
||||
Enabled by default on ChibiOS/ARM.
|
||||
|
||||
?> This setting will stop the ability to demo using battery packs.
|
||||
:::tip
|
||||
|
||||
This setting will stop the ability to demo using battery packs.
|
||||
|
||||
:::
|
||||
|
||||
```c
|
||||
#define SPLIT_USB_TIMEOUT 2000
|
||||
|
@@ -148,10 +148,10 @@ The default display size for this feature is 128x32 and all necessary defines ar
|
||||
|-----------------------|----------|-----------------------------------------------------------------------------------------------------------|
|
||||
|`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.<br>`(ST7565_DISPLAY_HEIGHT / 8 * ST7565_DISPLAY_WIDTH)`. |
|
||||
|`ST7565_MATRIX_SIZE` |`512` |The local buffer size to allocate.<br />`(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.<br>`(sizeof(ST7565_BLOCK_TYPE) * 8)`.|
|
||||
|`ST7565_BLOCK_SIZE` |`32` |The size of each block for dirty rendering<br>`(ST7565_MATRIX_SIZE / ST7565_BLOCK_COUNT)`. |
|
||||
|`ST7565_BLOCK_COUNT` |`16` |The number of blocks the display is divided into for dirty rendering.<br />`(sizeof(ST7565_BLOCK_TYPE) * 8)`.|
|
||||
|`ST7565_BLOCK_SIZE` |`32` |The size of each block for dirty rendering<br />`(ST7565_MATRIX_SIZE / ST7565_BLOCK_COUNT)`. |
|
||||
|
||||
## API
|
||||
|
||||
|
@@ -1,10 +1,10 @@
|
||||
# Stenography in QMK :id=stenography-in-qmk
|
||||
# Stenography in QMK {#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 with QWERTY Keyboard {#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.
|
||||
|
||||
@@ -12,7 +12,7 @@ To enable NKRO, add `NKRO_ENABLE = yes` in your `rules.mk` and make sure to pres
|
||||
|
||||
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 with Steno Protocol {#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`.
|
||||
|
||||
@@ -22,14 +22,18 @@ In this mode, Plover expects to speak with a steno machine over a serial port so
|
||||
|
||||
> 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).
|
||||
:::caution
|
||||
|
||||
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 {#tx-bolt}
|
||||
|
||||
TX Bolt communicates the status of 24 keys over a simple protocol in variable-sized (1–4 bytes) packets.
|
||||
|
||||
@@ -53,7 +57,7 @@ Examples of steno strokes and the associated packet:
|
||||
- `WAZ` = `00010000 01000010 11001000`
|
||||
- `PHAPBGS` = `00101000 01000010 10101100 11000010`
|
||||
|
||||
### GeminiPR :id=geminipr
|
||||
### GeminiPR {#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.
|
||||
|
||||
@@ -80,7 +84,7 @@ Examples of steno strokes and the associated packet:
|
||||
- `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
|
||||
### Switching protocols on the fly {#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.
|
||||
|
||||
@@ -98,11 +102,15 @@ Naturally, this option takes the most amount of firmware space as it needs to co
|
||||
|
||||
The default value for `STENO_PROTOCOL` is `all`.
|
||||
|
||||
## Configuring QMK for Steno :id=configuring-qmk-for-steno
|
||||
## Configuring QMK for Steno {#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).
|
||||
:::caution
|
||||
|
||||
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.
|
||||
|
||||
@@ -110,13 +118,13 @@ Once you have your keyboard flashed, launch Plover. Click the 'Configure...' but
|
||||
|
||||
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
|
||||
## Learning Stenography {#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
|
||||
## Interfacing with the code {#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.
|
||||
|
||||
@@ -147,7 +155,7 @@ This is not always equal to the number of bits set to 1 (aka the [Hamming weight
|
||||
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
|
||||
## Keycode Reference {#keycode-reference}
|
||||
|
||||
You must include `keymap_steno.h` to your `keymap.c` with `#include "keymap_steno.h"` before you can use these keycodes
|
||||
|
||||
|
@@ -45,7 +45,7 @@ const uint8_t PROGMEM encoder_hand_swap_config[NUM_ENCODERS] = { 1, 0 };
|
||||
#endif
|
||||
```
|
||||
|
||||
### Functions :id=functions
|
||||
### Functions {#functions}
|
||||
|
||||
| Function | Description |
|
||||
|----------------------|---------------------------------------------|
|
||||
|
@@ -1,12 +1,17 @@
|
||||
---
|
||||
sidebar_position: 5
|
||||
sidebar_label: Tap Dance
|
||||
---
|
||||
|
||||
# Tap Dance: A Single Key Can Do 3, 5, or 100 Different Things
|
||||
|
||||
## Introduction :id=introduction
|
||||
## Introduction {#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
|
||||
## How to Use Tap Dance {#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.
|
||||
|
||||
@@ -32,13 +37,17 @@ After this, you'll want to use the `tap_dance_actions` array to specify what act
|
||||
|
||||
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.
|
||||
:::caution
|
||||
|
||||
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
|
||||
## Implementation Details {#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!
|
||||
|
||||
@@ -48,9 +57,9 @@ To accomplish this logic, the tap dance mechanics use three entry points. The ma
|
||||
|
||||
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
|
||||
## Examples {#examples}
|
||||
|
||||
### Simple Example: Send `ESC` on Single Tap, `CAPS_LOCK` on Double Tap :id=simple-example
|
||||
### Simple Example: Send `ESC` on Single Tap, `CAPS_LOCK` on Double Tap {#simple-example}
|
||||
|
||||
Here's a simple example for a single definition:
|
||||
|
||||
@@ -77,7 +86,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
};
|
||||
```
|
||||
|
||||
### Complex Examples :id=complex-examples
|
||||
### Complex Examples {#complex-examples}
|
||||
|
||||
This section details several complex tap dance examples.
|
||||
All the enums used in the examples are declared like this:
|
||||
@@ -93,7 +102,7 @@ enum {
|
||||
};
|
||||
```
|
||||
|
||||
#### Example 1: Send "Safety Dance!" After 100 Taps :id=example-1
|
||||
#### Example 1: Send "Safety Dance!" After 100 Taps {#example-1}
|
||||
|
||||
```c
|
||||
void dance_egg(tap_dance_state_t *state, void *user_data) {
|
||||
@@ -108,7 +117,7 @@ tap_dance_action_t tap_dance_actions[] = {
|
||||
};
|
||||
```
|
||||
|
||||
#### Example 2: Turn LED Lights On Then Off, One at a Time :id=example-2
|
||||
#### Example 2: Turn LED Lights On Then Off, One at a Time {#example-2}
|
||||
|
||||
```c
|
||||
// On each tap, light up one LED, from right to left
|
||||
@@ -157,7 +166,7 @@ tap_dance_action_t tap_dance_actions[] = {
|
||||
};
|
||||
```
|
||||
|
||||
#### Example 3: Send `:` on Tap, `;` on Hold :id=example-3
|
||||
#### Example 3: Send `:` on Tap, `;` on Hold {#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()`.
|
||||
|
||||
@@ -217,7 +226,7 @@ tap_dance_action_t tap_dance_actions[] = {
|
||||
};
|
||||
```
|
||||
|
||||
#### Example 4: 'Quad Function Tap-Dance' :id=example-4
|
||||
#### Example 4: 'Quad Function Tap-Dance' {#example-4}
|
||||
|
||||
By [DanielGGordon](https://github.com/danielggordon)
|
||||
|
||||
@@ -358,7 +367,7 @@ 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
|
||||
#### Example 5: Using tap dance for advanced mod-tap and layer-tap keys {#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`.
|
||||
|
||||
@@ -450,7 +459,7 @@ tap_dance_action_t tap_dance_actions[] = {
|
||||
|
||||
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
|
||||
#### Example 6: Using tap dance for momentary-layer-switch and layer-toggle keys {#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.
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# Tri Layers :id=tri-layers
|
||||
# Tri Layers {#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`:
|
||||
|
||||
@@ -10,7 +10,7 @@ Note that the "upper", "lower" and "adjust" names don't have a particular signif
|
||||
|
||||
For a detailed explanation of how the layer stack works, check out [Keymap Overview](keymap.md#keymap-and-layers).
|
||||
|
||||
## Keycodes :id=keycodes
|
||||
## Keycodes {#keycodes}
|
||||
|
||||
| Keycode | Alias | Description |
|
||||
|----------------------|-----------|---------------------------------------------------------------------------------------------------------|
|
||||
|
@@ -10,15 +10,15 @@ In order to enable Unicode support on your keyboard, you will need to do the fol
|
||||
4. Add Unicode keycodes to your keymap.
|
||||
|
||||
|
||||
## 1. Methods :id=methods
|
||||
## 1. Methods {#methods}
|
||||
|
||||
QMK supports three different methods for enabling Unicode input and adding Unicode characters to your keymap. Each has its pros and cons in terms of flexibility and ease of use. Choose the one that best fits your use case.
|
||||
|
||||
The Basic method should be enough for most users. However, if you need a wider range of supported characters (including emoji, rare symbols etc.), you should use Unicode Map.
|
||||
|
||||
<br>
|
||||
<br />
|
||||
|
||||
### 1.1. Basic Unicode :id=basic-unicode
|
||||
### 1.1. Basic Unicode {#basic-unicode}
|
||||
|
||||
The easiest to use method, albeit somewhat limited. It stores Unicode characters as keycodes in the keymap itself, so it only supports code points up to `0x7FFF`. This covers characters for most modern languages (including East Asian), as well as symbols, but it doesn't cover emoji.
|
||||
|
||||
@@ -30,9 +30,9 @@ UNICODE_ENABLE = yes
|
||||
|
||||
Then add `UC(c)` keycodes to your keymap, where _c_ is the code point of the desired character (preferably in hexadecimal, up to 4 digits long). For example, `UC(0x40B)` will output [Ћ](https://unicode-table.com/en/040B/), and `UC(0x30C4)` will output [ツ](https://unicode-table.com/en/30C4).
|
||||
|
||||
<br>
|
||||
<br />
|
||||
|
||||
### 1.2. Unicode Map :id=unicode-map
|
||||
### 1.2. Unicode Map {#unicode-map}
|
||||
|
||||
In addition to standard character ranges, this method also covers emoji, ancient scripts, rare symbols etc. In fact, all possible code points (up to `0x10FFFF`) are supported. Here, Unicode characters are stored in a separate mapping table. You need to maintain a `unicode_map` array in your keymap file, which may contain at most 16384 entries.
|
||||
|
||||
@@ -68,9 +68,9 @@ This is most useful when creating a keymap for an international layout with spec
|
||||
|
||||
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.
|
||||
|
||||
<br>
|
||||
<br />
|
||||
|
||||
### 1.3. UCIS :id=ucis
|
||||
### 1.3. UCIS {#ucis}
|
||||
|
||||
This method also supports all possible code points. As with the Unicode Map method, you need to maintain a mapping table in your keymap file. However, there are no built-in keycodes for this feature — you have to create a custom keycode or function that invokes this functionality.
|
||||
|
||||
@@ -106,7 +106,7 @@ There are several functions that you can define in your keymap to customize the
|
||||
You can find the default implementations of these functions in [`process_ucis.c`](https://github.com/qmk/qmk_firmware/blob/master/quantum/process_keycode/process_ucis.c).
|
||||
|
||||
|
||||
## 2. Input Modes :id=input-modes
|
||||
## 2. Input Modes {#input-modes}
|
||||
|
||||
Unicode input in QMK works by inputting a sequence of characters to the OS, sort of like a macro. Unfortunately, the way this is done differs for each platform. Specifically, each platform requires a different combination of keys to trigger Unicode input. Therefore, a corresponding input mode has to be set in QMK.
|
||||
|
||||
@@ -117,7 +117,11 @@ The following input modes are available:
|
||||
To enable, go to _System Preferences > Keyboard > Input Sources_, add _Unicode Hex Input_ to the list (it's under _Other_), then activate it from the input dropdown in the Menu Bar.
|
||||
By default, this mode uses the left Option key (`KC_LALT`) for Unicode input, but this can be changed by defining [`UNICODE_KEY_MAC`](#input-key-configuration) with a different keycode.
|
||||
|
||||
!> Using the _Unicode Hex Input_ input source may disable some Option-based shortcuts, such as Option+Left and Option+Right.
|
||||
:::caution
|
||||
|
||||
Using the _Unicode Hex Input_ input source may disable some Option-based shortcuts, such as Option+Left and Option+Right.
|
||||
|
||||
:::
|
||||
|
||||
* **`UNICODE_MODE_LINUX`**: Linux built-in IBus Unicode input. Supports code points up to `0x10FFFF` (all possible code points).
|
||||
|
||||
@@ -139,7 +143,7 @@ The following input modes are available:
|
||||
By default, this mode uses right Alt (`KC_RALT`) as the Compose key, but this can be changed in the WinCompose settings and by defining [`UNICODE_KEY_WINC`](#input-key-configuration) with a different keycode.
|
||||
|
||||
|
||||
## 3. Setting the Input Mode :id=setting-the-input-mode
|
||||
## 3. Setting the Input Mode {#setting-the-input-mode}
|
||||
|
||||
To set your desired input mode, add the following define to your `config.h`:
|
||||
|
||||
@@ -174,7 +178,11 @@ You can switch the input mode at any time by using the following keycodes. Addin
|
||||
|
||||
You can also switch the input mode by calling `set_unicode_input_mode(x)` in your code, where _x_ is one of the above input mode constants (e.g. `UNICODE_MODE_LINUX`).
|
||||
|
||||
?> Using `UNICODE_SELECTED_MODES` is preferable to calling `set_unicode_input_mode()` in `matrix_init_user()` or similar functions, since it's better integrated into the Unicode system and has the added benefit of avoiding unnecessary writes to EEPROM.
|
||||
:::tip
|
||||
|
||||
Using `UNICODE_SELECTED_MODES` is preferable to calling `set_unicode_input_mode()` in `matrix_init_user()` or similar functions, since it's better integrated into the Unicode system and has the added benefit of avoiding unnecessary writes to EEPROM.
|
||||
|
||||
:::
|
||||
|
||||
#### Audio Feedback
|
||||
|
||||
@@ -272,7 +280,7 @@ AutoHotkey inserts the Text right of `Send, ` when this combination is pressed.
|
||||
If you enable the US International layout on the system, it will use punctuation to accent the characters. For instance, typing "\`a" will result in à.
|
||||
You can find details on how to enable this [here](https://support.microsoft.com/en-us/help/17424/windows-change-keyboard-layout).
|
||||
|
||||
## Software keyboard layout on Linux :id=custom-linux-layout
|
||||
## Software keyboard layout on Linux {#custom-linux-layout}
|
||||
|
||||
This method does not require Unicode support on the keyboard itself but instead uses a custom keyboard layout for Xorg. This is how special characters are inserted by regular keyboards. This does not require IBus and works in practically all software. Help on creating a custom layout can be found [here](https://www.linux.com/news/creating-custom-keyboard-layouts-x11-using-xkb/), [here](http://karols.github.io/blog/2013/11/18/creating-custom-keyboard-layouts-for-linux/) and [here](https://wiki.archlinux.org/index.php/X_keyboard_extension). An example of how you could edit the `us` layout to gain 🤣 on `RALT(KC_R)`:
|
||||
|
||||
|