commit
c7f3150066
|
@ -1,36 +0,0 @@
|
||||||
---
|
|
||||||
name: Bug report
|
|
||||||
about: Create a report to help us improve QMK Firmware.
|
|
||||||
title: "[Bug] "
|
|
||||||
labels: bug, help wanted
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- Provide a general summary of the bug in the title above. -->
|
|
||||||
|
|
||||||
<!--- This template is entirely optional and can be removed, but is here to help both you and us. -->
|
|
||||||
<!--- Anything on lines wrapped in comments like these will not show up in the final text. -->
|
|
||||||
|
|
||||||
## Describe the Bug
|
|
||||||
|
|
||||||
<!-- A clear and concise description of what the bug is. -->
|
|
||||||
|
|
||||||
## System Information
|
|
||||||
|
|
||||||
**Keyboard:**
|
|
||||||
**Revision (if applicable):**
|
|
||||||
**Operating system:**
|
|
||||||
**`qmk doctor` output:**
|
|
||||||
```
|
|
||||||
(Paste output here)
|
|
||||||
```
|
|
||||||
|
|
||||||
**Any keyboard related software installed?**
|
|
||||||
- [ ] AutoHotKey (Windows)
|
|
||||||
- [ ] Karabiner (macOS)
|
|
||||||
- [ ] Other:
|
|
||||||
|
|
||||||
## Additional Context
|
|
||||||
|
|
||||||
<!-- Add any other relevant information about the problem here. -->
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
name: Bug report
|
||||||
|
description: Create a report to help us improve QMK Firmware.
|
||||||
|
title: "[Bug] "
|
||||||
|
labels: ["bug", "help wanted"]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Provide a general summary of the bug in the title above.
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Describe the Bug
|
||||||
|
description: A clear and concise description of what the bug is.
|
||||||
|
- type: input
|
||||||
|
attributes:
|
||||||
|
label: Keyboard Used
|
||||||
|
description: The name of the keyboard from the `make` or `qmk compile`/`qmk flash` commands, eg. `planck/rev6`.
|
||||||
|
- type: input
|
||||||
|
attributes:
|
||||||
|
label: Link to product page (if applicable)
|
||||||
|
- type: input
|
||||||
|
attributes:
|
||||||
|
label: Operating System
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: qmk doctor Output
|
||||||
|
description: Output from running the `qmk doctor` command.
|
||||||
|
render: text
|
||||||
|
- type: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: Is AutoHotKey / Karabiner installed
|
||||||
|
options:
|
||||||
|
- label: AutoHotKey (Windows)
|
||||||
|
- label: Karabiner (macOS)
|
||||||
|
- type: input
|
||||||
|
attributes:
|
||||||
|
label: Other keyboard-related software installed
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Additional Context
|
||||||
|
description: Add any other relevant information about the problem here.
|
|
@ -1,24 +0,0 @@
|
||||||
---
|
|
||||||
name: Feature request
|
|
||||||
about: Suggest a new feature or changes to existing features.
|
|
||||||
title: "[Feature Request] "
|
|
||||||
labels: enhancement, help wanted
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!--- Provide a general summary of the changes you want in the title above. -->
|
|
||||||
|
|
||||||
<!--- This template is entirely optional and can be removed, but is here to help both you and us. -->
|
|
||||||
<!--- Anything on lines wrapped in comments like these will not show up in the final text. -->
|
|
||||||
|
|
||||||
## Feature Request Type
|
|
||||||
|
|
||||||
- [ ] Core functionality
|
|
||||||
- [ ] Add-on hardware support (eg. audio, RGB, OLED screen, etc.)
|
|
||||||
- [ ] Alteration (enhancement/optimization) of existing feature(s)
|
|
||||||
- [ ] New behavior
|
|
||||||
|
|
||||||
## Description
|
|
||||||
|
|
||||||
<!-- A few sentences describing what it is that you'd like to see in QMK. Additional information (such as links to spec sheets, licensing info, other related issues or PRs, etc) would be helpful. -->
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
name: Feature request
|
||||||
|
description: Suggest a new feature or changes to existing features.
|
||||||
|
title: "[Feature Request] "
|
||||||
|
labels: ["enhancement", "help wanted"]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Provide a general summary of the changes you want in the title above.
|
||||||
|
- type: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: Feature Request Type
|
||||||
|
options:
|
||||||
|
- label: Core functionality
|
||||||
|
- label: Add-on hardware support (eg. audio, RGB, OLED screen, etc.)
|
||||||
|
- label: Alteration (enhancement/optimization) of existing feature(s)
|
||||||
|
- label: New behavior
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Description
|
||||||
|
description: A few sentences describing what it is that you'd like to see in QMK. Additional information (such as links to spec sheets, licensing info, other related issues or PRs, etc) would be helpful.
|
|
@ -7,6 +7,9 @@ on:
|
||||||
paths:
|
paths:
|
||||||
- 'keyboards/**'
|
- 'keyboards/**'
|
||||||
- 'layouts/community/**'
|
- 'layouts/community/**'
|
||||||
|
- 'lib/python/**'
|
||||||
|
- 'data/**'
|
||||||
|
- '.github/workflows/api.yml'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
|
@ -27,7 +27,7 @@ jobs:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Bump version and push tag
|
- name: Bump version and push tag
|
||||||
uses: anothrNick/github-tag-action@1.39.0
|
uses: anothrNick/github-tag-action@1.52.0
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
DEFAULT_BUMP: 'patch'
|
DEFAULT_BUMP: 'patch'
|
||||||
|
|
|
@ -7,6 +7,9 @@ on:
|
||||||
paths:
|
paths:
|
||||||
- 'keyboards/**'
|
- 'keyboards/**'
|
||||||
- 'layouts/community/**'
|
- 'layouts/community/**'
|
||||||
|
- 'lib/python/**'
|
||||||
|
- 'data/**'
|
||||||
|
- '.github/workflows/develop_api.yml'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
|
@ -12,7 +12,7 @@ jobs:
|
||||||
stale:
|
stale:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@v5
|
- uses: actions/stale@v6
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
|
|
@ -18,3 +18,6 @@
|
||||||
[submodule "lib/printf"]
|
[submodule "lib/printf"]
|
||||||
path = lib/printf
|
path = lib/printf
|
||||||
url = https://github.com/qmk/printf
|
url = https://github.com/qmk/printf
|
||||||
|
[submodule "lib/pico-sdk"]
|
||||||
|
path = lib/pico-sdk
|
||||||
|
url = https://github.com/qmk/pico-sdk.git
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
"files.exclude": {
|
"files.exclude": {
|
||||||
"**/.build": true,
|
"**/.build": true,
|
||||||
"**/*.hex": true,
|
"**/*.hex": true,
|
||||||
"**/*.bin": true
|
"**/*.bin": true,
|
||||||
|
"**/*.uf2": true
|
||||||
},
|
},
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"*.h": "c",
|
"*.h": "c",
|
||||||
|
|
1
Makefile
1
Makefile
|
@ -401,6 +401,7 @@ ifndef SKIP_GIT
|
||||||
if [ ! -e lib/lufa ]; then git submodule sync lib/lufa && git submodule update --depth 50 --init lib/lufa; fi
|
if [ ! -e lib/lufa ]; then git submodule sync lib/lufa && git submodule update --depth 50 --init lib/lufa; fi
|
||||||
if [ ! -e lib/vusb ]; then git submodule sync lib/vusb && git submodule update --depth 50 --init lib/vusb; fi
|
if [ ! -e lib/vusb ]; then git submodule sync lib/vusb && git submodule update --depth 50 --init lib/vusb; fi
|
||||||
if [ ! -e lib/printf ]; then git submodule sync lib/printf && git submodule update --depth 50 --init lib/printf; fi
|
if [ ! -e lib/printf ]; then git submodule sync lib/printf && git submodule update --depth 50 --init lib/printf; fi
|
||||||
|
if [ ! -e lib/pico-sdk ]; then git submodule sync lib/pico-sdk && git submodule update --depth 50 --init lib/pico-sdk; fi
|
||||||
git submodule status --recursive 2>/dev/null | \
|
git submodule status --recursive 2>/dev/null | \
|
||||||
while IFS= read -r x; do \
|
while IFS= read -r x; do \
|
||||||
case "$$x" in \
|
case "$$x" in \
|
||||||
|
|
|
@ -105,8 +105,8 @@ ifeq ($(strip $(BOOTLOADER)), halfkay)
|
||||||
ifeq ($(strip $(MCU)), at90usb1286)
|
ifeq ($(strip $(MCU)), at90usb1286)
|
||||||
BOOTLOADER_SIZE = 1024
|
BOOTLOADER_SIZE = 1024
|
||||||
endif
|
endif
|
||||||
# Teensy LC, 3.x
|
# Teensy LC, 3.0, 3.1/2, 3.5, 3.6
|
||||||
ifneq (,$(filter $(MCU_ORIG), MKL26Z64 MK20DX128 MK20DX256 MK66FX1M0))
|
ifneq (,$(filter $(MCU_ORIG), MKL26Z64 MK20DX128 MK20DX256 MK64FX512 MK66FX1M0))
|
||||||
FIRMWARE_FORMAT = hex
|
FIRMWARE_FORMAT = hex
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
@ -199,6 +199,11 @@ endif
|
||||||
ifeq ($(strip $(BOOTLOADER)), tinyuf2)
|
ifeq ($(strip $(BOOTLOADER)), tinyuf2)
|
||||||
OPT_DEFS += -DBOOTLOADER_TINYUF2
|
OPT_DEFS += -DBOOTLOADER_TINYUF2
|
||||||
BOOTLOADER_TYPE = tinyuf2
|
BOOTLOADER_TYPE = tinyuf2
|
||||||
|
FIRMWARE_FORMAT = uf2
|
||||||
|
endif
|
||||||
|
ifeq ($(strip $(BOOTLOADER)), rp2040)
|
||||||
|
OPT_DEFS += -DBOOTLOADER_RP2040
|
||||||
|
BOOTLOADER_TYPE = rp2040
|
||||||
endif
|
endif
|
||||||
ifeq ($(strip $(BOOTLOADER)), halfkay)
|
ifeq ($(strip $(BOOTLOADER)), halfkay)
|
||||||
OPT_DEFS += -DBOOTLOADER_HALFKAY
|
OPT_DEFS += -DBOOTLOADER_HALFKAY
|
||||||
|
|
|
@ -13,6 +13,14 @@ endif
|
||||||
include paths.mk
|
include paths.mk
|
||||||
include $(BUILDDEFS_PATH)/message.mk
|
include $(BUILDDEFS_PATH)/message.mk
|
||||||
|
|
||||||
|
# Helper to add defines with a 'QMK_' prefix
|
||||||
|
define add_qmk_prefix_defs
|
||||||
|
ifdef $1
|
||||||
|
# Need to cater for 'STM32L4xx+'
|
||||||
|
OPT_DEFS += -DQMK_$(2)="$($1)" -DQMK_$(2)_$(shell echo $($1) | sed -e 's@+@Plus@g' -e 's@[^a-zA-Z0-9]@_@g' | tr '[:lower:]' '[:upper:]')
|
||||||
|
endif
|
||||||
|
endef
|
||||||
|
|
||||||
# Set the qmk cli to use
|
# Set the qmk cli to use
|
||||||
QMK_BIN ?= qmk
|
QMK_BIN ?= qmk
|
||||||
|
|
||||||
|
@ -390,10 +398,18 @@ ifneq ("$(KEYMAP_H)","")
|
||||||
CONFIG_H += $(KEYMAP_H)
|
CONFIG_H += $(KEYMAP_H)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
OPT_DEFS += -DKEYMAP_C=\"$(KEYMAP_C)\"
|
||||||
|
|
||||||
|
# If a keymap or userspace places their keymap array in another file instead, allow for it to be included
|
||||||
|
# !!NOTE!! -- For this to work, the source file cannot be part of $(SRC), so users should not add it via `SRC += <file>`
|
||||||
|
ifneq ($(strip $(INTROSPECTION_KEYMAP_C)),)
|
||||||
|
OPT_DEFS += -DINTROSPECTION_KEYMAP_C=\"$(strip $(INTROSPECTION_KEYMAP_C))\"
|
||||||
|
endif
|
||||||
|
|
||||||
# project specific files
|
# project specific files
|
||||||
SRC += \
|
SRC += \
|
||||||
$(KEYBOARD_SRC) \
|
$(KEYBOARD_SRC) \
|
||||||
$(KEYMAP_C) \
|
$(QUANTUM_DIR)/keymap_introspection.c \
|
||||||
$(QUANTUM_SRC) \
|
$(QUANTUM_SRC) \
|
||||||
$(QUANTUM_DIR)/main.c \
|
$(QUANTUM_DIR)/main.c \
|
||||||
|
|
||||||
|
@ -436,6 +452,14 @@ else
|
||||||
include $(TMK_PATH)/protocol/$(PLATFORM_KEY).mk
|
include $(TMK_PATH)/protocol/$(PLATFORM_KEY).mk
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Setup definitions based on the selected MCU
|
||||||
|
$(eval $(call add_qmk_prefix_defs,MCU_ORIG,MCU))
|
||||||
|
$(eval $(call add_qmk_prefix_defs,MCU_ARCH,MCU_ARCH))
|
||||||
|
$(eval $(call add_qmk_prefix_defs,MCU_PORT_NAME,MCU_PORT_NAME))
|
||||||
|
$(eval $(call add_qmk_prefix_defs,MCU_FAMILY,MCU_FAMILY))
|
||||||
|
$(eval $(call add_qmk_prefix_defs,MCU_SERIES,MCU_SERIES))
|
||||||
|
$(eval $(call add_qmk_prefix_defs,BOARD,BOARD))
|
||||||
|
|
||||||
# TODO: remove this bodge?
|
# TODO: remove this bodge?
|
||||||
PROJECT_DEFS := $(OPT_DEFS)
|
PROJECT_DEFS := $(OPT_DEFS)
|
||||||
PROJECT_INC := $(VPATH) $(EXTRAINCDIRS) $(KEYBOARD_PATHS)
|
PROJECT_INC := $(VPATH) $(EXTRAINCDIRS) $(KEYBOARD_PATHS)
|
||||||
|
@ -469,6 +493,19 @@ check-size: build
|
||||||
check-md5: build
|
check-md5: build
|
||||||
objs-size: build
|
objs-size: build
|
||||||
|
|
||||||
|
ifeq ($(strip $(TOP_SYMBOLS)),yes)
|
||||||
|
all: top-symbols
|
||||||
|
check-size: top-symbols
|
||||||
|
top-symbols: build
|
||||||
|
echo "###########################################"
|
||||||
|
echo "# Highest flash usage:"
|
||||||
|
$(NM) -Crtd --size-sort $(BUILD_DIR)/$(TARGET).elf | grep -i ' [t] ' | head -n10 | sed -e 's#^0000000# #g' -e 's#^000000# #g' -e 's#^00000# #g' -e 's#^0000# #g' -e 's#^000# #g' -e 's#^00# #g' -e 's#^0# #g'
|
||||||
|
echo "###########################################"
|
||||||
|
echo "# Highest RAM usage:"
|
||||||
|
$(NM) -Crtd --size-sort $(BUILD_DIR)/$(TARGET).elf | grep -i ' [dbv] ' | head -n10 | sed -e 's#^0000000# #g' -e 's#^000000# #g' -e 's#^00000# #g' -e 's#^0000# #g' -e 's#^000# #g' -e 's#^00# #g' -e 's#^0# #g'
|
||||||
|
echo "###########################################"
|
||||||
|
endif
|
||||||
|
|
||||||
include $(BUILDDEFS_PATH)/show_options.mk
|
include $(BUILDDEFS_PATH)/show_options.mk
|
||||||
include $(BUILDDEFS_PATH)/common_rules.mk
|
include $(BUILDDEFS_PATH)/common_rules.mk
|
||||||
|
|
||||||
|
|
|
@ -38,11 +38,11 @@ CREATE_MAP := no
|
||||||
VPATH += \
|
VPATH += \
|
||||||
$(LIB_PATH)/googletest \
|
$(LIB_PATH)/googletest \
|
||||||
$(LIB_PATH)/googlemock \
|
$(LIB_PATH)/googlemock \
|
||||||
$(LIB_PATH)/printf
|
$(COMMON_VPATH) \
|
||||||
|
$(TEST_PATH)
|
||||||
|
|
||||||
all: elf
|
all: elf
|
||||||
|
|
||||||
VPATH += $(COMMON_VPATH)
|
|
||||||
PLATFORM:=TEST
|
PLATFORM:=TEST
|
||||||
PLATFORM_KEY:=test
|
PLATFORM_KEY:=test
|
||||||
BOOTLOADER_TYPE:=none
|
BOOTLOADER_TYPE:=none
|
||||||
|
@ -63,6 +63,8 @@ include $(TMK_PATH)/protocol.mk
|
||||||
include $(QUANTUM_PATH)/debounce/tests/rules.mk
|
include $(QUANTUM_PATH)/debounce/tests/rules.mk
|
||||||
include $(QUANTUM_PATH)/encoder/tests/rules.mk
|
include $(QUANTUM_PATH)/encoder/tests/rules.mk
|
||||||
include $(QUANTUM_PATH)/sequencer/tests/rules.mk
|
include $(QUANTUM_PATH)/sequencer/tests/rules.mk
|
||||||
|
include $(QUANTUM_PATH)/wear_leveling/tests/rules.mk
|
||||||
|
include $(QUANTUM_PATH)/logging/print.mk
|
||||||
include $(PLATFORM_PATH)/test/rules.mk
|
include $(PLATFORM_PATH)/test/rules.mk
|
||||||
ifneq ($(filter $(FULL_TESTS),$(TEST)),)
|
ifneq ($(filter $(FULL_TESTS),$(TEST)),)
|
||||||
include $(BUILDDEFS_PATH)/build_full_test.mk
|
include $(BUILDDEFS_PATH)/build_full_test.mk
|
||||||
|
@ -70,7 +72,6 @@ endif
|
||||||
|
|
||||||
$(TEST)_SRC += \
|
$(TEST)_SRC += \
|
||||||
tests/test_common/main.c \
|
tests/test_common/main.c \
|
||||||
$(LIB_PATH)/printf/printf.c \
|
|
||||||
$(QUANTUM_PATH)/logging/print.c
|
$(QUANTUM_PATH)/logging/print.c
|
||||||
|
|
||||||
$(TEST_OBJ)/$(TEST)_SRC := $($(TEST)_SRC)
|
$(TEST_OBJ)/$(TEST)_SRC := $($(TEST)_SRC)
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
|
|
||||||
QUANTUM_SRC += \
|
QUANTUM_SRC += \
|
||||||
$(QUANTUM_DIR)/quantum.c \
|
$(QUANTUM_DIR)/quantum.c \
|
||||||
$(QUANTUM_DIR)/send_string.c \
|
|
||||||
$(QUANTUM_DIR)/bitwise.c \
|
$(QUANTUM_DIR)/bitwise.c \
|
||||||
$(QUANTUM_DIR)/led.c \
|
$(QUANTUM_DIR)/led.c \
|
||||||
$(QUANTUM_DIR)/action.c \
|
$(QUANTUM_DIR)/action.c \
|
||||||
|
@ -92,10 +91,29 @@ ifeq ($(MUSIC_ENABLE), yes)
|
||||||
SRC += $(QUANTUM_DIR)/process_keycode/process_music.c
|
SRC += $(QUANTUM_DIR)/process_keycode/process_music.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
VALID_STENO_PROTOCOL_TYPES := geminipr txbolt all
|
||||||
|
STENO_PROTOCOL ?= all
|
||||||
ifeq ($(strip $(STENO_ENABLE)), yes)
|
ifeq ($(strip $(STENO_ENABLE)), yes)
|
||||||
OPT_DEFS += -DSTENO_ENABLE
|
ifeq ($(filter $(STENO_PROTOCOL),$(VALID_STENO_PROTOCOL_TYPES)),)
|
||||||
VIRTSER_ENABLE ?= yes
|
$(call CATASTROPHIC_ERROR,Invalid STENO_PROTOCOL,STENO_PROTOCOL="$(STENO_PROTOCOL)" is not a valid stenography protocol)
|
||||||
SRC += $(QUANTUM_DIR)/process_keycode/process_steno.c
|
else
|
||||||
|
OPT_DEFS += -DSTENO_ENABLE
|
||||||
|
VIRTSER_ENABLE ?= yes
|
||||||
|
|
||||||
|
ifeq ($(strip $(STENO_PROTOCOL)), geminipr)
|
||||||
|
OPT_DEFS += -DSTENO_ENABLE_GEMINI
|
||||||
|
endif
|
||||||
|
ifeq ($(strip $(STENO_PROTOCOL)), txbolt)
|
||||||
|
OPT_DEFS += -DSTENO_ENABLE_BOLT
|
||||||
|
endif
|
||||||
|
ifeq ($(strip $(STENO_PROTOCOL)), all)
|
||||||
|
OPT_DEFS += -DSTENO_ENABLE_ALL
|
||||||
|
OPT_DEFS += -DSTENO_ENABLE_GEMINI
|
||||||
|
OPT_DEFS += -DSTENO_ENABLE_BOLT
|
||||||
|
endif
|
||||||
|
|
||||||
|
SRC += $(QUANTUM_DIR)/process_keycode/process_steno.c
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(VIRTSER_ENABLE)), yes)
|
ifeq ($(strip $(VIRTSER_ENABLE)), yes)
|
||||||
|
@ -108,15 +126,16 @@ ifeq ($(strip $(MOUSEKEY_ENABLE)), yes)
|
||||||
SRC += $(QUANTUM_DIR)/mousekey.c
|
SRC += $(QUANTUM_DIR)/mousekey.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
VALID_POINTING_DEVICE_DRIVER_TYPES := adns5050 adns9800 analog_joystick cirque_pinnacle_i2c cirque_pinnacle_spi pmw3360 pmw3389 pimoroni_trackball custom
|
VALID_POINTING_DEVICE_DRIVER_TYPES := adns5050 adns9800 analog_joystick cirque_pinnacle_i2c cirque_pinnacle_spi paw3204 pmw3360 pmw3389 pimoroni_trackball custom
|
||||||
ifeq ($(strip $(POINTING_DEVICE_ENABLE)), yes)
|
ifeq ($(strip $(POINTING_DEVICE_ENABLE)), yes)
|
||||||
ifeq ($(filter $(POINTING_DEVICE_DRIVER),$(VALID_POINTING_DEVICE_DRIVER_TYPES)),)
|
ifeq ($(filter $(POINTING_DEVICE_DRIVER),$(VALID_POINTING_DEVICE_DRIVER_TYPES)),)
|
||||||
$(call CATASTROPHIC_ERROR,Invalid POINTING_DEVICE_DRIVER,POINTING_DEVICE_DRIVER="$(POINTING_DEVICE_DRIVER)" is not a valid pointing device type)
|
$(call CATASTROPHIC_ERROR,Invalid POINTING_DEVICE_DRIVER,POINTING_DEVICE_DRIVER="$(POINTING_DEVICE_DRIVER)" is not a valid pointing device type)
|
||||||
else
|
else
|
||||||
OPT_DEFS += -DPOINTING_DEVICE_ENABLE
|
OPT_DEFS += -DPOINTING_DEVICE_ENABLE
|
||||||
MOUSE_ENABLE := yes
|
MOUSE_ENABLE := yes
|
||||||
SRC += $(QUANTUM_DIR)/pointing_device.c
|
VPATH += $(QUANTUM_DIR)/pointing_device
|
||||||
SRC += $(QUANTUM_DIR)/pointing_device_drivers.c
|
SRC += $(QUANTUM_DIR)/pointing_device/pointing_device.c
|
||||||
|
SRC += $(QUANTUM_DIR)/pointing_device/pointing_device_drivers.c
|
||||||
ifneq ($(strip $(POINTING_DEVICE_DRIVER)), custom)
|
ifneq ($(strip $(POINTING_DEVICE_DRIVER)), custom)
|
||||||
SRC += drivers/sensors/$(strip $(POINTING_DEVICE_DRIVER)).c
|
SRC += drivers/sensors/$(strip $(POINTING_DEVICE_DRIVER)).c
|
||||||
OPT_DEFS += -DPOINTING_DEVICE_DRIVER_$(strip $(shell echo $(POINTING_DEVICE_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
OPT_DEFS += -DPOINTING_DEVICE_DRIVER_$(strip $(shell echo $(POINTING_DEVICE_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
||||||
|
@ -131,19 +150,21 @@ ifeq ($(strip $(POINTING_DEVICE_ENABLE)), yes)
|
||||||
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), cirque_pinnacle_i2c)
|
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), cirque_pinnacle_i2c)
|
||||||
OPT_DEFS += -DSTM32_I2C -DHAL_USE_I2C=TRUE
|
OPT_DEFS += -DSTM32_I2C -DHAL_USE_I2C=TRUE
|
||||||
SRC += drivers/sensors/cirque_pinnacle.c
|
SRC += drivers/sensors/cirque_pinnacle.c
|
||||||
|
SRC += drivers/sensors/cirque_pinnacle_gestures.c
|
||||||
|
SRC += $(QUANTUM_DIR)/pointing_device/pointing_device_gestures.c
|
||||||
QUANTUM_LIB_SRC += i2c_master.c
|
QUANTUM_LIB_SRC += i2c_master.c
|
||||||
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), cirque_pinnacle_spi)
|
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), cirque_pinnacle_spi)
|
||||||
OPT_DEFS += -DSTM32_SPI -DHAL_USE_SPI=TRUE
|
OPT_DEFS += -DSTM32_SPI -DHAL_USE_SPI=TRUE
|
||||||
SRC += drivers/sensors/cirque_pinnacle.c
|
SRC += drivers/sensors/cirque_pinnacle.c
|
||||||
|
SRC += drivers/sensors/cirque_pinnacle_gestures.c
|
||||||
|
SRC += $(QUANTUM_DIR)/pointing_device/pointing_device_gestures.c
|
||||||
QUANTUM_LIB_SRC += spi_master.c
|
QUANTUM_LIB_SRC += spi_master.c
|
||||||
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), pimoroni_trackball)
|
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), pimoroni_trackball)
|
||||||
OPT_DEFS += -DSTM32_SPI -DHAL_USE_I2C=TRUE
|
OPT_DEFS += -DSTM32_SPI -DHAL_USE_I2C=TRUE
|
||||||
QUANTUM_LIB_SRC += i2c_master.c
|
QUANTUM_LIB_SRC += i2c_master.c
|
||||||
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), pmw3360)
|
else ifneq ($(filter $(strip $(POINTING_DEVICE_DRIVER)),pmw3360 pmw3389),)
|
||||||
OPT_DEFS += -DSTM32_SPI -DHAL_USE_SPI=TRUE
|
|
||||||
QUANTUM_LIB_SRC += spi_master.c
|
|
||||||
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), pmw3389)
|
|
||||||
OPT_DEFS += -DSTM32_SPI -DHAL_USE_SPI=TRUE
|
OPT_DEFS += -DSTM32_SPI -DHAL_USE_SPI=TRUE
|
||||||
|
SRC += drivers/sensors/pmw33xx_common.c
|
||||||
QUANTUM_LIB_SRC += spi_master.c
|
QUANTUM_LIB_SRC += spi_master.c
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
@ -154,33 +175,36 @@ ifeq ($(strip $(QUANTUM_PAINTER_ENABLE)), yes)
|
||||||
include $(QUANTUM_DIR)/painter/rules.mk
|
include $(QUANTUM_DIR)/painter/rules.mk
|
||||||
endif
|
endif
|
||||||
|
|
||||||
VALID_EEPROM_DRIVER_TYPES := vendor custom transient i2c spi
|
VALID_EEPROM_DRIVER_TYPES := vendor custom transient i2c spi wear_leveling
|
||||||
EEPROM_DRIVER ?= vendor
|
EEPROM_DRIVER ?= vendor
|
||||||
ifeq ($(filter $(EEPROM_DRIVER),$(VALID_EEPROM_DRIVER_TYPES)),)
|
ifeq ($(filter $(EEPROM_DRIVER),$(VALID_EEPROM_DRIVER_TYPES)),)
|
||||||
$(call CATASTROPHIC_ERROR,Invalid EEPROM_DRIVER,EEPROM_DRIVER="$(EEPROM_DRIVER)" is not a valid EEPROM driver)
|
$(call CATASTROPHIC_ERROR,Invalid EEPROM_DRIVER,EEPROM_DRIVER="$(EEPROM_DRIVER)" is not a valid EEPROM driver)
|
||||||
else
|
else
|
||||||
OPT_DEFS += -DEEPROM_ENABLE
|
OPT_DEFS += -DEEPROM_ENABLE
|
||||||
|
COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/eeprom
|
||||||
|
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
||||||
|
COMMON_VPATH += $(PLATFORM_COMMON_DIR)
|
||||||
ifeq ($(strip $(EEPROM_DRIVER)), custom)
|
ifeq ($(strip $(EEPROM_DRIVER)), custom)
|
||||||
# Custom EEPROM implementation -- only needs to implement init/erase/read_block/write_block
|
# Custom EEPROM implementation -- only needs to implement init/erase/read_block/write_block
|
||||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_CUSTOM
|
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_CUSTOM
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
|
||||||
SRC += eeprom_driver.c
|
SRC += eeprom_driver.c
|
||||||
|
else ifeq ($(strip $(EEPROM_DRIVER)), wear_leveling)
|
||||||
|
# Wear-leveling EEPROM implementation
|
||||||
|
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_WEAR_LEVELING
|
||||||
|
SRC += eeprom_driver.c eeprom_wear_leveling.c
|
||||||
else ifeq ($(strip $(EEPROM_DRIVER)), i2c)
|
else ifeq ($(strip $(EEPROM_DRIVER)), i2c)
|
||||||
# External I2C EEPROM implementation
|
# External I2C EEPROM implementation
|
||||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_I2C
|
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_I2C
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
|
||||||
QUANTUM_LIB_SRC += i2c_master.c
|
QUANTUM_LIB_SRC += i2c_master.c
|
||||||
SRC += eeprom_driver.c eeprom_i2c.c
|
SRC += eeprom_driver.c eeprom_i2c.c
|
||||||
else ifeq ($(strip $(EEPROM_DRIVER)), spi)
|
else ifeq ($(strip $(EEPROM_DRIVER)), spi)
|
||||||
# External SPI EEPROM implementation
|
# External SPI EEPROM implementation
|
||||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_SPI
|
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_SPI
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
|
||||||
QUANTUM_LIB_SRC += spi_master.c
|
QUANTUM_LIB_SRC += spi_master.c
|
||||||
SRC += eeprom_driver.c eeprom_spi.c
|
SRC += eeprom_driver.c eeprom_spi.c
|
||||||
else ifeq ($(strip $(EEPROM_DRIVER)), transient)
|
else ifeq ($(strip $(EEPROM_DRIVER)), transient)
|
||||||
# Transient EEPROM implementation -- no data storage but provides runtime area for it
|
# Transient EEPROM implementation -- no data storage but provides runtime area for it
|
||||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT
|
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
|
||||||
SRC += eeprom_driver.c eeprom_transient.c
|
SRC += eeprom_driver.c eeprom_transient.c
|
||||||
else ifeq ($(strip $(EEPROM_DRIVER)), vendor)
|
else ifeq ($(strip $(EEPROM_DRIVER)), vendor)
|
||||||
# Vendor-implemented EEPROM
|
# Vendor-implemented EEPROM
|
||||||
|
@ -191,17 +215,18 @@ else
|
||||||
ifneq ($(filter STM32F3xx_% STM32F1xx_% %_STM32F401xC %_STM32F401xE %_STM32F405xG %_STM32F411xE %_STM32F072xB %_STM32F042x6 %_GD32VF103xB %_GD32VF103x8, $(MCU_SERIES)_$(MCU_LDSCRIPT)),)
|
ifneq ($(filter STM32F3xx_% STM32F1xx_% %_STM32F401xC %_STM32F401xE %_STM32F405xG %_STM32F411xE %_STM32F072xB %_STM32F042x6 %_GD32VF103xB %_GD32VF103x8, $(MCU_SERIES)_$(MCU_LDSCRIPT)),)
|
||||||
# Emulated EEPROM
|
# Emulated EEPROM
|
||||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_STM32_FLASH_EMULATED
|
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_STM32_FLASH_EMULATED
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/flash
|
||||||
SRC += eeprom_driver.c
|
COMMON_VPATH += $(DRIVER_PATH)/flash
|
||||||
SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
|
SRC += eeprom_driver.c eeprom_stm32.c flash_stm32.c
|
||||||
SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
|
|
||||||
else ifneq ($(filter $(MCU_SERIES),STM32L0xx STM32L1xx),)
|
else ifneq ($(filter $(MCU_SERIES),STM32L0xx STM32L1xx),)
|
||||||
# True EEPROM on STM32L0xx, L1xx
|
# True EEPROM on STM32L0xx, L1xx
|
||||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_STM32_L0_L1
|
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_STM32_L0_L1
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
SRC += eeprom_driver.c eeprom_stm32_L0_L1.c
|
||||||
COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/eeprom
|
else ifneq ($(filter $(MCU_SERIES),RP2040),)
|
||||||
SRC += eeprom_driver.c
|
# Wear-leveling EEPROM implementation, backed by RP2040 flash
|
||||||
SRC += eeprom_stm32_L0_L1.c
|
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_WEAR_LEVELING
|
||||||
|
SRC += eeprom_driver.c eeprom_wear_leveling.c
|
||||||
|
WEAR_LEVELING_DRIVER = rp2040_flash
|
||||||
else ifneq ($(filter $(MCU_SERIES),KL2x K20x),)
|
else ifneq ($(filter $(MCU_SERIES),KL2x K20x),)
|
||||||
# Teensy EEPROM implementations
|
# Teensy EEPROM implementations
|
||||||
OPT_DEFS += -DEEPROM_TEENSY
|
OPT_DEFS += -DEEPROM_TEENSY
|
||||||
|
@ -209,32 +234,64 @@ else
|
||||||
else
|
else
|
||||||
# Fall back to transient, i.e. non-persistent
|
# Fall back to transient, i.e. non-persistent
|
||||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT
|
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
|
||||||
SRC += eeprom_driver.c eeprom_transient.c
|
SRC += eeprom_driver.c eeprom_transient.c
|
||||||
endif
|
endif
|
||||||
else ifeq ($(PLATFORM),ARM_ATSAM)
|
else ifeq ($(PLATFORM),ARM_ATSAM)
|
||||||
# arm_atsam EEPROM
|
# arm_atsam EEPROM
|
||||||
OPT_DEFS += -DEEPROM_SAMD
|
OPT_DEFS += -DEEPROM_SAMD
|
||||||
SRC += $(PLATFORM_COMMON_DIR)/eeprom_samd.c
|
SRC += eeprom_samd.c
|
||||||
else ifeq ($(PLATFORM),TEST)
|
else ifeq ($(PLATFORM),TEST)
|
||||||
# Test harness "EEPROM"
|
# Test harness "EEPROM"
|
||||||
OPT_DEFS += -DEEPROM_TEST_HARNESS
|
OPT_DEFS += -DEEPROM_TEST_HARNESS
|
||||||
SRC += $(PLATFORM_COMMON_DIR)/eeprom.c
|
SRC += eeprom.c
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
VALID_WEAR_LEVELING_DRIVER_TYPES := custom embedded_flash spi_flash rp2040_flash legacy
|
||||||
|
WEAR_LEVELING_DRIVER ?= none
|
||||||
|
ifneq ($(strip $(WEAR_LEVELING_DRIVER)),none)
|
||||||
|
ifeq ($(filter $(WEAR_LEVELING_DRIVER),$(VALID_WEAR_LEVELING_DRIVER_TYPES)),)
|
||||||
|
$(call CATASTROPHIC_ERROR,Invalid WEAR_LEVELING_DRIVER,WEAR_LEVELING_DRIVER="$(WEAR_LEVELING_DRIVER)" is not a valid wear leveling driver)
|
||||||
|
else
|
||||||
|
FNV_ENABLE := yes
|
||||||
|
OPT_DEFS += -DWEAR_LEVELING_ENABLE
|
||||||
|
OPT_DEFS += -DWEAR_LEVELING_$(strip $(shell echo $(WEAR_LEVELING_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
||||||
|
COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/wear_leveling
|
||||||
|
COMMON_VPATH += $(DRIVER_PATH)/wear_leveling
|
||||||
|
COMMON_VPATH += $(QUANTUM_DIR)/wear_leveling
|
||||||
|
SRC += wear_leveling.c
|
||||||
|
ifeq ($(strip $(WEAR_LEVELING_DRIVER)), embedded_flash)
|
||||||
|
OPT_DEFS += -DHAL_USE_EFL
|
||||||
|
SRC += wear_leveling_efl.c
|
||||||
|
POST_CONFIG_H += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/wear_leveling/wear_leveling_efl_config.h
|
||||||
|
else ifeq ($(strip $(WEAR_LEVELING_DRIVER)), spi_flash)
|
||||||
|
FLASH_DRIVER := spi
|
||||||
|
SRC += wear_leveling_flash_spi.c
|
||||||
|
POST_CONFIG_H += $(DRIVER_PATH)/wear_leveling/wear_leveling_flash_spi_config.h
|
||||||
|
else ifeq ($(strip $(WEAR_LEVELING_DRIVER)), rp2040_flash)
|
||||||
|
SRC += wear_leveling_rp2040_flash.c
|
||||||
|
POST_CONFIG_H += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_PATH)/wear_leveling/wear_leveling_rp2040_flash_config.h
|
||||||
|
else ifeq ($(strip $(WEAR_LEVELING_DRIVER)), legacy)
|
||||||
|
COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/flash
|
||||||
|
SRC += flash_stm32.c wear_leveling_legacy.c
|
||||||
|
POST_CONFIG_H += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/wear_leveling/wear_leveling_legacy_config.h
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
VALID_FLASH_DRIVER_TYPES := spi
|
VALID_FLASH_DRIVER_TYPES := spi
|
||||||
FLASH_DRIVER ?= no
|
FLASH_DRIVER ?= none
|
||||||
ifneq ($(strip $(FLASH_DRIVER)), no)
|
ifneq ($(strip $(FLASH_DRIVER)), none)
|
||||||
ifeq ($(filter $(FLASH_DRIVER),$(VALID_FLASH_DRIVER_TYPES)),)
|
ifeq ($(filter $(FLASH_DRIVER),$(VALID_FLASH_DRIVER_TYPES)),)
|
||||||
$(error FLASH_DRIVER="$(FLASH_DRIVER)" is not a valid FLASH driver)
|
$(call CATASTROPHIC_ERROR,Invalid FLASH_DRIVER,FLASH_DRIVER="$(FLASH_DRIVER)" is not a valid flash driver)
|
||||||
else
|
else
|
||||||
OPT_DEFS += -DFLASH_ENABLE
|
OPT_DEFS += -DFLASH_ENABLE
|
||||||
ifeq ($(strip $(FLASH_DRIVER)), spi)
|
ifeq ($(strip $(FLASH_DRIVER)),spi)
|
||||||
OPT_DEFS += -DFLASH_DRIVER -DFLASH_SPI
|
OPT_DEFS += -DFLASH_DRIVER -DFLASH_SPI
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/flash
|
COMMON_VPATH += $(DRIVER_PATH)/flash
|
||||||
SRC += flash_spi.c
|
SRC += flash_spi.c
|
||||||
|
QUANTUM_LIB_SRC += spi_master.c
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
@ -275,7 +332,7 @@ ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
LED_MATRIX_ENABLE ?= no
|
LED_MATRIX_ENABLE ?= no
|
||||||
VALID_LED_MATRIX_TYPES := IS31FL3731 IS31FL3742A IS31FL3743A IS31FL3745 IS31FL3746A custom
|
VALID_LED_MATRIX_TYPES := IS31FL3731 IS31FL3742A IS31FL3743A IS31FL3745 IS31FL3746A CKLED2001 custom
|
||||||
# TODO: IS31FL3733 IS31FL3737 IS31FL3741
|
# TODO: IS31FL3733 IS31FL3737 IS31FL3741
|
||||||
|
|
||||||
ifeq ($(strip $(LED_MATRIX_ENABLE)), yes)
|
ifeq ($(strip $(LED_MATRIX_ENABLE)), yes)
|
||||||
|
@ -331,6 +388,13 @@ endif
|
||||||
QUANTUM_LIB_SRC += i2c_master.c
|
QUANTUM_LIB_SRC += i2c_master.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(strip $(LED_MATRIX_DRIVER)), CKLED2001)
|
||||||
|
OPT_DEFS += -DCKLED2001 -DSTM32_I2C -DHAL_USE_I2C=TRUE
|
||||||
|
COMMON_VPATH += $(DRIVER_PATH)/led
|
||||||
|
SRC += ckled2001-simple.c
|
||||||
|
QUANTUM_LIB_SRC += i2c_master.c
|
||||||
|
endif
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
RGB_MATRIX_ENABLE ?= no
|
RGB_MATRIX_ENABLE ?= no
|
||||||
|
@ -500,7 +564,7 @@ ifeq ($(strip $(BACKLIGHT_ENABLE)), yes)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
VALID_WS2812_DRIVER_TYPES := bitbang pwm spi i2c
|
VALID_WS2812_DRIVER_TYPES := bitbang pwm spi i2c vendor
|
||||||
|
|
||||||
WS2812_DRIVER ?= bitbang
|
WS2812_DRIVER ?= bitbang
|
||||||
ifeq ($(strip $(WS2812_DRIVER_REQUIRED)), yes)
|
ifeq ($(strip $(WS2812_DRIVER_REQUIRED)), yes)
|
||||||
|
@ -542,12 +606,6 @@ ifeq ($(strip $(LED_TABLES)), yes)
|
||||||
SRC += $(QUANTUM_DIR)/led_tables.c
|
SRC += $(QUANTUM_DIR)/led_tables.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(TERMINAL_ENABLE)), yes)
|
|
||||||
SRC += $(QUANTUM_DIR)/process_keycode/process_terminal.c
|
|
||||||
OPT_DEFS += -DTERMINAL_ENABLE
|
|
||||||
OPT_DEFS += -DUSER_PRINT
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(strip $(VIA_ENABLE)), yes)
|
ifeq ($(strip $(VIA_ENABLE)), yes)
|
||||||
DYNAMIC_KEYMAP_ENABLE := yes
|
DYNAMIC_KEYMAP_ENABLE := yes
|
||||||
RAW_ENABLE := yes
|
RAW_ENABLE := yes
|
||||||
|
@ -595,6 +653,14 @@ ifneq ($(strip $(DEBOUNCE_TYPE)), custom)
|
||||||
QUANTUM_SRC += $(QUANTUM_DIR)/debounce/$(strip $(DEBOUNCE_TYPE)).c
|
QUANTUM_SRC += $(QUANTUM_DIR)/debounce/$(strip $(DEBOUNCE_TYPE)).c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
VALID_SERIAL_DRIVER_TYPES := bitbang usart vendor
|
||||||
|
|
||||||
|
SERIAL_DRIVER ?= bitbang
|
||||||
|
ifeq ($(filter $(SERIAL_DRIVER),$(VALID_SERIAL_DRIVER_TYPES)),)
|
||||||
|
$(call CATASTROPHIC_ERROR,Invalid SERIAL_DRIVER,SERIAL_DRIVER="$(SERIAL_DRIVER)" is not a valid SERIAL driver)
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(SPLIT_KEYBOARD)), yes)
|
ifeq ($(strip $(SPLIT_KEYBOARD)), yes)
|
||||||
POST_CONFIG_H += $(QUANTUM_DIR)/split_common/post_config.h
|
POST_CONFIG_H += $(QUANTUM_DIR)/split_common/post_config.h
|
||||||
OPT_DEFS += -DSPLIT_KEYBOARD
|
OPT_DEFS += -DSPLIT_KEYBOARD
|
||||||
|
@ -619,11 +685,11 @@ ifeq ($(strip $(SPLIT_KEYBOARD)), yes)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
SERIAL_DRIVER ?= bitbang
|
|
||||||
OPT_DEFS += -DSERIAL_DRIVER_$(strip $(shell echo $(SERIAL_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
OPT_DEFS += -DSERIAL_DRIVER_$(strip $(shell echo $(SERIAL_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
||||||
ifeq ($(strip $(SERIAL_DRIVER)), bitbang)
|
ifeq ($(strip $(SERIAL_DRIVER)), bitbang)
|
||||||
QUANTUM_LIB_SRC += serial.c
|
QUANTUM_LIB_SRC += serial.c
|
||||||
else
|
else
|
||||||
|
QUANTUM_LIB_SRC += serial_protocol.c
|
||||||
QUANTUM_LIB_SRC += serial_$(strip $(SERIAL_DRIVER)).c
|
QUANTUM_LIB_SRC += serial_$(strip $(SERIAL_DRIVER)).c
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
@ -635,6 +701,12 @@ ifeq ($(strip $(CRC_ENABLE)), yes)
|
||||||
SRC += crc.c
|
SRC += crc.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(strip $(FNV_ENABLE)), yes)
|
||||||
|
OPT_DEFS += -DFNV_ENABLE
|
||||||
|
VPATH += $(LIB_PATH)/fnv
|
||||||
|
SRC += qmk_fnv_type_validation.c hash_32a.c hash_64a.c
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(HAPTIC_ENABLE)),yes)
|
ifeq ($(strip $(HAPTIC_ENABLE)),yes)
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/haptic
|
COMMON_VPATH += $(DRIVER_PATH)/haptic
|
||||||
|
|
||||||
|
@ -711,6 +783,13 @@ ifeq ($(strip $(MAGIC_ENABLE)), yes)
|
||||||
OPT_DEFS += -DMAGIC_KEYCODE_ENABLE
|
OPT_DEFS += -DMAGIC_KEYCODE_ENABLE
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
SEND_STRING_ENABLE ?= yes
|
||||||
|
ifeq ($(strip $(SEND_STRING_ENABLE)), yes)
|
||||||
|
OPT_DEFS += -DSEND_STRING_ENABLE
|
||||||
|
COMMON_VPATH += $(QUANTUM_DIR)/send_string
|
||||||
|
SRC += $(QUANTUM_DIR)/send_string/send_string.c
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(AUTO_SHIFT_ENABLE)), yes)
|
ifeq ($(strip $(AUTO_SHIFT_ENABLE)), yes)
|
||||||
SRC += $(QUANTUM_DIR)/process_keycode/process_auto_shift.c
|
SRC += $(QUANTUM_DIR)/process_keycode/process_auto_shift.c
|
||||||
OPT_DEFS += -DAUTO_SHIFT_ENABLE
|
OPT_DEFS += -DAUTO_SHIFT_ENABLE
|
||||||
|
@ -821,3 +900,11 @@ ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
|
||||||
QUANTUM_LIB_SRC += uart.c
|
QUANTUM_LIB_SRC += uart.c
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(strip $(ENCODER_ENABLE)), yes)
|
||||||
|
SRC += $(QUANTUM_DIR)/encoder.c
|
||||||
|
OPT_DEFS += -DENCODER_ENABLE
|
||||||
|
ifeq ($(strip $(ENCODER_MAP_ENABLE)), yes)
|
||||||
|
OPT_DEFS += -DENCODER_MAP_ENABLE
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
|
@ -1,19 +1,5 @@
|
||||||
# Hey Emacs, this is a -*- makefile -*-
|
# Hey Emacs, this is a -*- makefile -*-
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
# WinAVR Makefile Template written by Eric B. Weddington, Jg Wunsch, et al.
|
|
||||||
#
|
|
||||||
# Released to the Public Domain
|
|
||||||
#
|
|
||||||
# Additional material for this makefile was written by:
|
|
||||||
# Peter Fleury
|
|
||||||
# Tim Henigan
|
|
||||||
# Colin O'Flynn
|
|
||||||
# Reiner Patommel
|
|
||||||
# Markus Pfaff
|
|
||||||
# Sander Pool
|
|
||||||
# Frederik Rouleau
|
|
||||||
# Carlos Lamas
|
|
||||||
#
|
|
||||||
|
|
||||||
# Enable vpath seraching for source files only
|
# Enable vpath seraching for source files only
|
||||||
# Without this, output files, could be read from the wrong .build directories
|
# Without this, output files, could be read from the wrong .build directories
|
||||||
|
@ -38,36 +24,15 @@ NO_LTO_OBJ := $(filter %.a,$(OBJ))
|
||||||
|
|
||||||
MASTER_OUTPUT := $(firstword $(OUTPUTS))
|
MASTER_OUTPUT := $(firstword $(OUTPUTS))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Output format. (can be srec, ihex, binary)
|
# Output format. (can be srec, ihex, binary)
|
||||||
FORMAT = ihex
|
FORMAT = ihex
|
||||||
|
|
||||||
# Optimization level, can be [0, 1, 2, 3, s].
|
# Optimization level, can be [0, 1, 2, 3, s].
|
||||||
# 0 = turn off optimization. s = optimize for size.
|
|
||||||
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
|
|
||||||
OPT ?= s
|
OPT ?= s
|
||||||
|
|
||||||
# Compiler flag to set the C Standard level.
|
# Compiler flag to set the C and C++ language standard level
|
||||||
# c89 = "ANSI" C
|
CSTANDARD = -std=gnu11
|
||||||
# gnu89 = c89 plus GCC extensions
|
CXXSTANDARD = -std=gnu++14
|
||||||
# c99 = ISO C99 standard (not yet fully implemented)
|
|
||||||
# gnu99 = c99 plus GCC extensions
|
|
||||||
CSTANDARD = -std=gnu99
|
|
||||||
|
|
||||||
|
|
||||||
# Place -D or -U options here for C sources
|
|
||||||
#CDEFS +=
|
|
||||||
|
|
||||||
|
|
||||||
# Place -D or -U options here for ASM sources
|
|
||||||
#ADEFS +=
|
|
||||||
|
|
||||||
|
|
||||||
# Place -D or -U options here for C++ sources
|
|
||||||
#CXXDEFS += -D__STDC_LIMIT_MACROS
|
|
||||||
#CXXDEFS += -D__STDC_CONSTANT_MACROS
|
|
||||||
#CXXDEFS +=
|
|
||||||
|
|
||||||
# Speed up recompilations by opt-in usage of ccache
|
# Speed up recompilations by opt-in usage of ccache
|
||||||
USE_CCACHE ?= no
|
USE_CCACHE ?= no
|
||||||
|
@ -75,12 +40,8 @@ ifneq ($(USE_CCACHE),no)
|
||||||
CC_PREFIX ?= ccache
|
CC_PREFIX ?= ccache
|
||||||
endif
|
endif
|
||||||
|
|
||||||
#---------------- Compiler Options C ----------------
|
#---------------- C Compiler Options ----------------
|
||||||
# -g*: generate debugging information
|
|
||||||
# -O*: optimization level
|
|
||||||
# -f...: tuning, see GCC manual and avr-libc documentation
|
|
||||||
# -Wall...: warning level
|
|
||||||
# -Wa,...: tell GCC to pass this to the assembler.
|
|
||||||
ifeq ($(strip $(LTO_ENABLE)), yes)
|
ifeq ($(strip $(LTO_ENABLE)), yes)
|
||||||
ifeq ($(PLATFORM),ARM_ATSAM)
|
ifeq ($(PLATFORM),ARM_ATSAM)
|
||||||
$(info Enabling LTO on arm_atsam-targeting boards is known to have a high likelihood of failure.)
|
$(info Enabling LTO on arm_atsam-targeting boards is known to have a high likelihood of failure.)
|
||||||
|
@ -111,23 +72,14 @@ CFLAGS += -Wstrict-prototypes
|
||||||
ifneq ($(strip $(ALLOW_WARNINGS)), yes)
|
ifneq ($(strip $(ALLOW_WARNINGS)), yes)
|
||||||
CFLAGS += -Werror
|
CFLAGS += -Werror
|
||||||
endif
|
endif
|
||||||
#CFLAGS += -mshort-calls
|
|
||||||
#CFLAGS += -fno-unit-at-a-time
|
|
||||||
#CFLAGS += -Wundef
|
|
||||||
#CFLAGS += -Wunreachable-code
|
|
||||||
#CFLAGS += -Wsign-compare
|
|
||||||
CFLAGS += $(CSTANDARD)
|
CFLAGS += $(CSTANDARD)
|
||||||
|
|
||||||
# This fixes lots of keyboards linking errors but SHOULDN'T BE A FINAL SOLUTION
|
# This fixes lots of keyboards linking errors but SHOULDN'T BE A FINAL SOLUTION
|
||||||
# Fixing of multiple variable definitions must be made.
|
# Fixing of multiple variable definitions must be made.
|
||||||
CFLAGS += -fcommon
|
CFLAGS += -fcommon
|
||||||
|
|
||||||
#---------------- Compiler Options C++ ----------------
|
#---------------- C++ Compiler Options ----------------
|
||||||
# -g*: generate debugging information
|
|
||||||
# -O*: optimization level
|
|
||||||
# -f...: tuning, see GCC manual and avr-libc documentation
|
|
||||||
# -Wall...: warning level
|
|
||||||
# -Wa,...: tell GCC to pass this to the assembler.
|
|
||||||
ifeq ($(strip $(DEBUG_ENABLE)),yes)
|
ifeq ($(strip $(DEBUG_ENABLE)),yes)
|
||||||
CXXFLAGS += -g$(DEBUG)
|
CXXFLAGS += -g$(DEBUG)
|
||||||
endif
|
endif
|
||||||
|
@ -141,57 +93,17 @@ CXXFLAGS += -Wundef
|
||||||
ifneq ($(strip $(ALLOW_WARNINGS)), yes)
|
ifneq ($(strip $(ALLOW_WARNINGS)), yes)
|
||||||
CXXFLAGS += -Werror
|
CXXFLAGS += -Werror
|
||||||
endif
|
endif
|
||||||
#CXXFLAGS += -mshort-calls
|
|
||||||
#CXXFLAGS += -fno-unit-at-a-time
|
|
||||||
#CXXFLAGS += -Wstrict-prototypes
|
|
||||||
#CXXFLAGS += -Wunreachable-code
|
|
||||||
#CXXFLAGS += -Wsign-compare
|
|
||||||
#CXXFLAGS += $(CSTANDARD)
|
|
||||||
|
|
||||||
#---------------- Assembler Options ----------------
|
#---------------- Assembler Options ----------------
|
||||||
|
|
||||||
ASFLAGS += $(ADEFS)
|
ASFLAGS += $(ADEFS)
|
||||||
ifeq ($(VERBOSE_AS_CMD),yes)
|
ifeq ($(VERBOSE_AS_CMD),yes)
|
||||||
ASFLAGS += -v
|
ASFLAGS += -v
|
||||||
endif
|
endif
|
||||||
|
|
||||||
#---------------- Library Options ----------------
|
|
||||||
# Minimalistic printf version
|
|
||||||
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
|
|
||||||
|
|
||||||
# Floating point printf version (requires MATH_LIB = -lm below)
|
|
||||||
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
|
|
||||||
|
|
||||||
# If this is left blank, then it will use the Standard printf version.
|
|
||||||
PRINTF_LIB =
|
|
||||||
#PRINTF_LIB = $(PRINTF_LIB_MIN)
|
|
||||||
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
|
|
||||||
|
|
||||||
|
|
||||||
# Minimalistic scanf version
|
|
||||||
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
|
|
||||||
|
|
||||||
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
|
|
||||||
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
|
|
||||||
|
|
||||||
# If this is left blank, then it will use the Standard scanf version.
|
|
||||||
SCANF_LIB =
|
|
||||||
#SCANF_LIB = $(SCANF_LIB_MIN)
|
|
||||||
#SCANF_LIB = $(SCANF_LIB_FLOAT)
|
|
||||||
|
|
||||||
|
|
||||||
MATH_LIB = -lm
|
|
||||||
CREATE_MAP ?= yes
|
|
||||||
|
|
||||||
|
|
||||||
#---------------- Linker Options ----------------
|
#---------------- Linker Options ----------------
|
||||||
# -Wl,...: tell GCC to pass this to linker.
|
|
||||||
# -Map: create map file
|
|
||||||
# --cref: add cross reference to map file
|
|
||||||
#
|
|
||||||
# Comennt out "--relax" option to avoid a error such:
|
|
||||||
# (.vectors+0x30): relocation truncated to fit: R_AVR_13_PCREL against symbol `__vector_12'
|
|
||||||
#
|
|
||||||
|
|
||||||
|
CREATE_MAP ?= yes
|
||||||
ifeq ($(CREATE_MAP),yes)
|
ifeq ($(CREATE_MAP),yes)
|
||||||
LDFLAGS += -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref
|
LDFLAGS += -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref
|
||||||
endif
|
endif
|
||||||
|
@ -201,20 +113,11 @@ endif
|
||||||
#LDFLAGS += -Wl,--relax
|
#LDFLAGS += -Wl,--relax
|
||||||
LDFLAGS += $(EXTMEMOPTS)
|
LDFLAGS += $(EXTMEMOPTS)
|
||||||
LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
|
LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
|
||||||
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
|
LDFLAGS += -lm
|
||||||
#LDFLAGS += -T linker_script.x
|
|
||||||
# You can give EXTRALDFLAGS at 'make' command line.
|
# You can give EXTRALDFLAGS at 'make' command line.
|
||||||
LDFLAGS += $(EXTRALDFLAGS)
|
LDFLAGS += $(EXTRALDFLAGS)
|
||||||
|
|
||||||
#---------------- Assembler Listings ----------------
|
#---------------- Assembler Listings ----------------
|
||||||
# -Wa,...: tell GCC to pass this to the assembler.
|
|
||||||
# -adhlns: create listing
|
|
||||||
# -gstabs: have the assembler create line number information; note that
|
|
||||||
# for use in COFF files, additional information about filenames
|
|
||||||
# and function names needs to be present in the assembler source
|
|
||||||
# files -- see avr-libc docs [FIXME: not yet described there]
|
|
||||||
# -listing-cont-lines: Sets the maximum number of continuation lines of hex
|
|
||||||
# dump that will be displayed for a given single line of source input.
|
|
||||||
|
|
||||||
ADHLNS_ENABLE ?= no
|
ADHLNS_ENABLE ?= no
|
||||||
ifeq ($(ADHLNS_ENABLE),yes)
|
ifeq ($(ADHLNS_ENABLE),yes)
|
||||||
|
@ -468,6 +371,7 @@ show_path:
|
||||||
dump_vars: ERROR_IF_EMPTY=""
|
dump_vars: ERROR_IF_EMPTY=""
|
||||||
dump_vars: ERROR_IF_NONBOOL=""
|
dump_vars: ERROR_IF_NONBOOL=""
|
||||||
dump_vars: ERROR_IF_UNSET=""
|
dump_vars: ERROR_IF_UNSET=""
|
||||||
|
dump_vars: CATASTROPHIC_ERROR=""
|
||||||
dump_vars:
|
dump_vars:
|
||||||
@$(foreach V,$(sort $(.VARIABLES)),$(if $(filter-out environment% default automatic,$(origin $V)),$(info $V=$($V))))
|
@$(foreach V,$(sort $(.VARIABLES)),$(if $(filter-out environment% default automatic,$(origin $V)),$(info $V=$($V))))
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,6 @@ GENERIC_FEATURES = \
|
||||||
DIP_SWITCH \
|
DIP_SWITCH \
|
||||||
DYNAMIC_KEYMAP \
|
DYNAMIC_KEYMAP \
|
||||||
DYNAMIC_MACRO \
|
DYNAMIC_MACRO \
|
||||||
ENCODER \
|
|
||||||
ENCODER_MAP \
|
|
||||||
GRAVE_ESC \
|
GRAVE_ESC \
|
||||||
HAPTIC \
|
HAPTIC \
|
||||||
KEY_LOCK \
|
KEY_LOCK \
|
||||||
|
|
|
@ -87,6 +87,33 @@ ifneq ($(findstring MK20DX256, $(MCU)),)
|
||||||
BOARD ?= PJRC_TEENSY_3_1
|
BOARD ?= PJRC_TEENSY_3_1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq ($(findstring MK64FX512, $(MCU)),)
|
||||||
|
# Cortex version
|
||||||
|
MCU = cortex-m4
|
||||||
|
|
||||||
|
# ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7
|
||||||
|
ARMV = 7
|
||||||
|
|
||||||
|
## chip/board settings
|
||||||
|
# - the next two should match the directories in
|
||||||
|
# <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
|
||||||
|
MCU_FAMILY = KINETIS
|
||||||
|
MCU_SERIES = K60x
|
||||||
|
|
||||||
|
# Linker script to use
|
||||||
|
# - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
|
||||||
|
# or <keyboard_dir>/ld/
|
||||||
|
MCU_LDSCRIPT ?= MK64FX512
|
||||||
|
|
||||||
|
# Startup code to use
|
||||||
|
# - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/
|
||||||
|
MCU_STARTUP ?= k60x
|
||||||
|
|
||||||
|
# Board: it should exist either in <chibios>/os/hal/boards/,
|
||||||
|
# <keyboard_dir>/boards/, or drivers/boards/
|
||||||
|
BOARD ?= PJRC_TEENSY_3_5
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq ($(findstring MK66FX1M0, $(MCU)),)
|
ifneq ($(findstring MK66FX1M0, $(MCU)),)
|
||||||
# Cortex version
|
# Cortex version
|
||||||
MCU = cortex-m4
|
MCU = cortex-m4
|
||||||
|
@ -116,6 +143,41 @@ ifneq ($(findstring MK66FX1M0, $(MCU)),)
|
||||||
BOARD ?= PJRC_TEENSY_3_6
|
BOARD ?= PJRC_TEENSY_3_6
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq ($(findstring RP2040, $(MCU)),)
|
||||||
|
# Cortex version
|
||||||
|
MCU = cortex-m0plus
|
||||||
|
|
||||||
|
# ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7
|
||||||
|
CHIBIOS_PORT = ARMv6-M-RP2
|
||||||
|
|
||||||
|
## chip/board settings
|
||||||
|
# - the next two should match the directories in
|
||||||
|
# <chibios[-contrib]>/os/hal/ports/$(MCU_PORT_NAME)/$(MCU_SERIES)
|
||||||
|
# OR
|
||||||
|
# <chibios[-contrib]>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
|
||||||
|
MCU_FAMILY = RP
|
||||||
|
MCU_SERIES = RP2040
|
||||||
|
|
||||||
|
# Linker script to use
|
||||||
|
# - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
|
||||||
|
# or <keyboard_dir>/ld/
|
||||||
|
STARTUPLD_CONTRIB = $(CHIBIOS_CONTRIB)/os/common/startup/ARMCMx/compilers/GCC/ld
|
||||||
|
MCU_LDSCRIPT ?= RP2040_FLASH_TIMECRIT
|
||||||
|
LDFLAGS += -L $(STARTUPLD_CONTRIB)
|
||||||
|
|
||||||
|
# Startup code to use
|
||||||
|
# - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/
|
||||||
|
MCU_STARTUP ?= rp2040
|
||||||
|
|
||||||
|
# Board: it should exist either in <chibios>/os/hal/boards/,
|
||||||
|
# <keyboard_dir>/boards/, or drivers/boards/
|
||||||
|
BOARD ?= GENERIC_PROMICRO_RP2040
|
||||||
|
|
||||||
|
# Default UF2 Bootloader settings
|
||||||
|
UF2_FAMILY ?= RP2040
|
||||||
|
FIRMWARE_FORMAT ?= uf2
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq ($(findstring STM32F042, $(MCU)),)
|
ifneq ($(findstring STM32F042, $(MCU)),)
|
||||||
# Cortex version
|
# Cortex version
|
||||||
MCU = cortex-m0
|
MCU = cortex-m0
|
||||||
|
@ -286,7 +348,8 @@ ifneq ($(findstring STM32F401, $(MCU)),)
|
||||||
# or <keyboard_dir>/ld/
|
# or <keyboard_dir>/ld/
|
||||||
ifeq ($(strip $(BOOTLOADER)), tinyuf2)
|
ifeq ($(strip $(BOOTLOADER)), tinyuf2)
|
||||||
MCU_LDSCRIPT ?= STM32F401xC_tinyuf2
|
MCU_LDSCRIPT ?= STM32F401xC_tinyuf2
|
||||||
FIRMWARE_FORMAT ?= uf2
|
EEPROM_DRIVER ?= wear_leveling
|
||||||
|
WEAR_LEVELING_DRIVER ?= legacy
|
||||||
else
|
else
|
||||||
MCU_LDSCRIPT ?= STM32F401xC
|
MCU_LDSCRIPT ?= STM32F401xC
|
||||||
endif
|
endif
|
||||||
|
@ -297,7 +360,7 @@ ifneq ($(findstring STM32F401, $(MCU)),)
|
||||||
|
|
||||||
# Board: it should exist either in <chibios>/os/hal/boards/,
|
# Board: it should exist either in <chibios>/os/hal/boards/,
|
||||||
# <keyboard_dir>/boards/, or drivers/boards/
|
# <keyboard_dir>/boards/, or drivers/boards/
|
||||||
BOARD ?= BLACKPILL_STM32_F401
|
BOARD ?= GENERIC_STM32_F401XC
|
||||||
|
|
||||||
USE_FPU ?= yes
|
USE_FPU ?= yes
|
||||||
|
|
||||||
|
@ -402,7 +465,8 @@ ifneq ($(findstring STM32F411, $(MCU)),)
|
||||||
# or <keyboard_dir>/ld/
|
# or <keyboard_dir>/ld/
|
||||||
ifeq ($(strip $(BOOTLOADER)), tinyuf2)
|
ifeq ($(strip $(BOOTLOADER)), tinyuf2)
|
||||||
MCU_LDSCRIPT ?= STM32F411xE_tinyuf2
|
MCU_LDSCRIPT ?= STM32F411xE_tinyuf2
|
||||||
FIRMWARE_FORMAT ?= uf2
|
EEPROM_DRIVER ?= wear_leveling
|
||||||
|
WEAR_LEVELING_DRIVER ?= legacy
|
||||||
else
|
else
|
||||||
MCU_LDSCRIPT ?= STM32F411xE
|
MCU_LDSCRIPT ?= STM32F411xE
|
||||||
endif
|
endif
|
||||||
|
@ -413,7 +477,7 @@ ifneq ($(findstring STM32F411, $(MCU)),)
|
||||||
|
|
||||||
# Board: it should exist either in <chibios>/os/hal/boards/,
|
# Board: it should exist either in <chibios>/os/hal/boards/,
|
||||||
# <keyboard_dir>/boards/, or drivers/boards/
|
# <keyboard_dir>/boards/, or drivers/boards/
|
||||||
BOARD ?= BLACKPILL_STM32_F411
|
BOARD ?= GENERIC_STM32_F411XE
|
||||||
|
|
||||||
USE_FPU ?= yes
|
USE_FPU ?= yes
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ BUILD_OPTION_NAMES = \
|
||||||
CONSOLE_ENABLE \
|
CONSOLE_ENABLE \
|
||||||
COMMAND_ENABLE \
|
COMMAND_ENABLE \
|
||||||
NKRO_ENABLE \
|
NKRO_ENABLE \
|
||||||
TERMINAL_ENABLE \
|
|
||||||
CUSTOM_MATRIX \
|
CUSTOM_MATRIX \
|
||||||
DEBOUNCE_TYPE \
|
DEBOUNCE_TYPE \
|
||||||
SPLIT_KEYBOARD \
|
SPLIT_KEYBOARD \
|
||||||
|
@ -46,6 +45,7 @@ OTHER_OPTION_NAMES = \
|
||||||
LEADER_ENABLE \
|
LEADER_ENABLE \
|
||||||
PRINTING_ENABLE \
|
PRINTING_ENABLE \
|
||||||
STENO_ENABLE \
|
STENO_ENABLE \
|
||||||
|
STENO_PROTOCOL \
|
||||||
TAP_DANCE_ENABLE \
|
TAP_DANCE_ENABLE \
|
||||||
VIRTSER_ENABLE \
|
VIRTSER_ENABLE \
|
||||||
OLED_ENABLE \
|
OLED_ENABLE \
|
||||||
|
|
|
@ -4,6 +4,7 @@ FULL_TESTS := $(notdir $(TEST_LIST))
|
||||||
include $(QUANTUM_PATH)/debounce/tests/testlist.mk
|
include $(QUANTUM_PATH)/debounce/tests/testlist.mk
|
||||||
include $(QUANTUM_PATH)/encoder/tests/testlist.mk
|
include $(QUANTUM_PATH)/encoder/tests/testlist.mk
|
||||||
include $(QUANTUM_PATH)/sequencer/tests/testlist.mk
|
include $(QUANTUM_PATH)/sequencer/tests/testlist.mk
|
||||||
|
include $(QUANTUM_PATH)/wear_leveling/tests/testlist.mk
|
||||||
include $(PLATFORM_PATH)/test/testlist.mk
|
include $(PLATFORM_PATH)/test/testlist.mk
|
||||||
|
|
||||||
define VALIDATE_TEST_LIST
|
define VALIDATE_TEST_LIST
|
||||||
|
|
|
@ -16,6 +16,30 @@
|
||||||
"board": "QMK_PROTON_C",
|
"board": "QMK_PROTON_C",
|
||||||
"pin_compatible": "promicro"
|
"pin_compatible": "promicro"
|
||||||
},
|
},
|
||||||
|
"kb2040": {
|
||||||
|
"processor": "RP2040",
|
||||||
|
"bootloader": "rp2040",
|
||||||
|
"board": "QMK_PM2040",
|
||||||
|
"pin_compatible": "promicro"
|
||||||
|
},
|
||||||
|
"promicro_rp2040": {
|
||||||
|
"processor": "RP2040",
|
||||||
|
"bootloader": "rp2040",
|
||||||
|
"board": "QMK_PM2040",
|
||||||
|
"pin_compatible": "promicro"
|
||||||
|
},
|
||||||
|
"blok": {
|
||||||
|
"processor": "RP2040",
|
||||||
|
"bootloader": "rp2040",
|
||||||
|
"board": "QMK_PM2040",
|
||||||
|
"pin_compatible": "promicro"
|
||||||
|
},
|
||||||
|
"bit_c_pro": {
|
||||||
|
"processor": "RP2040",
|
||||||
|
"bootloader": "rp2040",
|
||||||
|
"board": "QMK_PM2040",
|
||||||
|
"pin_compatible": "promicro"
|
||||||
|
},
|
||||||
"bluepill": {
|
"bluepill": {
|
||||||
"processor": "STM32F103",
|
"processor": "STM32F103",
|
||||||
"bootloader": "stm32duino",
|
"bootloader": "stm32duino",
|
||||||
|
@ -30,6 +54,18 @@
|
||||||
"processor": "STM32F411",
|
"processor": "STM32F411",
|
||||||
"bootloader": "stm32-dfu",
|
"bootloader": "stm32-dfu",
|
||||||
"board": "BLACKPILL_STM32_F411"
|
"board": "BLACKPILL_STM32_F411"
|
||||||
|
},
|
||||||
|
"stemcell": {
|
||||||
|
"processor": "STM32F411",
|
||||||
|
"bootloader": "tinyuf2",
|
||||||
|
"board": "STEMCELL",
|
||||||
|
"pin_compatible": "promicro"
|
||||||
|
},
|
||||||
|
"bonsai_c4": {
|
||||||
|
"processor": "STM32F411",
|
||||||
|
"bootloader": "stm32-dfu",
|
||||||
|
"board": "GENERIC_STM32_F411XE",
|
||||||
|
"pin_compatible": "promicro"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -13,6 +13,7 @@
|
||||||
"AUDIO_VOICES": {"info_key": "audio.voices", "value_type": "bool"},
|
"AUDIO_VOICES": {"info_key": "audio.voices", "value_type": "bool"},
|
||||||
"BACKLIGHT_BREATHING": {"info_key": "backlight.breathing", "value_type": "bool"},
|
"BACKLIGHT_BREATHING": {"info_key": "backlight.breathing", "value_type": "bool"},
|
||||||
"BREATHING_PERIOD": {"info_key": "backlight.breathing_period", "value_type": "int"},
|
"BREATHING_PERIOD": {"info_key": "backlight.breathing_period", "value_type": "int"},
|
||||||
|
"BACKLIGHT_ON_STATE": {"info_key": "backlight.on_state", "value_type": "int"},
|
||||||
"BACKLIGHT_PIN": {"info_key": "backlight.pin"},
|
"BACKLIGHT_PIN": {"info_key": "backlight.pin"},
|
||||||
"BOTH_SHIFTS_TURNS_ON_CAPS_WORD": {"info_key": "caps_word.both_shifts_turns_on", "value_type": "bool"},
|
"BOTH_SHIFTS_TURNS_ON_CAPS_WORD": {"info_key": "caps_word.both_shifts_turns_on", "value_type": "bool"},
|
||||||
"CAPS_WORD_IDLE_TIMEOUT": {"info_key": "caps_word.idle_timeout", "value_type": "int"},
|
"CAPS_WORD_IDLE_TIMEOUT": {"info_key": "caps_word.idle_timeout", "value_type": "int"},
|
||||||
|
@ -36,6 +37,9 @@
|
||||||
"LED_CAPS_LOCK_PIN": {"info_key": "indicators.caps_lock"},
|
"LED_CAPS_LOCK_PIN": {"info_key": "indicators.caps_lock"},
|
||||||
"LED_NUM_LOCK_PIN": {"info_key": "indicators.num_lock"},
|
"LED_NUM_LOCK_PIN": {"info_key": "indicators.num_lock"},
|
||||||
"LED_SCROLL_LOCK_PIN": {"info_key": "indicators.scroll_lock"},
|
"LED_SCROLL_LOCK_PIN": {"info_key": "indicators.scroll_lock"},
|
||||||
|
"LED_COMPOSE_PIN": {"info_key": "indicators.compose"},
|
||||||
|
"LED_KANA_PIN": {"info_key": "indicators.kana"},
|
||||||
|
"LED_PIN_ON_STATE": {"info_key": "indicators.on_state", "value_type": "int"},
|
||||||
"MANUFACTURER": {"info_key": "manufacturer"},
|
"MANUFACTURER": {"info_key": "manufacturer"},
|
||||||
"MATRIX_HAS_GHOST": {"info_key": "matrix_pins.ghost", "value_type": "bool"},
|
"MATRIX_HAS_GHOST": {"info_key": "matrix_pins.ghost", "value_type": "bool"},
|
||||||
"MATRIX_IO_DELAY": {"info_key": "matrix_pins.io_delay", "value_type": "int"},
|
"MATRIX_IO_DELAY": {"info_key": "matrix_pins.io_delay", "value_type": "int"},
|
||||||
|
@ -53,7 +57,6 @@
|
||||||
"RGB_DI_PIN": {"info_key": "rgblight.pin"},
|
"RGB_DI_PIN": {"info_key": "rgblight.pin"},
|
||||||
"RGBLED_NUM": {"info_key": "rgblight.led_count", "value_type": "int"},
|
"RGBLED_NUM": {"info_key": "rgblight.led_count", "value_type": "int"},
|
||||||
"RGBLED_SPLIT": {"info_key": "rgblight.split_count", "value_type": "array.int"},
|
"RGBLED_SPLIT": {"info_key": "rgblight.split_count", "value_type": "array.int"},
|
||||||
"RGBLIGHT_ANIMATIONS": {"info_key": "rgblight.animations.all", "value_type": "bool"},
|
|
||||||
"RGBLIGHT_EFFECT_ALTERNATING": {"info_key": "rgblight.animations.alternating", "value_type": "bool"},
|
"RGBLIGHT_EFFECT_ALTERNATING": {"info_key": "rgblight.animations.alternating", "value_type": "bool"},
|
||||||
"RGBLIGHT_EFFECT_BREATHING": {"info_key": "rgblight.animations.breathing", "value_type": "bool"},
|
"RGBLIGHT_EFFECT_BREATHING": {"info_key": "rgblight.animations.breathing", "value_type": "bool"},
|
||||||
"RGBLIGHT_EFFECT_CHRISTMAS": {"info_key": "rgblight.animations.christmas", "value_type": "bool"},
|
"RGBLIGHT_EFFECT_CHRISTMAS": {"info_key": "rgblight.animations.christmas", "value_type": "bool"},
|
||||||
|
@ -80,7 +83,6 @@
|
||||||
"VENDOR_ID": {"info_key": "usb.vid", "value_type": "hex"},
|
"VENDOR_ID": {"info_key": "usb.vid", "value_type": "hex"},
|
||||||
"QMK_ESC_OUTPUT": {"info_key": "qmk_lufa_bootloader.esc_output"},
|
"QMK_ESC_OUTPUT": {"info_key": "qmk_lufa_bootloader.esc_output"},
|
||||||
"QMK_ESC_INPUT": {"info_key": "qmk_lufa_bootloader.esc_input"},
|
"QMK_ESC_INPUT": {"info_key": "qmk_lufa_bootloader.esc_input"},
|
||||||
"QMK_KEYS_PER_SCAN": {"info_key": "qmk.keys_per_scan", "value_type": "int"},
|
|
||||||
"QMK_LED": {"info_key": "qmk_lufa_bootloader.led"},
|
"QMK_LED": {"info_key": "qmk_lufa_bootloader.led"},
|
||||||
"QMK_SPEAKER": {"info_key": "qmk_lufa_bootloader.speaker"},
|
"QMK_SPEAKER": {"info_key": "qmk_lufa_bootloader.speaker"},
|
||||||
"SECURE_UNLOCK_SEQUENCE": {"info_key": "secure.unlock_sequence", "value_type": "array.array.int", "to_json": false},
|
"SECURE_UNLOCK_SEQUENCE": {"info_key": "secure.unlock_sequence", "value_type": "array.array.int", "to_json": false},
|
||||||
|
@ -109,6 +111,9 @@
|
||||||
"NO_ACTION_MACRO": {"info_key": "_invalid.no_action_macro", "invalid": true},
|
"NO_ACTION_MACRO": {"info_key": "_invalid.no_action_macro", "invalid": true},
|
||||||
"NO_ACTION_FUNCTION": {"info_key": "_invalid.no_action_function", "invalid": true},
|
"NO_ACTION_FUNCTION": {"info_key": "_invalid.no_action_function", "invalid": true},
|
||||||
"DESCRIPTION": {"info_key": "_invalid.usb_description", "invalid": true},
|
"DESCRIPTION": {"info_key": "_invalid.usb_description", "invalid": true},
|
||||||
"DEBOUNCING_DELAY": {"info_key": "_invalid.debouncing_delay", "invalid": true, replace_with: "DEBOUNCE"},
|
"DEBOUNCING_DELAY": {"info_key": "_invalid.debouncing_delay", "invalid": true, "replace_with": "DEBOUNCE"},
|
||||||
"PREVENT_STUCK_MODIFIERS": {"info_key": "_invalid.prevent_stuck_mods", "invalid": true},
|
"PREVENT_STUCK_MODIFIERS": {"info_key": "_invalid.prevent_stuck_mods", "invalid": true},
|
||||||
|
"UNUSED_PINS": {"info_key": "_invalid.unused_pins", "deprecated": true},
|
||||||
|
"RGBLIGHT_ANIMATIONS": {"info_key": "rgblight.animations.all", "value_type": "bool", "deprecated": true},
|
||||||
|
"QMK_KEYS_PER_SCAN": {"info_key": "qmk.keys_per_scan", "value_type": "int", "deprecated": true}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,11 +14,13 @@
|
||||||
"BOOTLOADER": {"info_key": "bootloader", "warn_duplicate": false},
|
"BOOTLOADER": {"info_key": "bootloader", "warn_duplicate": false},
|
||||||
"BLUETOOTH": {"info_key": "bluetooth.driver"},
|
"BLUETOOTH": {"info_key": "bluetooth.driver"},
|
||||||
"CAPS_WORD_ENABLE": {"info_key": "caps_word.enabled", "value_type": "bool"},
|
"CAPS_WORD_ENABLE": {"info_key": "caps_word.enabled", "value_type": "bool"},
|
||||||
|
"ENCODER_ENABLE": {"info_key": "encoder.enabled", "value_type": "bool"},
|
||||||
"FIRMWARE_FORMAT": {"info_key": "build.firmware_format"},
|
"FIRMWARE_FORMAT": {"info_key": "build.firmware_format"},
|
||||||
"KEYBOARD_SHARED_EP": {"info_key": "usb.shared_endpoint.keyboard", "value_type": "bool"},
|
"KEYBOARD_SHARED_EP": {"info_key": "usb.shared_endpoint.keyboard", "value_type": "bool"},
|
||||||
"MOUSE_SHARED_EP": {"info_key": "usb.shared_endpoint.mouse", "value_type": "bool"},
|
"MOUSE_SHARED_EP": {"info_key": "usb.shared_endpoint.mouse", "value_type": "bool"},
|
||||||
"LAYOUTS": {"info_key": "community_layouts", "value_type": "list"},
|
"LAYOUTS": {"info_key": "community_layouts", "value_type": "list"},
|
||||||
"LED_MATRIX_DRIVER": {"info_key": "led_matrix.driver"},
|
"LED_MATRIX_DRIVER": {"info_key": "led_matrix.driver"},
|
||||||
|
"RGB_MATRIX_DRIVER": {"info_key": "rgb_matrix.driver"},
|
||||||
"LTO_ENABLE": {"info_key": "build.lto", "value_type": "bool"},
|
"LTO_ENABLE": {"info_key": "build.lto", "value_type": "bool"},
|
||||||
"MCU": {"info_key": "processor", "warn_duplicate": false},
|
"MCU": {"info_key": "processor", "warn_duplicate": false},
|
||||||
"MOUSEKEY_ENABLE": {"info_key": "mouse_key.enabled", "value_type": "bool"},
|
"MOUSEKEY_ENABLE": {"info_key": "mouse_key.enabled", "value_type": "bool"},
|
||||||
|
@ -28,9 +30,11 @@
|
||||||
"SPLIT_KEYBOARD": {"info_key": "split.enabled", "value_type": "bool"},
|
"SPLIT_KEYBOARD": {"info_key": "split.enabled", "value_type": "bool"},
|
||||||
"SPLIT_TRANSPORT": {"info_key": "split.transport.protocol", "to_c": false},
|
"SPLIT_TRANSPORT": {"info_key": "split.transport.protocol", "to_c": false},
|
||||||
"WAIT_FOR_USB": {"info_key": "usb.wait_for", "value_type": "bool"},
|
"WAIT_FOR_USB": {"info_key": "usb.wait_for", "value_type": "bool"},
|
||||||
|
"STENO_ENABLE": {"info_key": "stenography.enabled", "value_type": "bool"},
|
||||||
|
"STENO_PROTOCOL": {"info_key": "stenography.protocol"},
|
||||||
|
|
||||||
# Items we want flagged in lint
|
# Items we want flagged in lint
|
||||||
"CTPC": {"info_key": "_deprecated.ctpc", "deprecated": true, "replace_with": "CONVERT_TO=proton_c"},
|
"CTPC": {"info_key": "_deprecated.ctpc", "deprecated": true, "replace_with": "CONVERT_TO=proton_c"},
|
||||||
"CONVERT_TO_PROTON_C": {"info_key": "_deprecated.ctpc", "deprecated": true, "replace_with": "CONVERT_TO=proton_c"},
|
"CONVERT_TO_PROTON_C": {"info_key": "_deprecated.ctpc", "deprecated": true, "replace_with": "CONVERT_TO=proton_c"},
|
||||||
"VIAL_ENABLE": {"info_key": "_invalid.vial", "invalid": true},
|
"VIAL_ENABLE": {"info_key": "_invalid.vial", "invalid": true}
|
||||||
}
|
}
|
||||||
|
|
|
@ -242,9 +242,6 @@
|
||||||
honeycomb: {
|
honeycomb: {
|
||||||
target: 'keyhive/honeycomb'
|
target: 'keyhive/honeycomb'
|
||||||
},
|
},
|
||||||
id80: {
|
|
||||||
target: 'id80/ansi'
|
|
||||||
},
|
|
||||||
idb_60: {
|
idb_60: {
|
||||||
target: 'idb/idb_60',
|
target: 'idb/idb_60',
|
||||||
layouts: {
|
layouts: {
|
||||||
|
@ -826,6 +823,9 @@
|
||||||
geminate60: {
|
geminate60: {
|
||||||
target: 'weirdo/geminate60'
|
target: 'weirdo/geminate60'
|
||||||
},
|
},
|
||||||
|
gentleman65: {
|
||||||
|
target: 'jkeys_design/gentleman65'
|
||||||
|
},
|
||||||
georgi: {
|
georgi: {
|
||||||
target: 'gboards/georgi'
|
target: 'gboards/georgi'
|
||||||
},
|
},
|
||||||
|
@ -844,6 +844,9 @@
|
||||||
halberd: {
|
halberd: {
|
||||||
target: 'kagizaraya/halberd'
|
target: 'kagizaraya/halberd'
|
||||||
},
|
},
|
||||||
|
handwired/hillside/0_1: {
|
||||||
|
target: 'handwired/hillside/48'
|
||||||
|
}
|
||||||
hecomi/alpha: {
|
hecomi/alpha: {
|
||||||
target: 'takashiski/hecomi/alpha'
|
target: 'takashiski/hecomi/alpha'
|
||||||
},
|
},
|
||||||
|
@ -857,7 +860,13 @@
|
||||||
target: 'idobao/id67/rgb'
|
target: 'idobao/id67/rgb'
|
||||||
},
|
},
|
||||||
id80: {
|
id80: {
|
||||||
target: 'idobao/id80/v1'
|
target: 'idobao/id80/v2/ansi'
|
||||||
|
},
|
||||||
|
idobao/id80/v1/ansi: {
|
||||||
|
target: 'idobao/id80/v2/ansi'
|
||||||
|
},
|
||||||
|
idobao/id80/v1/iso: {
|
||||||
|
target: 'idobao/id80/v2/iso'
|
||||||
},
|
},
|
||||||
id87: {
|
id87: {
|
||||||
target: 'idobao/id87/v1'
|
target: 'idobao/id87/v1'
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"url": {"type": "string"}
|
"url": {"type": "string"}
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
"parse_errors": {"$ref": "qmk.definitions.v1#/string_array"},
|
"parse_errors": {"$ref": "qmk.definitions.v1#/string_array"},
|
||||||
"parse_warnings": {"$ref": "qmk.definitions.v1#/string_array"},
|
"parse_warnings": {"$ref": "qmk.definitions.v1#/string_array"},
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
"$schema": "https://json-schema.org/draft/2020-12/schema#",
|
||||||
"$id": "qmk.definitions.v1",
|
"$id": "qmk.definitions.v1",
|
||||||
"title": "Common definitions used across QMK's jsonschemas.",
|
"title": "Common definitions used across QMK's jsonschemas.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
@ -65,8 +65,7 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"key_unit": {
|
"key_unit": {
|
||||||
"type": "number",
|
"type": "number"
|
||||||
"min": 0.25
|
|
||||||
},
|
},
|
||||||
"keyboard": {
|
"keyboard": {
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
|
@ -103,8 +102,11 @@
|
||||||
"pattern": "^LINE_PIN\\d{1,2}$"
|
"pattern": "^LINE_PIN\\d{1,2}$"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "number",
|
"type": "string",
|
||||||
"multipleOf": 1
|
"pattern": "^GP\\d{1,2}$"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "null"
|
"type": "null"
|
||||||
|
@ -115,14 +117,12 @@
|
||||||
"type": "number"
|
"type": "number"
|
||||||
},
|
},
|
||||||
"signed_int": {
|
"signed_int": {
|
||||||
"type": "number",
|
"type": "integer"
|
||||||
"multipleOf": 1
|
|
||||||
},
|
},
|
||||||
"signed_int_8": {
|
"signed_int_8": {
|
||||||
"type": "number",
|
"type": "integer",
|
||||||
"min": -127,
|
"minimum": -127,
|
||||||
"max": 127,
|
"maximum": 127
|
||||||
"multipleOf": 1
|
|
||||||
},
|
},
|
||||||
"string_array": {
|
"string_array": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
|
@ -138,17 +138,20 @@
|
||||||
},
|
},
|
||||||
"unsigned_decimal": {
|
"unsigned_decimal": {
|
||||||
"type": "number",
|
"type": "number",
|
||||||
"min": 0
|
"minimum": 0
|
||||||
},
|
},
|
||||||
"unsigned_int": {
|
"unsigned_int": {
|
||||||
"type": "number",
|
"type": "integer",
|
||||||
"min": 0,
|
"minimum": 0
|
||||||
"multipleOf": 1
|
|
||||||
},
|
},
|
||||||
"unsigned_int_8": {
|
"unsigned_int_8": {
|
||||||
"type": "number",
|
"type": "integer",
|
||||||
"min": 0,
|
"minimum": 0,
|
||||||
"max": 255,
|
"maximum": 255
|
||||||
"multipleOf": 1
|
},
|
||||||
|
"bit": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,27 @@
|
||||||
{
|
{
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
"$schema": "https://json-schema.org/draft/2020-12/schema#",
|
||||||
"$id": "qmk.keyboard.v1",
|
"$id": "qmk.keyboard.v1",
|
||||||
"title": "Keyboard Information",
|
"title": "Keyboard Information",
|
||||||
|
"definitions": {
|
||||||
|
"encoder_config": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"rotary": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"required": ["pin_a", "pin_b"],
|
||||||
|
"properties": {
|
||||||
|
"pin_a": {"$ref": "qmk.definitions.v1#/mcu_pin"},
|
||||||
|
"pin_b": {"$ref": "qmk.definitions.v1#/mcu_pin"},
|
||||||
|
"resolution": {"$ref": "qmk.definitions.v1#/unsigned_int"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"keyboard_name": {"$ref": "qmk.definitions.v1#/text_identifier"},
|
"keyboard_name": {"$ref": "qmk.definitions.v1#/text_identifier"},
|
||||||
|
@ -14,7 +34,7 @@
|
||||||
},
|
},
|
||||||
"development_board": {
|
"development_board": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["promicro", "elite_c", "proton_c", "bluepill", "blackpill_f401", "blackpill_f411"]
|
"enum": ["promicro", "elite_c", "proton_c", "kb2040", "promicro_rp2040", "blok", "bit_c_pro", "stemcell", "bluepill", "blackpill_f401", "blackpill_f411", "bonsai_c4"]
|
||||||
},
|
},
|
||||||
"pin_compatible": {
|
"pin_compatible": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
@ -22,7 +42,7 @@
|
||||||
},
|
},
|
||||||
"processor": {
|
"processor": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["cortex-m0", "cortex-m0plus", "cortex-m3", "cortex-m4", "MKL26Z64", "MK20DX128", "MK20DX256", "MK66FX1M0", "STM32F042", "STM32F072", "STM32F103", "STM32F303", "STM32F401", "STM32F405", "STM32F407", "STM32F411", "STM32F446", "STM32G431", "STM32G474", "STM32L412", "STM32L422", "STM32L432", "STM32L433", "STM32L442", "STM32L443", "GD32VF103", "WB32F3G71", "WB32FQ95", "atmega16u2", "atmega32u2", "atmega16u4", "atmega32u4", "at90usb162", "at90usb646", "at90usb647", "at90usb1286", "at90usb1287", "atmega32a", "atmega328p", "atmega328", "attiny85", "unknown"]
|
"enum": ["cortex-m0", "cortex-m0plus", "cortex-m3", "cortex-m4", "MKL26Z64", "MK20DX128", "MK20DX256", "MK64FX512", "MK66FX1M0", "RP2040", "STM32F042", "STM32F072", "STM32F103", "STM32F303", "STM32F401", "STM32F405", "STM32F407", "STM32F411", "STM32F446", "STM32G431", "STM32G474", "STM32L412", "STM32L422", "STM32L432", "STM32L433", "STM32L442", "STM32L443", "GD32VF103", "WB32F3G71", "WB32FQ95", "atmega16u2", "atmega32u2", "atmega16u4", "atmega32u4", "at90usb162", "at90usb646", "at90usb647", "at90usb1286", "at90usb1287", "atmega32a", "atmega328p", "atmega328", "attiny85", "unknown"]
|
||||||
},
|
},
|
||||||
"audio": {
|
"audio": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
@ -40,12 +60,12 @@
|
||||||
"breathing": {"type": "boolean"},
|
"breathing": {"type": "boolean"},
|
||||||
"breathing_period": {"$ref": "qmk.definitions.v1#/unsigned_int_8"},
|
"breathing_period": {"$ref": "qmk.definitions.v1#/unsigned_int_8"},
|
||||||
"levels": {
|
"levels": {
|
||||||
"type": "number",
|
"type": "integer",
|
||||||
"min": 1,
|
"minimum": 1,
|
||||||
"max": 31,
|
"maximum": 31
|
||||||
"multipleOf": 1
|
|
||||||
},
|
},
|
||||||
"pin": {"$ref": "qmk.definitions.v1#/mcu_pin"}
|
"pin": {"$ref": "qmk.definitions.v1#/mcu_pin"},
|
||||||
|
"on_state": {"$ref": "qmk.definitions.v1#/bit"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bluetooth": {
|
"bluetooth": {
|
||||||
|
@ -56,7 +76,7 @@
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["BluefruitLE", "RN42"]
|
"enum": ["BluefruitLE", "RN42"]
|
||||||
},
|
},
|
||||||
"lto": {"type": "boolean"},
|
"lto": {"type": "boolean"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"board": {
|
"board": {
|
||||||
|
@ -66,7 +86,29 @@
|
||||||
},
|
},
|
||||||
"bootloader": {
|
"bootloader": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["atmel-dfu", "bootloadhid", "bootloadHID", "custom", "caterina", "halfkay", "kiibohd", "lufa-dfu", "lufa-ms", "md-boot", "qmk-dfu", "qmk-hid", "stm32-dfu", "stm32duino", "gd32v-dfu", "wb32-dfu", "unknown", "usbasploader", "USBasp", "tinyuf2"],
|
"enum": [
|
||||||
|
"atmel-dfu",
|
||||||
|
"bootloadhid",
|
||||||
|
"bootloadHID",
|
||||||
|
"caterina",
|
||||||
|
"custom",
|
||||||
|
"gd32v-dfu",
|
||||||
|
"halfkay",
|
||||||
|
"kiibohd",
|
||||||
|
"lufa-dfu",
|
||||||
|
"lufa-ms",
|
||||||
|
"md-boot",
|
||||||
|
"qmk-dfu",
|
||||||
|
"qmk-hid",
|
||||||
|
"rp2040",
|
||||||
|
"stm32-dfu",
|
||||||
|
"stm32duino",
|
||||||
|
"tinyuf2",
|
||||||
|
"unknown",
|
||||||
|
"usbasploader",
|
||||||
|
"USBasp",
|
||||||
|
"wb32-dfu"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"bootloader_instructions": {
|
"bootloader_instructions": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
@ -84,7 +126,7 @@
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["bin", "hex", "uf2"]
|
"enum": ["bin", "hex", "uf2"]
|
||||||
},
|
},
|
||||||
"lto": {"type": "boolean"},
|
"lto": {"type": "boolean"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"diode_direction": {
|
"diode_direction": {
|
||||||
|
@ -99,8 +141,8 @@
|
||||||
"enabled": {"type": "boolean"},
|
"enabled": {"type": "boolean"},
|
||||||
"both_shifts_turns_on": {"type": "boolean"},
|
"both_shifts_turns_on": {"type": "boolean"},
|
||||||
"double_tap_shift_turns_on": {"type": "boolean"},
|
"double_tap_shift_turns_on": {"type": "boolean"},
|
||||||
"idle_timeout": {"$ref": "qmk.definitions.v1#/unsigned_int"},
|
"idle_timeout": {"$ref": "qmk.definitions.v1#/unsigned_int"}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
"combo": {
|
"combo": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
@ -113,13 +155,22 @@
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {"$ref": "qmk.definitions.v1#/filename"}
|
"items": {"$ref": "qmk.definitions.v1#/filename"}
|
||||||
},
|
},
|
||||||
|
"encoder": {
|
||||||
|
"$ref": "#/definitions/encoder_config",
|
||||||
|
"properties": {
|
||||||
|
"enabled": {"type": "boolean"}
|
||||||
|
}
|
||||||
|
},
|
||||||
"features": {"$ref": "qmk.definitions.v1#/boolean_array"},
|
"features": {"$ref": "qmk.definitions.v1#/boolean_array"},
|
||||||
"indicators": {
|
"indicators": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"caps_lock": {"$ref": "qmk.definitions.v1#/mcu_pin"},
|
"caps_lock": {"$ref": "qmk.definitions.v1#/mcu_pin"},
|
||||||
"num_lock": {"$ref": "qmk.definitions.v1#/mcu_pin"},
|
"num_lock": {"$ref": "qmk.definitions.v1#/mcu_pin"},
|
||||||
"scroll_lock": {"$ref": "qmk.definitions.v1#/mcu_pin"}
|
"scroll_lock": {"$ref": "qmk.definitions.v1#/mcu_pin"},
|
||||||
|
"compose": {"$ref": "qmk.definitions.v1#/mcu_pin"},
|
||||||
|
"kana": {"$ref": "qmk.definitions.v1#/mcu_pin"},
|
||||||
|
"on_state": {"$ref": "qmk.definitions.v1#/bit"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"layout_aliases": {
|
"layout_aliases": {
|
||||||
|
@ -154,12 +205,11 @@
|
||||||
"minItems": 2,
|
"minItems": 2,
|
||||||
"maxItems": 2,
|
"maxItems": 2,
|
||||||
"items": {
|
"items": {
|
||||||
"type": "number",
|
"type": "integer",
|
||||||
"min": 0,
|
"minimum": 0
|
||||||
"multipleOf": 1
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"r": {"$ref": "qmk.definitions.v1#/unsigned_decimal"},
|
"r": {"$ref": "qmk.definitions.v1#/signed_decimal"},
|
||||||
"rx": {"$ref": "qmk.definitions.v1#/unsigned_decimal"},
|
"rx": {"$ref": "qmk.definitions.v1#/unsigned_decimal"},
|
||||||
"ry": {"$ref": "qmk.definitions.v1#/unsigned_decimal"},
|
"ry": {"$ref": "qmk.definitions.v1#/unsigned_decimal"},
|
||||||
"h": {"$ref": "qmk.definitions.v1#/key_unit"},
|
"h": {"$ref": "qmk.definitions.v1#/key_unit"},
|
||||||
|
@ -193,18 +243,17 @@
|
||||||
"items": {"$ref": "qmk.definitions.v1#/mcu_pin_array"}
|
"items": {"$ref": "qmk.definitions.v1#/mcu_pin_array"}
|
||||||
},
|
},
|
||||||
"cols": {"$ref": "qmk.definitions.v1#/mcu_pin_array"},
|
"cols": {"$ref": "qmk.definitions.v1#/mcu_pin_array"},
|
||||||
"rows": {"$ref": "qmk.definitions.v1#/mcu_pin_array"},
|
"rows": {"$ref": "qmk.definitions.v1#/mcu_pin_array"}
|
||||||
"unused": {"$ref": "qmk.definitions.v1#/mcu_pin_array"}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mouse_key": {
|
"mouse_key": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"enabled": {"type": "boolean"},
|
"enabled": {"type": "boolean"},
|
||||||
"delay": {"$ref": "qmk.definitions.v1#/unsigned_int_8"}
|
"delay": {"$ref": "qmk.definitions.v1#/unsigned_int_8"},
|
||||||
"interval": {"$ref": "qmk.definitions.v1#/unsigned_int_8"}
|
"interval": {"$ref": "qmk.definitions.v1#/unsigned_int_8"},
|
||||||
"max_speed": {"$ref": "qmk.definitions.v1#/unsigned_int_8"}
|
"max_speed": {"$ref": "qmk.definitions.v1#/unsigned_int_8"},
|
||||||
"time_to_max": {"$ref": "qmk.definitions.v1#/unsigned_int_8"}
|
"time_to_max": {"$ref": "qmk.definitions.v1#/unsigned_int_8"},
|
||||||
"wheel_delay": {"$ref": "qmk.definitions.v1#/unsigned_int_8"}
|
"wheel_delay": {"$ref": "qmk.definitions.v1#/unsigned_int_8"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -230,14 +279,13 @@
|
||||||
"minItems": 2,
|
"minItems": 2,
|
||||||
"maxItems": 2,
|
"maxItems": 2,
|
||||||
"items": {
|
"items": {
|
||||||
"type": "number",
|
"type": "integer",
|
||||||
"min": 0,
|
"minimum": 0
|
||||||
"multipleOf": 1
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"x": {"$ref": "qmk.definitions.v1#/key_unit"},
|
"x": {"$ref": "qmk.definitions.v1#/key_unit"},
|
||||||
"y": {"$ref": "qmk.definitions.v1#/key_unit"},
|
"y": {"$ref": "qmk.definitions.v1#/key_unit"},
|
||||||
"flags": {"$ref": "qmk.definitions.v1#/unsigned_decimal"}
|
"flags": {"$ref": "qmk.definitions.v1#/unsigned_int_8"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -258,14 +306,13 @@
|
||||||
"minItems": 2,
|
"minItems": 2,
|
||||||
"maxItems": 2,
|
"maxItems": 2,
|
||||||
"items": {
|
"items": {
|
||||||
"type": "number",
|
"type": "integer",
|
||||||
"min": 0,
|
"minimum": 0
|
||||||
"multipleOf": 1
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"x": {"$ref": "qmk.definitions.v1#/key_unit"},
|
"x": {"$ref": "qmk.definitions.v1#/key_unit"},
|
||||||
"y": {"$ref": "qmk.definitions.v1#/key_unit"},
|
"y": {"$ref": "qmk.definitions.v1#/key_unit"},
|
||||||
"flags": {"$ref": "qmk.definitions.v1#/unsigned_decimal"}
|
"flags": {"$ref": "qmk.definitions.v1#/unsigned_int_8"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,10 +337,9 @@
|
||||||
"blink": {"type": "boolean"},
|
"blink": {"type": "boolean"},
|
||||||
"enabled": {"type": "boolean"},
|
"enabled": {"type": "boolean"},
|
||||||
"max": {
|
"max": {
|
||||||
"type": "number",
|
"type": "integer",
|
||||||
"min": 1,
|
"minimum": 1,
|
||||||
"max": 32,
|
"maximum": 32
|
||||||
"multipleOf": 1
|
|
||||||
},
|
},
|
||||||
"override_rgb": {"type": "boolean"}
|
"override_rgb": {"type": "boolean"}
|
||||||
}
|
}
|
||||||
|
@ -307,8 +353,8 @@
|
||||||
"split": {"type": "boolean"},
|
"split": {"type": "boolean"},
|
||||||
"split_count": {
|
"split_count": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"minLength": 2,
|
"minItems": 2,
|
||||||
"maxLength": 2,
|
"maxItems": 2,
|
||||||
"items": {"$ref": "qmk.definitions.v1#/unsigned_int"}
|
"items": {"$ref": "qmk.definitions.v1#/unsigned_int"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -322,21 +368,31 @@
|
||||||
"idle_timeout": {"$ref": "qmk.definitions.v1#/unsigned_int"},
|
"idle_timeout": {"$ref": "qmk.definitions.v1#/unsigned_int"},
|
||||||
"unlock_sequence": {
|
"unlock_sequence": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"minLength": 1,
|
"minItems": 1,
|
||||||
"maxLength": 5,
|
"maxItems": 5,
|
||||||
"items": {
|
"items": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"minItems": 2,
|
"minItems": 2,
|
||||||
"maxItems": 2,
|
"maxItems": 2,
|
||||||
"items": {
|
"items": {
|
||||||
"type": "number",
|
"type": "integer",
|
||||||
"min": 0,
|
"minimum": 0
|
||||||
"multipleOf": 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"stenography": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"enabled": {"type": "boolean"},
|
||||||
|
"protocol": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["all", "geminipr", "txbolt"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"split": {
|
"split": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
|
@ -365,16 +421,24 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"encoder": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"right": {
|
||||||
|
"$ref": "#/definitions/encoder_config"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"main": {
|
"main": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["eeprom", "left", "matrix_grid", "pin", "right"]
|
"enum": ["eeprom", "left", "matrix_grid", "pin", "right"]
|
||||||
},
|
},
|
||||||
"soft_serial_pin": {"$ref": "qmk.definitions.v1#/mcu_pin"},
|
"soft_serial_pin": {"$ref": "qmk.definitions.v1#/mcu_pin"},
|
||||||
"soft_serial_speed": {
|
"soft_serial_speed": {
|
||||||
"type": "number",
|
"type": "integer",
|
||||||
"min": 0,
|
"minimum": 0,
|
||||||
"max": 5,
|
"maximum": 5
|
||||||
"multipleOf": 1
|
|
||||||
},
|
},
|
||||||
"transport": {
|
"transport": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
@ -416,7 +480,7 @@
|
||||||
"retro_per_key": {"type": "boolean"},
|
"retro_per_key": {"type": "boolean"},
|
||||||
"term": {"$ref": "qmk.definitions.v1#/unsigned_int"},
|
"term": {"$ref": "qmk.definitions.v1#/unsigned_int"},
|
||||||
"term_per_key": {"type": "boolean"},
|
"term_per_key": {"type": "boolean"},
|
||||||
"toggle": {"$ref": "qmk.definitions.v1#/unsigned_int"},
|
"toggle": {"$ref": "qmk.definitions.v1#/unsigned_int"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"usb": {
|
"usb": {
|
||||||
|
@ -428,7 +492,7 @@
|
||||||
"force_nkro": {"type": "boolean"},
|
"force_nkro": {"type": "boolean"},
|
||||||
"pid": {"$ref": "qmk.definitions.v1#/hex_number_4d"},
|
"pid": {"$ref": "qmk.definitions.v1#/hex_number_4d"},
|
||||||
"vid": {"$ref": "qmk.definitions.v1#/hex_number_4d"},
|
"vid": {"$ref": "qmk.definitions.v1#/hex_number_4d"},
|
||||||
"max_power": {"$ref": "qmk.definitions.v1#/unsigned_int_8"},
|
"max_power": {"$ref": "qmk.definitions.v1#/unsigned_int"},
|
||||||
"no_startup_check": {"type": "boolean"},
|
"no_startup_check": {"type": "boolean"},
|
||||||
"polling_interval": {"$ref": "qmk.definitions.v1#/unsigned_int_8"},
|
"polling_interval": {"$ref": "qmk.definitions.v1#/unsigned_int_8"},
|
||||||
"shared_endpoint": {
|
"shared_endpoint": {
|
||||||
|
@ -439,8 +503,8 @@
|
||||||
"mouse": {"type": "boolean"}
|
"mouse": {"type": "boolean"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"suspend_wakeup_delay": {"$ref": "qmk.definitions.v1#/unsigned_int_8"},
|
"suspend_wakeup_delay": {"$ref": "qmk.definitions.v1#/unsigned_int"},
|
||||||
"wait_for": {"type": "boolean"},
|
"wait_for": {"type": "boolean"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"qmk": {
|
"qmk": {
|
||||||
|
@ -448,8 +512,8 @@
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"properties": {
|
"properties": {
|
||||||
"keys_per_scan": {"$ref": "qmk.definitions.v1#/unsigned_int_8"},
|
"keys_per_scan": {"$ref": "qmk.definitions.v1#/unsigned_int_8"},
|
||||||
"tap_keycode_delay": {"$ref": "qmk.definitions.v1#/unsigned_int_8"},
|
"tap_keycode_delay": {"$ref": "qmk.definitions.v1#/unsigned_int"},
|
||||||
"tap_capslock_delay": {"$ref": "qmk.definitions.v1#/unsigned_int_8"},
|
"tap_capslock_delay": {"$ref": "qmk.definitions.v1#/unsigned_int"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"qmk_lufa_bootloader": {
|
"qmk_lufa_bootloader": {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
"$schema": "https://json-schema.org/draft/2020-12/schema#",
|
||||||
"$id": "qmk.keymap.v1",
|
"$id": "qmk.keymap.v1",
|
||||||
"title": "Keymap Information",
|
"title": "Keymap Information",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"action": {
|
"action": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ['beep', 'delay', 'down', 'tap', 'up']
|
"enum": ["beep", "delay", "down", "tap", "up"]
|
||||||
},
|
},
|
||||||
"keycodes": {
|
"keycodes": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
|
@ -50,8 +50,7 @@
|
||||||
},
|
},
|
||||||
"config": {"$ref": "qmk.keyboard.v1"},
|
"config": {"$ref": "qmk.keyboard.v1"},
|
||||||
"notes": {
|
"notes": {
|
||||||
"type": "string",
|
"type": "string"
|
||||||
"description": "asdf"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
|
|
|
@ -24,4 +24,4 @@ Enter the bootloader in 3 ways:
|
||||||
|
|
||||||
* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (usually the top left key or Escape) and plug in the keyboard
|
* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (usually the top left key or Escape) and plug in the keyboard
|
||||||
* **Physical reset button**: Briefly press the button on the back of the PCB - some may have pads you must short instead
|
* **Physical reset button**: Briefly press the button on the back of the PCB - some may have pads you must short instead
|
||||||
* **Keycode in layout**: Press the key mapped to `RESET` if it is available
|
* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available
|
||||||
|
|
|
@ -0,0 +1,343 @@
|
||||||
|
# QMK Breaking Changes - 2022 August 27 Changelog
|
||||||
|
|
||||||
|
## Notable Features :id=notable-features
|
||||||
|
|
||||||
|
### Add Raspberry Pi RP2040 support ([#14877](https://github.com/qmk/qmk_firmware/pull/14877), [#17514](https://github.com/qmk/qmk_firmware/pull/17514), [#17516](https://github.com/qmk/qmk_firmware/pull/17516), [#17519](https://github.com/qmk/qmk_firmware/pull/17519), [#17612](https://github.com/qmk/qmk_firmware/pull/17612), [#17512](https://github.com/qmk/qmk_firmware/pull/17512), [#17557](https://github.com/qmk/qmk_firmware/pull/17557), [#17817](https://github.com/qmk/qmk_firmware/pull/17817), [#17839](https://github.com/qmk/qmk_firmware/pull/17839), [#18100](https://github.com/qmk/qmk_firmware/pull/18100)) :id=rp2040-support
|
||||||
|
|
||||||
|
QMK _finally_ picked up support for RP2040-based boards, such as the Raspberry Pi Pico, the Sparkfun Pro Micro RP2040, and the Adafruit KB2040. One of QMK's newest collaborators, _@KarlK90_, effectively did `/micdrop` with RP2040, with a massive set of changes to both QMK and the repository QMK uses for the base platform support, ChibiOS[-Contrib]. There has been a flurry of development this breaking changes cycle related to RP2040 from a large number of contributors -- so much so that almost all standard QMK hardware subsystems are supported.
|
||||||
|
|
||||||
|
Check the [RP2040 platform development page](platformdev_rp2040.md) for all supported peripherals and other hardware implementation details.
|
||||||
|
|
||||||
|
### Allow `qmk flash` to use prebuilt firmware binaries ([#16584](https://github.com/qmk/qmk_firmware/pull/16584)) :id=cli-flash-binaries
|
||||||
|
|
||||||
|
A long-requested capability of the QMK CLI has been the ability to flash binaries directly, without needing to build a firmware. QMK provides prebuilt `develop`-based default firmwares on our [CI page](https://qmk.tzarc.io/) -- normally people would need [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases/latest) to flash them. This new functionality written by _@Erovia_ allows `qmk flash` to be provided the prebuilt file instead, simplifying the workflow for people who haven't got Toolbox available.
|
||||||
|
|
||||||
|
## Changes Requiring User Action :id=changes-requiring-user-action
|
||||||
|
|
||||||
|
### Default layers dropped from 32 to 16 ([#15286](https://github.com/qmk/qmk_firmware/pull/15286))
|
||||||
|
|
||||||
|
QMK allows for controlling the maximum number of layers it supports through `LAYER_STATE_(8|16|32)BIT`. Each definition allows for the same number of maximum layers -- `LAYER_STATE_8BIT` => 8 layers. There is also a corresponding firmware size decrease that goes along with smaller numbers -- given the vast majority of users don't use more than 16 layers the default has been swapped to 16. AVR users who were not previously specifying their max layer count may see some space freed up as a result.
|
||||||
|
|
||||||
|
### `RESET` => `QK_BOOT` ([#17940](https://github.com/qmk/qmk_firmware/pull/17940)) :id=reset-2-qk_boot
|
||||||
|
|
||||||
|
Following the last breaking changes cycle, QMK has been migrating usages of `RESET` to `QK_BOOT` due to naming collisions with our upstream board support packages. [#17940](https://github.com/qmk/qmk_firmware/pull/17940) converts user keymaps across to use the new keycode name. `RESET` should also move to `QK_BOOT`.
|
||||||
|
|
||||||
|
### Updated Keyboard Codebases :id=updated-keyboard-codebases
|
||||||
|
|
||||||
|
The following keyboards have had their source moved within QMK:
|
||||||
|
|
||||||
|
| Old Keyboard Name | New Keyboard Name |
|
||||||
|
|------------------------|--------------------------|
|
||||||
|
| gentleman65 | jkeys_design/gentleman65 |
|
||||||
|
| handwired/hillside/0_1 | handwired/hillside/48 |
|
||||||
|
| idobao/id80/v1/ansi | idobao/id80/v2/ansi |
|
||||||
|
| idobao/id80/v1/iso | idobao/id80/v2/iso |
|
||||||
|
|
||||||
|
### Data-driven USB IDs Refactoring ([#18152](https://github.com/qmk/qmk_firmware/pull/18152)) :id=usb-ids-Refactoring
|
||||||
|
|
||||||
|
QMK has decided to deprecate the specification of USB IDs inside `config.h` in favour of `info.json`, eventually leaving data-driven as the only method to specify USB information.
|
||||||
|
|
||||||
|
A significant number of keyboards have already been changed on `master` in a like-for-like fashion, and [#18152](https://github.com/qmk/qmk_firmware/pull/18152) performs the same transformations for keyboards already on `develop`.
|
||||||
|
|
||||||
|
Previously in `config.h`:
|
||||||
|
```c
|
||||||
|
#define VENDOR_ID 0x1234
|
||||||
|
#define PRODUCT_ID 0x5678
|
||||||
|
#define DEVICE_VER 0x0001
|
||||||
|
#define MANUFACTURER Me
|
||||||
|
#define PRODUCT MyKeyboard
|
||||||
|
```
|
||||||
|
|
||||||
|
Replaced by `info.json`:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"keyboard_name": "MyKeyboard",
|
||||||
|
"manufacturer": "Me",
|
||||||
|
"usb": {
|
||||||
|
"vid": "0x1234",
|
||||||
|
"pid": "0x5678",
|
||||||
|
"device_version": "0.0.1"
|
||||||
|
},
|
||||||
|
// ... layouts, etc. ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Deprecation Schedule
|
||||||
|
|
||||||
|
- From 2022 Aug 27, specifying USB information in `config.h` will produce warnings during build but will still function as previously.
|
||||||
|
- From 2022 Nov 26, specifying USB information in `config.h` will cause compilation to fail.
|
||||||
|
|
||||||
|
## Notable core changes :id=notable-core
|
||||||
|
|
||||||
|
### Board converters ([#17514](https://github.com/qmk/qmk_firmware/pull/17514), [#17603](https://github.com/qmk/qmk_firmware/pull/17603), [#17711](https://github.com/qmk/qmk_firmware/pull/17711), [#17827](https://github.com/qmk/qmk_firmware/pull/17827), [#17593](https://github.com/qmk/qmk_firmware/pull/17593), [#17652](https://github.com/qmk/qmk_firmware/pull/17652), [#17595](https://github.com/qmk/qmk_firmware/pull/17595)) :id=board-converters
|
||||||
|
|
||||||
|
Historically QMK had a `CONVERT_TO_PROTON_C` directive for `rules.mk` to allow people to replace an AVR-based Pro Micro with a QMK Proton C. Global parts shortages have prompted people to create their own pin-compatible boards -- QMK has made this conversion generic and now allows for drop-in replacements for a lot more boards. see the [Converters Feature](feature_converters.md) documentation for the full list of supported replacement boards -- in this breaking changes cycle we've gone from 1 to 7.
|
||||||
|
|
||||||
|
### Add cli command to import keyboard|keymap|kbfirmware ([#16668](https://github.com/qmk/qmk_firmware/pull/16668)) :id=cli-import
|
||||||
|
|
||||||
|
To help with importing keyboards and keymaps from other sources, _@zvecr_ added [#16668](https://github.com/qmk/qmk_firmware/pull/16668) which adds a new set of commands to the CLI to automatically import keyboards (`qmk import-keyboard -h`), keymaps (`qmk import-keymap -h`), and kbfirmware definitions (`qmk import-kbfirmware -h`) into QMK.
|
||||||
|
|
||||||
|
The now-EOL kbfirmware allowed people who aren't set up with QMK the ability to create keyboard firmwares without requiring a full installation of QMK. Unfortunately, it targets a 7-year-old version of QMK -- adding frustration for users who want the newest features, as well as for QMK maintainers who have to spend time explaining why QMK can't just accept a drive-by code drop from kbfirmware. With any luck, this new command helps both camps!
|
||||||
|
|
||||||
|
### Generic wear-leveling for EEPROM emulation ([#16996](https://github.com/qmk/qmk_firmware/pull/16996), [#17376](https://github.com/qmk/qmk_firmware/pull/17376), [#18102](https://github.com/qmk/qmk_firmware/pull/18102)) :id=wear-leveling
|
||||||
|
|
||||||
|
QMK has had the ability to write to internal MCU flash in order to emulate EEPROM for some time now, but it was only limited to a small number of MCUs. The base HAL used by QMK for a large number of ARM devices provides a "proper" embedded MCU flash driver, so _@tzarc_ decoupled the wear-leveling algorithm from the old flash writing code, improved it, wrote some tests, and enabled its use for a much larger number of other devices... including RP2040's XIP flash, and external SPI NOR Flash.
|
||||||
|
|
||||||
|
See the [EEPROM Driver](eeprom_driver.md) documentation for more information.
|
||||||
|
|
||||||
|
### Pointing Device Improvements ([#16371](https://github.com/qmk/qmk_firmware/pull/16371), [#17111](https://github.com/qmk/qmk_firmware/pull/17111), [#17176](https://github.com/qmk/qmk_firmware/pull/17176), [#17482](https://github.com/qmk/qmk_firmware/pull/17482), [#17776](https://github.com/qmk/qmk_firmware/pull/17776), [#17613](https://github.com/qmk/qmk_firmware/pull/17613)) :id=pointing-device-improvements
|
||||||
|
|
||||||
|
Ever since Pointing Device Driver support and Split Pointing Device support were added by _@drashna_ and _@daskygit_, there has been increased interest in the development of the pointing device subsystem and its associated code.
|
||||||
|
|
||||||
|
Both the PMW33xx and the Cirque Pinnacle implementations have seen a lot of improvement to their code, as has the mouse code in general. Features like circular/edge scrolling for the Cirque, and Kinetic movement for any sensor with "lift detection" ([#17482](https://github.com/qmk/qmk_firmware/pull/17482)). Additionally, for those that make fast motions with their pointing devices, support for much larger mouse movement reports has been added ([#16371](https://github.com/qmk/qmk_firmware/pull/16371)).
|
||||||
|
|
||||||
|
Other related changes:
|
||||||
|
|
||||||
|
* Add support for large Mouse Reports ([#16371](https://github.com/qmk/qmk_firmware/pull/16371))
|
||||||
|
* Improve PS/2 mouse performance ([#17111](https://github.com/qmk/qmk_firmware/pull/17111))
|
||||||
|
* Mouse key kinetic mode fix ([#17176](https://github.com/qmk/qmk_firmware/pull/17176))
|
||||||
|
* Circular scroll, inertial cursor ([#17482](https://github.com/qmk/qmk_firmware/pull/17482))
|
||||||
|
* Create generic Pointing Device Pin defines ([#17776](https://github.com/qmk/qmk_firmware/pull/17776))
|
||||||
|
* PMW33XX drivers overhaul ([#17613](https://github.com/qmk/qmk_firmware/pull/17613))
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Full changelist :id=full-changelist
|
||||||
|
|
||||||
|
Core:
|
||||||
|
* Tentative Teensy 3.5 support ([#14420](https://github.com/qmk/qmk_firmware/pull/14420))
|
||||||
|
* Make default layer size 16-bit ([#15286](https://github.com/qmk/qmk_firmware/pull/15286))
|
||||||
|
* Process all changed keys in one scan loop, deprecate `QMK_KEYS_PER_SCAN` ([#15292](https://github.com/qmk/qmk_firmware/pull/15292))
|
||||||
|
* Do not enable PERMISSIVE_HOLD when TAPPING_TERM exceeds 500ms ([#15674](https://github.com/qmk/qmk_firmware/pull/15674))
|
||||||
|
* Allow usage of ChibiOS's SIO driver for split keyboards ([#15907](https://github.com/qmk/qmk_firmware/pull/15907))
|
||||||
|
* [Controller] Added board config for custom controller STeMCell ([#16287](https://github.com/qmk/qmk_firmware/pull/16287))
|
||||||
|
* PoC: Swap Escape and Caps ([#16336](https://github.com/qmk/qmk_firmware/pull/16336))
|
||||||
|
* Add support for large Mouse Reports ([#16371](https://github.com/qmk/qmk_firmware/pull/16371))
|
||||||
|
* tap-dance: Restructure code and document in more detail ([#16394](https://github.com/qmk/qmk_firmware/pull/16394))
|
||||||
|
* Teaching the CLI to flash binaries ([#16584](https://github.com/qmk/qmk_firmware/pull/16584))
|
||||||
|
* Split ChibiOS usart split driver in protocol and hardware driver part ([#16669](https://github.com/qmk/qmk_firmware/pull/16669))
|
||||||
|
* Added Wait time to sending each Keys for Dynamic Macros function ([#16800](https://github.com/qmk/qmk_firmware/pull/16800))
|
||||||
|
* Added Delay time to sending each Keys for VIA Macros function feature ([#16810](https://github.com/qmk/qmk_firmware/pull/16810))
|
||||||
|
* Improve avr wait_us() ([#16879](https://github.com/qmk/qmk_firmware/pull/16879))
|
||||||
|
* Improve ENCODER_DEFAULT_POS to recognize lost ticks ([#16932](https://github.com/qmk/qmk_firmware/pull/16932))
|
||||||
|
* Added emacs as an "operating system" for input mode. ([#16949](https://github.com/qmk/qmk_firmware/pull/16949))
|
||||||
|
* 24LC32A EEPROM addition ([#16990](https://github.com/qmk/qmk_firmware/pull/16990))
|
||||||
|
* Refactor steno and add `STENO_PROTOCOL = [all|txbolt|geminipr]` ([#17065](https://github.com/qmk/qmk_firmware/pull/17065))
|
||||||
|
* improvements for Cirque Pinnacle trackpads ([#17091](https://github.com/qmk/qmk_firmware/pull/17091))
|
||||||
|
* Use TAP_HOLD_CAPS_DELAY for KC_LOCKING_CAPS_LOCK ([#17099](https://github.com/qmk/qmk_firmware/pull/17099))
|
||||||
|
* Improve PS/2 mouse performance ([#17111](https://github.com/qmk/qmk_firmware/pull/17111))
|
||||||
|
* Update C standard to GNU11, C++ to GNU++14 ([#17114](https://github.com/qmk/qmk_firmware/pull/17114))
|
||||||
|
* Added ws2812_pwm support for WB32 MCU. ([#17142](https://github.com/qmk/qmk_firmware/pull/17142))
|
||||||
|
* Added ws2812_spi support for WB32 MCU ([#17143](https://github.com/qmk/qmk_firmware/pull/17143))
|
||||||
|
* Make bootloader_jump for dualbank STM32 respect STM32_BOOTLOADER_DUAL_BANK_DELAY ([#17178](https://github.com/qmk/qmk_firmware/pull/17178))
|
||||||
|
* Expose the time of the last change to the LED state ([#17222](https://github.com/qmk/qmk_firmware/pull/17222))
|
||||||
|
* [Code] Add solid reactive gradient mode ([#17228](https://github.com/qmk/qmk_firmware/pull/17228))
|
||||||
|
* Add keymap wrappers for introspection into the keymap. ([#17229](https://github.com/qmk/qmk_firmware/pull/17229))
|
||||||
|
* Ensure eeconfig initialised before reading EEPROM handedness. ([#17256](https://github.com/qmk/qmk_firmware/pull/17256))
|
||||||
|
* Add uf2-split-* make targets. ([#17257](https://github.com/qmk/qmk_firmware/pull/17257))
|
||||||
|
* Removes terminal from QMK. ([#17258](https://github.com/qmk/qmk_firmware/pull/17258))
|
||||||
|
* Make SPI Mode configurable for AW20216 and change default mode to 3 ([#17263](https://github.com/qmk/qmk_firmware/pull/17263))
|
||||||
|
* Move SPLIT_HAND_PIN setup to split_pre_init ([#17271](https://github.com/qmk/qmk_firmware/pull/17271))
|
||||||
|
* Allow larger SPLIT_USB_TIMEOUT with default SPLIT_USB_TIMEOUT_POLL ([#17272](https://github.com/qmk/qmk_firmware/pull/17272))
|
||||||
|
* Feature-ify Send String ([#17275](https://github.com/qmk/qmk_firmware/pull/17275))
|
||||||
|
* Rework paths for eeprom locations. ([#17326](https://github.com/qmk/qmk_firmware/pull/17326))
|
||||||
|
* Pca9505/6 driver ([#17333](https://github.com/qmk/qmk_firmware/pull/17333))
|
||||||
|
* Cirque Attenuation Setting ([#17342](https://github.com/qmk/qmk_firmware/pull/17342))
|
||||||
|
* Scale brigthness for VIA ([#17352](https://github.com/qmk/qmk_firmware/pull/17352))
|
||||||
|
* Ensure that rgb+via compiles in all cases ([#17355](https://github.com/qmk/qmk_firmware/pull/17355))
|
||||||
|
* Wear-leveling EEPROM drivers: `embedded_flash`, `spi_flash`, `legacy` ([#17376](https://github.com/qmk/qmk_firmware/pull/17376))
|
||||||
|
* In honor of king terry ([#17387](https://github.com/qmk/qmk_firmware/pull/17387))
|
||||||
|
* tap-dance: Rename tests so that tap_dance is used consistently ([#17396](https://github.com/qmk/qmk_firmware/pull/17396))
|
||||||
|
* IS31FL3737 Global Current Setting ([#17420](https://github.com/qmk/qmk_firmware/pull/17420))
|
||||||
|
* [QP] Add ILI9488 support. ([#17438](https://github.com/qmk/qmk_firmware/pull/17438))
|
||||||
|
* Mark GD32VF103 as ChibiOS-Contrib ([#17444](https://github.com/qmk/qmk_firmware/pull/17444))
|
||||||
|
* ISSI Drivers Global Current Option ([#17448](https://github.com/qmk/qmk_firmware/pull/17448))
|
||||||
|
* [Split] pointing transport check ([#17481](https://github.com/qmk/qmk_firmware/pull/17481))
|
||||||
|
* Cirque trackpad features: circular scroll, inertial cursor ([#17482](https://github.com/qmk/qmk_firmware/pull/17482))
|
||||||
|
* RGB heatmap skip NO_LED ([#17488](https://github.com/qmk/qmk_firmware/pull/17488))
|
||||||
|
* Add kb2040 and sparkfun rp2040 converters ([#17514](https://github.com/qmk/qmk_firmware/pull/17514))
|
||||||
|
* [style] rp2040 stage2 formatting ([#17516](https://github.com/qmk/qmk_firmware/pull/17516))
|
||||||
|
* Also check /run/media/ for uf2 drives ([#17517](https://github.com/qmk/qmk_firmware/pull/17517))
|
||||||
|
* RP2040 emulated EEPROM. ([#17519](https://github.com/qmk/qmk_firmware/pull/17519))
|
||||||
|
* Make debounce algorithms signal matrix changes ([#17554](https://github.com/qmk/qmk_firmware/pull/17554))
|
||||||
|
* Update PM2040 I2C pins ([#17578](https://github.com/qmk/qmk_firmware/pull/17578))
|
||||||
|
* Added implementation of WB32 MCU wear_leveling_efl. ([#17579](https://github.com/qmk/qmk_firmware/pull/17579))
|
||||||
|
* Use Pro Micro SDA/SCL pinout for PM2040 ([#17595](https://github.com/qmk/qmk_firmware/pull/17595))
|
||||||
|
* Refactor Pixel Fractal effect ([#17602](https://github.com/qmk/qmk_firmware/pull/17602))
|
||||||
|
* Add Blok RP2040 converter ([#17603](https://github.com/qmk/qmk_firmware/pull/17603))
|
||||||
|
* Use polled waiting on ChibiOS platforms that support it ([#17607](https://github.com/qmk/qmk_firmware/pull/17607))
|
||||||
|
* Stabilize Half-duplex RP2040 PIO split comms ([#17612](https://github.com/qmk/qmk_firmware/pull/17612))
|
||||||
|
* PMW33XX drivers overhaul ([#17613](https://github.com/qmk/qmk_firmware/pull/17613))
|
||||||
|
* Include stdint.h in avr/i2c_master.h ([#17639](https://github.com/qmk/qmk_firmware/pull/17639))
|
||||||
|
* Add led matrix support for CKLED2001 ([#17643](https://github.com/qmk/qmk_firmware/pull/17643))
|
||||||
|
* `STM32_USB_USE_OTG1` => `USB_ENDPOINTS_ARE_REORDERABLE` ([#17647](https://github.com/qmk/qmk_firmware/pull/17647))
|
||||||
|
* Allow MCU-specific overrides for SPI flags. ([#17650](https://github.com/qmk/qmk_firmware/pull/17650))
|
||||||
|
* Update LED/RGB Matrix flag function behavior ([#17651](https://github.com/qmk/qmk_firmware/pull/17651))
|
||||||
|
* Cirque circular scroll: Support POINTING_DEVICE_COMBINED ([#17654](https://github.com/qmk/qmk_firmware/pull/17654))
|
||||||
|
* Add support for PAW3204 Optical Sensor ([#17669](https://github.com/qmk/qmk_firmware/pull/17669))
|
||||||
|
* Add LED limits call ([#17679](https://github.com/qmk/qmk_firmware/pull/17679))
|
||||||
|
* Move Pointing Device code to a subdirectory ([#17684](https://github.com/qmk/qmk_firmware/pull/17684))
|
||||||
|
* Avoid OOB in dynamic_keymap_reset ([#17695](https://github.com/qmk/qmk_firmware/pull/17695))
|
||||||
|
* Allow dynamic keymap to compile without `via.h` ([#17703](https://github.com/qmk/qmk_firmware/pull/17703))
|
||||||
|
* Use correct angle tune range of +/-127 on PMW33XX ([#17708](https://github.com/qmk/qmk_firmware/pull/17708))
|
||||||
|
* Add Bonsai C4 converter ([#17711](https://github.com/qmk/qmk_firmware/pull/17711))
|
||||||
|
* VIA Encoder Map Support ([#17734](https://github.com/qmk/qmk_firmware/pull/17734))
|
||||||
|
* Move Pointing Device Initialization to after Split Post Initialization ([#17740](https://github.com/qmk/qmk_firmware/pull/17740))
|
||||||
|
* Add ability to enter bootloader mode from `QK_MAKE` ([#17745](https://github.com/qmk/qmk_firmware/pull/17745))
|
||||||
|
* Add `tap_code16_delay` ([#17748](https://github.com/qmk/qmk_firmware/pull/17748))
|
||||||
|
* Implement relative mode for Cirque trackpad ([#17760](https://github.com/qmk/qmk_firmware/pull/17760))
|
||||||
|
* Create generic Pointing Device Pin defines ([#17776](https://github.com/qmk/qmk_firmware/pull/17776))
|
||||||
|
* Constrain Cirque Pinnacle coordinates ([#17803](https://github.com/qmk/qmk_firmware/pull/17803))
|
||||||
|
* Refactor/rename postprocess_steno_user → post_process_steno_user ([#17823](https://github.com/qmk/qmk_firmware/pull/17823))
|
||||||
|
* Add Bit-C PRO converter ([#17827](https://github.com/qmk/qmk_firmware/pull/17827))
|
||||||
|
* guard RPC invocation by checking RPC info against crc checksum ([#17840](https://github.com/qmk/qmk_firmware/pull/17840))
|
||||||
|
* Add ST7735 driver to Quantum Painter ([#17848](https://github.com/qmk/qmk_firmware/pull/17848))
|
||||||
|
* Add minimal STM32F103C6 support ([#17853](https://github.com/qmk/qmk_firmware/pull/17853))
|
||||||
|
* Remove legacy AVR ssd1306 driver ([#17864](https://github.com/qmk/qmk_firmware/pull/17864))
|
||||||
|
* Remove tmk_core 'serial' code ([#17866](https://github.com/qmk/qmk_firmware/pull/17866))
|
||||||
|
* Use LT_ZCAR in place of LT_PLUS for modded kc definitions of keymap_lithuanian_qwerty.h ([#18000](https://github.com/qmk/qmk_firmware/pull/18000))
|
||||||
|
* Remove invisible variation selector-15 from keymap_japanese.h ([#18007](https://github.com/qmk/qmk_firmware/pull/18007))
|
||||||
|
* define CZ_PERC S(CZ_PLUS) → define CZ_PERC S(CZ_EQL) ([#18008](https://github.com/qmk/qmk_firmware/pull/18008))
|
||||||
|
* KR_DQUO S(KR_COLN) → KR_DQUO S(KR_QUOT) in keymap_korean.h ([#18011](https://github.com/qmk/qmk_firmware/pull/18011))
|
||||||
|
* Replace ; by : in the shifted symbols ASCII art of keymap_norman ([#18029](https://github.com/qmk/qmk_firmware/pull/18029))
|
||||||
|
* Add eeprom defaults for tinyuf2 bootloader ([#18042](https://github.com/qmk/qmk_firmware/pull/18042))
|
||||||
|
* Remove duplicate COMBINING HORN in keymap_us_extended.h ([#18045](https://github.com/qmk/qmk_firmware/pull/18045))
|
||||||
|
* Nix shell updates for `develop` ([#18131](https://github.com/qmk/qmk_firmware/pull/18131))
|
||||||
|
|
||||||
|
CLI:
|
||||||
|
* Add cli command to import keyboard|keymap|kbfirmware ([#16668](https://github.com/qmk/qmk_firmware/pull/16668))
|
||||||
|
* Publish data as part of API generation ([#17020](https://github.com/qmk/qmk_firmware/pull/17020))
|
||||||
|
* Allow encoder config from info.json ([#17295](https://github.com/qmk/qmk_firmware/pull/17295))
|
||||||
|
* `qmk doctor`: show arch for macOS ([#17356](https://github.com/qmk/qmk_firmware/pull/17356))
|
||||||
|
* Use --exclude-from=.gitignore in place of --exclude-standard ([#17399](https://github.com/qmk/qmk_firmware/pull/17399))
|
||||||
|
* Improve importer workflow ([#17707](https://github.com/qmk/qmk_firmware/pull/17707))
|
||||||
|
* Remove legacy bootmagic cli parsing ([#18099](https://github.com/qmk/qmk_firmware/pull/18099))
|
||||||
|
* Align CLI requirements ([#18117](https://github.com/qmk/qmk_firmware/pull/18117))
|
||||||
|
|
||||||
|
Submodule updates:
|
||||||
|
* Add Raspberry Pi RP2040 support ([#14877](https://github.com/qmk/qmk_firmware/pull/14877))
|
||||||
|
* Update mpaland/printf to eyalroz/printf fork ([#16163](https://github.com/qmk/qmk_firmware/pull/16163))
|
||||||
|
* Generic wear-leveling algorithm ([#16996](https://github.com/qmk/qmk_firmware/pull/16996))
|
||||||
|
* Update LUFA submodule ([#17368](https://github.com/qmk/qmk_firmware/pull/17368))
|
||||||
|
* Update V-USB submodule ([#17385](https://github.com/qmk/qmk_firmware/pull/17385))
|
||||||
|
* Update ChibiOS-Contrib ([#17540](https://github.com/qmk/qmk_firmware/pull/17540))
|
||||||
|
* Update to latest ChibiOS-Contrib. ([#18016](https://github.com/qmk/qmk_firmware/pull/18016))
|
||||||
|
* Update LUFA submodule ([#18168](https://github.com/qmk/qmk_firmware/pull/18168))
|
||||||
|
|
||||||
|
Keyboards:
|
||||||
|
* GMMK 2 WBG7 MCU compatibility ([#16436](https://github.com/qmk/qmk_firmware/pull/16436))
|
||||||
|
* bastardkb: restructure folder hierarchy ([#16778](https://github.com/qmk/qmk_firmware/pull/16778))
|
||||||
|
* Add Gentleman 65 SE Solderd PCB support ([#16992](https://github.com/qmk/qmk_firmware/pull/16992))
|
||||||
|
* Move/Rename to Hillside48, simplify default keymap ([#17210](https://github.com/qmk/qmk_firmware/pull/17210))
|
||||||
|
* IDOBAO ID67 code touch-ups and include factory keymap ([#17231](https://github.com/qmk/qmk_firmware/pull/17231))
|
||||||
|
* IDOBAO ID87v2 code rewrite and include factory keymap ([#17232](https://github.com/qmk/qmk_firmware/pull/17232))
|
||||||
|
* IDOBAO ID80v3 code rewrite and include factory keymap ([#17234](https://github.com/qmk/qmk_firmware/pull/17234))
|
||||||
|
* IDOBAO ID80v1 folder rename ([#17265](https://github.com/qmk/qmk_firmware/pull/17265))
|
||||||
|
* Fine!40 PCB Support ([#17426](https://github.com/qmk/qmk_firmware/pull/17426))
|
||||||
|
* Update Charybdis code for Extended Mouse reports ([#17435](https://github.com/qmk/qmk_firmware/pull/17435))
|
||||||
|
* (develop)AP2: Enable support for WL EEPROM Driver ([#17506](https://github.com/qmk/qmk_firmware/pull/17506))
|
||||||
|
* (develop)Keychron Q2: Enable support for WL EEPROM Driver ([#17507](https://github.com/qmk/qmk_firmware/pull/17507))
|
||||||
|
* Add Adafruit Macropad RP2040 ([#17512](https://github.com/qmk/qmk_firmware/pull/17512))
|
||||||
|
* Add RP2040 config defaults ([#17557](https://github.com/qmk/qmk_firmware/pull/17557))
|
||||||
|
* Add support keyboard Feker IK75 ([#17611](https://github.com/qmk/qmk_firmware/pull/17611))
|
||||||
|
* boardsource/holiday/spooky data driven ([#17632](https://github.com/qmk/qmk_firmware/pull/17632))
|
||||||
|
* boardsource/lulu data driven ([#17638](https://github.com/qmk/qmk_firmware/pull/17638))
|
||||||
|
* Added support for gmmk pro rev2 keyboard. ([#17655](https://github.com/qmk/qmk_firmware/pull/17655))
|
||||||
|
* boardsource/microdox data driven ([#17675](https://github.com/qmk/qmk_firmware/pull/17675))
|
||||||
|
* Remove full bootmagic config from user files ([#17702](https://github.com/qmk/qmk_firmware/pull/17702))
|
||||||
|
* (develop) Update bootmagic for Adafruit Macropad ([#17755](https://github.com/qmk/qmk_firmware/pull/17755))
|
||||||
|
* Add a kb2040 version of the onkey keyboard that works with the oled keymap ([#17786](https://github.com/qmk/qmk_firmware/pull/17786))
|
||||||
|
* Enable mousekeys by default for RGBKB Sol3 ([#17842](https://github.com/qmk/qmk_firmware/pull/17842))
|
||||||
|
* More glyph transformations for spidey3 userspace ([#17854](https://github.com/qmk/qmk_firmware/pull/17854))
|
||||||
|
* Default rgblight ([#17855](https://github.com/qmk/qmk_firmware/pull/17855))
|
||||||
|
* Refactor satt/comet46 to use core OLED driver ([#17856](https://github.com/qmk/qmk_firmware/pull/17856))
|
||||||
|
* Convert yosino58 to use split common ([#17861](https://github.com/qmk/qmk_firmware/pull/17861))
|
||||||
|
* Migrate crkbd keymaps to oled driver ([#17863](https://github.com/qmk/qmk_firmware/pull/17863))
|
||||||
|
* Overhaul uzu42 ([#17868](https://github.com/qmk/qmk_firmware/pull/17868))
|
||||||
|
* Update ginkgo65hot to allow use of community layouts ([#17911](https://github.com/qmk/qmk_firmware/pull/17911))
|
||||||
|
* Remove `UNUSED_PINS` ([#17931](https://github.com/qmk/qmk_firmware/pull/17931))
|
||||||
|
* RESET -> QK_BOOT user keymaps ([#17940](https://github.com/qmk/qmk_firmware/pull/17940))
|
||||||
|
* Add cursor layer to DMQ Spin ([#17996](https://github.com/qmk/qmk_firmware/pull/17996))
|
||||||
|
* add new keyboard 'soda/cherish' ([#18057](https://github.com/qmk/qmk_firmware/pull/18057))
|
||||||
|
* Move keyboard USB IDs and strings to data driven: develop ([#18152](https://github.com/qmk/qmk_firmware/pull/18152))
|
||||||
|
|
||||||
|
Keyboard fixes:
|
||||||
|
* Fixup SPI mode 3 => 0 on tzarc/djinn, `develop`. ([#17440](https://github.com/qmk/qmk_firmware/pull/17440))
|
||||||
|
* Fixup doio/kb16 ([#17545](https://github.com/qmk/qmk_firmware/pull/17545))
|
||||||
|
* Adafruit Macropad: Add VIA keymap, fix default km ([#17735](https://github.com/qmk/qmk_firmware/pull/17735))
|
||||||
|
* Fix compilation issues for Charybdis/Dilemma ([#17791](https://github.com/qmk/qmk_firmware/pull/17791))
|
||||||
|
* bastardkb: fix info.json changes that got reverted during the last merge from `master` to `develop` ([#17800](https://github.com/qmk/qmk_firmware/pull/17800))
|
||||||
|
* Fixup uzu42 ([#17867](https://github.com/qmk/qmk_firmware/pull/17867))
|
||||||
|
* use correct function in Dilemma splinky ([#17923](https://github.com/qmk/qmk_firmware/pull/17923))
|
||||||
|
* Fix compilation issues for Boardsource Microdox ([#18037](https://github.com/qmk/qmk_firmware/pull/18037))
|
||||||
|
* Fixup gmmk/pro/rev2 USB Data ([#18056](https://github.com/qmk/qmk_firmware/pull/18056))
|
||||||
|
|
||||||
|
Others:
|
||||||
|
* backlight|led 'on state' for DD configuration ([#17383](https://github.com/qmk/qmk_firmware/pull/17383))
|
||||||
|
* Dump out the largest symbols in flash and in RAM. ([#17397](https://github.com/qmk/qmk_firmware/pull/17397))
|
||||||
|
* Re-order user space rules inclusion ([#17459](https://github.com/qmk/qmk_firmware/pull/17459))
|
||||||
|
* Update feature_split_keyboard.md to add extra detail about left and right matrices. ([#17492](https://github.com/qmk/qmk_firmware/pull/17492))
|
||||||
|
* Swap F4x1 default board files away from blackpill ([#17522](https://github.com/qmk/qmk_firmware/pull/17522))
|
||||||
|
* Add converter docs ([#17593](https://github.com/qmk/qmk_firmware/pull/17593))
|
||||||
|
* Updates to Pointing Device Docs ([#17777](https://github.com/qmk/qmk_firmware/pull/17777))
|
||||||
|
* Add deprecated check for RGBLIGHT_ANIMATIONS ([#17832](https://github.com/qmk/qmk_firmware/pull/17832))
|
||||||
|
* Remove OLED driver Split Common warning ([#17862](https://github.com/qmk/qmk_firmware/pull/17862))
|
||||||
|
* Revert " Re-order user space rules inclusion (#17459)" ([#18032](https://github.com/qmk/qmk_firmware/pull/18032))
|
||||||
|
|
||||||
|
Bugs:
|
||||||
|
* Minor schema fixes ([#14200](https://github.com/qmk/qmk_firmware/pull/14200))
|
||||||
|
* Fix buffer size for WS2812 PWM driver ([#17046](https://github.com/qmk/qmk_firmware/pull/17046))
|
||||||
|
* Fix AVR I2C master 1ms timeout ([#17174](https://github.com/qmk/qmk_firmware/pull/17174))
|
||||||
|
* Mouse key kinetic mode fix ([#17176](https://github.com/qmk/qmk_firmware/pull/17176))
|
||||||
|
* Fix RGB heatmap to use XY positions and use correct led limits. ([#17184](https://github.com/qmk/qmk_firmware/pull/17184))
|
||||||
|
* Fix keys being discarded after using the leader key ([#17287](https://github.com/qmk/qmk_firmware/pull/17287))
|
||||||
|
* Fixup pimoroni trackball ([#17335](https://github.com/qmk/qmk_firmware/pull/17335))
|
||||||
|
* Fix via builds broken by brightness scaling ([#17354](https://github.com/qmk/qmk_firmware/pull/17354))
|
||||||
|
* SPI Bugfix for ChibiOS `21.11.1` => `21.11.2` ([#17371](https://github.com/qmk/qmk_firmware/pull/17371))
|
||||||
|
* Additional schema fixes ([#17414](https://github.com/qmk/qmk_firmware/pull/17414))
|
||||||
|
* Fix deadlocks on disconnected secondary half ([#17423](https://github.com/qmk/qmk_firmware/pull/17423))
|
||||||
|
* [Fix] Fix compilation warning for non-split keebs after #17423 ([#17439](https://github.com/qmk/qmk_firmware/pull/17439))
|
||||||
|
* Fix Caps Word to treat mod-taps more consistently. ([#17463](https://github.com/qmk/qmk_firmware/pull/17463))
|
||||||
|
* Fix docs regarding `USB_SUSPEND_WAKEUP_DELAY` ([#17501](https://github.com/qmk/qmk_firmware/pull/17501))
|
||||||
|
* Fixup SSD1351 build after #17438 ([#17533](https://github.com/qmk/qmk_firmware/pull/17533))
|
||||||
|
* Fixup SPI init procedure, SPI EEPROM sequencing ([#17534](https://github.com/qmk/qmk_firmware/pull/17534))
|
||||||
|
* Fix Caps Word capitalization when used with Combos + Auto Shift. ([#17549](https://github.com/qmk/qmk_firmware/pull/17549))
|
||||||
|
* Allow for `keymaps` array to be implemented in a file other than `$(KEYMAP_C)` ([#17559](https://github.com/qmk/qmk_firmware/pull/17559))
|
||||||
|
* [Fix] printf update aftermath ([#17584](https://github.com/qmk/qmk_firmware/pull/17584))
|
||||||
|
* Fix rgbkb/sol/rev2 build issues ([#17601](https://github.com/qmk/qmk_firmware/pull/17601))
|
||||||
|
* More DD encoder fixes ([#17615](https://github.com/qmk/qmk_firmware/pull/17615))
|
||||||
|
* [Fix] Make ChibiOS `_wait.h` independent of `quantum.h` ([#17645](https://github.com/qmk/qmk_firmware/pull/17645))
|
||||||
|
* Grammar fixes for docs/feature_converters.md ([#17652](https://github.com/qmk/qmk_firmware/pull/17652))
|
||||||
|
* Fix compilation issue with Cirque Guestures file ([#17656](https://github.com/qmk/qmk_firmware/pull/17656))
|
||||||
|
* Fix compile issue with LED Matrix ([#17658](https://github.com/qmk/qmk_firmware/pull/17658))
|
||||||
|
* Post-bootloader EFL/SPI fixes. ([#17661](https://github.com/qmk/qmk_firmware/pull/17661))
|
||||||
|
* Fix LED limit loop ([#17678](https://github.com/qmk/qmk_firmware/pull/17678))
|
||||||
|
* [Fix] Use correct angle tune range of +/-30 on PMW33XX ([#17693](https://github.com/qmk/qmk_firmware/pull/17693))
|
||||||
|
* Fix AVR compilation of FNV by using standard integer typenames. ([#17716](https://github.com/qmk/qmk_firmware/pull/17716))
|
||||||
|
* fix syntax error in header file ([#17732](https://github.com/qmk/qmk_firmware/pull/17732))
|
||||||
|
* Fix custom debug function and sample output ([#17790](https://github.com/qmk/qmk_firmware/pull/17790))
|
||||||
|
* Fix QK_MAKE's reboot check ([#17795](https://github.com/qmk/qmk_firmware/pull/17795))
|
||||||
|
* Chibios: Stop I2C peripheral on transaction error ([#17798](https://github.com/qmk/qmk_firmware/pull/17798))
|
||||||
|
* Fix ChibiOS `i2c_master` error codes ([#17808](https://github.com/qmk/qmk_firmware/pull/17808))
|
||||||
|
* Update ChibiOS Contrib for RP2040 fixes ([#17817](https://github.com/qmk/qmk_firmware/pull/17817))
|
||||||
|
* RP2040 disable PIO IRQs on serial timeout ([#17839](https://github.com/qmk/qmk_firmware/pull/17839))
|
||||||
|
* Fix POINTING_DEVICE_GESTURES_SCROLL_ENABLE typo ([#17850](https://github.com/qmk/qmk_firmware/pull/17850))
|
||||||
|
* Fixup compilation of printf-like functions with uint32_t args. ([#17904](https://github.com/qmk/qmk_firmware/pull/17904))
|
||||||
|
* Fix issue with #17904. ([#17905](https://github.com/qmk/qmk_firmware/pull/17905))
|
||||||
|
* Always run pointing device init ([#17936](https://github.com/qmk/qmk_firmware/pull/17936))
|
||||||
|
* Align TO() max layers with other keycodes ([#17989](https://github.com/qmk/qmk_firmware/pull/17989))
|
||||||
|
* Fix Bépo's BP_NNBS (narrow non-breaking space) ([#17999](https://github.com/qmk/qmk_firmware/pull/17999))
|
||||||
|
* Move Encoder+Encoder Map from generic features ([#18018](https://github.com/qmk/qmk_firmware/pull/18018))
|
||||||
|
* Fix wrong varaible in encoder block ([#18020](https://github.com/qmk/qmk_firmware/pull/18020))
|
||||||
|
* Fix LV_CCAR and LV_NCED in keymap_latvian.h ([#18025](https://github.com/qmk/qmk_firmware/pull/18025))
|
||||||
|
* Use ANSI ASCII art and fix comments for LT_COLN and LT_UNDS in keymap_lithuanian_qwerty.h ([#18028](https://github.com/qmk/qmk_firmware/pull/18028))
|
||||||
|
* Partially revert some WB32 specific changes ([#18038](https://github.com/qmk/qmk_firmware/pull/18038))
|
||||||
|
* Fix Emulated EEPROM issue with F466 ([#18039](https://github.com/qmk/qmk_firmware/pull/18039))
|
||||||
|
* Fix DV_SCLN and DV_COLN in keymap_spanish_dvorak.h ([#18043](https://github.com/qmk/qmk_firmware/pull/18043))
|
||||||
|
* Fix missing development_board schema entry ([#18050](https://github.com/qmk/qmk_firmware/pull/18050))
|
||||||
|
* Add key event check to `is_tap_record` and remove `is_tap_key` ([#18063](https://github.com/qmk/qmk_firmware/pull/18063))
|
||||||
|
* Fix GD32VF103 WS2812 PWM driver ([#18067](https://github.com/qmk/qmk_firmware/pull/18067))
|
||||||
|
* Fix new-keyboard default for RP2040 bootloader ([#18100](https://github.com/qmk/qmk_firmware/pull/18100))
|
||||||
|
* Fixup F4xx wear-leveling bootloader check ([#18102](https://github.com/qmk/qmk_firmware/pull/18102))
|
||||||
|
* Fix PID value for the Keyboardio Atreus 2 bootloader ([#18116](https://github.com/qmk/qmk_firmware/pull/18116))
|
||||||
|
* Add missing SS_LOPT and SS_ROPT defines ([#18175](https://github.com/qmk/qmk_firmware/pull/18175))
|
|
@ -79,18 +79,18 @@
|
||||||
* [Caps Word](feature_caps_word.md)
|
* [Caps Word](feature_caps_word.md)
|
||||||
* [Combos](feature_combo.md)
|
* [Combos](feature_combo.md)
|
||||||
* [Debounce API](feature_debounce_type.md)
|
* [Debounce API](feature_debounce_type.md)
|
||||||
|
* [EEPROM](feature_eeprom.md)
|
||||||
* [Key Lock](feature_key_lock.md)
|
* [Key Lock](feature_key_lock.md)
|
||||||
* [Key Overrides](feature_key_overrides.md)
|
* [Key Overrides](feature_key_overrides.md)
|
||||||
* [Layers](feature_layers.md)
|
* [Layers](feature_layers.md)
|
||||||
* [One Shot Keys](one_shot_keys.md)
|
* [One Shot Keys](one_shot_keys.md)
|
||||||
* [Pointing Device](feature_pointing_device.md)
|
|
||||||
* [Raw HID](feature_rawhid.md)
|
* [Raw HID](feature_rawhid.md)
|
||||||
* [Secure](feature_secure.md)
|
* [Secure](feature_secure.md)
|
||||||
|
* [Send String](feature_send_string.md)
|
||||||
* [Sequencer](feature_sequencer.md)
|
* [Sequencer](feature_sequencer.md)
|
||||||
* [Swap Hands](feature_swap_hands.md)
|
* [Swap Hands](feature_swap_hands.md)
|
||||||
* [Tap Dance](feature_tap_dance.md)
|
* [Tap Dance](feature_tap_dance.md)
|
||||||
* [Tap-Hold Configuration](tap_hold.md)
|
* [Tap-Hold Configuration](tap_hold.md)
|
||||||
* [Terminal](feature_terminal.md)
|
|
||||||
* [Unicode](feature_unicode.md)
|
* [Unicode](feature_unicode.md)
|
||||||
* [Userspace](feature_userspace.md)
|
* [Userspace](feature_userspace.md)
|
||||||
* [WPM Calculation](feature_wpm.md)
|
* [WPM Calculation](feature_wpm.md)
|
||||||
|
@ -109,6 +109,7 @@
|
||||||
* [Audio](feature_audio.md)
|
* [Audio](feature_audio.md)
|
||||||
* [Bluetooth](feature_bluetooth.md)
|
* [Bluetooth](feature_bluetooth.md)
|
||||||
* [Bootmagic Lite](feature_bootmagic.md)
|
* [Bootmagic Lite](feature_bootmagic.md)
|
||||||
|
* [Converters](feature_converters.md)
|
||||||
* [Custom Matrix](custom_matrix.md)
|
* [Custom Matrix](custom_matrix.md)
|
||||||
* [Digitizer](feature_digitizer.md)
|
* [Digitizer](feature_digitizer.md)
|
||||||
* [DIP Switch](feature_dip_switch.md)
|
* [DIP Switch](feature_dip_switch.md)
|
||||||
|
@ -117,7 +118,7 @@
|
||||||
* [Joystick](feature_joystick.md)
|
* [Joystick](feature_joystick.md)
|
||||||
* [LED Indicators](feature_led_indicators.md)
|
* [LED Indicators](feature_led_indicators.md)
|
||||||
* [MIDI](feature_midi.md)
|
* [MIDI](feature_midi.md)
|
||||||
* [Proton C Conversion](proton_c_conversion.md)
|
* [Pointing Device](feature_pointing_device.md)
|
||||||
* [PS/2 Mouse](feature_ps2_mouse.md)
|
* [PS/2 Mouse](feature_ps2_mouse.md)
|
||||||
* [Split Keyboard](feature_split_keyboard.md)
|
* [Split Keyboard](feature_split_keyboard.md)
|
||||||
* [Stenography](feature_stenography.md)
|
* [Stenography](feature_stenography.md)
|
||||||
|
@ -135,7 +136,7 @@
|
||||||
* Breaking Changes
|
* Breaking Changes
|
||||||
* [Overview](breaking_changes.md)
|
* [Overview](breaking_changes.md)
|
||||||
* [My Pull Request Was Flagged](breaking_changes_instructions.md)
|
* [My Pull Request Was Flagged](breaking_changes_instructions.md)
|
||||||
* [Most Recent ChangeLog](ChangeLog/20220528.md "QMK v0.17.0 - 2022 May 28")
|
* [Most Recent ChangeLog](ChangeLog/20220827.md "QMK v0.18.0 - 2022 Aug 27")
|
||||||
* [Past Breaking Changes](breaking_changes_history.md)
|
* [Past Breaking Changes](breaking_changes_history.md)
|
||||||
|
|
||||||
* C Development
|
* C Development
|
||||||
|
@ -149,6 +150,7 @@
|
||||||
* [SPI Driver](spi_driver.md)
|
* [SPI Driver](spi_driver.md)
|
||||||
* [WS2812 Driver](ws2812_driver.md)
|
* [WS2812 Driver](ws2812_driver.md)
|
||||||
* [EEPROM Driver](eeprom_driver.md)
|
* [EEPROM Driver](eeprom_driver.md)
|
||||||
|
* [Flash Driver](flash_driver.md)
|
||||||
* ['serial' Driver](serial_driver.md)
|
* ['serial' Driver](serial_driver.md)
|
||||||
* [UART Driver](uart_driver.md)
|
* [UART Driver](uart_driver.md)
|
||||||
* [GPIO Controls](gpio_control.md)
|
* [GPIO Controls](gpio_control.md)
|
||||||
|
@ -167,6 +169,8 @@
|
||||||
* Arm/ChibiOS
|
* Arm/ChibiOS
|
||||||
* [Selecting an MCU](platformdev_selecting_arm_mcu.md)
|
* [Selecting an MCU](platformdev_selecting_arm_mcu.md)
|
||||||
* [Early initialization](platformdev_chibios_earlyinit.md)
|
* [Early initialization](platformdev_chibios_earlyinit.md)
|
||||||
|
* [Raspberry Pi RP2040](platformdev_rp2040.md)
|
||||||
|
* [Proton C](platformdev_proton_c.md)
|
||||||
* [WeAct Blackpill F411](platformdev_blackpill_f411.md)
|
* [WeAct Blackpill F411](platformdev_blackpill_f411.md)
|
||||||
|
|
||||||
* QMK Reference
|
* QMK Reference
|
||||||
|
|
|
@ -16,7 +16,7 @@ This service is an asynchronous API for compiling custom keymaps. You POST some
|
||||||
"layers": [
|
"layers": [
|
||||||
["KC_GRV","KC_1","KC_2","KC_3","KC_4","KC_5","KC_6","KC_7","KC_8","KC_9","KC_0","KC_MINS","KC_EQL","KC_GRV","KC_BSPC","KC_PGUP","KC_TAB","KC_Q","KC_W","KC_E","KC_R","KC_T","KC_Y","KC_U","KC_I","KC_O","KC_P","KC_LBRC","KC_RBRC","KC_BSLS","KC_PGDN","KC_CAPS","KC_A","KC_S","KC_D","KC_F","KC_G","KC_H","KC_J","KC_K","KC_L","KC_SCLN","KC_QUOT","KC_NUHS","KC_ENT","KC_LSFT","KC_NUBS","KC_Z","KC_X","KC_C","KC_V","KC_B","KC_N","KC_M","KC_COMM","KC_DOT","KC_SLSH","KC_RO","KC_RSFT","KC_UP","KC_LCTL","KC_LGUI","KC_LALT","KC_MHEN","KC_SPC","KC_SPC","KC_HENK","KC_RALT","KC_RCTL","MO(1)","KC_LEFT","KC_DOWN","KC_RIGHT"],
|
["KC_GRV","KC_1","KC_2","KC_3","KC_4","KC_5","KC_6","KC_7","KC_8","KC_9","KC_0","KC_MINS","KC_EQL","KC_GRV","KC_BSPC","KC_PGUP","KC_TAB","KC_Q","KC_W","KC_E","KC_R","KC_T","KC_Y","KC_U","KC_I","KC_O","KC_P","KC_LBRC","KC_RBRC","KC_BSLS","KC_PGDN","KC_CAPS","KC_A","KC_S","KC_D","KC_F","KC_G","KC_H","KC_J","KC_K","KC_L","KC_SCLN","KC_QUOT","KC_NUHS","KC_ENT","KC_LSFT","KC_NUBS","KC_Z","KC_X","KC_C","KC_V","KC_B","KC_N","KC_M","KC_COMM","KC_DOT","KC_SLSH","KC_RO","KC_RSFT","KC_UP","KC_LCTL","KC_LGUI","KC_LALT","KC_MHEN","KC_SPC","KC_SPC","KC_HENK","KC_RALT","KC_RCTL","MO(1)","KC_LEFT","KC_DOWN","KC_RIGHT"],
|
||||||
["KC_ESC","KC_F1","KC_F2","KC_F3","KC_F4","KC_F5","KC_F6","KC_F7","KC_F8","KC_F9","KC_F10","KC_F11","KC_F12","KC_TRNS","KC_DEL","BL_STEP","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","_______","KC_TRNS","KC_PSCR","KC_SLCK","KC_PAUS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(2)","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_PGUP","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(1)","KC_LEFT","KC_PGDN","KC_RGHT"],
|
["KC_ESC","KC_F1","KC_F2","KC_F3","KC_F4","KC_F5","KC_F6","KC_F7","KC_F8","KC_F9","KC_F10","KC_F11","KC_F12","KC_TRNS","KC_DEL","BL_STEP","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","_______","KC_TRNS","KC_PSCR","KC_SLCK","KC_PAUS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(2)","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_PGUP","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(1)","KC_LEFT","KC_PGDN","KC_RGHT"],
|
||||||
["KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","RESET","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(2)","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(1)","KC_TRNS","KC_TRNS","KC_TRNS"]
|
["KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","QK_BOOT","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(2)","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(1)","KC_TRNS","KC_TRNS","KC_TRNS"]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
@ -8,6 +8,7 @@ The breaking change period is when we will merge PR's that change QMK in dangero
|
||||||
|
|
||||||
## What has been included in past Breaking Changes?
|
## What has been included in past Breaking Changes?
|
||||||
|
|
||||||
|
* [2022 Aug 27](ChangeLog/20220827.md)
|
||||||
* [2022 May 28](ChangeLog/20220528.md)
|
* [2022 May 28](ChangeLog/20220528.md)
|
||||||
* [2022 Feb 26](ChangeLog/20220226.md)
|
* [2022 Feb 26](ChangeLog/20220226.md)
|
||||||
* [2021 Nov 27](ChangeLog/20211127.md)
|
* [2021 Nov 27](ChangeLog/20211127.md)
|
||||||
|
@ -22,18 +23,18 @@ The breaking change period is when we will merge PR's that change QMK in dangero
|
||||||
|
|
||||||
## When is the next Breaking Change?
|
## When is the next Breaking Change?
|
||||||
|
|
||||||
The next Breaking Change is scheduled for August 27, 2022.
|
The next Breaking Change is scheduled for November 26, 2022.
|
||||||
|
|
||||||
### Important Dates
|
### Important Dates
|
||||||
|
|
||||||
* 2022 May 28 - `develop` is tagged with a new release version. Each push to `master` is subsequently merged to `develop` by GitHub actions.
|
* 2022 Aug 27 - `develop` is tagged with a new release version. Each push to `master` is subsequently merged to `develop` by GitHub actions.
|
||||||
* 2022 Jul 31 - `develop` closed to new PR's.
|
* 2022 Oct 29 - `develop` closed to new PR's.
|
||||||
* 2022 Jul 31 - Call for testers.
|
* 2022 Oct 29 - Call for testers.
|
||||||
* 2022 Aug 13 - Last day for merges -- after this point `develop` is locked for testing and accepts only bugfixes
|
* 2022 Nov 12 - Last day for merges -- after this point `develop` is locked for testing and accepts only bugfixes
|
||||||
* 2022 Aug 20 - `develop` is locked, only critical bugfix PR's merged.
|
* 2022 Nov 19 - `develop` is locked, only critical bugfix PR's merged.
|
||||||
* 2022 Aug 25 - `master` is locked, no PR's merged.
|
* 2022 Nov 24 - `master` is locked, no PR's merged.
|
||||||
* 2022 Aug 27 - Merge `develop` to `master`.
|
* 2022 Nov 26 - Merge `develop` to `master`.
|
||||||
* 2022 Aug 27 - `master` is unlocked. PR's can be merged again.
|
* 2022 Nov 26 - `master` is unlocked. PR's can be merged again.
|
||||||
|
|
||||||
## What changes will be included?
|
## What changes will be included?
|
||||||
|
|
||||||
|
@ -44,7 +45,7 @@ If you want your breaking change to be included in this round you need to create
|
||||||
Criteria for acceptance:
|
Criteria for acceptance:
|
||||||
|
|
||||||
* The PR is complete and ready to merge
|
* The PR is complete and ready to merge
|
||||||
* The PR has a ChangeLog file describing the changes under `<qmk_firmware>/docs/Changelog/20220827`.
|
* The PR has a ChangeLog file describing the changes under `<qmk_firmware>/docs/Changelog/20221126`.
|
||||||
* This should be in Markdown format, with a name in the format `PR12345.md`, substituting the digits for your PR's ID.
|
* This should be in Markdown format, with a name in the format `PR12345.md`, substituting the digits for your PR's ID.
|
||||||
* One strong recommendation that the ChangeLog document matches the PR description on GitHub, so as to ensure traceability.
|
* One strong recommendation that the ChangeLog document matches the PR description on GitHub, so as to ensure traceability.
|
||||||
|
|
||||||
|
@ -110,7 +111,7 @@ This happens immediately after the previous `develop` branch is merged to `maste
|
||||||
* `git pull --ff-only`
|
* `git pull --ff-only`
|
||||||
* `git merge --no-ff master`
|
* `git merge --no-ff master`
|
||||||
* Edit `readme.md`
|
* Edit `readme.md`
|
||||||
* Add a big notice at the top that this is a testing branch.
|
* Add a big notice at the top that this is a testing branch. See previous revisions of the `develop` branch.
|
||||||
* Include a link to this document
|
* Include a link to this document
|
||||||
* `git commit -m 'Branch point for <DATE> Breaking Change'`
|
* `git commit -m 'Branch point for <DATE> Breaking Change'`
|
||||||
* `git tag breakpoint_<YYYY>_<MM>_<DD>`
|
* `git tag breakpoint_<YYYY>_<MM>_<DD>`
|
||||||
|
@ -121,15 +122,19 @@ This happens immediately after the previous `develop` branch is merged to `maste
|
||||||
* Validate each submodule SHA1 matches the qmk fork, e.g. for ChibiOS:
|
* Validate each submodule SHA1 matches the qmk fork, e.g. for ChibiOS:
|
||||||
* Go to [qmk/ChibiOS](https://github.com/qmk/ChibiOS)
|
* Go to [qmk/ChibiOS](https://github.com/qmk/ChibiOS)
|
||||||
* Compare the commit hash in the above output to the commit hash in the repository
|
* Compare the commit hash in the above output to the commit hash in the repository
|
||||||
* If there's a mismatch:
|
* If there's a mismatch, that repository needs to have its `master` branch updated to match (otherwise Configurator won't work):
|
||||||
* `cd lib/chibios`
|
* `cd lib/chibios`
|
||||||
* `git fetch --all`
|
* `git fetch --all`
|
||||||
* `git checkout master`
|
* `git checkout master`
|
||||||
* `git reset --hard <commit hash>`
|
* `git reset --hard <commit hash>`
|
||||||
* `git push origin master --force-with-lease`
|
* `git push origin master --force-with-lease`
|
||||||
|
|
||||||
|
* Announce that both `master` and `develop` are now unlocked -- message `@Breaking Changes Updates` on `#qmk_firmware` in Discord:
|
||||||
|
* `@Breaking Changes Updates -- Hey folks, develop has now been merged into master -- newest batch of changes are now available for everyone to use!`
|
||||||
|
|
||||||
* (Optional) [update ChibiOS + ChibiOS-Contrib on `develop`](chibios_upgrade_instructions.md)
|
* (Optional) [update ChibiOS + ChibiOS-Contrib on `develop`](chibios_upgrade_instructions.md)
|
||||||
|
|
||||||
|
|
||||||
### Set up Discord events for the next cycle
|
### Set up Discord events for the next cycle
|
||||||
|
|
||||||
* Update this file with the new dates: `docs/breaking_changes.md`
|
* Update this file with the new dates: `docs/breaking_changes.md`
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
This page links to all previous changelogs from the QMK Breaking Changes process.
|
This page links to all previous changelogs from the QMK Breaking Changes process.
|
||||||
|
|
||||||
|
* [2022 Aug 27](ChangeLog/20220827.md) - version 0.18.0
|
||||||
* [2022 May 28](ChangeLog/20220528.md) - version 0.17.0
|
* [2022 May 28](ChangeLog/20220528.md) - version 0.17.0
|
||||||
* [2022 Feb 26](ChangeLog/20220226.md) - version 0.16.0
|
* [2022 Feb 26](ChangeLog/20220226.md) - version 0.16.0
|
||||||
* [2021 Nov 27](ChangeLog/20211127.md) - version 0.15.0
|
* [2021 Nov 27](ChangeLog/20211127.md) - version 0.15.0
|
||||||
|
|
|
@ -90,6 +90,8 @@ This command is similar to `qmk compile`, but can also target a bootloader. The
|
||||||
|
|
||||||
This command is directory aware. It will automatically fill in KEYBOARD and/or KEYMAP if you are in a keyboard or keymap directory.
|
This command is directory aware. It will automatically fill in KEYBOARD and/or KEYMAP if you are in a keyboard or keymap directory.
|
||||||
|
|
||||||
|
This command can also flash binary firmware files (hex or bin) such as the ones produced by [Configurator](https://config.qmk.fm).
|
||||||
|
|
||||||
**Usage for Configurator Exports**:
|
**Usage for Configurator Exports**:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -102,6 +104,21 @@ qmk flash [-bl <bootloader>] [-c] [-e <var>=<value>] [-j <num_jobs>] <configurat
|
||||||
qmk flash -kb <keyboard_name> -km <keymap_name> [-bl <bootloader>] [-c] [-e <var>=<value>] [-j <num_jobs>]
|
qmk flash -kb <keyboard_name> -km <keymap_name> [-bl <bootloader>] [-c] [-e <var>=<value>] [-j <num_jobs>]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Usage for pre-compiled firmwares**:
|
||||||
|
|
||||||
|
**Note**: The microcontroller needs to be specified (`-m` argument) for keyboards with the following bootloaders:
|
||||||
|
* HalfKay
|
||||||
|
* QMK HID
|
||||||
|
* USBaspLoader
|
||||||
|
|
||||||
|
ISP flashing is also supported with the following flashers and require the microcontroller to be specified:
|
||||||
|
* USBasp
|
||||||
|
* USBtinyISP
|
||||||
|
|
||||||
|
```
|
||||||
|
qmk flash [-m <microcontroller>] <compiledFirmware.[bin|hex]>
|
||||||
|
```
|
||||||
|
|
||||||
**Listing the Bootloaders**
|
**Listing the Bootloaders**
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -352,6 +369,73 @@ $ qmk via2json -kb ai03/polaris -o polaris_keymap.json polaris_via_backup.json
|
||||||
Ψ Wrote keymap to /home/you/qmk_firmware/polaris_keymap.json
|
Ψ Wrote keymap to /home/you/qmk_firmware/polaris_keymap.json
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## `qmk import-keyboard`
|
||||||
|
|
||||||
|
This command imports a data-driven `info.json` keyboard into the repo.
|
||||||
|
|
||||||
|
**Usage**:
|
||||||
|
|
||||||
|
```
|
||||||
|
usage: qmk import-keyboard [-h] filename
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
|
||||||
|
```
|
||||||
|
$ qmk import-keyboard ~/Downloads/forever60.json
|
||||||
|
Ψ Importing forever60.json.
|
||||||
|
|
||||||
|
Ψ Imported a new keyboard named forever60.
|
||||||
|
Ψ To start working on things, `cd` into keyboards/forever60,
|
||||||
|
Ψ or open the directory in your preferred text editor.
|
||||||
|
Ψ And build with qmk compile -kb forever60 -km default.
|
||||||
|
```
|
||||||
|
|
||||||
|
## `qmk import-keymap`
|
||||||
|
|
||||||
|
This command imports a data-driven `keymap.json` keymap into the repo.
|
||||||
|
|
||||||
|
**Usage**:
|
||||||
|
|
||||||
|
```
|
||||||
|
usage: qmk import-keymap [-h] filename
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
|
||||||
|
```
|
||||||
|
qmk import-keymap ~/Downloads/asdf2.json
|
||||||
|
Ψ Importing asdf2.json.
|
||||||
|
|
||||||
|
Ψ Imported a new keymap named asdf2.
|
||||||
|
Ψ To start working on things, `cd` into keyboards/takashicompany/dogtag/keymaps/asdf2,
|
||||||
|
Ψ or open the directory in your preferred text editor.
|
||||||
|
Ψ And build with qmk compile -kb takashicompany/dogtag -km asdf2.
|
||||||
|
```
|
||||||
|
|
||||||
|
## `qmk import-kbfirmware`
|
||||||
|
|
||||||
|
This command creates a new keyboard based on a [Keyboard Firmware Builder](https://kbfirmware.com/) export.
|
||||||
|
|
||||||
|
**Usage**:
|
||||||
|
|
||||||
|
```
|
||||||
|
usage: qmk import-kbfirmware [-h] filename
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
|
||||||
|
```
|
||||||
|
$ qmk import-kbfirmware ~/Downloads/gh62.json
|
||||||
|
Ψ Importing gh62.json.
|
||||||
|
|
||||||
|
⚠ Support here is basic - Consider using 'qmk new-keyboard' instead
|
||||||
|
Ψ Imported a new keyboard named gh62.
|
||||||
|
Ψ To start working on things, `cd` into keyboards/gh62,
|
||||||
|
Ψ or open the directory in your preferred text editor.
|
||||||
|
Ψ And build with qmk compile -kb gh62 -km default.
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Developer Commands
|
# Developer Commands
|
||||||
|
@ -527,3 +611,4 @@ This command converts a TTF font to an intermediate format for editing, before c
|
||||||
## `qmk painter-convert-font-image`
|
## `qmk painter-convert-font-image`
|
||||||
|
|
||||||
This command converts an intermediate font image to the QFF File Format. See the [Quantum Painter](quantum_painter.md?id=quantum-painter-cli) documentation for more information on this command.
|
This command converts an intermediate font image to the QFF File Format. See the [Quantum Painter](quantum_painter.md?id=quantum-painter-cli) documentation for more information on this command.
|
||||||
|
|
||||||
|
|
|
@ -62,9 +62,17 @@ You can also use any ARM chip with USB that [ChibiOS](https://www.chibios.org) s
|
||||||
* [MK20DX128](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k2x-usb/kinetis-k20-50-mhz-full-speed-usb-mixed-signal-integration-microcontrollers-based-on-arm-cortex-m4-core:K20_50)
|
* [MK20DX128](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k2x-usb/kinetis-k20-50-mhz-full-speed-usb-mixed-signal-integration-microcontrollers-based-on-arm-cortex-m4-core:K20_50)
|
||||||
* [MK20DX256](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k2x-usb/kinetis-k20-72-mhz-full-speed-usb-mixed-signal-integration-microcontrollers-mcus-based-on-arm-cortex-m4-core:K20_72)
|
* [MK20DX256](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k2x-usb/kinetis-k20-72-mhz-full-speed-usb-mixed-signal-integration-microcontrollers-mcus-based-on-arm-cortex-m4-core:K20_72)
|
||||||
* PJRC Teensy 3.2
|
* PJRC Teensy 3.2
|
||||||
|
* [MK64FX512](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k6x-ethernet/kinetis-k64-120-mhz-256-kb-sram-microcontrollers-mcus-based-on-arm-cortex-m4-core:K64_120)
|
||||||
|
* PJRC Teensy 3.5
|
||||||
* [MK66FX1M0](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k6x-ethernet/kinetis-k66-180-mhz-dual-high-speed-full-speed-usbs-2mb-flash-microcontrollers-mcus-based-on-arm-cortex-m4-core:K66_180)
|
* [MK66FX1M0](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k6x-ethernet/kinetis-k66-180-mhz-dual-high-speed-full-speed-usbs-2mb-flash-microcontrollers-mcus-based-on-arm-cortex-m4-core:K66_180)
|
||||||
* PJRC Teensy 3.6
|
* PJRC Teensy 3.6
|
||||||
|
|
||||||
|
### Raspberry Pi
|
||||||
|
|
||||||
|
* [RP2040](https://www.raspberrypi.com/documentation/microcontrollers/rp2040.html)
|
||||||
|
|
||||||
|
For a detailed overview about the RP2040 support by QMK see the [dedicated RP2040 page](platformdev_rp2040.md).
|
||||||
|
|
||||||
## Atmel ATSAM
|
## Atmel ATSAM
|
||||||
|
|
||||||
There is limited support for one of Atmel's ATSAM microcontrollers, that being the [ATSAMD51J18A](https://www.microchip.com/wwwproducts/en/ATSAMD51J18A) used by the [Massdrop keyboards](https://github.com/qmk/qmk_firmware/tree/master/keyboards/massdrop). However, it is not recommended to design a board with this microcontroller as the support is quite specialized to Massdrop hardware.
|
There is limited support for one of Atmel's ATSAM microcontrollers, that being the [ATSAMD51J18A](https://www.microchip.com/wwwproducts/en/ATSAMD51J18A) used by the [Massdrop keyboards](https://github.com/qmk/qmk_firmware/tree/master/keyboards/massdrop). However, it is not recommended to design a board with this microcontroller as the support is quite specialized to Massdrop hardware.
|
||||||
|
|
|
@ -2,7 +2,17 @@
|
||||||
|
|
||||||
QMK is nearly infinitely configurable. Wherever possible we err on the side of allowing users to customize their keyboard, even at the expense of code size. That level of flexibility makes for a daunting configuration experience, however.
|
QMK is nearly infinitely configurable. Wherever possible we err on the side of allowing users to customize their keyboard, even at the expense of code size. That level of flexibility makes for a daunting configuration experience, however.
|
||||||
|
|
||||||
There are two main types of configuration files in QMK- `config.h` and `rules.mk`. 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:
|
There are three main types of configuration files in QMK:
|
||||||
|
|
||||||
|
* `config.h`, which contains various preprocessor directives (`#define`, `#ifdef`)
|
||||||
|
* `rules.mk`, which contains additional variables
|
||||||
|
* `info.json`, which is utilized for [data-driven configuration](https://docs.qmk.fm/#/data_driven_config)
|
||||||
|
|
||||||
|
This page will only discuss the first two types, `config.h` and `rules.mk`.
|
||||||
|
|
||||||
|
?> While not all settings have data-driven equivalents yet, keyboard makers are encouraged to utilize the `info.json` file to set the metadata for their boards when possible. See the [`info.json` Format](https://docs.qmk.fm/#/reference_info_json) page for more details.
|
||||||
|
|
||||||
|
These files exist at various levels in QMK and all files of the same type are combined to build the final configuration. The levels, from lowest priority to highest priority, are:
|
||||||
|
|
||||||
* QMK Default
|
* QMK Default
|
||||||
* Keyboard
|
* Keyboard
|
||||||
|
@ -57,8 +67,6 @@ This is a C header file that is one of the first things included, and will persi
|
||||||
* may be omitted by the keyboard designer if matrix reads are handled in an alternate manner. See [low-level matrix overrides](custom_quantum_functions.md?id=low-level-matrix-overrides) for more information.
|
* may be omitted by the keyboard designer if matrix reads are handled in an alternate manner. See [low-level matrix overrides](custom_quantum_functions.md?id=low-level-matrix-overrides) for more information.
|
||||||
* `#define MATRIX_IO_DELAY 30`
|
* `#define MATRIX_IO_DELAY 30`
|
||||||
* the delay in microseconds when between changing matrix pin state and reading values
|
* the delay in microseconds when between changing matrix pin state and reading values
|
||||||
* `#define UNUSED_PINS { D1, D2, D3, B1, B2, B3 }`
|
|
||||||
* pins unused by the keyboard for reference
|
|
||||||
* `#define MATRIX_HAS_GHOST`
|
* `#define MATRIX_HAS_GHOST`
|
||||||
* define is matrix has ghost (unlikely)
|
* define is matrix has ghost (unlikely)
|
||||||
* `#define MATRIX_UNSELECT_DRIVE_HIGH`
|
* `#define MATRIX_UNSELECT_DRIVE_HIGH`
|
||||||
|
@ -107,8 +115,10 @@ This is a C header file that is one of the first things included, and will persi
|
||||||
* sets the maximum power (in mA) over USB for the device (default: 500)
|
* sets the maximum power (in mA) over USB for the device (default: 500)
|
||||||
* `#define USB_POLLING_INTERVAL_MS 10`
|
* `#define USB_POLLING_INTERVAL_MS 10`
|
||||||
* sets the USB polling rate in milliseconds for the keyboard, mouse, and shared (NKRO/media keys) interfaces
|
* sets the USB polling rate in milliseconds for the keyboard, mouse, and shared (NKRO/media keys) interfaces
|
||||||
* `#define USB_SUSPEND_WAKEUP_DELAY 200`
|
* `#define USB_SUSPEND_WAKEUP_DELAY 0`
|
||||||
* set the number of milliseconde to pause after sending a wakeup packet
|
* sets the number of milliseconds to pause after sending a wakeup packet.
|
||||||
|
Disabled by default, you might want to set this to 200 (or higher) if the
|
||||||
|
keyboard does not wake up properly after suspending.
|
||||||
* `#define F_SCL 100000L`
|
* `#define F_SCL 100000L`
|
||||||
* sets the I2C clock rate speed for keyboards using I2C. The default is `400000L`, except for keyboards using `split_common`, where the default is `100000L`.
|
* sets the I2C clock rate speed for keyboards using I2C. The default is `400000L`, except for keyboards using `split_common`, where the default is `100000L`.
|
||||||
|
|
||||||
|
@ -141,7 +151,7 @@ If you define these options you will enable the associated feature, which may in
|
||||||
## Behaviors That Can Be Configured
|
## Behaviors That Can Be Configured
|
||||||
|
|
||||||
* `#define TAPPING_TERM 200`
|
* `#define TAPPING_TERM 200`
|
||||||
* how long before a tap becomes a hold, if set above 500, a key tapped during the tapping term will turn it into a hold too
|
* how long before a key press becomes a hold
|
||||||
* `#define TAPPING_TERM_PER_KEY`
|
* `#define TAPPING_TERM_PER_KEY`
|
||||||
* enables handling for per key `TAPPING_TERM` settings
|
* enables handling for per key `TAPPING_TERM` settings
|
||||||
* `#define RETRO_TAPPING`
|
* `#define RETRO_TAPPING`
|
||||||
|
@ -174,19 +184,12 @@ If you define these options you will enable the associated feature, which may in
|
||||||
* sets the timer for leader key chords to run on each key press rather than overall
|
* sets the timer for leader key chords to run on each key press rather than overall
|
||||||
* `#define LEADER_KEY_STRICT_KEY_PROCESSING`
|
* `#define LEADER_KEY_STRICT_KEY_PROCESSING`
|
||||||
* Disables keycode filtering for Mod-Tap and Layer-Tap keycodes. Eg, if you enable this, you would need to specify `MT(MOD_CTL, KC_A)` if you want to use `KC_A`.
|
* Disables keycode filtering for Mod-Tap and Layer-Tap keycodes. Eg, if you enable this, you would need to specify `MT(MOD_CTL, KC_A)` if you want to use `KC_A`.
|
||||||
|
* `#define MOUSE_EXTENDED_REPORT`
|
||||||
|
* Enables support for extended reports (-32767 to 32767, instead of -127 to 127), which may allow for smoother reporting, and prevent maxing out of the reports. Applies to both Pointing Device and Mousekeys.
|
||||||
* `#define ONESHOT_TIMEOUT 300`
|
* `#define ONESHOT_TIMEOUT 300`
|
||||||
* how long before oneshot times out
|
* how long before oneshot times out
|
||||||
* `#define ONESHOT_TAP_TOGGLE 2`
|
* `#define ONESHOT_TAP_TOGGLE 2`
|
||||||
* how many taps before oneshot toggle is triggered
|
* how many taps before oneshot toggle is triggered
|
||||||
* `#define QMK_KEYS_PER_SCAN 4`
|
|
||||||
* Allows sending more than one key per scan. By default, only one key event gets
|
|
||||||
sent via `process_record()` per scan. This has little impact on most typing, but
|
|
||||||
if you're doing a lot of chords, or your scan rate is slow to begin with, you can
|
|
||||||
have some delay in processing key events. Each press and release is a separate
|
|
||||||
event. For a keyboard with 1ms or so scan times, even a very fast typist isn't
|
|
||||||
going to produce the 500 keystrokes a second needed to actually get more than a
|
|
||||||
few ms of delay from this. But if you're doing chording on something with 3-4ms
|
|
||||||
scan times? You probably want this.
|
|
||||||
* `#define COMBO_COUNT 2`
|
* `#define COMBO_COUNT 2`
|
||||||
* Set this to the number of combos that you're using in the [Combo](feature_combo.md) feature. Or leave it undefined and programmatically set the count.
|
* Set this to the number of combos that you're using in the [Combo](feature_combo.md) feature. Or leave it undefined and programmatically set the count.
|
||||||
* `#define COMBO_TERM 200`
|
* `#define COMBO_TERM 200`
|
||||||
|
@ -214,8 +217,6 @@ If you define these options you will enable the associated feature, which may in
|
||||||
|
|
||||||
* `#define RGB_DI_PIN D7`
|
* `#define RGB_DI_PIN D7`
|
||||||
* pin the DI on the WS2812 is hooked-up to
|
* pin the DI on the WS2812 is hooked-up to
|
||||||
* `#define RGBLIGHT_ANIMATIONS`
|
|
||||||
* run RGB animations
|
|
||||||
* `#define RGBLIGHT_LAYERS`
|
* `#define RGBLIGHT_LAYERS`
|
||||||
* Lets you define [lighting layers](feature_rgblight.md?id=lighting-layers) that can be toggled on or off. Great for showing the current keyboard layer or caps lock state.
|
* Lets you define [lighting layers](feature_rgblight.md?id=lighting-layers) that can be toggled on or off. Great for showing the current keyboard layer or caps lock state.
|
||||||
* `#define RGBLIGHT_MAX_LAYERS`
|
* `#define RGBLIGHT_MAX_LAYERS`
|
||||||
|
|
|
@ -56,7 +56,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||||
[1] = LAYOUT_all(
|
[1] = LAYOUT_all(
|
||||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_TOG, RGB_MOD, RGB_HUD, RGB_HUI, RGB_SAD, RGB_SAI, RGB_VAD, RGB_VAI, BL_TOGG, BL_DEC, BL_INC,
|
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_TOG, RGB_MOD, RGB_HUD, RGB_HUI, RGB_SAD, RGB_SAI, RGB_VAD, RGB_VAI, BL_TOGG, BL_DEC, BL_INC,
|
||||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_VOLU,
|
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_VOLU,
|
||||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RESET, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY, KC_MNXT, KC_VOLD,
|
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, QK_BOOT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY, KC_MNXT, KC_VOLD,
|
||||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
|
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
|
||||||
|
@ -84,7 +84,7 @@ The default keymap uses the `LAYOUT_all` macro, so that will be the value of the
|
||||||
[
|
[
|
||||||
"KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "RGB_TOG", "RGB_MOD", "RGB_HUD", "RGB_HUI", "RGB_SAD", "RGB_SAI", "RGB_VAD", "RGB_VAI", "BL_TOGG", "BL_DEC", "BL_INC",
|
"KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "RGB_TOG", "RGB_MOD", "RGB_HUD", "RGB_HUI", "RGB_SAD", "RGB_SAI", "RGB_VAD", "RGB_VAI", "BL_TOGG", "BL_DEC", "BL_INC",
|
||||||
"KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_VOLU",
|
"KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_VOLU",
|
||||||
"KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "RESET", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_MPLY", "KC_MNXT", "KC_VOLD",
|
"KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "QK_BOOT", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_MPLY", "KC_MNXT", "KC_VOLD",
|
||||||
"KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS",
|
"KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS",
|
||||||
"KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS",
|
"KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS",
|
||||||
"KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS"
|
"KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS"
|
||||||
|
|
|
@ -81,17 +81,17 @@ void matrix_init(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t matrix_scan(void) {
|
uint8_t matrix_scan(void) {
|
||||||
bool matrix_has_changed = false;
|
bool changed = false;
|
||||||
|
|
||||||
// TODO: add matrix scanning routine here
|
// TODO: add matrix scanning routine here
|
||||||
|
|
||||||
// Unless hardware debouncing - use the configured debounce routine
|
// Unless hardware debouncing - use the configured debounce routine
|
||||||
debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
|
changed = debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
|
||||||
|
|
||||||
// This *must* be called for correct keyboard behavior
|
// This *must* be called for correct keyboard behavior
|
||||||
matrix_scan_quantum();
|
matrix_scan_quantum();
|
||||||
|
|
||||||
return matrix_has_changed;
|
return changed;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -227,185 +227,6 @@ void suspend_wakeup_init_user(void) {
|
||||||
* Keyboard/Revision: `void suspend_power_down_kb(void)` and `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)`
|
* Keymap: `void suspend_power_down_kb(void)` and `void suspend_wakeup_init_user(void)`
|
||||||
|
|
||||||
# Layer Change Code :id=layer-change-code
|
|
||||||
|
|
||||||
This runs code every time that the layers get changed. This can be useful for layer indication, or custom layer handling.
|
|
||||||
|
|
||||||
### Example `layer_state_set_*` Implementation
|
|
||||||
|
|
||||||
This example shows how to set the [RGB Underglow](feature_rgblight.md) lights based on the layer, using the Planck as an example.
|
|
||||||
|
|
||||||
```c
|
|
||||||
layer_state_t layer_state_set_user(layer_state_t state) {
|
|
||||||
switch (get_highest_layer(state)) {
|
|
||||||
case _RAISE:
|
|
||||||
rgblight_setrgb (0x00, 0x00, 0xFF);
|
|
||||||
break;
|
|
||||||
case _LOWER:
|
|
||||||
rgblight_setrgb (0xFF, 0x00, 0x00);
|
|
||||||
break;
|
|
||||||
case _PLOVER:
|
|
||||||
rgblight_setrgb (0x00, 0xFF, 0x00);
|
|
||||||
break;
|
|
||||||
case _ADJUST:
|
|
||||||
rgblight_setrgb (0x7A, 0x00, 0xFF);
|
|
||||||
break;
|
|
||||||
default: // for any other layers, or the default layer
|
|
||||||
rgblight_setrgb (0x00, 0xFF, 0xFF);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Use the `IS_LAYER_ON_STATE(state, layer)` and `IS_LAYER_OFF_STATE(state, layer)` macros to check the status of a particular layer.
|
|
||||||
|
|
||||||
Outside of `layer_state_set_*` functions, you can use the `IS_LAYER_ON(layer)` and `IS_LAYER_OFF(layer)` macros to check global layer state.
|
|
||||||
|
|
||||||
### `layer_state_set_*` Function Documentation
|
|
||||||
|
|
||||||
* Keyboard/Revision: `layer_state_t layer_state_set_kb(layer_state_t state)`
|
|
||||||
* Keymap: `layer_state_t layer_state_set_user(layer_state_t state)`
|
|
||||||
|
|
||||||
|
|
||||||
The `state` is the bitmask of the active layers, as explained in the [Keymap Overview](keymap.md#keymap-layer-status)
|
|
||||||
|
|
||||||
|
|
||||||
# Persistent Configuration (EEPROM)
|
|
||||||
|
|
||||||
This allows you to configure persistent settings for your keyboard. These settings are stored in the EEPROM of your controller, and are retained even after power loss. The settings can be read with `eeconfig_read_kb` and `eeconfig_read_user`, and can be written to using `eeconfig_update_kb` and `eeconfig_update_user`. This is useful for features that you want to be able to toggle (like toggling rgb layer indication). Additionally, you can use `eeconfig_init_kb` and `eeconfig_init_user` to set the default values for the EEPROM.
|
|
||||||
|
|
||||||
The complicated part here, is that there are a bunch of ways that you can store and access data via EEPROM, and there is no "correct" way to do this. However, you only have a DWORD (4 bytes) for each function.
|
|
||||||
|
|
||||||
Keep in mind that EEPROM has a limited number of writes. While this is very high, it's not the only thing writing to the EEPROM, and if you write too often, you can potentially drastically shorten the life of your MCU.
|
|
||||||
|
|
||||||
* If you don't understand the example, then you may want to avoid using this feature, as it is rather complicated.
|
|
||||||
|
|
||||||
### Example Implementation
|
|
||||||
|
|
||||||
This is an example of how to add settings, and read and write it. We're using the user keymap for the example here. This is a complex function, and has a lot going on. In fact, it uses a lot of the above functions to work!
|
|
||||||
|
|
||||||
|
|
||||||
In your keymap.c file, add this to the top:
|
|
||||||
```c
|
|
||||||
typedef union {
|
|
||||||
uint32_t raw;
|
|
||||||
struct {
|
|
||||||
bool rgb_layer_change :1;
|
|
||||||
};
|
|
||||||
} user_config_t;
|
|
||||||
|
|
||||||
user_config_t user_config;
|
|
||||||
```
|
|
||||||
|
|
||||||
This sets up a 32 bit structure that we can store settings with in memory, and write to the EEPROM. Using this removes the need to define variables, since they're defined in this structure. Remember that `bool` (boolean) values use 1 bit, `uint8_t` uses 8 bits, `uint16_t` uses up 16 bits. You can mix and match, but changing the order can cause issues, as it will change the values that are read and written.
|
|
||||||
|
|
||||||
We're using `rgb_layer_change`, for the `layer_state_set_*` function, and use `keyboard_post_init_user` and `process_record_user` to configure everything.
|
|
||||||
|
|
||||||
Now, using the `keyboard_post_init_user` code above, you want to add `eeconfig_read_user()` to it, to populate the structure you've just created. And you can then immediately use this structure to control functionality in your keymap. And It should look like:
|
|
||||||
```c
|
|
||||||
void keyboard_post_init_user(void) {
|
|
||||||
// Call the keymap level matrix init.
|
|
||||||
|
|
||||||
// Read the user config from EEPROM
|
|
||||||
user_config.raw = eeconfig_read_user();
|
|
||||||
|
|
||||||
// Set default layer, if enabled
|
|
||||||
if (user_config.rgb_layer_change) {
|
|
||||||
rgblight_enable_noeeprom();
|
|
||||||
rgblight_sethsv_noeeprom_cyan();
|
|
||||||
rgblight_mode_noeeprom(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
The above function will use the EEPROM config immediately after reading it, to set the default layer's RGB color. The "raw" value of it is converted in a usable structure based on the "union" that you created above.
|
|
||||||
|
|
||||||
```c
|
|
||||||
layer_state_t layer_state_set_user(layer_state_t state) {
|
|
||||||
switch (get_highest_layer(state)) {
|
|
||||||
case _RAISE:
|
|
||||||
if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_magenta(); rgblight_mode_noeeprom(1); }
|
|
||||||
break;
|
|
||||||
case _LOWER:
|
|
||||||
if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_red(); rgblight_mode_noeeprom(1); }
|
|
||||||
break;
|
|
||||||
case _PLOVER:
|
|
||||||
if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_green(); rgblight_mode_noeeprom(1); }
|
|
||||||
break;
|
|
||||||
case _ADJUST:
|
|
||||||
if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_white(); rgblight_mode_noeeprom(1); }
|
|
||||||
break;
|
|
||||||
default: // for any other layers, or the default layer
|
|
||||||
if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_cyan(); rgblight_mode_noeeprom(1); }
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
This will cause the RGB underglow to be changed ONLY if the value was enabled. Now to configure this value, create a new keycode for `process_record_user` called `RGB_LYR`. Additionally, we want to make sure that if you use the normal RGB codes, that it turns off Using the example above, make it look this:
|
|
||||||
```c
|
|
||||||
|
|
||||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
|
||||||
switch (keycode) {
|
|
||||||
case FOO:
|
|
||||||
if (record->event.pressed) {
|
|
||||||
// Do something when pressed
|
|
||||||
} else {
|
|
||||||
// Do something else when release
|
|
||||||
}
|
|
||||||
return false; // Skip all further processing of this key
|
|
||||||
case KC_ENTER:
|
|
||||||
// Play a tone when enter is pressed
|
|
||||||
if (record->event.pressed) {
|
|
||||||
PLAY_SONG(tone_qwerty);
|
|
||||||
}
|
|
||||||
return true; // Let QMK send the enter press/release events
|
|
||||||
case RGB_LYR: // This allows me to use underglow as layer indication, or as normal
|
|
||||||
if (record->event.pressed) {
|
|
||||||
user_config.rgb_layer_change ^= 1; // Toggles the status
|
|
||||||
eeconfig_update_user(user_config.raw); // Writes the new status to EEPROM
|
|
||||||
if (user_config.rgb_layer_change) { // if layer state indication is enabled,
|
|
||||||
layer_state_set(layer_state); // then immediately update the layer color
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // For any of the RGB codes (see quantum_keycodes.h, L400 for reference)
|
|
||||||
if (record->event.pressed) { //This disables layer indication, as it's assumed that if you're changing this ... you want that disabled
|
|
||||||
if (user_config.rgb_layer_change) { // only if this is enabled
|
|
||||||
user_config.rgb_layer_change = false; // disable it, and
|
|
||||||
eeconfig_update_user(user_config.raw); // write the setings to EEPROM
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true; break;
|
|
||||||
default:
|
|
||||||
return true; // Process all other keycodes normally
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
And lastly, you want to add the `eeconfig_init_user` function, so that when the EEPROM is reset, you can specify default values, and even custom actions. To force an EEPROM reset, use the `EEP_RST` keycode or [Bootmagic Lite](feature_bootmagic.md) functionallity. For example, if you want to set rgb layer indication by default, and save the default valued.
|
|
||||||
|
|
||||||
```c
|
|
||||||
void eeconfig_init_user(void) { // EEPROM is getting reset!
|
|
||||||
user_config.raw = 0;
|
|
||||||
user_config.rgb_layer_change = true; // We want this enabled by default
|
|
||||||
eeconfig_update_user(user_config.raw); // Write default value to EEPROM now
|
|
||||||
|
|
||||||
// use the non noeeprom versions, to write these values to EEPROM too
|
|
||||||
rgblight_enable(); // Enable RGB by default
|
|
||||||
rgblight_sethsv_cyan(); // Set it to CYAN by default
|
|
||||||
rgblight_mode(1); // set to solid by default
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
And you're done. The RGB layer indication will only work if you want it to. And it will be saved, even after unplugging the board. And if you use any of the RGB codes, it will disable the layer indication, so that it stays on the mode and color that you set it to.
|
|
||||||
|
|
||||||
### 'EECONFIG' Function Documentation
|
|
||||||
|
|
||||||
* Keyboard/Revision: `void eeconfig_init_kb(void)`, `uint32_t eeconfig_read_kb(void)` and `void eeconfig_update_kb(uint32_t val)`
|
|
||||||
* Keymap: `void eeconfig_init_user(void)`, `uint32_t eeconfig_read_user(void)` and `void eeconfig_update_user(uint32_t val)`
|
|
||||||
|
|
||||||
The `val` is the value of the data that you want to write to EEPROM. And the `eeconfig_read_*` function return a 32 bit (DWORD) value from the EEPROM.
|
|
||||||
|
|
||||||
# Deferred Execution :id=deferred-execution
|
# Deferred Execution :id=deferred-execution
|
||||||
|
|
||||||
QMK has the ability to execute a callback after a specified period of time, rather than having to manually manage timers. To enable this functionality, set `DEFERRED_EXEC_ENABLE = yes` in rules.mk.
|
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.
|
||||||
|
@ -471,3 +292,15 @@ If registrations fail, then you can increase this value in your keyboard or keym
|
||||||
```c
|
```c
|
||||||
#define MAX_DEFERRED_EXECUTORS 16
|
#define MAX_DEFERRED_EXECUTORS 16
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# Advanced topics :id=advanced-topics
|
||||||
|
|
||||||
|
This page used to encompass a large set of features. We have moved many sections that used to be part of this page to their own pages. Everything below this point is simply a redirect so that people following old links on the web find what they're looking for.
|
||||||
|
|
||||||
|
## Layer Change Code :id=layer-change-code
|
||||||
|
|
||||||
|
[Layer change code](feature_layers.md#layer-change-code)
|
||||||
|
|
||||||
|
## Persistent Configuration (EEPROM) :id=persistent-configuration-eeprom
|
||||||
|
|
||||||
|
[Persistent Configuration (EEPROM)](feature_eeprom.md)
|
||||||
|
|
|
@ -22,7 +22,7 @@ You will then need to add support for your new configuration to `info.json`. The
|
||||||
|
|
||||||
1. Add it to the schema in `data/schemas/keyboards.jsonschema`
|
1. Add it to the schema in `data/schemas/keyboards.jsonschema`
|
||||||
1. Add a mapping in `data/maps`
|
1. Add a mapping in `data/maps`
|
||||||
1. (optional and discoraged) Add code to extract/generate it to:
|
1. (optional and discouraged) Add code to extract/generate it to:
|
||||||
* `lib/python/qmk/info.py`
|
* `lib/python/qmk/info.py`
|
||||||
* `lib/python/qmk/cli/generate/config_h.py`
|
* `lib/python/qmk/cli/generate/config_h.py`
|
||||||
* `lib/python/qmk/cli/generate/rules_mk.py`
|
* `lib/python/qmk/cli/generate/rules_mk.py`
|
||||||
|
|
|
@ -8,7 +8,7 @@ We recommend the use of the [Zadig](https://zadig.akeo.ie/) utility. If you have
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Put your keyboard into bootloader mode, either by hitting the `RESET` keycode (which may be on a different layer), or by pressing the reset switch that's usually located on the underside of the board. If your keyboard has neither, try holding Escape or Space+`B` as you plug it in (see the [Bootmagic Lite](feature_bootmagic.md) docs for more details). Some boards use [Command](feature_command.md) instead of Bootmagic; in this case, you can enter bootloader mode by hitting Left Shift+Right Shift+`B` or Left Shift+Right Shift+Escape at any point while the keyboard is plugged in.
|
Put your keyboard into bootloader mode, either by hitting the `QK_BOOT` keycode (which may be on a different layer), or by pressing the reset switch that's usually located on the underside of the board. If your keyboard has neither, try holding Escape or Space+`B` as you plug it in (see the [Bootmagic Lite](feature_bootmagic.md) docs for more details). Some boards use [Command](feature_command.md) instead of Bootmagic; in this case, you can enter bootloader mode by hitting Left Shift+Right Shift+`B` or Left Shift+Right Shift+Escape at any point while the keyboard is plugged in.
|
||||||
Some keyboards may have specific instructions for entering the bootloader. For example, the [Bootmagic Lite](feature_bootmagic.md) key (default: Escape) might be on a different key, e.g. Left Control; or the magic combination for Command (default: Left Shift+Right Shift) might require you to hold something else, e.g. Left Control+Right Control. Refer to the board's README file if you are unsure.
|
Some keyboards may have specific instructions for entering the bootloader. For example, the [Bootmagic Lite](feature_bootmagic.md) key (default: Escape) might be on a different key, e.g. Left Control; or the magic combination for Command (default: Left Shift+Right Shift) might require you to hold something else, e.g. Left Control+Right Control. Refer to the board's README file if you are unsure.
|
||||||
|
|
||||||
To put a device in bootloader mode with USBaspLoader, tap the `RESET` button while holding down the `BOOT` button.
|
To put a device in bootloader mode with USBaspLoader, tap the `RESET` button while holding down the `BOOT` button.
|
||||||
|
|
|
@ -2,12 +2,15 @@
|
||||||
|
|
||||||
The EEPROM driver can be swapped out depending on the needs of the keyboard, or whether extra hardware is present.
|
The EEPROM driver can be swapped out depending on the needs of the keyboard, or whether extra hardware is present.
|
||||||
|
|
||||||
|
Selecting the EEPROM driver is done in your keyboard's `rules.mk`:
|
||||||
|
|
||||||
Driver | Description
|
Driver | Description
|
||||||
-----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
`EEPROM_DRIVER = vendor` (default) | Uses the on-chip driver provided by the chip manufacturer. For AVR, this is provided by avr-libc. This is supported on ARM for a subset of chips -- STM32F3xx, STM32F1xx, and STM32F072xB will be emulated by writing to flash. STM32L0xx and STM32L1xx will use the onboard dedicated true EEPROM. Other chips will generally act as "transient" below.
|
`EEPROM_DRIVER = vendor` (default) | Uses the on-chip driver provided by the chip manufacturer. For AVR, this is provided by avr-libc. This is supported on ARM for a subset of chips -- STM32F3xx, STM32F1xx, and STM32F072xB will be emulated by writing to flash. STM32L0xx and STM32L1xx will use the onboard dedicated true EEPROM. Other chips will generally act as "transient" below.
|
||||||
`EEPROM_DRIVER = i2c` | Supports writing to I2C-based 24xx EEPROM chips. See the driver section below.
|
`EEPROM_DRIVER = i2c` | Supports writing to I2C-based 24xx EEPROM chips. See the driver section below.
|
||||||
`EEPROM_DRIVER = spi` | Supports writing to SPI-based 25xx EEPROM chips. See the driver section below.
|
`EEPROM_DRIVER = spi` | Supports writing to SPI-based 25xx EEPROM chips. See the driver section below.
|
||||||
`EEPROM_DRIVER = transient` | Fake EEPROM driver -- supports reading/writing to RAM, and will be discarded when power is lost.
|
`EEPROM_DRIVER = 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 :id=vendor-eeprom-driver-configuration
|
||||||
|
|
||||||
|
@ -43,8 +46,9 @@ Module | Equivalent `#define` | Source
|
||||||
-----------------|---------------------------------|------------------------------------------
|
-----------------|---------------------------------|------------------------------------------
|
||||||
CAT24C512 EEPROM | `#define EEPROM_I2C_CAT24C512` | <https://www.sparkfun.com/products/14764>
|
CAT24C512 EEPROM | `#define EEPROM_I2C_CAT24C512` | <https://www.sparkfun.com/products/14764>
|
||||||
RM24C512C EEPROM | `#define EEPROM_I2C_RM24C512C` | <https://www.sparkfun.com/products/14764>
|
RM24C512C EEPROM | `#define EEPROM_I2C_RM24C512C` | <https://www.sparkfun.com/products/14764>
|
||||||
24LC64 EEPROM | `#define EEPROM_I2C_24LC64` | <https://www.microchip.com/wwwproducts/en/24LC64>
|
24LC32A EEPROM | `#define EEPROM_I2C_24LC32A` | <https://www.microchip.com/en-us/product/24LC32A>
|
||||||
24LC128 EEPROM | `#define EEPROM_I2C_24LC128` | <https://www.microchip.com/wwwproducts/en/24LC128>
|
24LC64 EEPROM | `#define EEPROM_I2C_24LC64` | <https://www.microchip.com/en-us/product/24LC64>
|
||||||
|
24LC128 EEPROM | `#define EEPROM_I2C_24LC128` | <https://www.microchip.com/en-us/product/24LC128>
|
||||||
24LC256 EEPROM | `#define EEPROM_I2C_24LC256` | <https://www.sparkfun.com/products/525>
|
24LC256 EEPROM | `#define EEPROM_I2C_24LC256` | <https://www.sparkfun.com/products/525>
|
||||||
MB85RC256V FRAM | `#define EEPROM_I2C_MB85RC256V` | <https://www.adafruit.com/product/1895>
|
MB85RC256V FRAM | `#define EEPROM_I2C_MB85RC256V` | <https://www.adafruit.com/product/1895>
|
||||||
|
|
||||||
|
@ -54,13 +58,13 @@ MB85RC256V FRAM | `#define EEPROM_I2C_MB85RC256V` | <https://www.adafruit.com/p
|
||||||
|
|
||||||
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:
|
Currently QMK supports 25xx-series chips over SPI. As such, requires a working spi_master driver configuration. You can override the driver configuration via your config.h:
|
||||||
|
|
||||||
`config.h` override | Description | Default Value
|
`config.h` override | Default Value | Description
|
||||||
-----------------------------------------------|--------------------------------------------------------------------------------------|--------------
|
-----------------------------------------------|---------------|-------------------------------------------------------------------------------------
|
||||||
`#define EXTERNAL_EEPROM_SPI_SLAVE_SELECT_PIN` | SPI Slave select pin in order to inform that the EEPROM is currently being addressed | _none_
|
`#define EXTERNAL_EEPROM_SPI_SLAVE_SELECT_PIN` | _none_ | SPI Slave select pin in order to inform that the EEPROM is currently being addressed
|
||||||
`#define EXTERNAL_EEPROM_SPI_CLOCK_DIVISOR` | Clock divisor used to divide the peripheral clock to derive the SPI frequency | `64`
|
`#define EXTERNAL_EEPROM_SPI_CLOCK_DIVISOR` | `64` | Clock divisor used to divide the peripheral clock to derive the SPI frequency
|
||||||
`#define EXTERNAL_EEPROM_BYTE_COUNT` | Total size of the EEPROM in bytes | 8192
|
`#define EXTERNAL_EEPROM_BYTE_COUNT` | `8192` | Total size of the EEPROM in bytes
|
||||||
`#define EXTERNAL_EEPROM_PAGE_SIZE` | Page size of the EEPROM in bytes, as specified in the datasheet | 32
|
`#define EXTERNAL_EEPROM_PAGE_SIZE` | `32` | Page size of the EEPROM in bytes, as specified in the datasheet
|
||||||
`#define EXTERNAL_EEPROM_ADDRESS_SIZE` | The number of bytes to transmit for the memory location within the EEPROM | 2
|
`#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.
|
!> There's no way to determine if there is an SPI EEPROM actually responding. Generally, this will result in reads of nothing but zero.
|
||||||
|
|
||||||
|
@ -73,3 +77,84 @@ The only configurable item for the transient EEPROM driver is its size:
|
||||||
`#define TRANSIENT_EEPROM_SIZE` | Total size of the EEPROM storage in bytes | 64
|
`#define TRANSIENT_EEPROM_SIZE` | Total size of the EEPROM storage in bytes | 64
|
||||||
|
|
||||||
Default values and extended descriptions can be found in `drivers/eeprom/eeprom_transient.h`.
|
Default values and extended descriptions can be found in `drivers/eeprom/eeprom_transient.h`.
|
||||||
|
|
||||||
|
## Wear-leveling Driver Configuration :id=wear_leveling-eeprom-driver-configuration
|
||||||
|
|
||||||
|
The wear-leveling driver uses an algorithm to minimise the number of erase cycles on the underlying MCU flash memory.
|
||||||
|
|
||||||
|
There is no specific configuration for this driver, but the wear-leveling system used by this driver may need configuration. See the [wear-leveling configuration](#wear_leveling-configuration) section for more information.
|
||||||
|
|
||||||
|
# Wear-leveling Configuration :id=wear_leveling-configuration
|
||||||
|
|
||||||
|
The wear-leveling driver has a few possible _backing stores_ that may be used by adding to your keyboard's `rules.mk` file:
|
||||||
|
|
||||||
|
Driver | Description
|
||||||
|
----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
`WEAR_LEVELING_DRIVER = embedded_flash` | This driver is used for emulating EEPROM by writing to embedded flash on the MCU.
|
||||||
|
`WEAR_LEVELING_DRIVER = spi_flash` | This driver is used to address external SPI NOR Flash peripherals.
|
||||||
|
`WEAR_LEVELING_DRIVER = rp2040_flash` | This driver is used to write to the same storage the RP2040 executes code from.
|
||||||
|
`WEAR_LEVELING_DRIVER = legacy` | This driver is the "legacy" emulated EEPROM provided in historical revisions of QMK. Currently used for STM32F0xx and STM32F4x1, but slated for deprecation and removal once `embedded_flash` support for those MCU families is complete.
|
||||||
|
|
||||||
|
!> All wear-leveling drivers require an amount of RAM equivalent to the selected logical EEPROM size. Increasing the size to 32kB of EEPROM requires 32kB of RAM, which a significant number of MCUs simply do not have.
|
||||||
|
|
||||||
|
## Wear-leveling Embedded Flash Driver Configuration :id=wear_leveling-efl-driver-configuration
|
||||||
|
|
||||||
|
This driver performs writes to the embedded flash storage embedded in the MCU. In most circumstances, the last few of sectors of flash are used in order to minimise the likelihood of collision with program code.
|
||||||
|
|
||||||
|
Configurable options in your keyboard's `config.h`:
|
||||||
|
|
||||||
|
`config.h` override | Default | Description
|
||||||
|
-----------------------------------------|-------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
`#define WEAR_LEVELING_EFL_FIRST_SECTOR` | _unset_ | The first sector on the MCU to use. By default this is not defined and calculated at runtime based on the MCU. However, different flash sizes on MCUs may require custom configuration.
|
||||||
|
`#define WEAR_LEVELING_EFL_FLASH_SIZE` | _unset_ | Allows overriding the flash size available for use for wear-leveling. Under normal circumstances this is automatically calculated and should not need to be overridden. Specifying a size larger than the amount actually available in flash will usually prevent the MCU from booting.
|
||||||
|
`#define WEAR_LEVELING_LOGICAL_SIZE` | `1024` | Number of bytes "exposed" to the rest of QMK and denotes the size of the usable EEPROM.
|
||||||
|
`#define WEAR_LEVELING_BACKING_SIZE` | `2048` | Number of bytes used by the wear-leveling algorithm for its underlying storage, and needs to be a multiple of the logical size.
|
||||||
|
`#define BACKING_STORE_WRITE_SIZE` | _automatic_ | The byte width of the underlying write used on the MCU, and is usually automatically determined from the selected MCU family. If an error occurs in the auto-detection, you'll need to consult the MCU's datasheet and determine this value, specifying it directly.
|
||||||
|
|
||||||
|
!> If your MCU does not boot after swapping to the EFL wear-leveling driver, it's likely that the flash size is incorrectly detected, usually as an MCU with larger flash and may require overriding.
|
||||||
|
|
||||||
|
## Wear-leveling SPI Flash Driver Configuration :id=wear_leveling-flash_spi-driver-configuration
|
||||||
|
|
||||||
|
This driver performs writes to an external SPI NOR Flash peripheral. It also requires a working configuration for the SPI NOR Flash peripheral -- see the [flash driver](flash_driver.md) documentation for more information.
|
||||||
|
|
||||||
|
Configurable options in your keyboard's `config.h`:
|
||||||
|
|
||||||
|
`config.h` override | Default | Description
|
||||||
|
----------------------------------------------------|--------------------------------|--------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
`#define WEAR_LEVELING_EXTERNAL_FLASH_BLOCK_COUNT` | `1` | Number of blocks in the external flash used by the wear-leveling algorithm.
|
||||||
|
`#define WEAR_LEVELING_EXTERNAL_FLASH_BLOCK_OFFSET` | `0` | The index first block in the external flash used by the wear-leveling algorithm.
|
||||||
|
`#define WEAR_LEVELING_LOGICAL_SIZE` | `((block_count*block_size)/2)` | Number of bytes "exposed" to the rest of QMK and denotes the size of the usable EEPROM. Result must be <= 64kB.
|
||||||
|
`#define WEAR_LEVELING_BACKING_SIZE` | `(block_count*block_size)` | Number of bytes used by the wear-leveling algorithm for its underlying storage, and needs to be a multiple of the logical size.
|
||||||
|
`#define BACKING_STORE_WRITE_SIZE` | `8` | The write width used whenever a write is performed on the external flash peripheral.
|
||||||
|
|
||||||
|
!> There is currently a limit of 64kB for the EEPROM subsystem within QMK, so using a larger flash is not going to be beneficial as the logical size cannot be increased beyond 65536. The backing size may be increased to a larger value, but erase timing may suffer as a result.
|
||||||
|
|
||||||
|
## Wear-leveling RP2040 Driver Configuration :id=wear_leveling-rp2040-driver-configuration
|
||||||
|
|
||||||
|
This driver performs writes to the same underlying storage that the RP2040 executes its code.
|
||||||
|
|
||||||
|
Configurable options in your keyboard's `config.h`:
|
||||||
|
|
||||||
|
`config.h` override | Default | Description
|
||||||
|
------------------------------------------|----------------------------|--------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
`#define WEAR_LEVELING_RP2040_FLASH_SIZE` | `PICO_FLASH_SIZE_BYTES` | Number of bytes of flash on the board.
|
||||||
|
`#define WEAR_LEVELING_RP2040_FLASH_BASE` | `(flash_size-sector_size)` | The byte-wise location that the backing storage should be located.
|
||||||
|
`#define WEAR_LEVELING_LOGICAL_SIZE` | `4096` | Number of bytes "exposed" to the rest of QMK and denotes the size of the usable EEPROM.
|
||||||
|
`#define WEAR_LEVELING_BACKING_SIZE` | `8192` | Number of bytes used by the wear-leveling algorithm for its underlying storage, and needs to be a multiple of the logical size as well as the sector size.
|
||||||
|
`#define BACKING_STORE_WRITE_SIZE` | `2` | The write width used whenever a write is performed on the external flash peripheral.
|
||||||
|
|
||||||
|
## Wear-leveling Legacy EEPROM Emulation Driver Configuration :id=wear_leveling-legacy-driver-configuration
|
||||||
|
|
||||||
|
This driver performs writes to the embedded flash storage embedded in the MCU much like the normal Embedded Flash Driver, and is only for use with STM32F0xx and STM32F4x1 devices. This flash implementation is still currently provided as the EFL driver is currently non-functional for the previously mentioned families.
|
||||||
|
|
||||||
|
By default, `1024` bytes of emulated EEPROM is provided:
|
||||||
|
|
||||||
|
MCU | EEPROM Provided | Flash Used
|
||||||
|
----------|-----------------|--------------
|
||||||
|
STM32F042 | `1024` bytes | `2048` bytes
|
||||||
|
STM32F070 | `1024` bytes | `2048` bytes
|
||||||
|
STM32F072 | `1024` bytes | `2048` bytes
|
||||||
|
STM32F401 | `1024` bytes | `16384` bytes
|
||||||
|
STM32F411 | `1024` bytes | `16384` bytes
|
||||||
|
|
||||||
|
Under normal circumstances configuration of this driver requires intimate knowledge of the MCU's flash structure -- reconfiguration is at your own risk and will require referring to the code.
|
||||||
|
|
|
@ -59,7 +59,7 @@ When porting, or when attempting to diagnose pcb issues, it can be useful to kno
|
||||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||||
// If console is enabled, it will print the matrix position and status of each key pressed
|
// If console is enabled, it will print the matrix position and status of each key pressed
|
||||||
#ifdef CONSOLE_ENABLE
|
#ifdef CONSOLE_ENABLE
|
||||||
uprintf("KL: kc: 0x%04X, col: %u, row: %u, pressed: %b, time: %u, interrupt: %b, count: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed, record->event.time, record->tap.interrupted, record->tap.count);
|
uprintf("KL: kc: 0x%04X, col: %2u, row: %2u, pressed: %u, time: %5u, int: %u, count: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed, record->event.time, record->tap.interrupted, record->tap.count);
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -69,12 +69,12 @@ Example output
|
||||||
```
|
```
|
||||||
Waiting for device:.......
|
Waiting for device:.......
|
||||||
Listening:
|
Listening:
|
||||||
KL: kc: 169, col: 0, row: 0, pressed: 1
|
KL: kc: 169, col: 0, row: 0, pressed: 1, time: 15505, int: 0, count: 0
|
||||||
KL: kc: 169, col: 0, row: 0, pressed: 0
|
KL: kc: 169, col: 0, row: 0, pressed: 0, time: 15510, int: 0, count: 0
|
||||||
KL: kc: 174, col: 1, row: 0, pressed: 1
|
KL: kc: 174, col: 1, row: 0, pressed: 1, time: 15703, int: 0, count: 0
|
||||||
KL: kc: 174, col: 1, row: 0, pressed: 0
|
KL: kc: 174, col: 1, row: 0, pressed: 0, time: 15843, int: 0, count: 0
|
||||||
KL: kc: 172, col: 2, row: 0, pressed: 1
|
KL: kc: 172, col: 2, row: 0, pressed: 1, time: 16303, int: 0, count: 0
|
||||||
KL: kc: 172, col: 2, row: 0, pressed: 0
|
KL: kc: 172, col: 2, row: 0, pressed: 0, time: 16411, int: 0, count: 0
|
||||||
```
|
```
|
||||||
|
|
||||||
### How long did it take to scan for a keypress?
|
### How long did it take to scan for a keypress?
|
||||||
|
@ -133,3 +133,4 @@ Check:
|
||||||
- Set `debug_enable=true`. See [Debugging](#debugging)
|
- Set `debug_enable=true`. See [Debugging](#debugging)
|
||||||
- Try using `print` function instead of debug print. See **common/print.h**.
|
- Try using `print` function instead of debug print. See **common/print.h**.
|
||||||
- Disconnect other devices with console function. See [Issue #97](https://github.com/tmk/tmk_keyboard/issues/97).
|
- Disconnect other devices with console function. See [Issue #97](https://github.com/tmk/tmk_keyboard/issues/97).
|
||||||
|
- Ensure all strings end with a newline character (`\n`). QMK Toolbox prints console output on a per-line basis.
|
||||||
|
|
|
@ -10,7 +10,7 @@ You probably don't want to "brick" your keyboard, making it impossible
|
||||||
to rewrite firmware onto it. Here are some of the parameters to show
|
to rewrite firmware onto it. Here are some of the parameters to show
|
||||||
what things are (and likely aren't) too risky.
|
what things are (and likely aren't) too risky.
|
||||||
|
|
||||||
- If your keyboard map does not include RESET, then, to get into DFU
|
- If your keyboard map does not include QK_BOOT, then, to get into DFU
|
||||||
mode, you will need to press the reset button on the PCB, which
|
mode, you will need to press the reset button on the PCB, which
|
||||||
requires unscrewing the bottom.
|
requires unscrewing the bottom.
|
||||||
- Messing with tmk_core / common files might make the keyboard
|
- Messing with tmk_core / common files might make the keyboard
|
||||||
|
|
|
@ -161,7 +161,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
# Legacy Content :id=legacy-content
|
# Advanced topics :id=advanced-topics
|
||||||
|
|
||||||
This page used to encompass a large set of features. We have moved many sections that used to be part of this page to their own pages. Everything below this point is simply a redirect so that people following old links on the web find what they're looking for.
|
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.
|
||||||
|
|
||||||
|
|
|
@ -114,7 +114,7 @@ The audio core offers interface functions to get/set/change the tone multiplexin
|
||||||
There's a couple of different sounds that will automatically be enabled without any other configuration:
|
There's a couple of different sounds that will automatically be enabled without any other configuration:
|
||||||
```
|
```
|
||||||
STARTUP_SONG // plays when the keyboard starts up (audio.c)
|
STARTUP_SONG // plays when the keyboard starts up (audio.c)
|
||||||
GOODBYE_SONG // plays when you press the RESET key (quantum.c)
|
GOODBYE_SONG // plays when you press the QK_BOOT key (quantum.c)
|
||||||
AG_NORM_SONG // plays when you press AG_NORM (quantum.c)
|
AG_NORM_SONG // plays when you press AG_NORM (quantum.c)
|
||||||
AG_SWAP_SONG // plays when you press AG_SWAP (quantum.c)
|
AG_SWAP_SONG // plays when you press AG_SWAP (quantum.c)
|
||||||
CG_NORM_SONG // plays when you press CG_NORM (quantum.c)
|
CG_NORM_SONG // plays when you press CG_NORM (quantum.c)
|
||||||
|
@ -177,7 +177,7 @@ The available keycodes for audio are:
|
||||||
|`AUDIO_INIT_DELAY` | *Not defined* |Enables delay during startup song to accomidate for USB startup issues. |
|
|`AUDIO_INIT_DELAY` | *Not defined* |Enables delay during startup song to accomidate for USB startup issues. |
|
||||||
|`AUDIO_ENABLE_TONE_MULTIPLEXING` | *Not defined* |Enables time splicing/multiplexing to create multiple tones simutaneously. |
|
|`AUDIO_ENABLE_TONE_MULTIPLEXING` | *Not defined* |Enables time splicing/multiplexing to create multiple tones simutaneously. |
|
||||||
|`STARTUP_SONG` | `STARTUP_SOUND` |Plays when the keyboard starts up (audio.c) |
|
|`STARTUP_SONG` | `STARTUP_SOUND` |Plays when the keyboard starts up (audio.c) |
|
||||||
|`GOODBYE_SONG` | `GOODBYE_SOUND` |Plays when you press the RESET key (quantum.c) |
|
|`GOODBYE_SONG` | `GOODBYE_SOUND` |Plays when you press the QK_BOOT key (quantum.c) |
|
||||||
|`AG_NORM_SONG` | `AG_NORM_SOUND` |Plays when you press AG_NORM (process_magic.c) |
|
|`AG_NORM_SONG` | `AG_NORM_SOUND` |Plays when you press AG_NORM (process_magic.c) |
|
||||||
|`AG_SWAP_SONG` | `AG_SWAP_SOUND` |Plays when you press AG_SWAP (process_magic.c) |
|
|`AG_SWAP_SONG` | `AG_SWAP_SOUND` |Plays when you press AG_SWAP (process_magic.c) |
|
||||||
|`CG_NORM_SONG` | `AG_NORM_SOUND` |Plays when you press CG_NORM (process_magic.c) |
|
|`CG_NORM_SONG` | `AG_NORM_SOUND` |Plays when you press CG_NORM (process_magic.c) |
|
||||||
|
|
|
@ -4,11 +4,14 @@ It is often useful to type a single word in all capitals, for instance
|
||||||
abbreviations like "QMK", or in code, identifiers like `KC_SPC`. "Caps Word" is
|
abbreviations like "QMK", or in code, identifiers like `KC_SPC`. "Caps Word" is
|
||||||
a modern alternative to Caps Lock:
|
a modern alternative to Caps Lock:
|
||||||
|
|
||||||
* Letters are capitalized while active, and Caps Word automatically disables
|
* While active, letters are capitalized and `-` becomes `_`. The `_` makes it easier
|
||||||
|
to type constant names (eg 'PROGRAM\_CONSTANTS').
|
||||||
|
|
||||||
|
* Caps Word automatically disables
|
||||||
itself at the end of the word. That is, it stops by default once a space or
|
itself at the end of the word. That is, it stops by default once a space or
|
||||||
any key other than `a`--`z`, `0`--`9`, `-`, `_`, delete, or backspace is
|
any key other than `KC_A`--`KC_Z`, `KC_0`--`KC_9`, `KC_MINS`, `KC_UNDS`,
|
||||||
pressed. Caps Word also disables itself if the keyboard is idle for 5 seconds.
|
`KC_DELETE`, or `KC_BACKSPACE` is pressed. Caps Word also disables itself if
|
||||||
This is configurable, see below.
|
the keyboard is idle for 5 seconds. This is configurable, see below.
|
||||||
|
|
||||||
* To avoid requiring a dedicated key for Caps Word, there is an option
|
* To avoid requiring a dedicated key for Caps Word, there is an option
|
||||||
(`BOTH_SHIFTS_TURNS_ON_CAPS_WORD`) to activate Caps Word by simultaneously
|
(`BOTH_SHIFTS_TURNS_ON_CAPS_WORD`) to activate Caps Word by simultaneously
|
||||||
|
@ -16,7 +19,17 @@ a modern alternative to Caps Lock:
|
||||||
|
|
||||||
* The implementation does not use the Caps Lock (`KC_CAPS`) keycode. Caps Word
|
* The implementation does not use the Caps Lock (`KC_CAPS`) keycode. Caps Word
|
||||||
works even if you're remapping Caps Lock at the OS level to Ctrl or something
|
works even if you're remapping Caps Lock at the OS level to Ctrl or something
|
||||||
else, as Emacs and Vim users often do.
|
else, as Emacs and Vim users often do. As a consequence, Caps Word does not
|
||||||
|
follow the typical Caps Lock behaviour and may thus act in potentially
|
||||||
|
unexpected ways, especially when using an *OS* keyboard layout other than US
|
||||||
|
or UK. For example, Dvorak's <kbd>, <</kbd> key (`DV_COMM` aka `KC_W`) will
|
||||||
|
get shifted because Caps Word interprets that keycode as the letter 'W' by
|
||||||
|
default, the Spanish <kbd>Ñ</kbd> key (`ES_NTIL` aka `KC_SCLN`) will not get
|
||||||
|
capitalized because Caps Word interprets it as the semicolon ';' punctuation
|
||||||
|
character, and the US hyphen key (`KC_MINS`), while unaffected by Caps Lock,
|
||||||
|
is shifted by Caps Word. However, this is not really a problem because you can
|
||||||
|
[configure which keys should Caps Word
|
||||||
|
shift](#configure-which-keys-are-word-breaking).
|
||||||
|
|
||||||
|
|
||||||
## How do I enable Caps Word :id=how-do-i-enable-caps-word
|
## How do I enable Caps Word :id=how-do-i-enable-caps-word
|
||||||
|
|
|
@ -0,0 +1,138 @@
|
||||||
|
# Converters
|
||||||
|
|
||||||
|
Since many drop-in replacement controllers now exist, we've done our best to make them easy to use in existing designs.
|
||||||
|
|
||||||
|
This page documents the handy automated process for converting keyboards.
|
||||||
|
|
||||||
|
### Supported Converters
|
||||||
|
|
||||||
|
Currently the following converters are available:
|
||||||
|
|
||||||
|
| From | To |
|
||||||
|
|------------|-------------------|
|
||||||
|
| `promicro` | `proton_c` |
|
||||||
|
| `promicro` | `kb2040` |
|
||||||
|
| `promicro` | `promicro_rp2040` |
|
||||||
|
| `promicro` | `blok` |
|
||||||
|
| `promicro` | `bit_c_pro` |
|
||||||
|
| `promicro` | `stemcell` |
|
||||||
|
| `promicro` | `bonsai_c4` |
|
||||||
|
|
||||||
|
See below for more in depth information on each converter.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Each converter category is broken down by its declared `pin compatibility`.
|
||||||
|
This ensures that only valid combinations are attempted.
|
||||||
|
|
||||||
|
You can generate the firmware by appending `-e CONVERT_TO=<target>` to your compile/flash command. For example:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
qmk flash -c -kb keebio/bdn9/rev1 -km default -e CONVERT_TO=proton_c
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also add the same `CONVERT_TO=<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.
|
||||||
|
|
||||||
|
### Conditional Configuration
|
||||||
|
|
||||||
|
Once a converter is enabled, it exposes the `CONVERT_TO_<target_uppercase>` flag that you can use in your code with `#ifdef`s, For example:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#ifdef CONVERT_TO_PROTON_C
|
||||||
|
// Proton C code
|
||||||
|
#else
|
||||||
|
// Pro Micro code
|
||||||
|
#endif
|
||||||
|
```
|
||||||
|
|
||||||
|
## Pro Micro
|
||||||
|
|
||||||
|
If a board currently supported in QMK uses a [Pro Micro](https://www.sparkfun.com/products/12640) (or compatible board), the supported alternative controllers are:
|
||||||
|
|
||||||
|
| Device | Target |
|
||||||
|
|------------------------------------------------------------------------------------------|-------------------|
|
||||||
|
| [Proton C](https://qmk.fm/proton-c/) | `proton_c` |
|
||||||
|
| [Adafruit KB2040](https://learn.adafruit.com/adafruit-kb2040) | `kb2040` |
|
||||||
|
| [SparkFun Pro Micro - RP2040](https://www.sparkfun.com/products/18288) | `promicro_rp2040` |
|
||||||
|
| [Blok](https://boardsource.xyz/store/628b95b494dfa308a6581622) | `blok` |
|
||||||
|
| [Bit-C PRO](https://nullbits.co/bit-c-pro) | `bit_c_pro` |
|
||||||
|
| [STeMCell](https://github.com/megamind4089/STeMCell) | `stemcell` |
|
||||||
|
| [customMK Bonsai C4](https://shop.custommk.com/products/bonsai-c4-microcontroller-board) | `bonsai_c4` |
|
||||||
|
|
||||||
|
Converter summary:
|
||||||
|
|
||||||
|
| Target | Argument | `rules.mk` | Condition |
|
||||||
|
|-------------------|---------------------------------|------------------------------|-------------------------------------|
|
||||||
|
| `proton_c` | `-e CONVERT_TO=proton_c` | `CONVERT_TO=proton_c` | `#ifdef CONVERT_TO_PROTON_C` |
|
||||||
|
| `kb2040` | `-e CONVERT_TO=kb2040` | `CONVERT_TO=kb2040` | `#ifdef CONVERT_TO_KB2040` |
|
||||||
|
| `promicro_rp2040` | `-e CONVERT_TO=promicro_rp2040` | `CONVERT_TO=promicro_rp2040` | `#ifdef CONVERT_TO_PROMICRO_RP2040` |
|
||||||
|
| `blok` | `-e CONVERT_TO=blok` | `CONVERT_TO=blok` | `#ifdef CONVERT_TO_BLOK` |
|
||||||
|
| `bit_c_pro` | `-e CONVERT_TO=bit_c_pro` | `CONVERT_TO=bit_c_pro` | `#ifdef CONVERT_TO_BIT_C_PRO` |
|
||||||
|
| `stemcell` | `-e CONVERT_TO=stemcell` | `CONVERT_TO=stemcell` | `#ifdef CONVERT_TO_STEMCELL` |
|
||||||
|
| `bonsai_c4` | `-e CONVERT_TO=bonsai_c4` | `CONVERT_TO=bonsai_c4` | `#ifdef CONVERT_TO_BONSAI_C4` |
|
||||||
|
|
||||||
|
### Proton C :id=proton_c
|
||||||
|
|
||||||
|
The Proton C only has one on-board LED (C13), and by default, the TXLED (D5) is mapped to it. If you want the RXLED (B0) mapped to it instead, add this line to your `config.h`:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define CONVERT_TO_PROTON_C_RXLED
|
||||||
|
```
|
||||||
|
|
||||||
|
The following defaults are based on what has been implemented for STM32 boards.
|
||||||
|
|
||||||
|
| Feature | Notes |
|
||||||
|
|----------------------------------------------|------------------------------------------------------------------------------------------------------------------|
|
||||||
|
| [Audio](feature_audio.md) | Enabled |
|
||||||
|
| [RGB Lighting](feature_rgblight.md) | Disabled |
|
||||||
|
| [Backlight](feature_backlight.md) | Forces [task driven PWM](feature_backlight.md#software-pwm-driver) until ARM can provide automatic configuration |
|
||||||
|
| USB Host (e.g. USB-USB converter) | Not supported (USB host code is AVR specific and is not currently supported on ARM) |
|
||||||
|
| [Split keyboards](feature_split_keyboard.md) | Partial - heavily dependent on enabled features |
|
||||||
|
|
||||||
|
### Adafruit KB2040 :id=kb2040
|
||||||
|
|
||||||
|
The following defaults are based on what has been implemented for [RP2040](platformdev_rp2040.md) boards.
|
||||||
|
|
||||||
|
| Feature | Notes |
|
||||||
|
|----------------------------------------------|------------------------------------------------------------------------------------------------------------------|
|
||||||
|
| [RGB Lighting](feature_rgblight.md) | Enabled via `PIO` vendor driver |
|
||||||
|
| [Backlight](feature_backlight.md) | Forces [task driven PWM](feature_backlight.md#software-pwm-driver) until ARM can provide automatic configuration |
|
||||||
|
| USB Host (e.g. USB-USB converter) | Not supported (USB host code is AVR specific and is not currently supported on ARM) |
|
||||||
|
| [Split keyboards](feature_split_keyboard.md) | Partial via `PIO` vendor driver - heavily dependent on enabled features |
|
||||||
|
|
||||||
|
### SparkFun Pro Micro - RP2040, Blok, and Bit-C PRO :id=promicro_rp2040
|
||||||
|
|
||||||
|
Currently identical to [Adafruit KB2040](#kb2040).
|
||||||
|
|
||||||
|
### STeMCell :id=stemcell
|
||||||
|
|
||||||
|
Feature set currently identical to [Proton C](#proton_c).
|
||||||
|
There are two versions of STeMCell available, with different pinouts:
|
||||||
|
- v1.0.0
|
||||||
|
- v2.0.0 (pre-release v1.0.1, v1.0.2)
|
||||||
|
Default official firmware only supports v2.0.0 STeMCell.
|
||||||
|
|
||||||
|
STeMCell has support to swap UART and I2C pins, to enable single-wire uart communication in STM chips.
|
||||||
|
|
||||||
|
The following additional flags has to be used while compiling, based on the pin used for split communication.
|
||||||
|
|
||||||
|
| Split Pin | Compile flags |
|
||||||
|
|-----------|---------------|
|
||||||
|
| D3 | -e STMC_US=yes|
|
||||||
|
| D2 | Not needed |
|
||||||
|
| D1 | -e STMC_IS=yes|
|
||||||
|
| D0 | Not needed |
|
||||||
|
|
||||||
|
### Bonsai C4 :id=bonsai_c4
|
||||||
|
|
||||||
|
The Bonsai C4 only has one on-board LED (B2), and by default, both the Pro Micro TXLED (D5) and RXLED (B0) are mapped to it. If you want only one of them mapped, you can undefine one and redefine it to another pin by adding these line to your `config.h`:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#undef B0
|
||||||
|
// If Vbus detection is unused, we can send RXLED to the Vbus detect pin instead
|
||||||
|
#define B0 PAL_LINE(GPIOA, 9)
|
||||||
|
```
|
||||||
|
|
||||||
|
No peripherals are enabled by default at this time, but example code to enable SPI, I2C, PWM, and Serial communications can be found [here](/keyboards/custommk/bonsai_c4_template)
|
|
@ -35,6 +35,7 @@ There are a number of options added that should allow some additional degree of
|
||||||
|`DYNAMIC_MACRO_SIZE` |128 |Sets the amount of memory that Dynamic Macros can use. This is a limited resource, dependent on the controller. |
|
|`DYNAMIC_MACRO_SIZE` |128 |Sets the amount of memory that Dynamic Macros can use. This is a limited resource, dependent on the controller. |
|
||||||
|`DYNAMIC_MACRO_USER_CALL` |*Not defined* |Defining this falls back to using the user `keymap.c` file to trigger the macro behavior. |
|
|`DYNAMIC_MACRO_USER_CALL` |*Not defined* |Defining this falls back to using the user `keymap.c` file to trigger the macro behavior. |
|
||||||
|`DYNAMIC_MACRO_NO_NESTING` |*Not Defined* |Defining this disables the ability to call a macro from another macro (nested macros). |
|
|`DYNAMIC_MACRO_NO_NESTING` |*Not Defined* |Defining this disables the ability to call a macro from another macro (nested macros). |
|
||||||
|
|`DYNAMIC_MACRO_DELAY` |*Not Defined* |Sets the waiting time (ms unit) when sending each key. |
|
||||||
|
|
||||||
|
|
||||||
If the LEDs start blinking during the recording with each keypress, it means there is no more space for the macro in the macro buffer. To fit the macro in, either make the other macro shorter (they share the same buffer) or increase the buffer size by adding the `DYNAMIC_MACRO_SIZE` define in your `config.h` (default value: 128; please read the comments for it in the header).
|
If the LEDs start blinking during the recording with each keypress, it means there is no more space for the macro in the macro buffer. To fit the macro in, either make the other macro shorter (they share the same buffer) or increase the buffer size by adding the `DYNAMIC_MACRO_SIZE` define in your `config.h` (default value: 128; please read the comments for it in the header).
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
# Persistent Configuration (EEPROM)
|
||||||
|
|
||||||
|
This allows you to configure persistent settings for your keyboard. These settings are stored in the EEPROM of your controller, and are retained even after power loss. The settings can be read with `eeconfig_read_kb` and `eeconfig_read_user`, and can be written to using `eeconfig_update_kb` and `eeconfig_update_user`. This is useful for features that you want to be able to toggle (like toggling rgb layer indication). Additionally, you can use `eeconfig_init_kb` and `eeconfig_init_user` to set the default values for the EEPROM.
|
||||||
|
|
||||||
|
The complicated part here, is that there are a bunch of ways that you can store and access data via EEPROM, and there is no "correct" way to do this. However, you only have a DWORD (4 bytes) for each function.
|
||||||
|
|
||||||
|
Keep in mind that EEPROM has a limited number of writes. While this is very high, it's not the only thing writing to the EEPROM, and if you write too often, you can potentially drastically shorten the life of your MCU.
|
||||||
|
|
||||||
|
* If you don't understand the example, then you may want to avoid using this feature, as it is rather complicated.
|
||||||
|
|
||||||
|
## Example Implementation
|
||||||
|
|
||||||
|
This is an example of how to add settings, and read and write it. We're using the user keymap for the example here. This is a complex function, and has a lot going on. In fact, it uses a lot of the above functions to work!
|
||||||
|
|
||||||
|
|
||||||
|
In your keymap.c file, add this to the top:
|
||||||
|
```c
|
||||||
|
typedef union {
|
||||||
|
uint32_t raw;
|
||||||
|
struct {
|
||||||
|
bool rgb_layer_change :1;
|
||||||
|
};
|
||||||
|
} user_config_t;
|
||||||
|
|
||||||
|
user_config_t user_config;
|
||||||
|
```
|
||||||
|
|
||||||
|
This sets up a 32 bit structure that we can store settings with in memory, and write to the EEPROM. Using this removes the need to define variables, since they're defined in this structure. Remember that `bool` (boolean) values use 1 bit, `uint8_t` uses 8 bits, `uint16_t` uses up 16 bits. You can mix and match, but changing the order can cause issues, as it will change the values that are read and written.
|
||||||
|
|
||||||
|
We're using `rgb_layer_change`, for the `layer_state_set_*` function, and use `keyboard_post_init_user` and `process_record_user` to configure everything.
|
||||||
|
|
||||||
|
Now, using the `keyboard_post_init_user` code above, you want to add `eeconfig_read_user()` to it, to populate the structure you've just created. And you can then immediately use this structure to control functionality in your keymap. And It should look like:
|
||||||
|
```c
|
||||||
|
void keyboard_post_init_user(void) {
|
||||||
|
// Call the keymap level matrix init.
|
||||||
|
|
||||||
|
// Read the user config from EEPROM
|
||||||
|
user_config.raw = eeconfig_read_user();
|
||||||
|
|
||||||
|
// Set default layer, if enabled
|
||||||
|
if (user_config.rgb_layer_change) {
|
||||||
|
rgblight_enable_noeeprom();
|
||||||
|
rgblight_sethsv_noeeprom_cyan();
|
||||||
|
rgblight_mode_noeeprom(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
The above function will use the EEPROM config immediately after reading it, to set the default layer's RGB color. The "raw" value of it is converted in a usable structure based on the "union" that you created above.
|
||||||
|
|
||||||
|
```c
|
||||||
|
layer_state_t layer_state_set_user(layer_state_t state) {
|
||||||
|
switch (get_highest_layer(state)) {
|
||||||
|
case _RAISE:
|
||||||
|
if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_magenta(); rgblight_mode_noeeprom(1); }
|
||||||
|
break;
|
||||||
|
case _LOWER:
|
||||||
|
if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_red(); rgblight_mode_noeeprom(1); }
|
||||||
|
break;
|
||||||
|
case _PLOVER:
|
||||||
|
if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_green(); rgblight_mode_noeeprom(1); }
|
||||||
|
break;
|
||||||
|
case _ADJUST:
|
||||||
|
if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_white(); rgblight_mode_noeeprom(1); }
|
||||||
|
break;
|
||||||
|
default: // for any other layers, or the default layer
|
||||||
|
if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_cyan(); rgblight_mode_noeeprom(1); }
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
This will cause the RGB underglow to be changed ONLY if the value was enabled. Now to configure this value, create a new keycode for `process_record_user` called `RGB_LYR`. Additionally, we want to make sure that if you use the normal RGB codes, that it turns off Using the example above, make it look this:
|
||||||
|
```c
|
||||||
|
|
||||||
|
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
switch (keycode) {
|
||||||
|
case FOO:
|
||||||
|
if (record->event.pressed) {
|
||||||
|
// Do something when pressed
|
||||||
|
} else {
|
||||||
|
// Do something else when release
|
||||||
|
}
|
||||||
|
return false; // Skip all further processing of this key
|
||||||
|
case KC_ENTER:
|
||||||
|
// Play a tone when enter is pressed
|
||||||
|
if (record->event.pressed) {
|
||||||
|
PLAY_SONG(tone_qwerty);
|
||||||
|
}
|
||||||
|
return true; // Let QMK send the enter press/release events
|
||||||
|
case RGB_LYR: // This allows me to use underglow as layer indication, or as normal
|
||||||
|
if (record->event.pressed) {
|
||||||
|
user_config.rgb_layer_change ^= 1; // Toggles the status
|
||||||
|
eeconfig_update_user(user_config.raw); // Writes the new status to EEPROM
|
||||||
|
if (user_config.rgb_layer_change) { // if layer state indication is enabled,
|
||||||
|
layer_state_set(layer_state); // then immediately update the layer color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // For any of the RGB codes (see quantum_keycodes.h, L400 for reference)
|
||||||
|
if (record->event.pressed) { //This disables layer indication, as it's assumed that if you're changing this ... you want that disabled
|
||||||
|
if (user_config.rgb_layer_change) { // only if this is enabled
|
||||||
|
user_config.rgb_layer_change = false; // disable it, and
|
||||||
|
eeconfig_update_user(user_config.raw); // write the setings to EEPROM
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true; break;
|
||||||
|
default:
|
||||||
|
return true; // Process all other keycodes normally
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
And lastly, you want to add the `eeconfig_init_user` function, so that when the EEPROM is reset, you can specify default values, and even custom actions. To force an EEPROM reset, use the `EEP_RST` keycode or [Bootmagic Lite](feature_bootmagic.md) functionallity. For example, if you want to set rgb layer indication by default, and save the default valued.
|
||||||
|
|
||||||
|
```c
|
||||||
|
void eeconfig_init_user(void) { // EEPROM is getting reset!
|
||||||
|
user_config.raw = 0;
|
||||||
|
user_config.rgb_layer_change = true; // We want this enabled by default
|
||||||
|
eeconfig_update_user(user_config.raw); // Write default value to EEPROM now
|
||||||
|
|
||||||
|
// use the non noeeprom versions, to write these values to EEPROM too
|
||||||
|
rgblight_enable(); // Enable RGB by default
|
||||||
|
rgblight_sethsv_cyan(); // Set it to CYAN by default
|
||||||
|
rgblight_mode(1); // set to solid by default
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
And you're done. The RGB layer indication will only work if you want it to. And it will be saved, even after unplugging the board. And if you use any of the RGB codes, it will disable the layer indication, so that it stays on the mode and color that you set it to.
|
||||||
|
|
||||||
|
## 'EECONFIG' Function Documentation
|
||||||
|
|
||||||
|
* Keyboard/Revision: `void eeconfig_init_kb(void)`, `uint32_t eeconfig_read_kb(void)` and `void eeconfig_update_kb(uint32_t val)`
|
||||||
|
* Keymap: `void eeconfig_init_user(void)`, `uint32_t eeconfig_read_user(void)` and `void eeconfig_update_user(uint32_t val)`
|
||||||
|
|
||||||
|
The `val` is the value of the data that you want to write to EEPROM. And the `eeconfig_read_*` function return a 32 bit (DWORD) value from the EEPROM.
|
|
@ -69,7 +69,7 @@ Additionally, if one side does not have an encoder, you can specify `{}` for the
|
||||||
|
|
||||||
## Encoder map :id=encoder-map
|
## Encoder map :id=encoder-map
|
||||||
|
|
||||||
Encoder mapping may be added to your `keymap.c`, which replicates the normal keyswitch layer handling functionality, but with encoders. Add this to your `rules.mk`:
|
Encoder mapping may be added to your `keymap.c`, which replicates the normal keyswitch layer handling functionality, but with encoders. Add this to your keymap's `rules.mk`:
|
||||||
|
|
||||||
```make
|
```make
|
||||||
ENCODER_MAP_ENABLE = yes
|
ENCODER_MAP_ENABLE = yes
|
||||||
|
@ -88,6 +88,8 @@ const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][2] = {
|
||||||
#endif
|
#endif
|
||||||
```
|
```
|
||||||
|
|
||||||
|
?> This should only be enabled at the keymap level.
|
||||||
|
|
||||||
## Callbacks
|
## Callbacks
|
||||||
|
|
||||||
When not using `ENCODER_MAP_ENABLE = yes`, the callback functions can be inserted into your `<keyboard>.c`:
|
When not using `ENCODER_MAP_ENABLE = yes`, the callback functions can be inserted into your `<keyboard>.c`:
|
||||||
|
|
|
@ -89,3 +89,46 @@ 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_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_state_cmp(state, layer)` | Checks `state` to see if the specified `layer` is enabled. Intended for use in layer callbacks. | `IS_LAYER_ON_STATE(state, layer)`, `IS_LAYER_OFF_STATE(state, layer)` |
|
||||||
|
|
||||||
|
## Layer Change Code :id=layer-change-code
|
||||||
|
|
||||||
|
This runs code every time that the layers get changed. This can be useful for layer indication, or custom layer handling.
|
||||||
|
|
||||||
|
### Example `layer_state_set_*` Implementation
|
||||||
|
|
||||||
|
This example shows how to set the [RGB Underglow](feature_rgblight.md) lights based on the layer, using the Planck as an example.
|
||||||
|
|
||||||
|
```c
|
||||||
|
layer_state_t layer_state_set_user(layer_state_t state) {
|
||||||
|
switch (get_highest_layer(state)) {
|
||||||
|
case _RAISE:
|
||||||
|
rgblight_setrgb (0x00, 0x00, 0xFF);
|
||||||
|
break;
|
||||||
|
case _LOWER:
|
||||||
|
rgblight_setrgb (0xFF, 0x00, 0x00);
|
||||||
|
break;
|
||||||
|
case _PLOVER:
|
||||||
|
rgblight_setrgb (0x00, 0xFF, 0x00);
|
||||||
|
break;
|
||||||
|
case _ADJUST:
|
||||||
|
rgblight_setrgb (0x7A, 0x00, 0xFF);
|
||||||
|
break;
|
||||||
|
default: // for any other layers, or the default layer
|
||||||
|
rgblight_setrgb (0x00, 0xFF, 0xFF);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the `IS_LAYER_ON_STATE(state, layer)` and `IS_LAYER_OFF_STATE(state, layer)` macros to check the status of a particular layer.
|
||||||
|
|
||||||
|
Outside of `layer_state_set_*` functions, you can use the `IS_LAYER_ON(layer)` and `IS_LAYER_OFF(layer)` macros to check global layer state.
|
||||||
|
|
||||||
|
### `layer_state_set_*` Function Documentation
|
||||||
|
|
||||||
|
* Keyboard/Revision: `layer_state_t layer_state_set_kb(layer_state_t state)`
|
||||||
|
* Keymap: `layer_state_t layer_state_set_user(layer_state_t state)`
|
||||||
|
|
||||||
|
|
||||||
|
The `state` is the bitmask of the active layers, as explained in the [Keymap Overview](keymap.md#keymap-layer-status)
|
||||||
|
|
|
@ -106,6 +106,8 @@ Only basic keycodes (prefixed by `KC_`) are supported. Do not include the `KC_`
|
||||||
|
|
||||||
### `SEND_STRING()` & `process_record_user`
|
### `SEND_STRING()` & `process_record_user`
|
||||||
|
|
||||||
|
See also: [Send String](feature_send_string.md)
|
||||||
|
|
||||||
Sometimes you want a key to type out words or phrases. For the most common situations, we've provided `SEND_STRING()`, which will type out a string (i.e. a sequence of characters) for you. All ASCII characters that are easily translatable to a keycode are supported (e.g. `qmk 123\n\t`).
|
Sometimes you want a key to type out words or phrases. For the most common situations, we've provided `SEND_STRING()`, which will type out a string (i.e. a sequence of characters) for you. All ASCII characters that are easily translatable to a keycode are supported (e.g. `qmk 123\n\t`).
|
||||||
|
|
||||||
Here is an example `keymap.c` for a two-key keyboard:
|
Here is an example `keymap.c` for a two-key keyboard:
|
||||||
|
@ -347,7 +349,7 @@ If the keycode is `KC_CAPS`, it waits `TAP_HOLD_CAPS_DELAY` milliseconds instead
|
||||||
|
|
||||||
Like `tap_code(<kc>)`, but with a `delay` parameter for specifying arbitrary intervals before sending the unregister event.
|
Like `tap_code(<kc>)`, but with a `delay` parameter for specifying arbitrary intervals before sending the unregister event.
|
||||||
|
|
||||||
#### `register_code16(<kc>);`, `unregister_code16(<kc>);` and `tap_code16(<kc>);`
|
#### `register_code16(<kc>);`, `unregister_code16(<kc>);`, `tap_code16(<kc>);` and `tap_code16_delay(<kc>, <delay>);`
|
||||||
|
|
||||||
These functions work similar to their regular counterparts, but allow you to use modded keycodes (with Shift, Alt, Control, and/or GUI applied to them).
|
These functions work similar to their regular counterparts, but allow you to use modded keycodes (with Shift, Alt, Control, and/or GUI applied to them).
|
||||||
|
|
||||||
|
|
|
@ -87,9 +87,9 @@ This is an extension of the accelerated mode. The kinetic mode uses a quadratic
|
||||||
|`MK_KINETIC_SPEED` |undefined|Enable kinetic mode |
|
|`MK_KINETIC_SPEED` |undefined|Enable kinetic mode |
|
||||||
|`MOUSEKEY_DELAY` |5 |Delay between pressing a movement key and cursor movement |
|
|`MOUSEKEY_DELAY` |5 |Delay between pressing a movement key and cursor movement |
|
||||||
|`MOUSEKEY_INTERVAL` |10 |Time between cursor movements in milliseconds |
|
|`MOUSEKEY_INTERVAL` |10 |Time between cursor movements in milliseconds |
|
||||||
|`MOUSEKEY_MOVE_DELTA` |5 |Step size for accelerating from initial to base speed |
|
|`MOUSEKEY_MOVE_DELTA` |16 |Step size for accelerating from initial to base speed |
|
||||||
|`MOUSEKEY_INITIAL_SPEED` |100 |Initial speed of the cursor in pixel per second |
|
|`MOUSEKEY_INITIAL_SPEED` |100 |Initial speed of the cursor in pixel per second |
|
||||||
|`MOUSEKEY_BASE_SPEED` |1000 |Maximum cursor speed at which acceleration stops |
|
|`MOUSEKEY_BASE_SPEED` |5000 |Maximum cursor speed at which acceleration stops |
|
||||||
|`MOUSEKEY_DECELERATED_SPEED` |400 |Decelerated cursor speed |
|
|`MOUSEKEY_DECELERATED_SPEED` |400 |Decelerated cursor speed |
|
||||||
|`MOUSEKEY_ACCELERATED_SPEED` |3000 |Accelerated cursor speed |
|
|`MOUSEKEY_ACCELERATED_SPEED` |3000 |Accelerated cursor speed |
|
||||||
|`MOUSEKEY_WHEEL_INITIAL_MOVEMENTS` |16 |Initial number of movements of the mouse wheel |
|
|`MOUSEKEY_WHEEL_INITIAL_MOVEMENTS` |16 |Initial number of movements of the mouse wheel |
|
||||||
|
@ -100,7 +100,7 @@ This is an extension of the accelerated mode. The kinetic mode uses a quadratic
|
||||||
Tips:
|
Tips:
|
||||||
|
|
||||||
* The smoothness of the cursor movement depends on the `MOUSEKEY_INTERVAL` setting. The shorter the interval is set the smoother the movement will be. Setting the value too low makes the cursor unresponsive. Lower settings are possible if the micro processor is fast enough. For example: At an interval of `8` milliseconds, `125` movements per second will be initiated. With a base speed of `1000` each movement will move the cursor by `8` pixels.
|
* The smoothness of the cursor movement depends on the `MOUSEKEY_INTERVAL` setting. The shorter the interval is set the smoother the movement will be. Setting the value too low makes the cursor unresponsive. Lower settings are possible if the micro processor is fast enough. For example: At an interval of `8` milliseconds, `125` movements per second will be initiated. With a base speed of `1000` each movement will move the cursor by `8` pixels.
|
||||||
* Mouse wheel movements are implemented differently from cursor movements. While it's okay for the cursor to move multiple pixels at once for the mouse wheel this would lead to jerky movements. Instead, the mouse wheel operates at step size `1`. Setting mouse wheel speed is done by adjusting the number of wheel movements per second.
|
* Mouse wheel movements are implemented differently from cursor movements. While it's okay for the cursor to move multiple pixels at once for the mouse wheel this would lead to jerky movements. Instead, the mouse wheel operates at step size `2`. Setting mouse wheel speed is done by adjusting the number of wheel movements per second.
|
||||||
|
|
||||||
### Constant mode
|
### Constant mode
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,6 @@ Tested combinations:
|
||||||
|
|
||||||
Hardware configurations using Arm-based microcontrollers or different sizes of OLED modules may be compatible, but are untested.
|
Hardware configurations using Arm-based microcontrollers or different sizes of OLED modules may be compatible, but are untested.
|
||||||
|
|
||||||
!> Warning: This OLED driver currently uses the new i2c_master driver from Split Common code. If your split keyboard uses I2C to communicate between sides, this driver could cause an address conflict (serial is fine). Please contact your keyboard vendor and ask them to migrate to the latest Split Common code to fix this. In addition, the display timeout system to reduce OLED burn-in also uses Split Common to detect keypresses, so you will need to implement custom timeout logic for non-Split Common keyboards.
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
To enable the OLED feature, there are two steps. First, when compiling your keyboard, you'll need to add the following to your `rules.mk`:
|
To enable the OLED feature, there are two steps. First, when compiling your keyboard, you'll need to add the following to your `rules.mk`:
|
||||||
|
|
|
@ -10,7 +10,7 @@ POINTING_DEVICE_ENABLE = yes
|
||||||
|
|
||||||
## Sensor Drivers
|
## Sensor Drivers
|
||||||
|
|
||||||
There are a number of sensors that are supported by default. Note that only one sensor can be enabled by `POINTING_DEVICE_DRIVER` at a time. If you need to enable more than one sensor, then you need to implement it manually.
|
There are a number of sensors that are supported by default. Note that only one sensor can be enabled by `POINTING_DEVICE_DRIVER` at a time. If you need to enable more than one sensor, then you need to implement it manually, using the `custom` driver.
|
||||||
|
|
||||||
### ADNS 5050 Sensor
|
### ADNS 5050 Sensor
|
||||||
|
|
||||||
|
@ -22,11 +22,13 @@ POINTING_DEVICE_DRIVER = adns5050
|
||||||
|
|
||||||
The ADNS 5050 sensor uses a serial type protocol for communication, and requires an additional light source.
|
The ADNS 5050 sensor uses a serial type protocol for communication, and requires an additional light source.
|
||||||
|
|
||||||
| Setting | Description |
|
| Setting | Description | Default |
|
||||||
|--------------------|---------------------------------------------------------------------|
|
| ------------------- | ------------------------------------------------------------------- | -------------------------- |
|
||||||
|`ADNS5050_SCLK_PIN` | (Required) The pin connected to the clock pin of the sensor. |
|
| `ADNS5050_SCLK_PIN` | (Required) The pin connected to the clock pin of the sensor. | `POINTING_DEVICE_SCLK_PIN` |
|
||||||
|`ADNS5050_SDIO_PIN` | (Required) The pin connected to the data pin of the sensor. |
|
| `ADNS5050_SDIO_PIN` | (Required) The pin connected to the data pin of the sensor. | `POINTING_DEVICE_SDIO_PIN` |
|
||||||
|`ADNS5050_CS_PIN` | (Required) The pin connected to the cable select pin of the sensor. |
|
| `ADNS5050_CS_PIN` | (Required) The pin connected to the cable select pin of the sensor. | `POINTING_DEVICE_CS_PIN` |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The CPI range is 125-1375, in increments of 125. Defaults to 500 CPI.
|
The CPI range is 125-1375, in increments of 125. Defaults to 500 CPI.
|
||||||
|
|
||||||
|
@ -40,13 +42,13 @@ POINTING_DEVICE_DRIVER = adns9800
|
||||||
|
|
||||||
The ADNS 9800 is an SPI driven optical sensor, that uses laser output for surface tracking.
|
The ADNS 9800 is an SPI driven optical sensor, that uses laser output for surface tracking.
|
||||||
|
|
||||||
| Setting | Description | Default |
|
| Setting | Description | Default |
|
||||||
|--------------------------------|------------------------------------------------------------------------|---------------|
|
| ----------------------- | ---------------------------------------------------------------------- | ------------------------ |
|
||||||
|`ADNS9800_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `2000000` |
|
| `ADNS9800_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `2000000` |
|
||||||
|`ADNS9800_SPI_LSBFIRST` | (Optional) Sets the Least/Most Significant Byte First setting for SPI. | `false` |
|
| `ADNS9800_SPI_LSBFIRST` | (Optional) Sets the Least/Most Significant Byte First setting for SPI. | `false` |
|
||||||
|`ADNS9800_SPI_MODE` | (Optional) Sets the SPI Mode for the sensor. | `3` |
|
| `ADNS9800_SPI_MODE` | (Optional) Sets the SPI Mode for the sensor. | `3` |
|
||||||
|`ADNS9800_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ |
|
| `ADNS9800_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ |
|
||||||
|`ADNS9800_CS_PIN` | (Required) Sets the Cable Select pin connected to the sensor. | _not defined_ |
|
| `ADNS9800_CS_PIN` | (Required) Sets the Cable Select pin connected to the sensor. | `POINTING_DEVICE_CS_PIN` |
|
||||||
|
|
||||||
|
|
||||||
The CPI range is 800-8200, in increments of 200. Defaults to 1800 CPI.
|
The CPI range is 800-8200, in increments of 200. Defaults to 1800 CPI.
|
||||||
|
@ -61,17 +63,16 @@ POINTING_DEVICE_DRIVER = analog_joystick
|
||||||
|
|
||||||
The Analog Joystick is an analog (ADC) driven sensor. There are a variety of joysticks that you can use for this.
|
The Analog Joystick is an analog (ADC) driven sensor. There are a variety of joysticks that you can use for this.
|
||||||
|
|
||||||
| Setting | Description | Default |
|
| Setting | Description | Default |
|
||||||
|----------------------------------|----------------------------------------------------------------------------|---------------|
|
| --------------------------------- | -------------------------------------------------------------------------- | ------------- |
|
||||||
|`ANALOG_JOYSTICK_X_AXIS_PIN` | (Required) The pin used for the vertical/X axis. | _not defined_ |
|
| `ANALOG_JOYSTICK_X_AXIS_PIN` | (Required) The pin used for the vertical/X axis. | _not defined_ |
|
||||||
|`ANALOG_JOYSTICK_Y_AXIS_PIN` | (Required) The pin used for the horizontal/Y axis. | _not defined_ |
|
| `ANALOG_JOYSTICK_Y_AXIS_PIN` | (Required) The pin used for the horizontal/Y axis. | _not defined_ |
|
||||||
|`ANALOG_JOYSTICK_AXIS_MIN` | (Optional) Sets the lower range to be considered movement. | `0` |
|
| `ANALOG_JOYSTICK_AXIS_MIN` | (Optional) Sets the lower range to be considered movement. | `0` |
|
||||||
|`ANALOG_JOYSTICK_AXIS_MAX` | (Optional) Sets the upper range to be considered movement. | `1023` |
|
| `ANALOG_JOYSTICK_AXIS_MAX` | (Optional) Sets the upper range to be considered movement. | `1023` |
|
||||||
|`ANALOG_JOYSTICK_SPEED_REGULATOR` | (Optional) The divisor used to slow down movement. (lower makes it faster) | `20` |
|
| `ANALOG_JOYSTICK_SPEED_REGULATOR` | (Optional) The divisor used to slow down movement. (lower makes it faster) | `20` |
|
||||||
|`ANALOG_JOYSTICK_READ_INTERVAL` | (Optional) The interval in milliseconds between reads. | `10` |
|
| `ANALOG_JOYSTICK_READ_INTERVAL` | (Optional) The interval in milliseconds between reads. | `10` |
|
||||||
|`ANALOG_JOYSTICK_SPEED_MAX` | (Optional) The maximum value used for motion. | `2` |
|
| `ANALOG_JOYSTICK_SPEED_MAX` | (Optional) The maximum value used for motion. | `2` |
|
||||||
|`ANALOG_JOYSTICK_CLICK_PIN` | (Optional) The pin wired up to the press switch of the analog stick. | _not defined_ |
|
| `ANALOG_JOYSTICK_CLICK_PIN` | (Optional) The pin wired up to the press switch of the analog stick. | _not defined_ |
|
||||||
|
|
||||||
|
|
||||||
### Cirque Trackpad
|
### Cirque Trackpad
|
||||||
|
|
||||||
|
@ -90,29 +91,93 @@ POINTING_DEVICE_DRIVER = cirque_pinnacle_spi
|
||||||
|
|
||||||
This supports the Cirque Pinnacle 1CA027 Touch Controller, which is used in the TM040040, TM035035 and the TM023023 trackpads. These are I2C or SPI compatible, and both configurations are supported.
|
This supports the Cirque Pinnacle 1CA027 Touch Controller, which is used in the TM040040, TM035035 and the TM023023 trackpads. These are I2C or SPI compatible, and both configurations are supported.
|
||||||
|
|
||||||
| Setting | Description | Default |
|
#### Common settings
|
||||||
|---------------------------------|---------------------------------------------------------------------------------|-----------------------|
|
|
||||||
|`CIRQUE_PINNACLE_X_LOWER` | (Optional) The minimum reachable X value on the sensor. | `127` |
|
|
||||||
|`CIRQUE_PINNACLE_X_UPPER` | (Optional) The maximum reachable X value on the sensor. | `1919` |
|
|
||||||
|`CIRQUE_PINNACLE_Y_LOWER` | (Optional) The minimum reachable Y value on the sensor. | `63` |
|
|
||||||
|`CIRQUE_PINNACLE_Y_UPPER` | (Optional) The maximum reachable Y value on the sensor. | `1471` |
|
|
||||||
|`CIRQUE_PINNACLE_TAPPING_TERM` | (Optional) Length of time that a touch can be to be considered a tap. | `TAPPING_TERM`/`200` |
|
|
||||||
|`CIRQUE_PINNACLE_TOUCH_DEBOUNCE` | (Optional) Length of time that a touch can be to be considered a tap. | `TAPPING_TERM`/`200` |
|
|
||||||
|
|
||||||
| I2C Setting | Description | Default |
|
| Setting | Description | Default |
|
||||||
|--------------------------|---------------------------------------------------------------------------------|---------|
|
| -------------------------------- | ---------------------------------------------------------- | ------------------ |
|
||||||
|`CIRQUE_PINNACLE_ADDR` | (Required) Sets the I2C Address for the Cirque Trackpad | `0x2A` |
|
| `CIRQUE_PINNACLE_DIAMETER_MM` | (Optional) Diameter of the trackpad sensor in millimeters. | `40` |
|
||||||
|`CIRQUE_PINNACLE_TIMEOUT` | (Optional) The timeout for i2c communication with the trackpad in milliseconds. | `20` |
|
| `CIRQUE_PINNACLE_ATTENUATION` | (Optional) Sets the attenuation of the sensor data. | `ADC_ATTENUATE_4X` |
|
||||||
|
| `CIRQUE_PINNACLE_CURVED_OVERLAY` | (Optional) Applies settings tuned for curved overlay. | _not defined_ |
|
||||||
|
| `CIRQUE_PINNACLE_POSITION_MODE` | (Optional) Mode of operation. | _not defined_ |
|
||||||
|
|
||||||
| SPI Setting | Description | Default |
|
**`CIRQUE_PINNACLE_ATTENUATION`** is a measure of how much data is suppressed in regards to sensitivity. The higher the attenuation, the less sensitive the touchpad will be.
|
||||||
|-------------------------------|------------------------------------------------------------------------|---------------|
|
|
||||||
|`CIRQUE_PINNACLE_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `1000000` |
|
|
||||||
|`CIRQUE_PINNACLE_SPI_LSBFIRST` | (Optional) Sets the Least/Most Significant Byte First setting for SPI. | `false` |
|
|
||||||
|`CIRQUE_PINNACLE_SPI_MODE` | (Optional) Sets the SPI Mode for the sensor. | `1` |
|
|
||||||
|`CIRQUE_PINNACLE_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ |
|
|
||||||
|`CIRQUE_PINNACLE_SPI_CS_PIN` | (Required) Sets the Cable Select pin connected to the sensor. | _not defined_ |
|
|
||||||
|
|
||||||
Default Scaling/CPI is 1024.
|
Default attenuation is set to 4X, although if you are using a thicker overlay (such as the curved overlay) you will want a lower attenuation such as 2X. The possible values are:
|
||||||
|
* `ADC_ATTENUATE_4X`: Least sensitive
|
||||||
|
* `ADC_ATTENUATE_3X`
|
||||||
|
* `ADC_ATTENUATE_2X`
|
||||||
|
* `ADC_ATTENUATE_1X`: Most sensitive
|
||||||
|
|
||||||
|
**`CIRQUE_PINNACLE_POSITION_MODE`** can be `CIRQUE_PINNACLE_ABSOLUTE_MODE` or `CIRQUE_PINNACLE_RELATIVE_MODE`. Modes differ in supported features/gestures.
|
||||||
|
|
||||||
|
* `CIRQUE_PINNACLE_ABSOLUTE_MODE`: Reports absolute x, y, z (touch pressure) coordinates and up to 5 hw buttons connected to the trackpad
|
||||||
|
* `CIRQUE_PINNACLE_RELATIVE_MODE`: Reports x/y deltas, scroll and up to 3 buttons (2 of them can be from taps, see gestures) connected to trackpad. Supports taps on secondary side of split. Saves about 2k of flash compared to absolute mode with all features.
|
||||||
|
|
||||||
|
| I2C Setting | Description | Default |
|
||||||
|
| ------------------------- | ------------------------------------------------------------------------------- | ------- |
|
||||||
|
| `CIRQUE_PINNACLE_ADDR` | (Required) Sets the I2C Address for the Cirque Trackpad | `0x2A` |
|
||||||
|
| `CIRQUE_PINNACLE_TIMEOUT` | (Optional) The timeout for i2c communication with the trackpad in milliseconds. | `20` |
|
||||||
|
|
||||||
|
| SPI Setting | Description | Default |
|
||||||
|
| ------------------------------ | ---------------------------------------------------------------------- | ------------------------ |
|
||||||
|
| `CIRQUE_PINNACLE_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `1000000` |
|
||||||
|
| `CIRQUE_PINNACLE_SPI_LSBFIRST` | (Optional) Sets the Least/Most Significant Byte First setting for SPI. | `false` |
|
||||||
|
| `CIRQUE_PINNACLE_SPI_MODE` | (Optional) Sets the SPI Mode for the sensor. | `1` |
|
||||||
|
| `CIRQUE_PINNACLE_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ |
|
||||||
|
| `CIRQUE_PINNACLE_SPI_CS_PIN` | (Required) Sets the Cable Select pin connected to the sensor. | `POINTING_DEVICE_CS_PIN` |
|
||||||
|
|
||||||
|
Default Scaling is 1024. Actual CPI depends on trackpad diameter.
|
||||||
|
|
||||||
|
Also see the `POINTING_DEVICE_TASK_THROTTLE_MS`, which defaults to 10ms when using Cirque Pinnacle, which matches the internal update rate of the position registers (in standard configuration). Advanced configuration for pen/stylus usage might require lower values.
|
||||||
|
|
||||||
|
#### Absolute mode settings
|
||||||
|
|
||||||
|
| Setting | Description | Default |
|
||||||
|
| -------------------------------- | ---------------------------------------------------------- | ------------------ |
|
||||||
|
| `CIRQUE_PINNACLE_X_LOWER` | (Optional) The minimum reachable X value on the sensor. | `127` |
|
||||||
|
| `CIRQUE_PINNACLE_X_UPPER` | (Optional) The maximum reachable X value on the sensor. | `1919` |
|
||||||
|
| `CIRQUE_PINNACLE_Y_LOWER` | (Optional) The minimum reachable Y value on the sensor. | `63` |
|
||||||
|
| `CIRQUE_PINNACLE_Y_UPPER` | (Optional) The maximum reachable Y value on the sensor. | `1471` |
|
||||||
|
|
||||||
|
#### Absolute mode gestures
|
||||||
|
|
||||||
|
| Gesture Setting | Description | Default |
|
||||||
|
| ---------------------------------------------- | ------------------------------------------------------------------------------ | -------------------- |
|
||||||
|
| `CIRQUE_PINNACLE_TAP_ENABLE` | (Optional) Enable tap to click. This currently only works on the master side. | _not defined_ |
|
||||||
|
| `CIRQUE_PINNACLE_TAPPING_TERM` | (Optional) Length of time that a touch can be to be considered a tap. | `TAPPING_TERM`/`200` |
|
||||||
|
| `CIRQUE_PINNACLE_TOUCH_DEBOUNCE` | (Optional) Length of time that a touch can be to be considered a tap. | `TAPPING_TERM`/`200` |
|
||||||
|
|
||||||
|
`POINTING_DEVICE_GESTURES_SCROLL_ENABLE` in this mode enables circular scroll. Touch originating in outer ring can trigger scroll by moving along the perimeter. Near side triggers vertical scroll and far side triggers horizontal scroll.
|
||||||
|
|
||||||
|
Additionally, `POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE` is supported in this mode.
|
||||||
|
|
||||||
|
#### Relative mode gestures
|
||||||
|
|
||||||
|
| Gesture Setting | Description | Default |
|
||||||
|
| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
|
||||||
|
| `CIRQUE_PINNACLE_TAP_ENABLE` | (Optional) Enable tap to "left click". Works on both sides of a split keyboard. | _not defined_ |
|
||||||
|
| `CIRQUE_PINNACLE_SECONDARY_TAP_ENABLE` | (Optional) Tap in upper right corner (half of the finger needs to be outside of the trackpad) of the trackpad will result in "right click". `CIRQUE_PINNACLE_TAP_ENABLE` must be enabled. | _not defined_ |
|
||||||
|
|
||||||
|
Tapping term and debounce are not configurable in this mode since it's handled by trackpad internally.
|
||||||
|
|
||||||
|
`POINTING_DEVICE_GESTURES_SCROLL_ENABLE` in this mode enables side scroll. Touch originating on the right side can trigger vertical scroll (IntelliSense trackpad style).
|
||||||
|
|
||||||
|
### PAW 3204 Sensor
|
||||||
|
|
||||||
|
To use the paw 3204 sensor, add this to your `rules.mk`
|
||||||
|
|
||||||
|
```make
|
||||||
|
POINTING_DEVICE_DRIVER = paw3204
|
||||||
|
```
|
||||||
|
|
||||||
|
The paw 3204 sensor uses a serial type protocol for communication, and requires an additional light source.
|
||||||
|
|
||||||
|
| Setting | Description | Default |
|
||||||
|
| ------------------ |--------------------------------------------------------------- | -------------------------- |
|
||||||
|
| `PAW3204_SCLK_PIN` | (Required) The pin connected to the clock pin of the sensor. | `POINTING_DEVICE_SCLK_PIN` |
|
||||||
|
| `PAW3204_SDIO_PIN` | (Required) The pin connected to the data pin of the sensor. | `POINTING_DEVICE_SDIO_PIN` |
|
||||||
|
|
||||||
|
The CPI range is 400-1600, with supported values of (400, 500, 600, 800, 1000, 1200 and 1600). Defaults to 1000 CPI.
|
||||||
|
|
||||||
### Pimoroni Trackball
|
### Pimoroni Trackball
|
||||||
|
|
||||||
|
@ -124,62 +189,69 @@ POINTING_DEVICE_DRIVER = pimoroni_trackball
|
||||||
|
|
||||||
The Pimoroni Trackball module is a I2C based breakout board with an RGB enable trackball.
|
The Pimoroni Trackball module is a I2C based breakout board with an RGB enable trackball.
|
||||||
|
|
||||||
| Setting | Description | Default |
|
| Setting | Description | Default |
|
||||||
|-------------------------------------|------------------------------------------------------------------------------------|---------|
|
| ------------------------------------ | ---------------------------------------------------------------------------------- | ------- |
|
||||||
|`PIMORONI_TRACKBALL_ADDRESS` | (Required) Sets the I2C Address for the Pimoroni Trackball. | `0x0A` |
|
| `PIMORONI_TRACKBALL_ADDRESS` | (Required) Sets the I2C Address for the Pimoroni Trackball. | `0x0A` |
|
||||||
|`PIMORONI_TRACKBALL_TIMEOUT` | (Optional) The timeout for i2c communication with the trackball in milliseconds. | `100` |
|
| `PIMORONI_TRACKBALL_TIMEOUT` | (Optional) The timeout for i2c communication with the trackball in milliseconds. | `100` |
|
||||||
|`PIMORONI_TRACKBALL_SCALE` | (Optional) The multiplier used to generate reports from the sensor. | `5` |
|
| `PIMORONI_TRACKBALL_SCALE` | (Optional) The multiplier used to generate reports from the sensor. | `5` |
|
||||||
|`PIMORONI_TRACKBALL_DEBOUNCE_CYCLES` | (Optional) The number of scan cycles used for debouncing on the ball press. | `20` |
|
| `PIMORONI_TRACKBALL_DEBOUNCE_CYCLES` | (Optional) The number of scan cycles used for debouncing on the ball press. | `20` |
|
||||||
|`PIMORONI_TRACKBALL_ERROR_COUNT` | (Optional) Specifies the number of read/write errors until the sensor is disabled. | `10` |
|
| `PIMORONI_TRACKBALL_ERROR_COUNT` | (Optional) Specifies the number of read/write errors until the sensor is disabled. | `10` |
|
||||||
|
|
||||||
### PMW 3360 Sensor
|
### PMW 3360 and PMW 3389 Sensor
|
||||||
|
|
||||||
This drivers supports multiple sensors _per_ controller, so 2 can be attached at the same side for split keyboards (or unsplit keyboards).
|
This drivers supports both the PMW 3360 and PMW 3389 sensor as well as multiple sensors of the same type _per_ controller, so 2 can be attached at the same side for split keyboards (or unsplit keyboards).
|
||||||
To use the PMW 3360 sensor, add this to your `rules.mk`
|
|
||||||
|
To use the **PMW 3360** sensor, add this to your `rules.mk`
|
||||||
|
|
||||||
```make
|
```make
|
||||||
POINTING_DEVICE_DRIVER = pmw3360
|
POINTING_DEVICE_DRIVER = pmw3360
|
||||||
```
|
```
|
||||||
|
|
||||||
The PMW 3360 is an SPI driven optical sensor, that uses a built in IR LED for surface tracking.
|
|
||||||
|
|
||||||
| Setting | Description | Default |
|
|
||||||
|-----------------------------|--------------------------------------------------------------------------------------------|---------------|
|
|
||||||
|`PMW3360_CS_PIN` | (Required) Sets the Cable Select pin connected to the sensor. | _not defined_ |
|
|
||||||
|`PMW3360_CS_PINS` | (Alternative) Sets the Cable Select pins connected to multiple sensors. | _not defined_ |
|
|
||||||
|`PMW3360_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `2000000` |
|
|
||||||
|`PMW3360_SPI_LSBFIRST` | (Optional) Sets the Least/Most Significant Byte First setting for SPI. | `false` |
|
|
||||||
|`PMW3360_SPI_MODE` | (Optional) Sets the SPI Mode for the sensor. | `3` |
|
|
||||||
|`PMW3360_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ |
|
|
||||||
|`PMW3360_LIFTOFF_DISTANCE` | (Optional) Sets the lift off distance at run time | `0x02` |
|
|
||||||
|`ROTATIONAL_TRANSFORM_ANGLE` | (Optional) Allows for the sensor data to be rotated +/- 127 degrees directly in the sensor.| `0` |
|
|
||||||
|`PMW3360_FIRMWARE_UPLOAD_FAST` | (Optional) Skips the 15us wait between firmware blocks. | _not defined_ |
|
|
||||||
|
|
||||||
The CPI range is 100-12000, in increments of 100. Defaults to 1600 CPI.
|
The CPI range is 100-12000, in increments of 100. Defaults to 1600 CPI.
|
||||||
|
|
||||||
To use multiple sensors, instead of setting `PMW3360_CS_PIN` you need to set `PMW3360_CS_PINS` and also handle and merge the read from this sensor in user code.
|
To use the **PMW 3389** sensor, add this to your `rules.mk`
|
||||||
|
|
||||||
|
```make
|
||||||
|
POINTING_DEVICE_DRIVER = pmw3389
|
||||||
|
```
|
||||||
|
|
||||||
|
The CPI range is 50-16000, in increments of 50. Defaults to 2000 CPI.
|
||||||
|
|
||||||
|
Both PMW 3360 and PMW 3389 are SPI driven optical sensors, that use a built in IR LED for surface tracking.
|
||||||
|
|
||||||
|
| Setting | Description | Default |
|
||||||
|
| ---------------------------- | ------------------------------------------------------------------------------------------- | ------------------------ |
|
||||||
|
| `PMW33XX_CS_PIN` | (Required) Sets the Cable Select pin connected to the sensor. | `POINTING_DEVICE_CS_PIN` |
|
||||||
|
| `PMW33XX_CS_PINS` | (Alternative) Sets the Cable Select pins connected to multiple sensors. | _not defined_ |
|
||||||
|
| `PMW33XX_CPI` | (Optional) Sets counts per inch sensitivity of the sensor. | _varies_ |
|
||||||
|
| `PMW33XX_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `2000000` |
|
||||||
|
| `PMW33XX_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ |
|
||||||
|
| `PMW33XX_LIFTOFF_DISTANCE` | (Optional) Sets the lift off distance at run time | `0x02` |
|
||||||
|
| `ROTATIONAL_TRANSFORM_ANGLE` | (Optional) Allows for the sensor data to be rotated +/- 127 degrees directly in the sensor. | `0` |
|
||||||
|
|
||||||
|
To use multiple sensors, instead of setting `PMW33XX_CS_PIN` you need to set `PMW33XX_CS_PINS` and also handle and merge the read from this sensor in user code.
|
||||||
Note that different (per sensor) values of CPI, speed liftoff, rotational angle or flipping of X/Y is not currently supported.
|
Note that different (per sensor) values of CPI, speed liftoff, rotational angle or flipping of X/Y is not currently supported.
|
||||||
|
|
||||||
```c
|
```c
|
||||||
// in config.h:
|
// in config.h:
|
||||||
#define PMW3360_CS_PINS { B5, B6 }
|
#define PMW33XX_CS_PINS { B5, B6 }
|
||||||
|
|
||||||
// in keyboard.c:
|
// in keyboard.c:
|
||||||
#ifdef POINTING_DEVICE_ENABLE
|
#ifdef POINTING_DEVICE_ENABLE
|
||||||
void pointing_device_init_kb(void) {
|
void pointing_device_init_kb(void) {
|
||||||
pmw3360_init(1); // index 1 is the second device.
|
pmw33xx_init(1); // index 1 is the second device.
|
||||||
pointing_device_set_cpi(800); // applies to both sensors
|
pmw33xx_set_cpi(0, 800); // applies to first sensor
|
||||||
|
pmw33xx_set_cpi(1, 800); // applies to second sensor
|
||||||
pointing_device_init_user();
|
pointing_device_init_user();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Contains report from sensor #0 already, need to merge in from sensor #1
|
// Contains report from sensor #0 already, need to merge in from sensor #1
|
||||||
report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) {
|
report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) {
|
||||||
report_pmw3360_t data = pmw3360_read_burst(1);
|
pmw33xx_report_t report = pmw33xx_read_burst(1);
|
||||||
if (data.isOnSurface && data.isMotion) {
|
if (!report.motion.b.is_lifted && report.motion.b.is_motion) {
|
||||||
// From quantum/pointing_device_drivers.c
|
// From quantum/pointing_device_drivers.c
|
||||||
#define constrain_hid(amt) ((amt) < -127 ? -127 : ((amt) > 127 ? 127 : (amt)))
|
#define constrain_hid(amt) ((amt) < -127 ? -127 : ((amt) > 127 ? 127 : (amt)))
|
||||||
mouse_report.x = constrain_hid(mouse_report.x + data.dx);
|
mouse_report.x = constrain_hid(mouse_report.x + report.delta_x);
|
||||||
mouse_report.y = constrain_hid(mouse_report.y + data.dy);
|
mouse_report.y = constrain_hid(mouse_report.y + report.delta_y);
|
||||||
}
|
}
|
||||||
return pointing_device_task_user(mouse_report);
|
return pointing_device_task_user(mouse_report);
|
||||||
}
|
}
|
||||||
|
@ -187,30 +259,6 @@ report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) {
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### PMW 3389 Sensor
|
|
||||||
|
|
||||||
To use the PMW 3389 sensor, add this to your `rules.mk`
|
|
||||||
|
|
||||||
```make
|
|
||||||
POINTING_DEVICE_DRIVER = pmw3389
|
|
||||||
```
|
|
||||||
|
|
||||||
The PMW 3389 is an SPI driven optical sensor, that uses a built in IR LED for surface tracking.
|
|
||||||
|
|
||||||
| Setting | Description | Default |
|
|
||||||
|---------------------------------|--------------------------------------------------------------------------------------------|---------------|
|
|
||||||
|`PMW3389_CS_PIN` | (Required) Sets the Cable Select pin connected to the sensor. | _not defined_ |
|
|
||||||
|`PMW3389_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `2000000` |
|
|
||||||
|`PMW3389_SPI_LSBFIRST` | (Optional) Sets the Least/Most Significant Byte First setting for SPI. | `false` |
|
|
||||||
|`PMW3389_SPI_MODE` | (Optional) Sets the SPI Mode for the sensor. | `3` |
|
|
||||||
|`PMW3389_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ |
|
|
||||||
|`PMW3389_LIFTOFF_DISTANCE` | (Optional) Sets the lift off distance at run time | `0x02` |
|
|
||||||
|`ROTATIONAL_TRANSFORM_ANGLE` | (Optional) Allows for the sensor data to be rotated +/- 30 degrees directly in the sensor. | `0` |
|
|
||||||
|`PMW3389_FIRMWARE_UPLOAD_FAST` | (Optional) Skips the 15us wait between firmware blocks. | _not defined_ |
|
|
||||||
|
|
||||||
The CPI range is 50-16000, in increments of 50. Defaults to 2000 CPI.
|
|
||||||
|
|
||||||
|
|
||||||
### Custom Driver
|
### Custom Driver
|
||||||
|
|
||||||
If you have a sensor type that isn't supported above, a custom option is available by adding the following to your `rules.mk`
|
If you have a sensor type that isn't supported above, a custom option is available by adding the following to your `rules.mk`
|
||||||
|
@ -232,41 +280,50 @@ void pointing_device_driver_set_cpi(uint16_t cpi) {}
|
||||||
|
|
||||||
## Common Configuration
|
## Common Configuration
|
||||||
|
|
||||||
| Setting | Description | Default |
|
| Setting | Description | Default |
|
||||||
|----------------------------------|-----------------------------------------------------------------------|-------------------|
|
| ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ------------- |
|
||||||
|`POINTING_DEVICE_ROTATION_90` | (Optional) Rotates the X and Y data by 90 degrees. | _not defined_ |
|
| `MOUSE_EXTENDED_REPORT` | (Optional) Enables support for extended mouse reports. (-32767 to 32767, instead of just -127 to 127). | _not defined_ |
|
||||||
|`POINTING_DEVICE_ROTATION_180` | (Optional) Rotates the X and Y data by 180 degrees. | _not defined_ |
|
| `POINTING_DEVICE_ROTATION_90` | (Optional) Rotates the X and Y data by 90 degrees. | _not defined_ |
|
||||||
|`POINTING_DEVICE_ROTATION_270` | (Optional) Rotates the X and Y data by 270 degrees. | _not defined_ |
|
| `POINTING_DEVICE_ROTATION_180` | (Optional) Rotates the X and Y data by 180 degrees. | _not defined_ |
|
||||||
|`POINTING_DEVICE_INVERT_X` | (Optional) Inverts the X axis report. | _not defined_ |
|
| `POINTING_DEVICE_ROTATION_270` | (Optional) Rotates the X and Y data by 270 degrees. | _not defined_ |
|
||||||
|`POINTING_DEVICE_INVERT_Y` | (Optional) Inverts the Y axis report. | _not defined_ |
|
| `POINTING_DEVICE_INVERT_X` | (Optional) Inverts the X axis report. | _not defined_ |
|
||||||
|`POINTING_DEVICE_MOTION_PIN` | (Optional) If supported, will only read from sensor if pin is active. | _not defined_ |
|
| `POINTING_DEVICE_INVERT_Y` | (Optional) Inverts the Y axis report. | _not defined_ |
|
||||||
|`POINTING_DEVICE_TASK_THROTTLE_MS` | (Optional) Limits the frequency that the sensor is polled for motion. | _not defined_ |
|
| `POINTING_DEVICE_MOTION_PIN` | (Optional) If supported, will only read from sensor if pin is active. | _not defined_ |
|
||||||
|
| `POINTING_DEVICE_TASK_THROTTLE_MS` | (Optional) Limits the frequency that the sensor is polled for motion. | _not defined_ |
|
||||||
|
| `POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE` | (Optional) Enable inertial cursor. Cursor continues moving after a flick gesture and slows down by kinetic friction. | _not defined_ |
|
||||||
|
| `POINTING_DEVICE_GESTURES_SCROLL_ENABLE` | (Optional) Enable scroll gesture. The gesture that activates the scroll is device dependent. | _not defined_ |
|
||||||
|
| `POINTING_DEVICE_CS_PIN` | (Optional) Provides a default CS pin, useful for supporting multiple sensor configs. | _not defined_ |
|
||||||
|
| `POINTING_DEVICE_SDIO_PIN` | (Optional) Provides a default SDIO pin, useful for supporting multiple sensor configs. | _not defined_ |
|
||||||
|
| `POINTING_DEVICE_SCLK_PIN` | (Optional) Provides a default SCLK pin, useful for supporting multiple sensor configs. | _not defined_ |
|
||||||
|
|
||||||
!> When using `SPLIT_POINTING_ENABLE` the `POINTING_DEVICE_MOTION_PIN` functionality is not supported and `POINTING_DEVICE_TASK_THROTTLE_MS` will default to `1`. Increasing this value will increase transport performance at the cost of possible mouse responsiveness.
|
!> When using `SPLIT_POINTING_ENABLE` the `POINTING_DEVICE_MOTION_PIN` functionality is not supported and `POINTING_DEVICE_TASK_THROTTLE_MS` will default to `1`. Increasing this value will increase transport performance at the cost of possible mouse responsiveness.
|
||||||
|
|
||||||
|
The `POINTING_DEVICE_CS_PIN`, `POINTING_DEVICE_SDIO_PIN`, and `POINTING_DEVICE_SCLK_PIN` provide a convenient way to define a single pin that can be used for an interchangeable sensor config. This allows you to have a single config, without defining each device. Each sensor allows for this to be overridden with their own defines.
|
||||||
|
|
||||||
|
!> Any pointing device with a lift/contact status can integrate inertial cursor feature into its driver, controlled by `POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE`. e.g. PMW3360 can use Lift_Stat from Motion register. Note that `POINTING_DEVICE_MOTION_PIN` cannot be used with this feature; continuous polling of `get_report()` is needed to generate glide reports.
|
||||||
|
|
||||||
## Split Keyboard Configuration
|
## Split Keyboard Configuration
|
||||||
|
|
||||||
The following configuration options are only available when using `SPLIT_POINTING_ENABLE` see [data sync options](feature_split_keyboard.md?id=data-sync-options). The rotation and invert `*_RIGHT` options are only used with `POINTING_DEVICE_COMBINED`. If using `POINTING_DEVICE_LEFT` or `POINTING_DEVICE_RIGHT` use the common configuration above to configure your pointing device.
|
The following configuration options are only available when using `SPLIT_POINTING_ENABLE` see [data sync options](feature_split_keyboard.md?id=data-sync-options). The rotation and invert `*_RIGHT` options are only used with `POINTING_DEVICE_COMBINED`. If using `POINTING_DEVICE_LEFT` or `POINTING_DEVICE_RIGHT` use the common configuration above to configure your pointing device.
|
||||||
|
|
||||||
| Setting | Description | Default |
|
| Setting | Description | Default |
|
||||||
|----------------------------------------|-----------------------------------------------------------------------|---------------|
|
| ------------------------------------ | ----------------------------------------------------------------------------------------------------- | ------------- |
|
||||||
|`POINTING_DEVICE_LEFT` | Pointing device on the left side (Required - pick one only) | _not defined_ |
|
| `POINTING_DEVICE_LEFT` | Pointing device on the left side (Required - pick one only) | _not defined_ |
|
||||||
|`POINTING_DEVICE_RIGHT` | Pointing device on the right side (Required - pick one only) | _not defined_ |
|
| `POINTING_DEVICE_RIGHT` | Pointing device on the right side (Required - pick one only) | _not defined_ |
|
||||||
|`POINTING_DEVICE_COMBINED` | Pointing device on both sides (Required - pick one only) | _not defined_ |
|
| `POINTING_DEVICE_COMBINED` | Pointing device on both sides (Required - pick one only) | _not defined_ |
|
||||||
|`POINTING_DEVICE_ROTATION_90_RIGHT` | (Optional) Rotates the X and Y data by 90 degrees. | _not defined_ |
|
| `POINTING_DEVICE_ROTATION_90_RIGHT` | (Optional) Rotates the X and Y data by 90 degrees. | _not defined_ |
|
||||||
|`POINTING_DEVICE_ROTATION_180_RIGHT` | (Optional) Rotates the X and Y data by 180 degrees. | _not defined_ |
|
| `POINTING_DEVICE_ROTATION_180_RIGHT` | (Optional) Rotates the X and Y data by 180 degrees. | _not defined_ |
|
||||||
|`POINTING_DEVICE_ROTATION_270_RIGHT` | (Optional) Rotates the X and Y data by 270 degrees. | _not defined_ |
|
| `POINTING_DEVICE_ROTATION_270_RIGHT` | (Optional) Rotates the X and Y data by 270 degrees. | _not defined_ |
|
||||||
|`POINTING_DEVICE_INVERT_X_RIGHT` | (Optional) Inverts the X axis report. | _not defined_ |
|
| `POINTING_DEVICE_INVERT_X_RIGHT` | (Optional) Inverts the X axis report. | _not defined_ |
|
||||||
|`POINTING_DEVICE_INVERT_Y_RIGHT` | (Optional) Inverts the Y 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.
|
!> 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
|
## Callbacks and Functions
|
||||||
|
|
||||||
| Function | Description |
|
| Function | Description |
|
||||||
|-----------------------------------|----------------------------------------------------------------------------------------------------------------------------------------|
|
| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
|
||||||
| `pointing_device_init_kb(void)` | Callback to allow for keyboard level initialization. Useful for additional hardware sensors. |
|
| `pointing_device_init_kb(void)` | Callback to allow for keyboard level initialization. Useful for additional hardware sensors. |
|
||||||
| `pointing_device_init_user(void)` | Callback to allow for user level initialization. Useful for additional hardware sensors. |
|
| `pointing_device_init_user(void)` | Callback to allow for user level initialization. Useful for additional hardware sensors. |
|
||||||
| `pointing_device_task_kb(mouse_report)` | Callback that sends sensor data, so keyboard code can intercept and modify the data. Returns a mouse report. |
|
| `pointing_device_task_kb(mouse_report)` | Callback that sends sensor data, so keyboard code can intercept and modify the data. Returns a mouse report. |
|
||||||
|
@ -278,7 +335,7 @@ The following configuration options are only available when using `SPLIT_POINTIN
|
||||||
| `pointing_device_set_report(mouse_report)` | Sets the mouse report to the assigned `mouse_report_t` data structured passed to the function. |
|
| `pointing_device_set_report(mouse_report)` | Sets the mouse report to the assigned `mouse_report_t` data structured passed to the function. |
|
||||||
| `pointing_device_send(void)` | Sends the current mouse report to the host system. Function can be replaced. |
|
| `pointing_device_send(void)` | Sends the current mouse report to the host system. Function can be replaced. |
|
||||||
| `has_mouse_report_changed(new_report, old_report)` | Compares the old and new `mouse_report_t` data and returns true only if it has changed. |
|
| `has_mouse_report_changed(new_report, old_report)` | Compares the old and new `mouse_report_t` data and returns true only if it has changed. |
|
||||||
| `pointing_device_adjust_by_defines(mouse_report)` | Applies rotations and invert configurations to a raw mouse report. |
|
| `pointing_device_adjust_by_defines(mouse_report)` | Applies rotations and invert configurations to a raw mouse report. |
|
||||||
|
|
||||||
|
|
||||||
## Split Keyboard Callbacks and Functions
|
## Split Keyboard Callbacks and Functions
|
||||||
|
@ -286,7 +343,7 @@ The following configuration options are only available when using `SPLIT_POINTIN
|
||||||
The combined functions below are only available when using `SPLIT_POINTING_ENABLE` and `POINTING_DEVICE_COMBINED`. The 2 callbacks `pointing_device_task_combined_*` replace the single sided equivalents above. See the [combined pointing devices example](feature_pointing_device.md?id=combined-pointing-devices)
|
The combined functions below are only available when using `SPLIT_POINTING_ENABLE` and `POINTING_DEVICE_COMBINED`. The 2 callbacks `pointing_device_task_combined_*` replace the single sided equivalents above. See the [combined pointing devices example](feature_pointing_device.md?id=combined-pointing-devices)
|
||||||
|
|
||||||
| Function | Description |
|
| Function | Description |
|
||||||
|-----------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------|
|
| --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
||||||
| `pointing_device_set_shared_report(mouse_report)` | Sets the shared mouse report to the assigned `mouse_report_t` data structured passed to the function. |
|
| `pointing_device_set_shared_report(mouse_report)` | Sets the shared mouse report to the assigned `mouse_report_t` data structured passed to the function. |
|
||||||
| `pointing_device_set_cpi_on_side(bool, uint16_t)` | Sets the CPI/DPI of one side, if supported. Passing `true` will set the left and `false` the right` |
|
| `pointing_device_set_cpi_on_side(bool, uint16_t)` | Sets the CPI/DPI of one side, if supported. Passing `true` will set the left and `false` the right` |
|
||||||
| `pointing_device_combine_reports(left_report, right_report)` | Returns a combined mouse_report of left_report and right_report (as a `mouse_report_t` data structure) |
|
| `pointing_device_combine_reports(left_report, right_report)` | Returns a combined mouse_report of left_report and right_report (as a `mouse_report_t` data structure) |
|
||||||
|
@ -430,4 +487,3 @@ report_mouse_t pointing_device_task_combined_user(report_mouse_t left_report, re
|
||||||
return pointing_device_combine_reports(left_report, right_report);
|
return pointing_device_combine_reports(left_report, right_report);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
=======
|
|
||||||
|
|
|
@ -86,6 +86,7 @@ You can use between 1 and 4 IS31FL3733 IC's. Do not specify `DRIVER_ADDR_<N>` de
|
||||||
| `ISSI_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 |
|
| `ISSI_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 |
|
||||||
| `ISSI_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 |
|
| `ISSI_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 |
|
||||||
| `ISSI_PWM_FREQUENCY` | (Optional) PWM Frequency Setting - IS31FL3733B only | 0 |
|
| `ISSI_PWM_FREQUENCY` | (Optional) PWM Frequency Setting - IS31FL3733B only | 0 |
|
||||||
|
| `ISSI_GLOBALCURRENT` | (Optional) Configuration for the Global Current Register | 0xFF |
|
||||||
| `ISSI_SWPULLUP` | (Optional) Set the value of the SWx lines on-chip de-ghosting resistors | PUR_0R (Disabled) |
|
| `ISSI_SWPULLUP` | (Optional) Set the value of the SWx lines on-chip de-ghosting resistors | PUR_0R (Disabled) |
|
||||||
| `ISSI_CSPULLUP` | (Optional) Set the value of the CSx lines on-chip de-ghosting resistors | PUR_0R (Disabled) |
|
| `ISSI_CSPULLUP` | (Optional) Set the value of the CSx lines on-chip de-ghosting resistors | PUR_0R (Disabled) |
|
||||||
| `DRIVER_COUNT` | (Required) How many RGB driver IC's are present | |
|
| `DRIVER_COUNT` | (Required) How many RGB driver IC's are present | |
|
||||||
|
@ -172,6 +173,7 @@ Configure the hardware via your `config.h`:
|
||||||
| `ISSI_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 |
|
| `ISSI_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 |
|
||||||
| `ISSI_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 |
|
| `ISSI_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 |
|
||||||
| `ISSI_PWM_FREQUENCY` | (Optional) PWM Frequency Setting - IS31FL3737B only | 0 |
|
| `ISSI_PWM_FREQUENCY` | (Optional) PWM Frequency Setting - IS31FL3737B only | 0 |
|
||||||
|
| `ISSI_GLOBALCURRENT` | (Optional) Configuration for the Global Current Register | 0xFF |
|
||||||
| `ISSI_SWPULLUP` | (Optional) Set the value of the SWx lines on-chip de-ghosting resistors | PUR_0R (Disabled) |
|
| `ISSI_SWPULLUP` | (Optional) Set the value of the SWx lines on-chip de-ghosting resistors | PUR_0R (Disabled) |
|
||||||
| `ISSI_CSPULLUP` | (Optional) Set the value of the CSx lines on-chip de-ghosting resistors | PUR_0R (Disabled) |
|
| `ISSI_CSPULLUP` | (Optional) Set the value of the CSx lines on-chip de-ghosting resistors | PUR_0R (Disabled) |
|
||||||
| `DRIVER_COUNT` | (Required) How many RGB driver IC's are present | |
|
| `DRIVER_COUNT` | (Required) How many RGB driver IC's are present | |
|
||||||
|
@ -409,6 +411,7 @@ You can use up to 2 AW20216 IC's. Do not specify `DRIVER_<N>_xxx` defines for IC
|
||||||
| `DRIVER_LED_TOTAL` | (Required) How many RGB lights are present across all drivers | |
|
| `DRIVER_LED_TOTAL` | (Required) How many RGB lights are present across all drivers | |
|
||||||
| `AW_SCALING_MAX` | (Optional) LED current scaling value (0-255, higher values mean LED is brighter at full PWM) | 150 |
|
| `AW_SCALING_MAX` | (Optional) LED current scaling value (0-255, higher values mean LED is brighter at full PWM) | 150 |
|
||||||
| `AW_GLOBAL_CURRENT_MAX` | (Optional) Driver global current limit (0-255, higher values means the driver may consume more power) | 150 |
|
| `AW_GLOBAL_CURRENT_MAX` | (Optional) Driver global current limit (0-255, higher values means the driver may consume more power) | 150 |
|
||||||
|
| `AW_SPI_MODE` | (Optional) Mode for SPI communication (0-3, defines polarity and phase of the clock) | 3 |
|
||||||
| `AW_SPI_DIVISOR` | (Optional) Clock divisor for SPI communication (powers of 2, smaller numbers means faster communication, should not be less than 4) | 4 |
|
| `AW_SPI_DIVISOR` | (Optional) Clock divisor for SPI communication (powers of 2, smaller numbers means faster communication, should not be less than 4) | 4 |
|
||||||
|
|
||||||
Here is an example using 2 drivers.
|
Here is an example using 2 drivers.
|
||||||
|
@ -665,11 +668,36 @@ In order to change the delay of temperature decrease define `RGB_MATRIX_TYPING_H
|
||||||
#define RGB_MATRIX_TYPING_HEATMAP_DECREASE_DELAY_MS 50
|
#define RGB_MATRIX_TYPING_HEATMAP_DECREASE_DELAY_MS 50
|
||||||
```
|
```
|
||||||
|
|
||||||
Heatmap effect may not light up the correct adjacent LEDs for certain key matrix layout such as split keyboards. The following define will limit the effect to pressed keys only:
|
As heatmap uses the physical position of the leds set in the g_led_config, you may need to tweak the following options to get the best effect for your keyboard. Note the size of this grid is `224x64`.
|
||||||
|
|
||||||
|
Limit the distance the effect spreads to surrounding keys.
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define RGB_MATRIX_TYPING_HEATMAP_SPREAD 40
|
||||||
|
```
|
||||||
|
|
||||||
|
Limit how hot surrounding keys get from each press.
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define RGB_MATRIX_TYPING_HEATMAP_AREA_LIMIT 16
|
||||||
|
```
|
||||||
|
|
||||||
|
Remove the spread effect entirely.
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#define RGB_MATRIX_TYPING_HEATMAP_SLIM
|
#define RGB_MATRIX_TYPING_HEATMAP_SLIM
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### RGB Matrix Effect Solid Reactive :id=rgb-matrix-effect-solid-reactive
|
||||||
|
|
||||||
|
Solid reactive effects will pulse RGB light on key presses with user configurable hues. To enable gradient mode that will automatically change reactive color, add the following define:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define RGB_MATRIX_SOLID_REACTIVE_GRADIENT_MODE
|
||||||
|
```
|
||||||
|
|
||||||
|
Gradient mode will loop through the color wheel hues over time and its duration can be controlled with the effect speed keycodes (`RGB_SPI`/`RGB_SPD`).
|
||||||
|
|
||||||
## Custom RGB Matrix Effects :id=custom-rgb-matrix-effects
|
## Custom RGB Matrix Effects :id=custom-rgb-matrix-effects
|
||||||
|
|
||||||
By setting `RGB_MATRIX_CUSTOM_USER = yes` in `rules.mk`, new effects can be defined directly from your keymap or userspace, without having to edit any QMK core files. To declare new effects, create a `rgb_matrix_user.inc` file in the user keymap directory or userspace folder.
|
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.
|
||||||
|
|
|
@ -105,7 +105,7 @@ Your RGB lighting can be configured by placing these `#define`s in your `config.
|
||||||
## Effects and Animations
|
## Effects and Animations
|
||||||
|
|
||||||
Not only can this lighting be whatever color you want,
|
Not only can this lighting be whatever color you want,
|
||||||
if `RGBLIGHT_EFFECT_xxxx` or `RGBLIGHT_ANIMATIONS` is defined, you also have a number of animation modes at your disposal:
|
if `RGBLIGHT_EFFECT_xxxx` is defined, you also have a number of animation modes at your disposal:
|
||||||
|
|
||||||
|Mode number symbol |Additional number |Description |
|
|Mode number symbol |Additional number |Description |
|
||||||
|-----------------------------|-------------------|---------------------------------------|
|
|-----------------------------|-------------------|---------------------------------------|
|
||||||
|
@ -125,13 +125,14 @@ Check out [this video](https://youtube.com/watch?v=VKrpPAHlisY) for a demonstrat
|
||||||
|
|
||||||
Note: For versions older than 0.6.117, The mode numbers were written directly. In `quantum/rgblight/rgblight.h` there is a contrast table between the old mode number and the current symbol.
|
Note: For versions older than 0.6.117, The mode numbers were written directly. In `quantum/rgblight/rgblight.h` there is a contrast table between the old mode number and the current symbol.
|
||||||
|
|
||||||
|
|
||||||
### Effect and Animation Toggles
|
### Effect and Animation Toggles
|
||||||
|
|
||||||
Use these defines to add or remove animations from the firmware. When you are running low on flash space, it can be helpful to disable animations you are not using.
|
Use these defines to add or remove animations from the firmware. When you are running low on flash space, it can be helpful to disable animations you are not using.
|
||||||
|
|
||||||
|Define |Default |Description |
|
|Define |Default |Description |
|
||||||
|------------------------------------|-------------|-------------------------------------------------------------------------|
|
|------------------------------------|-------------|-------------------------------------------------------------------------|
|
||||||
|`RGBLIGHT_ANIMATIONS` |*Not defined*|Enable all additional animation modes. |
|
|`RGBLIGHT_ANIMATIONS` |*Not defined*|Enable all additional animation modes. (deprecated) |
|
||||||
|`RGBLIGHT_EFFECT_ALTERNATING` |*Not defined*|Enable alternating animation mode. |
|
|`RGBLIGHT_EFFECT_ALTERNATING` |*Not defined*|Enable alternating animation mode. |
|
||||||
|`RGBLIGHT_EFFECT_BREATHING` |*Not defined*|Enable breathing animation mode. |
|
|`RGBLIGHT_EFFECT_BREATHING` |*Not defined*|Enable breathing animation mode. |
|
||||||
|`RGBLIGHT_EFFECT_CHRISTMAS` |*Not defined*|Enable christmas animation mode. |
|
|`RGBLIGHT_EFFECT_CHRISTMAS` |*Not defined*|Enable christmas animation mode. |
|
||||||
|
@ -143,6 +144,8 @@ 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_STATIC_GRADIENT` |*Not defined*|Enable static gradient mode. |
|
||||||
|`RGBLIGHT_EFFECT_TWINKLE` |*Not defined*|Enable twinkle animation mode. |
|
|`RGBLIGHT_EFFECT_TWINKLE` |*Not defined*|Enable twinkle animation mode. |
|
||||||
|
|
||||||
|
!> `RGBLIGHT_ANIMATIONS` is being deprecated and animation modes should be explicitly defined.
|
||||||
|
|
||||||
### Effect and Animation Settings
|
### Effect and Animation Settings
|
||||||
|
|
||||||
The following options are used to tweak the various animations:
|
The following options are used to tweak the various animations:
|
||||||
|
@ -162,14 +165,12 @@ The following options are used to tweak the various animations:
|
||||||
|`RGBLIGHT_EFFECT_TWINKLE_PROBABILITY`|`1/127` |Adjusts how likely each LED is to twinkle (on each animation step) |
|
|`RGBLIGHT_EFFECT_TWINKLE_PROBABILITY`|`1/127` |Adjusts how likely each LED is to twinkle (on each animation step) |
|
||||||
|
|
||||||
### Example Usage to Reduce Memory Footprint
|
### Example Usage to Reduce Memory Footprint
|
||||||
1. Remove `RGBLIGHT_ANIMATIONS` from `config.h`.
|
1. Selectively disable the animations you want to enable. The following would enable two animations and save about 4KiB:
|
||||||
1. Selectively add the animations you want to enable. The following would enable two animations and save about 4KiB:
|
|
||||||
|
|
||||||
```diff
|
```diff
|
||||||
#undef RGBLED_NUM
|
#undef RGBLED_NUM
|
||||||
-#define RGBLIGHT_ANIMATIONS
|
+#undef RGBLIGHT_EFFECT_STATIC_GRADIENT
|
||||||
+#define RGBLIGHT_EFFECT_STATIC_GRADIENT
|
+#undef RGBLIGHT_EFFECT_RAINBOW_SWIRL
|
||||||
+#define RGBLIGHT_EFFECT_RAINBOW_SWIRL
|
|
||||||
#define RGBLED_NUM 12
|
#define RGBLED_NUM 12
|
||||||
#define RGBLIGHT_HUE_STEP 8
|
#define RGBLIGHT_HUE_STEP 8
|
||||||
#define RGBLIGHT_SAT_STEP 8
|
#define RGBLIGHT_SAT_STEP 8
|
||||||
|
|
|
@ -0,0 +1,224 @@
|
||||||
|
# Send String
|
||||||
|
|
||||||
|
The Send String API is part of QMK's macro system. It allows for sequences of keystrokes to be sent automatically.
|
||||||
|
|
||||||
|
The full ASCII character set is supported, along with all of the keycodes in the Basic Keycode range (as these are the only ones that will actually be sent to the host).
|
||||||
|
|
||||||
|
?> Unicode characters are **not** supported with this API -- see the [Unicode](feature_unicode.md) feature instead.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Send String is enabled by default, so there is usually no need for any special setup. However, if it is disabled, add the following to your `rules.mk`:
|
||||||
|
|
||||||
|
```make
|
||||||
|
SEND_STRING_ENABLE = yes
|
||||||
|
```
|
||||||
|
|
||||||
|
## Basic Configuration
|
||||||
|
|
||||||
|
Add the following to your `config.h`:
|
||||||
|
|
||||||
|
|Define |Default |Description |
|
||||||
|
|-----------------|----------------|------------------------------------------------------------------------------------------------------------|
|
||||||
|
|`SENDSTRING_BELL`|*Not defined* |If the [Audio](feature_audio.md) feature is enabled, the `\a` character (ASCII `BEL`) will beep the speaker.|
|
||||||
|
|`BELL_SOUND` |`TERMINAL_SOUND`|The song to play when the `\a` character is encountered. By default, this is an eighth note of C5. |
|
||||||
|
|
||||||
|
## Keycodes
|
||||||
|
|
||||||
|
The Send String functions accept C string literals, but specific keycodes can be injected with the below macros. All of the keycodes in the [Basic Keycode range](keycodes_basic.md) are supported (as these are the only ones that will actually be sent to the host), but with an `X_` prefix instead of `KC_`.
|
||||||
|
|
||||||
|
|Macro |Description |
|
||||||
|
|--------------|-------------------------------------------------------------------|
|
||||||
|
|`SS_TAP(x)` |Send a keydown, then keyup, event for the given Send String keycode|
|
||||||
|
|`SS_DOWN(x)` |Send a keydown event for the given Send String keycode |
|
||||||
|
|`SS_UP(x)` |Send a keyup event for the given Send String keycode |
|
||||||
|
|`SS_DELAY(ms)`|Wait for `ms` milliseconds |
|
||||||
|
|
||||||
|
The following characters are also mapped to their respective keycodes for convenience:
|
||||||
|
|
||||||
|
|Character|Hex |ASCII|Keycode |
|
||||||
|
|---------|------|-----|--------------|
|
||||||
|
|`\b` |`\x08`|`BS` |`KC_BACKSPACE`|
|
||||||
|
|`\e` |`\x09`|`ESC`|`KC_ESCAPE` |
|
||||||
|
|`\n` |`\x0A`|`LF` |`KC_ENTER` |
|
||||||
|
|`\t` |`\x1B`|`TAB`|`KC_TAB` |
|
||||||
|
| |`\x7F`|`DEL`|`KC_DELETE` |
|
||||||
|
|
||||||
|
### Language Support
|
||||||
|
|
||||||
|
By default, Send String assumes your OS keyboard layout is set to US ANSI. If you are using a different keyboard layout, you can [override the lookup tables used to convert ASCII characters to keystrokes](reference_keymap_extras.md#sendstring-support).
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Hello World
|
||||||
|
|
||||||
|
A simple custom keycode which types out "Hello, world!" and the Enter key when pressed.
|
||||||
|
|
||||||
|
Add the following to your `keymap.c`:
|
||||||
|
|
||||||
|
```c
|
||||||
|
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
switch (keycode) {
|
||||||
|
case SS_HELLO:
|
||||||
|
if (record->event.pressed) {
|
||||||
|
SEND_STRING("Hello, world!\n");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Keycode Injection
|
||||||
|
|
||||||
|
This example types out opening and closing curly braces, then taps the left arrow key to move the cursor between the two.
|
||||||
|
|
||||||
|
```c
|
||||||
|
SEND_STRING("{}" SS_TAP(X_LEFT));
|
||||||
|
```
|
||||||
|
|
||||||
|
This example types Ctrl+A, then Ctrl+C, without releasing Ctrl.
|
||||||
|
|
||||||
|
```c
|
||||||
|
SEND_STRING(SS_LCTL("ac"));
|
||||||
|
```
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
### `void send_string(const char *string)`
|
||||||
|
|
||||||
|
Type out a string of ASCII characters.
|
||||||
|
|
||||||
|
This function simply calls `send_string_with_delay(string, 0)`.
|
||||||
|
|
||||||
|
#### Arguments
|
||||||
|
|
||||||
|
- `const char *string`
|
||||||
|
The string to type out.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `void send_string_with_delay(const char *string, uint8_t interval)`
|
||||||
|
|
||||||
|
Type out a string of ASCII characters, with a delay between each character.
|
||||||
|
|
||||||
|
#### Arguments
|
||||||
|
|
||||||
|
- `const char *string`
|
||||||
|
The string to type out.
|
||||||
|
- `uint8_t interval`
|
||||||
|
The amount of time, in milliseconds, to wait before typing the next character.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `void send_string_P(const char *string)`
|
||||||
|
|
||||||
|
Type out a PROGMEM string of ASCII characters.
|
||||||
|
|
||||||
|
On ARM devices, this function is simply an alias for `send_string_with_delay(string, 0)`.
|
||||||
|
|
||||||
|
#### Arguments
|
||||||
|
|
||||||
|
- `const char *string`
|
||||||
|
The string to type out.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `void send_string_with_delay_P(const char *string, uint8_t interval)`
|
||||||
|
|
||||||
|
Type out a PROGMEM string of ASCII characters, with a delay between each character.
|
||||||
|
|
||||||
|
On ARM devices, this function is simply an alias for `send_string_with_delay(string, interval)`.
|
||||||
|
|
||||||
|
#### Arguments
|
||||||
|
|
||||||
|
- `const char *string`
|
||||||
|
The string to type out.
|
||||||
|
- `uint8_t interval`
|
||||||
|
The amount of time, in milliseconds, to wait before typing the next character.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `void send_char(char ascii_code)`
|
||||||
|
|
||||||
|
Type out an ASCII character.
|
||||||
|
|
||||||
|
#### Arguments
|
||||||
|
|
||||||
|
- `char ascii_code`
|
||||||
|
The character to type.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `void send_dword(uint32_t number)`
|
||||||
|
|
||||||
|
Type out an eight digit (unsigned 32-bit) hexadecimal value.
|
||||||
|
|
||||||
|
The format is `[0-9a-f]{8}`, eg. `00000000` through `ffffffff`.
|
||||||
|
|
||||||
|
#### Arguments
|
||||||
|
|
||||||
|
- `uint32_t number`
|
||||||
|
The value to type, from 0 to 4,294,967,295.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `void send_word(uint16_t number)`
|
||||||
|
|
||||||
|
Type out a four digit (unsigned 16-bit) hexadecimal value.
|
||||||
|
|
||||||
|
The format is `[0-9a-f]{4}`, eg. `0000` through `ffff`.
|
||||||
|
|
||||||
|
#### Arguments
|
||||||
|
|
||||||
|
- `uint16_t number`
|
||||||
|
The value to type, from 0 to 65,535.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `void send_byte(uint8_t number)`
|
||||||
|
|
||||||
|
Type out a two digit (8-bit) hexadecimal value.
|
||||||
|
|
||||||
|
The format is `[0-9a-f]{2}`, eg. `00` through `ff`.
|
||||||
|
|
||||||
|
#### Arguments
|
||||||
|
|
||||||
|
- `uint8_t number`
|
||||||
|
The value to type, from 0 to 255.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `void send_nibble(uint8_t number)`
|
||||||
|
|
||||||
|
Type out a single hexadecimal digit.
|
||||||
|
|
||||||
|
The format is `[0-9a-f]{1}`, eg. `0` through `f`.
|
||||||
|
|
||||||
|
#### Arguments
|
||||||
|
|
||||||
|
- `uint8_t number`
|
||||||
|
The value to type, from 0 to 15.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `void tap_random_base64(void)`
|
||||||
|
|
||||||
|
Type a pseudorandom character from the set `A-Z`, `a-z`, `0-9`, `+` and `/`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `SEND_STRING(string)`
|
||||||
|
|
||||||
|
Shortcut macro for `send_string_with_delay_P(PSTR(string), 0)`.
|
||||||
|
|
||||||
|
On ARM devices, this define evaluates to `send_string_with_delay(string, 0)`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `SEND_STRING_DELAY(string, interval)`
|
||||||
|
|
||||||
|
Shortcut macro for `send_string_with_delay_P(PSTR(string), interval)`.
|
||||||
|
|
||||||
|
On ARM devices, this define evaluates to `send_string_with_delay(string, interval)`.
|
|
@ -143,6 +143,9 @@ Next, you will have to flash the EEPROM files once for the correct hand to the c
|
||||||
* ARM controllers with a DFU compatible bootloader (e.g. Proton-C):
|
* ARM controllers with a DFU compatible bootloader (e.g. Proton-C):
|
||||||
* `:dfu-util-split-left`
|
* `:dfu-util-split-left`
|
||||||
* `:dfu-util-split-right`
|
* `:dfu-util-split-right`
|
||||||
|
* ARM controllers with a UF2 compatible bootloader:
|
||||||
|
* `:uf2-split-left`
|
||||||
|
* `:uf2-split-right`
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
@ -367,7 +370,7 @@ There are some settings that you may need to configure, based on how the hardwar
|
||||||
#define MATRIX_COL_PINS_RIGHT { <col pins> }
|
#define MATRIX_COL_PINS_RIGHT { <col pins> }
|
||||||
```
|
```
|
||||||
|
|
||||||
This allows you to specify a different set of pins for the matrix on the right side. This is useful if you have a board with differently-shaped halves that requires a different configuration (such as Keebio's Quefrency).
|
This allows you to specify a different set of pins for the matrix on the right side. This is useful if you have a board with differently-shaped halves that requires a different configuration (such as Keebio's Quefrency). The number of pins in the right and left matrices must be the same, if you have a board with a different number of rows or columns on one side, pad out the extra spaces with `NO_PIN` and make sure you add the unused rows or columns to your matrix.
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#define DIRECT_PINS_RIGHT { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } }
|
#define DIRECT_PINS_RIGHT { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } }
|
||||||
|
|
|
@ -8,46 +8,107 @@ The [Open Steno Project](https://www.openstenoproject.org/) has built an open-so
|
||||||
|
|
||||||
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.
|
Plover can work with any standard QWERTY keyboard, although it is more efficient if the keyboard supports NKRO (n-key rollover) to allow Plover to see all the pressed keys at once. An example keymap for Plover can be found in `planck/keymaps/default`. Switching to the `PLOVER` layer adjusts the position of the keyboard to support the number bar.
|
||||||
|
|
||||||
To use Plover with QMK just enable NKRO and optionally adjust your layout 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.
|
To enable NKRO, add `NKRO_ENABLE = yes` in your `rules.mk` and make sure to press `NK_ON` to turn it on because `NKRO_ENABLE = yes` merely adds the possibility of switching to NKRO mode but it doesn't automatically switch to it. If you want to automatically switch, add `#define FORCE_NKRO` in your `config.h`.
|
||||||
|
|
||||||
|
You may also need to adjust your layout, either in QMK or in Plover, if you have anything other than a standard layout. You may also want to purchase some steno-friendly keycaps to make it easier to hit multiple keys.
|
||||||
|
|
||||||
## Plover with Steno Protocol :id=plover-with-steno-protocol
|
## Plover with Steno Protocol :id=plover-with-steno-protocol
|
||||||
|
|
||||||
Plover also understands the language of several steno machines. QMK can speak a couple of these languages, TX Bolt and GeminiPR. An example layout can be found in `planck/keymaps/steno`.
|
Plover also understands the language of several steno machines. QMK can speak a couple of these languages: TX Bolt and GeminiPR. An example layout can be found in `planck/keymaps/steno`.
|
||||||
|
|
||||||
When QMK speaks to Plover over a steno protocol Plover will not use the keyboard as input. This means that you can switch back and forth between a standard keyboard and your steno keyboard, or even switch layers from Plover to standard and back without needing to activate/deactivate Plover.
|
When QMK speaks to Plover over a steno protocol, Plover will not use the keyboard as input. This means that you can switch back and forth between a standard keyboard and your steno keyboard, or even switch layers from Plover to standard and back without needing to activate/deactivate Plover.
|
||||||
|
|
||||||
In this mode Plover expects to speak with a steno machine over a serial port so QMK will present itself to the operating system as a virtual serial port in addition to a keyboard. By default QMK will speak the TX Bolt protocol but can be switched to GeminiPR; the last protocol used is stored in non-volatile memory so QMK will use the same protocol on restart.
|
In this mode, Plover expects to speak with a steno machine over a serial port so QMK will present itself to the operating system as a virtual serial port in addition to a keyboard.
|
||||||
|
|
||||||
> Note: Due to hardware limitations you may not be able to run both a virtual serial port and mouse emulation at the same time.
|
> Note: Due to hardware limitations, you might not be able to run both a virtual serial port and mouse emulation at the same time.
|
||||||
|
|
||||||
|
!> Serial stenography protocols are not supported on [V-USB keyboards](compatible_microcontrollers#atmel-avr).
|
||||||
|
|
||||||
|
To enable stenography protocols, add the following lines to your `rules.mk`:
|
||||||
|
```mk
|
||||||
|
STENO_ENABLE = yes
|
||||||
|
```
|
||||||
|
|
||||||
### TX Bolt :id=tx-bolt
|
### TX Bolt :id=tx-bolt
|
||||||
|
|
||||||
TX Bolt communicates the status of 24 keys over a very simple protocol in variable-sized (1-5 byte) packets.
|
TX Bolt communicates the status of 24 keys over a simple protocol in variable-sized (1–4 bytes) packets.
|
||||||
|
|
||||||
|
To select TX Bolt, add the following lines to your `rules.mk`:
|
||||||
|
```mk
|
||||||
|
STENO_ENABLE = yes
|
||||||
|
STENO_PROTOCOL = txbolt
|
||||||
|
```
|
||||||
|
|
||||||
|
Each byte of the packet represents a different group of steno keys. Determining the group of a certain byte of the packet is done by checking the first two bits, the remaining bits are set if the corresponding steno key was pressed for the stroke. The last set of keys (as indicated by leading `11`) needs to keep track of less keys than there are bits so one of the bits is constantly 0.
|
||||||
|
|
||||||
|
The start of a new packet can be detected by comparing the group “ID” (the two MSBs) of the current byte to that of the previously received byte. If the group “ID” of the current byte is smaller or equal to that of the previous byte, it means that the current byte is the beginning of a new packet.
|
||||||
|
|
||||||
|
The format of TX Bolt packets is shown below.
|
||||||
|
```
|
||||||
|
00HWPKTS 01UE*OAR 10GLBPRF 110#ZDST
|
||||||
|
```
|
||||||
|
|
||||||
|
Examples of steno strokes and the associated packet:
|
||||||
|
- `EUBG` = `01110000 10101000`
|
||||||
|
- `WAZ` = `00010000 01000010 11001000`
|
||||||
|
- `PHAPBGS` = `00101000 01000010 10101100 11000010`
|
||||||
|
|
||||||
### GeminiPR :id=geminipr
|
### GeminiPR :id=geminipr
|
||||||
|
|
||||||
GeminiPR encodes 42 keys into a 6-byte packet. While TX Bolt contains everything that is necessary for standard stenography, GeminiPR opens up many more options, including supporting non-English theories.
|
GeminiPR encodes 42 keys into a 6-byte packet. While TX Bolt contains everything that is necessary for standard stenography, GeminiPR opens up many more options, including differentiating between top and bottom `S-`, and supporting non-English theories.
|
||||||
|
|
||||||
|
To select GeminiPR, add the following lines to your `rules.mk`:
|
||||||
|
```mk
|
||||||
|
STENO_ENABLE = yes
|
||||||
|
STENO_PROTOCOL = geminipr
|
||||||
|
```
|
||||||
|
|
||||||
|
All packets in the GeminiPR protocol consist of exactly six bytes, used as bit-arrays for different groups of keys. The beginning of a packet is indicated by setting the most significant bit (MSB) to 1 while setting the MSB of the remaining five bytes to 0.
|
||||||
|
|
||||||
|
The format of GeminiPR packets is shown below.
|
||||||
|
```
|
||||||
|
1 Fn #1 #2 #3 #4 #5 #6
|
||||||
|
0 S1- S2- T- K- P- W- H-
|
||||||
|
0 R- A- O- *1 *2 res1 res2
|
||||||
|
0 pwr *3 *4 -E -U -F -R
|
||||||
|
0 -P -B -L -G -T -S -D
|
||||||
|
0 #7 #8 #9 #A #B #C -Z
|
||||||
|
```
|
||||||
|
|
||||||
|
Examples of steno strokes and the associated packet:
|
||||||
|
- `EUBG` = `10000000 00000000 00000000 00001100 00101000 00000000`
|
||||||
|
- `WAZ` = `10000000 00000010 00100000 00000000 00000000 00000001`
|
||||||
|
- `PHAPBGS` = `10000000 00000101 00100000 00000000 01101010 00000000`
|
||||||
|
|
||||||
|
### Switching protocols on the fly :id=switching-protocols-on-the-fly
|
||||||
|
|
||||||
|
If you wish to switch the serial protocol used to transfer the steno chords without having to recompile your keyboard firmware every time, you can press the `QK_STENO_BOLT` and `QK_STENO_GEMINI` keycodes in order to switch protocols on the fly.
|
||||||
|
|
||||||
|
To enable these special keycodes, add the following lines to your `rules.mk`:
|
||||||
|
```mk
|
||||||
|
STENO_ENABLE = yes
|
||||||
|
STENO_PROTOCOL = all
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to switch protocols programatically, as part of a custom macro for example, don't use `tap_code(QK_STENO_*)`, as `tap_code` only supports [basic keycodes](keycodes_basic). Instead, you should use `steno_set_mode(STENO_MODE_*)`, whose valid arguments are `STENO_MODE_BOLT` and `STENO_MODE_GEMINI`.
|
||||||
|
|
||||||
|
The default protocol is Gemini PR but the last protocol used is stored in non-volatile memory so QMK will remember your choice between reboots of your keyboard — assuming that your keyboard features (emulated) EEPROM.
|
||||||
|
|
||||||
|
Naturally, this option takes the most amount of firmware space as it needs to compile the code for all the available stenography protocols. In most cases, compiling a single stenography protocol is sufficient.
|
||||||
|
|
||||||
|
The default value for `STENO_PROTOCOL` is `all`.
|
||||||
|
|
||||||
## Configuring QMK for Steno :id=configuring-qmk-for-steno
|
## Configuring QMK for Steno :id=configuring-qmk-for-steno
|
||||||
|
|
||||||
Firstly, enable steno in your keymap's Makefile. You may also need disable mousekeys, 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.
|
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.
|
||||||
|
|
||||||
```make
|
!> 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).
|
||||||
STENO_ENABLE = yes
|
|
||||||
MOUSEKEY_ENABLE = no
|
|
||||||
```
|
|
||||||
|
|
||||||
In your keymap create a new layer for Plover. 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. If you would like to switch modes on the fly you can use the keycodes `QK_STENO_BOLT` and `QK_STENO_GEMINI`. If you only want to use one of the protocols you may set it up in your initialization function:
|
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.
|
||||||
|
|
||||||
```c
|
Once you have your keyboard flashed, launch Plover. Click the 'Configure...' button. In the 'Machine' tab, select the Stenotype Machine that corresponds to your desired protocol. Click the 'Configure...' button on this tab and enter the serial port or click 'Scan'. Baud rate is fine at 9600 (although you should be able to set as high as 115200 with no issues). Use the default settings for everything else (Data Bits: 8, Stop Bits: 1, Parity: N, no flow control).
|
||||||
void eeconfig_init_user() {
|
|
||||||
steno_set_mode(STENO_MODE_GEMINI); // or STENO_MODE_BOLT
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Once you have your keyboard flashed launch Plover. Click the 'Configure...' button. In the 'Machine' tab select the Stenotype Machine that corresponds to your desired protocol. Click the 'Configure...' button on this tab and enter the serial port or click 'Scan'. Baud rate is fine at 9600 (although you should be able to set as high as 115200 with no issues). Use the default settings for everything else (Data Bits: 8, Stop Bits: 1, Parity: N, no flow control).
|
To test your keymap, you can chord keys on your keyboard and either look at the output of the 'paper tape' (Tools > Paper Tape) or that of the 'layout display' (Tools > Layout Display). If your strokes correctly show up, you are now ready to steno!
|
||||||
|
|
||||||
On the display tab click 'Open stroke display'. With Plover disabled you should be able to hit keys on your keyboard and see them show up in the stroke display window. Use this to make sure you have set up your keymap correctly. You are now ready to steno!
|
|
||||||
|
|
||||||
## Learning Stenography :id=learning-stenography
|
## Learning Stenography :id=learning-stenography
|
||||||
|
|
||||||
|
@ -60,7 +121,7 @@ On the display tab click 'Open stroke display'. With Plover disabled you should
|
||||||
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.
|
The steno code has three interceptable hooks. If you define these functions, they will be called at certain points in processing; if they return true, processing continues, otherwise it's assumed you handled things.
|
||||||
|
|
||||||
```c
|
```c
|
||||||
bool send_steno_chord_user(steno_mode_t mode, uint8_t chord[6]);
|
bool send_steno_chord_user(steno_mode_t mode, uint8_t chord[MAX_STROKE_SIZE]);
|
||||||
```
|
```
|
||||||
|
|
||||||
This function is called when a chord is about to be sent. Mode will be one of `STENO_MODE_BOLT` or `STENO_MODE_GEMINI`. This represents the actual chord that would be sent via whichever protocol. You can modify the chord provided to alter what gets sent. Remember to return true if you want the regular sending process to happen.
|
This function is called when a chord is about to be sent. Mode will be one of `STENO_MODE_BOLT` or `STENO_MODE_GEMINI`. This represents the actual chord that would be sent via whichever protocol. You can modify the chord provided to alter what gets sent. Remember to return true if you want the regular sending process to happen.
|
||||||
|
@ -72,15 +133,23 @@ bool process_steno_user(uint16_t keycode, keyrecord_t *record) { return true; }
|
||||||
This function is called when a keypress has come in, before it is processed. The keycode should be one of `QK_STENO_BOLT`, `QK_STENO_GEMINI`, or one of the `STN_*` key values.
|
This function is called when a keypress has come in, before it is processed. The keycode should be one of `QK_STENO_BOLT`, `QK_STENO_GEMINI`, or one of the `STN_*` key values.
|
||||||
|
|
||||||
```c
|
```c
|
||||||
bool postprocess_steno_user(uint16_t keycode, keyrecord_t *record, steno_mode_t mode, uint8_t chord[6], int8_t pressed);
|
bool post_process_steno_user(uint16_t keycode, keyrecord_t *record, steno_mode_t mode, uint8_t chord[MAX_STROKE_SIZE], int8_t n_pressed_keys);
|
||||||
```
|
```
|
||||||
|
|
||||||
This function is called after a key has been processed, but before any decision about whether or not to send a chord. If `IS_PRESSED(record->event)` is false, and `pressed` is 0 or 1, the chord will be sent shortly, but has not yet been sent. This is where to put hooks for things like, say, live displays of steno chords or keys.
|
This function is called after a key has been processed, but before any decision about whether or not to send a chord. This is where to put hooks for things like, say, live displays of steno chords or keys.
|
||||||
|
|
||||||
|
If `IS_PRESSED(record->event)` is false, and `n_pressed_keys` is 0 or 1, the chord will be sent shortly, but has not yet been sent. This relieves you of the need of keeping track of where a packet ends and another begins.
|
||||||
|
|
||||||
|
The `chord` argument contains the packet of the current chord as specified by the protocol in use. This is *NOT* simply a list of chorded steno keys of the form `[STN_E, STN_U, STN_BR, STN_GR]`. Refer to the appropriate protocol section of this document to learn more about the format of the packets in your steno protocol/mode of choice.
|
||||||
|
|
||||||
|
The `n_pressed_keys` argument is the number of physical keys actually being held down.
|
||||||
|
This is not always equal to the number of bits set to 1 (aka the [Hamming weight](https://en.wikipedia.org/wiki/Hamming_weight)) in `chord` because it is possible to simultaneously press down four keys, then release three of those four keys and then press yet another key while the fourth finger is still holding down its key.
|
||||||
|
At the end of this scenario given as an example, `chord` would have five bits set to 1 but
|
||||||
|
`n_pressed_keys` would be set to 2 because there are only two keys currently being pressed down.
|
||||||
|
|
||||||
## Keycode Reference :id=keycode-reference
|
## Keycode Reference :id=keycode-reference
|
||||||
|
|
||||||
As defined in `keymap_steno.h`.
|
You must include `keymap_steno.h` to your `keymap.c` with `#include "keymap_steno.h"` before you can use these keycodes
|
||||||
|
|
||||||
> Note: TX Bolt does not support the full set of keys. The TX Bolt implementation in QMK will map the GeminiPR keys to the nearest TX Bolt key so that one key map will work for both.
|
> Note: TX Bolt does not support the full set of keys. The TX Bolt implementation in QMK will map the GeminiPR keys to the nearest TX Bolt key so that one key map will work for both.
|
||||||
|
|
||||||
|
@ -124,10 +193,10 @@ As defined in `keymap_steno.h`.
|
||||||
|`STN_SR`|`STN_SR`| `-S`|
|
|`STN_SR`|`STN_SR`| `-S`|
|
||||||
|`STN_DR`|`STN_DR`| `-D`|
|
|`STN_DR`|`STN_DR`| `-D`|
|
||||||
|`STN_ZR`|`STN_ZR`| `-Z`|
|
|`STN_ZR`|`STN_ZR`| `-Z`|
|
||||||
|`STN_FN`|| (GeminiPR only)|
|
|`STN_FN`|| (Function)|
|
||||||
|`STN_RES1`||(GeminiPR only)|
|
|`STN_RES1`||(Reset 1)|
|
||||||
|`STN_RES2`||(GeminiPR only)|
|
|`STN_RES2`||(Reset 2)|
|
||||||
|`STN_PWR`||(GeminiPR only)|
|
|`STN_PWR`||(Power)|
|
||||||
|
|
||||||
If you do not want to hit two keys with one finger combined keycodes can be used. These are also defined in `keymap_steno.h`, and causes both keys to be reported as pressed or released. To use these keycodes define `STENO_COMBINEDMAP` in your `config.h` file.
|
If you do not want to hit two keys with one finger combined keycodes can be used. These are also defined in `keymap_steno.h`, and causes both keys to be reported as pressed or released. To use these keycodes define `STENO_COMBINEDMAP` in your `config.h` file.
|
||||||
|
|
||||||
|
|
|
@ -14,55 +14,48 @@ Optionally, you might want to set a custom `TAPPING_TERM` time by adding somethi
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#define TAPPING_TERM 175
|
#define TAPPING_TERM 175
|
||||||
|
#define TAPPING_TERM_PER_KEY
|
||||||
```
|
```
|
||||||
|
|
||||||
The `TAPPING_TERM` time is the maximum time allowed between taps of your Tap Dance key, and is measured in milliseconds. For example, if you used the above `#define` statement and set up a Tap Dance key that sends `Space` on single-tap and `Enter` on double-tap, then this key will send `ENT` only if you tap this key twice in less than 175ms. If you tap the key, wait more than 175ms, and tap the key again you'll end up sending `SPC SPC` instead.
|
The `TAPPING_TERM` time is the maximum time allowed between taps of your Tap Dance key, and is measured in milliseconds. For example, if you used the above `#define` statement and set up a Tap Dance key that sends `Space` on single-tap and `Enter` on double-tap, then this key will send `ENT` only if you tap this key twice in less than 175ms. If you tap the key, wait more than 175ms, and tap the key again you'll end up sending `SPC SPC` instead. The `TAPPING_TERM_PER_KEY` definition is only needed if you control the tapping term through a [custom `get_tapping_term` function](tap_hold.md#tapping_term), which may be needed because `TAPPING_TERM` affects not just tap-dance keys.
|
||||||
|
|
||||||
Next, you will want to define some tap-dance keys, which is easiest to do with the `TD()` macro, that takes a number which will later be used as an index into the `tap_dance_actions` array.
|
Next, you will want to define some tap-dance keys, which is easiest to do with the `TD()` macro. That macro takes a number which will later be used as an index into the `tap_dance_actions` array and turns it into a tap-dance keycode.
|
||||||
|
|
||||||
After this, you'll want to use the `tap_dance_actions` array to specify what actions shall be taken when a tap-dance key is in action. Currently, there are five possible options:
|
After this, you'll want to use the `tap_dance_actions` array to specify what actions shall be taken when a tap-dance key is in action. Currently, there are five possible options:
|
||||||
|
|
||||||
* `ACTION_TAP_DANCE_DOUBLE(kc1, kc2)`: Sends the `kc1` keycode when tapped once, `kc2` otherwise. When the key is held, the appropriate keycode is registered: `kc1` when pressed and held, `kc2` when tapped once, then pressed and held.
|
* `ACTION_TAP_DANCE_DOUBLE(kc1, kc2)`: Sends the `kc1` keycode when tapped once, `kc2` otherwise. When the key is held, the appropriate keycode is registered: `kc1` when pressed and held, `kc2` when tapped once, then pressed and held.
|
||||||
* `ACTION_TAP_DANCE_LAYER_MOVE(kc, layer)`: Sends the `kc` keycode when tapped once, or moves to `layer`. (this functions like the `TO` layer keycode).
|
* `ACTION_TAP_DANCE_LAYER_MOVE(kc, layer)`: Sends the `kc` keycode when tapped once, or moves to `layer`. (this functions like the `TO` layer keycode).
|
||||||
* This is the same as `ACTION_TAP_DANCE_DUAL_ROLE`, but renamed to something that is clearer about its functionality. Both names will work.
|
|
||||||
* `ACTION_TAP_DANCE_LAYER_TOGGLE(kc, layer)`: Sends the `kc` keycode when tapped once, or toggles the state of `layer`. (this functions like the `TG` layer keycode).
|
* `ACTION_TAP_DANCE_LAYER_TOGGLE(kc, layer)`: Sends the `kc` keycode when tapped once, or toggles the state of `layer`. (this functions like the `TG` layer keycode).
|
||||||
* `ACTION_TAP_DANCE_FN(fn)`: Calls the specified function - defined in the user keymap - with the final tap count of the tap dance action.
|
* `ACTION_TAP_DANCE_FN(fn)`: Calls the specified function - defined in the user keymap - with the final tap count of the tap dance action.
|
||||||
* `ACTION_TAP_DANCE_FN_ADVANCED(on_each_tap_fn, on_dance_finished_fn, on_dance_reset_fn)`: Calls the first specified function - defined in the user keymap - on every tap, the second function when the dance action finishes (like the previous option), and the last function when the tap dance action resets.
|
* `ACTION_TAP_DANCE_FN_ADVANCED(on_each_tap_fn, on_dance_finished_fn, on_dance_reset_fn)`: Calls the first specified function - defined in the user keymap - on every tap, the second function when the dance action finishes (like the previous option), and the last function when the tap dance action resets.
|
||||||
* ~~`ACTION_TAP_DANCE_FN_ADVANCED_TIME(on_each_tap_fn, on_dance_finished_fn, on_dance_reset_fn, tap_specific_tapping_term)`~~: This functions identically to the `ACTION_TAP_DANCE_FN_ADVANCED` function, but uses a custom tapping term for it, instead of the predefined `TAPPING_TERM`.
|
|
||||||
* This is deprecated in favor of the Per Key Tapping Term functionality, as outlined [here](tap_hold.md#tapping-term). You'd want to check for the specific `TD()` macro that you want to use (such as `TD(TD_ESC_CAPS)`) instead of using this specific Tap Dance function.
|
|
||||||
|
|
||||||
|
|
||||||
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.
|
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.
|
!> 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 option is good for simple layer-switching cases.
|
Similar to the first option, the second and third option are good for simple layer-switching cases.
|
||||||
|
|
||||||
For more complicated cases, use the third or fourth options (examples of each are listed below).
|
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.
|
||||||
|
|
||||||
Finally, the fifth option is particularly useful if your non-Tap-Dance keys start behaving weirdly after adding the code for your Tap Dance keys. The likely problem is that you changed the `TAPPING_TERM` time to make your Tap Dance keys easier for you to use, and that this has changed the way your other keys handle interrupts.
|
|
||||||
|
|
||||||
## Implementation Details :id=implementation
|
## Implementation Details :id=implementation
|
||||||
|
|
||||||
Well, that's the bulk of it! You should now be able to work through the examples below, and to develop your own Tap Dance functionality. But if you want a deeper understanding of what's going on behind the scenes, then read on for the explanation of how it all works!
|
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!
|
||||||
|
|
||||||
The main entry point is `process_tap_dance()`, called from `process_record_quantum()`, which is run for every keypress, and our handler gets to run early. This function checks whether the key pressed is a tap-dance key. If it is not, and a tap-dance was in action, we handle that first, and enqueue the newly pressed key. If it is a tap-dance key, then we check if it is the same as the already active one (if there's one active, that is). If it is not, we fire off the old one first, then register the new one. If it was the same, we increment the counter and reset the timer.
|
Let's go over the three functions mentioned in `ACTION_TAP_DANCE_FN_ADVANCED` in a little more detail. They all receive the same two arguments: a pointer to a structure that holds all dance related state information, and a pointer to a use case specific state variable. The three functions differ in when they are called. The first, `on_each_tap_fn()`, is called every time the tap dance key is *pressed*. Before it is called, the counter is incremented and the timer is reset. The second function, `on_dance_finished_fn()`, is called when the tap dance is interrupted or ends because `TAPPING_TERM` milliseconds have passed since the last tap. When the `finished` field of the dance state structure is set to `true`, the `on_dance_finished_fn()` is skipped. After `on_dance_finished_fn()` was called or would have been called, but no sooner than when the tap dance key is *released*, `on_dance_reset_fn()` is called. It is possible to end a tap dance immediately, skipping `on_dance_finished_fn()`, but not `on_dance_reset_fn`, by calling `reset_tap_dance(state)`.
|
||||||
|
|
||||||
|
To accomplish this logic, the tap dance mechanics use three entry points. The main entry point is `process_tap_dance()`, called from `process_record_quantum()` *after* `process_record_kb()` and `process_record_user()`. This function is responsible for calling `on_each_tap_fn()` and `on_dance_reset_fn()`. In order to handle interruptions of a tap dance, another entry point, `preprocess_tap_dance()` is run right at the beginning of `process_record_quantum()`. This function checks whether the key pressed is a tap-dance key. If it is not, and a tap-dance was in action, we handle that first, and enqueue the newly pressed key. If it is a tap-dance key, then we check if it is the same as the already active one (if there's one active, that is). If it is not, we fire off the old one first, then register the new one. Finally, `tap_dance_task()` periodically checks whether `TAPPING_TERM` has passed since the last key press and finishes a tap dance if that is the case.
|
||||||
|
|
||||||
This means that you have `TAPPING_TERM` time to tap the key again; you do not have to input all the taps within a single `TAPPING_TERM` timeframe. This allows for longer tap counts, with minimal impact on responsiveness.
|
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.
|
||||||
|
|
||||||
Our next stop is `tap_dance_task()`. This handles the timeout of tap-dance keys.
|
|
||||||
|
|
||||||
For the sake of flexibility, tap-dance actions can be either a pair of keycodes, or a user function. The latter allows one to handle higher tap counts, or do extra things, like blink the LEDs, fiddle with the backlighting, and so on. This is accomplished by using an union, and some clever macros.
|
|
||||||
|
|
||||||
## Examples :id=examples
|
## Examples :id=examples
|
||||||
|
|
||||||
### Simple Example :id=simple-example
|
### Simple Example: Send `ESC` on Single Tap, `CAPS_LOCK` on Double Tap :id=simple-example
|
||||||
|
|
||||||
Here's a simple example for a single definition:
|
Here's a simple example for a single definition:
|
||||||
|
|
||||||
1. In your `rules.mk`, add `TAP_DANCE_ENABLE = yes`
|
1. In your `rules.mk`, add `TAP_DANCE_ENABLE = yes`
|
||||||
2. In your `config.h` (which you can copy from `qmk_firmware/keyboards/planck/config.h` to your keymap directory), add `#define TAPPING_TERM 200`
|
2. In your `keymap.c` file, define the variables and definitions, then add to your keymap:
|
||||||
3. In your `keymap.c` file, define the variables and definitions, then add to your keymap:
|
|
||||||
|
|
||||||
```c
|
```c
|
||||||
// Tap Dance declarations
|
// Tap Dance declarations
|
||||||
|
@ -92,40 +85,15 @@ All the enums used in the examples are declared like this:
|
||||||
```c
|
```c
|
||||||
// Enums defined for all examples:
|
// Enums defined for all examples:
|
||||||
enum {
|
enum {
|
||||||
CT_SE,
|
TD_ESC_CAPS,
|
||||||
CT_CLN,
|
|
||||||
CT_EGG,
|
CT_EGG,
|
||||||
CT_FLSH,
|
CT_FLSH,
|
||||||
X_TAP_DANCE
|
CT_CLN,
|
||||||
|
X_CTL,
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Example 1: Send `:` on Single Tap, `;` on Double Tap :id=example-1
|
#### Example 1: Send "Safety Dance!" After 100 Taps :id=example-1
|
||||||
|
|
||||||
```c
|
|
||||||
void dance_cln_finished(qk_tap_dance_state_t *state, void *user_data) {
|
|
||||||
if (state->count == 1) {
|
|
||||||
register_code16(KC_COLN);
|
|
||||||
} else {
|
|
||||||
register_code(KC_SCLN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dance_cln_reset(qk_tap_dance_state_t *state, void *user_data) {
|
|
||||||
if (state->count == 1) {
|
|
||||||
unregister_code16(KC_COLN);
|
|
||||||
} else {
|
|
||||||
unregister_code(KC_SCLN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// All tap dance functions would go here. Only showing this one.
|
|
||||||
qk_tap_dance_action_t tap_dance_actions[] = {
|
|
||||||
[CT_CLN] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, dance_cln_finished, dance_cln_reset),
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Example 2: Send "Safety Dance!" After 100 Taps :id=example-2
|
|
||||||
|
|
||||||
```c
|
```c
|
||||||
void dance_egg(qk_tap_dance_state_t *state, void *user_data) {
|
void dance_egg(qk_tap_dance_state_t *state, void *user_data) {
|
||||||
|
@ -140,7 +108,7 @@ qk_tap_dance_action_t tap_dance_actions[] = {
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Example 3: Turn LED Lights On Then Off, One at a Time :id=example-3
|
#### Example 2: Turn LED Lights On Then Off, One at a Time :id=example-2
|
||||||
|
|
||||||
```c
|
```c
|
||||||
// On each tap, light up one LED, from right to left
|
// On each tap, light up one LED, from right to left
|
||||||
|
@ -181,15 +149,74 @@ void dance_flsh_reset(qk_tap_dance_state_t *state, void *user_data) {
|
||||||
ergodox_right_led_3_off();
|
ergodox_right_led_3_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
// All tap dances now put together. Example 3 is "CT_FLASH"
|
// All tap dances now put together. Example 2 is "CT_FLSH"
|
||||||
qk_tap_dance_action_t tap_dance_actions[] = {
|
qk_tap_dance_action_t tap_dance_actions[] = {
|
||||||
[CT_SE] = ACTION_TAP_DANCE_DOUBLE(KC_SPC, KC_ENT),
|
[TD_ESC_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_CAPS),
|
||||||
[CT_CLN] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, dance_cln_finished, dance_cln_reset),
|
|
||||||
[CT_EGG] = ACTION_TAP_DANCE_FN(dance_egg),
|
[CT_EGG] = ACTION_TAP_DANCE_FN(dance_egg),
|
||||||
[CT_FLSH] = ACTION_TAP_DANCE_FN_ADVANCED(dance_flsh_each, dance_flsh_finished, dance_flsh_reset)
|
[CT_FLSH] = ACTION_TAP_DANCE_FN_ADVANCED(dance_flsh_each, dance_flsh_finished, dance_flsh_reset)
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Example 3: Send `:` on Tap, `;` on Hold :id=example-3
|
||||||
|
|
||||||
|
With a little effort, powerful tap-hold configurations can be implemented as tap dances. To emit taps as early as possible, we need to act on releases of the tap dance key. There is no callback for this in the tap dance framework, so we use `process_record_user()`.
|
||||||
|
|
||||||
|
```c
|
||||||
|
typedef struct {
|
||||||
|
uint16_t tap;
|
||||||
|
uint16_t hold;
|
||||||
|
uint16_t held;
|
||||||
|
} tap_dance_tap_hold_t;
|
||||||
|
|
||||||
|
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
qk_tap_dance_action_t *action;
|
||||||
|
|
||||||
|
switch (keycode) {
|
||||||
|
case TD(CT_CLN): // list all tap dance keycodes with tap-hold configurations
|
||||||
|
action = &tap_dance_actions[TD_INDEX(keycode)];
|
||||||
|
if (!record->event.pressed && action->state.count && !action->state.finished) {
|
||||||
|
tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)action->user_data;
|
||||||
|
tap_code16(tap_hold->tap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tap_dance_tap_hold_finished(qk_tap_dance_state_t *state, void *user_data) {
|
||||||
|
tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)user_data;
|
||||||
|
|
||||||
|
if (state->pressed) {
|
||||||
|
if (state->count == 1
|
||||||
|
#ifndef PERMISSIVE_HOLD
|
||||||
|
&& !state->interrupted
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
register_code16(tap_hold->hold);
|
||||||
|
tap_hold->held = tap_hold->hold;
|
||||||
|
} else {
|
||||||
|
register_code16(tap_hold->tap);
|
||||||
|
tap_hold->held = tap_hold->tap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tap_dance_tap_hold_reset(qk_tap_dance_state_t *state, void *user_data) {
|
||||||
|
tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)user_data;
|
||||||
|
|
||||||
|
if (tap_hold->held) {
|
||||||
|
unregister_code16(tap_hold->held);
|
||||||
|
tap_hold->held = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ACTION_TAP_DANCE_TAP_HOLD(tap, hold) \
|
||||||
|
{ .fn = {NULL, tap_dance_tap_hold_finished, tap_dance_tap_hold_reset}, .user_data = (void *)&((tap_dance_tap_hold_t){tap, hold, 0}), }
|
||||||
|
|
||||||
|
qk_tap_dance_action_t tap_dance_actions[] = {
|
||||||
|
[CT_CLN] = ACTION_TAP_DANCE_TAP_HOLD(KC_COLN, KC_SCLN),
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
#### Example 4: 'Quad Function Tap-Dance' :id=example-4
|
#### Example 4: 'Quad Function Tap-Dance' :id=example-4
|
||||||
|
|
||||||
By [DanielGGordon](https://github.com/danielggordon)
|
By [DanielGGordon](https://github.com/danielggordon)
|
||||||
|
@ -305,7 +332,8 @@ void x_finished(qk_tap_dance_state_t *state, void *user_data) {
|
||||||
// Last case is for fast typing. Assuming your key is `f`:
|
// Last case is for fast typing. Assuming your key is `f`:
|
||||||
// For example, when typing the word `buffer`, and you want to make sure that you send `ff` and not `Esc`.
|
// For example, when typing the word `buffer`, and you want to make sure that you send `ff` and not `Esc`.
|
||||||
// In order to type `ff` when typing fast, the next character will have to be hit within the `TAPPING_TERM`, which by default is 200ms.
|
// In order to type `ff` when typing fast, the next character will have to be hit within the `TAPPING_TERM`, which by default is 200ms.
|
||||||
case TD_DOUBLE_SINGLE_TAP: tap_code(KC_X); register_code(KC_X);
|
case TD_DOUBLE_SINGLE_TAP: tap_code(KC_X); register_code(KC_X); break;
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,8 +342,9 @@ void x_reset(qk_tap_dance_state_t *state, void *user_data) {
|
||||||
case TD_SINGLE_TAP: unregister_code(KC_X); break;
|
case TD_SINGLE_TAP: unregister_code(KC_X); break;
|
||||||
case TD_SINGLE_HOLD: unregister_code(KC_LCTL); break;
|
case TD_SINGLE_HOLD: unregister_code(KC_LCTL); break;
|
||||||
case TD_DOUBLE_TAP: unregister_code(KC_ESC); break;
|
case TD_DOUBLE_TAP: unregister_code(KC_ESC); break;
|
||||||
case TD_DOUBLE_HOLD: unregister_code(KC_LALT);
|
case TD_DOUBLE_HOLD: unregister_code(KC_LALT); break;
|
||||||
case TD_DOUBLE_SINGLE_TAP: unregister_code(KC_X);
|
case TD_DOUBLE_SINGLE_TAP: unregister_code(KC_X); break;
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
xtap_state.state = TD_NONE;
|
xtap_state.state = TD_NONE;
|
||||||
}
|
}
|
||||||
|
@ -329,7 +358,7 @@ And then simply use `TD(X_CTL)` anywhere in your keymap.
|
||||||
|
|
||||||
If you want to implement this in your userspace, then you may want to check out how [DanielGGordon](https://github.com/qmk/qmk_firmware/tree/master/users/gordon) has implemented this in their userspace.
|
If you want to implement this in your userspace, then you may want to check out how [DanielGGordon](https://github.com/qmk/qmk_firmware/tree/master/users/gordon) has implemented this in their userspace.
|
||||||
|
|
||||||
> In this configuration "hold" takes place **after** tap dance timeout (see `ACTION_TAP_DANCE_FN_ADVANCED_TIME`). 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`).
|
> 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 :id=example-5
|
||||||
|
|
||||||
|
@ -511,8 +540,18 @@ void ql_reset(qk_tap_dance_state_t *state, void *user_data) {
|
||||||
|
|
||||||
// Associate our tap dance key with its functionality
|
// Associate our tap dance key with its functionality
|
||||||
qk_tap_dance_action_t tap_dance_actions[] = {
|
qk_tap_dance_action_t tap_dance_actions[] = {
|
||||||
[QUOT_LAYR] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, ql_finished, ql_reset, 275)
|
[QUOT_LAYR] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, ql_finished, ql_reset)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Set a long-ish tapping term for tap-dance keys
|
||||||
|
uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
switch (keycode) {
|
||||||
|
case QK_TAP_DANCE ... QK_TAP_DANCE_MAX:
|
||||||
|
return 275;
|
||||||
|
default:
|
||||||
|
return TAPPING_TERM;
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The above code is similar to that used in previous examples. The one point to note is that we need to be able to check which layers are active at any time so we can toggle them if needed. To do this we use the `layer_state_is(layer)` function which returns `true` if the given `layer` is active.
|
The above code is similar to that used in previous examples. The one point to note is that we need to be able to check which layers are active at any time so we can toggle them if needed. To do this we use the `layer_state_is(layer)` function which returns `true` if the given `layer` is active.
|
||||||
|
@ -521,6 +560,6 @@ The use of `cur_dance()` and `ql_tap_state` mirrors the above examples.
|
||||||
|
|
||||||
The `case: TD_SINGLE_TAP` in `ql_finished` is similar to the above examples. The `TD_SINGLE_HOLD` case works in conjunction with `ql_reset()` to switch to `_MY_LAYER` while the tap dance key is held, and to switch away from `_MY_LAYER` when the key is released. This mirrors the use of `MO(_MY_LAYER)`. The `TD_DOUBLE_TAP` case works by checking whether `_MY_LAYER` is the active layer, and toggling it on or off accordingly. This mirrors the use of `TG(_MY_LAYER)`.
|
The `case: TD_SINGLE_TAP` in `ql_finished` is similar to the above examples. The `TD_SINGLE_HOLD` case works in conjunction with `ql_reset()` to switch to `_MY_LAYER` while the tap dance key is held, and to switch away from `_MY_LAYER` when the key is released. This mirrors the use of `MO(_MY_LAYER)`. The `TD_DOUBLE_TAP` case works by checking whether `_MY_LAYER` is the active layer, and toggling it on or off accordingly. This mirrors the use of `TG(_MY_LAYER)`.
|
||||||
|
|
||||||
`tap_dance_actions[]` works similar to the above examples. Note that I used `ACTION_TAP_DANCE_FN_ADVANCED_TIME()` instead of `ACTION_TAP_DANCE_FN_ADVANCED()`. This is because I like my `TAPPING_TERM` to be short (\~175ms) for my non-tap-dance keys but find that this is too quick for me to reliably complete tap dance actions - thus the increased time of 275ms here.
|
`tap_dance_actions[]` works similar to the above examples. Note that, additionally, I set a longer tapping term for the tap dance keys. This is because I like my `TAPPING_TERM` to be short (\~175ms) for my non-tap-dance keys but find that this is too quick for me to reliably complete tap dance actions - thus the increased time of 275ms here. In order for the per-key tapping terms to take effect, `TAPPING_TERM_PER_KEY` must be defined in your `config.h`.
|
||||||
|
|
||||||
Finally, to get this tap dance key working, be sure to include `TD(QUOT_LAYR)` in your `keymaps[]`.
|
Finally, to get this tap dance key working, be sure to include `TD(QUOT_LAYR)` in your `keymaps[]`.
|
||||||
|
|
|
@ -1,107 +0,0 @@
|
||||||
# Terminal
|
|
||||||
|
|
||||||
> This feature is currently *huge*, and should probably only be put on boards with a lot of memory, or for fun.
|
|
||||||
|
|
||||||
The terminal feature is a command-line-like interface designed to communicate through a text editor with keystrokes. It's beneficial to turn off auto-indent features in your editor.
|
|
||||||
|
|
||||||
To enable, stick this in your `rules.mk` or `Makefile`:
|
|
||||||
|
|
||||||
TERMINAL_ENABLE = yes
|
|
||||||
|
|
||||||
And use the `TERM_ON` and `TERM_OFF` keycodes to turn it on or off.
|
|
||||||
|
|
||||||
When enabled, a `> ` prompt will appear, where you'll be able to type, backspace (a bell will ding if you reach the beginning and audio is enabled), and hit enter to send the command. Arrow keys are currently disabled so it doesn't get confused. Moving your cursor around with the mouse is discouraged.
|
|
||||||
|
|
||||||
`#define TERMINAL_HELP` enables some other output helpers that aren't really needed with this page.
|
|
||||||
|
|
||||||
Pressing "up" and "down" will allow you to cycle through the past 5 commands entered.
|
|
||||||
|
|
||||||
## Future Ideas
|
|
||||||
|
|
||||||
* Keyboard/user-extensible commands
|
|
||||||
* Smaller footprint
|
|
||||||
* Arrow key support
|
|
||||||
* Command history - Done
|
|
||||||
* SD card support
|
|
||||||
* LCD support for buffer display
|
|
||||||
* Keycode -> name string LUT
|
|
||||||
* Layer status
|
|
||||||
* *Analog/digital port read/write*
|
|
||||||
* RGB mode stuff
|
|
||||||
* Macro definitions
|
|
||||||
* EEPROM read/write
|
|
||||||
* Audio control
|
|
||||||
|
|
||||||
## Current Commands
|
|
||||||
|
|
||||||
### `about`
|
|
||||||
|
|
||||||
Prints out the current version of QMK with a build date:
|
|
||||||
|
|
||||||
```
|
|
||||||
> about
|
|
||||||
QMK Firmware
|
|
||||||
v0.5.115-7-g80ed73-dirty
|
|
||||||
Built: 2017-08-29-20:24:44
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### `print-buffer`
|
|
||||||
|
|
||||||
Outputs the last 5 commands entered
|
|
||||||
|
|
||||||
```
|
|
||||||
> print-buffer
|
|
||||||
0. print-buffer
|
|
||||||
1. help
|
|
||||||
2. about
|
|
||||||
3. keymap 0
|
|
||||||
4. help
|
|
||||||
5. flush-buffer
|
|
||||||
```
|
|
||||||
|
|
||||||
### `flush-buffer`
|
|
||||||
|
|
||||||
Clears command buffer
|
|
||||||
```
|
|
||||||
> flush-buffer
|
|
||||||
Buffer cleared!
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### `help`
|
|
||||||
|
|
||||||
|
|
||||||
Prints out the available commands:
|
|
||||||
|
|
||||||
```
|
|
||||||
> help
|
|
||||||
commands available:
|
|
||||||
about help keycode keymap exit print-buffer flush-buffer
|
|
||||||
```
|
|
||||||
|
|
||||||
### `keycode <layer> <row> <col>`
|
|
||||||
|
|
||||||
Prints out the keycode value of a certain layer, row, and column:
|
|
||||||
|
|
||||||
```
|
|
||||||
> keycode 0 1 0
|
|
||||||
0x29 (41)
|
|
||||||
```
|
|
||||||
|
|
||||||
### `keymap <layer>`
|
|
||||||
|
|
||||||
Prints out the entire keymap for a certain layer
|
|
||||||
|
|
||||||
```
|
|
||||||
> keymap 0
|
|
||||||
0x002b, 0x0014, 0x001a, 0x0008, 0x0015, 0x0017, 0x001c, 0x0018, 0x000c, 0x0012, 0x0013, 0x002a,
|
|
||||||
0x0029, 0x0004, 0x0016, 0x0007, 0x0009, 0x000a, 0x000b, 0x000d, 0x000e, 0x000f, 0x0033, 0x0034,
|
|
||||||
0x00e1, 0x001d, 0x001b, 0x0006, 0x0019, 0x0005, 0x0011, 0x0010, 0x0036, 0x0037, 0x0038, 0x0028,
|
|
||||||
0x5cd6, 0x00e0, 0x00e2, 0x00e3, 0x5cd4, 0x002c, 0x002c, 0x5cd5, 0x0050, 0x0051, 0x0052, 0x004f,
|
|
||||||
>
|
|
||||||
```
|
|
||||||
|
|
||||||
### `exit`
|
|
||||||
|
|
||||||
Exits the terminal - same as `TERM_OFF`.
|
|
|
@ -172,6 +172,7 @@ You can switch the input mode at any time by using the following keycodes. Addin
|
||||||
|`UNICODE_MODE_WIN` |`UC_M_WI`|`UC_WIN` |Switch to Windows input |
|
|`UNICODE_MODE_WIN` |`UC_M_WI`|`UC_WIN` |Switch to Windows input |
|
||||||
|`UNICODE_MODE_BSD` |`UC_M_BS`|`UC_BSD` |Switch to BSD input _(not implemented)_ |
|
|`UNICODE_MODE_BSD` |`UC_M_BS`|`UC_BSD` |Switch to BSD input _(not implemented)_ |
|
||||||
|`UNICODE_MODE_WINC` |`UC_M_WC`|`UC_WINC` |Switch to Windows input using WinCompose |
|
|`UNICODE_MODE_WINC` |`UC_M_WC`|`UC_WINC` |Switch to Windows input using WinCompose |
|
||||||
|
|`UNICODE_MODE_EMACS` |`UC_M_EM`|`UC_EMACS` |Switch to emacs (`C-x-8 RET`) |
|
||||||
|
|
||||||
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. `UC_LNX`).
|
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. `UC_LNX`).
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ Compatible flashers:
|
||||||
Flashing sequence:
|
Flashing sequence:
|
||||||
|
|
||||||
1. Enter the bootloader using any of the following methods:
|
1. Enter the bootloader using any of the following methods:
|
||||||
* Press the `RESET` keycode
|
* Press the `QK_BOOT` keycode
|
||||||
* Press the `RESET` button on the PCB if available
|
* Press the `RESET` button on the PCB if available
|
||||||
* Short RST to GND quickly
|
* Short RST to GND quickly
|
||||||
2. Wait for the OS to detect the device
|
2. Wait for the OS to detect the device
|
||||||
|
@ -87,7 +87,7 @@ Compatible flashers:
|
||||||
Flashing sequence:
|
Flashing sequence:
|
||||||
|
|
||||||
1. Enter the bootloader using any of the following methods (you only have 7 seconds to flash once it enters; some variants may require you to reset twice within 750 milliseconds):
|
1. Enter the bootloader using any of the following methods (you only have 7 seconds to flash once it enters; some variants may require you to reset twice within 750 milliseconds):
|
||||||
* Press the `RESET` keycode
|
* Press the `QK_BOOT` keycode
|
||||||
* Press the `RESET` button on the PCB if available
|
* Press the `RESET` button on the PCB if available
|
||||||
* Short RST to GND quickly
|
* Short RST to GND quickly
|
||||||
2. Wait for the OS to detect the device
|
2. Wait for the OS to detect the device
|
||||||
|
@ -123,7 +123,7 @@ Compatible flashers:
|
||||||
Flashing sequence:
|
Flashing sequence:
|
||||||
|
|
||||||
1. Enter the bootloader using any of the following methods (you only have 7 seconds to flash once it enters):
|
1. Enter the bootloader using any of the following methods (you only have 7 seconds to flash once it enters):
|
||||||
* Press the `RESET` keycode
|
* Press the `QK_BOOT` keycode
|
||||||
* Press the `RESET` button on the Teensy or PCB if available
|
* Press the `RESET` button on the Teensy or PCB if available
|
||||||
* short RST to GND quickly
|
* short RST to GND quickly
|
||||||
2. Wait for the OS to detect the device
|
2. Wait for the OS to detect the device
|
||||||
|
@ -153,7 +153,7 @@ Compatible flashers:
|
||||||
Flashing sequence:
|
Flashing sequence:
|
||||||
|
|
||||||
1. Enter the bootloader using any of the following methods:
|
1. Enter the bootloader using any of the following methods:
|
||||||
* Press the `RESET` keycode
|
* Press the `QK_BOOT` keycode
|
||||||
* Keep the `BOOT` button held while quickly tapping the `RESET` button on the PCB
|
* Keep the `BOOT` button held while quickly tapping the `RESET` button on the PCB
|
||||||
2. Wait for the OS to detect the device
|
2. Wait for the OS to detect the device
|
||||||
3. Flash a .hex file
|
3. Flash a .hex file
|
||||||
|
@ -182,7 +182,7 @@ Compatible flashers:
|
||||||
Flashing sequence:
|
Flashing sequence:
|
||||||
|
|
||||||
1. Enter the bootloader using any of the following methods:
|
1. Enter the bootloader using any of the following methods:
|
||||||
* Tap the `RESET` keycode
|
* Tap the `QK_BOOT` keycode
|
||||||
* Hold the salt key while plugging the keyboard in - for PS2AVRGB boards, this is usually the key connected to MCU pins A0 and B0, otherwise it will be documented in your keyboard's readme
|
* Hold the salt key while plugging the keyboard in - for PS2AVRGB boards, this is usually the key connected to MCU pins A0 and B0, otherwise it will be documented in your keyboard's readme
|
||||||
2. Wait for the OS to detect the device
|
2. Wait for the OS to detect the device
|
||||||
3. Flash a .hex file
|
3. Flash a .hex file
|
||||||
|
@ -223,7 +223,7 @@ Compatible flashers:
|
||||||
Flashing sequence:
|
Flashing sequence:
|
||||||
|
|
||||||
1. Enter the bootloader using any of the following methods:
|
1. Enter the bootloader using any of the following methods:
|
||||||
* Press the `RESET` keycode
|
* Press the `QK_BOOT` keycode
|
||||||
* Press the `RESET` button on the PCB if available
|
* Press the `RESET` button on the PCB if available
|
||||||
* short RST to GND quickly
|
* short RST to GND quickly
|
||||||
2. Wait for the OS to detect the device
|
2. Wait for the OS to detect the device
|
||||||
|
@ -256,7 +256,7 @@ Compatible flashers:
|
||||||
Flashing sequence:
|
Flashing sequence:
|
||||||
|
|
||||||
1. Enter the bootloader using any of the following methods:
|
1. Enter the bootloader using any of the following methods:
|
||||||
* Tap the `RESET` keycode (may not work on STM32F042 devices)
|
* Tap the `QK_BOOT` keycode (may not work on STM32F042 devices)
|
||||||
* If a reset circuit is present, tap the `RESET` button on the PCB; some boards may also have a toggle switch that must be flipped
|
* If a reset circuit is present, tap the `RESET` button on the PCB; some boards may also have a toggle switch that must be flipped
|
||||||
* Otherwise, you need to bridge `BOOT0` to VCC (via `BOOT0` button or jumper), short `RESET` to GND (via `RESET` button or jumper), and then let go of the `BOOT0` bridge
|
* Otherwise, you need to bridge `BOOT0` to VCC (via `BOOT0` button or jumper), short `RESET` to GND (via `RESET` button or jumper), and then let go of the `BOOT0` bridge
|
||||||
2. Wait for the OS to detect the device
|
2. Wait for the OS to detect the device
|
||||||
|
@ -292,7 +292,7 @@ Compatible flashers:
|
||||||
Flashing sequence:
|
Flashing sequence:
|
||||||
|
|
||||||
1. Enter the bootloader using any of the following methods:
|
1. Enter the bootloader using any of the following methods:
|
||||||
* Tap the `RESET` keycode
|
* Tap the `QK_BOOT` keycode
|
||||||
* If a reset circuit is present, tap the `RESET` button on the PCB
|
* If a reset circuit is present, tap the `RESET` button on the PCB
|
||||||
* Otherwise, you need to bridge `BOOT0` to VCC (via `BOOT0` button or jumper), short `RESET` to GND (via `RESET` button or jumper), and then let go of the `BOOT0` bridge
|
* Otherwise, you need to bridge `BOOT0` to VCC (via `BOOT0` button or jumper), short `RESET` to GND (via `RESET` button or jumper), and then let go of the `BOOT0` bridge
|
||||||
2. Wait for the OS to detect the device
|
2. Wait for the OS to detect the device
|
||||||
|
@ -316,7 +316,7 @@ Compatible flashers:
|
||||||
Flashing sequence:
|
Flashing sequence:
|
||||||
|
|
||||||
1. Enter the bootloader using any of the following methods:
|
1. Enter the bootloader using any of the following methods:
|
||||||
* Tap the `RESET` keycode
|
* Tap the `QK_BOOT` keycode
|
||||||
* Press the `RESET` button on the PCB
|
* Press the `RESET` button on the PCB
|
||||||
2. Wait for the OS to detect the device
|
2. Wait for the OS to detect the device
|
||||||
3. Flash a .bin file
|
3. Flash a .bin file
|
||||||
|
@ -342,7 +342,7 @@ Compatible flashers:
|
||||||
Flashing sequence:
|
Flashing sequence:
|
||||||
|
|
||||||
1. Enter the bootloader using any of the following methods:
|
1. Enter the bootloader using any of the following methods:
|
||||||
* Tap the `RESET` keycode
|
* Tap the `QK_BOOT` keycode
|
||||||
* Double-tap the `nRST` button on the PCB.
|
* Double-tap the `nRST` button on the PCB.
|
||||||
2. Wait for the OS to detect the device
|
2. Wait for the OS to detect the device
|
||||||
3. Copy the .uf2 file to the new USB disk
|
3. Copy the .uf2 file to the new USB disk
|
||||||
|
@ -353,8 +353,51 @@ or
|
||||||
CLI Flashing sequence:
|
CLI Flashing sequence:
|
||||||
|
|
||||||
1. Enter the bootloader using any of the following methods:
|
1. Enter the bootloader using any of the following methods:
|
||||||
* Tap the `RESET` keycode
|
* Tap the `QK_BOOT` keycode
|
||||||
* Double-tap the `nRST` button on the PCB.
|
* Double-tap the `nRST` button on the PCB.
|
||||||
2. Wait for the OS to detect the device
|
2. Wait for the OS to detect the device
|
||||||
3. Flash via QMK CLI eg. `qmk flash --keyboard handwired/onekey/blackpill_f411_tinyuf2 --keymap default`
|
3. Flash via QMK CLI eg. `qmk flash --keyboard handwired/onekey/blackpill_f411_tinyuf2 --keymap default`
|
||||||
4. Wait for the keyboard to become available
|
4. Wait for the keyboard to become available
|
||||||
|
|
||||||
|
### `make` Targets
|
||||||
|
|
||||||
|
* `:uf2-split-left` and `:uf2-split-right`: Flashes the firmware but also sets the handedness setting in EEPROM by generating a side specific firmware.
|
||||||
|
|
||||||
|
## Raspberry Pi RP2040 UF2
|
||||||
|
|
||||||
|
The `rules.mk` setting for this bootloader is `rp2040`, and can be specified at the keymap or user level.
|
||||||
|
|
||||||
|
To ensure compatibility with the rp2040 bootloader, make sure this block is present in your `rules.mk`:
|
||||||
|
|
||||||
|
```make
|
||||||
|
# Bootloader selection
|
||||||
|
BOOTLOADER = rp2040
|
||||||
|
```
|
||||||
|
|
||||||
|
Compatible flashers:
|
||||||
|
|
||||||
|
* Any application able to copy a file from one place to another, such as _macOS Finder_ or _Windows Explorer_.
|
||||||
|
|
||||||
|
Flashing sequence:
|
||||||
|
|
||||||
|
1. Enter the bootloader using any of the following methods:
|
||||||
|
* Tap the `QK_BOOT` keycode
|
||||||
|
* Hold the `BOOTSEL` button on the PCB while plugin in the usb cable.
|
||||||
|
* Double-tap the `RESET` button on the PCB<sup>1</sup>.
|
||||||
|
2. Wait for the OS to detect the device
|
||||||
|
3. Copy the .uf2 file to the new USB disk
|
||||||
|
4. Wait for the keyboard to become available
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
CLI Flashing sequence:
|
||||||
|
|
||||||
|
1. Enter the bootloader using any of the following methods:
|
||||||
|
* Tap the `QK_BOOT` keycode
|
||||||
|
* Hold the `BOOTSEL` button on the PCB while plugin in the usb cable.
|
||||||
|
* Double-tap the `RESET` button on the PCB<sup>1</sup>.
|
||||||
|
2. Wait for the OS to detect the device
|
||||||
|
3. Flash via QMK CLI eg. `qmk flash --keyboard handwired/onekey/rpi_pico --keymap default`
|
||||||
|
4. Wait for the keyboard to become available
|
||||||
|
|
||||||
|
<sup>1</sup>: This works only if QMK was compiled with `RP2040_BOOTLOADER_DOUBLE_TAP_RESET` defined.
|
||||||
|
|
|
@ -5,7 +5,7 @@ ps2avr(GB) boards use an ATmega32A microcontroller and a different bootloader. I
|
||||||
General flashing sequence:
|
General flashing sequence:
|
||||||
|
|
||||||
1. Enter the bootloader using any of the following methods:
|
1. Enter the bootloader using any of the following methods:
|
||||||
* Tap the `RESET` keycode (may not work on all devices)
|
* Tap the `QK_BOOT` keycode (may not work on all devices)
|
||||||
* Hold the salt key while plugging the keyboard in (usually documented within keyboard readme)
|
* Hold the salt key while plugging the keyboard in (usually documented within keyboard readme)
|
||||||
2. Wait for the OS to detect the device
|
2. Wait for the OS to detect the device
|
||||||
3. Flash a .hex file
|
3. Flash a .hex file
|
||||||
|
|
|
@ -177,20 +177,25 @@ From here, you should have a working keyboard once you program a firmware.
|
||||||
|
|
||||||
Simple firmware can be created easily using the [Keyboard Firmware Builder](https://kbfirmware.com/) website. Recreate your layout using [Keyboard Layout Editor](https://www.keyboard-layout-editor.com), import it and recreate the matrix (if not already done as part of [planning the matrix](#planning-the-matrix).
|
Simple firmware can be created easily using the [Keyboard Firmware Builder](https://kbfirmware.com/) website. Recreate your layout using [Keyboard Layout Editor](https://www.keyboard-layout-editor.com), import it and recreate the matrix (if not already done as part of [planning the matrix](#planning-the-matrix).
|
||||||
|
|
||||||
Go through the rest of the tabs, assigning keys until you get to the last one where you can compile and download your firmware. The .hex file can be flashed straight onto your keyboard, and the .zip of source files can be modified for advanced functionality and compiled locally using the method described in [Building Your First Firmware](newbs_building_firmware?id=build-your-firmware).
|
Go through the rest of the tabs, assigning keys until you get to the last one where you can compile and download your firmware. The .hex file can be flashed straight onto your keyboard, or for advanced functionality, compiled locally after [Setting up Your Environment](newbs_getting_started.md).
|
||||||
|
|
||||||
The source given by Keyboard Firmware Builder is QMK, but is based on a version of QMK from early 2017. To compile the code from your .zip file in a modern version of QMK Firmware, you'll need to open the .zip and follow these instructions:
|
The source given by Keyboard Firmware Builder is QMK, but is based on a version of QMK from early 2017. To compile the firmware in a modern version of QMK Firmware, you'll need to export via the `Save Configuration` button, then run:
|
||||||
|
|
||||||
|
qmk import-kbfirmware /path/to/export.json
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ qmk import-kbfirmware ~/Downloads/gh62.json
|
||||||
|
Ψ Importing gh62.json.
|
||||||
|
|
||||||
|
⚠ Support here is basic - Consider using 'qmk new-keyboard' instead
|
||||||
|
Ψ Imported a new keyboard named gh62.
|
||||||
|
Ψ To start working on things, `cd` into keyboards/gh62,
|
||||||
|
Ψ or open the directory in your preferred text editor.
|
||||||
|
Ψ And build with qmk compile -kb gh62 -km default.
|
||||||
|
```
|
||||||
|
|
||||||
1. Extract the `kb` folder to `qmk_firmware/keyboards/handwired/`.
|
|
||||||
2. Open the extracted `kb` folder, then proceed to the `keymaps/default/` folder, and open `keymap.c`.
|
|
||||||
3. Locate and delete the `action_get_macro` code block:
|
|
||||||
```
|
|
||||||
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
|
|
||||||
...
|
|
||||||
return MACRO_NONE;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
4. Save and close `keymap.c`.
|
|
||||||
|
|
||||||
## Flashing the Firmware
|
## Flashing the Firmware
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,6 @@
|
||||||
* [スワップハンド](ja/feature_swap_hands.md)
|
* [スワップハンド](ja/feature_swap_hands.md)
|
||||||
* [タップダンス](ja/feature_tap_dance.md)
|
* [タップダンス](ja/feature_tap_dance.md)
|
||||||
* [タップホールド設定](ja/tap_hold.md)
|
* [タップホールド設定](ja/tap_hold.md)
|
||||||
* [ターミナル](ja/feature_terminal.md)
|
|
||||||
* [ユニコード](ja/feature_unicode.md)
|
* [ユニコード](ja/feature_unicode.md)
|
||||||
* [ユーザスペース](ja/feature_userspace.md)
|
* [ユーザスペース](ja/feature_userspace.md)
|
||||||
* [WPM 計算](ja/feature_wpm.md)
|
* [WPM 計算](ja/feature_wpm.md)
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
"layers": [
|
"layers": [
|
||||||
["KC_GRV","KC_1","KC_2","KC_3","KC_4","KC_5","KC_6","KC_7","KC_8","KC_9","KC_0","KC_MINS","KC_EQL","KC_GRV","KC_BSPC","KC_PGUP","KC_TAB","KC_Q","KC_W","KC_E","KC_R","KC_T","KC_Y","KC_U","KC_I","KC_O","KC_P","KC_LBRC","KC_RBRC","KC_BSLS","KC_PGDN","KC_CAPS","KC_A","KC_S","KC_D","KC_F","KC_G","KC_H","KC_J","KC_K","KC_L","KC_SCLN","KC_QUOT","KC_NUHS","KC_ENT","KC_LSFT","KC_NUBS","KC_Z","KC_X","KC_C","KC_V","KC_B","KC_N","KC_M","KC_COMM","KC_DOT","KC_SLSH","KC_RO","KC_RSFT","KC_UP","KC_LCTL","KC_LGUI","KC_LALT","KC_MHEN","KC_SPC","KC_SPC","KC_HENK","KC_RALT","KC_RCTL","MO(1)","KC_LEFT","KC_DOWN","KC_RIGHT"],
|
["KC_GRV","KC_1","KC_2","KC_3","KC_4","KC_5","KC_6","KC_7","KC_8","KC_9","KC_0","KC_MINS","KC_EQL","KC_GRV","KC_BSPC","KC_PGUP","KC_TAB","KC_Q","KC_W","KC_E","KC_R","KC_T","KC_Y","KC_U","KC_I","KC_O","KC_P","KC_LBRC","KC_RBRC","KC_BSLS","KC_PGDN","KC_CAPS","KC_A","KC_S","KC_D","KC_F","KC_G","KC_H","KC_J","KC_K","KC_L","KC_SCLN","KC_QUOT","KC_NUHS","KC_ENT","KC_LSFT","KC_NUBS","KC_Z","KC_X","KC_C","KC_V","KC_B","KC_N","KC_M","KC_COMM","KC_DOT","KC_SLSH","KC_RO","KC_RSFT","KC_UP","KC_LCTL","KC_LGUI","KC_LALT","KC_MHEN","KC_SPC","KC_SPC","KC_HENK","KC_RALT","KC_RCTL","MO(1)","KC_LEFT","KC_DOWN","KC_RIGHT"],
|
||||||
["KC_ESC","KC_F1","KC_F2","KC_F3","KC_F4","KC_F5","KC_F6","KC_F7","KC_F8","KC_F9","KC_F10","KC_F11","KC_F12","KC_TRNS","KC_DEL","BL_STEP","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","_______","KC_TRNS","KC_PSCR","KC_SLCK","KC_PAUS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(2)","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_PGUP","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(1)","KC_LEFT","KC_PGDN","KC_RGHT"],
|
["KC_ESC","KC_F1","KC_F2","KC_F3","KC_F4","KC_F5","KC_F6","KC_F7","KC_F8","KC_F9","KC_F10","KC_F11","KC_F12","KC_TRNS","KC_DEL","BL_STEP","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","_______","KC_TRNS","KC_PSCR","KC_SLCK","KC_PAUS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(2)","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_PGUP","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(1)","KC_LEFT","KC_PGDN","KC_RGHT"],
|
||||||
["KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","RESET","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(2)","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(1)","KC_TRNS","KC_TRNS","KC_TRNS"]
|
["KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","QK_BOOT","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(2)","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(1)","KC_TRNS","KC_TRNS","KC_TRNS"]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
@ -108,7 +108,7 @@ QMK での全ての利用可能な設定にはデフォルトがあります。
|
||||||
* デバイスの USB 経由の最大電力(mA) を設定します (デフォルト: 500)
|
* デバイスの USB 経由の最大電力(mA) を設定します (デフォルト: 500)
|
||||||
* `#define USB_POLLING_INTERVAL_MS 10`
|
* `#define USB_POLLING_INTERVAL_MS 10`
|
||||||
* キーボード、マウス および 共有 (NKRO/メディアキー) インタフェースのための USB ポーリングレートをミリ秒で設定します
|
* キーボード、マウス および 共有 (NKRO/メディアキー) インタフェースのための USB ポーリングレートをミリ秒で設定します
|
||||||
* `#define USB_SUSPEND_WAKEUP_DELAY 200`
|
* `#define USB_SUSPEND_WAKEUP_DELAY 0`
|
||||||
* ウェイクアップパケットを送信した後で一時停止するミリ秒を設定します
|
* ウェイクアップパケットを送信した後で一時停止するミリ秒を設定します
|
||||||
* `#define F_SCL 100000L`
|
* `#define F_SCL 100000L`
|
||||||
* I2C を使用するキーボードのための I2C クロックレート速度を設定します。デフォルトは `400000L` ですが、`split_common` を使っているキーボードは別でデフォルトは `100000L` です。
|
* I2C を使用するキーボードのための I2C クロックレート速度を設定します。デフォルトは `400000L` ですが、`split_common` を使っているキーボードは別でデフォルトは `100000L` です。
|
||||||
|
@ -144,7 +144,7 @@ QMK での全ての利用可能な設定にはデフォルトがあります。
|
||||||
## 設定可能な挙動 :id=behaviors-that-can-be-configured
|
## 設定可能な挙動 :id=behaviors-that-can-be-configured
|
||||||
|
|
||||||
* `#define TAPPING_TERM 200`
|
* `#define TAPPING_TERM 200`
|
||||||
* タップがホールドになるまでの時間。500以上に設定された場合、タップ期間中にタップされたキーもホールドになります。(訳注: PERMISSIVE_HOLDも参照)
|
* タップがホールドになるまでの時間。
|
||||||
* `#define TAPPING_TERM_PER_KEY`
|
* `#define TAPPING_TERM_PER_KEY`
|
||||||
* キーごとの `TAPPING_TERM` 設定の処理を有効にします
|
* キーごとの `TAPPING_TERM` 設定の処理を有効にします
|
||||||
* `#define RETRO_TAPPING`
|
* `#define RETRO_TAPPING`
|
||||||
|
@ -181,8 +181,6 @@ QMK での全ての利用可能な設定にはデフォルトがあります。
|
||||||
* ワンショットがタイムアウトするまでの時間
|
* ワンショットがタイムアウトするまでの時間
|
||||||
* `#define ONESHOT_TAP_TOGGLE 2`
|
* `#define ONESHOT_TAP_TOGGLE 2`
|
||||||
* ワンショットトグルが引き起こされるまでのタップ数
|
* ワンショットトグルが引き起こされるまでのタップ数
|
||||||
* `#define QMK_KEYS_PER_SCAN 4`
|
|
||||||
* 走査ごとに1つ以上のキーを送信できるようにします。デフォルトでは、走査ごとに `process_record()` 経由で1つのキーイベントのみが送信されます。これはほとんどのタイピングにほとんど影響しませんが、多くのコードを入力しているか、走査レートが最初から遅い場合、キーイベントの処理に多少の遅延が生じる可能性があります。それぞれのプレスとリリースは別のイベントです。スキャン時間が 1ms 程度のキーボードの場合、とても高速なタイピストでさえ、実際にキーボードから数 ms 以上の遅延を発生させるのに必要な 500 キーストロークを1秒間に生成することはないでしょう。しかし、3~4ms の走査時間でコードを入力している場合はどうでしょうか?おそらくこれが必要です。
|
|
||||||
* `#define COMBO_COUNT 2`
|
* `#define COMBO_COUNT 2`
|
||||||
* [コンボ](ja/feature_combo.md)機能で使っているコンボの数にこれを設定します。
|
* [コンボ](ja/feature_combo.md)機能で使っているコンボの数にこれを設定します。
|
||||||
* `#define COMBO_TERM 200`
|
* `#define COMBO_TERM 200`
|
||||||
|
@ -196,8 +194,6 @@ QMK での全ての利用可能な設定にはデフォルトがあります。
|
||||||
|
|
||||||
* `#define RGB_DI_PIN D7`
|
* `#define RGB_DI_PIN D7`
|
||||||
* WS2812 の DI 端子につなぐピン
|
* WS2812 の DI 端子につなぐピン
|
||||||
* `#define RGBLIGHT_ANIMATIONS`
|
|
||||||
* RGB アニメーションを実行します
|
|
||||||
* `#define RGBLIGHT_LAYERS`
|
* `#define RGBLIGHT_LAYERS`
|
||||||
* オンとオフを切り替えることができる [ライトレイヤー](ja/feature_rgblight.md?id=lighting-layers) を定義できます。現在のキーボードレイヤーまたは Caps Lock 状態を表示するのに最適です。
|
* オンとオフを切り替えることができる [ライトレイヤー](ja/feature_rgblight.md?id=lighting-layers) を定義できます。現在のキーボードレイヤーまたは Caps Lock 状態を表示するのに最適です。
|
||||||
* `#define RGBLIGHT_MAX_LAYERS`
|
* `#define RGBLIGHT_MAX_LAYERS`
|
||||||
|
|
|
@ -87,17 +87,17 @@ void matrix_init(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t matrix_scan(void) {
|
uint8_t matrix_scan(void) {
|
||||||
bool matrix_has_changed = false;
|
bool changed = false;
|
||||||
|
|
||||||
// TODO: ここにマトリックススキャンルーチンを追加します
|
// TODO: ここにマトリックススキャンルーチンを追加します
|
||||||
|
|
||||||
// ハードウェアによるデバウンスがない場合 - 設定されているデバウンスルーチンを使用します
|
// ハードウェアによるデバウンスがない場合 - 設定されているデバウンスルーチンを使用します
|
||||||
debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
|
changed = debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
|
||||||
|
|
||||||
// 正しいキーボード動作のためにこれを呼び出す*必要があります*
|
// 正しいキーボード動作のためにこれを呼び出す*必要があります*
|
||||||
matrix_scan_quantum();
|
matrix_scan_quantum();
|
||||||
|
|
||||||
return matrix_has_changed;
|
return changed;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
あなたはおそらくキーボードを「文鎮化」したくないでしょう。文鎮化するとファームウェアを書き換えられないようになります。リスクがあまりに高い(そしてそうでないかもしれない)ものの一部のリストを示します。
|
あなたはおそらくキーボードを「文鎮化」したくないでしょう。文鎮化するとファームウェアを書き換えられないようになります。リスクがあまりに高い(そしてそうでないかもしれない)ものの一部のリストを示します。
|
||||||
|
|
||||||
- キーボードマップに RESET が含まれない場合、DFU モードに入るには、PCB のリセットボタンを押す必要があります。底部のネジを外す必要があります。
|
- キーボードマップに QK_BOOT が含まれない場合、DFU モードに入るには、PCB のリセットボタンを押す必要があります。底部のネジを外す必要があります。
|
||||||
- tmk_core / common にあるファイルを触るとキーボードが操作不能になるかもしれません。
|
- tmk_core / common にあるファイルを触るとキーボードが操作不能になるかもしれません。
|
||||||
- .hex ファイルが大きすぎると問題を引き起こします; `make dfu` コマンドはブロックを削除し、サイズを検査し(おっと、間違った順序です!)、エラーを出力し、
|
- .hex ファイルが大きすぎると問題を引き起こします; `make dfu` コマンドはブロックを削除し、サイズを検査し(おっと、間違った順序です!)、エラーを出力し、
|
||||||
キーボードへの書き込みに失敗し、DFU モードのままになります。
|
キーボードへの書き込みに失敗し、DFU モードのままになります。
|
||||||
|
|
|
@ -23,7 +23,7 @@ Timer 3:
|
||||||
|
|
||||||
```
|
```
|
||||||
STARTUP_SONG // キーボードの起動時に再生 (audio.c)
|
STARTUP_SONG // キーボードの起動時に再生 (audio.c)
|
||||||
GOODBYE_SONG // RESET キーを押すと再生 (quantum.c)
|
GOODBYE_SONG // QK_BOOT キーを押すと再生 (quantum.c)
|
||||||
AG_NORM_SONG // AG_NORM キーを押すと再生 (quantum.c)
|
AG_NORM_SONG // AG_NORM キーを押すと再生 (quantum.c)
|
||||||
AG_SWAP_SONG // AG_SWAP キーを押すと再生 (quantum.c)
|
AG_SWAP_SONG // AG_SWAP キーを押すと再生 (quantum.c)
|
||||||
CG_NORM_SONG // CG_NORM キーを押すと再生 (quantum.c)
|
CG_NORM_SONG // CG_NORM キーを押すと再生 (quantum.c)
|
||||||
|
|
|
@ -40,6 +40,7 @@ QMK はその場で作られた一時的なマクロをサポートします。
|
||||||
| `DYNAMIC_MACRO_SIZE` | 128 | 動的マクロが使用できるメモリ量を設定します。これは限られたリソースであり、コントローラに依存します。 |
|
| `DYNAMIC_MACRO_SIZE` | 128 | 動的マクロが使用できるメモリ量を設定します。これは限られたリソースであり、コントローラに依存します。 |
|
||||||
| `DYNAMIC_MACRO_USER_CALL` | *定義なし* | これを定義すると、ユーザの `keymap.c` ファイルを使ってマクロが起動されます。 |
|
| `DYNAMIC_MACRO_USER_CALL` | *定義なし* | これを定義すると、ユーザの `keymap.c` ファイルを使ってマクロが起動されます。 |
|
||||||
| `DYNAMIC_MACRO_NO_NESTING` | *定義なし* | これを定義すると、別のマクロからマクロを呼び出す(入れ子になったマクロ)機能を無効にします。 |
|
| `DYNAMIC_MACRO_NO_NESTING` | *定義なし* | これを定義すると、別のマクロからマクロを呼び出す(入れ子になったマクロ)機能を無効にします。 |
|
||||||
|
| `DYNAMIC_MACRO_DELAY` | *定義なし* | 各キーを送信する時の待ち時間(ms単位)を設定します。 |
|
||||||
|
|
||||||
|
|
||||||
記録中にキーを押すたびに LED が点滅し始めた場合は、マクロバッファにマクロを入れるスペースがもう無いことを意味します。マクロを入れるには、他のマクロ(それらは同じバッファを共有します)を短くするか、`config.h` に `DYNAMIC_MACRO_SIZE` 定義を追加することでバッファを増やします(デフォルト値: 128; ヘッダ内のコメントを読んでください)。
|
記録中にキーを押すたびに LED が点滅し始めた場合は、マクロバッファにマクロを入れるスペースがもう無いことを意味します。マクロを入れるには、他のマクロ(それらは同じバッファを共有します)を短くするか、`config.h` に `DYNAMIC_MACRO_SIZE` 定義を追加することでバッファを増やします(デフォルト値: 128; ヘッダ内のコメントを読んでください)。
|
||||||
|
|
|
@ -77,7 +77,7 @@ bool process_steno_user(uint16_t keycode, keyrecord_t *record) { return true; }
|
||||||
この関数はキーが押されるとキーが処理される前に呼び出されます。キーコードは `QK_STENO_BOLT`、`QK_STENO_GEMINI` あるいは `STN_*` キー値のいずれかでなければなりません。
|
この関数はキーが押されるとキーが処理される前に呼び出されます。キーコードは `QK_STENO_BOLT`、`QK_STENO_GEMINI` あるいは `STN_*` キー値のいずれかでなければなりません。
|
||||||
|
|
||||||
```c
|
```c
|
||||||
bool postprocess_steno_user(uint16_t keycode, keyrecord_t *record, steno_mode_t mode, uint8_t chord[6], int8_t pressed);
|
bool post_process_steno_user(uint16_t keycode, keyrecord_t *record, steno_mode_t mode, uint8_t chord[6], int8_t pressed);
|
||||||
```
|
```
|
||||||
|
|
||||||
この関数はキーが処理された後、ただしコードを送信するかどうかを決める前に呼び出されます。`IS_PRESSED(record->event)` が false で、`pressed` が 0 または 1 の場合は、コードはまもなく送信されますが、まだ送信されてはいません。ここが速記コードあるいはキーのライブ表示などのフックを配置する場所です。
|
この関数はキーが処理された後、ただしコードを送信するかどうかを決める前に呼び出されます。`IS_PRESSED(record->event)` が false で、`pressed` が 0 または 1 の場合は、コードはまもなく送信されますが、まだ送信されてはいません。ここが速記コードあるいはキーのライブ表示などのフックを配置する場所です。
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
|
|
||||||
* `ACTION_TAP_DANCE_DOUBLE(kc1, kc2)`: 1回タップすると `kc1` キーコードを送信し、2回タップすると `kc2` キーコードを送信します。キーを押し続けているときは、適切なキーコードが登録されます: キーを押し続けた場合は `kc1`、一度タップしてから続けてもう一度キーを押してそのまま押し続けたときは、 `kc2` が登録されます。
|
* `ACTION_TAP_DANCE_DOUBLE(kc1, kc2)`: 1回タップすると `kc1` キーコードを送信し、2回タップすると `kc2` キーコードを送信します。キーを押し続けているときは、適切なキーコードが登録されます: キーを押し続けた場合は `kc1`、一度タップしてから続けてもう一度キーを押してそのまま押し続けたときは、 `kc2` が登録されます。
|
||||||
* `ACTION_TAP_DANCE_LAYER_MOVE(kc, layer)`: 1回タップすると `kc` キーコードが送信され、2回タップすると `layer` レイヤーに移動します(これは `TO` レイヤーキーコードのように機能します)。
|
* `ACTION_TAP_DANCE_LAYER_MOVE(kc, layer)`: 1回タップすると `kc` キーコードが送信され、2回タップすると `layer` レイヤーに移動します(これは `TO` レイヤーキーコードのように機能します)。
|
||||||
* この機能は `ACTION_TAP_DANCE_DUAL_ROLE` と同じですが、機能が明確になるように関数名を変更しました。どちらの関数名でも実行できます。
|
|
||||||
* `ACTION_TAP_DANCE_LAYER_TOGGLE(kc, layer)`: 1回タップすると `kc` キーコードが送信され、2回タップすると `layer` の状態をトグルします(これは `TG` レイヤーキーコードのように機能します)。
|
* `ACTION_TAP_DANCE_LAYER_TOGGLE(kc, layer)`: 1回タップすると `kc` キーコードが送信され、2回タップすると `layer` の状態をトグルします(これは `TG` レイヤーキーコードのように機能します)。
|
||||||
* `ACTION_TAP_DANCE_FN(fn)`: ユーザーキーマップに定義した指定の関数が呼び出されます。タップダンス実行の回数分タップすると、最後の時点で呼び出されます。
|
* `ACTION_TAP_DANCE_FN(fn)`: ユーザーキーマップに定義した指定の関数が呼び出されます。タップダンス実行の回数分タップすると、最後の時点で呼び出されます。
|
||||||
* `ACTION_TAP_DANCE_FN_ADVANCED(on_each_tap_fn, on_dance_finished_fn, on_dance_reset_fn)`: タップする度にユーザーキーマップに定義した最初の関数が呼び出されます。タップダンスの実行が終わった時点で2番目の関数が呼び出され、タップダンスの実行をリセットするときに最後の関数が呼び出されます。
|
* `ACTION_TAP_DANCE_FN_ADVANCED(on_each_tap_fn, on_dance_finished_fn, on_dance_reset_fn)`: タップする度にユーザーキーマップに定義した最初の関数が呼び出されます。タップダンスの実行が終わった時点で2番目の関数が呼び出され、タップダンスの実行をリセットするときに最後の関数が呼び出されます。
|
||||||
|
|
|
@ -1,112 +0,0 @@
|
||||||
# ターミナル
|
|
||||||
|
|
||||||
<!---
|
|
||||||
original document: 0.8.147:docs/feature_terminal.md
|
|
||||||
git diff 0.8.147 HEAD -- docs/feature_terminal.md | cat
|
|
||||||
-->
|
|
||||||
|
|
||||||
> この機能は現在のところ*巨大*であり、おそらく大量のメモリを搭載したキーボード、または楽しみのためにのみ配置する必要があります。
|
|
||||||
|
|
||||||
ターミナル機能はテキストエディタを介してキーストロークで通信するように設計されたコマンドラインのようなインタフェースです。エディタで自動インデント機能をオフにすることは有益です。
|
|
||||||
|
|
||||||
有効にするには、以下を `rules.mk` または `Makefile` に貼り付けます:
|
|
||||||
|
|
||||||
TERMINAL_ENABLE = yes
|
|
||||||
|
|
||||||
そして、オンまたはオフにするために、`TERM_ON` および `TERM_OFF` キーコードを使います。
|
|
||||||
|
|
||||||
有効な場合、`> ` プロンプトが現れ、ここでコマンドやバックスペース(オーディオが有効な場合は、先頭に到達するとベルが鳴ります)を入力することができ、エンターを入力するとコマンドを送信します。矢印キーは現在のところ無効なため、混乱することはありません。マウスでカーソルを移動することはお勧めしません。
|
|
||||||
|
|
||||||
`#define TERMINAL_HELP` は、このページでは実際には必要のない他の出力ヘルパーを有効にします。
|
|
||||||
|
|
||||||
"上矢印" および "下矢印" により、過去に入力した5つのコマンドを順に切り替えることができます。
|
|
||||||
|
|
||||||
## 今後のアイデア
|
|
||||||
|
|
||||||
* キーボード/ユーザ拡張可能なコマンド
|
|
||||||
* より小さなフットプリント
|
|
||||||
* 矢印キーのサポート
|
|
||||||
* コマンド履歴 - 完了
|
|
||||||
* SD カードのサポート
|
|
||||||
* バッファディスプレイのための LCD サポート
|
|
||||||
* キーコード -> 名称の対応表
|
|
||||||
* レイヤー状態
|
|
||||||
* *アナログ/デジタル ポートの読み込み/書き込み*
|
|
||||||
* RGB モード関連機能
|
|
||||||
* マクロ定義
|
|
||||||
* EEPROM の読み込み/書き込み
|
|
||||||
* オーディオ制御
|
|
||||||
|
|
||||||
## 現在のコマンド
|
|
||||||
|
|
||||||
### `about`
|
|
||||||
|
|
||||||
現在の QMK のバージョンとビルドした日の出力:
|
|
||||||
|
|
||||||
```
|
|
||||||
> about
|
|
||||||
QMK Firmware
|
|
||||||
v0.5.115-7-g80ed73-dirty
|
|
||||||
Built: 2017-08-29-20:24:44
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### `print-buffer`
|
|
||||||
|
|
||||||
最後に入力した5つのコマンドの出力
|
|
||||||
|
|
||||||
```
|
|
||||||
> print-buffer
|
|
||||||
0. print-buffer
|
|
||||||
1. help
|
|
||||||
2. about
|
|
||||||
3. keymap 0
|
|
||||||
4. help
|
|
||||||
5. flush-buffer
|
|
||||||
```
|
|
||||||
|
|
||||||
### `flush-buffer`
|
|
||||||
|
|
||||||
コマンドバッファをクリア
|
|
||||||
```
|
|
||||||
> flush-buffer
|
|
||||||
Buffer cleared!
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### `help`
|
|
||||||
|
|
||||||
|
|
||||||
利用可能なコマンドの出力:
|
|
||||||
|
|
||||||
```
|
|
||||||
> help
|
|
||||||
commands available:
|
|
||||||
about help keycode keymap exit print-buffer flush-buffer
|
|
||||||
```
|
|
||||||
|
|
||||||
### `keycode <layer> <row> <col>`
|
|
||||||
|
|
||||||
特定のレイヤー、行および列のキーコード値の出力:
|
|
||||||
|
|
||||||
```
|
|
||||||
> keycode 0 1 0
|
|
||||||
0x29 (41)
|
|
||||||
```
|
|
||||||
|
|
||||||
### `keymap <layer>`
|
|
||||||
|
|
||||||
特定のレイヤーの全てのキーマップの出力
|
|
||||||
|
|
||||||
```
|
|
||||||
> keymap 0
|
|
||||||
0x002b, 0x0014, 0x001a, 0x0008, 0x0015, 0x0017, 0x001c, 0x0018, 0x000c, 0x0012, 0x0013, 0x002a,
|
|
||||||
0x0029, 0x0004, 0x0016, 0x0007, 0x0009, 0x000a, 0x000b, 0x000d, 0x000e, 0x000f, 0x0033, 0x0034,
|
|
||||||
0x00e1, 0x001d, 0x001b, 0x0006, 0x0019, 0x0005, 0x0011, 0x0010, 0x0036, 0x0037, 0x0038, 0x0028,
|
|
||||||
0x5cd6, 0x00e0, 0x00e2, 0x00e3, 0x5cd4, 0x002c, 0x002c, 0x5cd5, 0x0050, 0x0051, 0x0052, 0x004f,
|
|
||||||
>
|
|
||||||
```
|
|
||||||
|
|
||||||
### `exit`
|
|
||||||
|
|
||||||
ターミナルの終了 - `TERM_OFF` と同じ。
|
|
|
@ -34,7 +34,7 @@ BOOTLOADER = atmel-dfu
|
||||||
|
|
||||||
書き込み手順:
|
書き込み手順:
|
||||||
|
|
||||||
1. `RESET` キーコードを押すか、RESET ボタンをタップします(または RST を GND にショートします)。
|
1. `QK_BOOT` キーコードを押すか、RESET ボタンをタップします(または RST を GND にショートします)。
|
||||||
2. OS がデバイスを検知するのを待ちます。
|
2. OS がデバイスを検知するのを待ちます。
|
||||||
3. メモリを消去します(自動的に実行されるかもしれません)
|
3. メモリを消去します(自動的に実行されるかもしれません)
|
||||||
4. .hex ファイルを書き込みます
|
4. .hex ファイルを書き込みます
|
||||||
|
@ -94,7 +94,7 @@ BOOTLOADER = caterina
|
||||||
|
|
||||||
書き込み手順:
|
書き込み手順:
|
||||||
|
|
||||||
1. `RESET` キーコードを押すか、RST をすばやく GND にショートします (入力後7秒で書き込みます)
|
1. `QK_BOOT` キーコードを押すか、RST をすばやく GND にショートします (入力後7秒で書き込みます)
|
||||||
2. OS がデバイスを検知するのを待ちます。
|
2. OS がデバイスを検知するのを待ちます。
|
||||||
3. .hex ファイルを書き込みます
|
3. .hex ファイルを書き込みます
|
||||||
4. デバイスが自動的にリセットされるのを待ちます
|
4. デバイスが自動的にリセットされるのを待ちます
|
||||||
|
@ -141,7 +141,7 @@ BOOTLOADER = halfkay
|
||||||
|
|
||||||
書き込み手順:
|
書き込み手順:
|
||||||
|
|
||||||
1. `RESET` キーコードを押すか、RST をすばやく GND にショートします (入力後7秒で書き込みます)
|
1. `QK_BOOT` キーコードを押すか、RST をすばやく GND にショートします (入力後7秒で書き込みます)
|
||||||
2. OS がデバイスを検知するのを待ちます。
|
2. OS がデバイスを検知するのを待ちます。
|
||||||
3. .hex ファイルを書き込みます
|
3. .hex ファイルを書き込みます
|
||||||
4. デバイスをアプリケーションモードにリセットします(自動的に実行されるかもしれません)
|
4. デバイスをアプリケーションモードにリセットします(自動的に実行されるかもしれません)
|
||||||
|
@ -172,7 +172,7 @@ BOOTLOADER = USBasp
|
||||||
|
|
||||||
書き込み手順:
|
書き込み手順:
|
||||||
|
|
||||||
1. `RESET` キーコードを押すか、RST を GND にすばやくショートしながら、ブートピンを GND にショートしたままにします。
|
1. `QK_BOOT` キーコードを押すか、RST を GND にすばやくショートしながら、ブートピンを GND にショートしたままにします。
|
||||||
2. OS がデバイスを検知するのを待ちます。
|
2. OS がデバイスを検知するのを待ちます。
|
||||||
3. .hex ファイルを書き込みます
|
3. .hex ファイルを書き込みます
|
||||||
4. デバイスをアプリケーションモードにリセットします(自動的に実行されるかもしれません)
|
4. デバイスをアプリケーションモードにリセットします(自動的に実行されるかもしれません)
|
||||||
|
@ -203,7 +203,7 @@ BOOTLOADER = bootloadHID
|
||||||
書き込み手順:
|
書き込み手順:
|
||||||
|
|
||||||
1. 以下のいずれかの方法を使ってブートローダに入ります:
|
1. 以下のいずれかの方法を使ってブートローダに入ります:
|
||||||
* `RESET` キーコードをタップします (全てのデバイスでは動作しないかもしれません)
|
* `QK_BOOT` キーコードをタップします (全てのデバイスでは動作しないかもしれません)
|
||||||
* キーボードを接続しながらソルトキーを押し続けます (通常はキーボードの readme に書かれています)
|
* キーボードを接続しながらソルトキーを押し続けます (通常はキーボードの readme に書かれています)
|
||||||
2. OS がデバイスを検知するのを待ちます。
|
2. OS がデバイスを検知するのを待ちます。
|
||||||
3. .hex ファイルを書き込みます
|
3. .hex ファイルを書き込みます
|
||||||
|
@ -227,7 +227,7 @@ BOOTLOADER = bootloadHID
|
||||||
書き込み手順:
|
書き込み手順:
|
||||||
|
|
||||||
1. 以下のいずれかの方法を使ってブートローダに入ります:
|
1. 以下のいずれかの方法を使ってブートローダに入ります:
|
||||||
* `RESET` キーコードをタップします (STM32F042 デバイスでは動作しないかもしれません)
|
* `QK_BOOT` キーコードをタップします (STM32F042 デバイスでは動作しないかもしれません)
|
||||||
* リセット回路が存在する場合、RESET ボタンをタップします
|
* リセット回路が存在する場合、RESET ボタンをタップします
|
||||||
* それ以外の場合は、(BOOT0 ボタンあるいはブリッジ経由で)BOOT0 を VCC にブリッジし、(REEST ボタンあるいはブリッジ経由で)RESET を GND にショートし、BOOT0 ブリッジを放す必要があります。
|
* それ以外の場合は、(BOOT0 ボタンあるいはブリッジ経由で)BOOT0 を VCC にブリッジし、(REEST ボタンあるいはブリッジ経由で)RESET を GND にショートし、BOOT0 ブリッジを放す必要があります。
|
||||||
2. OS がデバイスを検知するのを待ちます。
|
2. OS がデバイスを検知するのを待ちます。
|
||||||
|
|
|
@ -10,7 +10,7 @@ ps2avr(GB) キーボードは ATmega32A マイクロコントローラを使い
|
||||||
一般的な書き込みシーケンス:
|
一般的な書き込みシーケンス:
|
||||||
|
|
||||||
1. 以下のいずれかの方法を使ってブートローダに入ります:
|
1. 以下のいずれかの方法を使ってブートローダに入ります:
|
||||||
* `RESET` キーコードをタップします (全てのデバイスでは動作しないかもしれません)
|
* `QK_BOOT` キーコードをタップします (全てのデバイスでは動作しないかもしれません)
|
||||||
* ソルトキーを押し続けながらキーボードを接続します (通常はキーボードの readme に書かれています)
|
* ソルトキーを押し続けながらキーボードを接続します (通常はキーボードの readme に書かれています)
|
||||||
2. OS がデバイスを検知するのを待ちます。
|
2. OS がデバイスを検知するのを待ちます。
|
||||||
3. .hex ファイルを書き込みます
|
3. .hex ファイルを書き込みます
|
||||||
|
|
|
@ -228,10 +228,10 @@
|
||||||
[Quantum キーコード](ja/quantum_keycodes.md#qmk-keycodes) も見てください。
|
[Quantum キーコード](ja/quantum_keycodes.md#qmk-keycodes) も見てください。
|
||||||
|
|
||||||
|キー |エイリアス |説明 |
|
|キー |エイリアス |説明 |
|
||||||
|--------------|-----------|---------------------------------------------------------|
|
|-----------------|---------|---------------------------------------------------------|
|
||||||
|`RESET` | |ファームウエア書き込みのためにキーボードをブートローダーモードにします |
|
|`QK_BOOTLOADER` |`QK_BOOT`|ファームウエア書き込みのためにキーボードをブートローダーモードにします |
|
||||||
|`DEBUG` | |デバッグモードを切り替えます |
|
|`QK_DEBUG_TOGGLE`|`DB_TOGG`|デバッグモードを切り替えます |
|
||||||
|`EEPROM_RESET`|`EEP_RST` |キーボードの EEPROM (不揮発メモリ) を再初期化します |
|
|`QK_CLEAR_EEPROM`|`EE_CLR` |キーボードの EEPROM (不揮発メモリ) を再初期化します |
|
||||||
|
|
||||||
## オーディオキー :id=audio-keys
|
## オーディオキー :id=audio-keys
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ quantum 内の全てのキーコードは `0x0000` と `0xFFFF` の間の数値
|
||||||
## QMK キーコード :id=qmk-keycodes
|
## QMK キーコード :id=qmk-keycodes
|
||||||
|
|
||||||
| キー | エイリアス | 説明 |
|
| キー | エイリアス | 説明 |
|
||||||
|----------------|------------|--------------------------------------------------------|
|
|-----------------|---------|--------------------------------------------------------|
|
||||||
| `RESET` | | 書き込みのために、キーボードを bootloader モードにする |
|
|`QK_BOOTLOADER` |`QK_BOOT`| 書き込みのために、キーボードを bootloader モードにする |
|
||||||
| `DEBUG` | | デバッグモードの切り替え |
|
|`QK_DEBUG_TOGGLE`|`DB_TOGG`| デバッグモードの切り替え |
|
||||||
| `EEPROM_RESET` | `EEP_RST` | キーボードの EEPROM (永続化メモリ) を再初期化する |
|
|`QK_CLEAR_EEPROM`|`EE_CLR` | キーボードの EEPROM (永続化メモリ) を再初期化する |
|
||||||
|
|
|
@ -161,7 +161,6 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||||
* [`bool process_combo(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_combo.c#L115)
|
* [`bool process_combo(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_combo.c#L115)
|
||||||
* [`bool process_printer(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_printer.c#L77)
|
* [`bool process_printer(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_printer.c#L77)
|
||||||
* [`bool process_auto_shift(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_auto_shift.c#L94)
|
* [`bool process_auto_shift(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_auto_shift.c#L94)
|
||||||
* [`bool process_terminal(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_terminal.c#L264)
|
|
||||||
* [Quantum 固有のキーコードを識別して処理する](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/quantum.c#L291)
|
* [Quantum 固有のキーコードを識別して処理する](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/quantum.c#L291)
|
||||||
|
|
||||||
この一連のイベントの中の任意のステップで (`process_record_kb()` のような)関数は `false` を返して、以降の処理を停止することができます。
|
この一連のイベントの中の任意のステップで (`process_record_kb()` のような)関数は `false` を返して、以降の処理を停止することができます。
|
||||||
|
|
|
@ -219,13 +219,13 @@ See also: [Basic Keycodes](keycodes_basic.md)
|
||||||
|
|
||||||
See also: [Quantum Keycodes](quantum_keycodes.md#qmk-keycodes)
|
See also: [Quantum Keycodes](quantum_keycodes.md#qmk-keycodes)
|
||||||
|
|
||||||
|Key |Aliases |Description |
|
|Key |Aliases |Description |
|
||||||
|-----------------|---------|---------------------------------------------------------------------------------|
|
|-----------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
|`QK_BOOTLOADER` |`QK_BOOT`|Put the keyboard into bootloader mode for flashing |
|
|`QK_BOOTLOADER` |`QK_BOOT`|Put the keyboard into bootloader mode for flashing |
|
||||||
|`QK_DEBUG_TOGGLE`|`DB_TOGG`|Toggle debug mode |
|
|`QK_DEBUG_TOGGLE`|`DB_TOGG`|Toggle debug mode |
|
||||||
|`QK_CLEAR_EEPROM`|`EE_CLR` |Reinitializes the keyboard's EEPROM (persistent memory) |
|
|`QK_CLEAR_EEPROM`|`EE_CLR` |Reinitializes the keyboard's EEPROM (persistent memory) |
|
||||||
|`QK_MAKE` | |Sends `qmk compile -kb (keyboard) -km (keymap)`, or `qmk flash` if shift is held |
|
|`QK_MAKE` | |Sends `qmk compile -kb (keyboard) -km (keymap)`, or `qmk flash` if shift is held. Puts keyboard into bootloader mode if shift & control are held |
|
||||||
|`QK_REBOOT` |`QK_RBT` |Resets the keyboard. Does not load the bootloader |
|
|`QK_REBOOT` |`QK_RBT` |Resets the keyboard. Does not load the bootloader |
|
||||||
|
|
||||||
## Audio Keys :id=audio-keys
|
## Audio Keys :id=audio-keys
|
||||||
|
|
||||||
|
@ -337,6 +337,9 @@ See also: [Magic Keycodes](keycodes_magic.md)
|
||||||
|`MAGIC_SWAP_CONTROL_CAPSLOCK` |`CL_SWAP`|Swap Caps Lock and Left Control |
|
|`MAGIC_SWAP_CONTROL_CAPSLOCK` |`CL_SWAP`|Swap Caps Lock and Left Control |
|
||||||
|`MAGIC_UNSWAP_CONTROL_CAPSLOCK` |`CL_NORM`|Unswap Caps Lock and Left Control |
|
|`MAGIC_UNSWAP_CONTROL_CAPSLOCK` |`CL_NORM`|Unswap Caps Lock and Left Control |
|
||||||
|`MAGIC_TOGGLE_CONTROL_CAPSLOCK` |`CL_TOGG`|Toggle Caps Lock and Left Control swap |
|
|`MAGIC_TOGGLE_CONTROL_CAPSLOCK` |`CL_TOGG`|Toggle Caps Lock and Left Control swap |
|
||||||
|
|`MAGIC_SWAP_ESCAPE_CAPSLOCK` |`EC_SWAP`|Swap Caps Lock and Escape |
|
||||||
|
|`MAGIC_UNSWAP_ESCAPE_CAPSLOCK` |`EC_NORM`|Unswap Caps Lock and Escape |
|
||||||
|
|`MAGIC_TOGGLE_ESCAPE_CAPSLOCK` |`EC_TOGG`|Toggle Caps Lock and Escape swap |
|
||||||
|`MAGIC_CAPSLOCK_TO_CONTROL` |`CL_CTRL`|Treat Caps Lock as Control |
|
|`MAGIC_CAPSLOCK_TO_CONTROL` |`CL_CTRL`|Treat Caps Lock as Control |
|
||||||
|`MAGIC_UNCAPSLOCK_TO_CONTROL` |`CL_CAPS`|Stop treating Caps Lock as Control |
|
|`MAGIC_UNCAPSLOCK_TO_CONTROL` |`CL_CAPS`|Stop treating Caps Lock as Control |
|
||||||
|`MAGIC_SWAP_LCTL_LGUI` |`LCG_SWP`|Swap Left Control and GUI |
|
|`MAGIC_SWAP_LCTL_LGUI` |`LCG_SWP`|Swap Left Control and GUI |
|
||||||
|
|
|
@ -7,6 +7,9 @@
|
||||||
|`MAGIC_SWAP_CONTROL_CAPSLOCK` |`CL_SWAP`|Swap Caps Lock and Left Control |
|
|`MAGIC_SWAP_CONTROL_CAPSLOCK` |`CL_SWAP`|Swap Caps Lock and Left Control |
|
||||||
|`MAGIC_UNSWAP_CONTROL_CAPSLOCK` |`CL_NORM`|Unswap Caps Lock and Left Control |
|
|`MAGIC_UNSWAP_CONTROL_CAPSLOCK` |`CL_NORM`|Unswap Caps Lock and Left Control |
|
||||||
|`MAGIC_TOGGLE_CONTROL_CAPSLOCK` |`CL_TOGG`|Toggle Caps Lock and Left Control swap |
|
|`MAGIC_TOGGLE_CONTROL_CAPSLOCK` |`CL_TOGG`|Toggle Caps Lock and Left Control swap |
|
||||||
|
|`MAGIC_SWAP_ESCAPE_CAPSLOCK` |`EC_SWAP`|Swap Caps Lock and Escape |
|
||||||
|
|`MAGIC_UNSWAP_ESCAPE_CAPSLOCK` |`EC_NORM`|Unswap Caps Lock and Escape |
|
||||||
|
|`MAGIC_TOGGLE_ESCAPE_CAPSLOCK` |`EC_TOGG`|Toggle Caps Lock and Escape swap |
|
||||||
|`MAGIC_CAPSLOCK_TO_CONTROL` |`CL_CTRL`|Treat Caps Lock as Control |
|
|`MAGIC_CAPSLOCK_TO_CONTROL` |`CL_CTRL`|Treat Caps Lock as Control |
|
||||||
|`MAGIC_UNCAPSLOCK_TO_CONTROL` |`CL_CAPS`|Stop treating Caps Lock as Control |
|
|`MAGIC_UNCAPSLOCK_TO_CONTROL` |`CL_CAPS`|Stop treating Caps Lock as Control |
|
||||||
|`MAGIC_SWAP_LCTL_LGUI` |`LCG_SWP`|Swap Left Control and GUI |
|
|`MAGIC_SWAP_LCTL_LGUI` |`LCG_SWP`|Swap Left Control and GUI |
|
||||||
|
|
|
@ -92,11 +92,10 @@ These keycodes allow the processing to fall through to lower layers in search of
|
||||||
|
|
||||||
For this example we will walk through an [older version of the default Clueboard 66% keymap](https://github.com/qmk/qmk_firmware/blob/ca01d94005f67ec4fa9528353481faa622d949ae/keyboards/clueboard/keymaps/default/keymap.c). You'll find it helpful to open that file in another browser window so you can look at everything in context.
|
For this example we will walk through an [older version of the default Clueboard 66% keymap](https://github.com/qmk/qmk_firmware/blob/ca01d94005f67ec4fa9528353481faa622d949ae/keyboards/clueboard/keymaps/default/keymap.c). You'll find it helpful to open that file in another browser window so you can look at everything in context.
|
||||||
|
|
||||||
There are 3 main sections of a `keymap.c` file you'll want to concern yourself with:
|
There are 2 main sections of a `keymap.c` file you'll want to concern yourself with:
|
||||||
|
|
||||||
* [The Definitions](#definitions)
|
* [The Definitions](#definitions)
|
||||||
* [The Layer/Keymap Datastructure](#layers-and-keymaps)
|
* [The Layer/Keymap Datastructure](#layers-and-keymaps)
|
||||||
* [Custom Functions](#custom-functions), if any
|
|
||||||
|
|
||||||
### Definitions
|
### Definitions
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ Open your `keymap.c` file in your text editor. Inside this file you'll find the
|
||||||
|
|
||||||
This line indicates where the list of Layers begins. Below that you'll find lines containing `LAYOUT`, and these lines indicate the start of a layer. Below that line is the list of keys that comprise a particular layer.
|
This line indicates where the list of Layers begins. Below that you'll find lines containing `LAYOUT`, and these lines indicate the start of a layer. Below that line is the list of keys that comprise a particular layer.
|
||||||
|
|
||||||
!> When editing your keymap file be careful not to add or remove any commas. If you do you will prevent your firmware from compiling and it may not be easy to figure out where the extra, or missing, comma is.
|
!> When editing your keymap file be careful not to add or remove any commas. If you do, you will prevent your firmware from compiling and it may not be easy to figure out where the extra, or missing, comma is.
|
||||||
|
|
||||||
## Customize The Layout To Your Liking
|
## Customize The Layout To Your Liking
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ The function `early_hardware_init_pre` is the earliest possible code that can be
|
||||||
|
|
||||||
This is executed before RAM gets cleared, and before clocks or GPIOs are configured; for example, ChibiOS delays are not likely to work at this point. After executing this function, RAM on the MCU may be zero'ed. Assigning values to variables during execution of this function may be overwritten.
|
This is executed before RAM gets cleared, and before clocks or GPIOs are configured; for example, ChibiOS delays are not likely to work at this point. After executing this function, RAM on the MCU may be zero'ed. Assigning values to variables during execution of this function may be overwritten.
|
||||||
|
|
||||||
As such, if you wish to override this API consider limiting use to writing to low-level registers. The default implementation of this function can be configured to jump to bootloader if a `RESET` key was pressed:
|
As such, if you wish to override this API consider limiting use to writing to low-level registers. The default implementation of this function can be configured to jump to bootloader if a `QK_BOOT` key was pressed:
|
||||||
|
|
||||||
| `config.h` override | Description | Default |
|
| `config.h` override | Description | Default |
|
||||||
|-----------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|
|
|-----------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|
|
||||||
|
@ -20,7 +20,7 @@ As such, if you wish to override this API consider limiting use to writing to lo
|
||||||
| `#define STM32_BOOTLOADER_DUAL_BANK` | Relevant for dual-bank STM32 MCUs, signifies that a GPIO is to be toggled in order to enter bootloader mode. | `FALSE` |
|
| `#define STM32_BOOTLOADER_DUAL_BANK` | Relevant for dual-bank STM32 MCUs, signifies that a GPIO is to be toggled in order to enter bootloader mode. | `FALSE` |
|
||||||
| `#define STM32_BOOTLOADER_DUAL_BANK_GPIO` | Relevant for dual-bank STM32 MCUs, the pin to toggle when attempting to enter bootloader mode, e.g. `B8` | `<none>` |
|
| `#define STM32_BOOTLOADER_DUAL_BANK_GPIO` | Relevant for dual-bank STM32 MCUs, the pin to toggle when attempting to enter bootloader mode, e.g. `B8` | `<none>` |
|
||||||
| `#define STM32_BOOTLOADER_DUAL_BANK_POLARITY` | Relevant for dual-bank STM32 MCUs, the value to set the pin to in order to trigger charging of the RC circuit. e.g. `0` or `1`. | `0` |
|
| `#define STM32_BOOTLOADER_DUAL_BANK_POLARITY` | Relevant for dual-bank STM32 MCUs, the value to set the pin to in order to trigger charging of the RC circuit. e.g. `0` or `1`. | `0` |
|
||||||
| `#define STM32_BOOTLOADER_DUAL_BANK_DELAY` | Relevant for dual-bank STM32 MCUs, an arbitrary measurement of time to delay before resetting the MCU. Increasing number increases the delay. | `100000` |
|
| `#define STM32_BOOTLOADER_DUAL_BANK_DELAY` | Relevant for dual-bank STM32 MCUs, an arbitrary measurement of time to delay before resetting the MCU. Increasing number increases the delay. | `100` |
|
||||||
|
|
||||||
Kinetis MCUs have no configurable options.
|
Kinetis MCUs have no configurable options.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
# Proton C
|
||||||
|
|
||||||
|
The Proton C is an Arm STM32F303xC based drop-in replacement for the Pro Micro.
|
||||||
|
|
||||||
|
<img src="https://i.imgur.com/GdsN1Rdh.jpg" alt="Proton C" />
|
||||||
|
|
||||||
|
#### Features
|
||||||
|
|
||||||
|
* Through-hole mounted USB-C Port
|
||||||
|
* 32-bit 72MHz Cortex-M4 processor (STM32F303CCT6)
|
||||||
|
* I2C, SPI, PWM, DMA, DAC, USART, I2S
|
||||||
|
* 23x 3.3V I/O Ports
|
||||||
|
* 1x 5V output for WS2812 LED chains
|
||||||
|
* 256kB flash
|
||||||
|
* 40kB RAM
|
||||||
|
* AST1109MLTRQ speaker footprint
|
||||||
|
* Reset button
|
||||||
|
|
||||||
|
## Warnings
|
||||||
|
|
||||||
|
Some of the PCBs compatible with Pro Micro have VCC (3.3V) and RAW (5V) pins connected (shorted) on the pcb. Using the Proton C will short 5V power from USB and regulated 3.3V which is connected directly to the MCU. Shorting those pins may damage the MCU on the Proton C.
|
||||||
|
|
||||||
|
So far, it appears that this is only an issue on the Gherkin PCBs, but other PCBs may be affected in this way.
|
||||||
|
|
||||||
|
In this case, you may want to not hook up the RAW pin at all.
|
||||||
|
|
||||||
|
## Manual Conversion
|
||||||
|
|
||||||
|
To use the Proton C natively, without having to specify `CONVERT_TO=proton_c`, you need to change the `MCU` line in `rules.mk`:
|
||||||
|
|
||||||
|
```
|
||||||
|
MCU = STM32F303
|
||||||
|
BOARD = QMK_PROTON_C
|
||||||
|
```
|
||||||
|
|
||||||
|
Remove these variables if they exist:
|
||||||
|
|
||||||
|
* `BOOTLOADER`
|
||||||
|
* `EXTRA_FLAGS`
|
||||||
|
|
||||||
|
Finally convert all pin assignments in `config.h` to the stm32 equivalents.
|
||||||
|
|
||||||
|
| Pro Micro Left | Proton C Left | | Proton C Right | Pro Micro Right |
|
||||||
|
|-----------|----------|-|----------|-----------|
|
||||||
|
| `D3` | `A9` | | 5v | RAW (5v) |
|
||||||
|
| `D2` | `A10` | | GND | GND |
|
||||||
|
| GND | GND | | FLASH | RESET |
|
||||||
|
| GND | GND | | 3.3v | VCC <sup>1</sup> |
|
||||||
|
| `D1` | `B7` | | `A2` | `F4` |
|
||||||
|
| `D0` | `B6` | | `A1` | `F5` |
|
||||||
|
| `D4` | `B5` | | `A0` | `F6` |
|
||||||
|
| `C6` | `B4` | | `B8` | `F7` |
|
||||||
|
| `D7` | `B3` | | `B13` | `B1` |
|
||||||
|
| `E6` | `B2` | | `B14` | `B3` |
|
||||||
|
| `B4` | `B1` | | `B15` | `B2` |
|
||||||
|
| `B5` | `B0` | | `B9` | `B6` |
|
||||||
|
| `B0` (RX LED) | `C13` <sup>2</sup> | | `C13` <sup>2</sup> | `D5` (TX LED) |
|
||||||
|
|
||||||
|
You can also make use of several new pins on the extended portion of the Proton C:
|
||||||
|
|
||||||
|
| Left | | Right |
|
||||||
|
|------|-|-------|
|
||||||
|
| `A4`<sup>3</sup> | | `B10` |
|
||||||
|
| `A5`<sup>4</sup> | | `B11` |
|
||||||
|
| `A6` | | `B12` |
|
||||||
|
| `A7` | | `A14`<sup>5</sup> (SWCLK) |
|
||||||
|
| `A8` | | `A13`<sup>5</sup> (SWDIO) |
|
||||||
|
| `A15` | | RESET<sup>6</sup> |
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
1. On a Pro Micro VCC can be 3.3v or 5v.
|
||||||
|
2. A Proton C only has one onboard LED, not two like a Pro Micro. The Pro Micro has an RX LED on `D5` and a TX LED on `B0`.
|
||||||
|
3. `A4` is shared with the speaker.
|
||||||
|
4. `A5` is shared with the speaker.
|
||||||
|
5. `A13` and `A14` are used for hardware debugging (SWD). You can also use them for GPIO, but should use them last.
|
||||||
|
6. Short RESET to 3.3v (pull high) to reboot the MCU. This does not enter bootloader mode like a Pro Micro, it only resets the MCU.
|
|
@ -0,0 +1,125 @@
|
||||||
|
# Raspberry Pi RP2040
|
||||||
|
|
||||||
|
The following table shows the current driver status for peripherals on RP2040 MCUs:
|
||||||
|
|
||||||
|
| System | Support |
|
||||||
|
| ---------------------------------------------------------------- | ---------------------------------------------- |
|
||||||
|
| [ADC driver](adc_driver.md) | Support planned (no ETA) |
|
||||||
|
| [Audio](audio_driver.md) | Support planned (no ETA) |
|
||||||
|
| [I2C driver](i2c_driver.md) | :heavy_check_mark: |
|
||||||
|
| [SPI driver](spi_driver.md) | :heavy_check_mark: |
|
||||||
|
| [WS2812 driver](ws2812_driver.md) | :heavy_check_mark: using `PIO` driver |
|
||||||
|
| [External EEPROMs](eeprom_driver.md) | :heavy_check_mark: using `I2C` or `SPI` driver |
|
||||||
|
| [EEPROM emulation](eeprom_driver.md#wear_leveling-configuration) | :heavy_check_mark: |
|
||||||
|
| [serial driver](serial_driver.md) | :heavy_check_mark: using `SIO` or `PIO` driver |
|
||||||
|
| [UART driver](uart_driver.md) | Support planned (no ETA) |
|
||||||
|
|
||||||
|
## GPIO
|
||||||
|
|
||||||
|
<img alt="Raspberry Pi Pico pinout" src="https://i.imgur.com/nLaiYDE.jpg" width="48%"/>
|
||||||
|
<img alt="Sparkfun RP2040 Pro Micro pinout" src="https://i.imgur.com/1TPAhrs.jpg" width="48%"/>
|
||||||
|
|
||||||
|
!> The GPIO pins of the RP2040 are not 5V tolerant!
|
||||||
|
|
||||||
|
### Pin nomenclature
|
||||||
|
|
||||||
|
To address individual pins on the RP2040, QMK uses the `GPx` abbreviation -- where the `x` stands for the GPIO number of the pin. This number can likely be found on the official pinout diagram of your board. Note that these GPIO numbers match the RP2040 MCU datasheet, and don't necessarily match the number you see printed on the board. For instance the Raspberry Pi Pico uses numbers from 1 to 40 for their pins, but these are not identical to the RP2040's GPIO numbers. So if you want to use the pin 11 of the Pico for your keyboard, you would refer to it as `GP8` in the config files.
|
||||||
|
|
||||||
|
### Alternate functions
|
||||||
|
|
||||||
|
The RP2040 features flexible GPIO function multiplexing, this means that every pin can be connected to nearly all the internal peripherals like I2C, SPI, UART or PWM. This allows for flexible PCB designs that are much less restricted in the selection of GPIO pins. To find out which pin can use which peripheral refer to the official [Raspberry PI RP2040 datasheet](https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf#page=14) section 1.4.3 GPIO functions.
|
||||||
|
|
||||||
|
## Selecting hardware peripherals and drivers
|
||||||
|
|
||||||
|
QMK RP2040 support builds upon ChibiOS and thus follows their convention for activating drivers and associated hardware peripherals. These tables only give a quick overview which values have to be used, please refer to the ChibiOS specific sections on the driver pages.
|
||||||
|
|
||||||
|
### I2C Driver
|
||||||
|
|
||||||
|
| RP2040 Peripheral | `mcuconf.h` values | `I2C_DRIVER` |
|
||||||
|
| ----------------- | ------------------ | ------------ |
|
||||||
|
| `I2C0` | `RP_I2C_USE_I2C0` | `I2CD1` |
|
||||||
|
| `I2C1` | `RP_I2C_USE_I2C1` | `I2CD2` |
|
||||||
|
|
||||||
|
To configure the I2C driver please read the [ChibiOS/ARM](i2c_driver.md#arm-configuration) section.
|
||||||
|
|
||||||
|
### SPI Driver
|
||||||
|
|
||||||
|
| RP2040 Peripheral | `mcuconf.h` values | `SPI_DRIVER` |
|
||||||
|
| ----------------- | ------------------ | ------------ |
|
||||||
|
| `SPI0` | `RP_SPI_USE_SPI0` | `SPID0` |
|
||||||
|
| `SPI1` | `RP_SPI_USE_SPI1` | `SPID1` |
|
||||||
|
|
||||||
|
To configure the SPI driver please read the [ChibiOS/ARM](spi_driver.md#chibiosarm-configuration) section.
|
||||||
|
|
||||||
|
## Double-tap reset boot-loader entry :id=double-tap
|
||||||
|
|
||||||
|
The double-tap reset mechanism is an alternate way in QMK to enter the embedded mass storage UF2 boot-loader of the RP2040. It enables bootloader entry by a fast double-tap of the reset pin on start up, which is similar to the behavior of AVR Pro Micros. This feature activated by default for the Pro Micro RP2040 board, but has to be configured for other boards. To activate it, add the following options to your keyboards `config.h` file:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET // Activates the double-tap behavior
|
||||||
|
#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT 200U // Timeout window in ms in which the double tap can occur.
|
||||||
|
#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED GP17 // Specify a optional status led by GPIO number which blinks when entering the bootloader
|
||||||
|
```
|
||||||
|
|
||||||
|
## Pre-defined RP2040 boards
|
||||||
|
|
||||||
|
QMK defines two boards that you can choose from to base your RP2040 powered keyboard upon. These boards provide pre-configured default pins and drivers.
|
||||||
|
|
||||||
|
### Generic Pro Micro RP2040
|
||||||
|
|
||||||
|
This is the default board that is chosen, unless any other RP2040 board is selected in your keyboards `rules.mk` file. It assumes a pin layout for the I2C, SPI and Serial drivers which is identical to the Sparkfun Pro Micro RP2040, however all values can be overwritten by defining them in your keyboards `config.h` file. The [double-tap](#double-tap) reset to enter boot-loader behavior is activated by default.
|
||||||
|
|
||||||
|
|
||||||
|
| Driver configuration define | Value |
|
||||||
|
| -------------------------------------------------------------------------- | ------------------------------------ |
|
||||||
|
| **I2C driver** | |
|
||||||
|
| `I2C_DRIVER` | `I2CD2` |
|
||||||
|
| `I2C1_SDA_PIN` | `GP2` |
|
||||||
|
| `I2C1_SCL_PIN` | `GP3` |
|
||||||
|
| **SPI driver** | |
|
||||||
|
| `SPI_DRIVER` | `SPID0` |
|
||||||
|
| `SPI_SCK_PIN` | `GP18` |
|
||||||
|
| `SPI_MISO_PIN` | `GP20` |
|
||||||
|
| `SPI_MOSI_PIN` | `GP19` |
|
||||||
|
| **Serial driver** | |
|
||||||
|
| `SERIAL_USART_DRIVER` ([SIO Driver](serial_driver.md#the-sio-driver) only) | `SIOD0` |
|
||||||
|
| `SOFT_SERIAL_PIN` | undefined, use `SERIAL_USART_TX_PIN` |
|
||||||
|
| `SERIAL_USART_TX_PIN` | `GP0` |
|
||||||
|
| `SERIAL_USART_RX_PIN` | `GP1` |
|
||||||
|
|
||||||
|
?> The pin-outs of Adafruit's KB2040 and Boardsource's Blok both deviate from the Sparkfun Pro Micro RP2040. Lookup the pin-out of these boards and adjust your keyboards pin definition accordingly if you want to use these boards.
|
||||||
|
|
||||||
|
### Generic RP2040 board
|
||||||
|
|
||||||
|
This board can be chosen as a base for RP2040 keyboards which configure all necessary pins and drivers themselves and do not wish to leverage the configuration matching the Generic Pro Micro RP2040 board. Thus it doesn't provide any pre-configured pins or drivers. To select this board add the following line to your keyboards `rules.mk` file.
|
||||||
|
|
||||||
|
```make
|
||||||
|
BOARD = GENERIC_RP_RP2040
|
||||||
|
```
|
||||||
|
|
||||||
|
## Split keyboard support
|
||||||
|
|
||||||
|
Split keyboards are fully supported using the [serial driver](serial_driver.md) in both full-duplex and half-duplex configurations. Two driver subsystems are supported by the RP2040, the hardware UART based `SIO` and the Programmable IO based `PIO` driver.
|
||||||
|
|
||||||
|
| Feature | [SIO Driver](serial_driver.md#the-sio-driver) | [PIO Driver](serial_driver.md#the-pio-driver) |
|
||||||
|
| ----------------------------- | --------------------------------------------- | --------------------------------------------- |
|
||||||
|
| Half-Duplex operation | | :heavy_check_mark: |
|
||||||
|
| Full-Duplex operation | :heavy_check_mark: | :heavy_check_mark: |
|
||||||
|
| `TX` and `RX` pin swapping | | :heavy_check_mark: |
|
||||||
|
| Any GPIO as `TX` and `RX` pin | Only UART capable pins | :heavy_check_mark: |
|
||||||
|
| Simple configuration | | :heavy_check_mark: |
|
||||||
|
|
||||||
|
The `PIO` driver is much more flexible then the `SIO` driver, the only "downside" is the usage of `PIO` resources which in turn are not available for advanced user programs. Under normal circumstances, this resource allocation will be a non-issue.
|
||||||
|
|
||||||
|
## RP2040 second stage bootloader selection
|
||||||
|
|
||||||
|
As the RP2040 does not have any internal flash memory it depends on an external SPI flash memory chip to store and execute instructions from. To successfully interact with a wide variety of these chips a second stage bootloader that is compatible with the chosen external flash memory has to be supplied with each firmware image. By default an `W25Q080` compatible bootloader is assumed, but others can be chosen by adding one of the defines listed in the table below to your keyboards `config.h` file.
|
||||||
|
|
||||||
|
| Compatible with flash chip | Selection |
|
||||||
|
| :------------------------- | ---------------------------------- |
|
||||||
|
| W25Q080 | Selected by default |
|
||||||
|
| AT25SF128A | `#define RP2040_FLASH_AT25SF128A` |
|
||||||
|
| GD25Q64CS | `#define RP2040_FLASH_GD25Q64CS` |
|
||||||
|
| W25X10CL | `#define RP2040_FLASH_W25X10CL` |
|
||||||
|
| IS25LP080 | `#define RP2040_FLASH_IS25LP080` |
|
||||||
|
| Generic 03H flash | `#define RP2040_FLASH_GENERIC_03H` |
|
|
@ -52,6 +52,9 @@ https://github.com/qmk/qmk_firmware/pulls?q=is%3Apr+is%3Aclosed+label%3Akeyboard
|
||||||
- valid maintainer
|
- valid maintainer
|
||||||
- valid USB VID/PID and device version
|
- valid USB VID/PID and device version
|
||||||
- displays correctly in Configurator (press Ctrl+Shift+I to preview local file, turn on fast input to verify ordering)
|
- displays correctly in Configurator (press Ctrl+Shift+I to preview local file, turn on fast input to verify ordering)
|
||||||
|
- `layout` definitions should include matrix positions, so that `LAYOUT` macros can be generated at build time
|
||||||
|
- should use standard definitions if applicable
|
||||||
|
- use the Community Layout macro names where they apply (preferred above `LAYOUT`/`LAYOUT_all`)
|
||||||
- `readme.md`
|
- `readme.md`
|
||||||
- standard template should be present -- [link to template](https://github.com/qmk/qmk_firmware/blob/master/data/templates/keyboard/readme.md)
|
- standard template should be present -- [link to template](https://github.com/qmk/qmk_firmware/blob/master/data/templates/keyboard/readme.md)
|
||||||
- flash command is present, and has `:flash` at end
|
- flash command is present, and has `:flash` at end
|
||||||
|
@ -67,6 +70,9 @@ https://github.com/qmk/qmk_firmware/pulls?q=is%3Apr+is%3Aclosed+label%3Akeyboard
|
||||||
- no `(-/+size)` comments related to enabling features
|
- no `(-/+size)` comments related to enabling features
|
||||||
- remove the list of alternate bootloaders if one has been specified
|
- remove the list of alternate bootloaders if one has been specified
|
||||||
- no re-definitions of the default MCU parameters if same value, when compared to the equivalent MCU in [mcu_selection.mk](https://github.com/qmk/qmk_firmware/blob/master/builddefs/mcu_selection.mk)
|
- no re-definitions of the default MCU parameters if same value, when compared to the equivalent MCU in [mcu_selection.mk](https://github.com/qmk/qmk_firmware/blob/master/builddefs/mcu_selection.mk)
|
||||||
|
- no "keymap only" features enabled
|
||||||
|
- `COMBO_ENABLE`
|
||||||
|
- `ENCODER_MAP_ENABLE`
|
||||||
- keyboard `config.h`
|
- keyboard `config.h`
|
||||||
- don't repeat `MANUFACTURER` in the `PRODUCT` value
|
- don't repeat `MANUFACTURER` in the `PRODUCT` value
|
||||||
- no `#define DESCRIPTION`
|
- no `#define DESCRIPTION`
|
||||||
|
@ -79,17 +85,15 @@ https://github.com/qmk/qmk_firmware/pulls?q=is%3Apr+is%3Aclosed+label%3Akeyboard
|
||||||
- Vial-related files or changes will not be accepted, as they are not used by QMK firmware (no Vial-specific core code has been submitted or merged)
|
- Vial-related files or changes will not be accepted, as they are not used by QMK firmware (no Vial-specific core code has been submitted or merged)
|
||||||
- `<keyboard>.c`
|
- `<keyboard>.c`
|
||||||
- empty `xxxx_xxxx_kb()` or other weak-defined default implemented functions removed
|
- empty `xxxx_xxxx_kb()` or other weak-defined default implemented functions removed
|
||||||
|
- empty `xxxx_xxxx_user()` or other user-level functions are disallowed at the keyboard level and must be moved to keymaps
|
||||||
- commented-out functions removed too
|
- commented-out functions removed too
|
||||||
- `matrix_init_board()` etc. migrated to `keyboard_pre_init_kb()`, see: [keyboard_pre_init*](custom_quantum_functions.md?id=keyboard_pre_init_-function-documentation)
|
- `matrix_init_board()` etc. migrated to `keyboard_pre_init_kb()`, see: [keyboard_pre_init*](custom_quantum_functions.md?id=keyboard_pre_init_-function-documentation)
|
||||||
- prefer `CUSTOM_MATRIX = lite` if custom matrix used, allows for standard debounce, see [custom matrix 'lite'](custom_matrix.md?id=lite)
|
- prefer `CUSTOM_MATRIX = lite` if custom matrix used, allows for standard debounce, see [custom matrix 'lite'](custom_matrix.md?id=lite)
|
||||||
- prefer LED indicator [Configuration Options](feature_led_indicators.md?id=configuration-options) to custom `led_update_*()` implementations where possible
|
- prefer LED indicator [Configuration Options](feature_led_indicators.md?id=configuration-options) to custom `led_update_*()` implementations where possible
|
||||||
- Encoder support should not be hacked into the keymap here -- no `tap_code(dynamic_keymap_get_keycode())` or `action_exec()` hacks. The [Encoder Map](feature_encoders.md?id=encoder-map) feature already supports the dynamic keymap feature (what power's VIA's "live keymap updates" capability).
|
- Encoder support should not require any keyboard-level code, and associated keymaps should now leverage the [Encoder Map](feature_encoders.md?id=encoder-map) feature instead.
|
||||||
- If support is absolutely necessary, it should be implemented exclusively at the keymap level, with none of the implementation bleeding into the keyboard level (no empty rows/columns, no encoder specific layouts, etc.), as those configurations can be redefined at the keymap level. Keymaps can then choose to use the `action_exec` hack. <!-- because people will complain, give them a way to implement it, in the meanwhile. To be removed. -->
|
|
||||||
- [Request for official proper VIA support](https://github.com/the-via/app/issues/26)
|
|
||||||
- `<keyboard>.h`
|
- `<keyboard>.h`
|
||||||
- `#include "quantum.h"` appears at the top
|
- `#include "quantum.h"` appears at the top
|
||||||
- `LAYOUT` macros should use standard definitions if applicable
|
- `LAYOUT` macros should be moved to `info.json`
|
||||||
- use the Community Layout macro names where they apply (preferred above `LAYOUT`/`LAYOUT_all`)
|
|
||||||
- keymap `config.h`
|
- keymap `config.h`
|
||||||
- no duplication of `rules.mk` or `config.h` from keyboard
|
- no duplication of `rules.mk` or `config.h` from keyboard
|
||||||
- `keymaps/default/keymap.c`
|
- `keymaps/default/keymap.c`
|
||||||
|
@ -109,7 +113,7 @@ https://github.com/qmk/qmk_firmware/pulls?q=is%3Apr+is%3Aclosed+label%3Akeyboard
|
||||||
- submitters can also have a "manufacturer-matching" keymap that mirrors existing functionality of the commercial product, if porting an existing board
|
- submitters can also have a "manufacturer-matching" keymap that mirrors existing functionality of the commercial product, if porting an existing board
|
||||||
- Do not include VIA json files in the PR. These do not belong in the QMK repository as they are not used by QMK firmware -- they belong in the [VIA Keyboard Repo](https://github.com/the-via/keyboards)
|
- Do not include VIA json files in the PR. These do not belong in the QMK repository as they are not used by QMK firmware -- they belong in the [VIA Keyboard Repo](https://github.com/the-via/keyboards)
|
||||||
- Do not include source files from another keyboard or vendors keyboard folder. Including core files is fine.
|
- Do not include source files from another keyboard or vendors keyboard folder. Including core files is fine.
|
||||||
- For instance, only `wilba_tech` boards using be including `keyboards/wilba_tech/wt_main.c` and `keyboards/wilba_tech/wt_rgb_backlight.c`. But including `drivers/sensors/pmw3360.c` is absolutely fine.
|
- For instance, only `wilba_tech` boards shall include `keyboards/wilba_tech/wt_main.c` and `keyboards/wilba_tech/wt_rgb_backlight.c`. But including `drivers/sensors/pmw3360.c` is absolutely fine for any and all boards.
|
||||||
- Code that needs to be used by multiple boards is a candidate for core code changes, and should be separated out.
|
- Code that needs to be used by multiple boards is a candidate for core code changes, and should be separated out.
|
||||||
|
|
||||||
Also, specific to ChibiOS:
|
Also, specific to ChibiOS:
|
||||||
|
@ -131,6 +135,7 @@ Also, specific to ChibiOS:
|
||||||
- for new MCUs, a new "child" keyboard should be added that targets your newly-added MCU, so that builds can be verified
|
- for new MCUs, a new "child" keyboard should be added that targets your newly-added MCU, so that builds can be verified
|
||||||
- for new hardware support such as display panels, core-side matrix implementations, or other peripherals, an associated keymap should be provided
|
- for new hardware support such as display panels, core-side matrix implementations, or other peripherals, an associated keymap should be provided
|
||||||
- if an existing keymap exists that can leverage this functionality this may not be required (e.g. a new RGB driver chip, supported by the `rgb` keymap) -- consult with the QMK Collaborators on Discord to determine if there is sufficient overlap already
|
- if an existing keymap exists that can leverage this functionality this may not be required (e.g. a new RGB driver chip, supported by the `rgb` keymap) -- consult with the QMK Collaborators on Discord to determine if there is sufficient overlap already
|
||||||
|
- any features adding `_kb`/`_user` callbacks must return a `bool`, to allow for user override of keyboard-level callbacks.
|
||||||
- other requirements are at the discretion of QMK collaborators
|
- other requirements are at the discretion of QMK collaborators
|
||||||
- core is a lot more subjective given the breadth of posted changes
|
- core is a lot more subjective given the breadth of posted changes
|
||||||
|
|
||||||
|
|
|
@ -1,91 +0,0 @@
|
||||||
# Converting a board to use the Proton C
|
|
||||||
|
|
||||||
Since the Proton C is a drop-in replacement for a Pro Micro we've made it easy to use. This page documents a handy automated process for converting keyboards, as well as documenting the manual process if you'd like to make use of Proton C features that aren't available on Pro Micros.
|
|
||||||
|
|
||||||
## Automatic Conversion
|
|
||||||
|
|
||||||
If a board currently supported in QMK uses a Pro Micro (or compatible board) and you want to use the Proton C, you can generate the firmware by appending `CONVERT_TO_PROTON_C=yes` (or `CTPC=yes`) to your make argument, like this:
|
|
||||||
|
|
||||||
make 40percentclub/mf68:default CTPC=yes
|
|
||||||
|
|
||||||
You can add the same argument to your keymap's `rules.mk`, which will accomplish the same thing.
|
|
||||||
|
|
||||||
This exposes the `CONVERT_TO_PROTON_C` flag that you can use in your code with `#ifdef`s, like this:
|
|
||||||
|
|
||||||
```c
|
|
||||||
#ifdef CONVERT_TO_PROTON_C
|
|
||||||
// Proton C code
|
|
||||||
#else
|
|
||||||
// Pro Micro code
|
|
||||||
#endif
|
|
||||||
```
|
|
||||||
|
|
||||||
If you get errors about `PORTB/DDRB`, etc not being defined, so 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.
|
|
||||||
|
|
||||||
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 like to your `config.h`:
|
|
||||||
|
|
||||||
#define CONVERT_TO_PROTON_C_RXLED
|
|
||||||
|
|
||||||
## Feature Conversion
|
|
||||||
|
|
||||||
These are defaults based on what has been implemented for ARM boards.
|
|
||||||
|
|
||||||
| Feature | Notes |
|
|
||||||
|-------------------------------------|------------------------------------------------------------------------------------------------------------------|
|
|
||||||
| [Audio](feature_audio.md) | Enabled |
|
|
||||||
| [RGB Lighting](feature_rgblight.md) | Disabled |
|
|
||||||
| [Backlight](feature_backlight.md) | Forces [task driven PWM](feature_backlight.md#software-pwm-driver) until ARM can provide automatic configuration |
|
|
||||||
| USB Host (e.g. USB-USB converter) | Not supported (USB host code is AVR specific and is not currently supported on ARM) |
|
|
||||||
| [Split keyboards](feature_split_keyboard.md) | Partial - heavily dependent on enabled features |
|
|
||||||
|
|
||||||
## Manual Conversion
|
|
||||||
|
|
||||||
To use the Proton C natively, without having to specify `CTPC=yes`, you need to change the `MCU` line in `rules.mk`:
|
|
||||||
|
|
||||||
```
|
|
||||||
MCU = STM32F303
|
|
||||||
BOARD = QMK_PROTON_C
|
|
||||||
```
|
|
||||||
|
|
||||||
Remove these variables if they exist:
|
|
||||||
|
|
||||||
* `BOOTLOADER`
|
|
||||||
* `EXTRA_FLAGS`
|
|
||||||
|
|
||||||
Finally convert all pin assignments in `config.h` to the stm32 equivalents.
|
|
||||||
|
|
||||||
| Pro Micro Left | Proton C Left | | Proton C Right | Pro Micro Right |
|
|
||||||
|-----------|----------|-|----------|-----------|
|
|
||||||
| `D3` | `A9` | | 5v | RAW (5v) |
|
|
||||||
| `D2` | `A10` | | GND | GND |
|
|
||||||
| GND | GND | | FLASH | RESET |
|
|
||||||
| GND | GND | | 3.3v | VCC <sup>1</sup> |
|
|
||||||
| `D1` | `B7` | | `A2` | `F4` |
|
|
||||||
| `D0` | `B6` | | `A1` | `F5` |
|
|
||||||
| `D4` | `B5` | | `A0` | `F6` |
|
|
||||||
| `C6` | `B4` | | `B8` | `F7` |
|
|
||||||
| `D7` | `B3` | | `B13` | `B1` |
|
|
||||||
| `E6` | `B2` | | `B14` | `B3` |
|
|
||||||
| `B4` | `B1` | | `B15` | `B2` |
|
|
||||||
| `B5` | `B0` | | `B9` | `B6` |
|
|
||||||
| `B0` (RX LED) | `C13` <sup>2</sup> | | `C13` <sup>2</sup> | `D5` (TX LED) |
|
|
||||||
|
|
||||||
You can also make use of several new pins on the extended portion of the Proton C:
|
|
||||||
|
|
||||||
| Left | | Right |
|
|
||||||
|------|-|-------|
|
|
||||||
| `A4`<sup>3</sup> | | `B10` |
|
|
||||||
| `A5`<sup>4</sup> | | `B11` |
|
|
||||||
| `A6` | | `B12` |
|
|
||||||
| `A7` | | `A14`<sup>5</sup> (SWCLK) |
|
|
||||||
| `A8` | | `A13`<sup>5</sup> (SWDIO) |
|
|
||||||
| `A15` | | RESET<sup>6</sup> |
|
|
||||||
|
|
||||||
Notes:
|
|
||||||
|
|
||||||
1. On a Pro Micro VCC can be 3.3v or 5v.
|
|
||||||
2. A Proton C only has one onboard LED, not two like a Pro Micro. The Pro Micro has an RX LED on `D5` and a TX LED on `B0`.
|
|
||||||
3. `A4` is shared with the speaker.
|
|
||||||
4. `A5` is shared with the speaker.
|
|
||||||
5. `A13` and `A14` are used for hardware debugging (SWD). You can also use them for GPIO, but should use them last.
|
|
||||||
6. Short RESET to 3.3v (pull high) to reboot the MCU. This does not enter bootloader mode like a Pro Micro, it only resets the MCU.
|
|
|
@ -8,10 +8,10 @@ On this page we have documented keycodes between `0x00FF` and `0xFFFF` which are
|
||||||
|
|
||||||
## QMK Keycodes :id=qmk-keycodes
|
## QMK Keycodes :id=qmk-keycodes
|
||||||
|
|
||||||
|Key |Aliases |Description |
|
|Key |Aliases |Description |
|
||||||
|-----------------|---------|---------------------------------------------------------------------------------|
|
|-----------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
|`QK_BOOTLOADER` |`QK_BOOT`|Put the keyboard into bootloader mode for flashing |
|
|`QK_BOOTLOADER` |`QK_BOOT`|Put the keyboard into bootloader mode for flashing |
|
||||||
|`QK_DEBUG_TOGGLE`|`DB_TOGG`|Toggle debug mode |
|
|`QK_DEBUG_TOGGLE`|`DB_TOGG`|Toggle debug mode |
|
||||||
|`QK_CLEAR_EEPROM`|`EE_CLR` |Reinitializes the keyboard's EEPROM (persistent memory) |
|
|`QK_CLEAR_EEPROM`|`EE_CLR` |Reinitializes the keyboard's EEPROM (persistent memory) |
|
||||||
|`QK_MAKE` | |Sends `qmk compile -kb (keyboard) -km (keymap)`, or `qmk flash` if shift is held |
|
|`QK_MAKE` | |Sends `qmk compile -kb (keyboard) -km (keymap)`, or `qmk flash` if shift is held. Puts keyboard into bootloader mode if shift & control are held |
|
||||||
|`QK_REBOOT` |`QK_RBT` |Resets the keyboard. Does not load the bootloader |
|
|`QK_REBOOT` |`QK_RBT` |Resets the keyboard. Does not load the bootloader |
|
||||||
|
|
|
@ -24,8 +24,10 @@ Hardware supported:
|
||||||
| GC9A01 | RGB LCD (circular) | 240x240 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS = gc9a01_spi` |
|
| GC9A01 | RGB LCD (circular) | 240x240 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS = gc9a01_spi` |
|
||||||
| ILI9163 | RGB LCD | 128x128 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS = ili9163_spi` |
|
| ILI9163 | RGB LCD | 128x128 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS = ili9163_spi` |
|
||||||
| ILI9341 | RGB LCD | 240x320 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS = ili9341_spi` |
|
| ILI9341 | RGB LCD | 240x320 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS = ili9341_spi` |
|
||||||
|
| ILI9488 | RGB LCD | 320x480 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS = ili9488_spi` |
|
||||||
| SSD1351 | RGB OLED | 128x128 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS = ssd1351_spi` |
|
| SSD1351 | RGB OLED | 128x128 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS = ssd1351_spi` |
|
||||||
| ST7789 | RGB LCD | 240x320, 240x240 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS = st7789_spi` |
|
| ST7789 | RGB LCD | 240x320, 240x240 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS = st7789_spi` |
|
||||||
|
| ST7735 | RGB LCD | 132x162, 80x160 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS = st7735_spi` |
|
||||||
|
|
||||||
## Quantum Painter Configuration :id=quantum-painter-config
|
## Quantum Painter Configuration :id=quantum-painter-config
|
||||||
|
|
||||||
|
@ -654,6 +656,30 @@ The maximum number of displays can be configured by changing the following in yo
|
||||||
#define ILI9341_NUM_DEVICES 3
|
#define ILI9341_NUM_DEVICES 3
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### ILI9488 :id=qp-driver-ili9488
|
||||||
|
|
||||||
|
Enabling support for the ILI9488 in Quantum Painter is done by adding the following to `rules.mk`:
|
||||||
|
|
||||||
|
```make
|
||||||
|
QUANTUM_PAINTER_ENABLE = yes
|
||||||
|
QUANTUM_PAINTER_DRIVERS = ili9488_spi
|
||||||
|
```
|
||||||
|
|
||||||
|
Creating a ILI9488 device in firmware can then be done with the following API:
|
||||||
|
|
||||||
|
```c
|
||||||
|
painter_device_t qp_ili9488_make_spi_device(uint16_t panel_width, uint16_t panel_height, pin_t chip_select_pin, pin_t dc_pin, pin_t reset_pin, uint16_t spi_divisor, int spi_mode);
|
||||||
|
```
|
||||||
|
|
||||||
|
The device handle returned from the `qp_ili9488_make_spi_device` function can be used to perform all other drawing operations.
|
||||||
|
|
||||||
|
The maximum number of displays can be configured by changing the following in your `config.h` (default is 1):
|
||||||
|
|
||||||
|
```c
|
||||||
|
// 3 displays:
|
||||||
|
#define ILI9488_NUM_DEVICES 3
|
||||||
|
```
|
||||||
|
|
||||||
### SSD1351 :id=qp-driver-ssd1351
|
### SSD1351 :id=qp-driver-ssd1351
|
||||||
|
|
||||||
Enabling support for the SSD1351 in Quantum Painter is done by adding the following to `rules.mk`:
|
Enabling support for the SSD1351 in Quantum Painter is done by adding the following to `rules.mk`:
|
||||||
|
@ -703,3 +729,29 @@ The maximum number of displays can be configured by changing the following in yo
|
||||||
```
|
```
|
||||||
|
|
||||||
!> Some ST7789 devices are known to have different drawing offsets -- despite being a 240x320 pixel display controller internally, some display panels are only 240x240, or smaller. These may require an offset to be applied; see `qp_set_viewport_offsets` above for information on how to override the offsets if they aren't correctly rendered.
|
!> Some ST7789 devices are known to have different drawing offsets -- despite being a 240x320 pixel display controller internally, some display panels are only 240x240, or smaller. These may require an offset to be applied; see `qp_set_viewport_offsets` above for information on how to override the offsets if they aren't correctly rendered.
|
||||||
|
|
||||||
|
### ST7735 :id=qp-driver-st7735
|
||||||
|
|
||||||
|
Enabling support for the ST7735 in Quantum Painter is done by adding the following to `rules.mk`:
|
||||||
|
|
||||||
|
```make
|
||||||
|
QUANTUM_PAINTER_ENABLE = yes
|
||||||
|
QUANTUM_PAINTER_DRIVERS = st7735_spi
|
||||||
|
```
|
||||||
|
|
||||||
|
Creating a ST7735 device in firmware can then be done with the following API:
|
||||||
|
|
||||||
|
```c
|
||||||
|
painter_device_t qp_st7735_make_spi_device(uint16_t panel_width, uint16_t panel_height, pin_t chip_select_pin, pin_t dc_pin, pin_t reset_pin, uint16_t spi_divisor, int spi_mode);
|
||||||
|
```
|
||||||
|
|
||||||
|
The device handle returned from the `qp_st7735_make_spi_device` function can be used to perform all other drawing operations.
|
||||||
|
|
||||||
|
The maximum number of displays can be configured by changing the following in your `config.h` (default is 1):
|
||||||
|
|
||||||
|
```c
|
||||||
|
// 3 displays:
|
||||||
|
#define ST7735_NUM_DEVICES 3
|
||||||
|
```
|
||||||
|
|
||||||
|
!> Some ST7735 devices are known to have different drawing offsets -- despite being a 132x162 pixel display controller internally, some display panels are only 80x160, or smaller. These may require an offset to be applied; see `qp_set_viewport_offsets` above for information on how to override the offsets if they aren't correctly rendered.
|
|
@ -1,12 +1,12 @@
|
||||||
# `info.json`
|
# `info.json`
|
||||||
|
|
||||||
This file is used by the [QMK API](https://github.com/qmk/qmk_api). It contains the information [QMK Configurator](https://config.qmk.fm/) needs to display a representation of your keyboard. You can also set metadata here.
|
The information contained in `info.json` is combined with the `config.h` and `rules.mk` files, dynamically generating the necessary configuration for your keyboard at compile time. It is also used by the [QMK API](https://github.com/qmk/qmk_api), and contains the information [QMK Configurator](https://config.qmk.fm/) needs to display a representation of your keyboard.
|
||||||
|
|
||||||
You can create `info.json` files at every level under `qmk_firmware/keyboards/<name>` to specify this metadata. These files are combined, with more specific files overriding keys in less specific files. This means you do not need to duplicate your metadata information. For example, `qmk_firmware/keyboards/clueboard/info.json` specifies `manufacturer` and `maintainer`, while `qmk_firmware/keyboards/clueboard/66/info.json` specifies more specific information about Clueboard 66%.
|
You can create `info.json` files at every level under `qmk_firmware/keyboards/<name>`. These files are combined, with more specific files overriding keys in less specific files. This means you do not need to duplicate your metadata information. For example, `qmk_firmware/keyboards/clueboard/info.json` specifies `manufacturer` and `maintainer`, while `qmk_firmware/keyboards/clueboard/66/info.json` specifies more specific information about Clueboard 66%.
|
||||||
|
|
||||||
## `info.json` Format
|
## `info.json` Format
|
||||||
|
|
||||||
The `info.json` file is a JSON formatted dictionary with the following keys available to be set. You do not have to set all of them, merely the keys that apply to your keyboard.
|
The `info.json` file is a JSON formatted dictionary. The first six keys noted here must be defined in `info.json`, or your keyboard will not be accepted into the QMK repository.
|
||||||
|
|
||||||
* `keyboard_name`
|
* `keyboard_name`
|
||||||
* A free-form text string describing the keyboard.
|
* A free-form text string describing the keyboard.
|
||||||
|
@ -20,6 +20,11 @@ The `info.json` file is a JSON formatted dictionary with the following keys avai
|
||||||
* `maintainer`
|
* `maintainer`
|
||||||
* GitHub username of the maintainer, or `qmk` for community maintained boards.
|
* GitHub username of the maintainer, or `qmk` for community maintained boards.
|
||||||
* Example: `skullydazed`
|
* Example: `skullydazed`
|
||||||
|
* `usb`
|
||||||
|
* Configure USB VID, PID, and device version. See the [USB](#USB) section for more detail.
|
||||||
|
|
||||||
|
There are many more optional keys, some of which are described below. Others may be found by examining `data/schemas`.
|
||||||
|
|
||||||
* `debounce`
|
* `debounce`
|
||||||
* The amount of time in milliseconds to wait for debounce to happen.
|
* The amount of time in milliseconds to wait for debounce to happen.
|
||||||
* Default: `5`
|
* Default: `5`
|
||||||
|
@ -33,8 +38,6 @@ The `info.json` file is a JSON formatted dictionary with the following keys avai
|
||||||
* Configure the pins corresponding to columns and rows, or direct pins. See the [Matrix Pins](#matrix-pins) section for more detail.
|
* Configure the pins corresponding to columns and rows, or direct pins. See the [Matrix Pins](#matrix-pins) section for more detail.
|
||||||
* `rgblight`
|
* `rgblight`
|
||||||
* Configure the [RGB Lighting feature](feature_rgblight.md). See the [RGB Lighting](#rgb-lighting) section for more detail.
|
* Configure the [RGB Lighting feature](feature_rgblight.md). See the [RGB Lighting](#rgb-lighting) section for more detail.
|
||||||
* `usb`
|
|
||||||
* Configure USB VID, PID, and other parameters. See the [USB](#USB) section for more detail.
|
|
||||||
|
|
||||||
### Layout Format
|
### Layout Format
|
||||||
|
|
||||||
|
@ -45,7 +48,7 @@ Within our `info.json` file the `layouts` portion of the dictionary contains sev
|
||||||
|
|
||||||
### Key Dictionary Format
|
### Key Dictionary Format
|
||||||
|
|
||||||
Each Key Dictionary in a layout describes the physical properties of a key. If you are familiar with the Raw Code for <https://keyboard-layout-editor.com> you will find many of the concepts the same. We re-use the same key names and layout choices wherever possible, but unlike keyboard-layout-editor each key is stateless, inheriting no properties from the keys that came before it.
|
Each Key Dictionary in a layout describes the physical properties of a key. If you are familiar with the Raw Data for <https://keyboard-layout-editor.com> you will find many of the concepts the same. We re-use the same key names and layout choices wherever possible, but unlike keyboard-layout-editor each key is stateless, inheriting no properties from the keys that came before it.
|
||||||
|
|
||||||
All key positions and rotations are specified in relation to the top-left corner of the keyboard, and the top-left corner of each key.
|
All key positions and rotations are specified in relation to the top-left corner of the keyboard, and the top-left corner of each key.
|
||||||
|
|
||||||
|
@ -91,6 +94,8 @@ Direct pins are when you connect one side of the switch to GND and the other sid
|
||||||
|
|
||||||
When specifying direct pins you need to arrange them in nested arrays. The outer array consists of rows, while the inner array uses text strings to identify the pins used in each row. You can use `null` to indicate an empty spot in the matrix.
|
When specifying direct pins you need to arrange them in nested arrays. The outer array consists of rows, while the inner array uses text strings to identify the pins used in each row. You can use `null` to indicate an empty spot in the matrix.
|
||||||
|
|
||||||
|
Notice that when using direct pins, `diode_direction` is left undefined.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
|
@ -113,6 +118,14 @@ Example:
|
||||||
This section controls basic 2-pin LEDs, which typically pass through keyswitches and are soldered into the PCB, or are placed in PCB sockets.
|
This section controls basic 2-pin LEDs, which typically pass through keyswitches and are soldered into the PCB, or are placed in PCB sockets.
|
||||||
### Backlight
|
### Backlight
|
||||||
|
|
||||||
|
Enable by setting
|
||||||
|
|
||||||
|
```json
|
||||||
|
"features": {
|
||||||
|
"backlight": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
* `breathing`
|
* `breathing`
|
||||||
* Enable backlight breathing, if supported
|
* Enable backlight breathing, if supported
|
||||||
* `breathing_period`
|
* `breathing_period`
|
||||||
|
@ -145,6 +158,13 @@ Used for indicating Num Lock, Caps Lock, and Scroll Lock. May be soldered in-swi
|
||||||
* The pin that controls the `Caps Lock` LED
|
* The pin that controls the `Caps Lock` LED
|
||||||
* `scroll_lock`
|
* `scroll_lock`
|
||||||
* The pin that controls the `Scroll Lock` LED
|
* The pin that controls the `Scroll Lock` LED
|
||||||
|
* `compose`
|
||||||
|
* The pin that controls the `Compose` LED
|
||||||
|
* `kana`
|
||||||
|
* The pin that controls the `Kana` LED
|
||||||
|
* `on_state`
|
||||||
|
* The state of the indicator pins when the LED is "on" - `1` for high, `0` for low
|
||||||
|
* Default: `1`
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
@ -177,8 +197,9 @@ The following items can be set. Not every value is required.
|
||||||
* Set to `true` to enable synchronization functionality between split halves
|
* Set to `true` to enable synchronization functionality between split halves
|
||||||
* `split_count`
|
* `split_count`
|
||||||
* For split keyboards, the number of LEDs on each side
|
* For split keyboards, the number of LEDs on each side
|
||||||
|
* Example `[ 10 , 10 ]`
|
||||||
* `max_brightness`
|
* `max_brightness`
|
||||||
* (0-255) What the maxmimum brightness (value) level is
|
* What the maximum brightness (value) level is (0-255)
|
||||||
* `hue_steps`
|
* `hue_steps`
|
||||||
* How many steps of adjustment to have for hue
|
* How many steps of adjustment to have for hue
|
||||||
* `saturation_steps`
|
* `saturation_steps`
|
||||||
|
@ -197,7 +218,8 @@ Example:
|
||||||
"saturation_steps": 17,
|
"saturation_steps": 17,
|
||||||
"brightness_steps": 17,
|
"brightness_steps": 17,
|
||||||
"animations": {
|
"animations": {
|
||||||
"all": true
|
"knight": true,
|
||||||
|
"rainbow_swirl": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,6 +261,50 @@ Example:
|
||||||
|
|
||||||
The device version is a BCD (binary coded decimal) value, in the format `MMmr`, so the below value would look like `0x0100` in the generated code. This also means the maximum valid values for each part are `99.9.9`, despite it being a hexadecimal value under the hood.
|
The device version is a BCD (binary coded decimal) value, in the format `MMmr`, so the below value would look like `0x0100` in the generated code. This also means the maximum valid values for each part are `99.9.9`, despite it being a hexadecimal value under the hood.
|
||||||
|
|
||||||
|
### Encoders
|
||||||
|
|
||||||
|
This section controls the basic [rotary encoder](feature_encoders.md) support.
|
||||||
|
|
||||||
|
Enable by setting
|
||||||
|
|
||||||
|
```json
|
||||||
|
"features": {
|
||||||
|
"encoder": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The following items can be set. Not every value is required.
|
||||||
|
|
||||||
|
* `pin_a`
|
||||||
|
* __Required__. A pad definition
|
||||||
|
* `pin_b`
|
||||||
|
* __Required__. B pad definition
|
||||||
|
* `resolution`
|
||||||
|
* How many pulses the encoder registers between each detent
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"encoder": {
|
||||||
|
"rotary": [
|
||||||
|
{ "pin_a": "B5", "pin_b": "A2" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"encoder": {
|
||||||
|
"rotary": [
|
||||||
|
{ "pin_a": "B5", "pin_b": "A2", "resolution": 4 }
|
||||||
|
{ "pin_a": "B6", "pin_b": "A3", "resolution": 2 }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Secure
|
### Secure
|
||||||
|
|
||||||
The following options can be configured:
|
The following options can be configured:
|
||||||
|
|
|
@ -1,129 +1,301 @@
|
||||||
# 'serial' Driver
|
# 'serial' Driver
|
||||||
This driver powers the [Split Keyboard](feature_split_keyboard.md) feature.
|
|
||||||
|
The serial driver powers the [Split Keyboard](feature_split_keyboard.md) feature. Several implementations are available, depending on the platform of your split keyboard. Note that none of the drivers support split keyboards with more then two halves.
|
||||||
|
|
||||||
|
| Driver | AVR | ARM | Connection between halves |
|
||||||
|
| --------------------------------------- | ------------------ | ------------------ | --------------------------------------------------------------------------------------------- |
|
||||||
|
| [Bitbang](#bitbang) | :heavy_check_mark: | :heavy_check_mark: | Single wire communication. One wire is used for reception and transmission. |
|
||||||
|
| [USART Half-duplex](#usart-half-duplex) | | :heavy_check_mark: | Efficient single wire communication. One wire is used for reception and transmission. |
|
||||||
|
| [USART Full-duplex](#usart-full-duplex) | | :heavy_check_mark: | Efficient two wire communication. Two distinct wires are used for reception and transmission. |
|
||||||
|
|
||||||
?> Serial in this context should be read as **sending information one bit at a time**, rather than implementing UART/USART/RS485/RS232 standards.
|
?> Serial in this context should be read as **sending information one bit at a time**, rather than implementing UART/USART/RS485/RS232 standards.
|
||||||
|
|
||||||
Drivers in this category have the following characteristics:
|
<hr>
|
||||||
* bit bang and USART Half-duplex provide data and signaling over a single conductor
|
|
||||||
* USART Full-duplex provide data and signaling over two conductors
|
|
||||||
* They are all limited to single master and single slave communication scheme
|
|
||||||
|
|
||||||
## Supported Driver Types
|
## Bitbang
|
||||||
|
|
||||||
| | AVR | ARM |
|
This is the Default driver, the absence of configuration assumes this driver. It works by [bit banging](https://en.wikipedia.org/wiki/Bit_banging) a GPIO pin using the CPU. It is therefore not as efficient as a dedicated hardware peripheral, which the Half-duplex and Full-duplex drivers use.
|
||||||
| ----------------- | ------------------ | ------------------ |
|
|
||||||
| bit bang | :heavy_check_mark: | :heavy_check_mark: |
|
|
||||||
| USART Half-duplex | | :heavy_check_mark: |
|
|
||||||
| USART Full-duplex | | :heavy_check_mark: |
|
|
||||||
|
|
||||||
## Driver configuration
|
!> On ARM platforms the bitbang driver causes connection issues when using it together with the bitbang WS2812 driver. Choosing alternate drivers for both serial and WS2812 (instead of bitbang) is strongly recommended.
|
||||||
|
|
||||||
### Bitbang
|
### Pin configuration
|
||||||
Default driver, the absence of configuration assumes this driver. To configure it, add this to your rules.mk:
|
|
||||||
|
```
|
||||||
|
LEFT RIGHT
|
||||||
|
+-------+ SERIAL +-------+
|
||||||
|
| SSP |-----------------| SSP |
|
||||||
|
| | VDD | |
|
||||||
|
| |-----------------| |
|
||||||
|
| | GND | |
|
||||||
|
| |-----------------| |
|
||||||
|
+-------+ +-------+
|
||||||
|
```
|
||||||
|
|
||||||
|
One GPIO pin is needed for the bitbang driver, as only one wire is used for receiving and transmitting data. This pin is referred to as the `SOFT_SERIAL_PIN` (SSP) in the configuration. A simple TRS or USB cable provides enough conductors for this driver to work.
|
||||||
|
|
||||||
|
### Setup
|
||||||
|
|
||||||
|
To use the bitbang driver follow these steps to activate it.
|
||||||
|
|
||||||
|
1. Change the `SERIAL_DRIVER` to `bitbang` in your keyboards `rules.mk` file:
|
||||||
|
|
||||||
```make
|
```make
|
||||||
SERIAL_DRIVER = bitbang
|
SERIAL_DRIVER = bitbang
|
||||||
```
|
```
|
||||||
|
|
||||||
Configure the driver via your config.h:
|
2. Configure the GPIO pin of your keyboard via the `config.h` file:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#define SOFT_SERIAL_PIN D0 // or D1, D2, D3, E6
|
#define SOFT_SERIAL_PIN D0 // or D1, D2, D3, E6
|
||||||
#define SELECT_SOFT_SERIAL_SPEED 1 // or 0, 2, 3, 4, 5
|
|
||||||
// 0: about 189kbps (Experimental only)
|
|
||||||
// 1: about 137kbps (default)
|
|
||||||
// 2: about 75kbps
|
|
||||||
// 3: about 39kbps
|
|
||||||
// 4: about 26kbps
|
|
||||||
// 5: about 20kbps
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### ARM
|
3. On ARM platforms you must turn on ChibiOS `PAL_USE_CALLBACKS` feature:
|
||||||
|
|
||||||
!> The bitbang driver causes connection issues with bitbang WS2812 driver
|
* In `halconf.h` add the line `#define PAL_USE_CALLBACKS TRUE`.
|
||||||
|
|
||||||
Along with the generic options above, you must also turn on the `PAL_USE_CALLBACKS` feature in your halconf.h.
|
<hr>
|
||||||
|
|
||||||
### USART Half-duplex
|
## USART Half-duplex
|
||||||
Targeting STM32 boards where communication is offloaded to a USART hardware device. The advantage over bitbang is that this provides fast and accurate timings. `SERIAL_PIN_TX` for this driver is the configured USART TX pin. As this Pin is configured in open-drain mode an **external pull-up resistor is needed to keep the line high** (resistor values of 1.5k to 8.2k are known to work). To configure it, add this to your rules.mk:
|
|
||||||
|
Targeting ARM boards based on ChibiOS, where communication is offloaded to a USART hardware device that supports Half-duplex operation. The advantages over bitbanging are fast, accurate timings and reduced CPU usage. Therefore it is advised to choose this driver or the Full-duplex driver whenever possible.
|
||||||
|
|
||||||
|
### Pin configuration
|
||||||
|
|
||||||
|
```
|
||||||
|
LEFT RIGHT
|
||||||
|
+-------+ | | +-------+
|
||||||
|
| | R R | |
|
||||||
|
| | | SERIAL | | |
|
||||||
|
| TX |-----------------| TX |
|
||||||
|
| | VDD | |
|
||||||
|
| |-----------------| |
|
||||||
|
| | GND | |
|
||||||
|
| |-----------------| |
|
||||||
|
+-------+ +-------+
|
||||||
|
```
|
||||||
|
|
||||||
|
Only one GPIO pin is needed for the Half-duplex driver, as only one wire is used for receiving and transmitting data. This pin is referred to as the `SERIAL_USART_TX_PIN` in the configuration. Take care that the pin you chose can act as the TX pin of the USART peripheral. A simple TRS or USB cable provides enough conductors for this driver to work. As the split connection is configured to work in open-drain mode, an **external pull-up resistor is needed to keep the line high**. Resistor values of 1.5kΩ to 8.2kΩ are known to work.
|
||||||
|
|
||||||
|
### Setup
|
||||||
|
|
||||||
|
To use the Half-duplex driver follow these steps to activate it. If you target the Raspberry Pi RP2040 PIO implementation skip step 1.
|
||||||
|
|
||||||
|
1. Change the `SERIAL_DRIVER` to `usart` in your keyboards `rules.mk` file:
|
||||||
|
|
||||||
```make
|
```make
|
||||||
SERIAL_DRIVER = usart
|
SERIAL_DRIVER = usart
|
||||||
```
|
```
|
||||||
|
|
||||||
Configure the hardware via your config.h:
|
2. (RP2040 PIO only!) Change the `SERIAL_DRIVER` to `vendor` in your keyboards `rules.mk` file:
|
||||||
|
|
||||||
|
```make
|
||||||
|
SERIAL_DRIVER = vendor
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Configure the hardware of your keyboard via the `config.h` file:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#define SOFT_SERIAL_PIN B6 // USART TX pin
|
#define SERIAL_USART_TX_PIN B6 // The GPIO pin that is used split communication.
|
||||||
//#define USART1_REMAP // Remap USART TX and RX pins on STM32F103 MCUs, see table below.
|
|
||||||
#define SELECT_SOFT_SERIAL_SPEED 1 // or 0, 2, 3, 4, 5
|
|
||||||
// 0: about 460800 baud
|
|
||||||
// 1: about 230400 baud (default)
|
|
||||||
// 2: about 115200 baud
|
|
||||||
// 3: about 57600 baud
|
|
||||||
// 4: about 38400 baud
|
|
||||||
// 5: about 19200 baud
|
|
||||||
#define SERIAL_USART_DRIVER SD1 // USART driver of TX pin. default: SD1
|
|
||||||
#define SERIAL_USART_TX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7
|
|
||||||
#define SERIAL_USART_TIMEOUT 20 // USART driver timeout. default 20
|
|
||||||
```
|
```
|
||||||
|
|
||||||
You must also enable the ChibiOS `SERIAL` feature:
|
For STM32 MCUs several GPIO configuration options can be changed as well. See the section ["Alternate Functions for selected STM32 MCUs"](alternate-functions-for-selected-stm32-mcus).
|
||||||
* In your board's halconf.h: `#define HAL_USE_SERIAL TRUE`
|
|
||||||
* In your board's mcuconf.h: `#define STM32_SERIAL_USE_USARTn TRUE` (where 'n' matches the peripheral number of your selected USART on the MCU)
|
|
||||||
|
|
||||||
Do note that the configuration required is for the `SERIAL` peripheral, not the `UART` peripheral.
|
```c
|
||||||
|
#define USART1_REMAP // Remap USART TX and RX pins on STM32F103 MCUs, see table below.
|
||||||
|
#define SERIAL_USART_TX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7
|
||||||
|
```
|
||||||
|
|
||||||
### USART Full-duplex
|
1. Decide either for `SERIAL`, `SIO` or `PIO` subsystem, see the section ["Choosing a driver subsystem"](#choosing-a-driver-subsystem).
|
||||||
Targeting STM32 boards where communication is offloaded to a USART hardware device. The advantage over bitbang is that this provides fast and accurate timings. USART Full-Duplex requires two conductors **without** pull-up resistors instead of one conductor with a pull-up resistor unlike the Half-duplex driver. Due to its internal design it is more efficent, which can result in even faster transmission speeds.
|
|
||||||
|
|
||||||
#### Pin configuration
|
<hr>
|
||||||
|
|
||||||
`SERIAL_USART_TX_PIN` is the USART `TX` pin, `SERIAL_USART_RX_PIN` is the USART `RX` pin. No external pull-up resistors are needed as the `TX` pin operates in push-pull mode. To use this driver the usart peripherals `TX` and `RX` pins must be configured with the correct Alternate-functions. If you are using a Proton-C everything is already setup, same is true for STM32F103 MCUs. For MCUs which are using a modern flexible GPIO configuration you have to specify these by setting `SERIAL_USART_TX_PAL_MODE` and `SERIAL_USART_RX_PAL_MODE`. Refeer to the corresponding datasheets of your MCU or find those settings in the table below.
|
## USART Full-duplex
|
||||||
|
|
||||||
#### Connecting the halves and Pin Swap
|
Targeting ARM boards based on ChibiOS where communication is offloaded to an USART hardware device. The advantages over bitbanging are fast, accurate timings and reduced CPU usage. Therefore it is advised to choose this driver or the Full-duplex driver whenever possible. Due to its internal design it is slightly more efficient then the Half-duplex driver, but it should be primarily chosen if Half-duplex operation is not supported by the USART peripheral.
|
||||||
Please note that `TX` of the master half has to be connected with the `RX` pin of the slave half and `RX` of the master half has to be connected with the `TX` pin of the slave half! Usually this pin swap has to be done outside of the MCU e.g. with cables or on the pcb. Some MCUs like the STM32F303 used on the Proton-C allow this pin swap directly inside the MCU, this feature can be enabled using `#define SERIAL_USART_PIN_SWAP` in your config.h.
|
|
||||||
|
|
||||||
#### Setup
|
### Pin configuration
|
||||||
To use the driver, add this to your rules.mk:
|
|
||||||
|
```
|
||||||
|
LEFT RIGHT
|
||||||
|
+-------+ +-------+
|
||||||
|
| | SERIAL | |
|
||||||
|
| TX |-----------------| RX |
|
||||||
|
| | SERIAL | |
|
||||||
|
| RX |-----------------| TX |
|
||||||
|
| | VDD | |
|
||||||
|
| |-----------------| |
|
||||||
|
| | GND | |
|
||||||
|
| |-----------------| |
|
||||||
|
+-------+ +-------+
|
||||||
|
```
|
||||||
|
|
||||||
|
Two GPIO pins are needed for the Full-duplex driver, as two distinct wires are used for receiving and transmitting data. The pin transmitting data is the `TX` pin and refereed to as the `SERIAL_USART_TX_PIN`, the pin receiving data is the `RX` pin and refereed to as the `SERIAL_USART_RX_PIN` in this configuration. Please note that `TX` pin of the master half has to be connected with the `RX` pin of the slave half and the `RX` pin of the master half has to be connected with the `TX` pin of the slave half! Usually this pin swap has to be done outside of the MCU e.g. with cables or on the PCB. Some MCUs like the STM32F303 used on the Proton-C allow this pin swap directly inside the MCU. A simple TRRS or USB cable provides enough conductors for this driver to work.
|
||||||
|
|
||||||
|
To use this driver the usart peripherals `TX` and `RX` pins must be configured with the correct Alternate-functions. If you are using a Proton-C everything is already setup, same is true for STM32F103 MCUs. For MCUs which are using a modern flexible GPIO configuration you have to specify these by setting `SERIAL_USART_TX_PAL_MODE` and `SERIAL_USART_RX_PAL_MODE`. Refer to the corresponding datasheets of your MCU or find those settings in the section ["Alternate Functions for selected STM32 MCUs"](#alternate-functions-for-selected-stm32-mcus).
|
||||||
|
|
||||||
|
### Setup
|
||||||
|
|
||||||
|
To use the Full-duplex driver follow these steps to activate it. If you target the Raspberry Pi RP2040 PIO implementation skip step 1.
|
||||||
|
|
||||||
|
1. Change the `SERIAL_DRIVER` to `usart` in your keyboards `rules.mk` file:
|
||||||
|
|
||||||
```make
|
```make
|
||||||
SERIAL_DRIVER = usart
|
SERIAL_DRIVER = usart
|
||||||
```
|
```
|
||||||
|
|
||||||
Next configure the hardware via your config.h:
|
2. (RP2040 PIO only!) Change the `SERIAL_DRIVER` to `vendor` in your keyboards `rules.mk` file:
|
||||||
|
|
||||||
|
```make
|
||||||
|
SERIAL_DRIVER = vendor
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Configure the hardware of your keyboard via the `config.h` file:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#define SERIAL_USART_FULL_DUPLEX // Enable full duplex operation mode.
|
#define SERIAL_USART_FULL_DUPLEX // Enable full duplex operation mode.
|
||||||
#define SERIAL_USART_TX_PIN B6 // USART TX pin
|
#define SERIAL_USART_TX_PIN B6 // USART TX pin
|
||||||
#define SERIAL_USART_RX_PIN B7 // USART RX pin
|
#define SERIAL_USART_RX_PIN B7 // USART RX pin
|
||||||
//#define USART1_REMAP // Remap USART TX and RX pins on STM32F103 MCUs, see table below.
|
```
|
||||||
//#define SERIAL_USART_PIN_SWAP // Swap TX and RX pins if keyboard is master halve.
|
|
||||||
// Check if this feature is necessary with your keyboard design and available on the mcu.
|
For STM32 MCUs several GPIO configuration options, including the ability for `TX` to `RX` pin swapping, can be changed as well. See the section ["Alternate Functions for selected STM32 MCUs"](alternate-functions-for-selected-stm32-mcus).
|
||||||
#define SELECT_SOFT_SERIAL_SPEED 1 // or 0, 2, 3, 4, 5
|
|
||||||
// 0: 460800 baud
|
```c
|
||||||
// 1: 230400 baud (default)
|
#define SERIAL_USART_PIN_SWAP // Swap TX and RX pins if keyboard is master halve. (Only available on some MCUs)
|
||||||
// 2: 115200 baud
|
#define USART1_REMAP // Remap USART TX and RX pins on STM32F103 MCUs, see table below.
|
||||||
// 3: 57600 baud
|
|
||||||
// 4: 38400 baud
|
|
||||||
// 5: 19200 baud
|
|
||||||
#define SERIAL_USART_DRIVER SD1 // USART driver of TX and RX pin. default: SD1
|
|
||||||
#define SERIAL_USART_TX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7
|
#define SERIAL_USART_TX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7
|
||||||
#define SERIAL_USART_RX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7
|
```
|
||||||
|
|
||||||
|
1. Decide either for `SERIAL`, `SIO` or `PIO` subsystem, see the section ["Choosing a driver subsystem"](#choosing-a-driver-subsystem).
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
## Choosing a driver subsystem
|
||||||
|
|
||||||
|
### The `SERIAL` driver
|
||||||
|
|
||||||
|
The `SERIAL` Subsystem is supported for the majority of ChibiOS MCUs and should be used whenever supported. Follow these steps in order to activate it:
|
||||||
|
|
||||||
|
1. In your keyboards `halconf.h` add:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define HAL_USE_SERIAL TRUE
|
||||||
|
```
|
||||||
|
|
||||||
|
2. In your keyboards `mcuconf.h`: activate the USART peripheral that is used on your MCU. The shown example is for an STM32 MCU, so this will not work on MCUs by other manufacturers. You can find the correct names in the `mcuconf.h` files of your MCU that ship with ChibiOS.
|
||||||
|
|
||||||
|
Just below `#include_next <mcuconf.h>` add:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include_next <mcuconf.h>
|
||||||
|
|
||||||
|
#undef STM32_SERIAL_USE_USARTn
|
||||||
|
#define STM32_SERIAL_USE_USARTn TRUE
|
||||||
|
```
|
||||||
|
|
||||||
|
Where 'n' matches the peripheral number of your selected USART on the MCU.
|
||||||
|
|
||||||
|
3. In you keyboards `config.h`: override the default USART `SERIAL` driver if you use a USART peripheral that does not belong to the default selected `SD1` driver. For instance, if you selected `STM32_SERIAL_USE_USART3` the matching driver would be `SD3`.
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define SERIAL_USART_DRIVER SD3
|
||||||
|
```
|
||||||
|
|
||||||
|
### The `SIO` driver
|
||||||
|
|
||||||
|
The `SIO` Subsystem was added to ChibiOS with the 21.11 release and is only supported on selected MCUs. It should only be chosen when the `SERIAL` subsystem is not supported by your MCU.
|
||||||
|
|
||||||
|
Follow these steps in order to activate it:
|
||||||
|
|
||||||
|
1. In your keyboards `halconf.h` add:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define HAL_USE_SIO TRUE
|
||||||
|
```
|
||||||
|
|
||||||
|
2. In your keyboards `mcuconf.h:` activate the USART peripheral that is used on your MCU. The shown example is for an STM32 MCU, so this will not work on MCUs by other manufacturers. You can find the correct names in the `mcuconf.h` files of your MCU that ship with ChibiOS.
|
||||||
|
|
||||||
|
Just below `#include_next <mcuconf.h>` add:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include_next <mcuconf.h>
|
||||||
|
|
||||||
|
#undef STM32_SIO_USE_USARTn
|
||||||
|
#define STM32_SIO_USE_USARTn TRUE
|
||||||
|
```
|
||||||
|
|
||||||
|
Where 'n' matches the peripheral number of your selected USART on the MCU.
|
||||||
|
|
||||||
|
3. In you keyboards `config.h`: override the default USART `SIO` driver if you use a USART peripheral that does not belong to the default selected `SIOD1` driver. For instance, if you selected `STM32_SERIAL_USE_USART3` the matching driver would be `SIOD3`.
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define SERIAL_USART_DRIVER SIOD3
|
||||||
|
```
|
||||||
|
|
||||||
|
### The `PIO` driver
|
||||||
|
|
||||||
|
The `PIO` subsystem is a Raspberry Pi RP2040 specific implementation, using the integrated PIO peripheral and is therefore only available on this MCU. Because of the flexible nature of the PIO peripherals, **any** GPIO pin can be used as a `TX` or `RX` pin. Half-duplex and Full-duplex operation is fully supported. The Half-duplex operation mode uses the built-in pull-ups and GPIO manipulation on the RP2040 to drive the line high by default. An external pull-up is therefore not necessary.
|
||||||
|
|
||||||
|
Configure the hardware via your config.h:
|
||||||
|
```c
|
||||||
|
#define SERIAL_PIO_USE_PIO1 // Force the usage of PIO1 peripheral, by default the Serial implementation uses the PIO0 peripheral
|
||||||
|
```
|
||||||
|
|
||||||
|
The Serial PIO program uses 2 state machines, 13 instructions and the complete interrupt handler of the PIO peripheral it is running on.
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
## Advanced Configuration
|
||||||
|
|
||||||
|
There are several advanced configuration options that can be defined in your keyboards `config.h` file:
|
||||||
|
|
||||||
|
### Baudrate
|
||||||
|
|
||||||
|
If you're having issues or need a higher baudrate with serial communication, you can change the baudrate which in turn controls the communication speed for serial. You want to lower the baudrate if you experience failed transactions.
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define SELECT_SOFT_SERIAL_SPEED {#}
|
||||||
|
```
|
||||||
|
|
||||||
|
| Speed | Bitbang | Half-duplex and Full-duplex |
|
||||||
|
| ----- | -------------------------- | --------------------------- |
|
||||||
|
| `0` | 189000 baud (experimental) | 460800 baud |
|
||||||
|
| `1` | 137000 baud (default) | 230400 baud (default) |
|
||||||
|
| `2` | 75000 baud | 115200 baud |
|
||||||
|
| `3` | 39000 baud | 57600 baud |
|
||||||
|
| `4` | 26000 baud | 38400 baud |
|
||||||
|
| `5` | 20000 baud | 19200 baud |
|
||||||
|
|
||||||
|
Alternatively you can specify the baudrate directly by defining `SERIAL_USART_SPEED`.
|
||||||
|
|
||||||
|
### Timeout
|
||||||
|
|
||||||
|
This is the default time window in milliseconds in which a successful communication has to complete. Usually you don't want to change this value. But you can do so anyways by defining an alternate one in your keyboards `config.h` file:
|
||||||
|
|
||||||
|
```c
|
||||||
#define SERIAL_USART_TIMEOUT 20 // USART driver timeout. default 20
|
#define SERIAL_USART_TIMEOUT 20 // USART driver timeout. default 20
|
||||||
```
|
```
|
||||||
|
|
||||||
You must also enable the ChibiOS `SERIAL` feature:
|
<hr>
|
||||||
* In your board's halconf.h: `#define HAL_USE_SERIAL TRUE`
|
|
||||||
* In your board's mcuconf.h: `#define STM32_SERIAL_USE_USARTn TRUE` (where 'n' matches the peripheral number of your selected USART on the MCU)
|
|
||||||
|
|
||||||
Do note that the configuration required is for the `SERIAL` peripheral, not the `UART` peripheral.
|
## Troubleshooting
|
||||||
|
|
||||||
#### Pins for USART Peripherals with Alternate Functions for selected STM32 MCUs
|
If you're having issues withe serial communication, you can enable debug messages that will give you insights which part of the communication failed. The enable these messages add to your keyboards `config.h` file:
|
||||||
|
|
||||||
##### STM32F303 / Proton-C [Datasheet](https://www.st.com/resource/en/datasheet/stm32f303cc.pdf)
|
```c
|
||||||
|
#define SERIAL_DEBUG
|
||||||
|
```
|
||||||
|
|
||||||
|
?> The messages will be printed out to the `CONSOLE` output. For additional information, refer to [Debugging/Troubleshooting QMK](faq_debug.md).
|
||||||
|
|
||||||
|
## Alternate Functions for selected STM32 MCUs
|
||||||
|
|
||||||
|
Pins for USART Peripherals with
|
||||||
|
|
||||||
|
### STM32F303 / Proton-C [Datasheet](https://www.st.com/resource/en/datasheet/stm32f303cc.pdf)
|
||||||
|
|
||||||
Pin Swap available: :heavy_check_mark:
|
Pin Swap available: :heavy_check_mark:
|
||||||
|
|
||||||
| Pin | Function | Mode |
|
| Pin | Function | Mode |
|
||||||
| ---------- | -------- | ---- |
|
| ---------- | -------- | ---- |
|
||||||
| **USART1** | | |
|
| **USART1** | | |
|
||||||
| PA9 | TX | AF7 |
|
| PA9 | TX | AF7 |
|
||||||
|
@ -151,11 +323,11 @@ Pin Swap available: :heavy_check_mark:
|
||||||
| PD8 | TX | AF7 |
|
| PD8 | TX | AF7 |
|
||||||
| PD9 | RX | AF7 |
|
| PD9 | RX | AF7 |
|
||||||
|
|
||||||
##### STM32F072 [Datasheet](https://www.st.com/resource/en/datasheet/stm32f072c8.pdf)
|
### STM32F072 [Datasheet](https://www.st.com/resource/en/datasheet/stm32f072c8.pdf)
|
||||||
|
|
||||||
Pin Swap available: :heavy_check_mark:
|
Pin Swap available: :heavy_check_mark:
|
||||||
|
|
||||||
| Pin | Function | Mode |
|
| Pin | Function | Mode |
|
||||||
| ------ | -------- | ---- |
|
| ------ | -------- | ---- |
|
||||||
| USART1 | | |
|
| USART1 | | |
|
||||||
| PA9 | TX | AF1 |
|
| PA9 | TX | AF1 |
|
||||||
|
@ -180,7 +352,7 @@ Pin Swap available: :heavy_check_mark:
|
||||||
| PA0 | TX | AF4 |
|
| PA0 | TX | AF4 |
|
||||||
| PA1 | RX | AF4 |
|
| PA1 | RX | AF4 |
|
||||||
|
|
||||||
##### STM32F103 Medium Density (C8-CB) [Datasheet](https://www.st.com/resource/en/datasheet/stm32f103c8.pdf)
|
### STM32F103 Medium Density (C8-CB) [Datasheet](https://www.st.com/resource/en/datasheet/stm32f103c8.pdf)
|
||||||
|
|
||||||
Pin Swap available: N/A
|
Pin Swap available: N/A
|
||||||
|
|
||||||
|
@ -190,7 +362,7 @@ Pin remapping:
|
||||||
|
|
||||||
The pins of USART Peripherals use default Pins that can be remapped to use other pins using the AFIO registers. Default pins are marked **bold**. Add the appropriate defines to your config.h file.
|
The pins of USART Peripherals use default Pins that can be remapped to use other pins using the AFIO registers. Default pins are marked **bold**. Add the appropriate defines to your config.h file.
|
||||||
|
|
||||||
| Pin | Function | Mode | USART_REMAP |
|
| Pin | Function | Mode | USART_REMAP |
|
||||||
| ---------- | -------- | ---- | ------------------- |
|
| ---------- | -------- | ---- | ------------------- |
|
||||||
| **USART1** | | | |
|
| **USART1** | | | |
|
||||||
| **PA9** | TX | AFPP | |
|
| **PA9** | TX | AFPP | |
|
||||||
|
|
|
@ -188,7 +188,10 @@ If you've done all of this, and your firmware is still too large, then it's time
|
||||||
That said, there are a number of Pro Micro replacements with ARM controllers:
|
That said, there are a number of Pro Micro replacements with ARM controllers:
|
||||||
* [Proton C](https://qmk.fm/proton-c/) (out of stock)
|
* [Proton C](https://qmk.fm/proton-c/) (out of stock)
|
||||||
* [Bonsai C](https://github.com/customMK/Bonsai-C) (Open Source, DIY/PCBA)
|
* [Bonsai C](https://github.com/customMK/Bonsai-C) (Open Source, DIY/PCBA)
|
||||||
* [Raspberry Pi 2040](https://www.sparkfun.com/products/18288) (not currently supported, no ETA)
|
* [STeMCell](https://github.com/megamind4089/STeMCell) (Open Source, DIY/PCBA)
|
||||||
|
* [Adafruit KB2040](https://learn.adafruit.com/adafruit-kb2040)
|
||||||
|
* [SparkFun Pro Micro - RP2040](https://www.sparkfun.com/products/18288)
|
||||||
|
* [Blok](https://boardsource.xyz/store/628b95b494dfa308a6581622)
|
||||||
|
|
||||||
There are other, non-Pro Micro compatible boards out there. The most popular being:
|
There are other, non-Pro Micro compatible boards out there. The most popular being:
|
||||||
* [WeAct Blackpill F411](https://www.aliexpress.com/item/1005001456186625.html) (~$6 USD)
|
* [WeAct Blackpill F411](https://www.aliexpress.com/item/1005001456186625.html) (~$6 USD)
|
||||||
|
|
|
@ -71,7 +71,7 @@ At the keyboard level we define a C macro (typically named `LAYOUT()`) which map
|
||||||
|
|
||||||
Notice how the second block of our `LAYOUT()` macro matches the Matrix Scanning array above? This macro is what will map the matrix scanning array to keycodes. However, if you look at a 17 key numpad you'll notice that it has 3 places where the matrix could have a switch but doesn't, due to larger keys. We have populated those spaces with `KC_NO` so that our keymap definition doesn't have to.
|
Notice how the second block of our `LAYOUT()` macro matches the Matrix Scanning array above? This macro is what will map the matrix scanning array to keycodes. However, if you look at a 17 key numpad you'll notice that it has 3 places where the matrix could have a switch but doesn't, due to larger keys. We have populated those spaces with `KC_NO` so that our keymap definition doesn't have to.
|
||||||
|
|
||||||
You can also use this macro to handle unusual matrix layouts, for example the [Clueboard rev 2](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/keyboards/clueboard/66/rev2/rev2.h). Explaining that is outside the scope of this document.
|
You can also use this macro to handle unusual matrix layouts, for example the [Alice](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/keyboards/sneakbox/aliceclone/aliceclone.h#L24). Explaining that is outside the scope of this document.
|
||||||
|
|
||||||
##### Keycode Assignment
|
##### Keycode Assignment
|
||||||
|
|
||||||
|
@ -127,36 +127,48 @@ Comparing against our keymap we can see that the pressed key is `KC_NUM`. From h
|
||||||
|
|
||||||
The `process_record()` function itself is deceptively simple, but hidden within is a gateway to overriding functionality at various levels of QMK. The chain of events is listed below, using cluecard whenever we need to look at the keyboard/keymap level functions. Depending on options set in `rules.mk` or elsewhere, only a subset of the functions below will be included in final firmware.
|
The `process_record()` function itself is deceptively simple, but hidden within is a gateway to overriding functionality at various levels of QMK. The chain of events is listed below, using cluecard whenever we need to look at the keyboard/keymap level functions. Depending on options set in `rules.mk` or elsewhere, only a subset of the functions below will be included in final firmware.
|
||||||
|
|
||||||
* [`void action_exec(keyevent_t event)`](https://github.com/qmk/qmk_firmware/blob/88fe5c16a5cdca5e3cf13ef3cd91f5f1e4898c37/quantum/action.c#L70-L131)
|
* [`void action_exec(keyevent_t event)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/action.c#L78-L140)
|
||||||
* [`void pre_process_record_quantum(keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/ed49dbeac4c0deba1c6b511ac1ce8f4c542e1b3e/quantum/quantum.c#L176-L185)
|
* [`void pre_process_record_quantum(keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/quantum.c#L204)
|
||||||
* [`bool process_combo(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_combo.c#L115)
|
* [`bool process_combo(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_combo.c#L521)
|
||||||
* [`void process_record(keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/tmk_core/common/action.c#L172)
|
* [`void process_record(keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/action.c#L254)
|
||||||
* [`bool process_record_quantum(keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/quantum.c#L206)
|
* [`bool process_record_quantum(keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/quantum.c#L224)
|
||||||
* [Map this record to a keycode](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/quantum.c#L226)
|
* [Map this record to a keycode](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/quantum.c#L225)
|
||||||
* [`void velocikey_accelerate(void)`](https://github.com/qmk/qmk_firmware/blob/c1c5922aae7b60b7c7d13d3769350eed9dda17ab/quantum/velocikey.c#L27)
|
* [`void velocikey_accelerate(void)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/velocikey.c#L27)
|
||||||
* [`void preprocess_tap_dance(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_tap_dance.c#L119)
|
* [`void update_wpm(uint16_t keycode)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/wpm.c#L109)
|
||||||
* [`bool process_key_lock(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_key_lock.c#L62)
|
* [`void preprocess_tap_dance(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_tap_dance.c#L118)
|
||||||
* [`bool process_clicky(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_clicky.c#L79)
|
* [`bool process_key_lock(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_key_lock.c#L64)
|
||||||
* [`bool process_haptic(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/2cee371bf125a6ec541dd7c5a809573facc7c456/drivers/haptic/haptic.c#L216)
|
* [`bool process_dynamic_macro(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_dynamic_macro.c#L160)
|
||||||
* [`bool process_record_kb(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/keyboards/clueboard/card/card.c#L20)
|
* [`bool process_clicky(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_clicky.c#L84)
|
||||||
* [`bool process_record_user(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/keyboards/clueboard/card/keymaps/default/keymap.c#L58)
|
* [`bool process_haptic(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_haptic.c#L87)
|
||||||
* [`bool process_midi(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_midi.c#L81)
|
* [`bool process_record_via(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/via.c#L160)
|
||||||
* [`bool process_audio(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_audio.c#L19)
|
* [`bool process_record_kb(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/keyboards/planck/ez/ez.c#L271)
|
||||||
* [`bool process_steno(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_steno.c#L160)
|
* [`bool process_record_user(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/keyboards/planck/keymaps/default/keymap.c#L183)
|
||||||
* [`bool process_music(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_music.c#L114)
|
* [`bool process_secure(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_secure.c#L23)
|
||||||
|
* [`bool process_sequencer(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_sequencer.c#L19)
|
||||||
|
* [`bool process_midi(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_midi.c#L75)
|
||||||
|
* [`bool process_audio(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_audio.c#L18)
|
||||||
|
* [`bool process_backlight(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_backlight.c#L25)
|
||||||
|
* [`bool process_steno(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_steno.c#L159)
|
||||||
|
* [`bool process_music(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_music.c#L103)
|
||||||
* [`bool process_key_override(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/5a1b857dea45a17698f6baa7dd1b7a7ea907fb0a/quantum/process_keycode/process_key_override.c#L397)
|
* [`bool process_key_override(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/5a1b857dea45a17698f6baa7dd1b7a7ea907fb0a/quantum/process_keycode/process_key_override.c#L397)
|
||||||
* [`bool process_tap_dance(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_tap_dance.c#L141)
|
* [`bool process_tap_dance(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_tap_dance.c#L135)
|
||||||
* [`bool process_unicode_common(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_unicode_common.c#L169)
|
* [`bool process_caps_word(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_caps_word.c#L17)
|
||||||
|
* [`bool process_unicode_common(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_unicode_common.c#L290)
|
||||||
calls one of:
|
calls one of:
|
||||||
* [`bool process_unicode(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_unicode.c#L20)
|
* [`bool process_unicode(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_unicode.c#L21)
|
||||||
* [`bool process_unicodemap(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_unicodemap.c#L46)
|
* [`bool process_unicodemap(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_unicodemap.c#L42)
|
||||||
* [`bool process_ucis(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_ucis.c#L95)
|
* [`bool process_ucis(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_ucis.c#L70)
|
||||||
* [`bool process_leader(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_leader.c#L51)
|
* [`bool process_leader(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_leader.c#L48)
|
||||||
* [`bool process_printer(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_printer.c#L77)
|
* [`bool process_printer(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_printer.c#L77)
|
||||||
* [`bool process_auto_shift(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_auto_shift.c#L94)
|
* [`bool process_auto_shift(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_auto_shift.c#L353)
|
||||||
* `bool process_dynamic_tapping_term(uint16_t keycode, keyrecord_t *record)`
|
* [`bool process_dynamic_tapping_term(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_dynamic_tapping_term.c#L35)
|
||||||
* [`bool process_terminal(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_terminal.c#L264)
|
* [`bool process_space_cadet(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_space_cadet.c#L123)
|
||||||
* [Identify and process Quantum-specific keycodes](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/quantum.c#L291)
|
* [`bool process_magic(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_magic.c#L40)
|
||||||
|
* [`bool process_grave_esc(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_grave_esc.c#L23)
|
||||||
|
* [`bool process_rgb(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_rgb.c#L53)
|
||||||
|
* [`bool process_joystick(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_joystick.c#L9)
|
||||||
|
* [`bool process_programmable_button(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_programmable_button.c#L21)
|
||||||
|
* [Identify and process Quantum-specific keycodes](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/quantum.c#L343)
|
||||||
|
|
||||||
At any step during this chain of events a function (such as `process_record_kb()`) can `return false` to halt all further processing.
|
At any step during this chain of events a function (such as `process_record_kb()`) can `return false` to halt all further processing.
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,12 @@ These LEDs are called "addressable" because instead of using a wire per color, e
|
||||||
## Supported Driver Types
|
## Supported Driver Types
|
||||||
|
|
||||||
| | AVR | ARM |
|
| | AVR | ARM |
|
||||||
|----------|--------------------|--------------------|
|
| -------- | ------------------ | ------------------ |
|
||||||
| bit bang | :heavy_check_mark: | :heavy_check_mark: |
|
| bit bang | :heavy_check_mark: | :heavy_check_mark: |
|
||||||
| I2C | :heavy_check_mark: | |
|
| I2C | :heavy_check_mark: | |
|
||||||
| SPI | | :heavy_check_mark: |
|
| SPI | | :heavy_check_mark: |
|
||||||
| PWM | | :heavy_check_mark: |
|
| PWM | | :heavy_check_mark: |
|
||||||
|
| PIO | | :heavy_check_mark: |
|
||||||
|
|
||||||
## Driver configuration
|
## Driver configuration
|
||||||
|
|
||||||
|
@ -33,11 +34,11 @@ The default setting is 280 µs, which should work for most cases, but this can b
|
||||||
Some variants of the WS2812 may have their color components in a different physical or logical order. For example, the WS2812B-2020 has physically swapped red and green LEDs, which causes the wrong color to be displayed, because the default order of the bytes sent over the wire is defined as GRB.
|
Some variants of the WS2812 may have their color components in a different physical or logical order. For example, the WS2812B-2020 has physically swapped red and green LEDs, which causes the wrong color to be displayed, because the default order of the bytes sent over the wire is defined as GRB.
|
||||||
In this case, you can change the byte order by defining `WS2812_BYTE_ORDER` as one of the following values:
|
In this case, you can change the byte order by defining `WS2812_BYTE_ORDER` as one of the following values:
|
||||||
|
|
||||||
|Byte order |Known devices |
|
| Byte order | Known devices |
|
||||||
|---------------------------------|-----------------------------|
|
| --------------------------------- | ----------------------------- |
|
||||||
|`WS2812_BYTE_ORDER_GRB` (default)|Most WS2812's, SK6812, SK6805|
|
| `WS2812_BYTE_ORDER_GRB` (default) | Most WS2812's, SK6812, SK6805 |
|
||||||
|`WS2812_BYTE_ORDER_RGB` |WS2812B-2020 |
|
| `WS2812_BYTE_ORDER_RGB` | WS2812B-2020 |
|
||||||
|`WS2812_BYTE_ORDER_BGR` |TM1812 |
|
| `WS2812_BYTE_ORDER_BGR` | TM1812 |
|
||||||
|
|
||||||
|
|
||||||
### Bitbang
|
### Bitbang
|
||||||
|
@ -54,13 +55,13 @@ WS2812_DRIVER = bitbang
|
||||||
The WS2812 LED communication topology depends on a serialized timed window. Different versions of the addressable LEDs have differing requirements for the timing parameters, for instance, of the SK6812.
|
The WS2812 LED communication topology depends on a serialized timed window. Different versions of the addressable LEDs have differing requirements for the timing parameters, for instance, of the SK6812.
|
||||||
You can tune these parameters through the definition of the following macros:
|
You can tune these parameters through the definition of the following macros:
|
||||||
|
|
||||||
| Macro |Default | AVR | ARM |
|
| Macro | Default | AVR | ARM |
|
||||||
|---------------------|--------------------------------------------|--------------------|--------------------|
|
| --------------- | ---------------------------- | ------------------ | ------------------ |
|
||||||
|`WS2812_TIMING` |`1250` | :heavy_check_mark: | :heavy_check_mark: |
|
| `WS2812_TIMING` | `1250` | :heavy_check_mark: | :heavy_check_mark: |
|
||||||
|`WS2812_T0H` |`350` | :heavy_check_mark: | :heavy_check_mark: |
|
| `WS2812_T0H` | `350` | :heavy_check_mark: | :heavy_check_mark: |
|
||||||
|`WS2812_T0L` |`WS2812_TIMING - WS2812_T0H` | | :heavy_check_mark: |
|
| `WS2812_T0L` | `WS2812_TIMING - WS2812_T0H` | | :heavy_check_mark: |
|
||||||
|`WS2812_T1H` |`900` | :heavy_check_mark: | :heavy_check_mark: |
|
| `WS2812_T1H` | `900` | :heavy_check_mark: | :heavy_check_mark: |
|
||||||
|`WS2812_T1L` |`WS2812_TIMING - WS2812_T1H` | | :heavy_check_mark: |
|
| `WS2812_T1L` | `WS2812_TIMING - WS2812_T1H` | | :heavy_check_mark: |
|
||||||
|
|
||||||
### I2C
|
### I2C
|
||||||
Targeting boards where WS2812 support is offloaded to a 2nd MCU. Currently the driver is limited to AVR given the known consumers are ps2avrGB/BMC. To configure it, add this to your rules.mk:
|
Targeting boards where WS2812 support is offloaded to a 2nd MCU. Currently the driver is limited to AVR given the known consumers are ps2avrGB/BMC. To configure it, add this to your rules.mk:
|
||||||
|
@ -107,16 +108,16 @@ To adjust the baudrate at which the SPI peripheral is configured, users will nee
|
||||||
|
|
||||||
Only divisors of 2, 4, 8, 16, 32, 64, 128 and 256 are supported by hardware.
|
Only divisors of 2, 4, 8, 16, 32, 64, 128 and 256 are supported by hardware.
|
||||||
|
|
||||||
|Define |Default|Description |
|
| Define | Default | Description |
|
||||||
|--------------------|-------|-------------------------------------|
|
| -------------------- | ------- | ----------------------------------- |
|
||||||
|`WS2812_SPI_DIVISOR`|`16` |SPI source clock peripheral divisor |
|
| `WS2812_SPI_DIVISOR` | `16` | SPI source clock peripheral divisor |
|
||||||
|
|
||||||
#### Testing Notes
|
#### Testing Notes
|
||||||
|
|
||||||
While not an exhaustive list, the following table provides the scenarios that have been partially validated:
|
While not an exhaustive list, the following table provides the scenarios that have been partially validated:
|
||||||
|
|
||||||
| | SPI1 | SPI2 | SPI3 |
|
| | SPI1 | SPI2 | SPI3 |
|
||||||
|------|---------------------------------------------|-----------------------------------------|-----------------------|
|
| ---- | ------------------------------------------- | --------------------------------------- | --------------------- |
|
||||||
| f072 | ? | B15 :heavy_check_mark: (needs SCK: B13) | N/A |
|
| f072 | ? | B15 :heavy_check_mark: (needs SCK: B13) | N/A |
|
||||||
| f103 | A7 :heavy_check_mark: | B15 :heavy_check_mark: | N/A |
|
| f103 | A7 :heavy_check_mark: | B15 :heavy_check_mark: | N/A |
|
||||||
| f303 | A7 :heavy_check_mark: B5 :heavy_check_mark: | B15 :heavy_check_mark: | B5 :heavy_check_mark: |
|
| f303 | A7 :heavy_check_mark: B5 :heavy_check_mark: | B15 :heavy_check_mark: | B5 :heavy_check_mark: |
|
||||||
|
@ -150,15 +151,32 @@ You must also turn on the PWM feature in your halconf.h and mcuconf.h
|
||||||
|
|
||||||
While not an exhaustive list, the following table provides the scenarios that have been partially validated:
|
While not an exhaustive list, the following table provides the scenarios that have been partially validated:
|
||||||
|
|
||||||
| | Status |
|
| | Status |
|
||||||
|-|-|
|
| --------- | ------------------ |
|
||||||
| f072 | ? |
|
| f072 | ? |
|
||||||
| f103 | :heavy_check_mark: |
|
| f103 | :heavy_check_mark: |
|
||||||
| f303 | :heavy_check_mark: |
|
| f303 | :heavy_check_mark: |
|
||||||
| f401/f411 | :heavy_check_mark: |
|
| f401/f411 | :heavy_check_mark: |
|
||||||
|
|
||||||
*Other supported ChibiOS boards and/or pins may function, it will be highly chip and configuration dependent.*
|
*Other supported ChibiOS boards and/or pins may function, it will be highly chip and configuration dependent.*
|
||||||
|
|
||||||
|
### PIO
|
||||||
|
|
||||||
|
Targeting Raspberry Pi RP2040 boards only where WS2812 support is offloaded to an dedicated PIO implementation. This offloads processing of the WS2812 protocol from the MCU to a dedicated PIO program using DMA transfers.
|
||||||
|
|
||||||
|
To configure it, add this to your rules.mk:
|
||||||
|
|
||||||
|
```make
|
||||||
|
WS2812_DRIVER = vendor
|
||||||
|
```
|
||||||
|
|
||||||
|
Configure the hardware via your config.h:
|
||||||
|
```c
|
||||||
|
#define WS2812_PIO_USE_PIO1 // Force the usage of PIO1 peripheral, by default the WS2812 implementation uses the PIO0 peripheral
|
||||||
|
```
|
||||||
|
|
||||||
|
The WS2812 PIO programm uses 1 state machine, 4 instructions and does not use any interrupt handlers.
|
||||||
|
|
||||||
### Push Pull and Open Drain Configuration
|
### Push Pull and Open Drain Configuration
|
||||||
The default configuration is a push pull on the defined pin.
|
The default configuration is a push pull on the defined pin.
|
||||||
This can be configured for bitbang, PWM and SPI.
|
This can be configured for bitbang, PWM and SPI.
|
||||||
|
|
|
@ -91,7 +91,6 @@
|
||||||
* [换手](zh-cn/feature_swap_hands.md)
|
* [换手](zh-cn/feature_swap_hands.md)
|
||||||
* [一键多用](zh-cn/feature_tap_dance.md)
|
* [一键多用](zh-cn/feature_tap_dance.md)
|
||||||
* [点按配置](zh-cn/tap_hold.md)
|
* [点按配置](zh-cn/tap_hold.md)
|
||||||
* [终端](zh-cn/feature_terminal.md)
|
|
||||||
* [Unicode](zh-cn/feature_unicode.md)
|
* [Unicode](zh-cn/feature_unicode.md)
|
||||||
* [用户空间](zh-cn/feature_userspace.md)
|
* [用户空间](zh-cn/feature_userspace.md)
|
||||||
* [WPM计算](zh-cn/feature_wpm.md)
|
* [WPM计算](zh-cn/feature_wpm.md)
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue