Merge remote-tracking branch 'origin/develop'
This commit is contained in:
commit
e793128991
|
@ -5,6 +5,9 @@ AlignConsecutiveAssignments: 'true'
|
||||||
AlignConsecutiveDeclarations: 'true'
|
AlignConsecutiveDeclarations: 'true'
|
||||||
AlignOperands: 'true'
|
AlignOperands: 'true'
|
||||||
AllowAllParametersOfDeclarationOnNextLine: 'false'
|
AllowAllParametersOfDeclarationOnNextLine: 'false'
|
||||||
|
AllowShortCaseLabelsOnASingleLine: 'false'
|
||||||
|
AllowShortFunctionsOnASingleLine: Empty
|
||||||
|
AllowShortLoopsOnASingleLine: 'false'
|
||||||
AlwaysBreakAfterDefinitionReturnType: None
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
AlwaysBreakAfterReturnType: None
|
AlwaysBreakAfterReturnType: None
|
||||||
AlwaysBreakBeforeMultilineStrings: 'false'
|
AlwaysBreakBeforeMultilineStrings: 'false'
|
||||||
|
@ -20,6 +23,7 @@ SortIncludes: 'false'
|
||||||
SpaceBeforeAssignmentOperators: 'true'
|
SpaceBeforeAssignmentOperators: 'true'
|
||||||
SpaceBeforeParens: ControlStatements
|
SpaceBeforeParens: ControlStatements
|
||||||
SpaceInEmptyParentheses: 'false'
|
SpaceInEmptyParentheses: 'false'
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
TabWidth: '4'
|
TabWidth: '4'
|
||||||
UseTab: Never
|
UseTab: Never
|
||||||
|
|
||||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,6 +3,7 @@
|
||||||
*.swp
|
*.swp
|
||||||
*~
|
*~
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
._*
|
||||||
|
|
||||||
# Build artifacts
|
# Build artifacts
|
||||||
.clang_complete
|
.clang_complete
|
||||||
|
|
135
Makefile
135
Makefile
|
@ -19,6 +19,10 @@ endif
|
||||||
# Otherwise the [OK], [ERROR] and [WARN] messages won't be displayed correctly
|
# Otherwise the [OK], [ERROR] and [WARN] messages won't be displayed correctly
|
||||||
override SILENT := false
|
override SILENT := false
|
||||||
|
|
||||||
|
ifdef SKIP_VERSION
|
||||||
|
SKIP_GIT := yes
|
||||||
|
endif
|
||||||
|
|
||||||
ifndef SUB_IS_SILENT
|
ifndef SUB_IS_SILENT
|
||||||
ifndef SKIP_GIT
|
ifndef SKIP_GIT
|
||||||
QMK_VERSION := $(shell git describe --abbrev=0 --tags 2>/dev/null)
|
QMK_VERSION := $(shell git describe --abbrev=0 --tags 2>/dev/null)
|
||||||
|
@ -50,48 +54,12 @@ ABS_ROOT_MAKEFILE := $(abspath $(ROOT_MAKEFILE))
|
||||||
ABS_STARTING_DIR := $(dir $(ABS_STARTING_MAKEFILE))
|
ABS_STARTING_DIR := $(dir $(ABS_STARTING_MAKEFILE))
|
||||||
ABS_ROOT_DIR := $(dir $(ABS_ROOT_MAKEFILE))
|
ABS_ROOT_DIR := $(dir $(ABS_ROOT_MAKEFILE))
|
||||||
STARTING_DIR := $(subst $(ABS_ROOT_DIR),,$(ABS_STARTING_DIR))
|
STARTING_DIR := $(subst $(ABS_ROOT_DIR),,$(ABS_STARTING_DIR))
|
||||||
BUILD_DIR := $(ROOT_DIR)/.build
|
|
||||||
TEST_DIR := $(BUILD_DIR)/test
|
include paths.mk
|
||||||
|
|
||||||
|
TEST_OUTPUT_DIR := $(BUILD_DIR)/test
|
||||||
ERROR_FILE := $(BUILD_DIR)/error_occurred
|
ERROR_FILE := $(BUILD_DIR)/error_occurred
|
||||||
|
|
||||||
# Helper function to process the newt element of a space separated path
|
|
||||||
# It works a bit like the traditional functional head tail
|
|
||||||
# so the CURRENT_PATH_ELEMENT will become the new head
|
|
||||||
# and the PATH_ELEMENTS are the rest that are still unprocessed
|
|
||||||
define NEXT_PATH_ELEMENT
|
|
||||||
$$(eval CURRENT_PATH_ELEMENT := $$(firstword $$(PATH_ELEMENTS)))
|
|
||||||
$$(eval PATH_ELEMENTS := $$(wordlist 2,9999,$$(PATH_ELEMENTS)))
|
|
||||||
endef
|
|
||||||
|
|
||||||
# We change the / to spaces so that we more easily can work with the elements
|
|
||||||
# separately
|
|
||||||
PATH_ELEMENTS := $(subst /, ,$(STARTING_DIR))
|
|
||||||
# Initialize the path elements list for further processing
|
|
||||||
$(eval $(call NEXT_PATH_ELEMENT))
|
|
||||||
|
|
||||||
|
|
||||||
# Phony targets to enable a few simple make commands outside the main processing below.
|
|
||||||
.PHONY: list-keyboards
|
|
||||||
list-keyboards:
|
|
||||||
util/list_keyboards.sh | sort -u | tr '\n' ' '
|
|
||||||
|
|
||||||
.PHONY: generate-keyboards-file
|
|
||||||
generate-keyboards-file:
|
|
||||||
util/list_keyboards.sh | sort -u
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
clean:
|
|
||||||
echo -n 'Deleting .build/ ... '
|
|
||||||
rm -rf $(BUILD_DIR)
|
|
||||||
echo 'done.'
|
|
||||||
|
|
||||||
.PHONY: distclean
|
|
||||||
distclean: clean
|
|
||||||
echo -n 'Deleting *.bin, *.hex, and *.uf2 ... '
|
|
||||||
rm -f *.bin *.hex *.uf2
|
|
||||||
echo 'done.'
|
|
||||||
|
|
||||||
|
|
||||||
.DEFAULT_GOAL := all:all
|
.DEFAULT_GOAL := all:all
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,53 +87,20 @@ endef
|
||||||
# a function that returns the value
|
# a function that returns the value
|
||||||
COMPARE_AND_REMOVE_FROM_RULE = $(eval $(call COMPARE_AND_REMOVE_FROM_RULE_HELPER,$1))$(RULE_FOUND)
|
COMPARE_AND_REMOVE_FROM_RULE = $(eval $(call COMPARE_AND_REMOVE_FROM_RULE_HELPER,$1))$(RULE_FOUND)
|
||||||
|
|
||||||
|
# Try to find a match for the start of the rule to be checked
|
||||||
# Recursively try to find a match for the start of the rule to be checked
|
|
||||||
# $1 The list to be checked
|
|
||||||
# If a match is found, then RULE_FOUND is set to true
|
|
||||||
# and MATCHED_ITEM to the item that was matched
|
|
||||||
define TRY_TO_MATCH_RULE_FROM_LIST_HELPER3
|
|
||||||
ifneq ($1,)
|
|
||||||
ifeq ($$(call COMPARE_AND_REMOVE_FROM_RULE,$$(firstword $1)),true)
|
|
||||||
MATCHED_ITEM := $$(firstword $1)
|
|
||||||
else
|
|
||||||
$$(eval $$(call TRY_TO_MATCH_RULE_FROM_LIST_HELPER3,$$(wordlist 2,9999,$1)))
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endef
|
|
||||||
|
|
||||||
# A recursive helper function for finding the longest match
|
|
||||||
# $1 The list to be checked
|
|
||||||
# It works by always removing the currently matched item from the list
|
|
||||||
define TRY_TO_MATCH_RULE_FROM_LIST_HELPER2
|
|
||||||
# Stop the recursion when the list is empty
|
|
||||||
ifneq ($1,)
|
|
||||||
RULE_BEFORE := $$(RULE)
|
|
||||||
$$(eval $$(call TRY_TO_MATCH_RULE_FROM_LIST_HELPER3,$1))
|
|
||||||
# If a match is found in the current list, otherwise just return what we had before
|
|
||||||
ifeq ($$(RULE_FOUND),true)
|
|
||||||
# Save the best match so far and call itself recursively
|
|
||||||
BEST_MATCH := $$(MATCHED_ITEM)
|
|
||||||
BEST_MATCH_RULE := $$(RULE)
|
|
||||||
RULE_FOUND := false
|
|
||||||
RULE := $$(RULE_BEFORE)
|
|
||||||
$$(eval $$(call TRY_TO_MATCH_RULE_FROM_LIST_HELPER2,$$(filter-out $$(MATCHED_ITEM),$1)))
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endef
|
|
||||||
|
|
||||||
|
|
||||||
# Recursively try to find the longest match for the start of the rule to be checked
|
|
||||||
# $1 The list to be checked
|
# $1 The list to be checked
|
||||||
# If a match is found, then RULE_FOUND is set to true
|
# If a match is found, then RULE_FOUND is set to true
|
||||||
# and MATCHED_ITEM to the item that was matched
|
# and MATCHED_ITEM to the item that was matched
|
||||||
define TRY_TO_MATCH_RULE_FROM_LIST_HELPER
|
define TRY_TO_MATCH_RULE_FROM_LIST_HELPER
|
||||||
BEST_MATCH :=
|
# Split on ":", padding with empty strings to avoid indexing issues
|
||||||
$$(eval $$(call TRY_TO_MATCH_RULE_FROM_LIST_HELPER2,$1))
|
TOKEN1:=$$(shell python3 -c "import sys; print((sys.argv[1].split(':',1)+[''])[0])" $$(RULE))
|
||||||
ifneq ($$(BEST_MATCH),)
|
TOKENr:=$$(shell python3 -c "import sys; print((sys.argv[1].split(':',1)+[''])[1])" $$(RULE))
|
||||||
|
|
||||||
|
FOUNDx:=$$(shell echo $1 | tr " " "\n" | grep -Fx $$(TOKEN1))
|
||||||
|
ifneq ($$(FOUNDx),)
|
||||||
|
RULE := $$(TOKENr)
|
||||||
RULE_FOUND := true
|
RULE_FOUND := true
|
||||||
RULE := $$(BEST_MATCH_RULE)
|
MATCHED_ITEM := $$(TOKEN1)
|
||||||
MATCHED_ITEM := $$(BEST_MATCH)
|
|
||||||
else
|
else
|
||||||
RULE_FOUND := false
|
RULE_FOUND := false
|
||||||
MATCHED_ITEM :=
|
MATCHED_ITEM :=
|
||||||
|
@ -340,7 +275,7 @@ define PARSE_KEYMAP
|
||||||
# Specify the variables that we are passing forward to submake
|
# Specify the variables that we are passing forward to submake
|
||||||
MAKE_VARS := KEYBOARD=$$(CURRENT_KB) KEYMAP=$$(CURRENT_KM) REQUIRE_PLATFORM_KEY=$$(REQUIRE_PLATFORM_KEY) QMK_BIN=$$(QMK_BIN)
|
MAKE_VARS := KEYBOARD=$$(CURRENT_KB) KEYMAP=$$(CURRENT_KM) REQUIRE_PLATFORM_KEY=$$(REQUIRE_PLATFORM_KEY) QMK_BIN=$$(QMK_BIN)
|
||||||
# And the first part of the make command
|
# And the first part of the make command
|
||||||
MAKE_CMD := $$(MAKE) -r -R -C $(ROOT_DIR) -f build_keyboard.mk $$(MAKE_TARGET)
|
MAKE_CMD := $$(MAKE) -r -R -C $(ROOT_DIR) -f $(BUILDDEFS_PATH)/build_keyboard.mk $$(MAKE_TARGET)
|
||||||
# The message to display
|
# The message to display
|
||||||
MAKE_MSG := $$(MSG_MAKE_KB)
|
MAKE_MSG := $$(MSG_MAKE_KB)
|
||||||
# We run the command differently, depending on if we want more output or not
|
# We run the command differently, depending on if we want more output or not
|
||||||
|
@ -382,12 +317,12 @@ define BUILD_TEST
|
||||||
TEST_NAME := $$(notdir $$(TEST_PATH))
|
TEST_NAME := $$(notdir $$(TEST_PATH))
|
||||||
MAKE_TARGET := $2
|
MAKE_TARGET := $2
|
||||||
COMMAND := $1
|
COMMAND := $1
|
||||||
MAKE_CMD := $$(MAKE) -r -R -C $(ROOT_DIR) -f build_test.mk $$(MAKE_TARGET)
|
MAKE_CMD := $$(MAKE) -r -R -C $(ROOT_DIR) -f $(BUILDDEFS_PATH)/build_test.mk $$(MAKE_TARGET)
|
||||||
MAKE_VARS := TEST=$$(TEST_NAME) TEST_PATH=$$(TEST_PATH) FULL_TESTS="$$(FULL_TESTS)"
|
MAKE_VARS := TEST=$$(TEST_NAME) TEST_PATH=$$(TEST_PATH) FULL_TESTS="$$(FULL_TESTS)"
|
||||||
MAKE_MSG := $$(MSG_MAKE_TEST)
|
MAKE_MSG := $$(MSG_MAKE_TEST)
|
||||||
$$(eval $$(call BUILD))
|
$$(eval $$(call BUILD))
|
||||||
ifneq ($$(MAKE_TARGET),clean)
|
ifneq ($$(MAKE_TARGET),clean)
|
||||||
TEST_EXECUTABLE := $$(TEST_DIR)/$$(TEST_NAME).elf
|
TEST_EXECUTABLE := $$(TEST_OUTPUT_DIR)/$$(TEST_NAME).elf
|
||||||
TESTS += $$(TEST_NAME)
|
TESTS += $$(TEST_NAME)
|
||||||
TEST_MSG := $$(MSG_TEST)
|
TEST_MSG := $$(MSG_TEST)
|
||||||
$$(TEST_NAME)_COMMAND := \
|
$$(TEST_NAME)_COMMAND := \
|
||||||
|
@ -404,6 +339,7 @@ define PARSE_TEST
|
||||||
TESTS :=
|
TESTS :=
|
||||||
TEST_NAME := $$(firstword $$(subst :, ,$$(RULE)))
|
TEST_NAME := $$(firstword $$(subst :, ,$$(RULE)))
|
||||||
TEST_TARGET := $$(subst $$(TEST_NAME),,$$(subst $$(TEST_NAME):,,$$(RULE)))
|
TEST_TARGET := $$(subst $$(TEST_NAME),,$$(subst $$(TEST_NAME):,,$$(RULE)))
|
||||||
|
include $(BUILDDEFS_PATH)/testlist.mk
|
||||||
ifeq ($$(TEST_NAME),all)
|
ifeq ($$(TEST_NAME),all)
|
||||||
MATCHED_TESTS := $$(TEST_LIST)
|
MATCHED_TESTS := $$(TEST_LIST)
|
||||||
else
|
else
|
||||||
|
@ -426,7 +362,6 @@ define SET_SILENT_MODE
|
||||||
endif
|
endif
|
||||||
endef
|
endef
|
||||||
|
|
||||||
include paths.mk
|
|
||||||
include $(BUILDDEFS_PATH)/message.mk
|
include $(BUILDDEFS_PATH)/message.mk
|
||||||
|
|
||||||
ifeq ($(strip $(BREAK_ON_ERRORS)), yes)
|
ifeq ($(strip $(BREAK_ON_ERRORS)), yes)
|
||||||
|
@ -496,14 +431,22 @@ git-submodule:
|
||||||
git submodule sync --recursive
|
git submodule sync --recursive
|
||||||
git submodule update --init --recursive --progress
|
git submodule update --init --recursive --progress
|
||||||
|
|
||||||
# Generate the version.h file
|
.PHONY: list-keyboards
|
||||||
ifdef SKIP_GIT
|
list-keyboards:
|
||||||
VERSION_H_FLAGS := --skip-git
|
util/list_keyboards.sh | sort -u | tr '\n' ' '
|
||||||
endif
|
|
||||||
ifdef SKIP_VERSION
|
|
||||||
VERSION_H_FLAGS := --skip-all
|
|
||||||
SKIP_GIT := yes
|
|
||||||
endif
|
|
||||||
$(shell $(QMK_BIN) generate-version-h $(VERSION_H_FLAGS) -q -o quantum/version.h)
|
|
||||||
|
|
||||||
include $(ROOT_DIR)/testlist.mk
|
.PHONY: generate-keyboards-file
|
||||||
|
generate-keyboards-file:
|
||||||
|
util/list_keyboards.sh | sort -u
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
echo -n 'Deleting .build/ ... '
|
||||||
|
rm -rf $(BUILD_DIR)
|
||||||
|
echo 'done.'
|
||||||
|
|
||||||
|
.PHONY: distclean
|
||||||
|
distclean: clean
|
||||||
|
echo -n 'Deleting *.bin, *.hex, and *.uf2 ... '
|
||||||
|
rm -f *.bin *.hex *.uf2
|
||||||
|
echo 'done.'
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
# bootloadhid HIDBootFlash compatible (ATmega32A)
|
# bootloadhid HIDBootFlash compatible (ATmega32A)
|
||||||
# usbasploader USBaspLoader (ATmega328P)
|
# usbasploader USBaspLoader (ATmega328P)
|
||||||
# ARM:
|
# ARM:
|
||||||
|
# halfkay PJRC Teensy
|
||||||
# kiibohd Input:Club Kiibohd bootloader (only used on their boards)
|
# kiibohd Input:Club Kiibohd bootloader (only used on their boards)
|
||||||
# stm32duino STM32Duino (STM32F103x8)
|
# stm32duino STM32Duino (STM32F103x8)
|
||||||
# stm32-dfu STM32 USB DFU in ROM
|
# stm32-dfu STM32 USB DFU in ROM
|
||||||
|
@ -37,12 +38,23 @@
|
||||||
# RISC-V:
|
# RISC-V:
|
||||||
# gd32v-dfu GD32V USB DFU in ROM
|
# gd32v-dfu GD32V USB DFU in ROM
|
||||||
#
|
#
|
||||||
|
# If you need to provide your own implementation, you can set inside `rules.mk`
|
||||||
|
# `BOOTLOADER = custom` -- you'll need to provide your own implementations. See
|
||||||
|
# the respective file under `platforms/<PLATFORM>/bootloaders/custom.c` to see
|
||||||
|
# which functions may be overridden.
|
||||||
|
#
|
||||||
# BOOTLOADER_SIZE can still be defined manually, but it's recommended
|
# BOOTLOADER_SIZE can still be defined manually, but it's recommended
|
||||||
# you add any possible configuration to this list
|
# you add any possible configuration to this list
|
||||||
|
|
||||||
|
ifeq ($(strip $(BOOTLOADER)), custom)
|
||||||
|
OPT_DEFS += -DBOOTLOADER_CUSTOM
|
||||||
|
BOOTLOADER_TYPE = custom
|
||||||
|
endif
|
||||||
ifeq ($(strip $(BOOTLOADER)), atmel-dfu)
|
ifeq ($(strip $(BOOTLOADER)), atmel-dfu)
|
||||||
OPT_DEFS += -DBOOTLOADER_ATMEL_DFU
|
OPT_DEFS += -DBOOTLOADER_ATMEL_DFU
|
||||||
OPT_DEFS += -DBOOTLOADER_DFU
|
OPT_DEFS += -DBOOTLOADER_DFU
|
||||||
|
BOOTLOADER_TYPE = dfu
|
||||||
|
|
||||||
ifneq (,$(filter $(MCU), at90usb162 atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647))
|
ifneq (,$(filter $(MCU), at90usb162 atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647))
|
||||||
BOOTLOADER_SIZE = 4096
|
BOOTLOADER_SIZE = 4096
|
||||||
endif
|
endif
|
||||||
|
@ -53,6 +65,8 @@ endif
|
||||||
ifeq ($(strip $(BOOTLOADER)), lufa-dfu)
|
ifeq ($(strip $(BOOTLOADER)), lufa-dfu)
|
||||||
OPT_DEFS += -DBOOTLOADER_LUFA_DFU
|
OPT_DEFS += -DBOOTLOADER_LUFA_DFU
|
||||||
OPT_DEFS += -DBOOTLOADER_DFU
|
OPT_DEFS += -DBOOTLOADER_DFU
|
||||||
|
BOOTLOADER_TYPE = dfu
|
||||||
|
|
||||||
ifneq (,$(filter $(MCU), at90usb162 atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647))
|
ifneq (,$(filter $(MCU), at90usb162 atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647))
|
||||||
BOOTLOADER_SIZE ?= 4096
|
BOOTLOADER_SIZE ?= 4096
|
||||||
endif
|
endif
|
||||||
|
@ -63,6 +77,8 @@ endif
|
||||||
ifeq ($(strip $(BOOTLOADER)), qmk-dfu)
|
ifeq ($(strip $(BOOTLOADER)), qmk-dfu)
|
||||||
OPT_DEFS += -DBOOTLOADER_QMK_DFU
|
OPT_DEFS += -DBOOTLOADER_QMK_DFU
|
||||||
OPT_DEFS += -DBOOTLOADER_DFU
|
OPT_DEFS += -DBOOTLOADER_DFU
|
||||||
|
BOOTLOADER_TYPE = dfu
|
||||||
|
|
||||||
ifneq (,$(filter $(MCU), at90usb162 atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647))
|
ifneq (,$(filter $(MCU), at90usb162 atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647))
|
||||||
BOOTLOADER_SIZE ?= 4096
|
BOOTLOADER_SIZE ?= 4096
|
||||||
endif
|
endif
|
||||||
|
@ -73,10 +89,14 @@ endif
|
||||||
ifeq ($(strip $(BOOTLOADER)), qmk-hid)
|
ifeq ($(strip $(BOOTLOADER)), qmk-hid)
|
||||||
OPT_DEFS += -DBOOTLOADER_QMK_HID
|
OPT_DEFS += -DBOOTLOADER_QMK_HID
|
||||||
OPT_DEFS += -DBOOTLOADER_HID
|
OPT_DEFS += -DBOOTLOADER_HID
|
||||||
|
BOOTLOADER_TYPE = dfu
|
||||||
|
|
||||||
BOOTLOADER_SIZE ?= 4096
|
BOOTLOADER_SIZE ?= 4096
|
||||||
endif
|
endif
|
||||||
ifeq ($(strip $(BOOTLOADER)), halfkay)
|
ifeq ($(strip $(BOOTLOADER)), halfkay)
|
||||||
OPT_DEFS += -DBOOTLOADER_HALFKAY
|
OPT_DEFS += -DBOOTLOADER_HALFKAY
|
||||||
|
BOOTLOADER_TYPE = halfkay
|
||||||
|
|
||||||
ifeq ($(strip $(MCU)), atmega32u4)
|
ifeq ($(strip $(MCU)), atmega32u4)
|
||||||
BOOTLOADER_SIZE = 512
|
BOOTLOADER_SIZE = 512
|
||||||
endif
|
endif
|
||||||
|
@ -86,18 +106,26 @@ ifeq ($(strip $(BOOTLOADER)), halfkay)
|
||||||
endif
|
endif
|
||||||
ifeq ($(strip $(BOOTLOADER)), caterina)
|
ifeq ($(strip $(BOOTLOADER)), caterina)
|
||||||
OPT_DEFS += -DBOOTLOADER_CATERINA
|
OPT_DEFS += -DBOOTLOADER_CATERINA
|
||||||
|
BOOTLOADER_TYPE = caterina
|
||||||
|
|
||||||
BOOTLOADER_SIZE = 4096
|
BOOTLOADER_SIZE = 4096
|
||||||
endif
|
endif
|
||||||
ifneq (,$(filter $(BOOTLOADER), bootloadhid bootloadHID))
|
ifneq (,$(filter $(BOOTLOADER), bootloadhid bootloadHID))
|
||||||
OPT_DEFS += -DBOOTLOADER_BOOTLOADHID
|
OPT_DEFS += -DBOOTLOADER_BOOTLOADHID
|
||||||
|
BOOTLOADER_TYPE = bootloadhid
|
||||||
|
|
||||||
BOOTLOADER_SIZE = 4096
|
BOOTLOADER_SIZE = 4096
|
||||||
endif
|
endif
|
||||||
ifneq (,$(filter $(BOOTLOADER), usbasploader USBasp))
|
ifneq (,$(filter $(BOOTLOADER), usbasploader USBasp))
|
||||||
OPT_DEFS += -DBOOTLOADER_USBASP
|
OPT_DEFS += -DBOOTLOADER_USBASP
|
||||||
|
BOOTLOADER_TYPE = usbasploader
|
||||||
|
|
||||||
BOOTLOADER_SIZE = 4096
|
BOOTLOADER_SIZE = 4096
|
||||||
endif
|
endif
|
||||||
ifeq ($(strip $(BOOTLOADER)), lufa-ms)
|
ifeq ($(strip $(BOOTLOADER)), lufa-ms)
|
||||||
OPT_DEFS += -DBOOTLOADER_MS
|
OPT_DEFS += -DBOOTLOADER_MS
|
||||||
|
BOOTLOADER_TYPE = dfu
|
||||||
|
|
||||||
BOOTLOADER_SIZE ?= 8192
|
BOOTLOADER_SIZE ?= 8192
|
||||||
FIRMWARE_FORMAT = bin
|
FIRMWARE_FORMAT = bin
|
||||||
cpfirmware: lufa_warning
|
cpfirmware: lufa_warning
|
||||||
|
@ -115,6 +143,7 @@ endif
|
||||||
|
|
||||||
ifeq ($(strip $(BOOTLOADER)), stm32-dfu)
|
ifeq ($(strip $(BOOTLOADER)), stm32-dfu)
|
||||||
OPT_DEFS += -DBOOTLOADER_STM32_DFU
|
OPT_DEFS += -DBOOTLOADER_STM32_DFU
|
||||||
|
BOOTLOADER_TYPE = stm32_dfu
|
||||||
|
|
||||||
# Options to pass to dfu-util when flashing
|
# Options to pass to dfu-util when flashing
|
||||||
DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave
|
DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave
|
||||||
|
@ -122,6 +151,7 @@ ifeq ($(strip $(BOOTLOADER)), stm32-dfu)
|
||||||
endif
|
endif
|
||||||
ifeq ($(strip $(BOOTLOADER)), apm32-dfu)
|
ifeq ($(strip $(BOOTLOADER)), apm32-dfu)
|
||||||
OPT_DEFS += -DBOOTLOADER_APM32_DFU
|
OPT_DEFS += -DBOOTLOADER_APM32_DFU
|
||||||
|
BOOTLOADER_TYPE = stm32_dfu
|
||||||
|
|
||||||
# Options to pass to dfu-util when flashing
|
# Options to pass to dfu-util when flashing
|
||||||
DFU_ARGS ?= -d 314B:0106 -a 0 -s 0x08000000:leave
|
DFU_ARGS ?= -d 314B:0106 -a 0 -s 0x08000000:leave
|
||||||
|
@ -129,6 +159,7 @@ ifeq ($(strip $(BOOTLOADER)), apm32-dfu)
|
||||||
endif
|
endif
|
||||||
ifeq ($(strip $(BOOTLOADER)), gd32v-dfu)
|
ifeq ($(strip $(BOOTLOADER)), gd32v-dfu)
|
||||||
OPT_DEFS += -DBOOTLOADER_GD32V_DFU
|
OPT_DEFS += -DBOOTLOADER_GD32V_DFU
|
||||||
|
BOOTLOADER_TYPE = gd32v_dfu
|
||||||
|
|
||||||
# Options to pass to dfu-util when flashing
|
# Options to pass to dfu-util when flashing
|
||||||
DFU_ARGS ?= -d 28E9:0189 -a 0 -s 0x08000000:leave
|
DFU_ARGS ?= -d 28E9:0189 -a 0 -s 0x08000000:leave
|
||||||
|
@ -136,6 +167,8 @@ ifeq ($(strip $(BOOTLOADER)), gd32v-dfu)
|
||||||
endif
|
endif
|
||||||
ifeq ($(strip $(BOOTLOADER)), kiibohd)
|
ifeq ($(strip $(BOOTLOADER)), kiibohd)
|
||||||
OPT_DEFS += -DBOOTLOADER_KIIBOHD
|
OPT_DEFS += -DBOOTLOADER_KIIBOHD
|
||||||
|
BOOTLOADER_TYPE = kiibohd
|
||||||
|
|
||||||
ifeq ($(strip $(MCU_ORIG)), MK20DX128)
|
ifeq ($(strip $(MCU_ORIG)), MK20DX128)
|
||||||
MCU_LDSCRIPT = MK20DX128BLDR4
|
MCU_LDSCRIPT = MK20DX128BLDR4
|
||||||
endif
|
endif
|
||||||
|
@ -151,8 +184,7 @@ ifeq ($(strip $(BOOTLOADER)), stm32duino)
|
||||||
OPT_DEFS += -DBOOTLOADER_STM32DUINO
|
OPT_DEFS += -DBOOTLOADER_STM32DUINO
|
||||||
MCU_LDSCRIPT = STM32F103x8_stm32duino_bootloader
|
MCU_LDSCRIPT = STM32F103x8_stm32duino_bootloader
|
||||||
BOARD = STM32_F103_STM32DUINO
|
BOARD = STM32_F103_STM32DUINO
|
||||||
# STM32F103 does NOT have an USB bootloader in ROM (only serial), so setting anything here does not make much sense
|
BOOTLOADER_TYPE = stm32duino
|
||||||
STM32_BOOTLOADER_ADDRESS = 0x80000000
|
|
||||||
|
|
||||||
# Options to pass to dfu-util when flashing
|
# Options to pass to dfu-util when flashing
|
||||||
DFU_ARGS = -d 1EAF:0003 -a 2 -R
|
DFU_ARGS = -d 1EAF:0003 -a 2 -R
|
||||||
|
@ -160,4 +192,17 @@ ifeq ($(strip $(BOOTLOADER)), stm32duino)
|
||||||
endif
|
endif
|
||||||
ifeq ($(strip $(BOOTLOADER)), tinyuf2)
|
ifeq ($(strip $(BOOTLOADER)), tinyuf2)
|
||||||
OPT_DEFS += -DBOOTLOADER_TINYUF2
|
OPT_DEFS += -DBOOTLOADER_TINYUF2
|
||||||
|
BOOTLOADER_TYPE = tinyuf2
|
||||||
|
endif
|
||||||
|
ifeq ($(strip $(BOOTLOADER)), halfkay)
|
||||||
|
OPT_DEFS += -DBOOTLOADER_HALFKAY
|
||||||
|
BOOTLOADER_TYPE = halfkay
|
||||||
|
endif
|
||||||
|
ifeq ($(strip $(BOOTLOADER)), md-boot)
|
||||||
|
OPT_DEFS += -DBOOTLOADER_MD_BOOT
|
||||||
|
BOOTLOADER_TYPE = md_boot
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(strip $(BOOTLOADER_TYPE)),)
|
||||||
|
$(call CATASTROPHIC_ERROR,Invalid BOOTLOADER,No bootloader specified. Please set an appropriate 'BOOTLOADER' in your keyboard's 'rules.mk' file.)
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
$(TEST)_INC := \
|
$(TEST)_INC := \
|
||||||
tests\test_common\common_config.h
|
tests/test_common/common_config.h
|
||||||
|
|
||||||
$(TEST)_SRC := \
|
$(TEST)_SRC := \
|
||||||
$(TMK_COMMON_SRC) \
|
$(TMK_COMMON_SRC) \
|
||||||
|
@ -33,4 +33,4 @@ $(TEST)_DEFS := $(TMK_COMMON_DEFS) $(OPT_DEFS)
|
||||||
|
|
||||||
$(TEST)_CONFIG := $(TEST_PATH)/config.h
|
$(TEST)_CONFIG := $(TEST_PATH)/config.h
|
||||||
|
|
||||||
VPATH += $(TOP_DIR)/tests/test_common
|
VPATH += $(TOP_DIR)/tests/test_common
|
|
@ -37,6 +37,17 @@ ifdef SKIP_VERSION
|
||||||
OPT_DEFS += -DSKIP_VERSION
|
OPT_DEFS += -DSKIP_VERSION
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Generate the version.h file
|
||||||
|
ifdef SKIP_VERSION
|
||||||
|
VERSION_H_FLAGS := --skip-all
|
||||||
|
endif
|
||||||
|
ifdef SKIP_GIT
|
||||||
|
VERSION_H_FLAGS := --skip-git
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Generate the board's version.h file.
|
||||||
|
$(shell $(QMK_BIN) generate-version-h $(VERSION_H_FLAGS) -q -o $(KEYMAP_OUTPUT)/src/version.h)
|
||||||
|
|
||||||
# Determine which subfolders exist.
|
# Determine which subfolders exist.
|
||||||
KEYBOARD_FOLDER_PATH_1 := $(KEYBOARD)
|
KEYBOARD_FOLDER_PATH_1 := $(KEYBOARD)
|
||||||
KEYBOARD_FOLDER_PATH_2 := $(patsubst %/,%,$(dir $(KEYBOARD_FOLDER_PATH_1)))
|
KEYBOARD_FOLDER_PATH_2 := $(patsubst %/,%,$(dir $(KEYBOARD_FOLDER_PATH_1)))
|
||||||
|
@ -100,7 +111,7 @@ INFO_RULES_MK = $(shell $(QMK_BIN) generate-rules-mk --quiet --escape --keyboard
|
||||||
include $(INFO_RULES_MK)
|
include $(INFO_RULES_MK)
|
||||||
|
|
||||||
# Check for keymap.json first, so we can regenerate keymap.c
|
# Check for keymap.json first, so we can regenerate keymap.c
|
||||||
include build_json.mk
|
include $(BUILDDEFS_PATH)/build_json.mk
|
||||||
|
|
||||||
# Pull in keymap level rules.mk
|
# Pull in keymap level rules.mk
|
||||||
ifeq ("$(wildcard $(KEYMAP_PATH))", "")
|
ifeq ("$(wildcard $(KEYMAP_PATH))", "")
|
||||||
|
@ -127,9 +138,9 @@ ifeq ("$(wildcard $(KEYMAP_PATH))", "")
|
||||||
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_1)
|
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_1)
|
||||||
else ifneq ($(LAYOUTS),)
|
else ifneq ($(LAYOUTS),)
|
||||||
# If we haven't found a keymap yet fall back to community layouts
|
# If we haven't found a keymap yet fall back to community layouts
|
||||||
include build_layout.mk
|
include $(BUILDDEFS_PATH)/build_layout.mk
|
||||||
else
|
else
|
||||||
$(error Could not find keymap)
|
$(call CATASTROPHIC_ERROR,Invalid keymap,Could not find keymap)
|
||||||
# this state should never be reached
|
# this state should never be reached
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
@ -158,7 +169,7 @@ generated-files: $(KEYMAP_OUTPUT)/src/config.h $(KEYMAP_OUTPUT)/src/keymap.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(CTPC)), yes)
|
ifeq ($(strip $(CTPC)), yes)
|
||||||
CONVERT_TO_PROTON_C=yes
|
CONVERT_TO_PROTON_C=yes
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(CONVERT_TO_PROTON_C)), yes)
|
ifeq ($(strip $(CONVERT_TO_PROTON_C)), yes)
|
||||||
|
@ -384,8 +395,10 @@ VPATH += $(KEYMAP_PATH)
|
||||||
VPATH += $(USER_PATH)
|
VPATH += $(USER_PATH)
|
||||||
VPATH += $(KEYBOARD_PATHS)
|
VPATH += $(KEYBOARD_PATHS)
|
||||||
VPATH += $(COMMON_VPATH)
|
VPATH += $(COMMON_VPATH)
|
||||||
|
VPATH += $(KEYBOARD_OUTPUT)/src
|
||||||
|
VPATH += $(KEYMAP_OUTPUT)/src
|
||||||
|
|
||||||
include common_features.mk
|
include $(BUILDDEFS_PATH)/common_features.mk
|
||||||
include $(BUILDDEFS_PATH)/generic_features.mk
|
include $(BUILDDEFS_PATH)/generic_features.mk
|
||||||
include $(TMK_PATH)/protocol.mk
|
include $(TMK_PATH)/protocol.mk
|
||||||
include $(PLATFORM_PATH)/common.mk
|
include $(PLATFORM_PATH)/common.mk
|
||||||
|
@ -447,7 +460,7 @@ check-md5: build
|
||||||
objs-size: build
|
objs-size: build
|
||||||
|
|
||||||
include $(BUILDDEFS_PATH)/show_options.mk
|
include $(BUILDDEFS_PATH)/show_options.mk
|
||||||
include $(TMK_PATH)/rules.mk
|
include $(BUILDDEFS_PATH)/common_rules.mk
|
||||||
|
|
||||||
# Ensure we have generated files available for each of the objects
|
# Ensure we have generated files available for each of the objects
|
||||||
define GEN_FILES
|
define GEN_FILES
|
|
@ -25,7 +25,7 @@ ifneq ($(FORCE_LAYOUT),)
|
||||||
$(info Forcing layout: $(FORCE_LAYOUT))
|
$(info Forcing layout: $(FORCE_LAYOUT))
|
||||||
LAYOUTS := $(FORCE_LAYOUT)
|
LAYOUTS := $(FORCE_LAYOUT)
|
||||||
else
|
else
|
||||||
$(error Forced layout does not exist)
|
$(call CATASTROPHIC_ERROR,Invalid layout,Forced layout does not exist)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -43,6 +43,7 @@ all: elf
|
||||||
VPATH += $(COMMON_VPATH)
|
VPATH += $(COMMON_VPATH)
|
||||||
PLATFORM:=TEST
|
PLATFORM:=TEST
|
||||||
PLATFORM_KEY:=test
|
PLATFORM_KEY:=test
|
||||||
|
BOOTLOADER_TYPE:=none
|
||||||
|
|
||||||
ifeq ($(strip $(DEBUG)), 1)
|
ifeq ($(strip $(DEBUG)), 1)
|
||||||
CONSOLE_ENABLE = yes
|
CONSOLE_ENABLE = yes
|
||||||
|
@ -53,7 +54,7 @@ include tests/test_common/build.mk
|
||||||
include $(TEST_PATH)/test.mk
|
include $(TEST_PATH)/test.mk
|
||||||
endif
|
endif
|
||||||
|
|
||||||
include common_features.mk
|
include $(BUILDDEFS_PATH)/common_features.mk
|
||||||
include $(BUILDDEFS_PATH)/generic_features.mk
|
include $(BUILDDEFS_PATH)/generic_features.mk
|
||||||
include $(PLATFORM_PATH)/common.mk
|
include $(PLATFORM_PATH)/common.mk
|
||||||
include $(TMK_PATH)/protocol.mk
|
include $(TMK_PATH)/protocol.mk
|
||||||
|
@ -62,7 +63,7 @@ include $(QUANTUM_PATH)/encoder/tests/rules.mk
|
||||||
include $(QUANTUM_PATH)/sequencer/tests/rules.mk
|
include $(QUANTUM_PATH)/sequencer/tests/rules.mk
|
||||||
include $(PLATFORM_PATH)/test/rules.mk
|
include $(PLATFORM_PATH)/test/rules.mk
|
||||||
ifneq ($(filter $(FULL_TESTS),$(TEST)),)
|
ifneq ($(filter $(FULL_TESTS),$(TEST)),)
|
||||||
include build_full_test.mk
|
include $(BUILDDEFS_PATH)/build_full_test.mk
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(TEST)_SRC += \
|
$(TEST)_SRC += \
|
||||||
|
@ -76,7 +77,7 @@ $(TEST_OBJ)/$(TEST)_DEFS := $($(TEST)_DEFS)
|
||||||
$(TEST_OBJ)/$(TEST)_CONFIG := $($(TEST)_CONFIG)
|
$(TEST_OBJ)/$(TEST)_CONFIG := $($(TEST)_CONFIG)
|
||||||
|
|
||||||
include $(PLATFORM_PATH)/$(PLATFORM_KEY)/platform.mk
|
include $(PLATFORM_PATH)/$(PLATFORM_KEY)/platform.mk
|
||||||
include $(TMK_PATH)/rules.mk
|
include $(BUILDDEFS_PATH)/common_rules.mk
|
||||||
|
|
||||||
|
|
||||||
$(shell mkdir -p $(BUILD_DIR)/test 2>/dev/null)
|
$(shell mkdir -p $(BUILD_DIR)/test 2>/dev/null)
|
|
@ -20,7 +20,6 @@ QUANTUM_SRC += \
|
||||||
$(QUANTUM_DIR)/led.c \
|
$(QUANTUM_DIR)/led.c \
|
||||||
$(QUANTUM_DIR)/action.c \
|
$(QUANTUM_DIR)/action.c \
|
||||||
$(QUANTUM_DIR)/action_layer.c \
|
$(QUANTUM_DIR)/action_layer.c \
|
||||||
$(QUANTUM_DIR)/action_macro.c \
|
|
||||||
$(QUANTUM_DIR)/action_tapping.c \
|
$(QUANTUM_DIR)/action_tapping.c \
|
||||||
$(QUANTUM_DIR)/action_util.c \
|
$(QUANTUM_DIR)/action_util.c \
|
||||||
$(QUANTUM_DIR)/eeconfig.c \
|
$(QUANTUM_DIR)/eeconfig.c \
|
||||||
|
@ -109,11 +108,10 @@ 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 pimoroni_trackball custom
|
VALID_POINTING_DEVICE_DRIVER_TYPES := adns5050 adns9800 analog_joystick cirque_pinnacle_i2c cirque_pinnacle_spi pmw3360 pmw3389 pimoroni_trackball custom
|
||||||
POINTING_DEVICE_DRIVER ?= 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)),)
|
||||||
$(error 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
|
||||||
|
@ -144,6 +142,9 @@ ifeq ($(strip $(POINTING_DEVICE_ENABLE)), yes)
|
||||||
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), pmw3360)
|
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), pmw3360)
|
||||||
OPT_DEFS += -DSTM32_SPI -DHAL_USE_SPI=TRUE
|
OPT_DEFS += -DSTM32_SPI -DHAL_USE_SPI=TRUE
|
||||||
QUANTUM_LIB_SRC += spi_master.c
|
QUANTUM_LIB_SRC += spi_master.c
|
||||||
|
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), pmw3389)
|
||||||
|
OPT_DEFS += -DSTM32_SPI -DHAL_USE_SPI=TRUE
|
||||||
|
QUANTUM_LIB_SRC += spi_master.c
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
@ -151,56 +152,88 @@ endif
|
||||||
VALID_EEPROM_DRIVER_TYPES := vendor custom transient i2c spi
|
VALID_EEPROM_DRIVER_TYPES := vendor custom transient i2c spi
|
||||||
EEPROM_DRIVER ?= vendor
|
EEPROM_DRIVER ?= vendor
|
||||||
ifeq ($(filter $(EEPROM_DRIVER),$(VALID_EEPROM_DRIVER_TYPES)),)
|
ifeq ($(filter $(EEPROM_DRIVER),$(VALID_EEPROM_DRIVER_TYPES)),)
|
||||||
$(error 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
|
||||||
ifeq ($(strip $(EEPROM_DRIVER)), custom)
|
ifeq ($(strip $(EEPROM_DRIVER)), custom)
|
||||||
|
# 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
|
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
||||||
SRC += eeprom_driver.c
|
SRC += eeprom_driver.c
|
||||||
else ifeq ($(strip $(EEPROM_DRIVER)), i2c)
|
else ifeq ($(strip $(EEPROM_DRIVER)), i2c)
|
||||||
|
# External I2C EEPROM implementation
|
||||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_I2C
|
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_I2C
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
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
|
||||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_SPI
|
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_SPI
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
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
|
||||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT
|
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
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
|
||||||
OPT_DEFS += -DEEPROM_VENDOR
|
OPT_DEFS += -DEEPROM_VENDOR
|
||||||
ifeq ($(PLATFORM),AVR)
|
ifeq ($(PLATFORM),AVR)
|
||||||
# Automatically provided by avr-libc, nothing required
|
# Automatically provided by avr-libc, nothing required
|
||||||
else ifeq ($(PLATFORM),CHIBIOS)
|
else ifeq ($(PLATFORM),CHIBIOS)
|
||||||
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)),)
|
||||||
OPT_DEFS += -DEEPROM_DRIVER
|
# Emulated EEPROM
|
||||||
|
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_STM32_FLASH_EMULATED
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
||||||
SRC += eeprom_driver.c
|
SRC += eeprom_driver.c
|
||||||
SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
|
SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
|
||||||
SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
|
SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
|
||||||
else ifneq ($(filter $(MCU_SERIES),STM32L0xx STM32L1xx),)
|
else ifneq ($(filter $(MCU_SERIES),STM32L0xx STM32L1xx),)
|
||||||
OPT_DEFS += -DEEPROM_DRIVER
|
# True EEPROM on STM32L0xx, L1xx
|
||||||
|
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_STM32_L0_L1
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
||||||
COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/eeprom
|
COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/eeprom
|
||||||
SRC += eeprom_driver.c
|
SRC += eeprom_driver.c
|
||||||
SRC += eeprom_stm32_L0_L1.c
|
SRC += eeprom_stm32_L0_L1.c
|
||||||
|
else ifneq ($(filter $(MCU_SERIES),KL2x K20x),)
|
||||||
|
# Teensy EEPROM implementations
|
||||||
|
OPT_DEFS += -DEEPROM_TEENSY
|
||||||
|
SRC += eeprom_teensy.c
|
||||||
else
|
else
|
||||||
# This will effectively work the same as "transient" if not supported by the chip
|
# Fall back to transient, i.e. non-persistent
|
||||||
SRC += $(PLATFORM_COMMON_DIR)/eeprom_teensy.c
|
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT
|
||||||
|
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
||||||
|
SRC += eeprom_driver.c eeprom_transient.c
|
||||||
endif
|
endif
|
||||||
else ifeq ($(PLATFORM),ARM_ATSAM)
|
else ifeq ($(PLATFORM),ARM_ATSAM)
|
||||||
SRC += $(PLATFORM_COMMON_DIR)/eeprom.c
|
# arm_atsam EEPROM
|
||||||
|
OPT_DEFS += -DEEPROM_SAMD
|
||||||
|
SRC += $(PLATFORM_COMMON_DIR)/eeprom_samd.c
|
||||||
else ifeq ($(PLATFORM),TEST)
|
else ifeq ($(PLATFORM),TEST)
|
||||||
|
# Test harness "EEPROM"
|
||||||
|
OPT_DEFS += -DEEPROM_TEST_HARNESS
|
||||||
SRC += $(PLATFORM_COMMON_DIR)/eeprom.c
|
SRC += $(PLATFORM_COMMON_DIR)/eeprom.c
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
VALID_FLASH_DRIVER_TYPES := spi
|
||||||
|
FLASH_DRIVER ?= no
|
||||||
|
ifneq ($(strip $(FLASH_DRIVER)), no)
|
||||||
|
ifeq ($(filter $(FLASH_DRIVER),$(VALID_FLASH_DRIVER_TYPES)),)
|
||||||
|
$(error FLASH_DRIVER="$(FLASH_DRIVER)" is not a valid FLASH driver)
|
||||||
|
else
|
||||||
|
OPT_DEFS += -DFLASH_ENABLE
|
||||||
|
ifeq ($(strip $(FLASH_DRIVER)), spi)
|
||||||
|
OPT_DEFS += -DFLASH_DRIVER -DFLASH_SPI
|
||||||
|
COMMON_VPATH += $(DRIVER_PATH)/flash
|
||||||
|
SRC += flash_spi.c
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
RGBLIGHT_ENABLE ?= no
|
RGBLIGHT_ENABLE ?= no
|
||||||
VALID_RGBLIGHT_TYPES := WS2812 APA102 custom
|
VALID_RGBLIGHT_TYPES := WS2812 APA102 custom
|
||||||
|
|
||||||
|
@ -212,7 +245,7 @@ ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
|
||||||
RGBLIGHT_DRIVER ?= WS2812
|
RGBLIGHT_DRIVER ?= WS2812
|
||||||
|
|
||||||
ifeq ($(filter $(RGBLIGHT_DRIVER),$(VALID_RGBLIGHT_TYPES)),)
|
ifeq ($(filter $(RGBLIGHT_DRIVER),$(VALID_RGBLIGHT_TYPES)),)
|
||||||
$(error RGBLIGHT_DRIVER="$(RGBLIGHT_DRIVER)" is not a valid RGB type)
|
$(call CATASTROPHIC_ERROR,Invalid RGBLIGHT_DRIVER,RGBLIGHT_DRIVER="$(RGBLIGHT_DRIVER)" is not a valid RGB type)
|
||||||
else
|
else
|
||||||
COMMON_VPATH += $(QUANTUM_DIR)/rgblight
|
COMMON_VPATH += $(QUANTUM_DIR)/rgblight
|
||||||
POST_CONFIG_H += $(QUANTUM_DIR)/rgblight/rgblight_post_config.h
|
POST_CONFIG_H += $(QUANTUM_DIR)/rgblight/rgblight_post_config.h
|
||||||
|
@ -237,12 +270,12 @@ ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
LED_MATRIX_ENABLE ?= no
|
LED_MATRIX_ENABLE ?= no
|
||||||
VALID_LED_MATRIX_TYPES := IS31FL3731 custom
|
VALID_LED_MATRIX_TYPES := IS31FL3731 IS31FL3742A IS31FL3743A IS31FL3745 IS31FL3746A custom
|
||||||
# TODO: IS31FL3733 IS31FL3737 IS31FL3741
|
# TODO: IS31FL3733 IS31FL3737 IS31FL3741
|
||||||
|
|
||||||
ifeq ($(strip $(LED_MATRIX_ENABLE)), yes)
|
ifeq ($(strip $(LED_MATRIX_ENABLE)), yes)
|
||||||
ifeq ($(filter $(LED_MATRIX_DRIVER),$(VALID_LED_MATRIX_TYPES)),)
|
ifeq ($(filter $(LED_MATRIX_DRIVER),$(VALID_LED_MATRIX_TYPES)),)
|
||||||
$(error "$(LED_MATRIX_DRIVER)" is not a valid matrix type)
|
$(call CATASTROPHIC_ERROR,Invalid LED_MATRIX_DRIVER,LED_MATRIX_DRIVER="$(LED_MATRIX_DRIVER)" is not a valid matrix type)
|
||||||
endif
|
endif
|
||||||
OPT_DEFS += -DLED_MATRIX_ENABLE
|
OPT_DEFS += -DLED_MATRIX_ENABLE
|
||||||
ifneq (,$(filter $(MCU), atmega16u2 atmega32u2 at90usb162))
|
ifneq (,$(filter $(MCU), atmega16u2 atmega32u2 at90usb162))
|
||||||
|
@ -264,14 +297,43 @@ endif
|
||||||
SRC += is31fl3731-simple.c
|
SRC += is31fl3731-simple.c
|
||||||
QUANTUM_LIB_SRC += i2c_master.c
|
QUANTUM_LIB_SRC += i2c_master.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(strip $(LED_MATRIX_DRIVER)), IS31FL3742A)
|
||||||
|
OPT_DEFS += -DIS31FLCOMMON -DIS31FL3742A -DSTM32_I2C -DHAL_USE_I2C=TRUE
|
||||||
|
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
||||||
|
SRC += is31flcommon.c
|
||||||
|
QUANTUM_LIB_SRC += i2c_master.c
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(strip $(LED_MATRIX_DRIVER)), IS31FL3743A)
|
||||||
|
OPT_DEFS += -DIS31FLCOMMON -DIS31FL3743A -DSTM32_I2C -DHAL_USE_I2C=TRUE
|
||||||
|
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
||||||
|
SRC += is31flcommon.c
|
||||||
|
QUANTUM_LIB_SRC += i2c_master.c
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(strip $(LED_MATRIX_DRIVER)), IS31FL3745)
|
||||||
|
OPT_DEFS += -DIS31FLCOMMON -DIS31FL3745 -DSTM32_I2C -DHAL_USE_I2C=TRUE
|
||||||
|
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
||||||
|
SRC += is31flcommon.c
|
||||||
|
QUANTUM_LIB_SRC += i2c_master.c
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(strip $(LED_MATRIX_DRIVER)), IS31FL3746A)
|
||||||
|
OPT_DEFS += -DIS31FLCOMMON -DIS31FL3746A -DSTM32_I2C -DHAL_USE_I2C=TRUE
|
||||||
|
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
||||||
|
SRC += is31flcommon.c
|
||||||
|
QUANTUM_LIB_SRC += i2c_master.c
|
||||||
|
endif
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
RGB_MATRIX_ENABLE ?= no
|
RGB_MATRIX_ENABLE ?= no
|
||||||
VALID_RGB_MATRIX_TYPES := AW20216 IS31FL3731 IS31FL3733 IS31FL3737 IS31FL3741 CKLED2001 WS2812 custom
|
|
||||||
|
|
||||||
|
VALID_RGB_MATRIX_TYPES := AW20216 IS31FL3731 IS31FL3733 IS31FL3737 IS31FL3741 IS31FL3742A IS31FL3743A IS31FL3745 IS31FL3746A CKLED2001 WS2812 custom
|
||||||
ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
|
ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
|
||||||
ifeq ($(filter $(RGB_MATRIX_DRIVER),$(VALID_RGB_MATRIX_TYPES)),)
|
ifeq ($(filter $(RGB_MATRIX_DRIVER),$(VALID_RGB_MATRIX_TYPES)),)
|
||||||
$(error "$(RGB_MATRIX_DRIVER)" is not a valid matrix type)
|
$(call CATASTROPHIC_ERROR,Invalid RGB_MATRIX_DRIVER,RGB_MATRIX_DRIVER="$(RGB_MATRIX_DRIVER)" is not a valid matrix type)
|
||||||
endif
|
endif
|
||||||
OPT_DEFS += -DRGB_MATRIX_ENABLE
|
OPT_DEFS += -DRGB_MATRIX_ENABLE
|
||||||
ifneq (,$(filter $(MCU), atmega16u2 atmega32u2 at90usb162))
|
ifneq (,$(filter $(MCU), atmega16u2 atmega32u2 at90usb162))
|
||||||
|
@ -323,6 +385,34 @@ endif
|
||||||
QUANTUM_LIB_SRC += i2c_master.c
|
QUANTUM_LIB_SRC += i2c_master.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(strip $(RGB_MATRIX_DRIVER)), IS31FL3742A)
|
||||||
|
OPT_DEFS += -DIS31FLCOMMON -DIS31FL3742A -DSTM32_I2C -DHAL_USE_I2C=TRUE
|
||||||
|
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
||||||
|
SRC += is31flcommon.c
|
||||||
|
QUANTUM_LIB_SRC += i2c_master.c
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(strip $(RGB_MATRIX_DRIVER)), IS31FL3743A)
|
||||||
|
OPT_DEFS += -DIS31FLCOMMON -DIS31FL3743A -DSTM32_I2C -DHAL_USE_I2C=TRUE
|
||||||
|
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
||||||
|
SRC += is31flcommon.c
|
||||||
|
QUANTUM_LIB_SRC += i2c_master.c
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(strip $(RGB_MATRIX_DRIVER)), IS31FL3745)
|
||||||
|
OPT_DEFS += -DIS31FLCOMMON -DIS31FL3745 -DSTM32_I2C -DHAL_USE_I2C=TRUE
|
||||||
|
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
||||||
|
SRC += is31flcommon.c
|
||||||
|
QUANTUM_LIB_SRC += i2c_master.c
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(strip $(RGB_MATRIX_DRIVER)), IS31FL3746A)
|
||||||
|
OPT_DEFS += -DIS31FLCOMMON -DIS31FL3746A -DSTM32_I2C -DHAL_USE_I2C=TRUE
|
||||||
|
COMMON_VPATH += $(DRIVER_PATH)/led/issi
|
||||||
|
SRC += is31flcommon.c
|
||||||
|
QUANTUM_LIB_SRC += i2c_master.c
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(RGB_MATRIX_DRIVER)), CKLED2001)
|
ifeq ($(strip $(RGB_MATRIX_DRIVER)), CKLED2001)
|
||||||
OPT_DEFS += -DCKLED2001 -DSTM32_I2C -DHAL_USE_I2C=TRUE
|
OPT_DEFS += -DCKLED2001 -DSTM32_I2C -DHAL_USE_I2C=TRUE
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/led
|
COMMON_VPATH += $(DRIVER_PATH)/led
|
||||||
|
@ -356,7 +446,7 @@ endif
|
||||||
ifeq ($(strip $(PRINTING_ENABLE)), yes)
|
ifeq ($(strip $(PRINTING_ENABLE)), yes)
|
||||||
OPT_DEFS += -DPRINTING_ENABLE
|
OPT_DEFS += -DPRINTING_ENABLE
|
||||||
SRC += $(QUANTUM_DIR)/process_keycode/process_printer.c
|
SRC += $(QUANTUM_DIR)/process_keycode/process_printer.c
|
||||||
SRC += $(TMK_DIR)/protocol/serial_uart.c
|
QUANTUM_LIB_SRC += uart.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
VARIABLE_TRACE ?= no
|
VARIABLE_TRACE ?= no
|
||||||
|
@ -385,7 +475,7 @@ else
|
||||||
endif
|
endif
|
||||||
ifeq ($(strip $(BACKLIGHT_ENABLE)), yes)
|
ifeq ($(strip $(BACKLIGHT_ENABLE)), yes)
|
||||||
ifeq ($(filter $(BACKLIGHT_DRIVER),$(VALID_BACKLIGHT_TYPES)),)
|
ifeq ($(filter $(BACKLIGHT_DRIVER),$(VALID_BACKLIGHT_TYPES)),)
|
||||||
$(error BACKLIGHT_DRIVER="$(BACKLIGHT_DRIVER)" is not a valid backlight type)
|
$(call CATASTROPHIC_ERROR,Invalid BACKLIGHT_DRIVER,BACKLIGHT_DRIVER="$(BACKLIGHT_DRIVER)" is not a valid backlight type)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
COMMON_VPATH += $(QUANTUM_DIR)/backlight
|
COMMON_VPATH += $(QUANTUM_DIR)/backlight
|
||||||
|
@ -410,7 +500,7 @@ VALID_WS2812_DRIVER_TYPES := bitbang pwm spi i2c
|
||||||
WS2812_DRIVER ?= bitbang
|
WS2812_DRIVER ?= bitbang
|
||||||
ifeq ($(strip $(WS2812_DRIVER_REQUIRED)), yes)
|
ifeq ($(strip $(WS2812_DRIVER_REQUIRED)), yes)
|
||||||
ifeq ($(filter $(WS2812_DRIVER),$(VALID_WS2812_DRIVER_TYPES)),)
|
ifeq ($(filter $(WS2812_DRIVER),$(VALID_WS2812_DRIVER_TYPES)),)
|
||||||
$(error WS2812_DRIVER="$(WS2812_DRIVER)" is not a valid WS2812 driver)
|
$(call CATASTROPHIC_ERROR,Invalid WS2812_DRIVER,WS2812_DRIVER="$(WS2812_DRIVER)" is not a valid WS2812 driver)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
OPT_DEFS += -DWS2812_DRIVER_$(strip $(shell echo $(WS2812_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
OPT_DEFS += -DWS2812_DRIVER_$(strip $(shell echo $(WS2812_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
||||||
|
@ -465,7 +555,7 @@ VALID_MAGIC_TYPES := yes
|
||||||
BOOTMAGIC_ENABLE ?= no
|
BOOTMAGIC_ENABLE ?= no
|
||||||
ifneq ($(strip $(BOOTMAGIC_ENABLE)), no)
|
ifneq ($(strip $(BOOTMAGIC_ENABLE)), no)
|
||||||
ifeq ($(filter $(BOOTMAGIC_ENABLE),$(VALID_MAGIC_TYPES)),)
|
ifeq ($(filter $(BOOTMAGIC_ENABLE),$(VALID_MAGIC_TYPES)),)
|
||||||
$(error BOOTMAGIC_ENABLE="$(BOOTMAGIC_ENABLE)" is not a valid type of magic)
|
$(call CATASTROPHIC_ERROR,Invalid BOOTMAGIC_ENABLE,BOOTMAGIC_ENABLE="$(BOOTMAGIC_ENABLE)" is not a valid type of magic)
|
||||||
endif
|
endif
|
||||||
ifneq ($(strip $(BOOTMAGIC_ENABLE)), no)
|
ifneq ($(strip $(BOOTMAGIC_ENABLE)), no)
|
||||||
OPT_DEFS += -DBOOTMAGIC_LITE
|
OPT_DEFS += -DBOOTMAGIC_LITE
|
||||||
|
@ -481,7 +571,7 @@ CUSTOM_MATRIX ?= no
|
||||||
|
|
||||||
ifneq ($(strip $(CUSTOM_MATRIX)), yes)
|
ifneq ($(strip $(CUSTOM_MATRIX)), yes)
|
||||||
ifeq ($(filter $(CUSTOM_MATRIX),$(VALID_CUSTOM_MATRIX_TYPES)),)
|
ifeq ($(filter $(CUSTOM_MATRIX),$(VALID_CUSTOM_MATRIX_TYPES)),)
|
||||||
$(error CUSTOM_MATRIX="$(CUSTOM_MATRIX)" is not a valid custom matrix type)
|
$(call CATASTROPHIC_ERROR,Invalid CUSTOM_MATRIX,CUSTOM_MATRIX="$(CUSTOM_MATRIX)" is not a valid custom matrix type)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Include common stuff for all non custom matrix users
|
# Include common stuff for all non custom matrix users
|
||||||
|
@ -564,7 +654,7 @@ VALID_OLED_DRIVER_TYPES := SSD1306 custom
|
||||||
OLED_DRIVER ?= SSD1306
|
OLED_DRIVER ?= SSD1306
|
||||||
ifeq ($(strip $(OLED_ENABLE)), yes)
|
ifeq ($(strip $(OLED_ENABLE)), yes)
|
||||||
ifeq ($(filter $(OLED_DRIVER),$(VALID_OLED_DRIVER_TYPES)),)
|
ifeq ($(filter $(OLED_DRIVER),$(VALID_OLED_DRIVER_TYPES)),)
|
||||||
$(error OLED_DRIVER="$(OLED_DRIVER)" is not a valid OLED driver)
|
$(call CATASTROPHIC_ERROR,Invalid OLED_DRIVER,OLED_DRIVER="$(OLED_DRIVER)" is not a valid OLED driver)
|
||||||
else
|
else
|
||||||
OPT_DEFS += -DOLED_ENABLE
|
OPT_DEFS += -DOLED_ENABLE
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/oled
|
COMMON_VPATH += $(DRIVER_PATH)/oled
|
||||||
|
@ -604,6 +694,7 @@ ifeq ($(strip $(UNICODE_ENABLE)), yes)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(UNICODE_COMMON)), yes)
|
ifeq ($(strip $(UNICODE_COMMON)), yes)
|
||||||
|
OPT_DEFS += -DUNICODE_COMMON_ENABLE
|
||||||
SRC += $(QUANTUM_DIR)/process_keycode/process_unicode_common.c
|
SRC += $(QUANTUM_DIR)/process_keycode/process_unicode_common.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -631,7 +722,7 @@ endif
|
||||||
ifeq ($(strip $(PS2_USE_BUSYWAIT)), yes)
|
ifeq ($(strip $(PS2_USE_BUSYWAIT)), yes)
|
||||||
PS2_ENABLE := yes
|
PS2_ENABLE := yes
|
||||||
SRC += ps2_busywait.c
|
SRC += ps2_busywait.c
|
||||||
SRC += ps2_io_avr.c
|
SRC += ps2_io.c
|
||||||
OPT_DEFS += -DPS2_USE_BUSYWAIT
|
OPT_DEFS += -DPS2_USE_BUSYWAIT
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -660,7 +751,7 @@ VALID_JOYSTICK_TYPES := analog digital
|
||||||
JOYSTICK_DRIVER ?= analog
|
JOYSTICK_DRIVER ?= analog
|
||||||
ifeq ($(strip $(JOYSTICK_ENABLE)), yes)
|
ifeq ($(strip $(JOYSTICK_ENABLE)), yes)
|
||||||
ifeq ($(filter $(JOYSTICK_DRIVER),$(VALID_JOYSTICK_TYPES)),)
|
ifeq ($(filter $(JOYSTICK_DRIVER),$(VALID_JOYSTICK_TYPES)),)
|
||||||
$(error "$(JOYSTICK_DRIVER)" is not a valid joystick driver)
|
$(call CATASTROPHIC_ERROR,Invalid JOYSTICK_DRIVER,JOYSTICK_DRIVER="$(JOYSTICK_DRIVER)" is not a valid joystick driver)
|
||||||
endif
|
endif
|
||||||
OPT_DEFS += -DJOYSTICK_ENABLE
|
OPT_DEFS += -DJOYSTICK_ENABLE
|
||||||
SRC += $(QUANTUM_DIR)/process_keycode/process_joystick.c
|
SRC += $(QUANTUM_DIR)/process_keycode/process_joystick.c
|
||||||
|
@ -680,7 +771,7 @@ VALID_USBPD_DRIVER_TYPES = custom vendor
|
||||||
USBPD_DRIVER ?= vendor
|
USBPD_DRIVER ?= vendor
|
||||||
ifeq ($(strip $(USBPD_ENABLE)), yes)
|
ifeq ($(strip $(USBPD_ENABLE)), yes)
|
||||||
ifeq ($(filter $(strip $(USBPD_DRIVER)),$(VALID_USBPD_DRIVER_TYPES)),)
|
ifeq ($(filter $(strip $(USBPD_DRIVER)),$(VALID_USBPD_DRIVER_TYPES)),)
|
||||||
$(error USBPD_DRIVER="$(USBPD_DRIVER)" is not a valid USBPD driver)
|
$(call CATASTROPHIC_ERROR,Invalid USBPD_DRIVER,USBPD_DRIVER="$(USBPD_DRIVER)" is not a valid USBPD driver)
|
||||||
else
|
else
|
||||||
OPT_DEFS += -DUSBPD_ENABLE
|
OPT_DEFS += -DUSBPD_ENABLE
|
||||||
ifeq ($(strip $(USBPD_DRIVER)), vendor)
|
ifeq ($(strip $(USBPD_DRIVER)), vendor)
|
||||||
|
@ -690,7 +781,7 @@ ifeq ($(strip $(USBPD_ENABLE)), yes)
|
||||||
OPT_DEFS += -DUSBPD_STM32G4
|
OPT_DEFS += -DUSBPD_STM32G4
|
||||||
SRC += usbpd_stm32g4.c
|
SRC += usbpd_stm32g4.c
|
||||||
else
|
else
|
||||||
$(error There is no vendor-provided USBPD driver available)
|
$(call CATASTROPHIC_ERROR,Invalid USBPD_DRIVER,There is no vendor-provided USBPD driver available)
|
||||||
endif
|
endif
|
||||||
else ifeq ($(strip $(USBPD_DRIVER)), custom)
|
else ifeq ($(strip $(USBPD_DRIVER)), custom)
|
||||||
OPT_DEFS += -DUSBPD_CUSTOM
|
OPT_DEFS += -DUSBPD_CUSTOM
|
||||||
|
@ -700,25 +791,26 @@ ifeq ($(strip $(USBPD_ENABLE)), yes)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
BLUETOOTH_ENABLE ?= no
|
BLUETOOTH_ENABLE ?= no
|
||||||
VALID_BLUETOOTH_DRIVER_TYPES := AdafruitBLE RN42 custom
|
VALID_BLUETOOTH_DRIVER_TYPES := BluefruitLE RN42 custom
|
||||||
ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
|
ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
|
||||||
ifeq ($(filter $(strip $(BLUETOOTH_DRIVER)),$(VALID_BLUETOOTH_DRIVER_TYPES)),)
|
ifeq ($(filter $(strip $(BLUETOOTH_DRIVER)),$(VALID_BLUETOOTH_DRIVER_TYPES)),)
|
||||||
$(error "$(BLUETOOTH_DRIVER)" is not a valid Bluetooth driver type)
|
$(call CATASTROPHIC_ERROR,Invalid BLUETOOTH_DRIVER,BLUETOOTH_DRIVER="$(BLUETOOTH_DRIVER)" is not a valid Bluetooth driver type)
|
||||||
endif
|
endif
|
||||||
OPT_DEFS += -DBLUETOOTH_ENABLE
|
OPT_DEFS += -DBLUETOOTH_ENABLE
|
||||||
NO_USB_STARTUP_CHECK := yes
|
NO_USB_STARTUP_CHECK := yes
|
||||||
COMMON_VPATH += $(DRIVER_PATH)/bluetooth
|
COMMON_VPATH += $(DRIVER_PATH)/bluetooth
|
||||||
SRC += outputselect.c
|
SRC += outputselect.c
|
||||||
|
|
||||||
ifeq ($(strip $(BLUETOOTH_DRIVER)), AdafruitBLE)
|
ifeq ($(strip $(BLUETOOTH_DRIVER)), BluefruitLE)
|
||||||
OPT_DEFS += -DMODULE_ADAFRUIT_BLE
|
OPT_DEFS += -DBLUETOOTH_BLUEFRUIT_LE
|
||||||
SRC += analog.c
|
SRC += analog.c
|
||||||
SRC += $(DRIVER_PATH)/bluetooth/adafruit_ble.cpp
|
SRC += $(DRIVER_PATH)/bluetooth/bluefruit_le.cpp
|
||||||
QUANTUM_LIB_SRC += spi_master.c
|
QUANTUM_LIB_SRC += spi_master.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(BLUETOOTH_DRIVER)), RN42)
|
ifeq ($(strip $(BLUETOOTH_DRIVER)), RN42)
|
||||||
OPT_DEFS += -DMODULE_RN42
|
OPT_DEFS += -DBLUETOOTH_RN42
|
||||||
SRC += $(TMK_DIR)/protocol/serial_uart.c
|
SRC += $(DRIVER_PATH)/bluetooth/rn42.c
|
||||||
|
QUANTUM_LIB_SRC += uart.c
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
|
@ -234,6 +234,7 @@ endif
|
||||||
|
|
||||||
# Define programs and commands.
|
# Define programs and commands.
|
||||||
SHELL = sh
|
SHELL = sh
|
||||||
|
SED = sed
|
||||||
REMOVE = rm -f
|
REMOVE = rm -f
|
||||||
REMOVEDIR = rmdir
|
REMOVEDIR = rmdir
|
||||||
COPY = cp
|
COPY = cp
|
||||||
|
@ -292,17 +293,15 @@ sym: $(BUILD_DIR)/$(TARGET).sym
|
||||||
LIBNAME=lib$(TARGET).a
|
LIBNAME=lib$(TARGET).a
|
||||||
lib: $(LIBNAME)
|
lib: $(LIBNAME)
|
||||||
|
|
||||||
# Display size of file.
|
# Display size of file, modifying the output so people don't mistakenly grab the hex output
|
||||||
HEXSIZE = $(SIZE) --target=$(FORMAT) $(BUILD_DIR)/$(TARGET).hex
|
BINARY_SIZE = $(SIZE) --target=$(FORMAT) $(BUILD_DIR)/$(TARGET).hex | $(SED) -e 's/\.build\/.*$$/$(TARGET).$(FIRMWARE_FORMAT)/g'
|
||||||
#ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf
|
|
||||||
ELFSIZE = $(SIZE) $(BUILD_DIR)/$(TARGET).elf
|
|
||||||
|
|
||||||
sizebefore:
|
sizebefore:
|
||||||
@if test -f $(BUILD_DIR)/$(TARGET).hex; then $(SECHO) $(MSG_SIZE_BEFORE); $(SILENT) || $(HEXSIZE); \
|
@if test -f $(BUILD_DIR)/$(TARGET).hex; then $(SECHO) $(MSG_SIZE_BEFORE); $(SILENT) || $(BINARY_SIZE); \
|
||||||
2>/dev/null; $(SECHO); fi
|
2>/dev/null; $(SECHO); fi
|
||||||
|
|
||||||
sizeafter: $(BUILD_DIR)/$(TARGET).hex
|
sizeafter: $(BUILD_DIR)/$(TARGET).hex
|
||||||
@if test -f $(BUILD_DIR)/$(TARGET).hex; then $(SECHO); $(SECHO) $(MSG_SIZE_AFTER); $(SILENT) || $(HEXSIZE); \
|
@if test -f $(BUILD_DIR)/$(TARGET).hex; then $(SECHO); $(SECHO) $(MSG_SIZE_AFTER); $(SILENT) || $(BINARY_SIZE); \
|
||||||
2>/dev/null; $(SECHO); fi
|
2>/dev/null; $(SECHO); fi
|
||||||
|
|
||||||
# Display compiler version information.
|
# Display compiler version information.
|
||||||
|
@ -479,7 +478,7 @@ ifeq ($(findstring avr-gcc,$(CC)),avr-gcc)
|
||||||
SIZE_MARGIN = 1024
|
SIZE_MARGIN = 1024
|
||||||
|
|
||||||
check-size:
|
check-size:
|
||||||
$(eval MAX_SIZE=$(shell n=`$(CC) -E -mmcu=$(MCU) -D__ASSEMBLER__ $(CFLAGS) $(OPT_DEFS) platforms/avr/bootloader_size.c 2> /dev/null | sed -ne 's/\r//;/^#/n;/^AVR_SIZE:/,$${s/^AVR_SIZE: //;p;}'` && echo $$(($$n)) || echo 0))
|
$(eval MAX_SIZE=$(shell n=`$(CC) -E -mmcu=$(MCU) -D__ASSEMBLER__ $(CFLAGS) $(OPT_DEFS) platforms/avr/bootloader_size.c 2> /dev/null | $(SED) -ne 's/\r//;/^#/n;/^AVR_SIZE:/,$${s/^AVR_SIZE: //;p;}'` && echo $$(($$n)) || echo 0))
|
||||||
$(eval CURRENT_SIZE=$(shell if [ -f $(BUILD_DIR)/$(TARGET).hex ]; then $(SIZE) --target=$(FORMAT) $(BUILD_DIR)/$(TARGET).hex | $(AWK) 'NR==2 {print $$4}'; else printf 0; fi))
|
$(eval CURRENT_SIZE=$(shell if [ -f $(BUILD_DIR)/$(TARGET).hex ]; then $(SIZE) --target=$(FORMAT) $(BUILD_DIR)/$(TARGET).hex | $(AWK) 'NR==2 {print $$4}'; else printf 0; fi))
|
||||||
$(eval FREE_SIZE=$(shell expr $(MAX_SIZE) - $(CURRENT_SIZE)))
|
$(eval FREE_SIZE=$(shell expr $(MAX_SIZE) - $(CURRENT_SIZE)))
|
||||||
$(eval OVER_SIZE=$(shell expr $(CURRENT_SIZE) - $(MAX_SIZE)))
|
$(eval OVER_SIZE=$(shell expr $(CURRENT_SIZE) - $(MAX_SIZE)))
|
|
@ -143,6 +143,9 @@ ifneq ($(findstring STM32F042, $(MCU)),)
|
||||||
# This ensures that the EEPROM page buffer fits into RAM
|
# This ensures that the EEPROM page buffer fits into RAM
|
||||||
USE_PROCESS_STACKSIZE = 0x600
|
USE_PROCESS_STACKSIZE = 0x600
|
||||||
USE_EXCEPTIONS_STACKSIZE = 0x300
|
USE_EXCEPTIONS_STACKSIZE = 0x300
|
||||||
|
|
||||||
|
# Bootloader address for STM32 DFU
|
||||||
|
STM32_BOOTLOADER_ADDRESS ?= 0x1FFFC400
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(findstring STM32F072, $(MCU)),)
|
ifneq ($(findstring STM32F072, $(MCU)),)
|
||||||
|
@ -175,6 +178,9 @@ ifneq ($(findstring STM32F072, $(MCU)),)
|
||||||
|
|
||||||
# UF2 settings
|
# UF2 settings
|
||||||
UF2_FAMILY ?= STM32F0
|
UF2_FAMILY ?= STM32F0
|
||||||
|
|
||||||
|
# Bootloader address for STM32 DFU
|
||||||
|
STM32_BOOTLOADER_ADDRESS ?= 0x1FFFC800
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(findstring STM32F103, $(MCU)),)
|
ifneq ($(findstring STM32F103, $(MCU)),)
|
||||||
|
@ -239,6 +245,9 @@ ifneq ($(findstring STM32F303, $(MCU)),)
|
||||||
|
|
||||||
# UF2 settings
|
# UF2 settings
|
||||||
UF2_FAMILY ?= STM32F3
|
UF2_FAMILY ?= STM32F3
|
||||||
|
|
||||||
|
# Bootloader address for STM32 DFU
|
||||||
|
STM32_BOOTLOADER_ADDRESS ?= 0x1FFFD800
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(findstring STM32F401, $(MCU)),)
|
ifneq ($(findstring STM32F401, $(MCU)),)
|
||||||
|
@ -276,6 +285,9 @@ ifneq ($(findstring STM32F401, $(MCU)),)
|
||||||
|
|
||||||
# UF2 settings
|
# UF2 settings
|
||||||
UF2_FAMILY ?= STM32F4
|
UF2_FAMILY ?= STM32F4
|
||||||
|
|
||||||
|
# Bootloader address for STM32 DFU
|
||||||
|
STM32_BOOTLOADER_ADDRESS ?= 0x1FFF0000
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(findstring STM32F405, $(MCU)),)
|
ifneq ($(findstring STM32F405, $(MCU)),)
|
||||||
|
@ -308,6 +320,9 @@ ifneq ($(findstring STM32F405, $(MCU)),)
|
||||||
|
|
||||||
# UF2 settings
|
# UF2 settings
|
||||||
UF2_FAMILY ?= STM32F4
|
UF2_FAMILY ?= STM32F4
|
||||||
|
|
||||||
|
# Bootloader address for STM32 DFU
|
||||||
|
STM32_BOOTLOADER_ADDRESS ?= 0x1FFF0000
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(findstring STM32F407, $(MCU)),)
|
ifneq ($(findstring STM32F407, $(MCU)),)
|
||||||
|
@ -340,6 +355,9 @@ ifneq ($(findstring STM32F407, $(MCU)),)
|
||||||
|
|
||||||
# UF2 settings
|
# UF2 settings
|
||||||
UF2_FAMILY ?= STM32F4
|
UF2_FAMILY ?= STM32F4
|
||||||
|
|
||||||
|
# Bootloader address for STM32 DFU
|
||||||
|
STM32_BOOTLOADER_ADDRESS ?= 0x1FFF0000
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(findstring STM32F411, $(MCU)),)
|
ifneq ($(findstring STM32F411, $(MCU)),)
|
||||||
|
@ -377,6 +395,9 @@ ifneq ($(findstring STM32F411, $(MCU)),)
|
||||||
|
|
||||||
# UF2 settings
|
# UF2 settings
|
||||||
UF2_FAMILY ?= STM32F4
|
UF2_FAMILY ?= STM32F4
|
||||||
|
|
||||||
|
# Bootloader address for STM32 DFU
|
||||||
|
STM32_BOOTLOADER_ADDRESS ?= 0x1FFF0000
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(findstring STM32F446, $(MCU)),)
|
ifneq ($(findstring STM32F446, $(MCU)),)
|
||||||
|
@ -406,6 +427,9 @@ ifneq ($(findstring STM32F446, $(MCU)),)
|
||||||
BOARD ?= GENERIC_STM32_F446XE
|
BOARD ?= GENERIC_STM32_F446XE
|
||||||
|
|
||||||
USE_FPU ?= yes
|
USE_FPU ?= yes
|
||||||
|
|
||||||
|
# Bootloader address for STM32 DFU
|
||||||
|
STM32_BOOTLOADER_ADDRESS ?= 0x1FFF0000
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(findstring STM32G431, $(MCU)),)
|
ifneq ($(findstring STM32G431, $(MCU)),)
|
||||||
|
@ -438,6 +462,9 @@ ifneq ($(findstring STM32G431, $(MCU)),)
|
||||||
|
|
||||||
# UF2 settings
|
# UF2 settings
|
||||||
UF2_FAMILY ?= STM32G4
|
UF2_FAMILY ?= STM32G4
|
||||||
|
|
||||||
|
# Bootloader address for STM32 DFU
|
||||||
|
STM32_BOOTLOADER_ADDRESS ?= 0x1FFF0000
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(findstring STM32G474, $(MCU)),)
|
ifneq ($(findstring STM32G474, $(MCU)),)
|
||||||
|
@ -470,6 +497,46 @@ ifneq ($(findstring STM32G474, $(MCU)),)
|
||||||
|
|
||||||
# UF2 settings
|
# UF2 settings
|
||||||
UF2_FAMILY ?= STM32G4
|
UF2_FAMILY ?= STM32G4
|
||||||
|
|
||||||
|
# Bootloader address for STM32 DFU
|
||||||
|
STM32_BOOTLOADER_ADDRESS ?= 0x1FFF0000
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq (,$(filter $(MCU),STM32L432 STM32L442))
|
||||||
|
# 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 = STM32
|
||||||
|
MCU_SERIES = STM32L4xx
|
||||||
|
|
||||||
|
# Linker script to use
|
||||||
|
# - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/
|
||||||
|
# or <keyboard_dir>/ld/
|
||||||
|
MCU_LDSCRIPT ?= STM32L432xC
|
||||||
|
|
||||||
|
# Startup code to use
|
||||||
|
# - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/
|
||||||
|
MCU_STARTUP ?= stm32l4xx
|
||||||
|
|
||||||
|
# Board: it should exist either in <chibios>/os/hal/boards/,
|
||||||
|
# <keyboard_dir>/boards/, or drivers/boards/
|
||||||
|
BOARD ?= GENERIC_STM32_L432XC
|
||||||
|
|
||||||
|
PLATFORM_NAME ?= platform_l432
|
||||||
|
|
||||||
|
USE_FPU ?= yes
|
||||||
|
|
||||||
|
# UF2 settings
|
||||||
|
UF2_FAMILY ?= STM32L4
|
||||||
|
|
||||||
|
# Bootloader address for STM32 DFU
|
||||||
|
STM32_BOOTLOADER_ADDRESS ?= 0x1FFF0000
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter $(MCU),STM32L433 STM32L443))
|
ifneq (,$(filter $(MCU),STM32L433 STM32L443))
|
||||||
|
@ -504,6 +571,9 @@ ifneq (,$(filter $(MCU),STM32L433 STM32L443))
|
||||||
|
|
||||||
# UF2 settings
|
# UF2 settings
|
||||||
UF2_FAMILY ?= STM32L4
|
UF2_FAMILY ?= STM32L4
|
||||||
|
|
||||||
|
# Bootloader address for STM32 DFU
|
||||||
|
STM32_BOOTLOADER_ADDRESS ?= 0x1FFF0000
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter $(MCU),STM32L412 STM32L422))
|
ifneq (,$(filter $(MCU),STM32L412 STM32L422))
|
||||||
|
@ -538,6 +608,9 @@ ifneq (,$(filter $(MCU),STM32L412 STM32L422))
|
||||||
|
|
||||||
# UF2 settings
|
# UF2 settings
|
||||||
UF2_FAMILY ?= STM32L4
|
UF2_FAMILY ?= STM32L4
|
||||||
|
|
||||||
|
# Bootloader address for STM32 DFU
|
||||||
|
STM32_BOOTLOADER_ADDRESS ?= 0x1FFF0000
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(findstring WB32F3G71, $(MCU)),)
|
ifneq ($(findstring WB32F3G71, $(MCU)),)
|
||||||
|
@ -567,6 +640,10 @@ ifneq ($(findstring WB32F3G71, $(MCU)),)
|
||||||
BOARD ?= GENERIC_WB32_F3G71XX
|
BOARD ?= GENERIC_WB32_F3G71XX
|
||||||
|
|
||||||
USE_FPU ?= no
|
USE_FPU ?= no
|
||||||
|
|
||||||
|
# Bootloader address for WB32 DFU
|
||||||
|
STM32_BOOTLOADER_ADDRESS ?= 0x1FFFE000
|
||||||
|
WB32_BOOTLOADER_ADDRESS ?= 0x1FFFE000
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(findstring GD32VF103, $(MCU)),)
|
ifneq ($(findstring GD32VF103, $(MCU)),)
|
||||||
|
|
|
@ -87,6 +87,7 @@ define GENERATE_MSG_AVAILABLE_KEYMAPS
|
||||||
endef
|
endef
|
||||||
MSG_AVAILABLE_KEYMAPS = $(eval $(call GENERATE_MSG_AVAILABLE_KEYMAPS))$(MSG_AVAILABLE_KEYMAPS_ACTUAL)
|
MSG_AVAILABLE_KEYMAPS = $(eval $(call GENERATE_MSG_AVAILABLE_KEYMAPS))$(MSG_AVAILABLE_KEYMAPS_ACTUAL)
|
||||||
|
|
||||||
|
MSG_BOOTLOADER_NOT_FOUND_BASE = Bootloader not found. Make sure the board is in bootloader mode. See https://docs.qmk.fm/\#/newbs_flashing\n
|
||||||
MSG_CHECK_FILESIZE = Checking file size of $(TARGET).$(FIRMWARE_FORMAT)
|
MSG_CHECK_FILESIZE = Checking file size of $(TARGET).$(FIRMWARE_FORMAT)
|
||||||
MSG_CHECK_FILESIZE_SKIPPED = (Firmware size check does not yet support $(MCU_ORIG); skipping)
|
MSG_CHECK_FILESIZE_SKIPPED = (Firmware size check does not yet support $(MCU_ORIG); skipping)
|
||||||
MSG_FILE_TOO_BIG = $(ERROR_COLOR)The firmware is too large!$(NO_COLOR) $(CURRENT_SIZE)/$(MAX_SIZE) ($(OVER_SIZE) bytes over)\n
|
MSG_FILE_TOO_BIG = $(ERROR_COLOR)The firmware is too large!$(NO_COLOR) $(CURRENT_SIZE)/$(MAX_SIZE) ($(OVER_SIZE) bytes over)\n
|
||||||
|
@ -97,6 +98,11 @@ MSG_PYTHON_MISSING = $(ERROR_COLOR)ERROR:$(NO_COLOR) Cannot run \"qmk hello\"!\n
|
||||||
Please run $(BOLD)qmk setup$(NO_COLOR) to install all the dependencies QMK requires.\n\n
|
Please run $(BOLD)qmk setup$(NO_COLOR) to install all the dependencies QMK requires.\n\n
|
||||||
MSG_FLASH_BOOTLOADER = $(WARN_COLOR)WARNING:$(NO_COLOR) This board's bootloader is not specified or is not supported by the \":flash\" target at this time.\n\n
|
MSG_FLASH_BOOTLOADER = $(WARN_COLOR)WARNING:$(NO_COLOR) This board's bootloader is not specified or is not supported by the \":flash\" target at this time.\n\n
|
||||||
MSG_FLASH_ARCH = $(WARN_COLOR)WARNING:$(NO_COLOR) This board's architecture is not supported by the \":flash\" target at this time.\n\n
|
MSG_FLASH_ARCH = $(WARN_COLOR)WARNING:$(NO_COLOR) This board's architecture is not supported by the \":flash\" target at this time.\n\n
|
||||||
MSG_BOOTLOADER_NOT_FOUND = $(ERROR_COLOR)ERROR:$(NO_COLOR) Bootloader not found. Trying again in 5s (Ctrl+C to cancel)\n
|
MSG_BOOTLOADER_NOT_FOUND = $(ERROR_COLOR)ERROR:$(NO_COLOR) $(MSG_BOOTLOADER_NOT_FOUND_BASE) Trying again in 5s (Ctrl+C to cancel)\n
|
||||||
BOOTLOADER_RETRY_TIME ?= 0.5
|
BOOTLOADER_RETRY_TIME ?= 0.5
|
||||||
MSG_BOOTLOADER_NOT_FOUND_QUICK_RETRY = Bootloader not found. Trying again every $(BOOTLOADER_RETRY_TIME)s (Ctrl+C to cancel)
|
MSG_BOOTLOADER_NOT_FOUND_QUICK_RETRY = $(MSG_BOOTLOADER_NOT_FOUND_BASE) Trying again every $(BOOTLOADER_RETRY_TIME)s (Ctrl+C to cancel)
|
||||||
|
|
||||||
|
define CATASTROPHIC_ERROR
|
||||||
|
$(shell printf "\n * %-99s $(ERROR_STRING)\n" "$2" >&2)
|
||||||
|
$(error $1)
|
||||||
|
endef
|
|
@ -8,7 +8,7 @@ include $(PLATFORM_PATH)/test/testlist.mk
|
||||||
define VALIDATE_TEST_LIST
|
define VALIDATE_TEST_LIST
|
||||||
ifneq ($1,)
|
ifneq ($1,)
|
||||||
ifeq ($$(findstring -,$1),-)
|
ifeq ($$(findstring -,$1),-)
|
||||||
$$(error Test names can't contain '-', but '$1' does)
|
$$(call CATASTROPHIC_ERROR,Invalid test name,Test names can't contain '-', but '$1' does.)
|
||||||
else
|
else
|
||||||
$$(eval $$(call VALIDATE_TEST_LIST,$$(firstword $2),$$(wordlist 2,9999,$2)))
|
$$(eval $$(call VALIDATE_TEST_LIST,$$(firstword $2),$$(wordlist 2,9999,$2)))
|
||||||
endif
|
endif
|
|
@ -15,6 +15,8 @@
|
||||||
"COMBO_TERM": {"info_key": "combo.term", "value_type": "int"},
|
"COMBO_TERM": {"info_key": "combo.term", "value_type": "int"},
|
||||||
"DEBOUNCE": {"info_key": "debounce", "value_type": "int"},
|
"DEBOUNCE": {"info_key": "debounce", "value_type": "int"},
|
||||||
"DEVICE_VER": {"info_key": "usb.device_ver", "value_type": "hex"},
|
"DEVICE_VER": {"info_key": "usb.device_ver", "value_type": "hex"},
|
||||||
|
# TODO: Replace ^^^ with vvv
|
||||||
|
#"DEVICE_VER": {"info_key": "usb.device_version", "value_type": "bcd_version"},
|
||||||
"DESCRIPTION": {"info_key": "keyboard_folder", "to_json": false},
|
"DESCRIPTION": {"info_key": "keyboard_folder", "to_json": false},
|
||||||
"DIODE_DIRECTION": {"info_key": "diode_direction"},
|
"DIODE_DIRECTION": {"info_key": "diode_direction"},
|
||||||
"FORCE_NKRO": {"info_key": "usb.force_nkro", "value_type": "bool"},
|
"FORCE_NKRO": {"info_key": "usb.force_nkro", "value_type": "bool"},
|
||||||
|
|
|
@ -41,8 +41,14 @@
|
||||||
'atom47/rev3': {
|
'atom47/rev3': {
|
||||||
target: 'maartenwut/atom47/rev3'
|
target: 'maartenwut/atom47/rev3'
|
||||||
},
|
},
|
||||||
|
bakeneko60: {
|
||||||
|
target: 'kkatano/bakeneko60'
|
||||||
|
},
|
||||||
bakeneko65: {
|
bakeneko65: {
|
||||||
target: 'bakeneko65/rev2'
|
target: 'kkatano/bakeneko65/rev2'
|
||||||
|
},
|
||||||
|
bakeneko80: {
|
||||||
|
target: 'kkatano/bakeneko80'
|
||||||
},
|
},
|
||||||
bear_face: {
|
bear_face: {
|
||||||
target: 'bear_face/v1'
|
target: 'bear_face/v1'
|
||||||
|
@ -215,6 +221,9 @@
|
||||||
LAYOUT: 'LAYOUT_all'
|
LAYOUT: 'LAYOUT_all'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
idobo: {
|
||||||
|
target: 'idobao/id75'
|
||||||
|
},
|
||||||
'jj40': {
|
'jj40': {
|
||||||
target: 'kprepublic/jj40'
|
target: 'kprepublic/jj40'
|
||||||
},
|
},
|
||||||
|
@ -260,6 +269,9 @@
|
||||||
'lfkeyboards/smk65': {
|
'lfkeyboards/smk65': {
|
||||||
target: 'lfkeyboards/smk65/revb'
|
target: 'lfkeyboards/smk65/revb'
|
||||||
},
|
},
|
||||||
|
m3v3van: {
|
||||||
|
target: 'matthewdias/m3n3van'
|
||||||
|
},
|
||||||
'maartenwut/atom47/rev2': {
|
'maartenwut/atom47/rev2': {
|
||||||
target: 'evyd13/atom47/rev2'
|
target: 'evyd13/atom47/rev2'
|
||||||
},
|
},
|
||||||
|
@ -353,9 +365,15 @@
|
||||||
'mechlovin/hannah65': {
|
'mechlovin/hannah65': {
|
||||||
target: 'mechlovin/hannah65/rev1'
|
target: 'mechlovin/hannah65/rev1'
|
||||||
},
|
},
|
||||||
|
minim: {
|
||||||
|
target: 'matthewdias/minim'
|
||||||
|
},
|
||||||
model01: {
|
model01: {
|
||||||
target: 'keyboardio/model01'
|
target: 'keyboardio/model01'
|
||||||
},
|
},
|
||||||
|
model_v: {
|
||||||
|
target: 'matthewdias/model_v'
|
||||||
|
},
|
||||||
m0lly: {
|
m0lly: {
|
||||||
target: 'tkc/m0lly'
|
target: 'tkc/m0lly'
|
||||||
},
|
},
|
||||||
|
@ -498,6 +516,9 @@
|
||||||
'tokyo60': {
|
'tokyo60': {
|
||||||
target: 'tokyokeyboard/tokyo60'
|
target: 'tokyokeyboard/tokyo60'
|
||||||
},
|
},
|
||||||
|
'txuu': {
|
||||||
|
target: 'matthewdias/txuu'
|
||||||
|
},
|
||||||
underscore33: {
|
underscore33: {
|
||||||
target: 'underscore33/rev1'
|
target: 'underscore33/rev1'
|
||||||
},
|
},
|
||||||
|
@ -550,7 +571,7 @@
|
||||||
target: 'xelus/valor/rev1'
|
target: 'xelus/valor/rev1'
|
||||||
},
|
},
|
||||||
yd60mq: {
|
yd60mq: {
|
||||||
target: 'yd60mq/12led'
|
target: 'ymdk/yd60mq/12led'
|
||||||
},
|
},
|
||||||
ymd75: {
|
ymd75: {
|
||||||
target: 'ymd75/rev1'
|
target: 'ymd75/rev1'
|
||||||
|
@ -563,5 +584,615 @@
|
||||||
},
|
},
|
||||||
zeal65: {
|
zeal65: {
|
||||||
target: 'wilba_tech/zeal65'
|
target: 'wilba_tech/zeal65'
|
||||||
|
},
|
||||||
|
# Moved during 2022 Q1 cycle
|
||||||
|
6ball: {
|
||||||
|
target: 'maple_computing/6ball'
|
||||||
|
},
|
||||||
|
7skb: {
|
||||||
|
target: 'salicylic_acid3/7skb'
|
||||||
|
},
|
||||||
|
7splus: {
|
||||||
|
target: 'salicylic_acid3/7splus'
|
||||||
|
},
|
||||||
|
acr60: {
|
||||||
|
target: 'mechkeys/acr60'
|
||||||
|
},
|
||||||
|
adalyn: {
|
||||||
|
target: 'tominabox1/adalyn'
|
||||||
|
},
|
||||||
|
ajisai74: {
|
||||||
|
target: 'salicylic_acid3/ajisai74'
|
||||||
|
},
|
||||||
|
aleth42: {
|
||||||
|
target: '25keys/aleth42'
|
||||||
|
},
|
||||||
|
alicia_cook: {
|
||||||
|
target: 'ibnuda/alicia_cook'
|
||||||
|
},
|
||||||
|
allison: {
|
||||||
|
target: 'prototypist/allison'
|
||||||
|
},
|
||||||
|
allison_numpad: {
|
||||||
|
target: 'prototypist/allison_numpad'
|
||||||
|
},
|
||||||
|
alu84: {
|
||||||
|
target: 'mechkeys/alu84'
|
||||||
|
},
|
||||||
|
angel17: {
|
||||||
|
target: 'kakunpc/angel17'
|
||||||
|
},
|
||||||
|
angel64/alpha: {
|
||||||
|
target: 'kakunpc/angel64/alpha'
|
||||||
|
},
|
||||||
|
angel64/rev1: {
|
||||||
|
target: 'kakunpc/angel64/rev1'
|
||||||
|
},
|
||||||
|
arch_36: {
|
||||||
|
target: 'obosob/arch_36'
|
||||||
|
},
|
||||||
|
bakeneko60: {
|
||||||
|
target: 'kkatano/bakeneko60'
|
||||||
|
},
|
||||||
|
bakeneko65/rev2: {
|
||||||
|
target: 'kkatano/bakeneko65/rev2'
|
||||||
|
},
|
||||||
|
bakeneko65/rev3: {
|
||||||
|
target: 'kkatano/bakeneko65/rev3'
|
||||||
|
},
|
||||||
|
bakeneko80: {
|
||||||
|
target: 'kkatano/bakeneko80'
|
||||||
|
},
|
||||||
|
barleycorn: {
|
||||||
|
target: 'yiancardesigns/barleycorn'
|
||||||
|
},
|
||||||
|
bat43/rev1: {
|
||||||
|
target: 'dailycraft/bat43/rev1'
|
||||||
|
},
|
||||||
|
bat43/rev2: {
|
||||||
|
target: 'dailycraft/bat43/rev2'
|
||||||
|
},
|
||||||
|
bigseries/1key: {
|
||||||
|
target: 'woodkeys/bigseries/1key'
|
||||||
|
},
|
||||||
|
bigseries/2key: {
|
||||||
|
target: 'woodkeys/bigseries/2key'
|
||||||
|
},
|
||||||
|
bigseries/3key: {
|
||||||
|
target: 'woodkeys/bigseries/3key'
|
||||||
|
},
|
||||||
|
bigseries/4key: {
|
||||||
|
target: 'woodkeys/bigseries/4key'
|
||||||
|
},
|
||||||
|
bkf: {
|
||||||
|
target: 'drhigsby/bkf'
|
||||||
|
},
|
||||||
|
business_card/alpha: {
|
||||||
|
target: 'kakunpc/business_card/alpha'
|
||||||
|
},
|
||||||
|
business_card/beta: {
|
||||||
|
target: 'kakunpc/business_card/beta'
|
||||||
|
},
|
||||||
|
butterstick: {
|
||||||
|
target: 'gboards/butterstick'
|
||||||
|
},
|
||||||
|
c39: {
|
||||||
|
target: 'maple_computing/c39'
|
||||||
|
},
|
||||||
|
cassette42: {
|
||||||
|
target: '25keys/cassette42'
|
||||||
|
},
|
||||||
|
chidori: {
|
||||||
|
target: 'kagizaraya/chidori'
|
||||||
|
},
|
||||||
|
chili: {
|
||||||
|
target: 'ydkb/chili'
|
||||||
|
},
|
||||||
|
chimera_ergo: {
|
||||||
|
target: 'glenpickle/chimera_ergo'
|
||||||
|
},
|
||||||
|
chimera_ls: {
|
||||||
|
target: 'glenpickle/chimera_ls'
|
||||||
|
},
|
||||||
|
chimera_ortho: {
|
||||||
|
target: 'glenpickle/chimera_ortho'
|
||||||
|
},
|
||||||
|
chimera_ortho_plus: {
|
||||||
|
target: 'glenpickle/chimera_ortho_plus'
|
||||||
|
},
|
||||||
|
choc_taro: {
|
||||||
|
target: 'kakunpc/choc_taro'
|
||||||
|
},
|
||||||
|
choco60: {
|
||||||
|
target: 'recompile_keys/choco60'
|
||||||
|
},
|
||||||
|
christmas_tree: {
|
||||||
|
target: 'maple_computing/christmas_tree'
|
||||||
|
},
|
||||||
|
claw44/rev1: {
|
||||||
|
target: 'dailycraft/claw44/rev1'
|
||||||
|
},
|
||||||
|
cocoa40: {
|
||||||
|
target: 'recompile_keys/cocoa40'
|
||||||
|
},
|
||||||
|
comet46: {
|
||||||
|
target: 'satt/comet46'
|
||||||
|
},
|
||||||
|
cu24: {
|
||||||
|
target: 'capsunlocked/cu24'
|
||||||
|
},
|
||||||
|
cu75: {
|
||||||
|
target: 'capsunlocked/cu75'
|
||||||
|
},
|
||||||
|
cu80: {
|
||||||
|
target: 'capsunlocked/cu80/v1'
|
||||||
|
},
|
||||||
|
delilah: {
|
||||||
|
target: 'rainkeebs/delilah'
|
||||||
|
},
|
||||||
|
diverge3: {
|
||||||
|
target: 'unikeyboard/diverge3'
|
||||||
|
},
|
||||||
|
divergetm2: {
|
||||||
|
target: 'unikeyboard/divergetm2'
|
||||||
|
},
|
||||||
|
dozen0: {
|
||||||
|
target: 'yynmt/dozen0'
|
||||||
|
},
|
||||||
|
dubba175: {
|
||||||
|
target: 'drhigsby/dubba175'
|
||||||
|
},
|
||||||
|
eggman: {
|
||||||
|
target: 'qpockets/eggman'
|
||||||
|
},
|
||||||
|
ergo42: {
|
||||||
|
target: 'biacco42/ergo42'
|
||||||
|
},
|
||||||
|
ergoarrows: {
|
||||||
|
target: 'salicylic_acid3/ergoarrows'
|
||||||
|
},
|
||||||
|
ergodash/mini: {
|
||||||
|
target: 'omkbd/ergodash/mini'
|
||||||
|
},
|
||||||
|
ergodash/rev1: {
|
||||||
|
target: 'omkbd/ergodash/rev1'
|
||||||
|
},
|
||||||
|
ergodox_infinity: {
|
||||||
|
target: 'input_club/ergodox_infinity'
|
||||||
|
},
|
||||||
|
ergotaco: {
|
||||||
|
target: 'gboards/ergotaco'
|
||||||
|
},
|
||||||
|
espectro: {
|
||||||
|
target: 'mechkeys/espectro'
|
||||||
|
},
|
||||||
|
felix: {
|
||||||
|
target: 'unikeyboard/felix'
|
||||||
|
},
|
||||||
|
four_banger: {
|
||||||
|
target: 'bpiphany/four_banger'
|
||||||
|
},
|
||||||
|
freyr: {
|
||||||
|
target: 'hnahkb/freyr'
|
||||||
|
},
|
||||||
|
geminate60: {
|
||||||
|
target: 'weirdo/geminate60'
|
||||||
|
},
|
||||||
|
georgi: {
|
||||||
|
target: 'gboards/georgi'
|
||||||
|
},
|
||||||
|
gergo: {
|
||||||
|
target: 'gboards/gergo'
|
||||||
|
},
|
||||||
|
getta25: {
|
||||||
|
target: 'salicylic_acid3/getta25'
|
||||||
|
},
|
||||||
|
gingham: {
|
||||||
|
target: 'yiancardesigns/gingham'
|
||||||
|
},
|
||||||
|
gurindam: {
|
||||||
|
target: 'ibnuda/gurindam'
|
||||||
|
},
|
||||||
|
halberd: {
|
||||||
|
target: 'kagizaraya/halberd'
|
||||||
|
},
|
||||||
|
hecomi/alpha: {
|
||||||
|
target: 'takashiski/hecomi/alpha'
|
||||||
|
},
|
||||||
|
hid_liber: {
|
||||||
|
target: 'bpiphany/hid_liber'
|
||||||
|
},
|
||||||
|
id67/default_rgb: {
|
||||||
|
target: 'idobao/id67/default_rgb'
|
||||||
|
},
|
||||||
|
id67/rgb: {
|
||||||
|
target: 'idobao/id67/rgb'
|
||||||
|
},
|
||||||
|
id80: {
|
||||||
|
target: 'idobao/id80/v1'
|
||||||
|
},
|
||||||
|
id87: {
|
||||||
|
target: 'idobao/id87/v1'
|
||||||
|
},
|
||||||
|
idobo: {
|
||||||
|
target: 'idobao/id75/v1'
|
||||||
|
},
|
||||||
|
infinity60: {
|
||||||
|
target: 'input_club/infinity60'
|
||||||
|
},
|
||||||
|
ivy/rev1: {
|
||||||
|
target: 'maple_computing/ivy/rev1'
|
||||||
|
},
|
||||||
|
jisplit89: {
|
||||||
|
target: 'salicylic_acid3/jisplit89'
|
||||||
|
},
|
||||||
|
jnao: {
|
||||||
|
target: 'maple_computing/jnao'
|
||||||
|
},
|
||||||
|
just60: {
|
||||||
|
target: 'ydkb/just60'
|
||||||
|
},
|
||||||
|
k_type: {
|
||||||
|
target: 'input_club/k_type'
|
||||||
|
},
|
||||||
|
kagamidget: {
|
||||||
|
target: 'yynmt/kagamidget'
|
||||||
|
},
|
||||||
|
kelowna/rgb64: {
|
||||||
|
target: 'weirdo/kelowna/rgb64'
|
||||||
|
},
|
||||||
|
kprepublic/bm65hsrgb_iso: {
|
||||||
|
target: 'kprepublic/bm65hsrgb_iso/rev1'
|
||||||
|
},
|
||||||
|
kprepublic/bm68hsrgb: {
|
||||||
|
target: 'kprepublic/bm68hsrgb/rev1'
|
||||||
|
},
|
||||||
|
latin17rgb: {
|
||||||
|
target: 'latincompass/latin17rgb'
|
||||||
|
},
|
||||||
|
latin47ble: {
|
||||||
|
target: 'latincompass/latin47ble'
|
||||||
|
},
|
||||||
|
latin60rgb: {
|
||||||
|
target: 'latincompass/latin60rgb'
|
||||||
|
},
|
||||||
|
latin64ble: {
|
||||||
|
target: 'latincompass/latin64ble'
|
||||||
|
},
|
||||||
|
latin6rgb: {
|
||||||
|
target: 'latincompass/latin6rgb'
|
||||||
|
},
|
||||||
|
latinpad: {
|
||||||
|
target: 'latincompass/latinpad'
|
||||||
|
},
|
||||||
|
latinpadble: {
|
||||||
|
target: 'latincompass/latinpadble'
|
||||||
|
},
|
||||||
|
launchpad/rev1: {
|
||||||
|
target: 'maple_computing/launchpad/rev1'
|
||||||
|
},
|
||||||
|
lck75: {
|
||||||
|
target: 'lyso1/lck75'
|
||||||
|
},
|
||||||
|
le_chiffre: {
|
||||||
|
target: 'tominabox1/le_chiffre'
|
||||||
|
},
|
||||||
|
lefishe: {
|
||||||
|
target: 'lyso1/lefishe'
|
||||||
|
},
|
||||||
|
lets_split_eh/eh: {
|
||||||
|
target: 'maple_computing/lets_split_eh/eh'
|
||||||
|
},
|
||||||
|
ls_60: {
|
||||||
|
target: 'weirdo/ls_60'
|
||||||
|
},
|
||||||
|
m3n3van: {
|
||||||
|
target: 'matthewdias/m3n3van'
|
||||||
|
},
|
||||||
|
mechmini/v1: {
|
||||||
|
target: 'mechkeys/mechmini/v1'
|
||||||
|
},
|
||||||
|
mechmini/v2: {
|
||||||
|
target: 'mechkeys/mechmini/v2'
|
||||||
|
},
|
||||||
|
meira: {
|
||||||
|
target: 'woodkeys/meira'
|
||||||
|
},
|
||||||
|
meishi: {
|
||||||
|
target: 'biacco42/meishi'
|
||||||
|
},
|
||||||
|
meishi2: {
|
||||||
|
target: 'biacco42/meishi2'
|
||||||
|
},
|
||||||
|
minidox/rev1: {
|
||||||
|
target: 'maple_computing/minidox/rev1'
|
||||||
|
},
|
||||||
|
minim: {
|
||||||
|
target: 'matthewdias/minim'
|
||||||
|
},
|
||||||
|
mio: {
|
||||||
|
target: 'recompile_keys/mio'
|
||||||
|
},
|
||||||
|
model_v: {
|
||||||
|
target: 'matthewdias/model_v'
|
||||||
|
},
|
||||||
|
montex: {
|
||||||
|
target: 'idobao/montex/v1'
|
||||||
|
},
|
||||||
|
nafuda: {
|
||||||
|
target: 'salicylic_acid3/nafuda'
|
||||||
|
},
|
||||||
|
naiping/np64: {
|
||||||
|
target: 'weirdo/naiping/np64'
|
||||||
|
},
|
||||||
|
naiping/nphhkb: {
|
||||||
|
target: 'weirdo/naiping/nphhkb'
|
||||||
|
},
|
||||||
|
naiping/npminila: {
|
||||||
|
target: 'weirdo/naiping/npminila'
|
||||||
|
},
|
||||||
|
naked48: {
|
||||||
|
target: 'salicylic_acid3/naked48'
|
||||||
|
},
|
||||||
|
naked60: {
|
||||||
|
target: 'salicylic_acid3/naked60'
|
||||||
|
},
|
||||||
|
naked64: {
|
||||||
|
target: 'salicylic_acid3/naked64'
|
||||||
|
},
|
||||||
|
namecard2x4: {
|
||||||
|
target: 'takashiski/namecard2x4'
|
||||||
|
},
|
||||||
|
nebula12: {
|
||||||
|
target: 'spaceholdings/nebula12'
|
||||||
|
},
|
||||||
|
nebula68: {
|
||||||
|
target: 'spaceholdings/nebula68'
|
||||||
|
},
|
||||||
|
nebula68b: {
|
||||||
|
target: 'spaceholdings/nebula68b'
|
||||||
|
},
|
||||||
|
niu_mini: {
|
||||||
|
target: 'kbdfans/niu_mini'
|
||||||
|
},
|
||||||
|
nk1: {
|
||||||
|
target: 'novelkeys/nk1'
|
||||||
|
},
|
||||||
|
nk65: {
|
||||||
|
target: 'novelkeys/nk65'
|
||||||
|
},
|
||||||
|
nk87: {
|
||||||
|
target: 'novelkeys/nk87'
|
||||||
|
},
|
||||||
|
nknl7en: {
|
||||||
|
target: 'salicylic_acid3/nknl7en'
|
||||||
|
},
|
||||||
|
nknl7jp: {
|
||||||
|
target: 'salicylic_acid3/nknl7jp'
|
||||||
|
},
|
||||||
|
nomu30: {
|
||||||
|
target: 'recompile_keys/nomu30'
|
||||||
|
},
|
||||||
|
novelpad: {
|
||||||
|
target: 'novelkeys/novelpad'
|
||||||
|
},
|
||||||
|
ogurec: {
|
||||||
|
target: 'drhigsby/ogurec'
|
||||||
|
},
|
||||||
|
otaku_split/rev0: {
|
||||||
|
target: 'takashiski/otaku_split/rev0'
|
||||||
|
},
|
||||||
|
otaku_split/rev1: {
|
||||||
|
target: 'takashiski/otaku_split/rev1'
|
||||||
|
},
|
||||||
|
owl8: {
|
||||||
|
target: 'dailycraft/owl8'
|
||||||
|
},
|
||||||
|
packrat: {
|
||||||
|
target: 'drhigsby/packrat'
|
||||||
|
},
|
||||||
|
pistachio: {
|
||||||
|
target: 'rate/pistachio'
|
||||||
|
},
|
||||||
|
pistachio_mp: {
|
||||||
|
target: 'rate/pistachio_mp'
|
||||||
|
},
|
||||||
|
pistachio_pro: {
|
||||||
|
target: 'rate/pistachio_pro'
|
||||||
|
},
|
||||||
|
plexus75: {
|
||||||
|
target: 'checkerboards/plexus75'
|
||||||
|
},
|
||||||
|
pursuit40: {
|
||||||
|
target: 'checkerboards/pursuit40'
|
||||||
|
},
|
||||||
|
qaz: {
|
||||||
|
target: 'tominabox1/qaz'
|
||||||
|
},
|
||||||
|
quark: {
|
||||||
|
target: 'checkerboards/quark'
|
||||||
|
},
|
||||||
|
rabbit_capture_plan: {
|
||||||
|
target: 'kakunpc/rabbit_capture_plan'
|
||||||
|
},
|
||||||
|
rainkeeb: {
|
||||||
|
target: 'rainkeebs/rainkeeb'
|
||||||
|
},
|
||||||
|
reviung33: {
|
||||||
|
target: 'reviung/reviung33'
|
||||||
|
},
|
||||||
|
reviung34: {
|
||||||
|
target: 'reviung/reviung34'
|
||||||
|
},
|
||||||
|
reviung39: {
|
||||||
|
target: 'reviung/reviung39'
|
||||||
|
},
|
||||||
|
reviung41: {
|
||||||
|
target: 'reviung/reviung41'
|
||||||
|
},
|
||||||
|
reviung5: {
|
||||||
|
target: 'reviung/reviung5'
|
||||||
|
},
|
||||||
|
reviung53: {
|
||||||
|
target: 'reviung/reviung53'
|
||||||
|
},
|
||||||
|
reviung61: {
|
||||||
|
target: 'reviung/reviung61'
|
||||||
|
},
|
||||||
|
runner3680/3x6: {
|
||||||
|
target: 'omkbd/runner3680/3x6'
|
||||||
|
},
|
||||||
|
runner3680/3x7: {
|
||||||
|
target: 'omkbd/runner3680/3x7'
|
||||||
|
},
|
||||||
|
runner3680/3x8: {
|
||||||
|
target: 'omkbd/runner3680/3x8'
|
||||||
|
},
|
||||||
|
runner3680/4x6: {
|
||||||
|
target: 'omkbd/runner3680/4x6'
|
||||||
|
},
|
||||||
|
runner3680/4x7: {
|
||||||
|
target: 'omkbd/runner3680/4x7'
|
||||||
|
},
|
||||||
|
runner3680/4x8: {
|
||||||
|
target: 'omkbd/runner3680/4x8'
|
||||||
|
},
|
||||||
|
runner3680/5x6: {
|
||||||
|
target: 'omkbd/runner3680/5x6'
|
||||||
|
},
|
||||||
|
runner3680/5x6_5x8: {
|
||||||
|
target: 'omkbd/runner3680/5x6_5x8'
|
||||||
|
},
|
||||||
|
runner3680/5x7: {
|
||||||
|
target: 'omkbd/runner3680/5x7'
|
||||||
|
},
|
||||||
|
runner3680/5x8: {
|
||||||
|
target: 'omkbd/runner3680/5x8'
|
||||||
|
},
|
||||||
|
scarletbandana: {
|
||||||
|
target: 'woodkeys/scarletbandana'
|
||||||
|
},
|
||||||
|
scythe: {
|
||||||
|
target: 'kagizaraya/scythe'
|
||||||
|
},
|
||||||
|
seigaiha: {
|
||||||
|
target: 'yiancardesigns/seigaiha'
|
||||||
|
},
|
||||||
|
setta21: {
|
||||||
|
target: 'salicylic_acid3/setta21'
|
||||||
|
},
|
||||||
|
space_space/rev1: {
|
||||||
|
target: 'qpockets/space_space/rev1'
|
||||||
|
},
|
||||||
|
space_space/rev2: {
|
||||||
|
target: 'qpockets/space_space/rev2'
|
||||||
|
},
|
||||||
|
spiderisland/winry25tc: {
|
||||||
|
target: 'winry/winry25tc'
|
||||||
|
},
|
||||||
|
splitreus62: {
|
||||||
|
target: 'nacly/splitreus62'
|
||||||
|
},
|
||||||
|
squiggle/rev1: {
|
||||||
|
target: 'ibnuda/squiggle/rev1'
|
||||||
|
},
|
||||||
|
standaside: {
|
||||||
|
target: 'edi/standaside'
|
||||||
|
},
|
||||||
|
steal_this_keyboard: {
|
||||||
|
target: 'obosob/steal_this_keyboard'
|
||||||
|
},
|
||||||
|
stella: {
|
||||||
|
target: 'hnahkb/stella'
|
||||||
|
},
|
||||||
|
suihankey/alpha: {
|
||||||
|
target: 'kakunpc/suihankey/alpha'
|
||||||
|
},
|
||||||
|
suihankey/rev1: {
|
||||||
|
target: 'kakunpc/suihankey/rev1'
|
||||||
|
},
|
||||||
|
suihankey/split: {
|
||||||
|
target: 'kakunpc/suihankey/split'
|
||||||
|
},
|
||||||
|
the_ruler: {
|
||||||
|
target: 'maple_computing/the_ruler'
|
||||||
|
},
|
||||||
|
thedogkeyboard: {
|
||||||
|
target: 'kakunpc/thedogkeyboard'
|
||||||
|
},
|
||||||
|
tiger910: {
|
||||||
|
target: 'weirdo/tiger910'
|
||||||
|
},
|
||||||
|
treadstone32: {
|
||||||
|
target: 'marksard/treadstone32'
|
||||||
|
},
|
||||||
|
treadstone48/rev1: {
|
||||||
|
target: 'marksard/treadstone48/rev1'
|
||||||
|
},
|
||||||
|
treadstone48/rev2: {
|
||||||
|
target: 'marksard/treadstone48/rev2'
|
||||||
|
},
|
||||||
|
txuu: {
|
||||||
|
target: 'matthewdias/txuu'
|
||||||
|
},
|
||||||
|
ua62: {
|
||||||
|
target: 'nacly/ua62'
|
||||||
|
},
|
||||||
|
underscore33/rev1: {
|
||||||
|
target: 'tominabox1/underscore33/rev1'
|
||||||
|
},
|
||||||
|
underscore33/rev2: {
|
||||||
|
target: 'tominabox1/underscore33/rev2'
|
||||||
|
},
|
||||||
|
vn66: {
|
||||||
|
target: 'hnahkb/vn66'
|
||||||
|
},
|
||||||
|
wallaby: {
|
||||||
|
target: 'kkatano/wallaby'
|
||||||
|
},
|
||||||
|
wanten: {
|
||||||
|
target: 'qpockets/wanten'
|
||||||
|
},
|
||||||
|
whitefox: {
|
||||||
|
target: 'input_club/whitefox'
|
||||||
|
},
|
||||||
|
wings42/rev1: {
|
||||||
|
target: 'dailycraft/wings42/rev1'
|
||||||
|
},
|
||||||
|
wings42/rev1_extkeys: {
|
||||||
|
target: 'dailycraft/wings42/rev1_extkeys'
|
||||||
|
},
|
||||||
|
wings42/rev2: {
|
||||||
|
target: 'dailycraft/wings42/rev2'
|
||||||
|
},
|
||||||
|
yasui: {
|
||||||
|
target: 'rainkeebs/yasui'
|
||||||
|
},
|
||||||
|
yd60mq: {
|
||||||
|
target: 'ymdk/yd60mq'
|
||||||
|
},
|
||||||
|
yd68: {
|
||||||
|
target: 'ydkb/yd68'
|
||||||
|
},
|
||||||
|
ymd75: {
|
||||||
|
target: 'ymdk/ymd75'
|
||||||
|
},
|
||||||
|
ymd96: {
|
||||||
|
target: 'ymdk/ymd96'
|
||||||
|
},
|
||||||
|
ymdk_np21: {
|
||||||
|
target: 'ymdk/np21'
|
||||||
|
},
|
||||||
|
yurei: {
|
||||||
|
target: 'kkatano/yurei'
|
||||||
|
},
|
||||||
|
zinc: {
|
||||||
|
target: '25keys/zinc'
|
||||||
|
},
|
||||||
|
zinc/rev1: {
|
||||||
|
target: '25keys/zinc/rev1'
|
||||||
|
},
|
||||||
|
zinc/reva: {
|
||||||
|
target: '25keys/zinc/reva'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,10 @@
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"pattern": "^0x[0-9A-F]{4}$"
|
"pattern": "^0x[0-9A-F]{4}$"
|
||||||
},
|
},
|
||||||
|
"bcd_version": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^[0-9]{1,2}\\.[0-9]\\.[0-9]$"
|
||||||
|
},
|
||||||
"text_identifier": {
|
"text_identifier": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"minLength": 1,
|
"minLength": 1,
|
||||||
|
@ -47,6 +51,10 @@
|
||||||
},
|
},
|
||||||
"mcu_pin": {
|
"mcu_pin": {
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["NO_PIN"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"pattern": "^[A-K]\\d{1,2}$"
|
"pattern": "^[A-K]\\d{1,2}$"
|
||||||
|
@ -70,13 +78,13 @@
|
||||||
"signed_int": {
|
"signed_int": {
|
||||||
"type": "number",
|
"type": "number",
|
||||||
"multipleOf": 1
|
"multipleOf": 1
|
||||||
}
|
},
|
||||||
"signed_int_8": {
|
"signed_int_8": {
|
||||||
"type": "number",
|
"type": "number",
|
||||||
"min": -127,
|
"min": -127,
|
||||||
"max": 127,
|
"max": 127,
|
||||||
"multipleOf": 1
|
"multipleOf": 1
|
||||||
}
|
},
|
||||||
"string_array": {
|
"string_array": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
|
@ -97,7 +105,7 @@
|
||||||
"type": "number",
|
"type": "number",
|
||||||
"min": 0,
|
"min": 0,
|
||||||
"multipleOf": 1
|
"multipleOf": 1
|
||||||
}
|
},
|
||||||
"unsigned_int_8": {
|
"unsigned_int_8": {
|
||||||
"type": "number",
|
"type": "number",
|
||||||
"min": 0,
|
"min": 0,
|
||||||
|
|
|
@ -13,7 +13,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", "STM32L433", "STM32L443", "GD32VF103", "WB32F3G71", "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", "MK66FX1M0", "STM32F042", "STM32F072", "STM32F103", "STM32F303", "STM32F401", "STM32F405", "STM32F407", "STM32F411", "STM32F446", "STM32G431", "STM32G474", "STM32L412", "STM32L422", "STM32L432", "STM32L433", "STM32L442", "STM32L443", "GD32VF103", "WB32F3G71", "atmega16u2", "atmega32u2", "atmega16u4", "atmega32u4", "at90usb162", "at90usb646", "at90usb647", "at90usb1286", "at90usb1287", "atmega32a", "atmega328p", "atmega328", "attiny85", "unknown"]
|
||||||
},
|
},
|
||||||
"audio": {
|
"audio": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"driver": {
|
"driver": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["AdafruitBLE", "RN42"]
|
"enum": ["BluefruitLE", "RN42"]
|
||||||
},
|
},
|
||||||
"lto": {"type": "boolean"},
|
"lto": {"type": "boolean"},
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@
|
||||||
},
|
},
|
||||||
"bootloader": {
|
"bootloader": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["atmel-dfu", "bootloadhid", "bootloadHID", "caterina", "halfkay", "kiibohd", "lufa-dfu", "lufa-ms", "micronucleus", "qmk-dfu", "qmk-hid", "stm32-dfu", "stm32duino", "gd32v-dfu", "wb32-dfu", "unknown", "usbasploader", "USBasp", "tinyuf2"],
|
"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"],
|
||||||
},
|
},
|
||||||
"bootloader_instructions": {
|
"bootloader_instructions": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
@ -69,7 +69,7 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"debounce_type": {
|
"debounce_type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["custom", "eager_pk", "eager_pr", "sym_defer_pk", "sym_eager_pk"]
|
"enum": ["custom", "eager_pk", "eager_pr", "sym_defer_pk", "sym_defer_pr", "sym_eager_pk"]
|
||||||
},
|
},
|
||||||
"firmware_format": {
|
"firmware_format": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
@ -320,7 +320,8 @@
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"properties": {
|
"properties": {
|
||||||
"device_ver": {"$ref": "qmk.definitions.v1#/hex_number_4d"},
|
"device_ver": {"$ref": "qmk.definitions.v1#/hex_number_4d"}, # Deprecated
|
||||||
|
"device_version": {"$ref": "qmk.definitions.v1#/bcd_version"},
|
||||||
"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"},
|
||||||
|
|
|
@ -1,138 +0,0 @@
|
||||||
// Copyright %(YEAR)s %(YOUR_NAME)s (@%(USER_NAME)s)
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "config_common.h"
|
|
||||||
|
|
||||||
/* USB Device descriptor parameter */
|
|
||||||
#define VENDOR_ID 0xFEED
|
|
||||||
#define PRODUCT_ID 0x0000
|
|
||||||
#define DEVICE_VER 0x0001
|
|
||||||
#define MANUFACTURER %(USER_NAME)s
|
|
||||||
#define PRODUCT %(KEYBOARD)s
|
|
||||||
|
|
||||||
/* key matrix size */
|
|
||||||
#define MATRIX_ROWS 2
|
|
||||||
#define MATRIX_COLS 3
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Keyboard Matrix Assignments
|
|
||||||
*
|
|
||||||
* Change this to how you wired your keyboard
|
|
||||||
* COLS: AVR pins used for columns, left to right
|
|
||||||
* ROWS: AVR pins used for rows, top to bottom
|
|
||||||
* DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
|
|
||||||
* ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define MATRIX_ROW_PINS { D0, D5 }
|
|
||||||
#define MATRIX_COL_PINS { F1, F0, B0 }
|
|
||||||
#define UNUSED_PINS
|
|
||||||
|
|
||||||
/* COL2ROW, ROW2COL */
|
|
||||||
#define DIODE_DIRECTION COL2ROW
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Split Keyboard specific options, make sure you have 'SPLIT_KEYBOARD = yes' in your rules.mk, and define SOFT_SERIAL_PIN.
|
|
||||||
*/
|
|
||||||
#define SOFT_SERIAL_PIN D0 // or D1, D2, D3, E6
|
|
||||||
|
|
||||||
//#define LED_NUM_LOCK_PIN B0
|
|
||||||
//#define LED_CAPS_LOCK_PIN B1
|
|
||||||
//#define LED_SCROLL_LOCK_PIN B2
|
|
||||||
//#define LED_COMPOSE_PIN B3
|
|
||||||
//#define LED_KANA_PIN B4
|
|
||||||
|
|
||||||
//#define BACKLIGHT_PIN B7
|
|
||||||
//#define BACKLIGHT_LEVELS 3
|
|
||||||
//#define BACKLIGHT_BREATHING
|
|
||||||
|
|
||||||
//#define RGB_DI_PIN E2
|
|
||||||
//#ifdef RGB_DI_PIN
|
|
||||||
//# define RGBLED_NUM 16
|
|
||||||
//# define RGBLIGHT_HUE_STEP 8
|
|
||||||
//# define RGBLIGHT_SAT_STEP 8
|
|
||||||
//# define RGBLIGHT_VAL_STEP 8
|
|
||||||
//# define RGBLIGHT_LIMIT_VAL 255 /* The maximum brightness level */
|
|
||||||
//# define RGBLIGHT_SLEEP /* If defined, the RGB lighting will be switched off when the host goes to sleep */
|
|
||||||
/*== all animations enable ==*/
|
|
||||||
//# define RGBLIGHT_ANIMATIONS
|
|
||||||
/*== or choose animations ==*/
|
|
||||||
//# define RGBLIGHT_EFFECT_BREATHING
|
|
||||||
//# define RGBLIGHT_EFFECT_RAINBOW_MOOD
|
|
||||||
//# define RGBLIGHT_EFFECT_RAINBOW_SWIRL
|
|
||||||
//# define RGBLIGHT_EFFECT_SNAKE
|
|
||||||
//# define RGBLIGHT_EFFECT_KNIGHT
|
|
||||||
//# define RGBLIGHT_EFFECT_CHRISTMAS
|
|
||||||
//# define RGBLIGHT_EFFECT_STATIC_GRADIENT
|
|
||||||
//# define RGBLIGHT_EFFECT_RGB_TEST
|
|
||||||
//# define RGBLIGHT_EFFECT_ALTERNATING
|
|
||||||
/*== customize breathing effect ==*/
|
|
||||||
/*==== (DEFAULT) use fixed table instead of exp() and sin() ====*/
|
|
||||||
//# define RGBLIGHT_BREATHE_TABLE_SIZE 256 // 256(default) or 128 or 64
|
|
||||||
/*==== use exp() and sin() ====*/
|
|
||||||
//# define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85 // 1 to 2.7
|
|
||||||
//# define RGBLIGHT_EFFECT_BREATHE_MAX 255 // 0 to 255
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
|
|
||||||
#define DEBOUNCE 5
|
|
||||||
|
|
||||||
/* define if matrix has ghost (lacks anti-ghosting diodes) */
|
|
||||||
//#define MATRIX_HAS_GHOST
|
|
||||||
|
|
||||||
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
|
|
||||||
#define LOCKING_SUPPORT_ENABLE
|
|
||||||
/* Locking resynchronize hack */
|
|
||||||
#define LOCKING_RESYNC_ENABLE
|
|
||||||
|
|
||||||
/* If defined, GRAVE_ESC will always act as ESC when CTRL is held.
|
|
||||||
* This is useful for the Windows task manager shortcut (ctrl+shift+esc).
|
|
||||||
*/
|
|
||||||
//#define GRAVE_ESC_CTRL_OVERRIDE
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Force NKRO
|
|
||||||
*
|
|
||||||
* Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
|
|
||||||
* state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
|
|
||||||
* makefile for this to work.)
|
|
||||||
*
|
|
||||||
* If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
|
|
||||||
* until the next keyboard reset.
|
|
||||||
*
|
|
||||||
* NKRO may prevent your keystrokes from being detected in the BIOS, but it is
|
|
||||||
* fully operational during normal computer usage.
|
|
||||||
*
|
|
||||||
* For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
|
|
||||||
* or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
|
|
||||||
* bootmagic, NKRO mode will always be enabled until it is toggled again during a
|
|
||||||
* power-up.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
//#define FORCE_NKRO
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Feature disable options
|
|
||||||
* These options are also useful to firmware size reduction.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* disable debug print */
|
|
||||||
//#define NO_DEBUG
|
|
||||||
|
|
||||||
/* disable print */
|
|
||||||
//#define NO_PRINT
|
|
||||||
|
|
||||||
/* disable action features */
|
|
||||||
//#define NO_ACTION_LAYER
|
|
||||||
//#define NO_ACTION_TAPPING
|
|
||||||
//#define NO_ACTION_ONESHOT
|
|
||||||
|
|
||||||
/* disable these deprecated features by default */
|
|
||||||
#define NO_ACTION_MACRO
|
|
||||||
#define NO_ACTION_FUNCTION
|
|
||||||
|
|
||||||
/* Bootmagic Lite key configuration */
|
|
||||||
//#define BOOTMAGIC_LITE_ROW 0
|
|
||||||
//#define BOOTMAGIC_LITE_COLUMN 0
|
|
|
@ -1,4 +0,0 @@
|
||||||
// Copyright %(YEAR)s %(YOUR_NAME)s (@%(USER_NAME)s)
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#include "%(KEYBOARD)s.h"
|
|
|
@ -1,22 +0,0 @@
|
||||||
// Copyright %(YEAR)s %(YOUR_NAME)s (@%(USER_NAME)s)
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "quantum.h"
|
|
||||||
|
|
||||||
/* This is a shortcut to help you visually see your layout.
|
|
||||||
*
|
|
||||||
* The first section contains all of the arguments representing the physical
|
|
||||||
* layout of the board and position of the keys.
|
|
||||||
*
|
|
||||||
* The second converts the arguments into a two-dimensional array which
|
|
||||||
* represents the switch matrix.
|
|
||||||
*/
|
|
||||||
#define LAYOUT( \
|
|
||||||
k00, k01, k02, \
|
|
||||||
k10, k12 \
|
|
||||||
) { \
|
|
||||||
{ k00, k01, k02 }, \
|
|
||||||
{ k10, KC_NO, k12 } \
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
{
|
|
||||||
"keyboard_name": "%(KEYBOARD)s",
|
|
||||||
"url": "",
|
|
||||||
"maintainer": "%(USER_NAME)s",
|
|
||||||
"layouts": {
|
|
||||||
"LAYOUT": {
|
|
||||||
"layout": [
|
|
||||||
{"label": "k00", "x": 0, "y": 0},
|
|
||||||
{"label": "k01", "x": 1, "y": 0},
|
|
||||||
{"label": "k02", "x": 2, "y": 0},
|
|
||||||
|
|
||||||
{"label": "k10", "x": 0, "y": 1, "w": 1.5},
|
|
||||||
{"label": "k12", "x": 1.5, "y": 1, "w": 1.5}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
// Copyright %(YEAR)s %(YOUR_NAME)s (@%(USER_NAME)s)
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#include QMK_KEYBOARD_H
|
|
||||||
|
|
||||||
// Defines names for use in layer keycodes and the keymap
|
|
||||||
enum layer_names {
|
|
||||||
_BASE,
|
|
||||||
_FN
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
|
||||||
/* Base */
|
|
||||||
[_BASE] = LAYOUT(
|
|
||||||
KC_A, KC_1, MO(_FN),
|
|
||||||
KC_TAB, KC_SPC
|
|
||||||
),
|
|
||||||
[_FN] = LAYOUT(
|
|
||||||
_______, _______, _______,
|
|
||||||
RESET, XXXXXXX
|
|
||||||
)
|
|
||||||
};
|
|
|
@ -1 +0,0 @@
|
||||||
# The default keymap for %(KEYBOARD)s
|
|
20
data/templates/keyboard/config.h
Normal file
20
data/templates/keyboard/config.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright %YEAR% %REAL_NAME% (@%USER_NAME%)
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature disable options
|
||||||
|
* These options are also useful to firmware size reduction.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* disable debug print */
|
||||||
|
//#define NO_DEBUG
|
||||||
|
|
||||||
|
/* disable print */
|
||||||
|
//#define NO_PRINT
|
||||||
|
|
||||||
|
/* disable action features */
|
||||||
|
//#define NO_ACTION_LAYER
|
||||||
|
//#define NO_ACTION_TAPPING
|
||||||
|
//#define NO_ACTION_ONESHOT
|
25
data/templates/keyboard/info.json
Normal file
25
data/templates/keyboard/info.json
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"keyboard_name": "%KEYBOARD%",
|
||||||
|
"maintainer": "%USER_NAME%",
|
||||||
|
"manufacturer": "%REAL_NAME%",
|
||||||
|
"processor": "%MCU%",
|
||||||
|
"bootloader": "%BOOTLOADER%",
|
||||||
|
"diode_direction": "COL2ROW",
|
||||||
|
"matrix_pins": {
|
||||||
|
"cols": ["C2"],
|
||||||
|
"rows": ["D1"]
|
||||||
|
},
|
||||||
|
"usb": {
|
||||||
|
"vid": "0xFEED",
|
||||||
|
"pid": "0x0000",
|
||||||
|
"device_version": "1.0.0"
|
||||||
|
},
|
||||||
|
"features": {
|
||||||
|
"bootmagic_lite": true,
|
||||||
|
"command": false,
|
||||||
|
"console": false,
|
||||||
|
"extrakey": true,
|
||||||
|
"mousekey": true,
|
||||||
|
"nkro": true
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,20 +1,20 @@
|
||||||
# %(KEYBOARD)s
|
# %KEYBOARD%
|
||||||
|
|
||||||
![%(KEYBOARD)s](imgur.com image replace me!)
|
![%KEYBOARD%](imgur.com image replace me!)
|
||||||
|
|
||||||
*A short description of the keyboard/project*
|
*A short description of the keyboard/project*
|
||||||
|
|
||||||
* Keyboard Maintainer: [%(YOUR_NAME)s](https://github.com/%(USER_NAME)s)
|
* Keyboard Maintainer: [%REAL_NAME%](https://github.com/%USER_NAME%)
|
||||||
* Hardware Supported: *The PCBs, controllers supported*
|
* Hardware Supported: *The PCBs, controllers supported*
|
||||||
* Hardware Availability: *Links to where you can find this hardware*
|
* Hardware Availability: *Links to where you can find this hardware*
|
||||||
|
|
||||||
Make example for this keyboard (after setting up your build environment):
|
Make example for this keyboard (after setting up your build environment):
|
||||||
|
|
||||||
make %(KEYBOARD)s:default
|
make %KEYBOARD%:default
|
||||||
|
|
||||||
Flashing example for this keyboard:
|
Flashing example for this keyboard:
|
||||||
|
|
||||||
make %(KEYBOARD)s:default:flash
|
make %KEYBOARD%:default:flash
|
||||||
|
|
||||||
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
|
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
|
||||||
|
|
1
data/templates/keyboard/rules.mk
Normal file
1
data/templates/keyboard/rules.mk
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# This file intentionally left blank
|
|
@ -1,128 +0,0 @@
|
||||||
// Copyright %(YEAR)s %(YOUR_NAME)s (@%(USER_NAME)s)
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "config_common.h"
|
|
||||||
|
|
||||||
/* USB Device descriptor parameter */
|
|
||||||
#define VENDOR_ID 0xFEED
|
|
||||||
#define PRODUCT_ID 0x0000
|
|
||||||
#define DEVICE_VER 0x0001
|
|
||||||
#define MANUFACTURER %(USER_NAME)s
|
|
||||||
#define PRODUCT %(KEYBOARD)s
|
|
||||||
|
|
||||||
/* key matrix size */
|
|
||||||
#define MATRIX_ROWS 8
|
|
||||||
#define MATRIX_COLS 15
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Keyboard Matrix Assignments
|
|
||||||
*
|
|
||||||
* Change this to how you wired your keyboard
|
|
||||||
* COLS: AVR pins used for columns, left to right
|
|
||||||
* ROWS: AVR pins used for rows, top to bottom
|
|
||||||
* DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
|
|
||||||
* ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define MATRIX_ROW_PINS { B0, B1, B2, B3, B4, B5, B6, B7 }
|
|
||||||
#define MATRIX_COL_PINS { A0, A1, A2, A3, A4, A5, A6, A7, C7, C6, C5, C4, C3, C2, D7 }
|
|
||||||
#define UNUSED_PINS
|
|
||||||
|
|
||||||
/* COL2ROW, ROW2COL */
|
|
||||||
#define DIODE_DIRECTION COL2ROW
|
|
||||||
|
|
||||||
//#define LED_NUM_LOCK_PIN D0
|
|
||||||
//#define LED_CAPS_LOCK_PIN D1
|
|
||||||
//#define LED_SCROLL_LOCK_PIN D6
|
|
||||||
|
|
||||||
#define BACKLIGHT_PIN D4
|
|
||||||
//#define BACKLIGHT_LEVELS 3
|
|
||||||
//#define BACKLIGHT_BREATHING
|
|
||||||
|
|
||||||
#define RGBLED_NUM 16
|
|
||||||
//#define RGBLIGHT_HUE_STEP 8
|
|
||||||
//#define RGBLIGHT_SAT_STEP 8
|
|
||||||
//#define RGBLIGHT_VAL_STEP 8
|
|
||||||
//#define RGBLIGHT_LIMIT_VAL 255 /* The maximum brightness level */
|
|
||||||
//#define RGBLIGHT_SLEEP /* If defined, the RGB lighting will be switched off when the host goes to sleep */
|
|
||||||
/*== all animations enable ==*/
|
|
||||||
//#define RGBLIGHT_ANIMATIONS
|
|
||||||
/*== or choose animations ==*/
|
|
||||||
//#define RGBLIGHT_EFFECT_BREATHING
|
|
||||||
//#define RGBLIGHT_EFFECT_RAINBOW_MOOD
|
|
||||||
//#define RGBLIGHT_EFFECT_RAINBOW_SWIRL
|
|
||||||
//#define RGBLIGHT_EFFECT_SNAKE
|
|
||||||
//#define RGBLIGHT_EFFECT_KNIGHT
|
|
||||||
//#define RGBLIGHT_EFFECT_CHRISTMAS
|
|
||||||
//#define RGBLIGHT_EFFECT_STATIC_GRADIENT
|
|
||||||
//#define RGBLIGHT_EFFECT_RGB_TEST
|
|
||||||
//#define RGBLIGHT_EFFECT_ALTERNATING
|
|
||||||
/*== customize breathing effect ==*/
|
|
||||||
/*==== (DEFAULT) use fixed table instead of exp() and sin() ====*/
|
|
||||||
//#define RGBLIGHT_BREATHE_TABLE_SIZE 256 // 256(default) or 128 or 64
|
|
||||||
/*==== use exp() and sin() ====*/
|
|
||||||
//#define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85 // 1 to 2.7
|
|
||||||
//#define RGBLIGHT_EFFECT_BREATHE_MAX 255 // 0 to 255
|
|
||||||
|
|
||||||
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
|
|
||||||
#define DEBOUNCE 5
|
|
||||||
|
|
||||||
/* define if matrix has ghost (lacks anti-ghosting diodes) */
|
|
||||||
//#define MATRIX_HAS_GHOST
|
|
||||||
|
|
||||||
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
|
|
||||||
#define LOCKING_SUPPORT_ENABLE
|
|
||||||
/* Locking resynchronize hack */
|
|
||||||
#define LOCKING_RESYNC_ENABLE
|
|
||||||
|
|
||||||
/* If defined, GRAVE_ESC will always act as ESC when CTRL is held.
|
|
||||||
* This is useful for the Windows task manager shortcut (ctrl+shift+esc).
|
|
||||||
*/
|
|
||||||
//#define GRAVE_ESC_CTRL_OVERRIDE
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Force NKRO
|
|
||||||
*
|
|
||||||
* Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
|
|
||||||
* state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
|
|
||||||
* makefile for this to work.)
|
|
||||||
*
|
|
||||||
* If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
|
|
||||||
* until the next keyboard reset.
|
|
||||||
*
|
|
||||||
* NKRO may prevent your keystrokes from being detected in the BIOS, but it is
|
|
||||||
* fully operational during normal computer usage.
|
|
||||||
*
|
|
||||||
* For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
|
|
||||||
* or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
|
|
||||||
* bootmagic, NKRO mode will always be enabled until it is toggled again during a
|
|
||||||
* power-up.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
//#define FORCE_NKRO
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Feature disable options
|
|
||||||
* These options are also useful to firmware size reduction.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* disable debug print */
|
|
||||||
//#define NO_DEBUG
|
|
||||||
|
|
||||||
/* disable print */
|
|
||||||
//#define NO_PRINT
|
|
||||||
|
|
||||||
/* disable action features */
|
|
||||||
//#define NO_ACTION_LAYER
|
|
||||||
//#define NO_ACTION_TAPPING
|
|
||||||
//#define NO_ACTION_ONESHOT
|
|
||||||
|
|
||||||
/* disable these deprecated features by default */
|
|
||||||
#define NO_ACTION_MACRO
|
|
||||||
#define NO_ACTION_FUNCTION
|
|
||||||
|
|
||||||
/* Bootmagic Lite key configuration */
|
|
||||||
//#define BOOTMAGIC_LITE_ROW 0
|
|
||||||
//#define BOOTMAGIC_LITE_COLUMN 0
|
|
|
@ -1,28 +0,0 @@
|
||||||
# %(KEYBOARD)s
|
|
||||||
|
|
||||||
![%(KEYBOARD)s](imgur.com image replace me!)
|
|
||||||
|
|
||||||
*A short description of the keyboard/project*
|
|
||||||
|
|
||||||
* Keyboard Maintainer: [%(YOUR_NAME)s](https://github.com/yourusername)
|
|
||||||
* Hardware Supported: *The PCBs, controllers supported*
|
|
||||||
* Hardware Availability: *Links to where you can find this hardware*
|
|
||||||
|
|
||||||
Make example for this keyboard (after setting up your build environment):
|
|
||||||
|
|
||||||
make %(KEYBOARD)s:default
|
|
||||||
|
|
||||||
Flashing example for this keyboard ([after setting up the bootloadHID flashing environment](https://docs.qmk.fm/#/flashing_bootloadhid))
|
|
||||||
|
|
||||||
make %(KEYBOARD)s:default:flash
|
|
||||||
|
|
||||||
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
|
|
||||||
|
|
||||||
## Bootloader
|
|
||||||
|
|
||||||
Enter the bootloader in 3 ways:
|
|
||||||
|
|
||||||
* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (usually the top left key or Escape) and plug in the keyboard
|
|
||||||
* **BootloadHID reset**: Hold down the key connected to the `A0` and `B0` pins on the MCU if it is known (often top left or bottom left) and plug in the keyboard
|
|
||||||
* **Physical reset button**: Briefly press the button on the back of the PCB - some may have pads you must short instead
|
|
||||||
* **Keycode in layout**: Press the key mapped to `RESET` if it is available
|
|
|
@ -1,17 +0,0 @@
|
||||||
# MCU name
|
|
||||||
MCU = atmega32a
|
|
||||||
|
|
||||||
# Bootloader selection
|
|
||||||
BOOTLOADER = bootloadhid
|
|
||||||
|
|
||||||
# Build Options
|
|
||||||
# change yes to no to disable
|
|
||||||
#
|
|
||||||
BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite
|
|
||||||
MOUSEKEY_ENABLE = yes # Mouse keys
|
|
||||||
EXTRAKEY_ENABLE = yes # Audio control and System control
|
|
||||||
CONSOLE_ENABLE = no # Console for debug
|
|
||||||
COMMAND_ENABLE = no # Commands for debug and configuration
|
|
||||||
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
|
|
||||||
RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
|
|
||||||
WS2812_DRIVER = i2c
|
|
489
docs/ChangeLog/20220226.md
Normal file
489
docs/ChangeLog/20220226.md
Normal file
|
@ -0,0 +1,489 @@
|
||||||
|
# QMK Breaking Changes - 2022 February 26 Changelog
|
||||||
|
|
||||||
|
## Notable Features :id=notable-features
|
||||||
|
|
||||||
|
### Default USB Polling rate now 1kHz ([#15352](https://github.com/qmk/qmk_firmware/pull/15352))
|
||||||
|
|
||||||
|
The default USB Polling rate has been aligned across supported platforms to now be 1ms/1kHz.
|
||||||
|
|
||||||
|
Something something *Lets go gamers!*
|
||||||
|
|
||||||
|
### Split support for pointing devices ([#15304](https://github.com/qmk/qmk_firmware/pull/15304))
|
||||||
|
|
||||||
|
Pointing devices can now be shared across a split keyboard with support for a single pointing device or a pointing device on each side.
|
||||||
|
|
||||||
|
See the [Pointing Device](feature_pointing_device.md) documentation for further configuration options.
|
||||||
|
|
||||||
|
## Changes Requiring User Action :id=changes-requiring-user-action
|
||||||
|
|
||||||
|
### Legacy macro and action_function system removed ([#16025](https://github.com/qmk/qmk_firmware/pull/16025))
|
||||||
|
|
||||||
|
The long time deprecated `MACRO()` and `action_get_macro` methods have been removed. Where possible, existing usages have been migrated over to core [Macros](feature_macros.md).
|
||||||
|
|
||||||
|
### Create a build error if no bootloader is specified ([#16181](https://github.com/qmk/qmk_firmware/pull/16181))
|
||||||
|
|
||||||
|
Bootloader configuration is no longer assumed. Keyboards must now set either:
|
||||||
|
|
||||||
|
* `BOOTLOADER` within `rules.mk`
|
||||||
|
* `bootloader` within `info.json`
|
||||||
|
|
||||||
|
### Rename `AdafruitBLE` to `BluefruitLE` ([#16127](https://github.com/qmk/qmk_firmware/pull/16127))
|
||||||
|
|
||||||
|
In preparation of future bluetooth work, the `AdafruitBLE` integration has been renamed to allow potential for any other Adafruit BLE products.
|
||||||
|
|
||||||
|
### Updated Keyboard Codebases :id=updated-keyboard-codebases
|
||||||
|
|
||||||
|
The following keyboards have had their source moved within QMK:
|
||||||
|
|
||||||
|
| Old Keyboard Name | New Keyboard Name |
|
||||||
|
|----------------------------|------------------------------------|
|
||||||
|
| 6ball | maple_computing/6ball |
|
||||||
|
| 7skb | salicylic_acid3/7skb |
|
||||||
|
| 7splus | salicylic_acid3/7splus |
|
||||||
|
| acr60 | mechkeys/acr60 |
|
||||||
|
| adalyn | tominabox1/adalyn |
|
||||||
|
| ajisai74 | salicylic_acid3/ajisai74 |
|
||||||
|
| aleth42 | 25keys/aleth42 |
|
||||||
|
| alicia_cook | ibnuda/alicia_cook |
|
||||||
|
| allison_numpad | prototypist/allison_numpad |
|
||||||
|
| allison | prototypist/allison |
|
||||||
|
| alu84 | mechkeys/alu84 |
|
||||||
|
| angel17 | kakunpc/angel17 |
|
||||||
|
| angel64/alpha | kakunpc/angel64/alpha |
|
||||||
|
| angel64/rev1 | kakunpc/angel64/rev1 |
|
||||||
|
| arch_36 | obosob/arch_36 |
|
||||||
|
| bakeneko60 | kkatano/bakeneko60 |
|
||||||
|
| bakeneko65/rev2 | kkatano/bakeneko65/rev2 |
|
||||||
|
| bakeneko65/rev3 | kkatano/bakeneko65/rev3 |
|
||||||
|
| bakeneko80 | kkatano/bakeneko80 |
|
||||||
|
| barleycorn | yiancardesigns/barleycorn |
|
||||||
|
| bat43/rev1 | dailycraft/bat43/rev1 |
|
||||||
|
| bat43/rev2 | dailycraft/bat43/rev2 |
|
||||||
|
| bigseries/1key | woodkeys/bigseries/1key |
|
||||||
|
| bigseries/2key | woodkeys/bigseries/2key |
|
||||||
|
| bigseries/3key | woodkeys/bigseries/3key |
|
||||||
|
| bigseries/4key | woodkeys/bigseries/4key |
|
||||||
|
| bkf | drhigsby/bkf |
|
||||||
|
| business_card/alpha | kakunpc/business_card/alpha |
|
||||||
|
| business_card/beta | kakunpc/business_card/beta |
|
||||||
|
| butterstick | gboards/butterstick |
|
||||||
|
| c39 | maple_computing/c39 |
|
||||||
|
| cassette42 | 25keys/cassette42 |
|
||||||
|
| chidori | kagizaraya/chidori |
|
||||||
|
| chili | ydkb/chili |
|
||||||
|
| chimera_ergo | glenpickle/chimera_ergo |
|
||||||
|
| chimera_ls | glenpickle/chimera_ls |
|
||||||
|
| chimera_ortho | glenpickle/chimera_ortho |
|
||||||
|
| chimera_ortho_plus | glenpickle/chimera_ortho_plus |
|
||||||
|
| choco60 | recompile_keys/choco60 |
|
||||||
|
| choc_taro | kakunpc/choc_taro |
|
||||||
|
| christmas_tree | maple_computing/christmas_tree |
|
||||||
|
| claw44/rev1 | dailycraft/claw44/rev1 |
|
||||||
|
| cocoa40 | recompile_keys/cocoa40 |
|
||||||
|
| comet46 | satt/comet46 |
|
||||||
|
| cu24 | capsunlocked/cu24 |
|
||||||
|
| cu75 | capsunlocked/cu75 |
|
||||||
|
| cu80 | capsunlocked/cu80/v1 |
|
||||||
|
| delilah | rainkeebs/delilah |
|
||||||
|
| diverge3 | unikeyboard/diverge3 |
|
||||||
|
| divergetm2 | unikeyboard/divergetm2 |
|
||||||
|
| dozen0 | yynmt/dozen0 |
|
||||||
|
| dubba175 | drhigsby/dubba175 |
|
||||||
|
| eggman | qpockets/eggman |
|
||||||
|
| ergo42 | biacco42/ergo42 |
|
||||||
|
| ergoarrows | salicylic_acid3/ergoarrows |
|
||||||
|
| ergodash/mini | omkbd/ergodash/mini |
|
||||||
|
| ergodash/rev1 | omkbd/ergodash/rev1 |
|
||||||
|
| ergodox_infinity | input_club/ergodox_infinity |
|
||||||
|
| ergotaco | gboards/ergotaco |
|
||||||
|
| espectro | mechkeys/espectro |
|
||||||
|
| felix | unikeyboard/felix |
|
||||||
|
| four_banger | bpiphany/four_banger |
|
||||||
|
| freyr | hnahkb/freyr |
|
||||||
|
| geminate60 | weirdo/geminate60 |
|
||||||
|
| georgi | gboards/georgi |
|
||||||
|
| gergo | gboards/gergo |
|
||||||
|
| getta25 | salicylic_acid3/getta25 |
|
||||||
|
| gingham | yiancardesigns/gingham |
|
||||||
|
| gurindam | ibnuda/gurindam |
|
||||||
|
| halberd | kagizaraya/halberd |
|
||||||
|
| hecomi/alpha | takashiski/hecomi/alpha |
|
||||||
|
| hid_liber | bpiphany/hid_liber |
|
||||||
|
| id67/default_rgb | idobao/id67/default_rgb |
|
||||||
|
| id67/rgb | idobao/id67/rgb |
|
||||||
|
| id80 | idobao/id80/v1 |
|
||||||
|
| id87 | idobao/id87/v1 |
|
||||||
|
| idobo | idobao/id75/v1 |
|
||||||
|
| infinity60 | input_club/infinity60 |
|
||||||
|
| ivy/rev1 | maple_computing/ivy/rev1 |
|
||||||
|
| jisplit89 | salicylic_acid3/jisplit89 |
|
||||||
|
| jnao | maple_computing/jnao |
|
||||||
|
| just60 | ydkb/just60 |
|
||||||
|
| kagamidget | yynmt/kagamidget |
|
||||||
|
| kelowna/rgb64 | weirdo/kelowna/rgb64 |
|
||||||
|
| kprepublic/bm65hsrgb_iso | kprepublic/bm65hsrgb_iso/rev1 |
|
||||||
|
| kprepublic/bm68hsrgb | kprepublic/bm68hsrgb/rev1 |
|
||||||
|
| k_type | input_club/k_type |
|
||||||
|
| latin17rgb | latincompass/latin17rgb |
|
||||||
|
| latin47ble | latincompass/latin47ble |
|
||||||
|
| latin60rgb | latincompass/latin60rgb |
|
||||||
|
| latin64ble | latincompass/latin64ble |
|
||||||
|
| latin6rgb | latincompass/latin6rgb |
|
||||||
|
| latinpadble | latincompass/latinpadble |
|
||||||
|
| latinpad | latincompass/latinpad |
|
||||||
|
| launchpad/rev1 | maple_computing/launchpad/rev1 |
|
||||||
|
| lck75 | lyso1/lck75 |
|
||||||
|
| le_chiffre | tominabox1/le_chiffre |
|
||||||
|
| lefishe | lyso1/lefishe |
|
||||||
|
| lets_split_eh/eh | maple_computing/lets_split_eh/eh |
|
||||||
|
| ls_60 | weirdo/ls_60 |
|
||||||
|
| m3n3van | matthewdias/m3n3van |
|
||||||
|
| mechmini/v1 | mechkeys/mechmini/v1 |
|
||||||
|
| mechmini/v2 | mechkeys/mechmini/v2 |
|
||||||
|
| meira | woodkeys/meira |
|
||||||
|
| meishi2 | biacco42/meishi2 |
|
||||||
|
| meishi | biacco42/meishi |
|
||||||
|
| minidox/rev1 | maple_computing/minidox/rev1 |
|
||||||
|
| minim | matthewdias/minim |
|
||||||
|
| mio | recompile_keys/mio |
|
||||||
|
| model_v | matthewdias/model_v |
|
||||||
|
| montex | idobao/montex/v1 |
|
||||||
|
| nafuda | salicylic_acid3/nafuda |
|
||||||
|
| naiping/np64 | weirdo/naiping/np64 |
|
||||||
|
| naiping/nphhkb | weirdo/naiping/nphhkb |
|
||||||
|
| naiping/npminila | weirdo/naiping/npminila |
|
||||||
|
| naked48 | salicylic_acid3/naked48 |
|
||||||
|
| naked60 | salicylic_acid3/naked60 |
|
||||||
|
| naked64 | salicylic_acid3/naked64 |
|
||||||
|
| namecard2x4 | takashiski/namecard2x4 |
|
||||||
|
| nebula12 | spaceholdings/nebula12 |
|
||||||
|
| nebula68b | spaceholdings/nebula68b |
|
||||||
|
| nebula68 | spaceholdings/nebula68 |
|
||||||
|
| niu_mini | kbdfans/niu_mini |
|
||||||
|
| nk1 | novelkeys/nk1 |
|
||||||
|
| nk65 | novelkeys/nk65 |
|
||||||
|
| nk87 | novelkeys/nk87 |
|
||||||
|
| nknl7en | salicylic_acid3/nknl7en |
|
||||||
|
| nknl7jp | salicylic_acid3/nknl7jp |
|
||||||
|
| nomu30 | recompile_keys/nomu30 |
|
||||||
|
| novelpad | novelkeys/novelpad |
|
||||||
|
| ogurec | drhigsby/ogurec |
|
||||||
|
| otaku_split/rev0 | takashiski/otaku_split/rev0 |
|
||||||
|
| otaku_split/rev1 | takashiski/otaku_split/rev1 |
|
||||||
|
| owl8 | dailycraft/owl8 |
|
||||||
|
| packrat | drhigsby/packrat |
|
||||||
|
| pistachio_mp | rate/pistachio_mp |
|
||||||
|
| pistachio_pro | rate/pistachio_pro |
|
||||||
|
| pistachio | rate/pistachio |
|
||||||
|
| plexus75 | checkerboards/plexus75 |
|
||||||
|
| pursuit40 | checkerboards/pursuit40 |
|
||||||
|
| qaz | tominabox1/qaz |
|
||||||
|
| quark | checkerboards/quark |
|
||||||
|
| rabbit_capture_plan | kakunpc/rabbit_capture_plan |
|
||||||
|
| rainkeeb | rainkeebs/rainkeeb |
|
||||||
|
| reviung33 | reviung/reviung33 |
|
||||||
|
| reviung34 | reviung/reviung34 |
|
||||||
|
| reviung39 | reviung/reviung39 |
|
||||||
|
| reviung41 | reviung/reviung41 |
|
||||||
|
| reviung53 | reviung/reviung53 |
|
||||||
|
| reviung5 | reviung/reviung5 |
|
||||||
|
| reviung61 | reviung/reviung61 |
|
||||||
|
| runner3680/3x6 | omkbd/runner3680/3x6 |
|
||||||
|
| runner3680/3x7 | omkbd/runner3680/3x7 |
|
||||||
|
| runner3680/3x8 | omkbd/runner3680/3x8 |
|
||||||
|
| runner3680/4x6 | omkbd/runner3680/4x6 |
|
||||||
|
| runner3680/4x7 | omkbd/runner3680/4x7 |
|
||||||
|
| runner3680/4x8 | omkbd/runner3680/4x8 |
|
||||||
|
| runner3680/5x6_5x8 | omkbd/runner3680/5x6_5x8 |
|
||||||
|
| runner3680/5x6 | omkbd/runner3680/5x6 |
|
||||||
|
| runner3680/5x7 | omkbd/runner3680/5x7 |
|
||||||
|
| runner3680/5x8 | omkbd/runner3680/5x8 |
|
||||||
|
| scarletbandana | woodkeys/scarletbandana |
|
||||||
|
| scythe | kagizaraya/scythe |
|
||||||
|
| seigaiha | yiancardesigns/seigaiha |
|
||||||
|
| setta21 | salicylic_acid3/setta21 |
|
||||||
|
| space_space/rev1 | qpockets/space_space/rev1 |
|
||||||
|
| space_space/rev2 | qpockets/space_space/rev2 |
|
||||||
|
| spiderisland/winry25tc | winry/winry25tc |
|
||||||
|
| splitreus62 | nacly/splitreus62 |
|
||||||
|
| squiggle/rev1 | ibnuda/squiggle/rev1 |
|
||||||
|
| standaside | edi/standaside |
|
||||||
|
| steal_this_keyboard | obosob/steal_this_keyboard |
|
||||||
|
| stella | hnahkb/stella |
|
||||||
|
| suihankey/alpha | kakunpc/suihankey/alpha |
|
||||||
|
| suihankey/rev1 | kakunpc/suihankey/rev1 |
|
||||||
|
| suihankey/split | kakunpc/suihankey/split |
|
||||||
|
| thedogkeyboard | kakunpc/thedogkeyboard |
|
||||||
|
| the_ruler | maple_computing/the_ruler |
|
||||||
|
| tiger910 | weirdo/tiger910 |
|
||||||
|
| treadstone32 | marksard/treadstone32 |
|
||||||
|
| treadstone48/rev1 | marksard/treadstone48/rev1 |
|
||||||
|
| treadstone48/rev2 | marksard/treadstone48/rev2 |
|
||||||
|
| txuu | matthewdias/txuu |
|
||||||
|
| ua62 | nacly/ua62 |
|
||||||
|
| underscore33/rev1 | tominabox1/underscore33/rev1 |
|
||||||
|
| underscore33/rev2 | tominabox1/underscore33/rev2 |
|
||||||
|
| vn66 | hnahkb/vn66 |
|
||||||
|
| wallaby | kkatano/wallaby |
|
||||||
|
| wanten | qpockets/wanten |
|
||||||
|
| whitefox | input_club/whitefox |
|
||||||
|
| wings42/rev1 | dailycraft/wings42/rev1 |
|
||||||
|
| wings42/rev1_extkeys | dailycraft/wings42/rev1_extkeys |
|
||||||
|
| wings42/rev2 | dailycraft/wings42/rev2 |
|
||||||
|
| yasui | rainkeebs/yasui |
|
||||||
|
| yd60mq | ymdk/yd60mq |
|
||||||
|
| yd68 | ydkb/yd68 |
|
||||||
|
| ymd75 | ymdk/ymd75 |
|
||||||
|
| ymd96 | ymdk/ymd96 |
|
||||||
|
| ymdk_np21 | ymdk/np21 |
|
||||||
|
| yurei | kkatano/yurei |
|
||||||
|
| zinc | 25keys/zinc |
|
||||||
|
| zinc/rev1 | 25keys/zinc/rev1 |
|
||||||
|
| zinc/reva | 25keys/zinc/reva |
|
||||||
|
|
||||||
|
## Notable core changes :id=notable-core
|
||||||
|
|
||||||
|
### New MCU Support :id=new-mcu-support
|
||||||
|
|
||||||
|
Building on previous cycles, QMK firmware picked up support for a couple extra MCU variants:
|
||||||
|
|
||||||
|
* STM32L432
|
||||||
|
* STM32L442
|
||||||
|
|
||||||
|
### New Drivers
|
||||||
|
|
||||||
|
QMK now has core-supplied support for the following device peripherals:
|
||||||
|
|
||||||
|
#### LED
|
||||||
|
|
||||||
|
* IS31FL3742A
|
||||||
|
* IS31FL3743A
|
||||||
|
* IS31FL3745
|
||||||
|
* IS31FL3746A
|
||||||
|
|
||||||
|
#### GPIO
|
||||||
|
|
||||||
|
* SN74x138
|
||||||
|
* mcp23018
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Full changelist
|
||||||
|
|
||||||
|
Core:
|
||||||
|
* Initial pass at data driven new-keyboard subcommand ([#12795](https://github.com/qmk/qmk_firmware/pull/12795))
|
||||||
|
* Don't send keyboard reports that propagate no changes to the host ([#14065](https://github.com/qmk/qmk_firmware/pull/14065))
|
||||||
|
* Custom matrix lite support for split keyboards ([#14674](https://github.com/qmk/qmk_firmware/pull/14674))
|
||||||
|
* Add sym_defer_pr debouncer type ([#14948](https://github.com/qmk/qmk_firmware/pull/14948))
|
||||||
|
* Add RGB matrix & LED Matrix support for IS31FL3742A, IS31FL3743A, IS31FL3745, IS31FL3746A ([#14989](https://github.com/qmk/qmk_firmware/pull/14989))
|
||||||
|
* New combo configuration options ([#15083](https://github.com/qmk/qmk_firmware/pull/15083))
|
||||||
|
* IS31FL3733 driver for LED Matrix ([#15088](https://github.com/qmk/qmk_firmware/pull/15088))
|
||||||
|
* Add open-drain GPIO support. ([#15282](https://github.com/qmk/qmk_firmware/pull/15282))
|
||||||
|
* Make (un)register code functions weak ([#15285](https://github.com/qmk/qmk_firmware/pull/15285))
|
||||||
|
* Split support for pointing devices. ([#15304](https://github.com/qmk/qmk_firmware/pull/15304))
|
||||||
|
* Added cancel_key_lock function ([#15321](https://github.com/qmk/qmk_firmware/pull/15321))
|
||||||
|
* Remove matrix_is_modified() and debounce_is_active() ([#15349](https://github.com/qmk/qmk_firmware/pull/15349))
|
||||||
|
* Change default USB Polling rate to 1kHz ([#15352](https://github.com/qmk/qmk_firmware/pull/15352))
|
||||||
|
* Implement MAGIC_TOGGLE_CONTROL_CAPSLOCK ([#15368](https://github.com/qmk/qmk_firmware/pull/15368))
|
||||||
|
* Tidy up existing i2c_master implementations ([#15376](https://github.com/qmk/qmk_firmware/pull/15376))
|
||||||
|
* Generalize Unicode defines ([#15409](https://github.com/qmk/qmk_firmware/pull/15409))
|
||||||
|
* Added external spi flash driver. ([#15419](https://github.com/qmk/qmk_firmware/pull/15419))
|
||||||
|
* Remove Deprecated USB Polling comment from vusb.c ([#15420](https://github.com/qmk/qmk_firmware/pull/15420))
|
||||||
|
* Expand rotational range for PMW3360 Optical Sensor ([#15431](https://github.com/qmk/qmk_firmware/pull/15431))
|
||||||
|
* ChibiOS SVN mirror script update ([#15435](https://github.com/qmk/qmk_firmware/pull/15435))
|
||||||
|
* Refactor `bootloader_jump()` implementations ([#15450](https://github.com/qmk/qmk_firmware/pull/15450))
|
||||||
|
* added missing audio_off_user() callback ([#15457](https://github.com/qmk/qmk_firmware/pull/15457))
|
||||||
|
* Migrate serial_uart usages to UART driver ([#15479](https://github.com/qmk/qmk_firmware/pull/15479))
|
||||||
|
* Migrate RN42 to UART driver and refactor ([#15492](https://github.com/qmk/qmk_firmware/pull/15492))
|
||||||
|
* pwm3360 driver cleanup and diff reduction to adns9800 ([#15559](https://github.com/qmk/qmk_firmware/pull/15559))
|
||||||
|
* Advanced deferred_exec for core-side code. ([#15579](https://github.com/qmk/qmk_firmware/pull/15579))
|
||||||
|
* Adjust tap_code16 to account for TAP_HOLD_CAPS_DELAY ([#15635](https://github.com/qmk/qmk_firmware/pull/15635))
|
||||||
|
* Slight tidy up of keyboard task loop ([#15725](https://github.com/qmk/qmk_firmware/pull/15725))
|
||||||
|
* Unify the key up/down behaviour of RGB keycodes ([#15730](https://github.com/qmk/qmk_firmware/pull/15730))
|
||||||
|
* Add PMW3389 optical sensor Support (Updated) ([#15740](https://github.com/qmk/qmk_firmware/pull/15740))
|
||||||
|
* ChibiOS: add support for HID Programmable Buttons ([#15787](https://github.com/qmk/qmk_firmware/pull/15787))
|
||||||
|
* ChibiOS: shorten USB disconnect state on boot to 50ms ([#15805](https://github.com/qmk/qmk_firmware/pull/15805))
|
||||||
|
* Add init function to clear previous matrix effect ([#15815](https://github.com/qmk/qmk_firmware/pull/15815))
|
||||||
|
* Optimize initialization of PMW3360 Sensor ([#15821](https://github.com/qmk/qmk_firmware/pull/15821))
|
||||||
|
* Add Pixel Flow RGB matrix effect ([#15829](https://github.com/qmk/qmk_firmware/pull/15829))
|
||||||
|
* PMW3389 Revert Firmware load during Initilization ([#15859](https://github.com/qmk/qmk_firmware/pull/15859))
|
||||||
|
* Combo `TAP_CODE_DELAY` and `clear_weak_mods` ([#15866](https://github.com/qmk/qmk_firmware/pull/15866))
|
||||||
|
* Relocate matrix_scan_quantum tasks ([#15882](https://github.com/qmk/qmk_firmware/pull/15882))
|
||||||
|
* Adjust mouse key defaults ([#15883](https://github.com/qmk/qmk_firmware/pull/15883))
|
||||||
|
* RGB Matrix: Reload from EEPROM ([#15923](https://github.com/qmk/qmk_firmware/pull/15923))
|
||||||
|
* Enable a default task throttle for split pointing. ([#15925](https://github.com/qmk/qmk_firmware/pull/15925))
|
||||||
|
* Move mcp23018 driver to core ([#15944](https://github.com/qmk/qmk_firmware/pull/15944))
|
||||||
|
* Relocate matrix_init_quantum content ([#15953](https://github.com/qmk/qmk_firmware/pull/15953))
|
||||||
|
* Align location of some host led logic ([#15954](https://github.com/qmk/qmk_firmware/pull/15954))
|
||||||
|
* Rename some Quantum keycodes ([#15968](https://github.com/qmk/qmk_firmware/pull/15968))
|
||||||
|
* Migrate more makefile utilities to builddefs sub-directory ([#16002](https://github.com/qmk/qmk_firmware/pull/16002))
|
||||||
|
* Various Makefile optimisations ([#16015](https://github.com/qmk/qmk_firmware/pull/16015))
|
||||||
|
* Add support for STM32L432, STM32L442. ([#16016](https://github.com/qmk/qmk_firmware/pull/16016))
|
||||||
|
* EEPROM refactor: remove `eeprom_teensy.c` by default, use transient instead ([#16020](https://github.com/qmk/qmk_firmware/pull/16020))
|
||||||
|
* Deprecate Split Transaction status field ([#16023](https://github.com/qmk/qmk_firmware/pull/16023))
|
||||||
|
* Rip out old macro and action_function system ([#16025](https://github.com/qmk/qmk_firmware/pull/16025))
|
||||||
|
* Add a script that simplifies running commands under docker. ([#16028](https://github.com/qmk/qmk_firmware/pull/16028))
|
||||||
|
* Add support for Q-series on the ckled2001 LED driver ([#16051](https://github.com/qmk/qmk_firmware/pull/16051))
|
||||||
|
* Remove unused suspend_idle ([#16063](https://github.com/qmk/qmk_firmware/pull/16063))
|
||||||
|
* Initial migration of suspend callbacks ([#16067](https://github.com/qmk/qmk_firmware/pull/16067))
|
||||||
|
* Add layout change callbacks to VIA ([#16087](https://github.com/qmk/qmk_firmware/pull/16087))
|
||||||
|
* Rename `AdafruitBLE` to `BluefruitLE` ([#16127](https://github.com/qmk/qmk_firmware/pull/16127))
|
||||||
|
* Update outputselect to use platform connected state API ([#16185](https://github.com/qmk/qmk_firmware/pull/16185))
|
||||||
|
* Remove default pointing device driver. ([#16190](https://github.com/qmk/qmk_firmware/pull/16190))
|
||||||
|
* Add SN74x138 demultiplexer driver ([#16217](https://github.com/qmk/qmk_firmware/pull/16217))
|
||||||
|
* Standardise error output. ([#16220](https://github.com/qmk/qmk_firmware/pull/16220))
|
||||||
|
* Followup to #16220, more test error output. ([#16221](https://github.com/qmk/qmk_firmware/pull/16221))
|
||||||
|
* Misc size regression script improvements. ([#16268](https://github.com/qmk/qmk_firmware/pull/16268))
|
||||||
|
* Align existing pca9555 driver to better match mcp23018 API ([#16277](https://github.com/qmk/qmk_firmware/pull/16277))
|
||||||
|
* Size checks print out target firmware file instead ([#16290](https://github.com/qmk/qmk_firmware/pull/16290))
|
||||||
|
|
||||||
|
CLI:
|
||||||
|
* `develop` changelog generator: use the PR title instead ([#15537](https://github.com/qmk/qmk_firmware/pull/15537))
|
||||||
|
* `develop` changelog generator: skip code formatting in listing ([#16215](https://github.com/qmk/qmk_firmware/pull/16215))
|
||||||
|
|
||||||
|
Keyboards:
|
||||||
|
* Durgod: Increase scan rate by using wait_us timer ([#14091](https://github.com/qmk/qmk_firmware/pull/14091))
|
||||||
|
* Add another GMMK Pro ANSI Keymap with custom RGB. ([#14243](https://github.com/qmk/qmk_firmware/pull/14243))
|
||||||
|
* Parse USB device version BCD ([#14580](https://github.com/qmk/qmk_firmware/pull/14580))
|
||||||
|
* Add vitoni keymap for GMMK Pro (ISO) ([#15006](https://github.com/qmk/qmk_firmware/pull/15006))
|
||||||
|
* Move bm65hsrgb_iso and bm68hsrgb to rev1/ to prepare for updates to the boards ([#15132](https://github.com/qmk/qmk_firmware/pull/15132))
|
||||||
|
* Convert ergoinu to SPLIT_KEYBOARD ([#15305](https://github.com/qmk/qmk_firmware/pull/15305))
|
||||||
|
* Convert not_so_minidox to SPLIT_KEYBOARD ([#15306](https://github.com/qmk/qmk_firmware/pull/15306))
|
||||||
|
* Added new handwired keyboard Wakizashi 40 ([#15336](https://github.com/qmk/qmk_firmware/pull/15336))
|
||||||
|
* Convert ai03/orbit to SPLIT_KEYBOARD ([#15340](https://github.com/qmk/qmk_firmware/pull/15340))
|
||||||
|
* Remove manual enable of LTO within user keymaps ([#15378](https://github.com/qmk/qmk_firmware/pull/15378))
|
||||||
|
* Move to organization folder ([#15481](https://github.com/qmk/qmk_firmware/pull/15481))
|
||||||
|
* Convert some more boards to Matrix Lite ([#15489](https://github.com/qmk/qmk_firmware/pull/15489))
|
||||||
|
* Organize Reviung boards into a directory ([#15636](https://github.com/qmk/qmk_firmware/pull/15636))
|
||||||
|
* move winry25tc to winry/ ([#15637](https://github.com/qmk/qmk_firmware/pull/15637))
|
||||||
|
* Rename ymdk_np21 to np21 + move to ymdk vendor folder ([#15641](https://github.com/qmk/qmk_firmware/pull/15641))
|
||||||
|
* move ymd96 to ymdk vendor folder ([#15643](https://github.com/qmk/qmk_firmware/pull/15643))
|
||||||
|
* move ymd75 to ymdk vendor folder ([#15645](https://github.com/qmk/qmk_firmware/pull/15645))
|
||||||
|
* move yd60mq to ymdk vendor folder ([#15647](https://github.com/qmk/qmk_firmware/pull/15647))
|
||||||
|
* rename idobo to idobao/id75, move to vendor folder ([#15661](https://github.com/qmk/qmk_firmware/pull/15661))
|
||||||
|
* move ID67 to IDOBAO vendor folder ([#15662](https://github.com/qmk/qmk_firmware/pull/15662))
|
||||||
|
* move ID80 to IDOBAO vendor folder ([#15665](https://github.com/qmk/qmk_firmware/pull/15665))
|
||||||
|
* move ID87 to IDOBAO vendor folder ([#15667](https://github.com/qmk/qmk_firmware/pull/15667))
|
||||||
|
* move montex to IDOBAO vendor folder ([#15668](https://github.com/qmk/qmk_firmware/pull/15668))
|
||||||
|
* move @yangdigi 's keyboards to a YDKB folder ([#15681](https://github.com/qmk/qmk_firmware/pull/15681))
|
||||||
|
* move @kkatano 's keyboards to kkatano user folder ([#15684](https://github.com/qmk/qmk_firmware/pull/15684))
|
||||||
|
* Sol 3 Keyboard from RGBKB ([#15687](https://github.com/qmk/qmk_firmware/pull/15687))
|
||||||
|
* move cu24, cu75, cu80/v1 into capsunlocked folder ([#15758](https://github.com/qmk/qmk_firmware/pull/15758))
|
||||||
|
* move mechkeys keyboards into the mechkeys/ vendor folder ([#15760](https://github.com/qmk/qmk_firmware/pull/15760))
|
||||||
|
* move @lyso1 's boards into lyso1/ ([#15767](https://github.com/qmk/qmk_firmware/pull/15767))
|
||||||
|
* move prototypist boards into vendor folder ([#15780](https://github.com/qmk/qmk_firmware/pull/15780))
|
||||||
|
* move @yiancar 's boards into yiancardesigns/ ([#15781](https://github.com/qmk/qmk_firmware/pull/15781))
|
||||||
|
* move novelkeys keyboards to vendor folder ([#15783](https://github.com/qmk/qmk_firmware/pull/15783))
|
||||||
|
* move @weirdo-f 's keyboards into weirdo/ ([#15785](https://github.com/qmk/qmk_firmware/pull/15785))
|
||||||
|
* move @marksard 's boards to marksard/ ([#15786](https://github.com/qmk/qmk_firmware/pull/15786))
|
||||||
|
* move input club keyboards into vendor folder ([#15788](https://github.com/qmk/qmk_firmware/pull/15788))
|
||||||
|
* move @monksoffunk 's boards into 25keys/ ([#15789](https://github.com/qmk/qmk_firmware/pull/15789))
|
||||||
|
* move @Salicylic-acid3 's keyboards to salicylic-acid3/ ([#15791](https://github.com/qmk/qmk_firmware/pull/15791))
|
||||||
|
* move @rainkeebs 's keyboards to rainkeebs/ ([#15797](https://github.com/qmk/qmk_firmware/pull/15797))
|
||||||
|
* move standaside into edi/ ([#15798](https://github.com/qmk/qmk_firmware/pull/15798))
|
||||||
|
* move @obosob 's boards into obosob/ ([#15799](https://github.com/qmk/qmk_firmware/pull/15799))
|
||||||
|
* move @nacly 's boards to nacly/ ([#15801](https://github.com/qmk/qmk_firmware/pull/15801))
|
||||||
|
* move @kakunpc 's keebs into kakunpc/ ([#15814](https://github.com/qmk/qmk_firmware/pull/15814))
|
||||||
|
* move @qpocket 's keyboards to qpocket/ ([#15827](https://github.com/qmk/qmk_firmware/pull/15827))
|
||||||
|
* BDN9 keymap ([#15924](https://github.com/qmk/qmk_firmware/pull/15924))
|
||||||
|
* move @matthewdias 's keebs into matthewdias/ ([#15991](https://github.com/qmk/qmk_firmware/pull/15991))
|
||||||
|
* move id80 and id75 to v1 to accommodate for id75 v2 and id80 v3 ([#15992](https://github.com/qmk/qmk_firmware/pull/15992))
|
||||||
|
* Remove `action_function()` from LFKeyboards boards ([#15993](https://github.com/qmk/qmk_firmware/pull/15993))
|
||||||
|
* move @latincompass (aka @18438880 , @haierwangwei2005)'s boards to /latincompass ([#16039](https://github.com/qmk/qmk_firmware/pull/16039))
|
||||||
|
* move g heavy industry boards into /gboards ([#16040](https://github.com/qmk/qmk_firmware/pull/16040))
|
||||||
|
* move @drhigsby 's boards into /drhigsby ([#16041](https://github.com/qmk/qmk_firmware/pull/16041))
|
||||||
|
* More keyboard rules.mk cleanups ([#16044](https://github.com/qmk/qmk_firmware/pull/16044))
|
||||||
|
* move @That-Canadian 's boards into /maple_computing ([#16050](https://github.com/qmk/qmk_firmware/pull/16050))
|
||||||
|
* move @takai 's keyboards into /recompile_keys ([#16053](https://github.com/qmk/qmk_firmware/pull/16053))
|
||||||
|
* move @satt99 's comet46 to satt/ ([#16059](https://github.com/qmk/qmk_firmware/pull/16059))
|
||||||
|
* move @ka2hiro 's boards into /kagizaraya ([#16070](https://github.com/qmk/qmk_firmware/pull/16070))
|
||||||
|
* move @GlenPickle 's chimera* boards into a folder ([#16072](https://github.com/qmk/qmk_firmware/pull/16072))
|
||||||
|
* move @yynmt 's boards into /yynmt ([#16075](https://github.com/qmk/qmk_firmware/pull/16075))
|
||||||
|
* move @Biacco42 's keebs into /biacco42 ([#16080](https://github.com/qmk/qmk_firmware/pull/16080))
|
||||||
|
* move unikeyboard boards to /unikeyboard ([#16081](https://github.com/qmk/qmk_firmware/pull/16081))
|
||||||
|
* move four_banger to bpiphany ([#16082](https://github.com/qmk/qmk_firmware/pull/16082))
|
||||||
|
* move @takashiski 's keebs into /takashiski ([#16089](https://github.com/qmk/qmk_firmware/pull/16089))
|
||||||
|
* move hid_liber to /bpiphany ([#16091](https://github.com/qmk/qmk_firmware/pull/16091))
|
||||||
|
* move spaceholdings boards into /spaceholdings ([#16096](https://github.com/qmk/qmk_firmware/pull/16096))
|
||||||
|
* move @7-rate 's keebs to /rate ([#16099](https://github.com/qmk/qmk_firmware/pull/16099))
|
||||||
|
* move @npspears 's boards into /checkerboards ([#16100](https://github.com/qmk/qmk_firmware/pull/16100))
|
||||||
|
* move @vuhopkep 's keebs into /hnahkb ([#16102](https://github.com/qmk/qmk_firmware/pull/16102))
|
||||||
|
* move @ibnuda 's keebs into /ibnuda ([#16108](https://github.com/qmk/qmk_firmware/pull/16108))
|
||||||
|
* move @tominabox1 's keebs into /tominabox1 ([#16109](https://github.com/qmk/qmk_firmware/pull/16109))
|
||||||
|
* move niu_mini to /kbdfans ([#16112](https://github.com/qmk/qmk_firmware/pull/16112))
|
||||||
|
* move woodkeys.click keyboards to /woodkeys ([#16113](https://github.com/qmk/qmk_firmware/pull/16113))
|
||||||
|
* move @omkbd 's boards to /omkbd ([#16116](https://github.com/qmk/qmk_firmware/pull/16116))
|
||||||
|
* Overhaul Tractyl Manuform ([#16134](https://github.com/qmk/qmk_firmware/pull/16134))
|
||||||
|
* Reduce firmware size for dztech/dz60rgb_wkl/v2_1:via ([#16254](https://github.com/qmk/qmk_firmware/pull/16254))
|
||||||
|
|
||||||
|
Keyboard fixes:
|
||||||
|
* Fix build failure for UT47 ([#15483](https://github.com/qmk/qmk_firmware/pull/15483))
|
||||||
|
* Update grs_70ec to use newer custom matrix ([#15609](https://github.com/qmk/qmk_firmware/pull/15609))
|
||||||
|
* fix compiler issue with Tractyl Manuform 4x6 ([#15646](https://github.com/qmk/qmk_firmware/pull/15646))
|
||||||
|
* Fix CI. ([#15828](https://github.com/qmk/qmk_firmware/pull/15828))
|
||||||
|
* Yet another bad `DEFAULT_FOLDER` fix. ([#15904](https://github.com/qmk/qmk_firmware/pull/15904))
|
||||||
|
* Fix build failures for `mschwingen/modelm` ([#15987](https://github.com/qmk/qmk_firmware/pull/15987))
|
||||||
|
* `rocketboard_16`: Fix mismatched LUT sizes ([#15997](https://github.com/qmk/qmk_firmware/pull/15997))
|
||||||
|
* Fix erroneous SRC for Clueboard 66 hotswap ([#16007](https://github.com/qmk/qmk_firmware/pull/16007))
|
||||||
|
* Fix handwired/ms_sculpt_mobile default keymap ([#16032](https://github.com/qmk/qmk_firmware/pull/16032))
|
||||||
|
* Re-org Hillside folders as new model prep. Fix default keymap. ([#16128](https://github.com/qmk/qmk_firmware/pull/16128))
|
||||||
|
* Fix up default folder locations. Again. ([#16135](https://github.com/qmk/qmk_firmware/pull/16135))
|
||||||
|
* Sol3 rgb fix ([#16157](https://github.com/qmk/qmk_firmware/pull/16157))
|
||||||
|
* Add missing `BOOTLOADER` for a handful of boards ([#16225](https://github.com/qmk/qmk_firmware/pull/16225))
|
||||||
|
* Remove half implemented micronucleus bootloader support ([#16252](https://github.com/qmk/qmk_firmware/pull/16252))
|
||||||
|
* Fixup bootloaders. ([#16256](https://github.com/qmk/qmk_firmware/pull/16256))
|
||||||
|
* Fix idobao/id80/v3 compilation errors ([#16280](https://github.com/qmk/qmk_firmware/pull/16280))
|
||||||
|
* Remove parent-relative paths from keyboards. ([#16282](https://github.com/qmk/qmk_firmware/pull/16282))
|
||||||
|
* Bodge for helix build failures ([#16376](https://github.com/qmk/qmk_firmware/pull/16376))
|
||||||
|
|
||||||
|
Others:
|
||||||
|
* Add a clarification to an error message ([#15207](https://github.com/qmk/qmk_firmware/pull/15207))
|
||||||
|
* Clang-format tweaks ([#15906](https://github.com/qmk/qmk_firmware/pull/15906))
|
||||||
|
* Add example implementations for compatible MCUs list ([#15935](https://github.com/qmk/qmk_firmware/pull/15935))
|
||||||
|
* Add version.h to gitignore ([#16222](https://github.com/qmk/qmk_firmware/pull/16222))
|
||||||
|
* Update keyboard mapping for all moved boards this cycle ([#16312](https://github.com/qmk/qmk_firmware/pull/16312))
|
||||||
|
* Align docs to new-keyboard behaviour ([#16357](https://github.com/qmk/qmk_firmware/pull/16357))
|
||||||
|
* Align new-keyboard with recent schema updates ([#16378](https://github.com/qmk/qmk_firmware/pull/16378))
|
||||||
|
|
||||||
|
Bugs:
|
||||||
|
* Fixes potential wpm sampling overflow, along with code comment fixes ([#15277](https://github.com/qmk/qmk_firmware/pull/15277))
|
||||||
|
* Add missing define for unicode common ([#15416](https://github.com/qmk/qmk_firmware/pull/15416))
|
||||||
|
* Fix for SPI write timing in PMW3360 driver ([#15519](https://github.com/qmk/qmk_firmware/pull/15519))
|
||||||
|
* Documentation Typo fix ([#15538](https://github.com/qmk/qmk_firmware/pull/15538))
|
||||||
|
* fix a typo ([#15557](https://github.com/qmk/qmk_firmware/pull/15557))
|
||||||
|
* Fix avr serial compile ([#15589](https://github.com/qmk/qmk_firmware/pull/15589))
|
||||||
|
* More AVR GPIO compilation fixes. ([#15592](https://github.com/qmk/qmk_firmware/pull/15592))
|
||||||
|
* Fix bug and code regression for Split Common ([#15603](https://github.com/qmk/qmk_firmware/pull/15603))
|
||||||
|
* Include missing string.h include in split ([#15606](https://github.com/qmk/qmk_firmware/pull/15606))
|
||||||
|
* Fixes for bootloader refactor build failures ([#15638](https://github.com/qmk/qmk_firmware/pull/15638))
|
||||||
|
* Update pmw3360 driver after reading the datasheet top to bottom. Fix some outdated refs. ([#15682](https://github.com/qmk/qmk_firmware/pull/15682))
|
||||||
|
* Fix split pointing for analog joystick ([#15691](https://github.com/qmk/qmk_firmware/pull/15691))
|
||||||
|
* Fix broken bootloader builds in develop. ([#15880](https://github.com/qmk/qmk_firmware/pull/15880))
|
||||||
|
* Fix optical sensor firmware upload ([#15919](https://github.com/qmk/qmk_firmware/pull/15919))
|
||||||
|
* Pass in the keyrecord_t of the dual-role/tapping key when calling per-key tap hold functions ([#15938](https://github.com/qmk/qmk_firmware/pull/15938))
|
||||||
|
* fixed typo in orange HSV colors decalartion ([#15976](https://github.com/qmk/qmk_firmware/pull/15976))
|
||||||
|
* Fix hack for chibiOS reset name ([#15984](https://github.com/qmk/qmk_firmware/pull/15984))
|
||||||
|
* Fix right side ws2812 leds having two indices ([#15985](https://github.com/qmk/qmk_firmware/pull/15985))
|
||||||
|
* Workaround in Makefile for recursive rule matching ([#15988](https://github.com/qmk/qmk_firmware/pull/15988))
|
||||||
|
* Fix BACKLIGHT_CAPS_LOCK warning ([#15999](https://github.com/qmk/qmk_firmware/pull/15999))
|
||||||
|
* Fix compilation issues for led indicators ([#16001](https://github.com/qmk/qmk_firmware/pull/16001))
|
||||||
|
* ChibiOS timer fixes ([#16017](https://github.com/qmk/qmk_firmware/pull/16017))
|
||||||
|
* Fix bootloader_jump for certain CTRL boards ([#16026](https://github.com/qmk/qmk_firmware/pull/16026))
|
||||||
|
* Fix up issue with PROGMEM and hand_swap_config ([#16027](https://github.com/qmk/qmk_firmware/pull/16027))
|
||||||
|
* Don't make EEPROM size assumptions with dynamic keymaps. ([#16054](https://github.com/qmk/qmk_firmware/pull/16054))
|
||||||
|
* fix missed .noci in reviung move ([#16107](https://github.com/qmk/qmk_firmware/pull/16107))
|
||||||
|
* Fix issues with Python Tests ([#16162](https://github.com/qmk/qmk_firmware/pull/16162))
|
||||||
|
* Fixup multibuild filegen ([#16166](https://github.com/qmk/qmk_firmware/pull/16166))
|
||||||
|
* Remove old .gitignore entry. Add more macOS junk exclusions. ([#16167](https://github.com/qmk/qmk_firmware/pull/16167))
|
||||||
|
* Fixup builds so that teensy EEPROM knows which MCU it's targeting. ([#16168](https://github.com/qmk/qmk_firmware/pull/16168))
|
||||||
|
* Create a build error if no bootloader is specified. ([#16181](https://github.com/qmk/qmk_firmware/pull/16181))
|
||||||
|
* Ensure `version.h` is recreated each build. ([#16188](https://github.com/qmk/qmk_firmware/pull/16188))
|
||||||
|
* Add `custom` to list of valid bootloader types in info.json ([#16228](https://github.com/qmk/qmk_firmware/pull/16228))
|
||||||
|
* Fix `layer_state` restoration at end of dynamic macro feature #16208 ([#16230](https://github.com/qmk/qmk_firmware/pull/16230))
|
||||||
|
* Minor additions #12795 ([#16276](https://github.com/qmk/qmk_firmware/pull/16276))
|
||||||
|
* Various fixes for matrix _RIGHT handling ([#16292](https://github.com/qmk/qmk_firmware/pull/16292))
|
||||||
|
* Fix slashes in build_full_test.mk ([#16300](https://github.com/qmk/qmk_firmware/pull/16300))
|
||||||
|
* ps2/avr: use the correct file name ([#16316](https://github.com/qmk/qmk_firmware/pull/16316))
|
||||||
|
* Fix compilation of ChibiOS UART driver ([#16348](https://github.com/qmk/qmk_firmware/pull/16348))
|
||||||
|
* Various fixes for new-keyboard ([#16358](https://github.com/qmk/qmk_firmware/pull/16358))
|
||||||
|
* Allow NO_PIN within data driven configuration ([#16359](https://github.com/qmk/qmk_firmware/pull/16359))
|
|
@ -37,7 +37,6 @@
|
||||||
* Guides
|
* Guides
|
||||||
* [Customizing Functionality](custom_quantum_functions.md)
|
* [Customizing Functionality](custom_quantum_functions.md)
|
||||||
* [Driver Installation with Zadig](driver_installation_zadig.md)
|
* [Driver Installation with Zadig](driver_installation_zadig.md)
|
||||||
* [Easy Maker for One Offs](easy_maker.md)
|
|
||||||
* [Keymap Overview](keymap.md)
|
* [Keymap Overview](keymap.md)
|
||||||
* Development Environments
|
* Development Environments
|
||||||
* [Docker Guide](getting_started_docker.md)
|
* [Docker Guide](getting_started_docker.md)
|
||||||
|
@ -53,9 +52,6 @@
|
||||||
* [Your Fork](newbs_git_using_your_master_branch.md)
|
* [Your Fork](newbs_git_using_your_master_branch.md)
|
||||||
* [Merge Conflicts](newbs_git_resolving_merge_conflicts.md)
|
* [Merge Conflicts](newbs_git_resolving_merge_conflicts.md)
|
||||||
* [Fixing Your Branch](newbs_git_resynchronize_a_branch.md)
|
* [Fixing Your Branch](newbs_git_resynchronize_a_branch.md)
|
||||||
* Keyboard Building
|
|
||||||
* [Hand Wiring Guide](hand_wire.md)
|
|
||||||
* [ISP Flashing Guide](isp_flashing_guide.md)
|
|
||||||
|
|
||||||
* Simple Keycodes
|
* Simple Keycodes
|
||||||
* [Full List](keycodes.md)
|
* [Full List](keycodes.md)
|
||||||
|
@ -124,17 +120,22 @@
|
||||||
* [Thermal Printer](feature_thermal_printer.md)
|
* [Thermal Printer](feature_thermal_printer.md)
|
||||||
* [Velocikey](feature_velocikey.md)
|
* [Velocikey](feature_velocikey.md)
|
||||||
|
|
||||||
|
* Keyboard Building
|
||||||
|
* [Easy Maker for One Offs](easy_maker.md)
|
||||||
|
* [Porting Keyboards](porting_your_keyboard_to_qmk.md)
|
||||||
|
* [Hand Wiring Guide](hand_wire.md)
|
||||||
|
* [ISP Flashing Guide](isp_flashing_guide.md)
|
||||||
|
|
||||||
* Developing QMK
|
* Developing QMK
|
||||||
* [PR Checklist](pr_checklist.md)
|
* [PR Checklist](pr_checklist.md)
|
||||||
* 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/20211127.md "QMK v0.15.0 - 2021 Nov 27")
|
* [Most Recent ChangeLog](ChangeLog/20220226.md "QMK v0.16.0 - 2022 Feb 26")
|
||||||
* [Past Breaking Changes](breaking_changes_history.md)
|
* [Past Breaking Changes](breaking_changes_history.md)
|
||||||
|
|
||||||
* C Development
|
* C Development
|
||||||
* [ARM Debugging Guide](arm_debugging.md)
|
* [ARM Debugging Guide](arm_debugging.md)
|
||||||
* [AVR Processors](hardware_avr.md)
|
|
||||||
* [Coding Conventions](coding_conventions_c.md)
|
* [Coding Conventions](coding_conventions_c.md)
|
||||||
* [Compatible Microcontrollers](compatible_microcontrollers.md)
|
* [Compatible Microcontrollers](compatible_microcontrollers.md)
|
||||||
* [Drivers](hardware_drivers.md)
|
* [Drivers](hardware_drivers.md)
|
||||||
|
|
|
@ -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 Feb 26](ChangeLog/20220226.md)
|
||||||
* [2021 Nov 27](ChangeLog/20211127.md)
|
* [2021 Nov 27](ChangeLog/20211127.md)
|
||||||
* [2021 Aug 28](ChangeLog/20210828.md)
|
* [2021 Aug 28](ChangeLog/20210828.md)
|
||||||
* [2021 May 29](ChangeLog/20210529.md)
|
* [2021 May 29](ChangeLog/20210529.md)
|
||||||
|
@ -20,17 +21,17 @@ 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 February 26, 2022.
|
The next Breaking Change is scheduled for May 28, 2022.
|
||||||
|
|
||||||
### Important Dates
|
### Important Dates
|
||||||
|
|
||||||
* [x] 2021 Nov 27 - `develop` is tagged with a new release version. Each push to `master` is subsequently merged to `develop` by GitHub actions.
|
* [x] 2022 Feb 26 - `develop` is tagged with a new release version. Each push to `master` is subsequently merged to `develop` by GitHub actions.
|
||||||
* [ ] 2022 Jan 31 - `develop` closed to new PR's.
|
* [ ] 2022 Apr 31 - `develop` closed to new PR's.
|
||||||
* [ ] 2022 Jan 31 - Call for testers.
|
* [ ] 2022 Apr 31 - Call for testers.
|
||||||
* [ ] 2022 Feb 12 - Last day for merges -- after this point `develop` is locked for testing and accepts only bugfixes
|
* [ ] 2022 May 14 - Last day for merges -- after this point `develop` is locked for testing and accepts only bugfixes
|
||||||
* [ ] 2022 Feb 24 - `master` is locked, no PR's merged.
|
* [ ] 2022 May 26 - `master` is locked, no PR's merged.
|
||||||
* [ ] 2022 Feb 26 - Merge `develop` to `master`.
|
* [ ] 2022 May 28 - Merge `develop` to `master`.
|
||||||
* [ ] 2022 Feb 26 - `master` is unlocked. PR's can be merged again.
|
* [ ] 2022 May 28 - `master` is unlocked. PR's can be merged again.
|
||||||
|
|
||||||
## What changes will be included?
|
## What changes will be included?
|
||||||
|
|
||||||
|
|
|
@ -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 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
|
||||||
* [2021 Aug 28](ChangeLog/20210828.md) - version 0.14.0
|
* [2021 Aug 28](ChangeLog/20210828.md) - version 0.14.0
|
||||||
* [2021 May 29](ChangeLog/20210529.md) - version 0.13.0
|
* [2021 May 29](ChangeLog/20210529.md) - version 0.13.0
|
||||||
|
|
|
@ -310,7 +310,7 @@ Any arguments that are not provided will prompt for input. If `-u` is not passed
|
||||||
**Usage**:
|
**Usage**:
|
||||||
|
|
||||||
```
|
```
|
||||||
qmk new-keyboard [-kb KEYBOARD] [-t {avr,ps2avrgb}] -u USERNAME
|
qmk new-keyboard [-kb KEYBOARD] [-t {atmega32u4,STM32F303,etc}] [-l {60_ansi,75_iso,etc}] -u USERNAME
|
||||||
```
|
```
|
||||||
|
|
||||||
## `qmk new-keymap`
|
## `qmk new-keymap`
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Compatible Microcontrollers
|
# Compatible Microcontrollers
|
||||||
|
|
||||||
QMK runs on any USB-capable AVR or ARM microcontroller with enough flash space - generally 32kB or more, though it will *just* squeeze into 16kB with most features disabled.
|
QMK runs on any USB-capable AVR or ARM microcontroller with enough flash space - generally 32kB+ for AVR, and 64kB+ for ARM. With significant disabling of features, QMK may *just* squeeze into 16kB AVR MCUs.
|
||||||
|
|
||||||
## Atmel AVR
|
## Atmel AVR
|
||||||
|
|
||||||
|
@ -8,7 +8,11 @@ The following use [LUFA](https://www.fourwalledcubicle.com/LUFA.php) as the USB
|
||||||
|
|
||||||
* [ATmega16U2](https://www.microchip.com/wwwproducts/en/ATmega16U2) / [ATmega32U2](https://www.microchip.com/wwwproducts/en/ATmega32U2)
|
* [ATmega16U2](https://www.microchip.com/wwwproducts/en/ATmega16U2) / [ATmega32U2](https://www.microchip.com/wwwproducts/en/ATmega32U2)
|
||||||
* [ATmega16U4](https://www.microchip.com/wwwproducts/en/ATmega16U4) / [ATmega32U4](https://www.microchip.com/wwwproducts/en/ATmega32U4)
|
* [ATmega16U4](https://www.microchip.com/wwwproducts/en/ATmega16U4) / [ATmega32U4](https://www.microchip.com/wwwproducts/en/ATmega32U4)
|
||||||
|
* SparkFun Pro Micro (and clones)
|
||||||
|
* PJRC Teensy 2.0
|
||||||
|
* Adafruit Feather 32U4
|
||||||
* [AT90USB64](https://www.microchip.com/wwwproducts/en/AT90USB646) / [AT90USB128](https://www.microchip.com/wwwproducts/en/AT90USB1286)
|
* [AT90USB64](https://www.microchip.com/wwwproducts/en/AT90USB646) / [AT90USB128](https://www.microchip.com/wwwproducts/en/AT90USB1286)
|
||||||
|
* PJRC Teensy++ 2.0
|
||||||
* [AT90USB162](https://www.microchip.com/wwwproducts/en/AT90USB162)
|
* [AT90USB162](https://www.microchip.com/wwwproducts/en/AT90USB162)
|
||||||
|
|
||||||
Certain MCUs which do not have native USB will use [V-USB](https://www.obdev.at/products/vusb/index.html) instead:
|
Certain MCUs which do not have native USB will use [V-USB](https://www.obdev.at/products/vusb/index.html) instead:
|
||||||
|
@ -25,17 +29,23 @@ You can also use any ARM chip with USB that [ChibiOS](https://www.chibios.org) s
|
||||||
|
|
||||||
* [STM32F0x2](https://www.st.com/en/microcontrollers-microprocessors/stm32f0x2.html)
|
* [STM32F0x2](https://www.st.com/en/microcontrollers-microprocessors/stm32f0x2.html)
|
||||||
* [STM32F103](https://www.st.com/en/microcontrollers-microprocessors/stm32f103.html)
|
* [STM32F103](https://www.st.com/en/microcontrollers-microprocessors/stm32f103.html)
|
||||||
|
* Bluepill (with STM32duino bootloader)
|
||||||
* [STM32F303](https://www.st.com/en/microcontrollers-microprocessors/stm32f303.html)
|
* [STM32F303](https://www.st.com/en/microcontrollers-microprocessors/stm32f303.html)
|
||||||
|
* QMK Proton-C
|
||||||
* [STM32F401](https://www.st.com/en/microcontrollers-microprocessors/stm32f401.html)
|
* [STM32F401](https://www.st.com/en/microcontrollers-microprocessors/stm32f401.html)
|
||||||
|
* WeAct Blackpill
|
||||||
* [STM32F405](https://www.st.com/en/microcontrollers-microprocessors/stm32f405-415.html)
|
* [STM32F405](https://www.st.com/en/microcontrollers-microprocessors/stm32f405-415.html)
|
||||||
* [STM32F407](https://www.st.com/en/microcontrollers-microprocessors/stm32f407-417.html)
|
* [STM32F407](https://www.st.com/en/microcontrollers-microprocessors/stm32f407-417.html)
|
||||||
* [STM32F411](https://www.st.com/en/microcontrollers-microprocessors/stm32f411.html)
|
* [STM32F411](https://www.st.com/en/microcontrollers-microprocessors/stm32f411.html)
|
||||||
|
* WeAct Blackpill
|
||||||
* [STM32F446](https://www.st.com/en/microcontrollers-microprocessors/stm32f446.html)
|
* [STM32F446](https://www.st.com/en/microcontrollers-microprocessors/stm32f446.html)
|
||||||
* [STM32G431](https://www.st.com/en/microcontrollers-microprocessors/stm32g4x1.html)
|
* [STM32G431](https://www.st.com/en/microcontrollers-microprocessors/stm32g4x1.html)
|
||||||
* [STM32G474](https://www.st.com/en/microcontrollers-microprocessors/stm32g4x4.html)
|
* [STM32G474](https://www.st.com/en/microcontrollers-microprocessors/stm32g4x4.html)
|
||||||
* [STM32L412](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html)
|
* [STM32L412](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html)
|
||||||
* [STM32L422](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html)
|
* [STM32L422](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html)
|
||||||
|
* [STM32L432](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html)
|
||||||
* [STM32L433](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x3.html)
|
* [STM32L433](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x3.html)
|
||||||
|
* [STM32L442](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html)
|
||||||
* [STM32L443](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x3.html)
|
* [STM32L443](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x3.html)
|
||||||
|
|
||||||
### WestBerryTech (WB32)
|
### WestBerryTech (WB32)
|
||||||
|
@ -45,13 +55,16 @@ You can also use any ARM chip with USB that [ChibiOS](https://www.chibios.org) s
|
||||||
### NXP (Kinetis)
|
### NXP (Kinetis)
|
||||||
|
|
||||||
* [MKL26Z64](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/kl-series-cortex-m0-plus/kinetis-kl2x-72-96-mhz-usb-ultra-low-power-microcontrollers-mcus-based-on-arm-cortex-m0-plus-core:KL2x)
|
* [MKL26Z64](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/kl-series-cortex-m0-plus/kinetis-kl2x-72-96-mhz-usb-ultra-low-power-microcontrollers-mcus-based-on-arm-cortex-m0-plus-core:KL2x)
|
||||||
|
* PJRC Teensy LC
|
||||||
* [MK20DX128](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k2x-usb/kinetis-k20-50-mhz-full-speed-usb-mixed-signal-integration-microcontrollers-based-on-arm-cortex-m4-core:K20_50)
|
* [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
|
||||||
* [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
|
||||||
|
|
||||||
## 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).
|
There is limited support for one of Atmel's ATSAM microcontrollers, that being the [ATSAMD51J18A](https://www.microchip.com/wwwproducts/en/ATSAMD51J18A) used by the [Massdrop keyboards](https://github.com/qmk/qmk_firmware/tree/master/keyboards/massdrop). However, it is not recommended to design a board with this microcontroller as the support is quite specialized to Massdrop hardware.
|
||||||
|
|
||||||
## RISC-V
|
## RISC-V
|
||||||
|
|
||||||
|
|
|
@ -126,10 +126,6 @@ If you define these options you will disable the associated feature, which can s
|
||||||
* disable tap dance and other tapping features
|
* disable tap dance and other tapping features
|
||||||
* `#define NO_ACTION_ONESHOT`
|
* `#define NO_ACTION_ONESHOT`
|
||||||
* disable one-shot modifiers
|
* disable one-shot modifiers
|
||||||
* `#define NO_ACTION_MACRO`
|
|
||||||
* disable old-style macro handling using `MACRO()`, `action_get_macro()` _(deprecated)_
|
|
||||||
* `#define NO_ACTION_FUNCTION`
|
|
||||||
* disable old-style function handling using `fn_actions`, `action_function()` _(deprecated)_
|
|
||||||
|
|
||||||
## Features That Can Be Enabled
|
## Features That Can Be Enabled
|
||||||
|
|
||||||
|
@ -385,7 +381,6 @@ This is a [make](https://www.gnu.org/software/make/manual/make.html) file that i
|
||||||
* A list of [layouts](feature_layouts.md) this keyboard supports.
|
* A list of [layouts](feature_layouts.md) this keyboard supports.
|
||||||
* `LTO_ENABLE`
|
* `LTO_ENABLE`
|
||||||
* Enables Link Time Optimization (LTO) when compiling the keyboard. This makes the process take longer, but it can significantly reduce the compiled size (and since the firmware is small, the added time is not noticeable).
|
* Enables Link Time Optimization (LTO) when compiling the keyboard. This makes the process take longer, but it can significantly reduce the compiled size (and since the firmware is small, the added time is not noticeable).
|
||||||
However, this will automatically disable the legacy TMK Macros and Functions features, as these break when LTO is enabled. It does this by automatically defining `NO_ACTION_MACRO` and `NO_ACTION_FUNCTION`. (Note: This does not affect QMK [Macros](feature_macros.md) and [Layers](feature_layers.md).)
|
|
||||||
|
|
||||||
## AVR MCU Options
|
## AVR MCU Options
|
||||||
* `MCU = atmega32u4`
|
* `MCU = atmega32u4`
|
||||||
|
@ -436,8 +431,8 @@ Use these to enable or disable building certain features. The more you have enab
|
||||||
* MIDI controls
|
* MIDI controls
|
||||||
* `UNICODE_ENABLE`
|
* `UNICODE_ENABLE`
|
||||||
* Unicode
|
* Unicode
|
||||||
* `BLUETOOTH`
|
* `BLUETOOTH_ENABLE`
|
||||||
* Current options are AdafruitBLE, RN42
|
* Current options are BluefruitLE, RN42
|
||||||
* `SPLIT_KEYBOARD`
|
* `SPLIT_KEYBOARD`
|
||||||
* Enables split keyboard support (dual MCU like the let's split and bakingpy's boards) and includes all necessary files located at quantum/split_common
|
* Enables split keyboard support (dual MCU like the let's split and bakingpy's boards) and includes all necessary files located at quantum/split_common
|
||||||
* `CUSTOM_MATRIX`
|
* `CUSTOM_MATRIX`
|
||||||
|
|
|
@ -7,7 +7,7 @@ Currently Bluetooth support is limited to AVR based chips. For Bluetooth 2.1, QM
|
||||||
|Board |Bluetooth Protocol |Connection Type|rules.mk |Bluetooth Chip|
|
|Board |Bluetooth Protocol |Connection Type|rules.mk |Bluetooth Chip|
|
||||||
|----------------------------------------------------------------|--------------------|---------------|--------------------------------|--------------|
|
|----------------------------------------------------------------|--------------------|---------------|--------------------------------|--------------|
|
||||||
|Roving Networks RN-42 (Sparkfun Bluesmirf) |Bluetooth Classic |UART |`BLUETOOTH_DRIVER = RN42` |RN-42 |
|
|Roving Networks RN-42 (Sparkfun Bluesmirf) |Bluetooth Classic |UART |`BLUETOOTH_DRIVER = RN42` |RN-42 |
|
||||||
|[Bluefruit LE SPI Friend](https://www.adafruit.com/product/2633)|Bluetooth Low Energy|SPI |`BLUETOOTH_DRIVER = AdafruitBLE`|nRF51822 |
|
|[Bluefruit LE SPI Friend](https://www.adafruit.com/product/2633)|Bluetooth Low Energy|SPI |`BLUETOOTH_DRIVER = BluefruitLE`|nRF51822 |
|
||||||
|
|
||||||
Not Supported Yet but possible:
|
Not Supported Yet but possible:
|
||||||
* [Bluefruit LE UART Friend](https://www.adafruit.com/product/2479). [Possible tmk implementation found in](https://github.com/tmk/tmk_keyboard/issues/514)
|
* [Bluefruit LE UART Friend](https://www.adafruit.com/product/2479). [Possible tmk implementation found in](https://github.com/tmk/tmk_keyboard/issues/514)
|
||||||
|
@ -17,9 +17,9 @@ Not Supported Yet but possible:
|
||||||
|
|
||||||
### Adafruit BLE SPI Friend
|
### Adafruit BLE SPI Friend
|
||||||
Currently The only bluetooth chipset supported by QMK is the Adafruit Bluefruit SPI Friend. It's a Nordic nRF51822 based chip running Adafruit's custom firmware. Data is transmitted via Adafruit's SDEP over Hardware SPI. The [Feather 32u4 Bluefruit LE](https://www.adafruit.com/product/2829) is supported as it's an AVR mcu connected via SPI to the Nordic BLE chip with Adafruit firmware. If Building a custom board with the SPI friend it would be easiest to just use the pin selection that the 32u4 feather uses but you can change the pins in the config.h options with the following defines:
|
Currently The only bluetooth chipset supported by QMK is the Adafruit Bluefruit SPI Friend. It's a Nordic nRF51822 based chip running Adafruit's custom firmware. Data is transmitted via Adafruit's SDEP over Hardware SPI. The [Feather 32u4 Bluefruit LE](https://www.adafruit.com/product/2829) is supported as it's an AVR mcu connected via SPI to the Nordic BLE chip with Adafruit firmware. If Building a custom board with the SPI friend it would be easiest to just use the pin selection that the 32u4 feather uses but you can change the pins in the config.h options with the following defines:
|
||||||
* `#define ADAFRUIT_BLE_RST_PIN D4`
|
* `#define BLUEFRUIT_LE_RST_PIN D4`
|
||||||
* `#define ADAFRUIT_BLE_CS_PIN B4`
|
* `#define BLUEFRUIT_LE_CS_PIN B4`
|
||||||
* `#define ADAFRUIT_BLE_IRQ_PIN E6`
|
* `#define BLUEFRUIT_LE_IRQ_PIN E6`
|
||||||
|
|
||||||
A Bluefruit UART friend can be converted to an SPI friend, however this [requires](https://github.com/qmk/qmk_firmware/issues/2274) some reflashing and soldering directly to the MDBT40 chip.
|
A Bluefruit UART friend can be converted to an SPI friend, however this [requires](https://github.com/qmk/qmk_firmware/issues/2274) some reflashing and soldering directly to the MDBT40 chip.
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ Add the following to your `rules.mk`:
|
||||||
|
|
||||||
```make
|
```make
|
||||||
BLUETOOTH_ENABLE = yes
|
BLUETOOTH_ENABLE = yes
|
||||||
BLUETOOTH_DRIVER = AdafruitBLE # or RN42
|
BLUETOOTH_DRIVER = BluefruitLE # or RN42
|
||||||
```
|
```
|
||||||
|
|
||||||
## Bluetooth Keycodes
|
## Bluetooth Keycodes
|
||||||
|
|
|
@ -141,10 +141,13 @@ Processing combos has two buffers, one for the key presses, another for the comb
|
||||||
## Modifier Combos
|
## Modifier Combos
|
||||||
If a combo resolves to a Modifier, the window for processing the combo can be extended independently from normal combos. By default, this is disabled but can be enabled with `#define COMBO_MUST_HOLD_MODS`, and the time window can be configured with `#define COMBO_HOLD_TERM 150` (default: `TAPPING_TERM`). With `COMBO_MUST_HOLD_MODS`, you cannot tap the combo any more which makes the combo less prone to misfires.
|
If a combo resolves to a Modifier, the window for processing the combo can be extended independently from normal combos. By default, this is disabled but can be enabled with `#define COMBO_MUST_HOLD_MODS`, and the time window can be configured with `#define COMBO_HOLD_TERM 150` (default: `TAPPING_TERM`). With `COMBO_MUST_HOLD_MODS`, you cannot tap the combo any more which makes the combo less prone to misfires.
|
||||||
|
|
||||||
## Per Combo Timing, Holding and Tapping
|
## Strict key press order
|
||||||
For each combo, it is possible to configure the time window it has to pressed in, if it needs to be held down, or if it needs to be tapped.
|
By defining `COMBO_MUST_PRESS_IN_ORDER` combos only activate when the keys are pressed in the same order as they are defined in the key array.
|
||||||
|
|
||||||
For example, tap-only combos are useful if any (or all) of the underlying keys is a Mod-Tap or a Layer-Tap key. When you tap the combo, you get the combo result. When you press the combo and hold it down, the combo doesn't actually activate. Instead the keys are processed separately as if the combo wasn't even there.
|
## Per Combo Timing, Holding, Tapping and Key Press Order
|
||||||
|
For each combo, it is possible to configure the time window it has to pressed in, if it needs to be held down, if it needs to be tapped, or if its keys need to be pressed in order.
|
||||||
|
|
||||||
|
For example, tap-only combos are useful if any (or all) of the underlying keys are mod-tap or layer-tap keys. When you tap the combo, you get the combo result. When you press the combo and hold it down, the combo doesn't activate. Instead the keys are processed separately as if the combo wasn't even there.
|
||||||
|
|
||||||
In order to use these features, the following configuration options and functions need to be defined. Coming up with useful timings and configuration is left as an exercise for the reader.
|
In order to use these features, the following configuration options and functions need to be defined. Coming up with useful timings and configuration is left as an exercise for the reader.
|
||||||
|
|
||||||
|
@ -153,6 +156,7 @@ In order to use these features, the following configuration options and function
|
||||||
| `COMBO_TERM_PER_COMBO` | uint16_t get_combo_term(uint16_t index, combo_t \*combo) | Optional per-combo timeout window. (default: `COMBO_TERM`) |
|
| `COMBO_TERM_PER_COMBO` | uint16_t get_combo_term(uint16_t index, combo_t \*combo) | Optional per-combo timeout window. (default: `COMBO_TERM`) |
|
||||||
| `COMBO_MUST_HOLD_PER_COMBO` | bool get_combo_must_hold(uint16_t index, combo_t \*combo) | Controls if a given combo should fire immediately on tap or if it needs to be held. (default: `false`) |
|
| `COMBO_MUST_HOLD_PER_COMBO` | bool get_combo_must_hold(uint16_t index, combo_t \*combo) | Controls if a given combo should fire immediately on tap or if it needs to be held. (default: `false`) |
|
||||||
| `COMBO_MUST_TAP_PER_COMBO` | bool get_combo_must_tap(uint16_t index, combo_t \*combo) | Controls if a given combo should fire only if tapped within `COMBO_HOLD_TERM`. (default: `false`) |
|
| `COMBO_MUST_TAP_PER_COMBO` | bool get_combo_must_tap(uint16_t index, combo_t \*combo) | Controls if a given combo should fire only if tapped within `COMBO_HOLD_TERM`. (default: `false`) |
|
||||||
|
| `COMBO_MUST_PRESS_IN_ORDER_PER_COMBO` | bool get_combo_must_press_in_order(uint16_t index, combo_t \*combo) | Controls if a given combo should fire only if its keys are pressed in order. (default: `true`) |
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
```c
|
```c
|
||||||
|
@ -216,6 +220,38 @@ bool get_combo_must_tap(uint16_t index, combo_t *combo) {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool get_combo_must_press_in_order(uint16_t combo_index, combo_t *combo) {
|
||||||
|
switch (combo_index) {
|
||||||
|
/* List combos here that you want to only activate if their keys
|
||||||
|
* are pressed in the same order as they are defined in the combo's key
|
||||||
|
* array. */
|
||||||
|
case COMBO_NAME_HERE:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Generic hook to (dis)allow a combo activation
|
||||||
|
|
||||||
|
By defining `COMBO_SHOULD_TRIGGER` and its companying function `bool combo_should_trigger(uint16_t combo_index, combo_t *combo, uint16_t keycode, keyrecord_t *record)` you can block or allow combos to activate on the conditions of your choice.
|
||||||
|
For example, you could disallow some combos on the base layer and allow them on another. Or disable combos on the home row when a timer is running.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
```c
|
||||||
|
bool combo_should_trigger(uint16_t combo_index, combo_t *combo, uint16_t keycode, keyrecord_t *record) {
|
||||||
|
/* Disable combo `SOME_COMBO` on layer `_LAYER_A` */
|
||||||
|
switch (combo_index) {
|
||||||
|
case SOME_COMBO:
|
||||||
|
if (layer_state_is(_LAYER_A)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Variable Length Combos
|
## Variable Length Combos
|
||||||
|
|
|
@ -116,6 +116,7 @@ Where name of algorithm is one of:
|
||||||
For use in keyboards where refreshing ```NUM_KEYS``` 8-bit counters is computationally expensive / low scan rate, and fingers usually only hit one row at a time. This could be
|
For use in keyboards where refreshing ```NUM_KEYS``` 8-bit counters is computationally expensive / low scan rate, and fingers usually only hit one row at a time. This could be
|
||||||
appropriate for the ErgoDox models; the matrix is rotated 90°, and hence its "rows" are really columns, and each finger only hits a single "row" at a time in normal use.
|
appropriate for the ErgoDox models; the matrix is rotated 90°, and hence its "rows" are really columns, and each finger only hits a single "row" at a time in normal use.
|
||||||
* ```sym_eager_pk``` - debouncing per key. On any state change, response is immediate, followed by ```DEBOUNCE``` milliseconds of no further input for that key
|
* ```sym_eager_pk``` - debouncing per key. On any state change, response is immediate, followed by ```DEBOUNCE``` milliseconds of no further input for that key
|
||||||
|
* ```sym_defer_pr``` - debouncing per row. On any state change, a per-row timer is set. When ```DEBOUNCE``` milliseconds of no changes have occurred on that row, the entire row is pushed. Can improve responsiveness over `sym_defer_g` while being less susceptible than per-key debouncers to noise.
|
||||||
* ```sym_defer_pk``` - debouncing per key. On any state change, a per-key timer is set. When ```DEBOUNCE``` milliseconds of no changes have occurred on that key, the key status change is pushed.
|
* ```sym_defer_pk``` - debouncing per key. On any state change, a per-key timer is set. When ```DEBOUNCE``` milliseconds of no changes have occurred on that key, the key status change is pushed.
|
||||||
* ```asym_eager_defer_pk``` - debouncing per key. On a key-down state change, response is immediate, followed by ```DEBOUNCE``` milliseconds of no further input for that key. On a key-up state change, a per-key timer is set. When ```DEBOUNCE``` milliseconds of no changes have occurred on that key, the key-up status change is pushed.
|
* ```asym_eager_defer_pk``` - debouncing per key. On a key-down state change, response is immediate, followed by ```DEBOUNCE``` milliseconds of no further input for that key. On a key-up state change, a per-key timer is set. When ```DEBOUNCE``` milliseconds of no changes have occurred on that key, the key-up status change is pushed.
|
||||||
|
|
||||||
|
|
|
@ -4,17 +4,17 @@ If you're using a 60% keyboard, or any other layout with no F-row, you will have
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Replace the `KC_GRV` key in your keymap (usually to the left of the `1` key) with `KC_GESC`. Most of the time this key will output `KC_ESC` when pressed. However, when Shift or GUI are held down it will output `KC_GRV` instead.
|
Replace the `KC_GRV` key in your keymap (usually to the left of the `1` key) with `QK_GESC`. Most of the time this key will output `KC_ESC` when pressed. However, when Shift or GUI are held down it will output `KC_GRV` instead.
|
||||||
|
|
||||||
## What Your OS Sees
|
## What Your OS Sees
|
||||||
|
|
||||||
If Mary presses GESC on her keyboard, the OS will see an KC_ESC character. Now if Mary holds Shift down and presses GESC it will output `~`, or a shifted backtick. Now if she holds GUI/CMD/WIN, it will output a simple <code>`</code> character.
|
If Mary presses `QK_GESC` on her keyboard, the OS will see an KC_ESC character. Now if Mary holds Shift down and presses `QK_GESC` it will output `~`, or a shifted backtick. Now if she holds GUI/CMD/WIN, it will output a simple <code>`</code> character.
|
||||||
|
|
||||||
## Keycodes
|
## Keycodes
|
||||||
|
|
||||||
|Key |Aliases |Description |
|
|Key |Aliases |Description |
|
||||||
|---------|-----------|------------------------------------------------------------------|
|
|-----------------|---------|------------------------------------------------------------------|
|
||||||
|`KC_GESC`|`GRAVE_ESC`|Escape when pressed, <code>`</code> when Shift or GUI are held|
|
|`QK_GRAVE_ESCAPE`|`QK_GESC`|Escape when pressed, <code>`</code> when Shift or GUI are held|
|
||||||
|
|
||||||
### Caveats
|
### Caveats
|
||||||
|
|
||||||
|
|
|
@ -167,7 +167,7 @@ List of waveform sequences from the datasheet:
|
||||||
```
|
```
|
||||||
#define DRV_GREETING *sequence name or number*
|
#define DRV_GREETING *sequence name or number*
|
||||||
```
|
```
|
||||||
If haptic feedback is enabled, the keyboard will vibrate to a specific sqeuence during startup. That can be selected using the following define:
|
If haptic feedback is enabled, the keyboard will vibrate to a specific sequence during startup. That can be selected using the following define:
|
||||||
|
|
||||||
```
|
```
|
||||||
#define DRV_MODE_DEFAULT *sequence name or number*
|
#define DRV_MODE_DEFAULT *sequence name or number*
|
||||||
|
@ -191,9 +191,6 @@ With the entry of `#define NO_HAPTIC_MOD` in config.h, the following keys will n
|
||||||
* `TT()` layer tap toggle keys, when held to activate a layer. However when tapped `TAPPING_TOGGLE` times to permanently toggle the layer, on the last tap haptic feedback is still triggered.
|
* `TT()` layer tap toggle keys, when held to activate a layer. However when tapped `TAPPING_TOGGLE` times to permanently toggle the layer, on the last tap haptic feedback is still triggered.
|
||||||
* `MT()` mod tap keys, when held to keep a usual modifier key pressed. However when tapped, and the key is quickly released, and sends a keycode, haptic feedback is still triggered. See also [Mod-Tap](mod_tap.md).
|
* `MT()` mod tap keys, when held to keep a usual modifier key pressed. However when tapped, and the key is quickly released, and sends a keycode, haptic feedback is still triggered. See also [Mod-Tap](mod_tap.md).
|
||||||
|
|
||||||
### NO_HAPTIC_FN
|
|
||||||
With the entry of `#define NO_HAPTIC_FN` in config.h, deprecated `fn_actions` type function keys will not trigger a feedback.
|
|
||||||
|
|
||||||
### NO_HAPTIC_ALPHA
|
### NO_HAPTIC_ALPHA
|
||||||
With the entry of `#define NO_HAPTIC_ALPHA` in config.h, none of the alpha keys (A ... Z) will trigger a feedback.
|
With the entry of `#define NO_HAPTIC_ALPHA` in config.h, none of the alpha keys (A ... Z) will trigger a feedback.
|
||||||
|
|
||||||
|
@ -207,4 +204,4 @@ With the entry of `#define NO_HAPTIC_LOCKKEYS` in config.h, none of the followin
|
||||||
With the entry of `#define NO_HAPTIC_NAV` in config.h, none of the following keys will trigger a feedback: Print Screen, Pause, Insert, Delete, Page Down, Page Up, Left Arrow, Up Arrow, Right Arrow, Down Arrow, End, Home.
|
With the entry of `#define NO_HAPTIC_NAV` in config.h, none of the following keys will trigger a feedback: Print Screen, Pause, Insert, Delete, Page Down, Page Up, Left Arrow, Up Arrow, Right Arrow, Down Arrow, End, Home.
|
||||||
|
|
||||||
### NO_HAPTIC_NUMERIC
|
### NO_HAPTIC_NUMERIC
|
||||||
With the entry of `#define NO_HAPTIC_NUMERIC` in config.h, none of the following keys between 0 and 9 (KC_1 ... KC_0) will trigger a feedback.
|
With the entry of `#define NO_HAPTIC_NUMERIC` in config.h, none of the following keys between 0 and 9 (KC_1 ... KC_0) will trigger a feedback.
|
||||||
|
|
|
@ -19,4 +19,5 @@ First, enable Key Lock by setting `KEY_LOCK_ENABLE = yes` in your `rules.mk`. Th
|
||||||
Key Lock is only able to hold standard action keys and [One Shot modifier](one_shot_keys.md) keys (for example, if you have your Shift defined as `OSM(KC_LSFT)`).
|
Key Lock is only able to hold standard action keys and [One Shot modifier](one_shot_keys.md) keys (for example, if you have your Shift defined as `OSM(KC_LSFT)`).
|
||||||
This does not include any of the QMK special functions (except One Shot modifiers), or shifted versions of keys such as `KC_LPRN`. If it's in the [Basic Keycodes](keycodes_basic.md) list, it can be held.
|
This does not include any of the QMK special functions (except One Shot modifiers), or shifted versions of keys such as `KC_LPRN`. If it's in the [Basic Keycodes](keycodes_basic.md) list, it can be held.
|
||||||
|
|
||||||
Switching layers will not cancel the Key Lock.
|
Switching layers will not cancel the Key Lock. The Key Lock can be cancelled by calling the `cancel_key_lock()` function.
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,109 @@ const is31_led PROGMEM g_is31_leds[DRIVER_LED_TOTAL] = {
|
||||||
|
|
||||||
Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](https://www.issi.com/WW/pdf/31FL3731.pdf) and the header file `drivers/led/issi/is31fl3731-simple.h`. The `driver` is the index of the driver you defined in your `config.h` (`0`, `1`, `2`, or `3` ).
|
Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](https://www.issi.com/WW/pdf/31FL3731.pdf) and the header file `drivers/led/issi/is31fl3731-simple.h`. The `driver` is the index of the driver you defined in your `config.h` (`0`, `1`, `2`, or `3` ).
|
||||||
|
|
||||||
|
---
|
||||||
|
### IS31FLCOMMON :id=is31flcommon
|
||||||
|
|
||||||
|
There is basic support for addressable LED matrix lighting with a selection of I2C ISSI Lumissil LED controllers through a shared common driver. To enable it, add this to your `rules.mk`:
|
||||||
|
|
||||||
|
```makefile
|
||||||
|
LED_MATRIX_ENABLE = yes
|
||||||
|
LED_MATRIX_DRIVER = <driver name>
|
||||||
|
```
|
||||||
|
|
||||||
|
Where `<driver name>` is the applicable LED driver chip as below
|
||||||
|
|
||||||
|
| Driver Name | Data Sheet | Capability |
|
||||||
|
|-------------|------------|------------|
|
||||||
|
| `IS31FL3742A` | [datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3742A_DS.pdf) | 180 LED, 30x6 Matrix |
|
||||||
|
| `ISSIFL3743A` | [datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3743A_DS.pdf) | 198 LED, 18x11 Matrix |
|
||||||
|
| `IS31FL3745` | [datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3745_DS.pdf) | 144 LED, 18x8 Matrix |
|
||||||
|
| `IS31FL3746A` | [datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3746A_DS.pdf) | 72 LED, 18x4 Matrix |
|
||||||
|
|
||||||
|
You can use between 1 and 4 IC's. Do not specify `DRIVER_ADDR_<N>` define for IC's if not present on your keyboard. The `DRIVER_ADDR_1` default assumes that all Address pins on the controller have been connected to GND. Drivers that have SYNC functionality have the default settings to disable if 1 driver. If more than 1 drivers then `DRIVER_ADDR_1` will be set to Master and the remaiing ones set to Slave.
|
||||||
|
|
||||||
|
Configure the hardware via your `config.h`:
|
||||||
|
|
||||||
|
| Variable | Description | Default |
|
||||||
|
|----------|-------------|---------|
|
||||||
|
| `ISSI_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 |
|
||||||
|
| `ISSI_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 |
|
||||||
|
| `DRIVER_COUNT` | (Required) How many LED driver IC's are present | |
|
||||||
|
| `DRIVER_LED_TOTAL` | (Required) How many LED lights are present across all drivers | |
|
||||||
|
| `DRIVER_ADDR_1` | (Optional) Address for the first LED driver | |
|
||||||
|
| `DRIVER_ADDR_<N>` | (Required) Address for the additional LED drivers | |
|
||||||
|
| `ISSI_SSR_<N>` | (Optional) Configuration for the Spread Spectrum Register | |
|
||||||
|
| `ISSI_CONFIGURATION` | (Optional) Configuration for the Configuration Register | |
|
||||||
|
| `ISSI_GLOBALCURRENT` | (Optional) Configuration for the Global Current Register | 0xFF |
|
||||||
|
| `ISSI_PULLDOWNUP` | (Optional) Configuration for the Pull Up & Pull Down Register | |
|
||||||
|
| `ISSI_TEMP` | (Optional) Configuration for the Tempature Register | |
|
||||||
|
| `ISSI_PWM_ENABLE` | (Optional) Configuration for the PWM Enable Register | |
|
||||||
|
| `ISSI_PWM_SET` | (Optional) Configuration for the PWM Setting Register | |
|
||||||
|
| `ISSI_SCAL_LED ` | (Optional) Configuration for the LEDs Scaling Registers | 0xFF |
|
||||||
|
| `ISSI_MANUAL_SCALING` | (Optional) If you wish to configure the Scaling Registers manually | |
|
||||||
|
|
||||||
|
|
||||||
|
Defaults
|
||||||
|
|
||||||
|
| Variable | IS31FL3742A | IS31FL3743A | IS31FL3745 | IS31FL3746 |
|
||||||
|
|----------|-------------|-------------|------------|------------|
|
||||||
|
| `DRIVER_ADDR_1` | 0b0110000 | 0b0100000 | 0b0100000 | 0b1100000 |
|
||||||
|
| `ISSI_SSR_1` | 0x00 | 0x00 / 0x60 | 0x00 / 0xC0 | 0x00 |
|
||||||
|
| `ISSI_SSR_<2-4>` | 0x00 | 0x40 | 0x80 | 0x00 |
|
||||||
|
| `ISSI_CONFIGURATION` | 0x31 | 0x01 | 0x31 | 0x01 |
|
||||||
|
| `ISSI_PULLDOWNUP` | 0x55 | 0x33 | 0x33 | 0x33 |
|
||||||
|
| `ISSI_TEMP` | N/A | 0x00 | 0x00 | 0x00 |
|
||||||
|
| `ISSI_PWM_ENABLE` | N/A | N/A | N/A | 0x00 |
|
||||||
|
| `ISSI_PWM_SET` | 0x00 | N/A | N/A | 0x00 |
|
||||||
|
|
||||||
|
Here is an example using 2 drivers.
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define DRIVER_ADDR_2 0b0100001
|
||||||
|
|
||||||
|
#define DRIVER_COUNT 2
|
||||||
|
#define DRIVER_1_LED_TOTAL 66
|
||||||
|
#define DRIVER_2_LED_TOTAL 42
|
||||||
|
#define DRIVER_LED_TOTAL (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
|
||||||
|
```
|
||||||
|
!> Note the parentheses, this is so when `DRIVER_LED_TOTAL` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`.
|
||||||
|
|
||||||
|
Currently only 4 drivers are supported, but it would be trivial to support for more. Note that using a combination of different drivers is not supported. All drivers must be of the same model.
|
||||||
|
|
||||||
|
Define these arrays listing all the LEDs in your `<keyboard>.c`:
|
||||||
|
|
||||||
|
```c
|
||||||
|
const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = {
|
||||||
|
/* Refer to IS31 manual for these locations
|
||||||
|
* driver
|
||||||
|
* | LED address
|
||||||
|
* | | */
|
||||||
|
{ 0, CS1_SW1 },
|
||||||
|
{ 0, CS2_SW1 },
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Where `CSx_SWx` is the location of the LED in the matrix defined by the datasheet. The `driver` is the index of the driver you defined in your `config.h` (`0`, `1`, `2`, or `3` for now).
|
||||||
|
|
||||||
|
`ISSI_MANUAL_SCALING` is used to override the Scaling for individual LED's. By default they will be set as per `ISSI_SCAL_LED`. In `config.h` set how many LED's you want to manually set scaling for.
|
||||||
|
Eg `#define ISSI_MANUAL_SCALING 3`
|
||||||
|
|
||||||
|
Then Define the array listing all the LEDs you want to override in your `<keyboard>.c`:
|
||||||
|
|
||||||
|
```c
|
||||||
|
const is31_led __flash g_is31_scaling[ISSI_MANUAL_SCALING] = {
|
||||||
|
* LED Index
|
||||||
|
* | Scaling
|
||||||
|
* | | */
|
||||||
|
{5, 120},
|
||||||
|
{9, 120},
|
||||||
|
....
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Where LED Index is the position of the LED in the `g_is31_leds` array. The `scaling` value between 0 and 255 to be written to the Scaling Register.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Common Configuration :id=common-configuration
|
## Common Configuration :id=common-configuration
|
||||||
|
|
|
@ -59,13 +59,13 @@ This is the default mode. You can adjust the cursor and scrolling acceleration u
|
||||||
|
|
||||||
|Define |Default|Description |
|
|Define |Default|Description |
|
||||||
|----------------------------|-------|---------------------------------------------------------|
|
|----------------------------|-------|---------------------------------------------------------|
|
||||||
|`MOUSEKEY_DELAY` |300 |Delay between pressing a movement key and cursor movement|
|
|`MOUSEKEY_DELAY` |10 |Delay between pressing a movement key and cursor movement|
|
||||||
|`MOUSEKEY_INTERVAL` |50 |Time between cursor movements in milliseconds |
|
|`MOUSEKEY_INTERVAL` |20 |Time between cursor movements in milliseconds |
|
||||||
|`MOUSEKEY_MOVE_DELTA` |5 |Step size |
|
|`MOUSEKEY_MOVE_DELTA` |8 |Step size |
|
||||||
|`MOUSEKEY_MAX_SPEED` |10 |Maximum cursor speed at which acceleration stops |
|
|`MOUSEKEY_MAX_SPEED` |10 |Maximum cursor speed at which acceleration stops |
|
||||||
|`MOUSEKEY_TIME_TO_MAX` |20 |Time until maximum cursor speed is reached |
|
|`MOUSEKEY_TIME_TO_MAX` |30 |Time until maximum cursor speed is reached |
|
||||||
|`MOUSEKEY_WHEEL_DELAY` |300 |Delay between pressing a wheel key and wheel movement |
|
|`MOUSEKEY_WHEEL_DELAY` |10 |Delay between pressing a wheel key and wheel movement |
|
||||||
|`MOUSEKEY_WHEEL_INTERVAL` |100 |Time between wheel movements |
|
|`MOUSEKEY_WHEEL_INTERVAL` |80 |Time between wheel movements |
|
||||||
|`MOUSEKEY_WHEEL_MAX_SPEED` |8 |Maximum number of scroll steps per scroll action |
|
|`MOUSEKEY_WHEEL_MAX_SPEED` |8 |Maximum number of scroll steps per scroll action |
|
||||||
|`MOUSEKEY_WHEEL_TIME_TO_MAX`|40 |Time until maximum scroll speed is reached |
|
|`MOUSEKEY_WHEEL_TIME_TO_MAX`|40 |Time until maximum scroll speed is reached |
|
||||||
|
|
||||||
|
@ -85,9 +85,9 @@ This is an extension of the accelerated mode. The kinetic mode uses a quadratic
|
||||||
|Define |Default |Description |
|
|Define |Default |Description |
|
||||||
|--------------------------------------|---------|---------------------------------------------------------------|
|
|--------------------------------------|---------|---------------------------------------------------------------|
|
||||||
|`MK_KINETIC_SPEED` |undefined|Enable kinetic mode |
|
|`MK_KINETIC_SPEED` |undefined|Enable kinetic mode |
|
||||||
|`MOUSEKEY_DELAY` |8 |Delay between pressing a movement key and cursor movement |
|
|`MOUSEKEY_DELAY` |5 |Delay between pressing a movement key and cursor movement |
|
||||||
|`MOUSEKEY_INTERVAL` |8 |Time between cursor movements in milliseconds |
|
|`MOUSEKEY_INTERVAL` |10 |Time between cursor movements in milliseconds |
|
||||||
|`MOUSEKEY_MOVE_DELTA` |25 |Step size for accelerating from initial to base speed |
|
|`MOUSEKEY_MOVE_DELTA` |5 |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` |1000 |Maximum cursor speed at which acceleration stops |
|
||||||
|`MOUSEKEY_DECELERATED_SPEED` |400 |Decelerated cursor speed |
|
|`MOUSEKEY_DECELERATED_SPEED` |400 |Decelerated cursor speed |
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
Pointing Device is a generic name for a feature intended to be generic: moving the system pointer around. There are certainly other options for it - like mousekeys - but this aims to be easily modifiable and hardware driven. You can implement custom keys to control functionality, or you can gather information from other peripherals and insert it directly here - let QMK handle the processing for you.
|
Pointing Device is a generic name for a feature intended to be generic: moving the system pointer around. There are certainly other options for it - like mousekeys - but this aims to be easily modifiable and hardware driven. You can implement custom keys to control functionality, or you can gather information from other peripherals and insert it directly here - let QMK handle the processing for you.
|
||||||
|
|
||||||
To enable Pointing Device, uncomment the following line in your rules.mk:
|
To enable Pointing Device, add the following line in your rules.mk and specify one of the driver options below.
|
||||||
|
|
||||||
```make
|
```make
|
||||||
POINTING_DEVICE_ENABLE = yes
|
POINTING_DEVICE_ENABLE = yes
|
||||||
|
@ -40,13 +40,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. | _not defined_ |
|
||||||
|
|
||||||
|
|
||||||
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.
|
||||||
|
@ -69,7 +69,7 @@ The Analog Joystick is an analog (ADC) driven sensor. There are a variety of jo
|
||||||
|`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 maxiumum 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_ |
|
||||||
|
|
||||||
|
|
||||||
|
@ -127,11 +127,10 @@ The Pimoroni Trackball module is a I2C based breakout board with an RGB enable t
|
||||||
| 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 trackpad in milliseconds. | `100` |
|
|`PIMORONI_TRACKBALL_TIMEOUT` | (Optional) The timeout for i2c communication with the trackball in milliseconds. | `100` |
|
||||||
|`PIMORONI_TRACKBALL_INTERVAL_MS` | (Optional) The update/read interval for the sensor in milliseconds. | `8` |
|
|
||||||
|`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 Sensor
|
||||||
|
|
||||||
|
@ -145,20 +144,50 @@ The PMW 3360 is an SPI driven optical sensor, that uses a built in IR LED for su
|
||||||
|
|
||||||
| Setting | Description | Default |
|
| Setting | Description | Default |
|
||||||
|-----------------------------|--------------------------------------------------------------------------------------------|---------------|
|
|-----------------------------|--------------------------------------------------------------------------------------------|---------------|
|
||||||
|`PMW3360_CS_PIN` | (Required) Sets the Cable Select pin connected to the sensor. | _not defined_ |
|
|`PMW3360_CS_PIN` | (Required) Sets the Cable Select pin connected to the sensor. | _not defined_ |
|
||||||
|`PMW3360_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `2000000` |
|
|`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_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_MODE` | (Optional) Sets the SPI Mode for the sensor. | `3` |
|
||||||
|`PMW3360_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ |
|
|`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` |
|
|`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 +/- 30 degrees directly in the sensor. | `0` |
|
|`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.
|
||||||
|
|
||||||
|
### 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 here, you can manually implement it, by adding these functions (with the correct implementation for your device):
|
If you have a sensor type that isn't supported above, a custom option is available by adding the following to your `rules.mk`
|
||||||
|
|
||||||
|
```make
|
||||||
|
POINTING_DEVICE_DRIVER = custom
|
||||||
|
```
|
||||||
|
|
||||||
|
Using the custom driver will require implementing the following functions:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
void pointing_device_driver_init(void) {}
|
void pointing_device_driver_init(void) {}
|
||||||
|
@ -171,14 +200,35 @@ 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_ |
|
|`POINTING_DEVICE_ROTATION_90` | (Optional) Rotates the X and Y data by 90 degrees. | _not defined_ |
|
||||||
|`POINTING_DEVICE_ROTATION_180` | (Optional) Rotates the X and Y data by 180 degrees. | _not defined_ |
|
|`POINTING_DEVICE_ROTATION_180` | (Optional) Rotates the X and Y data by 180 degrees. | _not defined_ |
|
||||||
|`POINTING_DEVICE_ROTATION_270` | (Optional) Rotates the X and Y data by 270 degrees. | _not defined_ |
|
|`POINTING_DEVICE_ROTATION_270` | (Optional) Rotates the X and Y data by 270 degrees. | _not defined_ |
|
||||||
|`POINTING_DEVICE_INVERT_X` | (Optional) Inverts the X axis report. | _not defined_ |
|
|`POINTING_DEVICE_INVERT_X` | (Optional) Inverts the X axis report. | _not defined_ |
|
||||||
|`POINTING_DEVICE_INVERT_Y` | (Optional) Inverts the Y axis report. | _not defined_ |
|
|`POINTING_DEVICE_INVERT_Y` | (Optional) Inverts the Y axis report. | _not defined_ |
|
||||||
|`POINTING_DEVICE_MOTION_PIN` | (Optional) If supported, will only read from sensor if pin is active. | _not defined_ |
|
|`POINTING_DEVICE_MOTION_PIN` | (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_ |
|
||||||
|
|
||||||
|
!> 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.
|
||||||
|
|
||||||
|
|
||||||
|
## Split Keyboard Configuration
|
||||||
|
|
||||||
|
The following configuration options are only available when using `SPLIT_POINTING_ENABLE` see [data sync options](feature_split_keyboard.md?id=data-sync-options). The rotation and invert `*_RIGHT` options are only used with `POINTING_DEVICE_COMBINED`. If using `POINTING_DEVICE_LEFT` or `POINTING_DEVICE_RIGHT` use the common configuration above to configure your pointing device.
|
||||||
|
|
||||||
|
| Setting | Description | Default |
|
||||||
|
|----------------------------------------|-----------------------------------------------------------------------|---------------|
|
||||||
|
|`POINTING_DEVICE_LEFT` | Pointing device on the left side (Required - pick one only) | _not defined_ |
|
||||||
|
|`POINTING_DEVICE_RIGHT` | Pointing device on the right side (Required - pick one only) | _not defined_ |
|
||||||
|
|`POINTING_DEVICE_COMBINED` | Pointing device on both sides (Required - pick one only) | _not defined_ |
|
||||||
|
|`POINTING_DEVICE_ROTATION_90_RIGHT` | (Optional) Rotates the X and Y data by 90 degrees. | _not defined_ |
|
||||||
|
|`POINTING_DEVICE_ROTATION_180_RIGHT` | (Optional) Rotates the X and Y data by 180 degrees. | _not defined_ |
|
||||||
|
|`POINTING_DEVICE_ROTATION_270_RIGHT` | (Optional) Rotates the X and Y data by 270 degrees. | _not defined_ |
|
||||||
|
|`POINTING_DEVICE_INVERT_X_RIGHT` | (Optional) Inverts the X axis report. | _not defined_ |
|
||||||
|
|`POINTING_DEVICE_INVERT_Y_RIGHT` | (Optional) Inverts the Y axis report. | _not defined_ |
|
||||||
|
|
||||||
|
!> If there is a `_RIGHT` configuration option or callback, the [common configuration](feature_pointing_device.md?id=common-configuration) option will work for the left. For correct left/right detection you should setup a [handedness option](feature_split_keyboard?id=setting-handedness), `EE_HANDS` is usually a good option for an existing board that doesn't do handedness by hardware.
|
||||||
|
|
||||||
|
|
||||||
## Callbacks and Functions
|
## Callbacks and Functions
|
||||||
|
@ -188,7 +238,7 @@ void pointing_device_driver_set_cpi(uint16_t cpi) {}
|
||||||
| `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. |
|
||||||
| `pointing_device_task_user(mouse_report)` | Callback that sends sensor data, so user coe can intercept and modify the data. Returns a mouse report. |
|
| `pointing_device_task_user(mouse_report)` | Callback that sends sensor data, so user code can intercept and modify the data. Returns a mouse report. |
|
||||||
| `pointing_device_handle_buttons(buttons, pressed, button)` | Callback to handle hardware button presses. Returns a `uint8_t`. |
|
| `pointing_device_handle_buttons(buttons, pressed, button)` | Callback to handle hardware button presses. Returns a `uint8_t`. |
|
||||||
| `pointing_device_get_cpi(void)` | Gets the current CPI/DPI setting from the sensor, if supported. |
|
| `pointing_device_get_cpi(void)` | Gets the current CPI/DPI setting from the sensor, if supported. |
|
||||||
| `pointing_device_set_cpi(uint16_t)` | Sets the CPI/DPI, if supported. |
|
| `pointing_device_set_cpi(uint16_t)` | Sets the CPI/DPI, if supported. |
|
||||||
|
@ -196,6 +246,21 @@ void pointing_device_driver_set_cpi(uint16_t cpi) {}
|
||||||
| `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(old, new)` | Compares the old and new `mouse_report_t` data and returns true only if it has changed. |
|
| `has_mouse_report_changed(old, new)` | 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. |
|
||||||
|
|
||||||
|
|
||||||
|
## Split Keyboard Callbacks and Functions
|
||||||
|
|
||||||
|
The combined functions below are only available when using `SPLIT_POINTING_ENABLE` and `POINTING_DEVICE_COMBINED`. The 2 callbacks `pointing_device_task_combined_*` replace the single sided equivalents above. See the [combined pointing devices example](feature_pointing_device.md?id=combined-pointing-devices)
|
||||||
|
|
||||||
|
| Function | Description |
|
||||||
|
|-----------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------|
|
||||||
|
| `pointing_device_set_shared_report(mouse_report)` | Sets the shared mouse report to the assigned `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_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_task_combined_kb(left_report, right_report)` | Callback, so keyboard code can intercept and modify the data. Returns a combined mouse report. |
|
||||||
|
| `pointing_device_task_combined_user(left_report, right_report)` | Callback, so user code can intercept and modify. Returns a combined mouse report using `pointing_device_combine_reports` |
|
||||||
|
| `pointing_device_adjust_by_defines_right(mouse_report)` | Applies right side rotations and invert configurations to a raw mouse report. |
|
||||||
|
|
||||||
|
|
||||||
# Manipulating Mouse Reports
|
# Manipulating Mouse Reports
|
||||||
|
@ -274,3 +339,62 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||||
```
|
```
|
||||||
|
|
||||||
This allows you to toggle between scrolling and cursor movement by pressing the DRAG_SCROLL key.
|
This allows you to toggle between scrolling and cursor movement by pressing the DRAG_SCROLL key.
|
||||||
|
|
||||||
|
## Split Examples
|
||||||
|
|
||||||
|
The following examples make use the `SPLIT_POINTING_ENABLE` functionality and show how to manipulate the mouse report for a scrolling mode.
|
||||||
|
|
||||||
|
### Single Pointing Device
|
||||||
|
|
||||||
|
The following example will work with either `POINTING_DEVICE_LEFT` or `POINTING_DEVICE_RIGHT` and enables scrolling mode while on a particular layer.
|
||||||
|
|
||||||
|
```c
|
||||||
|
|
||||||
|
static bool scrolling_mode = false;
|
||||||
|
|
||||||
|
layer_state_t layer_state_set_user(layer_state_t state) {
|
||||||
|
switch (get_highest_layer(state)) {
|
||||||
|
case _RAISE: // If we're on the _RAISE layer enable scrolling mode
|
||||||
|
scrolling_mode = true;
|
||||||
|
pointing_device_set_cpi(2000);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (scrolling_mode) { // check if we were scrolling before and set disable if so
|
||||||
|
scrolling_mode = false;
|
||||||
|
pointing_device_set_cpi(8000);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
report_mouse_t pointing_device_task_user(report_mouse_t mouse_report) {
|
||||||
|
if (scrolling_mode) {
|
||||||
|
mouse_report.h = mouse_report.x;
|
||||||
|
mouse_report.v = mouse_report.y;
|
||||||
|
mouse_report.x = 0;
|
||||||
|
mouse_report.y = 0;
|
||||||
|
}
|
||||||
|
return mouse_report;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Combined Pointing Devices
|
||||||
|
|
||||||
|
The following example requires `POINTING_DEVICE_COMBINED` and sets the left side pointing device to scroll only.
|
||||||
|
|
||||||
|
```c
|
||||||
|
void keyboard_post_init_user(void) {
|
||||||
|
pointing_device_set_cpi_on_side(true, 1000); //Set cpi on left side to a low value for slower scrolling.
|
||||||
|
pointing_device_set_cpi_on_side(false, 8000); //Set cpi on right side to a reasonable value for mousing.
|
||||||
|
}
|
||||||
|
|
||||||
|
report_mouse_t pointing_device_task_combined_user(report_mouse_t left_report, report_mouse_t right_report) {
|
||||||
|
left_report.h = left_report.x;
|
||||||
|
left_report.v = left_report.y;
|
||||||
|
left_report.x = 0;
|
||||||
|
left_report.y = 0;
|
||||||
|
return pointing_device_combine_reports(left_report, right_report);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
=======
|
||||||
|
|
|
@ -232,6 +232,115 @@ const is31_led PROGMEM g_is31_leds[DRIVER_LED_TOTAL] = {
|
||||||
|
|
||||||
Where `X_Y` is the location of the LED in the matrix defined by [the datasheet](https://www.issi.com/WW/pdf/31FL3737.pdf) and the header file `drivers/led/issi/is31fl3737.h`. The `driver` is the index of the driver you defined in your `config.h` (Only `0`, `1` for now).
|
Where `X_Y` is the location of the LED in the matrix defined by [the datasheet](https://www.issi.com/WW/pdf/31FL3737.pdf) and the header file `drivers/led/issi/is31fl3737.h`. The `driver` is the index of the driver you defined in your `config.h` (Only `0`, `1` for now).
|
||||||
|
|
||||||
|
---
|
||||||
|
### IS31FLCOMMON :id=is31flcommon
|
||||||
|
|
||||||
|
There is basic support for addressable RGB matrix lighting with a selection of I2C ISSI Lumissil RGB controllers through a shared common driver. To enable it, add this to your `rules.mk`:
|
||||||
|
|
||||||
|
```makefile
|
||||||
|
RGB_MATRIX_ENABLE = yes
|
||||||
|
RGB_MATRIX_DRIVER = <driver name>
|
||||||
|
```
|
||||||
|
|
||||||
|
Where `<driver name>` is the applicable LED driver chip as below
|
||||||
|
|
||||||
|
| Driver Name | Data Sheet | Capability |
|
||||||
|
|-------------|------------|------------|
|
||||||
|
| `IS31FL3742A` | [datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3742A_DS.pdf) | 60 RGB, 30x6 Matrix |
|
||||||
|
| `ISSIFL3743A` | [datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3743A_DS.pdf) | 66 RGB, 18x11 Matrix |
|
||||||
|
| `IS31FL3745` | [datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3745_DS.pdf) | 48 RGB, 18x8 Matrix |
|
||||||
|
| `IS31FL3746A` | [datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3746A_DS.pdf) | 24 RGB, 18x4 Matrix |
|
||||||
|
|
||||||
|
You can use between 1 and 4 IC's. Do not specify `DRIVER_ADDR_<N>` define for IC's if not present on your keyboard. The `DRIVER_ADDR_1` default assumes that all Address pins on the controller have been connected to GND. Drivers that have SYNC functionality have the default settings to disable if 1 driver. If more than 1 drivers then `DRIVER_ADDR_1` will be set to Master and the remaining ones set to Slave.
|
||||||
|
|
||||||
|
Configure the hardware via your `config.h`:
|
||||||
|
|
||||||
|
| Variable | Description | Default |
|
||||||
|
|----------|-------------|---------|
|
||||||
|
| `ISSI_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 |
|
||||||
|
| `ISSI_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 |
|
||||||
|
| `DRIVER_COUNT` | (Required) How many RGB driver IC's are present | |
|
||||||
|
| `DRIVER_LED_TOTAL` | (Required) How many RGB lights are present across all drivers | |
|
||||||
|
| `DRIVER_ADDR_1` | (Optional) Address for the first RGB driver | |
|
||||||
|
| `DRIVER_ADDR_<N>` | (Required) Address for the additional RGB drivers | |
|
||||||
|
| `ISSI_SSR_<N>` | (Optional) Configuration for the Spread Spectrum Register | |
|
||||||
|
| `ISSI_CONFIGURATION` | (Optional) Configuration for the Configuration Register | |
|
||||||
|
| `ISSI_GLOBALCURRENT` | (Optional) Configuration for the Global Current Register | 0xFF |
|
||||||
|
| `ISSI_PULLDOWNUP` | (Optional) Configuration for the Pull Up & Pull Down Register | |
|
||||||
|
| `ISSI_TEMP` | (Optional) Configuration for the Tempature Register | |
|
||||||
|
| `ISSI_PWM_ENABLE` | (Optional) Configuration for the PWM Enable Register | |
|
||||||
|
| `ISSI_PWM_SET` | (Optional) Configuration for the PWM Setting Register | |
|
||||||
|
| `ISSI_SCAL_RED` | (Optional) Configuration for the RED LEDs in Scaling Registers | 0xFF |
|
||||||
|
| `ISSI_SCAL_BLUE` | (Optional) Configuration for the BLUE LEDs in Scaling Registers | 0xFF |
|
||||||
|
| `ISSI_SCAL_GREEN` | (Optional) Configuration for the GREEN LEDs in Scaling Registers | 0xFF |
|
||||||
|
| `ISSI_MANUAL_SCALING` | (Optional) If you wish to configure the Scaling Registers manually | |
|
||||||
|
|
||||||
|
|
||||||
|
Defaults
|
||||||
|
|
||||||
|
| Variable | IS31FL3742A | IS31FL3743A | IS31FL3745 | IS31FL3746 |
|
||||||
|
|----------|-------------|-------------|------------|------------|
|
||||||
|
| `DRIVER_ADDR_1` | 0b0110000 | 0b0100000 | 0b0100000 | 0b1100000 |
|
||||||
|
| `ISSI_SSR_1` | 0x00 | 0x00 / 0x60 | 0x00 / 0xC0 | 0x00 |
|
||||||
|
| `ISSI_SSR_<2-4>` | 0x00 | 0x40 | 0x80 | 0x00 |
|
||||||
|
| `ISSI_CONFIGURATION` | 0x31 | 0x01 | 0x31 | 0x01 |
|
||||||
|
| `ISSI_PULLDOWNUP` | 0x55 | 0x33 | 0x33 | 0x33 |
|
||||||
|
| `ISSI_TEMP` | N/A | 0x00 | 0x00 | 0x00 |
|
||||||
|
| `ISSI_PWM_ENABLE` | N/A | N/A | N/A | 0x00 |
|
||||||
|
| `ISSI_PWM_SET` | 0x00 | N/A | N/A | 0x00 |
|
||||||
|
|
||||||
|
Here is an example using 2 drivers.
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define DRIVER_ADDR_2 0b0100001
|
||||||
|
|
||||||
|
#define DRIVER_COUNT 2
|
||||||
|
#define DRIVER_1_LED_TOTAL 66
|
||||||
|
#define DRIVER_2_LED_TOTAL 42
|
||||||
|
#define DRIVER_LED_TOTAL (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
|
||||||
|
```
|
||||||
|
|
||||||
|
!> Note the parentheses, this is so when `DRIVER_LED_TOTAL` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`.
|
||||||
|
|
||||||
|
Currently only 4 drivers are supported, but it would be trivial to support for more. Note that using a combination of different drivers is not supported. All drivers must be of the same model.
|
||||||
|
|
||||||
|
Define these arrays listing all the LEDs in your `<keyboard>.c`:
|
||||||
|
|
||||||
|
```c
|
||||||
|
const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = {
|
||||||
|
/* Refer to IS31 manual for these locations
|
||||||
|
* driver
|
||||||
|
* | R location
|
||||||
|
* | | G location
|
||||||
|
* | | | B location
|
||||||
|
* | | | | */
|
||||||
|
{0, CS1_SW1, CS2_SW1, CS3_SW1},
|
||||||
|
....
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Where `CSx_SWx` is the location of the LED in the matrix defined by the datasheet. The `driver` is the index of the driver you defined in your `config.h` (`0`, `1`, `2`, or `3` for now).
|
||||||
|
|
||||||
|
`ISSI_MANUAL_SCALING` is used to override the Scaling for individual LED's. By default they will be set as per `ISSI_SCAL_<colour>`. In `config.h` set how many LED's you want to manually set scaling for.
|
||||||
|
Eg `#define ISSI_MANUAL_SCALING 3`
|
||||||
|
|
||||||
|
Then Define the array listing all the LEDs you want to override in your `<keyboard>.c`:
|
||||||
|
|
||||||
|
```c
|
||||||
|
const is31_led __flash g_is31_scaling[ISSI_MANUAL_SCALING] = {
|
||||||
|
* LED Index
|
||||||
|
* | R scaling
|
||||||
|
* | | G scaling
|
||||||
|
* | | | B scaling
|
||||||
|
* | | | | */
|
||||||
|
{5, 120, 155, 167},
|
||||||
|
{9, 120, 155, 167},
|
||||||
|
....
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Where LED Index is the position of the LED in the `g_is31_leds` array. The `scaling` value between 0 and 255 to be written to the Scaling Register.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### WS2812 :id=ws2812
|
### WS2812 :id=ws2812
|
||||||
|
@ -457,6 +566,7 @@ enum rgb_matrix_effects {
|
||||||
RGB_MATRIX_HUE_PENDULUM, // Hue shifts up a slight ammount in a wave to the right, then back to the left
|
RGB_MATRIX_HUE_PENDULUM, // Hue shifts up a slight ammount in a wave to the right, then back to the left
|
||||||
RGB_MATRIX_HUE_WAVE, // Hue shifts up a slight ammount and then back down in a wave to the right
|
RGB_MATRIX_HUE_WAVE, // Hue shifts up a slight ammount and then back down in a wave to the right
|
||||||
RGB_MATRIX_PIXEL_FRACTAL, // Single hue fractal filled keys pulsing horizontally out to edges
|
RGB_MATRIX_PIXEL_FRACTAL, // Single hue fractal filled keys pulsing horizontally out to edges
|
||||||
|
RGB_MATRIX_PIXEL_FLOW, // Pulsing RGB flow along LED wiring with random hues
|
||||||
RGB_MATRIX_PIXEL_RAIN, // Randomly light keys with random hues
|
RGB_MATRIX_PIXEL_RAIN, // Randomly light keys with random hues
|
||||||
#if define(RGB_MATRIX_FRAMEBUFFER_EFFECTS)
|
#if define(RGB_MATRIX_FRAMEBUFFER_EFFECTS)
|
||||||
RGB_MATRIX_TYPING_HEATMAP, // How hot is your WPM!
|
RGB_MATRIX_TYPING_HEATMAP, // How hot is your WPM!
|
||||||
|
@ -512,6 +622,7 @@ You can enable a single effect by defining `ENABLE_[EFFECT_NAME]` in your `confi
|
||||||
|`#define ENABLE_RGB_MATRIX_HUE_PENDULUM` |Enables `RGB_MATRIX_HUE_PENDULUM` |
|
|`#define ENABLE_RGB_MATRIX_HUE_PENDULUM` |Enables `RGB_MATRIX_HUE_PENDULUM` |
|
||||||
|`#define ENABLE_RGB_MATRIX_HUE_WAVE` |Enables `RGB_MATRIX_HUE_WAVE ` |
|
|`#define ENABLE_RGB_MATRIX_HUE_WAVE` |Enables `RGB_MATRIX_HUE_WAVE ` |
|
||||||
|`#define ENABLE_RGB_MATRIX_PIXEL_FRACTAL` |Enables `RGB_MATRIX_PIXEL_FRACTAL` |
|
|`#define ENABLE_RGB_MATRIX_PIXEL_FRACTAL` |Enables `RGB_MATRIX_PIXEL_FRACTAL` |
|
||||||
|
|`#define ENABLE_RGB_MATRIX_PIXEL_FLOW` |Enables `RGB_MATRIX_PIXEL_FLOW` |
|
||||||
|`#define ENABLE_RGB_MATRIX_PIXEL_RAIN` |Enables `RGB_MATRIX_PIXEL_RAIN` |
|
|`#define ENABLE_RGB_MATRIX_PIXEL_RAIN` |Enables `RGB_MATRIX_PIXEL_RAIN` |
|
||||||
|
|
||||||
?> These modes don't require any additional defines.
|
?> These modes don't require any additional defines.
|
||||||
|
@ -707,6 +818,7 @@ Where `28` is an unused index from `eeconfig.h`.
|
||||||
|`rgb_matrix_decrease_speed_noeeprom()` |Decrease the speed of the animations (not written to EEPROM) |
|
|`rgb_matrix_decrease_speed_noeeprom()` |Decrease the speed of the animations (not written to EEPROM) |
|
||||||
|`rgb_matrix_set_speed(speed)` |Set the speed of the animations to the given value where `speed` is between 0 and 255 |
|
|`rgb_matrix_set_speed(speed)` |Set the speed of the animations to the given value where `speed` is between 0 and 255 |
|
||||||
|`rgb_matrix_set_speed_noeeprom(speed)` |Set the speed of the animations to the given value where `speed` is between 0 and 255 (not written to EEPROM) |
|
|`rgb_matrix_set_speed_noeeprom(speed)` |Set the speed of the animations to the given value where `speed` is between 0 and 255 (not written to EEPROM) |
|
||||||
|
|`rgb_matrix_reload_from_eeprom()` |Reload the effect configuration (enabled, mode and color) from EEPROM |
|
||||||
|
|
||||||
### Change Color :id=change-color
|
### Change Color :id=change-color
|
||||||
|Function |Description |
|
|Function |Description |
|
||||||
|
|
|
@ -273,6 +273,14 @@ This enables transmitting the current OLED on/off status to the slave side of th
|
||||||
|
|
||||||
This enables transmitting the current ST7565 on/off status to the slave side of the split keyboard. The purpose of this feature is to support state (on/off state only) syncing.
|
This enables transmitting the current ST7565 on/off status to the slave side of the split keyboard. The purpose of this feature is to support state (on/off state only) syncing.
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define SPLIT_POINTING_ENABLE
|
||||||
|
```
|
||||||
|
|
||||||
|
This enables transmitting the pointing device status to the master side of the split keyboard. The purpose of this feature is to enable use pointing devices on the slave side.
|
||||||
|
|
||||||
|
!> There is additional required configuration for `SPLIT_POINTING_ENABLE` outlined in the [pointing device documentation](feature_pointing_device.md?id=split-keyboard-configuration).
|
||||||
|
|
||||||
### Custom data sync between sides :id=custom-data-sync
|
### Custom data sync between sides :id=custom-data-sync
|
||||||
|
|
||||||
QMK's split transport allows for arbitrary data transactions at both the keyboard and user levels. This is modelled on a remote procedure call, with the master invoking a function on the slave side, with the ability to send data from master to slave, process it slave side, and send data back from slave to master.
|
QMK's split transport allows for arbitrary data transactions at both the keyboard and user levels. This is modelled on a remote procedure call, with the master invoking a function on the slave side, with the ability to send data from master to slave, process it slave side, and send data back from slave to master.
|
||||||
|
|
|
@ -16,7 +16,7 @@ For split keyboards using soft serial, the computed WPM score will be available
|
||||||
| `WPM_ALLOW_COUNT_REGRESSION` | _Not defined_ | If defined allows the WPM to be decreased when hitting Delete or Backspace |
|
| `WPM_ALLOW_COUNT_REGRESSION` | _Not defined_ | If defined allows the WPM to be decreased when hitting Delete or Backspace |
|
||||||
| `WPM_UNFILTERED` | _Not defined_ | If undefined (the default), WPM values will be smoothed to avoid sudden changes in value |
|
| `WPM_UNFILTERED` | _Not defined_ | If undefined (the default), WPM values will be smoothed to avoid sudden changes in value |
|
||||||
| `WPM_SAMPLE_SECONDS` | `5` | This defines how many seconds of typing to average, when calculating WPM |
|
| `WPM_SAMPLE_SECONDS` | `5` | This defines how many seconds of typing to average, when calculating WPM |
|
||||||
| `WPM_SAMPLE_PERIODS` | `50` | This defines how many sampling periods to use when calculating WPM |
|
| `WPM_SAMPLE_PERIODS` | `25` | This defines how many sampling periods to use when calculating WPM |
|
||||||
| `WPM_LAUNCH_CONTROL` | _Not defined_ | If defined, WPM values will be calculated using partial buffers when typing begins |
|
| `WPM_LAUNCH_CONTROL` | _Not defined_ | If defined, WPM values will be calculated using partial buffers when typing begins |
|
||||||
|
|
||||||
'WPM_UNFILTERED' is potentially useful if you're filtering data in some other way (and also because it reduces the code required for the WPM feature), or if reducing measurement latency to a minimum is important for you.
|
'WPM_UNFILTERED' is potentially useful if you're filtering data in some other way (and also because it reduces the code required for the WPM feature), or if reducing measurement latency to a minimum is important for you.
|
||||||
|
|
24
docs/flash_driver.md
Normal file
24
docs/flash_driver.md
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# FLASH Driver Configuration :id=flash-driver-configuration
|
||||||
|
|
||||||
|
The FLASH driver can be swapped out depending on the needs of the keyboard, or whether extra hardware is present.
|
||||||
|
|
||||||
|
Driver | Description
|
||||||
|
-----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
`FLASH_DRIVER = spi` | Supports writing to almost all NOR Flash chips. See the driver section below.
|
||||||
|
|
||||||
|
|
||||||
|
## SPI FLASH Driver Configuration :id=spi-flash-driver-configuration
|
||||||
|
|
||||||
|
Currently QMK supports almost all NOR Flash chips over SPI. As such, requires a working spi_master driver configuration. You can override the driver configuration via your config.h:
|
||||||
|
|
||||||
|
`config.h` override | Description | Default Value
|
||||||
|
-----------------------------------------------|--------------------------------------------------------------------------------------|-----------------
|
||||||
|
`#define EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN` | SPI Slave select pin in order to inform that the FLASH is currently being addressed | _none_
|
||||||
|
`#define EXTERNAL_FLASH_SPI_CLOCK_DIVISOR` | Clock divisor used to divide the peripheral clock to derive the SPI frequency | `8`
|
||||||
|
`#define EXTERNAL_FLASH_PAGE_SIZE` | The Page size of the FLASH in bytes, as specified in the datasheet | `256`
|
||||||
|
`#define EXTERNAL_FLASH_SECTOR_SIZE` | The sector size of the FLASH in bytes, as specified in the datasheet | `(4 * 1024)`
|
||||||
|
`#define EXTERNAL_FLASH_BLOCK_SIZE` | The block size of the FLASH in bytes, as specified in the datasheet | `(64 * 1024)`
|
||||||
|
`#define EXTERNAL_FLASH_SIZE` | The total size of the FLASH in bytes, as specified in the datasheet | `(512 * 1024)`
|
||||||
|
`#define EXTERNAL_FLASH_ADDRESS_SIZE` | The Flash address size in bytes, as specified in datasheet | `3`
|
||||||
|
|
||||||
|
!> All the above default configurations are based on MX25L4006E NOR Flash.
|
|
@ -1,182 +0,0 @@
|
||||||
# Keyboards with AVR Processors
|
|
||||||
|
|
||||||
This page describes the support for AVR processors in QMK. AVR processors include the atmega32u4, atmega32u2, at90usb1286, and other processors from Atmel Corporation. AVR processors are 8-bit MCUs that are designed to be easy to work with. The most common AVR processors in keyboards have on-board USB and plenty of GPIO for supporting large keyboard matrices. They are the most popular MCU for use in keyboards today.
|
|
||||||
|
|
||||||
If you have not yet you should read the [Keyboard Guidelines](hardware_keyboard_guidelines.md) to get a sense of how keyboards fit into QMK.
|
|
||||||
|
|
||||||
## Adding Your AVR Keyboard to QMK
|
|
||||||
|
|
||||||
QMK has a number of features to simplify working with AVR keyboards. For most keyboards you don't have to write a single line of code. To get started, run `qmk new-keyboard`:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ qmk new-keyboard
|
|
||||||
Ψ Generating a new QMK keyboard directory
|
|
||||||
|
|
||||||
Keyboard Name: mycoolkeeb
|
|
||||||
Keyboard Type:
|
|
||||||
1. avr
|
|
||||||
2. ps2avrgb
|
|
||||||
Please enter your choice: [1]
|
|
||||||
Your Name: [John Smith]
|
|
||||||
Ψ Copying base template files...
|
|
||||||
Ψ Copying avr template files...
|
|
||||||
Ψ Renaming keyboard.[ch] to mycoolkeeb.[ch]...
|
|
||||||
Ψ Replacing %YEAR% with 2021...
|
|
||||||
Ψ Replacing %KEYBOARD% with mycoolkeeb...
|
|
||||||
Ψ Replacing %YOUR_NAME% with John Smith...
|
|
||||||
|
|
||||||
Ψ Created a new keyboard called mycoolkeeb.
|
|
||||||
Ψ To start working on things, `cd` into keyboards/mycoolkeeb,
|
|
||||||
Ψ or open the directory in your preferred text editor.
|
|
||||||
```
|
|
||||||
|
|
||||||
This will create all the files needed to support your new keyboard, and populate the settings with default values. Now you just need to customize it for your keyboard.
|
|
||||||
|
|
||||||
## `readme.md`
|
|
||||||
|
|
||||||
This is where you'll describe your keyboard. Please follow the [Keyboard Readme Template](documentation_templates.md#keyboard-readmemd-template) when writing your `readme.md`. You're encouraged to place an image at the top of your `readme.md`, please use an external service such as [Imgur](https://imgur.com) to host the images.
|
|
||||||
|
|
||||||
## `<keyboard>.c`
|
|
||||||
|
|
||||||
This is where all the custom logic for your keyboard goes. Many keyboards do not need to put anything at all in here. You can learn more about writing custom logic in [Custom Quantum Functions](custom_quantum_functions.md).
|
|
||||||
|
|
||||||
## `<keyboard>.h`
|
|
||||||
|
|
||||||
This is the file you define your [Layout Macro(s)](feature_layouts.md) in. At minimum you should have a `#define LAYOUT` for your keyboard that looks something like this:
|
|
||||||
|
|
||||||
```c
|
|
||||||
#define LAYOUT( \
|
|
||||||
k00, k01, k02, \
|
|
||||||
k10, k11 \
|
|
||||||
) { \
|
|
||||||
{ k00, k01, k02 }, \
|
|
||||||
{ k10, KC_NO, k11 }, \
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The first half of the `LAYOUT` pre-processor macro defines the physical arrangement of keys. The second half of the macro defines the matrix the switches are connected to. This allows you to have a physical arrangement of keys that differs from the wiring matrix.
|
|
||||||
|
|
||||||
Each of the `k__` variables needs to be unique, and typically they follow the format `k<row><col>`.
|
|
||||||
|
|
||||||
The physical matrix (the second half) must have a number of rows equaling `MATRIX_ROWS`, and each row must have exactly `MATRIX_COLS` elements in it. If you do not have this many physical keys you can use `KC_NO` to fill in the blank spots.
|
|
||||||
|
|
||||||
## `config.h`
|
|
||||||
|
|
||||||
The `config.h` file is where you configure the hardware and feature set for your keyboard. There are a lot of options that can be placed in that file, too many to list there. For a complete overview of available options see the [Config Options](config_options.md) page.
|
|
||||||
|
|
||||||
### Hardware Configuration
|
|
||||||
|
|
||||||
|
|
||||||
At the top of the `config.h` you'll find USB related settings. These control how your keyboard appears to the Operating System. If you don't have a good reason to change you should leave the `VENDOR_ID` as `0xFEED`. For the `PRODUCT_ID` you should pick a number that is not yet in use.
|
|
||||||
|
|
||||||
Do change the `MANUFACTURER` and `PRODUCT` lines to accurately reflect your keyboard.
|
|
||||||
|
|
||||||
```c
|
|
||||||
#define VENDOR_ID 0xFEED
|
|
||||||
#define PRODUCT_ID 0x6060
|
|
||||||
#define DEVICE_VER 0x0001
|
|
||||||
#define MANUFACTURER You
|
|
||||||
#define PRODUCT my_awesome_keyboard
|
|
||||||
```
|
|
||||||
|
|
||||||
?> Windows and macOS will display the `MANUFACTURER` and `PRODUCT` in the list of USB devices. `lsusb` on Linux instead prefers the values in the list maintained by the [USB ID Repository](http://www.linux-usb.org/usb-ids.html). By default, it will only use `MANUFACTURER` and `PRODUCT` if the list does not contain that `VENDOR_ID` / `PRODUCT_ID`. `sudo lsusb -v` will show the values reported by the device, and they are also present in kernel logs after plugging it in.
|
|
||||||
|
|
||||||
### Keyboard Matrix Configuration
|
|
||||||
|
|
||||||
The next section of the `config.h` file deals with your keyboard's matrix. The first thing you should set is the matrix's size. This is usually, but not always, the same number of rows and columns as the physical key arrangement.
|
|
||||||
|
|
||||||
```c
|
|
||||||
#define MATRIX_ROWS 2
|
|
||||||
#define MATRIX_COLS 3
|
|
||||||
```
|
|
||||||
|
|
||||||
Once you've defined the size of your matrix you need to define which pins on your MCU are connected to rows and columns. To do so simply specify the names of those pins:
|
|
||||||
|
|
||||||
```c
|
|
||||||
#define MATRIX_ROW_PINS { D0, D5 }
|
|
||||||
#define MATRIX_COL_PINS { F1, F0, B0 }
|
|
||||||
#define UNUSED_PINS
|
|
||||||
```
|
|
||||||
|
|
||||||
The number of `MATRIX_ROW_PINS` entries must be the same as the number you assigned to `MATRIX_ROWS`, and likewise for `MATRIX_COL_PINS` and `MATRIX_COLS`. You do not have to specify `UNUSED_PINS`, but you can if you want to document what pins are open.
|
|
||||||
|
|
||||||
Finally, you can specify the direction your diodes point. This can be `COL2ROW` or `ROW2COL`.
|
|
||||||
|
|
||||||
```c
|
|
||||||
#define DIODE_DIRECTION COL2ROW
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Direct Pin Matrix
|
|
||||||
To configure a keyboard where each switch is connected to a separate pin and ground instead of sharing row and column pins, use `DIRECT_PINS`. The mapping defines the pins of each switch in rows and columns, from left to right. Must conform to the sizes within `MATRIX_ROWS` and `MATRIX_COLS`, use `NO_PIN` to fill in blank spaces. Overrides the behaviour of `DIODE_DIRECTION`, `MATRIX_ROW_PINS` and `MATRIX_COL_PINS`.
|
|
||||||
|
|
||||||
```c
|
|
||||||
// #define MATRIX_ROW_PINS { D0, D5 }
|
|
||||||
// #define MATRIX_COL_PINS { F1, F0, B0 }
|
|
||||||
#define DIRECT_PINS { \
|
|
||||||
{ F1, E6, B0, B2, B3 }, \
|
|
||||||
{ F5, F0, B1, B7, D2 }, \
|
|
||||||
{ F6, F7, C7, D5, D3 }, \
|
|
||||||
{ B5, C6, B6, NO_PIN, NO_PIN } \
|
|
||||||
}
|
|
||||||
#define UNUSED_PINS
|
|
||||||
|
|
||||||
/* COL2ROW, ROW2COL */
|
|
||||||
//#define DIODE_DIRECTION
|
|
||||||
```
|
|
||||||
|
|
||||||
### Backlight Configuration
|
|
||||||
|
|
||||||
QMK supports backlighting on most GPIO pins. A select few of these can be driven by the MCU in hardware. For more details see the [Backlight Documentation](feature_backlight.md).
|
|
||||||
|
|
||||||
```c
|
|
||||||
#define BACKLIGHT_PIN B7
|
|
||||||
#define BACKLIGHT_LEVELS 3
|
|
||||||
#define BACKLIGHT_BREATHING
|
|
||||||
#define BREATHING_PERIOD 6
|
|
||||||
```
|
|
||||||
|
|
||||||
### Other Configuration Options
|
|
||||||
|
|
||||||
There are a lot of features that can be configured or tuned in `config.h`. You should see the [Config Options](config_options.md) page for more details.
|
|
||||||
|
|
||||||
## `rules.mk`
|
|
||||||
|
|
||||||
You use the `rules.mk` file to tell QMK what files to build and what features to enable. If you are building around an atmega32u4 you can largely leave these defaults alone. If you are using another MCU you may have to tweak some parameters.
|
|
||||||
|
|
||||||
### MCU Options
|
|
||||||
|
|
||||||
These options tell the build system what CPU to build for. Be very careful if you change any of these settings, you can render your keyboard inoperable.
|
|
||||||
|
|
||||||
```make
|
|
||||||
MCU = atmega32u4
|
|
||||||
F_CPU = 16000000
|
|
||||||
ARCH = AVR8
|
|
||||||
F_USB = $(F_CPU)
|
|
||||||
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
|
|
||||||
```
|
|
||||||
|
|
||||||
### Bootloaders
|
|
||||||
|
|
||||||
The bootloader is a special section of your MCU that allows you to upgrade the code stored on the MCU. Think of it like a Rescue Partition for your keyboard.
|
|
||||||
|
|
||||||
#### Teensy Bootloader Example
|
|
||||||
|
|
||||||
```make
|
|
||||||
BOOTLOADER = halfkay
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Atmel DFU Loader Example
|
|
||||||
|
|
||||||
```make
|
|
||||||
BOOTLOADER = atmel-dfu
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Pro Micro Bootloader Example
|
|
||||||
|
|
||||||
```make
|
|
||||||
BOOTLOADER = caterina
|
|
||||||
```
|
|
||||||
|
|
||||||
### Build Options
|
|
||||||
|
|
||||||
There are a number of features that can be turned on or off in `rules.mk`. See the [Config Options](config_options.md#feature-options) page for a detailed list and description.
|
|
|
@ -39,7 +39,6 @@
|
||||||
'/glossary': '/reference_glossary',
|
'/glossary': '/reference_glossary',
|
||||||
'/key_lock': '/feature_key_lock',
|
'/key_lock': '/feature_key_lock',
|
||||||
'/make_instructions': '/getting_started_make_guide',
|
'/make_instructions': '/getting_started_make_guide',
|
||||||
'/porting_your_keyboard_to_qmk': '/hardware_avr',
|
|
||||||
'/space_cadet_shift': '/feature_space_cadet_shift',
|
'/space_cadet_shift': '/feature_space_cadet_shift',
|
||||||
'/getting_started_getting_help': '/support',
|
'/getting_started_getting_help': '/support',
|
||||||
'/tap_dance': '/feature_tap_dance',
|
'/tap_dance': '/feature_tap_dance',
|
||||||
|
|
|
@ -6,17 +6,19 @@ QMK has a GPIO control abstraction layer which is microcontroller agnostic. This
|
||||||
|
|
||||||
The following functions provide basic control of GPIOs and are found in `platforms/<platform>/gpio.h`.
|
The following functions provide basic control of GPIOs and are found in `platforms/<platform>/gpio.h`.
|
||||||
|
|
||||||
|Function |Description | Old AVR Examples | Old ChibiOS/ARM Examples |
|
| Function | Description | Old AVR Examples | Old ChibiOS/ARM Examples |
|
||||||
|------------------------|--------------------------------------------------|-------------------------------------------------|-------------------------------------------------|
|
|------------------------------|-----------------------------------------------------|-------------------------------------------------|--------------------------------------------------|
|
||||||
| `setPinInput(pin)` | Set pin as input with high impedance (High-Z) | `DDRB &= ~(1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT)` |
|
| `setPinInput(pin)` | Set pin as input with high impedance (High-Z) | `DDRB &= ~(1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT)` |
|
||||||
| `setPinInputHigh(pin)` | Set pin as input with builtin pull-up resistor | `DDRB &= ~(1<<2); PORTB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT_PULLUP)` |
|
| `setPinInputHigh(pin)` | Set pin as input with builtin pull-up resistor | `DDRB &= ~(1<<2); PORTB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT_PULLUP)` |
|
||||||
| `setPinInputLow(pin)` | Set pin as input with builtin pull-down resistor | N/A (Not supported on AVR) | `palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN)` |
|
| `setPinInputLow(pin)` | Set pin as input with builtin pull-down resistor | N/A (Not supported on AVR) | `palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN)` |
|
||||||
| `setPinOutput(pin)` | Set pin as output | `DDRB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)` |
|
| `setPinOutput(pin)` | Set pin as output (alias of `setPinOutputPushPull`) | `DDRB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)` |
|
||||||
| `writePinHigh(pin)` | Set pin level as high, assuming it is an output | `PORTB \|= (1<<2)` | `palSetLine(pin)` |
|
| `setPinOutputPushPull(pin)` | Set pin as output, push/pull mode | `DDRB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)` |
|
||||||
| `writePinLow(pin)` | Set pin level as low, assuming it is an output | `PORTB &= ~(1<<2)` | `palClearLine(pin)` |
|
| `setPinOutputOpenDrain(pin)` | Set pin as output, open-drain mode | N/A (Not implemented on AVR) | `palSetLineMode(pin, PAL_MODE_OUTPUT_OPENDRAIN)` |
|
||||||
| `writePin(pin, level)` | Set pin level, assuming it is an output | `(level) ? PORTB \|= (1<<2) : PORTB &= ~(1<<2)` | `(level) ? palSetLine(pin) : palClearLine(pin)` |
|
| `writePinHigh(pin)` | Set pin level as high, assuming it is an output | `PORTB \|= (1<<2)` | `palSetLine(pin)` |
|
||||||
| `readPin(pin)` | Returns the level of the pin | `_SFR_IO8(pin >> 4) & _BV(pin & 0xF)` | `palReadLine(pin)` |
|
| `writePinLow(pin)` | Set pin level as low, assuming it is an output | `PORTB &= ~(1<<2)` | `palClearLine(pin)` |
|
||||||
| `togglePin(pin)` | Invert pin level, assuming it is an output | `PORTB ^= (1<<2)` | `palToggleLine(pin)` |
|
| `writePin(pin, level)` | Set pin level, assuming it is an output | `(level) ? PORTB \|= (1<<2) : PORTB &= ~(1<<2)` | `(level) ? palSetLine(pin) : palClearLine(pin)` |
|
||||||
|
| `readPin(pin)` | Returns the level of the pin | `_SFR_IO8(pin >> 4) & _BV(pin & 0xF)` | `palReadLine(pin)` |
|
||||||
|
| `togglePin(pin)` | Invert pin level, assuming it is an output | `PORTB ^= (1<<2)` | `palToggleLine(pin)` |
|
||||||
|
|
||||||
## Advanced Settings :id=advanced-settings
|
## Advanced Settings :id=advanced-settings
|
||||||
|
|
||||||
|
|
|
@ -219,11 +219,11 @@ 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 |
|
||||||
|--------------|---------|-------------------------------------------------------|
|
|-----------------|---------|-------------------------------------------------------|
|
||||||
|`RESET` | |Put the keyboard into bootloader mode for flashing |
|
|`QK_BOOTLOADER` |`QK_BOOT`|Put the keyboard into bootloader mode for flashing |
|
||||||
|`DEBUG` | |Toggle debug mode |
|
|`QK_DEBUG_TOGGLE`|`DB_TOGG`|Toggle debug mode |
|
||||||
|`EEPROM_RESET`|`EEP_RST`|Reinitializes the keyboard's EEPROM (persistent memory)|
|
|`QK_CLEAR_EEPROM`|`EE_CLR` |Reinitializes the keyboard's EEPROM (persistent memory)|
|
||||||
|
|
||||||
## Audio Keys :id=audio-keys
|
## Audio Keys :id=audio-keys
|
||||||
|
|
||||||
|
@ -283,9 +283,9 @@ See also: [Dynamic Macros](feature_dynamic_macros.md)
|
||||||
|
|
||||||
See also: [Grave Escape](feature_grave_esc.md)
|
See also: [Grave Escape](feature_grave_esc.md)
|
||||||
|
|
||||||
|Key |Aliases |Description |
|
|Key |Aliases |Description |
|
||||||
|-----------|---------|------------------------------------------------------------------|
|
|-----------------|---------|------------------------------------------------------------------|
|
||||||
|`GRAVE_ESC`|`KC_GESC`|Escape when pressed, <code>`</code> when Shift or GUI are held|
|
|`QK_GRAVE_ESCAPE`|`QK_GESC`|Escape when pressed, <code>`</code> when Shift or GUI are held|
|
||||||
|
|
||||||
## Key Lock :id=key-lock
|
## Key Lock :id=key-lock
|
||||||
|
|
||||||
|
@ -326,6 +326,7 @@ 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_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 |
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|----------------------------------|---------|--------------------------------------------------------------------------|
|
|----------------------------------|---------|--------------------------------------------------------------------------|
|
||||||
|`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_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 |
|
||||||
|
|
|
@ -136,7 +136,7 @@ After this you'll find a list of LAYOUT() macros. A LAYOUT() is simply a list of
|
||||||
|
|
||||||
`keymaps[][MATRIX_ROWS][MATRIX_COLS]` in QMK holds the 16 bit action code (sometimes referred as the quantum keycode) in it. For the keycode representing typical keys, its high byte is 0 and its low byte is the USB HID usage ID for keyboard.
|
`keymaps[][MATRIX_ROWS][MATRIX_COLS]` in QMK holds the 16 bit action code (sometimes referred as the quantum keycode) in it. For the keycode representing typical keys, its high byte is 0 and its low byte is the USB HID usage ID for keyboard.
|
||||||
|
|
||||||
> TMK from which QMK was forked uses `const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS]` instead and holds the 8 bit keycode. Some keycode values are reserved to induce execution of certain action codes via the `fn_actions[]` array.
|
> TMK from which QMK was forked uses `const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS]` instead and holds the 8 bit keycode.
|
||||||
|
|
||||||
#### Base Layer
|
#### Base Layer
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@ As such, if you wish to override this API consider limiting use to writing to lo
|
||||||
| `config.h` override | Description | Default |
|
| `config.h` override | Description | Default |
|
||||||
|-----------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|
|
|-----------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|
|
||||||
| `#define EARLY_INIT_PERFORM_BOOTLOADER_JUMP` | Whether or not bootloader is to be executed during the early initialisation code of QMK. | `FALSE` |
|
| `#define EARLY_INIT_PERFORM_BOOTLOADER_JUMP` | Whether or not bootloader is to be executed during the early initialisation code of QMK. | `FALSE` |
|
||||||
| `#define STM32_BOOTLOADER_ADDRESS` | Relevant for single-bank STM32 MCUs, signifies the memory address to jump to bootloader. Consult [AN2606](https://www.st.com/content/st_com/en/search.html#q=an2606-t=resources-page=1) for the _System Memory_ address for your MCU. This value should be of the format `0x11111111`. | `<none>` |
|
|
||||||
| `#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` |
|
||||||
|
|
163
docs/porting_your_keyboard_to_qmk.md
Normal file
163
docs/porting_your_keyboard_to_qmk.md
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
# Adding Your Keyboard to QMK
|
||||||
|
|
||||||
|
This page describes the support for [Compatible Microcontrollers](compatible_microcontrollers.md) in QMK.
|
||||||
|
|
||||||
|
If you have not yet you should read the [Keyboard Guidelines](hardware_keyboard_guidelines.md) to get a sense of how keyboards fit into QMK.
|
||||||
|
|
||||||
|
|
||||||
|
QMK has a number of features to simplify working with keyboards. For most, you don't have to write a single line of code. To get started, run `qmk new-keyboard`:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ qmk new-keyboard
|
||||||
|
Ψ Generating a new QMK keyboard directory
|
||||||
|
|
||||||
|
Name Your Keyboard Project
|
||||||
|
For more infomation, see:
|
||||||
|
https://docs.qmk.fm/#/hardware_keyboard_guidelines?id=naming-your-keyboardproject
|
||||||
|
|
||||||
|
keyboard Name? mycoolkeeb
|
||||||
|
|
||||||
|
Attribution
|
||||||
|
Used for maintainer, copyright, etc
|
||||||
|
|
||||||
|
Your GitHub Username? [jsmith]
|
||||||
|
|
||||||
|
More Attribution
|
||||||
|
Used for maintainer, copyright, etc
|
||||||
|
|
||||||
|
Your Real Name? [John Smith]
|
||||||
|
|
||||||
|
Pick Base Layout
|
||||||
|
As a starting point, one of the common layouts can be used to bootstrap the process
|
||||||
|
|
||||||
|
Default Layout?
|
||||||
|
1. 60_ansi
|
||||||
|
...
|
||||||
|
50. tkl_iso
|
||||||
|
51. none of the above
|
||||||
|
Please enter your choice: [51]
|
||||||
|
|
||||||
|
What Powers Your Project
|
||||||
|
For more infomation, see:
|
||||||
|
https://docs.qmk.fm/#/compatible_microcontrollers
|
||||||
|
|
||||||
|
MCU?
|
||||||
|
1. atmega32u4
|
||||||
|
...
|
||||||
|
22. STM32F303
|
||||||
|
Please enter your choice: [12]
|
||||||
|
Ψ Created a new keyboard called mycoolkeeb.
|
||||||
|
Ψ To start working on things, `cd` into keyboards/mycoolkeeb,
|
||||||
|
Ψ or open the directory in your preferred text editor.
|
||||||
|
Ψ And build with qmk compile -kb mycoolkeeb -km default.
|
||||||
|
```
|
||||||
|
|
||||||
|
This will create all the files needed to support your new keyboard, and populate the settings with default values. Now you just need to customize it for your keyboard.
|
||||||
|
|
||||||
|
## `readme.md`
|
||||||
|
|
||||||
|
This is where you'll describe your keyboard. Please follow the [Keyboard Readme Template](documentation_templates.md#keyboard-readmemd-template) when writing your `readme.md`. You're encouraged to place an image at the top of your `readme.md`, please use an external service such as [Imgur](https://imgur.com) to host the images.
|
||||||
|
|
||||||
|
## `info.json`
|
||||||
|
|
||||||
|
The `info.json` file is where you configure the hardware and feature set for your keyboard. There are a lot of options that can be placed in that file, too many to list here. For a complete overview of available options see the [Data Driven Configuration Options](reference_info_json.md) page.
|
||||||
|
|
||||||
|
### Hardware Configuration
|
||||||
|
|
||||||
|
At the top of the `info.json` you'll find USB related settings. These control how your keyboard appears to the Operating System. If you don't have a good reason to change you should leave the `usb.vid` as `0xFEED`. For the `usb.pid` you should pick a number that is not yet in use.
|
||||||
|
|
||||||
|
Do change the `manufacturer` and `keyboard_name` lines to accurately reflect your keyboard.
|
||||||
|
|
||||||
|
```json
|
||||||
|
"keyboard_name": "my_awesome_keyboard",
|
||||||
|
"maintainer": "You",
|
||||||
|
"usb": {
|
||||||
|
"vid": "0xFEED",
|
||||||
|
"pid": "0x0000",
|
||||||
|
"device_version": "1.0.0"
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
?> Windows and macOS will display the `manufacturer` and `keyboard_name` in the list of USB devices. `lsusb` on Linux instead prefers the values in the list maintained by the [USB ID Repository](http://www.linux-usb.org/usb-ids.html). By default, it will only use `manufacturer` and `keyboard_name` if the list does not contain that `usb.vid` / `usb.pid`. `sudo lsusb -v` will show the values reported by the device, and they are also present in kernel logs after plugging it in.
|
||||||
|
|
||||||
|
|
||||||
|
### Matrix Configuration
|
||||||
|
|
||||||
|
The next section of the `info` file deals with your keyboard's matrix. The first thing you should define is which pins on your MCU are connected to rows and columns. To do so simply specify the names of those pins:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"matrix_pins": {
|
||||||
|
"cols": ["C1", "C2", "C3", "C4"],
|
||||||
|
"rows": ["D1", "D2", "D3", "D4"]
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
The size of the `matrix_pins.cols` and `matrix_pins.rows` arrays infer the size of the matrix (previously `MATRIX_ROWS` and `MATRIX_COLS`).
|
||||||
|
|
||||||
|
Finally, you can specify the direction your diodes point. This can be `COL2ROW` or `ROW2COL`.
|
||||||
|
|
||||||
|
```json
|
||||||
|
"diode_direction": "ROW2COL",
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Direct Pin Matrix
|
||||||
|
To configure a keyboard where each switch is connected to a separate pin and ground instead of sharing row and column pins, use `matrix_pins.direct`. The mapping defines the pins of each switch in rows and columns, from left to right. The size of the `matrix_pins.direct` array infers the size of the matrix. Use `NO_PIN` to fill in blank spaces. Overrides the behaviour of `diode_direction`, `matrix_pins.cols` and `matrix_pins.rows`.
|
||||||
|
|
||||||
|
```json
|
||||||
|
"matrix_pins": {
|
||||||
|
"direct": [
|
||||||
|
["F1", "E6", "B0", "B2", "B3" ],
|
||||||
|
["F5", "F0", "B1", "B7", "D2" ],
|
||||||
|
["F6", "F7", "C7", "D5", "D3" ],
|
||||||
|
["B5", "C6", "B6", "NO_PIN", "NO_PIN"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
### Layout macros
|
||||||
|
|
||||||
|
Next is configuring Layout Macro(s). These define the physical arrangement of keys, and its position within the matrix that a switch are connected to. This allows you to have a physical arrangement of keys that differs from the wiring matrix.
|
||||||
|
|
||||||
|
```json
|
||||||
|
"layouts": {
|
||||||
|
"LAYOUT_ortho_4x4": {
|
||||||
|
"layout": [
|
||||||
|
{ "matrix": [0, 0], "x": 0, "y": 0 },
|
||||||
|
{ "matrix": [0, 1], "x": 1, "y": 0 },
|
||||||
|
{ "matrix": [0, 2], "x": 2, "y": 0 },
|
||||||
|
{ "matrix": [0, 3], "x": 3, "y": 0 },
|
||||||
|
{ "matrix": [1, 0], "x": 0, "y": 1 },
|
||||||
|
{ "matrix": [1, 1], "x": 1, "y": 1 },
|
||||||
|
{ "matrix": [1, 2], "x": 2, "y": 1 },
|
||||||
|
{ "matrix": [1, 3], "x": 3, "y": 1 },
|
||||||
|
{ "matrix": [2, 0], "x": 0, "y": 2 },
|
||||||
|
{ "matrix": [2, 1], "x": 1, "y": 2 },
|
||||||
|
{ "matrix": [2, 2], "x": 2, "y": 2 },
|
||||||
|
{ "matrix": [2, 3], "x": 3, "y": 2 },
|
||||||
|
{ "matrix": [3, 0], "x": 0, "y": 3 },
|
||||||
|
{ "matrix": [3, 1], "x": 1, "y": 3 },
|
||||||
|
{ "matrix": [3, 2], "x": 2, "y": 3 },
|
||||||
|
{ "matrix": [3, 3], "x": 3, "y": 3 }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
In the above example,
|
||||||
|
|
||||||
|
* `LAYOUT_ortho_4x4` defines the name of the layout macro
|
||||||
|
* It must conform to [hardware_keyboard_guidelines.md#ltkeyboard_namehgt]
|
||||||
|
* `"matrix": [0, 0]` defines the electrical position
|
||||||
|
|
||||||
|
## Additional Configuration
|
||||||
|
|
||||||
|
There are a lot of features that can be turned on or off, configured or tuned. Some of these have yet to be migrated over to [Data Driven Configuration](data_driven_config.md). The following sections cover the process for when an `info.json` option is unavailable.
|
||||||
|
|
||||||
|
### Configuration Options
|
||||||
|
|
||||||
|
For available options for `config.h`, you should see the [Config Options](config_options.md) page for more details.
|
||||||
|
|
||||||
|
### Build Options
|
||||||
|
|
||||||
|
For available options for `rules.mk`, see the [Config Options](config_options.md#feature-options) page for a detailed list and description.
|
|
@ -8,8 +8,8 @@ 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 |
|
||||||
|--------------|---------|-------------------------------------------------------|
|
|-----------------|---------|-------------------------------------------------------|
|
||||||
|`RESET` | |Put the keyboard into bootloader mode for flashing |
|
|`QK_BOOTLOADER` |`QK_BOOT`|Put the keyboard into bootloader mode for flashing |
|
||||||
|`DEBUG` | |Toggle debug mode |
|
|`QK_DEBUG_TOGGLE`|`DB_TOGG`|Toggle debug mode |
|
||||||
|`EEPROM_RESET`|`EEP_RST`|Reinitializes the keyboard's EEPROM (persistent memory)|
|
|`QK_CLEAR_EEPROM`|`EE_CLR` |Reinitializes the keyboard's EEPROM (persistent memory)|
|
||||||
|
|
|
@ -172,7 +172,7 @@ The following animations can be enabled:
|
||||||
|
|
||||||
### USB
|
### USB
|
||||||
|
|
||||||
Every USB keyboard needs to have its USB parmaters defined. At a minimum you need to set vid, pid, and device version.
|
Every USB keyboard needs to have its USB parameters defined. At a minimum you need to set the Vendor ID, Product ID, and device version.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
@ -181,7 +181,9 @@ Example:
|
||||||
"usb": {
|
"usb": {
|
||||||
"vid": "0xC1ED",
|
"vid": "0xC1ED",
|
||||||
"pid": "0x23B0",
|
"pid": "0x23B0",
|
||||||
"device_ver": "0x0001"
|
"device_version": "1.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The device version is a BCD (binary coded decimal) value, in the format `MMmr`, so the below value would look like `0x0100` in the generated code. This also means the maximum valid values for each part are `99.9.9`, despite it being a hexadecimal value under the hood.
|
||||||
|
|
|
@ -147,6 +147,7 @@ For RGB Matrix, these need to be explicitly enabled as well. To disable any that
|
||||||
#undef ENABLE_RGB_MATRIX_HUE_PENDULUM
|
#undef ENABLE_RGB_MATRIX_HUE_PENDULUM
|
||||||
#undef ENABLE_RGB_MATRIX_HUE_WAVE
|
#undef ENABLE_RGB_MATRIX_HUE_WAVE
|
||||||
#undef ENABLE_RGB_MATRIX_PIXEL_FRACTAL
|
#undef ENABLE_RGB_MATRIX_PIXEL_FRACTAL
|
||||||
|
#undef ENABLE_RGB_MATRIX_PIXEL_FLOW
|
||||||
#undef ENABLE_RGB_MATRIX_PIXEL_RAIN
|
#undef ENABLE_RGB_MATRIX_PIXEL_RAIN
|
||||||
|
|
||||||
#undef ENABLE_RGB_MATRIX_TYPING_HEATMAP
|
#undef ENABLE_RGB_MATRIX_TYPING_HEATMAP
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "adafruit_ble.h"
|
#include "bluefruit_le.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -16,20 +16,20 @@
|
||||||
// These are the pin assignments for the 32u4 boards.
|
// These are the pin assignments for the 32u4 boards.
|
||||||
// You may define them to something else in your config.h
|
// You may define them to something else in your config.h
|
||||||
// if yours is wired up differently.
|
// if yours is wired up differently.
|
||||||
#ifndef ADAFRUIT_BLE_RST_PIN
|
#ifndef BLUEFRUIT_LE_RST_PIN
|
||||||
# define ADAFRUIT_BLE_RST_PIN D4
|
# define BLUEFRUIT_LE_RST_PIN D4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ADAFRUIT_BLE_CS_PIN
|
#ifndef BLUEFRUIT_LE_CS_PIN
|
||||||
# define ADAFRUIT_BLE_CS_PIN B4
|
# define BLUEFRUIT_LE_CS_PIN B4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ADAFRUIT_BLE_IRQ_PIN
|
#ifndef BLUEFRUIT_LE_IRQ_PIN
|
||||||
# define ADAFRUIT_BLE_IRQ_PIN E6
|
# define BLUEFRUIT_LE_IRQ_PIN E6
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ADAFRUIT_BLE_SCK_DIVISOR
|
#ifndef BLUEFRUIT_LE_SCK_DIVISOR
|
||||||
# define ADAFRUIT_BLE_SCK_DIVISOR 2 // 4MHz SCK/8MHz CPU, calculated for Feather 32U4 BLE
|
# define BLUEFRUIT_LE_SCK_DIVISOR 2 // 4MHz SCK/8MHz CPU, calculated for Feather 32U4 BLE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SAMPLE_BATTERY
|
#define SAMPLE_BATTERY
|
||||||
|
@ -77,10 +77,10 @@ struct sdep_msg {
|
||||||
// information here.
|
// information here.
|
||||||
|
|
||||||
enum queue_type {
|
enum queue_type {
|
||||||
QTKeyReport, // 1-byte modifier + 6-byte key report
|
QTKeyReport, // 1-byte modifier + 6-byte key report
|
||||||
QTConsumer, // 16-bit key code
|
QTConsumer, // 16-bit key code
|
||||||
#ifdef MOUSE_ENABLE
|
#ifdef MOUSE_ENABLE
|
||||||
QTMouseMove, // 4-byte mouse report
|
QTMouseMove, // 4-byte mouse report
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -115,8 +115,8 @@ enum sdep_type {
|
||||||
SdepResponse = 0x20,
|
SdepResponse = 0x20,
|
||||||
SdepAlert = 0x40,
|
SdepAlert = 0x40,
|
||||||
SdepError = 0x80,
|
SdepError = 0x80,
|
||||||
SdepSlaveNotReady = 0xFE, // Try again later
|
SdepSlaveNotReady = 0xFE, // Try again later
|
||||||
SdepSlaveOverflow = 0xFF, // You read more data than is available
|
SdepSlaveOverflow = 0xFF, // You read more data than is available
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ble_cmd {
|
enum ble_cmd {
|
||||||
|
@ -143,7 +143,7 @@ static bool at_command_P(const char *cmd, char *resp, uint16_t resplen, bool ver
|
||||||
|
|
||||||
// Send a single SDEP packet
|
// Send a single SDEP packet
|
||||||
static bool sdep_send_pkt(const struct sdep_msg *msg, uint16_t timeout) {
|
static bool sdep_send_pkt(const struct sdep_msg *msg, uint16_t timeout) {
|
||||||
spi_start(ADAFRUIT_BLE_CS_PIN, false, 0, ADAFRUIT_BLE_SCK_DIVISOR);
|
spi_start(BLUEFRUIT_LE_CS_PIN, false, 0, BLUEFRUIT_LE_SCK_DIVISOR);
|
||||||
uint16_t timerStart = timer_read();
|
uint16_t timerStart = timer_read();
|
||||||
bool success = false;
|
bool success = false;
|
||||||
bool ready = false;
|
bool ready = false;
|
||||||
|
@ -157,7 +157,7 @@ static bool sdep_send_pkt(const struct sdep_msg *msg, uint16_t timeout) {
|
||||||
// Release it and let it initialize
|
// Release it and let it initialize
|
||||||
spi_stop();
|
spi_stop();
|
||||||
wait_us(SdepBackOff);
|
wait_us(SdepBackOff);
|
||||||
spi_start(ADAFRUIT_BLE_CS_PIN, false, 0, ADAFRUIT_BLE_SCK_DIVISOR);
|
spi_start(BLUEFRUIT_LE_CS_PIN, false, 0, BLUEFRUIT_LE_SCK_DIVISOR);
|
||||||
} while (timer_elapsed(timerStart) < timeout);
|
} while (timer_elapsed(timerStart) < timeout);
|
||||||
|
|
||||||
if (ready) {
|
if (ready) {
|
||||||
|
@ -190,7 +190,7 @@ static bool sdep_recv_pkt(struct sdep_msg *msg, uint16_t timeout) {
|
||||||
bool ready = false;
|
bool ready = false;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ready = readPin(ADAFRUIT_BLE_IRQ_PIN);
|
ready = readPin(BLUEFRUIT_LE_IRQ_PIN);
|
||||||
if (ready) {
|
if (ready) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ static bool sdep_recv_pkt(struct sdep_msg *msg, uint16_t timeout) {
|
||||||
} while (timer_elapsed(timerStart) < timeout);
|
} while (timer_elapsed(timerStart) < timeout);
|
||||||
|
|
||||||
if (ready) {
|
if (ready) {
|
||||||
spi_start(ADAFRUIT_BLE_CS_PIN, false, 0, ADAFRUIT_BLE_SCK_DIVISOR);
|
spi_start(BLUEFRUIT_LE_CS_PIN, false, 0, BLUEFRUIT_LE_SCK_DIVISOR);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
// Read the command type, waiting for the data to be ready
|
// Read the command type, waiting for the data to be ready
|
||||||
|
@ -207,7 +207,7 @@ static bool sdep_recv_pkt(struct sdep_msg *msg, uint16_t timeout) {
|
||||||
// Release it and let it initialize
|
// Release it and let it initialize
|
||||||
spi_stop();
|
spi_stop();
|
||||||
wait_us(SdepBackOff);
|
wait_us(SdepBackOff);
|
||||||
spi_start(ADAFRUIT_BLE_CS_PIN, false, 0, ADAFRUIT_BLE_SCK_DIVISOR);
|
spi_start(BLUEFRUIT_LE_CS_PIN, false, 0, BLUEFRUIT_LE_SCK_DIVISOR);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,7 +233,7 @@ static void resp_buf_read_one(bool greedy) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (readPin(ADAFRUIT_BLE_IRQ_PIN)) {
|
if (readPin(BLUEFRUIT_LE_IRQ_PIN)) {
|
||||||
struct sdep_msg msg;
|
struct sdep_msg msg;
|
||||||
|
|
||||||
again:
|
again:
|
||||||
|
@ -244,7 +244,7 @@ static void resp_buf_read_one(bool greedy) {
|
||||||
dprintf("recv latency %dms\n", TIMER_DIFF_16(timer_read(), last_send));
|
dprintf("recv latency %dms\n", TIMER_DIFF_16(timer_read(), last_send));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (greedy && resp_buf.peek(last_send) && readPin(ADAFRUIT_BLE_IRQ_PIN)) {
|
if (greedy && resp_buf.peek(last_send) && readPin(BLUEFRUIT_LE_IRQ_PIN)) {
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -295,24 +295,26 @@ static bool ble_init(void) {
|
||||||
state.configured = false;
|
state.configured = false;
|
||||||
state.is_connected = false;
|
state.is_connected = false;
|
||||||
|
|
||||||
setPinInput(ADAFRUIT_BLE_IRQ_PIN);
|
setPinInput(BLUEFRUIT_LE_IRQ_PIN);
|
||||||
|
|
||||||
spi_init();
|
spi_init();
|
||||||
|
|
||||||
// Perform a hardware reset
|
// Perform a hardware reset
|
||||||
setPinOutput(ADAFRUIT_BLE_RST_PIN);
|
setPinOutput(BLUEFRUIT_LE_RST_PIN);
|
||||||
writePinHigh(ADAFRUIT_BLE_RST_PIN);
|
writePinHigh(BLUEFRUIT_LE_RST_PIN);
|
||||||
writePinLow(ADAFRUIT_BLE_RST_PIN);
|
writePinLow(BLUEFRUIT_LE_RST_PIN);
|
||||||
wait_ms(10);
|
wait_ms(10);
|
||||||
writePinHigh(ADAFRUIT_BLE_RST_PIN);
|
writePinHigh(BLUEFRUIT_LE_RST_PIN);
|
||||||
|
|
||||||
wait_ms(1000); // Give it a second to initialize
|
wait_ms(1000); // Give it a second to initialize
|
||||||
|
|
||||||
state.initialized = true;
|
state.initialized = true;
|
||||||
return state.initialized;
|
return state.initialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint8_t min(uint8_t a, uint8_t b) { return a < b ? a : b; }
|
static inline uint8_t min(uint8_t a, uint8_t b) {
|
||||||
|
return a < b ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
static bool read_response(char *resp, uint16_t resplen, bool verbose) {
|
static bool read_response(char *resp, uint16_t resplen, bool verbose) {
|
||||||
char *dest = resp;
|
char *dest = resp;
|
||||||
|
@ -424,9 +426,11 @@ bool at_command_P(const char *cmd, char *resp, uint16_t resplen, bool verbose) {
|
||||||
return at_command(cmdbuf, resp, resplen, verbose);
|
return at_command(cmdbuf, resp, resplen, verbose);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool adafruit_ble_is_connected(void) { return state.is_connected; }
|
bool bluefruit_le_is_connected(void) {
|
||||||
|
return state.is_connected;
|
||||||
|
}
|
||||||
|
|
||||||
bool adafruit_ble_enable_keyboard(void) {
|
bool bluefruit_le_enable_keyboard(void) {
|
||||||
char resbuf[128];
|
char resbuf[128];
|
||||||
|
|
||||||
if (!state.initialized && !ble_init()) {
|
if (!state.initialized && !ble_init()) {
|
||||||
|
@ -498,16 +502,16 @@ static void set_connected(bool connected) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void adafruit_ble_task(void) {
|
void bluefruit_le_task(void) {
|
||||||
char resbuf[48];
|
char resbuf[48];
|
||||||
|
|
||||||
if (!state.configured && !adafruit_ble_enable_keyboard()) {
|
if (!state.configured && !bluefruit_le_enable_keyboard()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
resp_buf_read_one(true);
|
resp_buf_read_one(true);
|
||||||
send_buf_send_one(SdepShortTimeout);
|
send_buf_send_one(SdepShortTimeout);
|
||||||
|
|
||||||
if (resp_buf.empty() && (state.event_flags & UsingEvents) && readPin(ADAFRUIT_BLE_IRQ_PIN)) {
|
if (resp_buf.empty() && (state.event_flags & UsingEvents) && readPin(BLUEFRUIT_LE_IRQ_PIN)) {
|
||||||
// Must be an event update
|
// Must be an event update
|
||||||
if (at_command_P(PSTR("AT+EVENTSTATUS"), resbuf, sizeof(resbuf))) {
|
if (at_command_P(PSTR("AT+EVENTSTATUS"), resbuf, sizeof(resbuf))) {
|
||||||
uint32_t mask = strtoul(resbuf, NULL, 16);
|
uint32_t mask = strtoul(resbuf, NULL, 16);
|
||||||
|
@ -609,7 +613,7 @@ static bool process_queue_item(struct queue_item *item, uint16_t timeout) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void adafruit_ble_send_keys(uint8_t hid_modifier_mask, uint8_t *keys, uint8_t nkeys) {
|
void bluefruit_le_send_keys(uint8_t hid_modifier_mask, uint8_t *keys, uint8_t nkeys) {
|
||||||
struct queue_item item;
|
struct queue_item item;
|
||||||
bool didWait = false;
|
bool didWait = false;
|
||||||
|
|
||||||
|
@ -643,7 +647,7 @@ void adafruit_ble_send_keys(uint8_t hid_modifier_mask, uint8_t *keys, uint8_t nk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void adafruit_ble_send_consumer_key(uint16_t usage) {
|
void bluefruit_le_send_consumer_key(uint16_t usage) {
|
||||||
struct queue_item item;
|
struct queue_item item;
|
||||||
|
|
||||||
item.queue_type = QTConsumer;
|
item.queue_type = QTConsumer;
|
||||||
|
@ -655,7 +659,7 @@ void adafruit_ble_send_consumer_key(uint16_t usage) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MOUSE_ENABLE
|
#ifdef MOUSE_ENABLE
|
||||||
void adafruit_ble_send_mouse_move(int8_t x, int8_t y, int8_t scroll, int8_t pan, uint8_t buttons) {
|
void bluefruit_le_send_mouse_move(int8_t x, int8_t y, int8_t scroll, int8_t pan, uint8_t buttons) {
|
||||||
struct queue_item item;
|
struct queue_item item;
|
||||||
|
|
||||||
item.queue_type = QTMouseMove;
|
item.queue_type = QTMouseMove;
|
||||||
|
@ -671,9 +675,11 @@ void adafruit_ble_send_mouse_move(int8_t x, int8_t y, int8_t scroll, int8_t pan,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint32_t adafruit_ble_read_battery_voltage(void) { return state.vbat; }
|
uint32_t bluefruit_le_read_battery_voltage(void) {
|
||||||
|
return state.vbat;
|
||||||
|
}
|
||||||
|
|
||||||
bool adafruit_ble_set_mode_leds(bool on) {
|
bool bluefruit_le_set_mode_leds(bool on) {
|
||||||
if (!state.configured) {
|
if (!state.configured) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -689,7 +695,7 @@ bool adafruit_ble_set_mode_leds(bool on) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://learn.adafruit.com/adafruit-feather-32u4-bluefruit-le/ble-generic#at-plus-blepowerlevel
|
// https://learn.adafruit.com/adafruit-feather-32u4-bluefruit-le/ble-generic#at-plus-blepowerlevel
|
||||||
bool adafruit_ble_set_power_level(int8_t level) {
|
bool bluefruit_le_set_power_level(int8_t level) {
|
||||||
char cmd[46];
|
char cmd[46];
|
||||||
if (!state.configured) {
|
if (!state.configured) {
|
||||||
return false;
|
return false;
|
|
@ -16,43 +16,43 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Instruct the module to enable HID keyboard support and reset */
|
/* Instruct the module to enable HID keyboard support and reset */
|
||||||
extern bool adafruit_ble_enable_keyboard(void);
|
extern bool bluefruit_le_enable_keyboard(void);
|
||||||
|
|
||||||
/* Query to see if the BLE module is connected */
|
/* Query to see if the BLE module is connected */
|
||||||
extern bool adafruit_ble_query_is_connected(void);
|
extern bool bluefruit_le_query_is_connected(void);
|
||||||
|
|
||||||
/* Returns true if we believe that the BLE module is connected.
|
/* Returns true if we believe that the BLE module is connected.
|
||||||
* This uses our cached understanding that is maintained by
|
* This uses our cached understanding that is maintained by
|
||||||
* calling ble_task() periodically. */
|
* calling ble_task() periodically. */
|
||||||
extern bool adafruit_ble_is_connected(void);
|
extern bool bluefruit_le_is_connected(void);
|
||||||
|
|
||||||
/* Call this periodically to process BLE-originated things */
|
/* Call this periodically to process BLE-originated things */
|
||||||
extern void adafruit_ble_task(void);
|
extern void bluefruit_le_task(void);
|
||||||
|
|
||||||
/* Generates keypress events for a set of keys.
|
/* Generates keypress events for a set of keys.
|
||||||
* The hid modifier mask specifies the state of the modifier keys for
|
* The hid modifier mask specifies the state of the modifier keys for
|
||||||
* this set of keys.
|
* this set of keys.
|
||||||
* Also sends a key release indicator, so that the keys do not remain
|
* Also sends a key release indicator, so that the keys do not remain
|
||||||
* held down. */
|
* held down. */
|
||||||
extern void adafruit_ble_send_keys(uint8_t hid_modifier_mask, uint8_t *keys, uint8_t nkeys);
|
extern void bluefruit_le_send_keys(uint8_t hid_modifier_mask, uint8_t *keys, uint8_t nkeys);
|
||||||
|
|
||||||
/* Send a consumer usage.
|
/* Send a consumer usage.
|
||||||
* (milliseconds) */
|
* (milliseconds) */
|
||||||
extern void adafruit_ble_send_consumer_key(uint16_t usage);
|
extern void bluefruit_le_send_consumer_key(uint16_t usage);
|
||||||
|
|
||||||
#ifdef MOUSE_ENABLE
|
#ifdef MOUSE_ENABLE
|
||||||
/* Send a mouse/wheel movement report.
|
/* Send a mouse/wheel movement report.
|
||||||
* The parameters are signed and indicate positive or negative direction
|
* The parameters are signed and indicate positive or negative direction
|
||||||
* change. */
|
* change. */
|
||||||
extern void adafruit_ble_send_mouse_move(int8_t x, int8_t y, int8_t scroll, int8_t pan, uint8_t buttons);
|
extern void bluefruit_le_send_mouse_move(int8_t x, int8_t y, int8_t scroll, int8_t pan, uint8_t buttons);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Compute battery voltage by reading an analog pin.
|
/* Compute battery voltage by reading an analog pin.
|
||||||
* Returns the integer number of millivolts */
|
* Returns the integer number of millivolts */
|
||||||
extern uint32_t adafruit_ble_read_battery_voltage(void);
|
extern uint32_t bluefruit_le_read_battery_voltage(void);
|
||||||
|
|
||||||
extern bool adafruit_ble_set_mode_leds(bool on);
|
extern bool bluefruit_le_set_mode_leds(bool on);
|
||||||
extern bool adafruit_ble_set_power_level(int8_t level);
|
extern bool bluefruit_le_set_power_level(int8_t level);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
|
@ -13,13 +13,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "outputselect.h"
|
#include "outputselect.h"
|
||||||
|
#include "usb_util.h"
|
||||||
|
|
||||||
#if defined(PROTOCOL_LUFA)
|
#ifdef BLUETOOTH_BLUEFRUIT_LE
|
||||||
# include "lufa.h"
|
# include "bluefruit_le.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MODULE_ADAFRUIT_BLE
|
|
||||||
# include "adafruit_ble.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint8_t desired_output = OUTPUT_DEFAULT;
|
uint8_t desired_output = OUTPUT_DEFAULT;
|
||||||
|
@ -39,29 +36,23 @@ void set_output(uint8_t output) {
|
||||||
*/
|
*/
|
||||||
__attribute__((weak)) void set_output_user(uint8_t output) {}
|
__attribute__((weak)) void set_output_user(uint8_t output) {}
|
||||||
|
|
||||||
static bool is_usb_configured(void) {
|
|
||||||
#if defined(PROTOCOL_LUFA)
|
|
||||||
return USB_DeviceState == DEVICE_STATE_Configured;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief Auto Detect Output
|
/** \brief Auto Detect Output
|
||||||
*
|
*
|
||||||
* FIXME: Needs doc
|
* FIXME: Needs doc
|
||||||
*/
|
*/
|
||||||
uint8_t auto_detect_output(void) {
|
uint8_t auto_detect_output(void) {
|
||||||
if (is_usb_configured()) {
|
if (usb_connected_state()) {
|
||||||
return OUTPUT_USB;
|
return OUTPUT_USB;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MODULE_ADAFRUIT_BLE
|
#ifdef BLUETOOTH_BLUEFRUIT_LE
|
||||||
if (adafruit_ble_is_connected()) {
|
if (bluefruit_le_is_connected()) {
|
||||||
return OUTPUT_BLUETOOTH;
|
return OUTPUT_BLUETOOTH;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BLUETOOTH_ENABLE
|
#ifdef BLUETOOTH_ENABLE
|
||||||
return OUTPUT_BLUETOOTH; // should check if BT is connected here
|
return OUTPUT_BLUETOOTH; // should check if BT is connected here
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return OUTPUT_NONE;
|
return OUTPUT_NONE;
|
||||||
|
|
101
drivers/bluetooth/rn42.c
Normal file
101
drivers/bluetooth/rn42.c
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
/* Copyright 2021
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "report.h"
|
||||||
|
#include "uart.h"
|
||||||
|
|
||||||
|
#ifndef RN42_BAUD_RATE
|
||||||
|
# define RN42_BAUD_RATE 115200
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// https://cdn.sparkfun.com/datasheets/Wireless/Bluetooth/bluetooth_cr_UG-v1.0r.pdf#G7.663734
|
||||||
|
static inline uint16_t rn42_consumer_usage_to_bitmap(uint16_t usage) {
|
||||||
|
switch (usage) {
|
||||||
|
case AC_HOME:
|
||||||
|
return 0x0001;
|
||||||
|
case AL_EMAIL:
|
||||||
|
return 0x0002;
|
||||||
|
case AC_SEARCH:
|
||||||
|
return 0x0004;
|
||||||
|
case AL_KEYBOARD_LAYOUT:
|
||||||
|
return 0x0008;
|
||||||
|
case AUDIO_VOL_UP:
|
||||||
|
return 0x0010;
|
||||||
|
case AUDIO_VOL_DOWN:
|
||||||
|
return 0x0020;
|
||||||
|
case AUDIO_MUTE:
|
||||||
|
return 0x0040;
|
||||||
|
case TRANSPORT_PLAY_PAUSE:
|
||||||
|
return 0x0080;
|
||||||
|
case TRANSPORT_NEXT_TRACK:
|
||||||
|
return 0x0100;
|
||||||
|
case TRANSPORT_PREV_TRACK:
|
||||||
|
return 0x0200;
|
||||||
|
case TRANSPORT_STOP:
|
||||||
|
return 0x0400;
|
||||||
|
case TRANSPORT_EJECT:
|
||||||
|
return 0x0800;
|
||||||
|
case TRANSPORT_FAST_FORWARD:
|
||||||
|
return 0x1000;
|
||||||
|
case TRANSPORT_REWIND:
|
||||||
|
return 0x2000;
|
||||||
|
case TRANSPORT_STOP_EJECT:
|
||||||
|
return 0x4000;
|
||||||
|
case AL_LOCAL_BROWSER:
|
||||||
|
return 0x8000;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void rn42_init(void) {
|
||||||
|
uart_init(RN42_BAUD_RATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rn42_send_keyboard(report_keyboard_t *report) {
|
||||||
|
uart_write(0xFD);
|
||||||
|
uart_write(0x09);
|
||||||
|
uart_write(0x01);
|
||||||
|
uart_write(report->mods);
|
||||||
|
uart_write(0x00);
|
||||||
|
for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
|
||||||
|
uart_write(report->keys[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void rn42_send_mouse(report_mouse_t *report) {
|
||||||
|
uart_write(0xFD);
|
||||||
|
uart_write(0x00);
|
||||||
|
uart_write(0x03);
|
||||||
|
uart_write(report->buttons);
|
||||||
|
uart_write(report->x);
|
||||||
|
uart_write(report->y);
|
||||||
|
uart_write(report->v); // should try sending the wheel v here
|
||||||
|
uart_write(report->h); // should try sending the wheel h here
|
||||||
|
uart_write(0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rn42_send_consumer(uint16_t data) {
|
||||||
|
static uint16_t last_data = 0;
|
||||||
|
if (data == last_data) return;
|
||||||
|
last_data = data;
|
||||||
|
uint16_t bitmap = rn42_consumer_usage_to_bitmap(data);
|
||||||
|
uart_write(0xFD);
|
||||||
|
uart_write(0x03);
|
||||||
|
uart_write(0x03);
|
||||||
|
uart_write(bitmap & 0xFF);
|
||||||
|
uart_write((bitmap >> 8) & 0xFF);
|
||||||
|
}
|
25
drivers/bluetooth/rn42.h
Normal file
25
drivers/bluetooth/rn42.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/* Copyright 2021
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "report.h"
|
||||||
|
|
||||||
|
void rn42_init(void);
|
||||||
|
|
||||||
|
void rn42_send_keyboard(report_keyboard_t *report);
|
||||||
|
|
||||||
|
void rn42_send_mouse(report_mouse_t *report);
|
||||||
|
|
||||||
|
void rn42_send_consumer(uint16_t data);
|
|
@ -37,11 +37,17 @@ uint32_t eeprom_read_dword(const uint32_t *addr) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void eeprom_write_byte(uint8_t *addr, uint8_t value) { eeprom_write_block(&value, addr, 1); }
|
void eeprom_write_byte(uint8_t *addr, uint8_t value) {
|
||||||
|
eeprom_write_block(&value, addr, 1);
|
||||||
|
}
|
||||||
|
|
||||||
void eeprom_write_word(uint16_t *addr, uint16_t value) { eeprom_write_block(&value, addr, 2); }
|
void eeprom_write_word(uint16_t *addr, uint16_t value) {
|
||||||
|
eeprom_write_block(&value, addr, 2);
|
||||||
|
}
|
||||||
|
|
||||||
void eeprom_write_dword(uint32_t *addr, uint32_t value) { eeprom_write_block(&value, addr, 4); }
|
void eeprom_write_dword(uint32_t *addr, uint32_t value) {
|
||||||
|
eeprom_write_block(&value, addr, 4);
|
||||||
|
}
|
||||||
|
|
||||||
void eeprom_update_block(const void *buf, void *addr, size_t len) {
|
void eeprom_update_block(const void *buf, void *addr, size_t len) {
|
||||||
uint8_t read_buf[len];
|
uint8_t read_buf[len];
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
#if defined(CONSOLE_ENABLE) && defined(DEBUG_EEPROM_OUTPUT)
|
#if defined(CONSOLE_ENABLE) && defined(DEBUG_EEPROM_OUTPUT)
|
||||||
# include "timer.h"
|
# include "timer.h"
|
||||||
# include "debug.h"
|
# include "debug.h"
|
||||||
#endif // DEBUG_EEPROM_OUTPUT
|
#endif // DEBUG_EEPROM_OUTPUT
|
||||||
|
|
||||||
static inline void fill_target_address(uint8_t *buffer, const void *addr) {
|
static inline void fill_target_address(uint8_t *buffer, const void *addr) {
|
||||||
uintptr_t p = (uintptr_t)addr;
|
uintptr_t p = (uintptr_t)addr;
|
||||||
|
@ -91,7 +91,7 @@ void eeprom_read_block(void *buf, const void *addr, size_t len) {
|
||||||
dprintf(" %02X", (int)(((uint8_t *)buf)[i]));
|
dprintf(" %02X", (int)(((uint8_t *)buf)[i]));
|
||||||
}
|
}
|
||||||
dprintf("\n");
|
dprintf("\n");
|
||||||
#endif // DEBUG_EEPROM_OUTPUT
|
#endif // DEBUG_EEPROM_OUTPUT
|
||||||
}
|
}
|
||||||
|
|
||||||
void eeprom_write_block(const void *buf, void *addr, size_t len) {
|
void eeprom_write_block(const void *buf, void *addr, size_t len) {
|
||||||
|
@ -122,7 +122,7 @@ void eeprom_write_block(const void *buf, void *addr, size_t len) {
|
||||||
dprintf(" %02X", (int)(read_buf[i]));
|
dprintf(" %02X", (int)(read_buf[i]));
|
||||||
}
|
}
|
||||||
dprintf("\n");
|
dprintf("\n");
|
||||||
#endif // DEBUG_EEPROM_OUTPUT
|
#endif // DEBUG_EEPROM_OUTPUT
|
||||||
|
|
||||||
i2c_transmit(EXTERNAL_EEPROM_I2C_ADDRESS((uintptr_t)addr), complete_packet, EXTERNAL_EEPROM_ADDRESS_SIZE + write_length, 100);
|
i2c_transmit(EXTERNAL_EEPROM_I2C_ADDRESS((uintptr_t)addr), complete_packet, EXTERNAL_EEPROM_ADDRESS_SIZE + write_length, 100);
|
||||||
wait_ms(EXTERNAL_EEPROM_WRITE_TIME);
|
wait_ms(EXTERNAL_EEPROM_WRITE_TIME);
|
||||||
|
|
|
@ -52,7 +52,9 @@
|
||||||
# define EXTERNAL_EEPROM_SPI_TIMEOUT 100
|
# define EXTERNAL_EEPROM_SPI_TIMEOUT 100
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool spi_eeprom_start(void) { return spi_start(EXTERNAL_EEPROM_SPI_SLAVE_SELECT_PIN, EXTERNAL_EEPROM_SPI_LSBFIRST, EXTERNAL_EEPROM_SPI_MODE, EXTERNAL_EEPROM_SPI_CLOCK_DIVISOR); }
|
static bool spi_eeprom_start(void) {
|
||||||
|
return spi_start(EXTERNAL_EEPROM_SPI_SLAVE_SELECT_PIN, EXTERNAL_EEPROM_SPI_LSBFIRST, EXTERNAL_EEPROM_SPI_MODE, EXTERNAL_EEPROM_SPI_CLOCK_DIVISOR);
|
||||||
|
}
|
||||||
|
|
||||||
static spi_status_t spi_eeprom_wait_while_busy(int timeout) {
|
static spi_status_t spi_eeprom_wait_while_busy(int timeout) {
|
||||||
uint32_t deadline = timer_read32() + timeout;
|
uint32_t deadline = timer_read32() + timeout;
|
||||||
|
@ -80,7 +82,9 @@ static void spi_eeprom_transmit_address(uintptr_t addr) {
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
void eeprom_driver_init(void) { spi_init(); }
|
void eeprom_driver_init(void) {
|
||||||
|
spi_init();
|
||||||
|
}
|
||||||
|
|
||||||
void eeprom_driver_erase(void) {
|
void eeprom_driver_erase(void) {
|
||||||
#if defined(CONSOLE_ENABLE) && defined(DEBUG_EEPROM_OUTPUT)
|
#if defined(CONSOLE_ENABLE) && defined(DEBUG_EEPROM_OUTPUT)
|
||||||
|
@ -135,7 +139,7 @@ void eeprom_read_block(void *buf, const void *addr, size_t len) {
|
||||||
dprintf(" %02X", (int)(((uint8_t *)buf)[i]));
|
dprintf(" %02X", (int)(((uint8_t *)buf)[i]));
|
||||||
}
|
}
|
||||||
dprintf("\n");
|
dprintf("\n");
|
||||||
#endif // DEBUG_EEPROM_OUTPUT
|
#endif // DEBUG_EEPROM_OUTPUT
|
||||||
|
|
||||||
spi_stop();
|
spi_stop();
|
||||||
}
|
}
|
||||||
|
@ -192,7 +196,7 @@ void eeprom_write_block(const void *buf, void *addr, size_t len) {
|
||||||
dprintf(" %02X", (int)(uint8_t)(read_buf[i]));
|
dprintf(" %02X", (int)(uint8_t)(read_buf[i]));
|
||||||
}
|
}
|
||||||
dprintf("\n");
|
dprintf("\n");
|
||||||
#endif // DEBUG_EEPROM_OUTPUT
|
#endif // DEBUG_EEPROM_OUTPUT
|
||||||
|
|
||||||
spi_write(CMD_WRITE);
|
spi_write(CMD_WRITE);
|
||||||
spi_eeprom_transmit_address(target_addr);
|
spi_eeprom_transmit_address(target_addr);
|
||||||
|
|
|
@ -30,9 +30,13 @@ size_t clamp_length(intptr_t offset, size_t len) {
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
void eeprom_driver_init(void) { eeprom_driver_erase(); }
|
void eeprom_driver_init(void) {
|
||||||
|
eeprom_driver_erase();
|
||||||
|
}
|
||||||
|
|
||||||
void eeprom_driver_erase(void) { memset(transientBuffer, 0x00, TRANSIENT_EEPROM_SIZE); }
|
void eeprom_driver_erase(void) {
|
||||||
|
memset(transientBuffer, 0x00, TRANSIENT_EEPROM_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
void eeprom_read_block(void *buf, const void *addr, size_t len) {
|
void eeprom_read_block(void *buf, const void *addr, size_t len) {
|
||||||
intptr_t offset = (intptr_t)addr;
|
intptr_t offset = (intptr_t)addr;
|
||||||
|
|
|
@ -21,5 +21,5 @@
|
||||||
*/
|
*/
|
||||||
#ifndef TRANSIENT_EEPROM_SIZE
|
#ifndef TRANSIENT_EEPROM_SIZE
|
||||||
# include "eeconfig.h"
|
# include "eeconfig.h"
|
||||||
# define TRANSIENT_EEPROM_SIZE (((EECONFIG_SIZE + 3) / 4) * 4) // based off eeconfig's current usage, aligned to 4-byte sizes, to deal with LTO
|
# define TRANSIENT_EEPROM_SIZE (((EECONFIG_SIZE + 3) / 4) * 4) // based off eeconfig's current usage, aligned to 4-byte sizes, to deal with LTO
|
||||||
#endif
|
#endif
|
||||||
|
|
376
drivers/flash/flash_spi.c
Normal file
376
drivers/flash/flash_spi.c
Normal file
|
@ -0,0 +1,376 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2021 Westberry Technology (ChangZhou) Corp., Ltd
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
#include "wait.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "timer.h"
|
||||||
|
#include "flash_spi.h"
|
||||||
|
#include "spi_master.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
The time-out time of spi flash transmission.
|
||||||
|
*/
|
||||||
|
#ifndef EXTERNAL_FLASH_SPI_TIMEOUT
|
||||||
|
# define EXTERNAL_FLASH_SPI_TIMEOUT 1000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ID comands */
|
||||||
|
#define FLASH_CMD_RDID 0x9F /* RDID (Read Identification) */
|
||||||
|
#define FLASH_CMD_RES 0xAB /* RES (Read Electronic ID) */
|
||||||
|
#define FLASH_CMD_REMS 0x90 /* REMS (Read Electronic & Device ID) */
|
||||||
|
|
||||||
|
/* register comands */
|
||||||
|
#define FLASH_CMD_WRSR 0x01 /* WRSR (Write Status register) */
|
||||||
|
#define FLASH_CMD_RDSR 0x05 /* RDSR (Read Status register) */
|
||||||
|
|
||||||
|
/* READ comands */
|
||||||
|
#define FLASH_CMD_READ 0x03 /* READ (1 x I/O) */
|
||||||
|
#define FLASH_CMD_FASTREAD 0x0B /* FAST READ (Fast read data) */
|
||||||
|
#define FLASH_CMD_DREAD 0x3B /* DREAD (1In/2 Out fast read) */
|
||||||
|
|
||||||
|
/* Program comands */
|
||||||
|
#define FLASH_CMD_WREN 0x06 /* WREN (Write Enable) */
|
||||||
|
#define FLASH_CMD_WRDI 0x04 /* WRDI (Write Disable) */
|
||||||
|
#define FLASH_CMD_PP 0x02 /* PP (page program) */
|
||||||
|
|
||||||
|
/* Erase comands */
|
||||||
|
#define FLASH_CMD_SE 0x20 /* SE (Sector Erase) */
|
||||||
|
#define FLASH_CMD_BE 0xD8 /* BE (Block Erase) */
|
||||||
|
#define FLASH_CMD_CE 0x60 /* CE (Chip Erase) hex code: 60 or C7 */
|
||||||
|
|
||||||
|
/* Mode setting comands */
|
||||||
|
#define FLASH_CMD_DP 0xB9 /* DP (Deep Power Down) */
|
||||||
|
#define FLASH_CMD_RDP 0xAB /* RDP (Release form Deep Power Down) */
|
||||||
|
|
||||||
|
/* Status register */
|
||||||
|
#define FLASH_FLAG_WIP 0x01 /* Write in progress bit */
|
||||||
|
#define FLASH_FLAG_WEL 0x02 /* Write enable latch bit */
|
||||||
|
|
||||||
|
// #define DEBUG_FLASH_SPI_OUTPUT
|
||||||
|
|
||||||
|
static bool spi_flash_start(void) {
|
||||||
|
return spi_start(EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN, EXTERNAL_FLASH_SPI_LSBFIRST, EXTERNAL_FLASH_SPI_MODE, EXTERNAL_FLASH_SPI_CLOCK_DIVISOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static flash_status_t spi_flash_wait_while_busy(void) {
|
||||||
|
uint32_t deadline = timer_read32() + EXTERNAL_FLASH_SPI_TIMEOUT;
|
||||||
|
flash_status_t response = FLASH_STATUS_SUCCESS;
|
||||||
|
uint8_t retval;
|
||||||
|
|
||||||
|
do {
|
||||||
|
bool res = spi_flash_start();
|
||||||
|
if (!res) {
|
||||||
|
dprint("Failed to start SPI! [spi flash wait while busy]\n");
|
||||||
|
return FLASH_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
spi_write(FLASH_CMD_RDSR);
|
||||||
|
|
||||||
|
retval = (uint8_t)spi_read();
|
||||||
|
|
||||||
|
spi_stop();
|
||||||
|
|
||||||
|
if (timer_read32() >= deadline) {
|
||||||
|
response = FLASH_STATUS_TIMEOUT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (retval & FLASH_FLAG_WIP);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
static flash_status_t spi_flash_write_enable(void) {
|
||||||
|
bool res = spi_flash_start();
|
||||||
|
if (!res) {
|
||||||
|
dprint("Failed to start SPI! [spi flash write enable]\n");
|
||||||
|
return FLASH_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
spi_write(FLASH_CMD_WREN);
|
||||||
|
|
||||||
|
spi_stop();
|
||||||
|
|
||||||
|
return FLASH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static flash_status_t spi_flash_write_disable(void) {
|
||||||
|
bool res = spi_flash_start();
|
||||||
|
if (!res) {
|
||||||
|
dprint("Failed to start SPI! [spi flash write disable]\n");
|
||||||
|
return FLASH_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
spi_write(FLASH_CMD_WRDI);
|
||||||
|
|
||||||
|
spi_stop();
|
||||||
|
|
||||||
|
return FLASH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function is used for read transfer, write transfer and erase transfer. */
|
||||||
|
static flash_status_t spi_flash_transaction(uint8_t cmd, uint32_t addr, uint8_t *data, size_t len) {
|
||||||
|
flash_status_t response = FLASH_STATUS_SUCCESS;
|
||||||
|
uint8_t buffer[EXTERNAL_FLASH_ADDRESS_SIZE + 1];
|
||||||
|
|
||||||
|
buffer[0] = cmd;
|
||||||
|
for (int i = 0; i < EXTERNAL_FLASH_ADDRESS_SIZE; ++i) {
|
||||||
|
buffer[EXTERNAL_FLASH_ADDRESS_SIZE - i] = addr & 0xFF;
|
||||||
|
addr >>= 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool res = spi_flash_start();
|
||||||
|
if (!res) {
|
||||||
|
dprint("Failed to start SPI! [spi flash transmit]\n");
|
||||||
|
return FLASH_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
response = spi_transmit(buffer, sizeof(buffer));
|
||||||
|
|
||||||
|
if ((!response) && (data != NULL)) {
|
||||||
|
switch (cmd) {
|
||||||
|
case FLASH_CMD_READ:
|
||||||
|
response = spi_receive(data, len);
|
||||||
|
break;
|
||||||
|
case FLASH_CMD_PP:
|
||||||
|
response = spi_transmit(data, len);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
response = FLASH_STATUS_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spi_stop();
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
void flash_init(void) {
|
||||||
|
spi_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
flash_status_t flash_erase_chip(void) {
|
||||||
|
flash_status_t response = FLASH_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
/* Wait for the write-in-progress bit to be cleared. */
|
||||||
|
response = spi_flash_wait_while_busy();
|
||||||
|
if (response != FLASH_STATUS_SUCCESS) {
|
||||||
|
dprint("Failed to check WIP flag! [spi flash erase chip]\n");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable writes. */
|
||||||
|
response = spi_flash_write_enable();
|
||||||
|
if (response != FLASH_STATUS_SUCCESS) {
|
||||||
|
dprint("Failed to write-enable! [spi flash erase chip]\n");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Erase Chip. */
|
||||||
|
bool res = spi_flash_start();
|
||||||
|
if (!res) {
|
||||||
|
dprint("Failed to start SPI! [spi flash erase chip]\n");
|
||||||
|
return FLASH_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
spi_write(FLASH_CMD_CE);
|
||||||
|
spi_stop();
|
||||||
|
|
||||||
|
/* Wait for the write-in-progress bit to be cleared.*/
|
||||||
|
response = spi_flash_wait_while_busy();
|
||||||
|
if (response != FLASH_STATUS_SUCCESS) {
|
||||||
|
dprint("Failed to check WIP flag! [spi flash erase chip]\n");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
flash_status_t flash_erase_sector(uint32_t addr) {
|
||||||
|
flash_status_t response = FLASH_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
/* Check that the address exceeds the limit. */
|
||||||
|
if ((addr + (EXTERNAL_FLASH_SECTOR_SIZE)) >= (EXTERNAL_FLASH_SIZE) || ((addr % (EXTERNAL_FLASH_SECTOR_SIZE)) != 0)) {
|
||||||
|
dprintf("Flash erase sector address over limit! [addr:0x%x]\n", (uint32_t)addr);
|
||||||
|
return FLASH_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for the write-in-progress bit to be cleared. */
|
||||||
|
response = spi_flash_wait_while_busy();
|
||||||
|
if (response != FLASH_STATUS_SUCCESS) {
|
||||||
|
dprint("Failed to check WIP flag! [spi flash erase sector]\n");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable writes. */
|
||||||
|
response = spi_flash_write_enable();
|
||||||
|
if (response != FLASH_STATUS_SUCCESS) {
|
||||||
|
dprint("Failed to write-enable! [spi flash erase sector]\n");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Erase Sector. */
|
||||||
|
response = spi_flash_transaction(FLASH_CMD_SE, addr, NULL, 0);
|
||||||
|
if (response != FLASH_STATUS_SUCCESS) {
|
||||||
|
dprint("Failed to erase sector! [spi flash erase sector]\n");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for the write-in-progress bit to be cleared.*/
|
||||||
|
response = spi_flash_wait_while_busy();
|
||||||
|
if (response != FLASH_STATUS_SUCCESS) {
|
||||||
|
dprint("Failed to check WIP flag! [spi flash erase sector]\n");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
flash_status_t flash_erase_block(uint32_t addr) {
|
||||||
|
flash_status_t response = FLASH_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
/* Check that the address exceeds the limit. */
|
||||||
|
if ((addr + (EXTERNAL_FLASH_BLOCK_SIZE)) >= (EXTERNAL_FLASH_SIZE) || ((addr % (EXTERNAL_FLASH_BLOCK_SIZE)) != 0)) {
|
||||||
|
dprintf("Flash erase block address over limit! [addr:0x%x]\n", (uint32_t)addr);
|
||||||
|
return FLASH_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for the write-in-progress bit to be cleared. */
|
||||||
|
response = spi_flash_wait_while_busy();
|
||||||
|
if (response != FLASH_STATUS_SUCCESS) {
|
||||||
|
dprint("Failed to check WIP flag! [spi flash erase block]\n");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable writes. */
|
||||||
|
response = spi_flash_write_enable();
|
||||||
|
if (response != FLASH_STATUS_SUCCESS) {
|
||||||
|
dprint("Failed to write-enable! [spi flash erase block]\n");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Erase Block. */
|
||||||
|
response = spi_flash_transaction(FLASH_CMD_BE, addr, NULL, 0);
|
||||||
|
if (response != FLASH_STATUS_SUCCESS) {
|
||||||
|
dprint("Failed to erase block! [spi flash erase block]\n");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for the write-in-progress bit to be cleared.*/
|
||||||
|
response = spi_flash_wait_while_busy();
|
||||||
|
if (response != FLASH_STATUS_SUCCESS) {
|
||||||
|
dprint("Failed to check WIP flag! [spi flash erase block]\n");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
flash_status_t flash_read_block(uint32_t addr, void *buf, size_t len) {
|
||||||
|
flash_status_t response = FLASH_STATUS_SUCCESS;
|
||||||
|
uint8_t * read_buf = (uint8_t *)buf;
|
||||||
|
|
||||||
|
/* Wait for the write-in-progress bit to be cleared. */
|
||||||
|
response = spi_flash_wait_while_busy();
|
||||||
|
if (response != FLASH_STATUS_SUCCESS) {
|
||||||
|
dprint("Failed to check WIP flag! [spi flash read block]\n");
|
||||||
|
memset(read_buf, 0, len);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Perform read. */
|
||||||
|
response = spi_flash_transaction(FLASH_CMD_READ, addr, read_buf, len);
|
||||||
|
if (response != FLASH_STATUS_SUCCESS) {
|
||||||
|
dprint("Failed to read block! [spi flash read block]\n");
|
||||||
|
memset(read_buf, 0, len);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONSOLE_ENABLE) && defined(DEBUG_FLASH_SPI_OUTPUT)
|
||||||
|
dprintf("[SPI FLASH R] 0x%08lX: ", addr);
|
||||||
|
for (size_t i = 0; i < len; ++i) {
|
||||||
|
dprintf(" %02X", (int)(((uint8_t *)read_buf)[i]));
|
||||||
|
}
|
||||||
|
dprintf("\n");
|
||||||
|
#endif // DEBUG_FLASH_SPI_OUTPUT
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
flash_status_t flash_write_block(uint32_t addr, const void *buf, size_t len) {
|
||||||
|
flash_status_t response = FLASH_STATUS_SUCCESS;
|
||||||
|
uint8_t * write_buf = (uint8_t *)buf;
|
||||||
|
|
||||||
|
while (len > 0) {
|
||||||
|
uint32_t page_offset = addr % EXTERNAL_FLASH_PAGE_SIZE;
|
||||||
|
size_t write_length = EXTERNAL_FLASH_PAGE_SIZE - page_offset;
|
||||||
|
if (write_length > len) {
|
||||||
|
write_length = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for the write-in-progress bit to be cleared. */
|
||||||
|
response = spi_flash_wait_while_busy();
|
||||||
|
if (response != FLASH_STATUS_SUCCESS) {
|
||||||
|
dprint("Failed to check WIP flag! [spi flash write block]\n");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable writes. */
|
||||||
|
response = spi_flash_write_enable();
|
||||||
|
if (response != FLASH_STATUS_SUCCESS) {
|
||||||
|
dprint("Failed to write-enable! [spi flash write block]\n");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONSOLE_ENABLE) && defined(DEBUG_FLASH_SPI_OUTPUT)
|
||||||
|
dprintf("[SPI FLASH W] 0x%08lX: ", addr);
|
||||||
|
for (size_t i = 0; i < write_length; i++) {
|
||||||
|
dprintf(" %02X", (int)(uint8_t)(write_buf[i]));
|
||||||
|
}
|
||||||
|
dprintf("\n");
|
||||||
|
#endif // DEBUG_FLASH_SPI_OUTPUT
|
||||||
|
|
||||||
|
/* Perform the write. */
|
||||||
|
response = spi_flash_transaction(FLASH_CMD_PP, addr, write_buf, write_length);
|
||||||
|
if (response != FLASH_STATUS_SUCCESS) {
|
||||||
|
dprint("Failed to write block! [spi flash write block]\n");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
write_buf += write_length;
|
||||||
|
addr += write_length;
|
||||||
|
len -= write_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for the write-in-progress bit to be cleared. */
|
||||||
|
response = spi_flash_wait_while_busy();
|
||||||
|
if (response != FLASH_STATUS_SUCCESS) {
|
||||||
|
dprint("Failed to check WIP flag! [spi flash write block]\n");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disable writes. */
|
||||||
|
response = spi_flash_write_disable();
|
||||||
|
if (response != FLASH_STATUS_SUCCESS) {
|
||||||
|
dprint("Failed to write-disable! [spi flash write block]\n");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
136
drivers/flash/flash_spi.h
Normal file
136
drivers/flash/flash_spi.h
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2021 Westberry Technology (ChangZhou) Corp., Ltd
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/* All the following default configurations are based on MX25L4006E Nor FLASH. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
The slave select pin of the FLASH.
|
||||||
|
This needs to be a normal GPIO pin_t value, such as B14.
|
||||||
|
*/
|
||||||
|
#ifndef EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN
|
||||||
|
# error "No chip select pin defined -- missing EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
The clock divisor for SPI to ensure that the MCU is within the
|
||||||
|
specifications of the FLASH chip. Generally this will be PCLK divided by
|
||||||
|
the intended divisor -- check your clock settings and the datasheet of
|
||||||
|
your FLASH.
|
||||||
|
*/
|
||||||
|
#ifndef EXTERNAL_FLASH_SPI_CLOCK_DIVISOR
|
||||||
|
# ifdef __AVR__
|
||||||
|
# define EXTERNAL_FLASH_SPI_CLOCK_DIVISOR 4
|
||||||
|
# else
|
||||||
|
# define EXTERNAL_FLASH_SPI_CLOCK_DIVISOR 8
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
The SPI mode to communicate with the FLASH.
|
||||||
|
*/
|
||||||
|
#ifndef EXTERNAL_FLASH_SPI_MODE
|
||||||
|
# define EXTERNAL_FLASH_SPI_MODE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
Whether or not the SPI communication between the MCU and FLASH should be
|
||||||
|
LSB-first.
|
||||||
|
*/
|
||||||
|
#ifndef EXTERNAL_FLASH_SPI_LSBFIRST
|
||||||
|
# define EXTERNAL_FLASH_SPI_LSBFIRST false
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
The Flash address size in bytes, as specified in datasheet.
|
||||||
|
*/
|
||||||
|
#ifndef EXTERNAL_FLASH_ADDRESS_SIZE
|
||||||
|
# define EXTERNAL_FLASH_ADDRESS_SIZE 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
The page size of the FLASH in bytes, as specified in the datasheet.
|
||||||
|
*/
|
||||||
|
#ifndef EXTERNAL_FLASH_PAGE_SIZE
|
||||||
|
# define EXTERNAL_FLASH_PAGE_SIZE 256
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
The sector size of the FLASH in bytes, as specified in the datasheet.
|
||||||
|
*/
|
||||||
|
#ifndef EXTERNAL_FLASH_SECTOR_SIZE
|
||||||
|
# define EXTERNAL_FLASH_SECTOR_SIZE (4 * 1024)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
The block size of the FLASH in bytes, as specified in the datasheet.
|
||||||
|
*/
|
||||||
|
#ifndef EXTERNAL_FLASH_BLOCK_SIZE
|
||||||
|
# define EXTERNAL_FLASH_BLOCK_SIZE (64 * 1024)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
The total size of the FLASH in bytes, as specified in the datasheet.
|
||||||
|
*/
|
||||||
|
#ifndef EXTERNAL_FLASH_SIZE
|
||||||
|
# define EXTERNAL_FLASH_SIZE (512 * 1024)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
The block count of the FLASH, calculated by total FLASH size and block size.
|
||||||
|
*/
|
||||||
|
#define EXTERNAL_FLASH_BLOCK_COUNT ((EXTERNAL_FLASH_SIZE) / (EXTERNAL_FLASH_BLOCK_SIZE))
|
||||||
|
|
||||||
|
/*
|
||||||
|
The sector count of the FLASH, calculated by total FLASH size and sector size.
|
||||||
|
*/
|
||||||
|
#define EXTERNAL_FLASH_SECTOR_COUNT ((EXTERNAL_FLASH_SIZE) / (EXTERNAL_FLASH_SECTOR_SIZE))
|
||||||
|
|
||||||
|
/*
|
||||||
|
The page count of the FLASH, calculated by total FLASH size and page size.
|
||||||
|
*/
|
||||||
|
#define EXTERNAL_FLASH_PAGE_COUNT ((EXTERNAL_FLASH_SIZE) / (EXTERNAL_FLASH_PAGE_SIZE))
|
||||||
|
|
||||||
|
typedef int16_t flash_status_t;
|
||||||
|
|
||||||
|
#define FLASH_STATUS_SUCCESS (0)
|
||||||
|
#define FLASH_STATUS_ERROR (-1)
|
||||||
|
#define FLASH_STATUS_TIMEOUT (-2)
|
||||||
|
#define FLASH_STATUS_BAD_ADDRESS (-3)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void flash_init(void);
|
||||||
|
|
||||||
|
flash_status_t flash_erase_chip(void);
|
||||||
|
|
||||||
|
flash_status_t flash_erase_block(uint32_t addr);
|
||||||
|
|
||||||
|
flash_status_t flash_erase_sector(uint32_t addr);
|
||||||
|
|
||||||
|
flash_status_t flash_read_block(uint32_t addr, void *buf, size_t len);
|
||||||
|
|
||||||
|
flash_status_t flash_write_block(uint32_t addr, const void *buf, size_t len);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -1,18 +1,6 @@
|
||||||
/* Copyright 2020 zvecr<git@zvecr.com>
|
// Copyright 2022 zvecr<git@zvecr.com>
|
||||||
*
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#include "mcp23018.h"
|
#include "mcp23018.h"
|
||||||
#include "i2c_master.h"
|
#include "i2c_master.h"
|
||||||
#include "wait.h"
|
#include "wait.h"
|
||||||
|
@ -22,11 +10,11 @@
|
||||||
#define TIMEOUT 100
|
#define TIMEOUT 100
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
CMD_IODIRA = 0x00, // i/o direction register
|
CMD_IODIRA = 0x00, // i/o direction register
|
||||||
CMD_IODIRB = 0x01,
|
CMD_IODIRB = 0x01,
|
||||||
CMD_GPPUA = 0x0C, // GPIO pull-up resistor register
|
CMD_GPPUA = 0x0C, // GPIO pull-up resistor register
|
||||||
CMD_GPPUB = 0x0D,
|
CMD_GPPUB = 0x0D,
|
||||||
CMD_GPIOA = 0x12, // general purpose i/o port register (write modifies OLAT)
|
CMD_GPIOA = 0x12, // general purpose i/o port register (write modifies OLAT)
|
||||||
CMD_GPIOB = 0x13,
|
CMD_GPIOB = 0x13,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -40,7 +28,7 @@ void mcp23018_init(uint8_t addr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mcp23018_set_config(uint8_t slave_addr, uint8_t port, uint8_t conf) {
|
bool mcp23018_set_config(uint8_t slave_addr, mcp23018_port_t port, uint8_t conf) {
|
||||||
uint8_t addr = SLAVE_TO_ADDR(slave_addr);
|
uint8_t addr = SLAVE_TO_ADDR(slave_addr);
|
||||||
uint8_t cmdDirection = port ? CMD_IODIRB : CMD_IODIRA;
|
uint8_t cmdDirection = port ? CMD_IODIRB : CMD_IODIRA;
|
||||||
uint8_t cmdPullup = port ? CMD_GPPUB : CMD_GPPUA;
|
uint8_t cmdPullup = port ? CMD_GPPUB : CMD_GPPUA;
|
||||||
|
@ -60,7 +48,7 @@ bool mcp23018_set_config(uint8_t slave_addr, uint8_t port, uint8_t conf) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mcp23018_set_output(uint8_t slave_addr, uint8_t port, uint8_t conf) {
|
bool mcp23018_set_output(uint8_t slave_addr, mcp23018_port_t port, uint8_t conf) {
|
||||||
uint8_t addr = SLAVE_TO_ADDR(slave_addr);
|
uint8_t addr = SLAVE_TO_ADDR(slave_addr);
|
||||||
uint8_t cmd = port ? CMD_GPIOB : CMD_GPIOA;
|
uint8_t cmd = port ? CMD_GPIOB : CMD_GPIOA;
|
||||||
|
|
||||||
|
@ -86,7 +74,7 @@ bool mcp23018_set_output_all(uint8_t slave_addr, uint8_t confA, uint8_t confB) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mcp23018_readPins(uint8_t slave_addr, uint8_t port, uint8_t* out) {
|
bool mcp23018_readPins(uint8_t slave_addr, mcp23018_port_t port, uint8_t* out) {
|
||||||
uint8_t addr = SLAVE_TO_ADDR(slave_addr);
|
uint8_t addr = SLAVE_TO_ADDR(slave_addr);
|
||||||
uint8_t cmd = port ? CMD_GPIOB : CMD_GPIOA;
|
uint8_t cmd = port ? CMD_GPIOB : CMD_GPIOA;
|
||||||
|
|
65
drivers/gpio/mcp23018.h
Normal file
65
drivers/gpio/mcp23018.h
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
// Copyright 2022 zvecr<git@zvecr.com>
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Port ID
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
mcp23018_PORTA,
|
||||||
|
mcp23018_PORTB,
|
||||||
|
} mcp23018_port_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helpers for set_config
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
ALL_OUTPUT = 0,
|
||||||
|
ALL_INPUT = 0xFF,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helpers for set_output
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
ALL_LOW = 0,
|
||||||
|
ALL_HIGH = 0xFF,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init expander and any other dependent drivers
|
||||||
|
*/
|
||||||
|
void mcp23018_init(uint8_t slave_addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure input/output to a given port
|
||||||
|
*/
|
||||||
|
bool mcp23018_set_config(uint8_t slave_addr, mcp23018_port_t port, uint8_t conf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write high/low to a given port
|
||||||
|
*/
|
||||||
|
bool mcp23018_set_output(uint8_t slave_addr, mcp23018_port_t port, uint8_t conf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write high/low to both ports sequentially
|
||||||
|
*
|
||||||
|
* - slightly faster than multiple set_output
|
||||||
|
*/
|
||||||
|
bool mcp23018_set_output_all(uint8_t slave_addr, uint8_t confA, uint8_t confB);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read state of a given port
|
||||||
|
*/
|
||||||
|
bool mcp23018_readPins(uint8_t slave_addr, mcp23018_port_t port, uint8_t* ret);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read state of both ports sequentially
|
||||||
|
*
|
||||||
|
* - slightly faster than multiple readPins
|
||||||
|
*/
|
||||||
|
bool mcp23018_readPins_all(uint8_t slave_addr, uint16_t* ret);
|
|
@ -1,18 +1,6 @@
|
||||||
/* Copyright 2019
|
// Copyright 2020 zvecr<git@zvecr.com>
|
||||||
*
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#include "i2c_master.h"
|
#include "i2c_master.h"
|
||||||
#include "pca9555.h"
|
#include "pca9555.h"
|
||||||
|
|
||||||
|
@ -45,39 +33,59 @@ void pca9555_init(uint8_t slave_addr) {
|
||||||
// i2c_stop();
|
// i2c_stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pca9555_set_config(uint8_t slave_addr, uint8_t port, uint8_t conf) {
|
bool pca9555_set_config(uint8_t slave_addr, pca9555_port_t port, uint8_t conf) {
|
||||||
uint8_t addr = SLAVE_TO_ADDR(slave_addr);
|
uint8_t addr = SLAVE_TO_ADDR(slave_addr);
|
||||||
uint8_t cmd = port ? CMD_CONFIG_1 : CMD_CONFIG_0;
|
uint8_t cmd = port ? CMD_CONFIG_1 : CMD_CONFIG_0;
|
||||||
|
|
||||||
i2c_status_t ret = i2c_writeReg(addr, cmd, &conf, sizeof(conf), TIMEOUT);
|
i2c_status_t ret = i2c_writeReg(addr, cmd, &conf, sizeof(conf), TIMEOUT);
|
||||||
if (ret != I2C_STATUS_SUCCESS) {
|
if (ret != I2C_STATUS_SUCCESS) {
|
||||||
print("pca9555_set_config::FAILED\n");
|
print("pca9555_set_config::FAILED\n");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pca9555_set_output(uint8_t slave_addr, uint8_t port, uint8_t conf) {
|
bool pca9555_set_output(uint8_t slave_addr, pca9555_port_t port, uint8_t conf) {
|
||||||
uint8_t addr = SLAVE_TO_ADDR(slave_addr);
|
uint8_t addr = SLAVE_TO_ADDR(slave_addr);
|
||||||
uint8_t cmd = port ? CMD_OUTPUT_1 : CMD_OUTPUT_0;
|
uint8_t cmd = port ? CMD_OUTPUT_1 : CMD_OUTPUT_0;
|
||||||
|
|
||||||
i2c_status_t ret = i2c_writeReg(addr, cmd, &conf, sizeof(conf), TIMEOUT);
|
i2c_status_t ret = i2c_writeReg(addr, cmd, &conf, sizeof(conf), TIMEOUT);
|
||||||
if (ret != I2C_STATUS_SUCCESS) {
|
if (ret != I2C_STATUS_SUCCESS) {
|
||||||
print("pca9555_set_output::FAILED\n");
|
print("pca9555_set_output::FAILED\n");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t pca9555_readPins(uint8_t slave_addr, uint8_t port) {
|
bool pca9555_set_output_all(uint8_t slave_addr, uint8_t confA, uint8_t confB) {
|
||||||
|
uint8_t addr = SLAVE_TO_ADDR(slave_addr);
|
||||||
|
uint8_t conf[2] = {confA, confB};
|
||||||
|
|
||||||
|
i2c_status_t ret = i2c_writeReg(addr, CMD_OUTPUT_0, &conf[0], sizeof(conf), TIMEOUT);
|
||||||
|
if (ret != I2C_STATUS_SUCCESS) {
|
||||||
|
dprintf("pca9555_set_output::FAILED::%u\n", ret);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pca9555_readPins(uint8_t slave_addr, pca9555_port_t port, uint8_t* out) {
|
||||||
uint8_t addr = SLAVE_TO_ADDR(slave_addr);
|
uint8_t addr = SLAVE_TO_ADDR(slave_addr);
|
||||||
uint8_t cmd = port ? CMD_INPUT_1 : CMD_INPUT_0;
|
uint8_t cmd = port ? CMD_INPUT_1 : CMD_INPUT_0;
|
||||||
|
|
||||||
uint8_t data = 0;
|
i2c_status_t ret = i2c_readReg(addr, cmd, out, sizeof(uint8_t), TIMEOUT);
|
||||||
i2c_status_t ret = i2c_readReg(addr, cmd, &data, sizeof(data), TIMEOUT);
|
|
||||||
if (ret != I2C_STATUS_SUCCESS) {
|
if (ret != I2C_STATUS_SUCCESS) {
|
||||||
print("pca9555_readPins::FAILED\n");
|
print("pca9555_readPins::FAILED\n");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return data;
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t pca9555_readAllPins(uint8_t slave_addr) {
|
bool pca9555_readPins_all(uint8_t slave_addr, uint16_t* out) {
|
||||||
uint8_t addr = SLAVE_TO_ADDR(slave_addr);
|
uint8_t addr = SLAVE_TO_ADDR(slave_addr);
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
|
@ -85,11 +93,14 @@ uint16_t pca9555_readAllPins(uint8_t slave_addr) {
|
||||||
uint16_t u16;
|
uint16_t u16;
|
||||||
} data16;
|
} data16;
|
||||||
|
|
||||||
data16 data;
|
data16 data = {.u16 = 0};
|
||||||
|
|
||||||
i2c_status_t ret = i2c_readReg(addr, CMD_INPUT_0, &data.u8[0], sizeof(data), TIMEOUT);
|
i2c_status_t ret = i2c_readReg(addr, CMD_INPUT_0, &data.u8[0], sizeof(data), TIMEOUT);
|
||||||
if (ret != I2C_STATUS_SUCCESS) {
|
if (ret != I2C_STATUS_SUCCESS) {
|
||||||
print("pca9555_readAllPins::FAILED\n");
|
print("pca9555_readPins_all::FAILED\n");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return data.u16;
|
|
||||||
|
*out = data.u16;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,11 @@
|
||||||
/* Copyright 2019
|
// Copyright 2020 zvecr<git@zvecr.com>
|
||||||
*
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PCA9555
|
PCA9555
|
||||||
,----------.
|
,----------.
|
||||||
|
@ -38,20 +29,60 @@
|
||||||
`----------'
|
`----------'
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PCA9555_PORT0 0
|
/**
|
||||||
#define PCA9555_PORT1 1
|
* Port ID
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
PCA9555_PORT0,
|
||||||
|
PCA9555_PORT1,
|
||||||
|
} pca9555_port_t;
|
||||||
|
|
||||||
#define ALL_OUTPUT 0
|
/**
|
||||||
#define ALL_INPUT 0xFF
|
* Helpers for set_config
|
||||||
#define ALL_LOW 0
|
*/
|
||||||
#define ALL_HIGH 0xFF
|
enum {
|
||||||
|
ALL_OUTPUT = 0,
|
||||||
|
ALL_INPUT = 0xFF,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helpers for set_output
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
ALL_LOW = 0,
|
||||||
|
ALL_HIGH = 0xFF,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init expander and any other dependent drivers
|
||||||
|
*/
|
||||||
void pca9555_init(uint8_t slave_addr);
|
void pca9555_init(uint8_t slave_addr);
|
||||||
|
|
||||||
void pca9555_set_config(uint8_t slave_addr, uint8_t port, uint8_t conf);
|
/**
|
||||||
|
* Configure input/output to a given port
|
||||||
|
*/
|
||||||
|
bool pca9555_set_config(uint8_t slave_addr, pca9555_port_t port, uint8_t conf);
|
||||||
|
|
||||||
void pca9555_set_output(uint8_t slave_addr, uint8_t port, uint8_t conf);
|
/**
|
||||||
|
* Write high/low to a given port
|
||||||
|
*/
|
||||||
|
bool pca9555_set_output(uint8_t slave_addr, pca9555_port_t port, uint8_t conf);
|
||||||
|
|
||||||
uint8_t pca9555_readPins(uint8_t slave_addr, uint8_t port);
|
/**
|
||||||
|
* Write high/low to both ports sequentially
|
||||||
|
*
|
||||||
|
* - slightly faster than multiple set_output
|
||||||
|
*/
|
||||||
|
bool pca9555_set_output_all(uint8_t slave_addr, uint8_t confA, uint8_t confB);
|
||||||
|
|
||||||
uint16_t pca9555_readAllPins(uint8_t slave_addr);
|
/**
|
||||||
|
* Read state of a given port
|
||||||
|
*/
|
||||||
|
bool pca9555_readPins(uint8_t slave_addr, pca9555_port_t port, uint8_t* ret);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read state of both ports sequentially
|
||||||
|
*
|
||||||
|
* - slightly faster than multiple readPins
|
||||||
|
*/
|
||||||
|
bool pca9555_readPins_all(uint8_t slave_addr, uint16_t* ret);
|
||||||
|
|
65
drivers/gpio/sn74x138.c
Normal file
65
drivers/gpio/sn74x138.c
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/* Copyright 2022
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sn74x138.h"
|
||||||
|
#include "gpio.h"
|
||||||
|
|
||||||
|
#define ADDRESS_PIN_COUNT 3
|
||||||
|
|
||||||
|
#ifndef SN74X138_ADDRESS_PINS
|
||||||
|
# error sn74x138: no address pins defined!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const pin_t address_pins[ADDRESS_PIN_COUNT] = SN74X138_ADDRESS_PINS;
|
||||||
|
|
||||||
|
void sn74x138_init(void) {
|
||||||
|
for (int i = 0; i < ADDRESS_PIN_COUNT; i++) {
|
||||||
|
setPinOutput(address_pins[i]);
|
||||||
|
writePinLow(address_pins[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(SN74X138_E1_PIN)
|
||||||
|
setPinOutput(SN74X138_E1_PIN);
|
||||||
|
writePinHigh(SN74X138_E1_PIN);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(SN74X138_E2_PIN)
|
||||||
|
setPinOutput(SN74X138_E2_PIN);
|
||||||
|
writePinHigh(SN74X138_E2_PIN);
|
||||||
|
#endif
|
||||||
|
#if defined(SN74X138_E3_PIN)
|
||||||
|
setPinOutput(SN74X138_E3_PIN);
|
||||||
|
writePinLow(SN74X138_E3_PIN);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void sn74x138_set_enabled(bool enabled) {
|
||||||
|
#if defined(SN74X138_E1_PIN)
|
||||||
|
writePin(SN74X138_E1_PIN, !enabled);
|
||||||
|
#endif
|
||||||
|
#if defined(SN74X138_E2_PIN)
|
||||||
|
writePin(SN74X138_E2_PIN, !enabled);
|
||||||
|
#endif
|
||||||
|
#if defined(SN74X138_E3_PIN)
|
||||||
|
writePin(SN74X138_E3_PIN, enabled);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void sn74x138_set_addr(uint8_t address) {
|
||||||
|
for (int i = 0; i < ADDRESS_PIN_COUNT; i++) {
|
||||||
|
writePin(address_pins[i], address & (1 << i));
|
||||||
|
}
|
||||||
|
}
|
48
drivers/gpio/sn74x138.h
Normal file
48
drivers/gpio/sn74x138.h
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/* Copyright 2022
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Driver for 74x138 3-to-8 decoder/demultiplexer with inverting outputs
|
||||||
|
* https://assets.nexperia.com/documents/data-sheet/74HC_HCT138.pdf
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the address and output enable pins.
|
||||||
|
*/
|
||||||
|
void sn74x138_init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the enabled state.
|
||||||
|
*
|
||||||
|
* When enabled is true, pulls the E1 and E2 pins low, and the E3 pin high.
|
||||||
|
*
|
||||||
|
* \param enabled The enable state to set.
|
||||||
|
*/
|
||||||
|
void sn74x138_set_enabled(bool enabled);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the output pin address.
|
||||||
|
*
|
||||||
|
* The selected output pin will be pulled low, while the remaining output pins will be high.
|
||||||
|
*
|
||||||
|
* \param address The address to set, from 0 to 7.
|
||||||
|
*/
|
||||||
|
void sn74x138_set_addr(uint8_t address);
|
|
@ -106,12 +106,14 @@ void DRV_init(void) {
|
||||||
|
|
||||||
void DRV_rtp_init(void) {
|
void DRV_rtp_init(void) {
|
||||||
DRV_write(DRV_GO, 0x00);
|
DRV_write(DRV_GO, 0x00);
|
||||||
DRV_write(DRV_RTP_INPUT, 20); // 20 is the lowest value I've found where haptics can still be felt.
|
DRV_write(DRV_RTP_INPUT, 20); // 20 is the lowest value I've found where haptics can still be felt.
|
||||||
DRV_write(DRV_MODE, 0x05);
|
DRV_write(DRV_MODE, 0x05);
|
||||||
DRV_write(DRV_GO, 0x01);
|
DRV_write(DRV_GO, 0x01);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DRV_amplitude(uint8_t amplitude) { DRV_write(DRV_RTP_INPUT, amplitude); }
|
void DRV_amplitude(uint8_t amplitude) {
|
||||||
|
DRV_write(DRV_RTP_INPUT, amplitude);
|
||||||
|
}
|
||||||
|
|
||||||
void DRV_pulse(uint8_t sequence) {
|
void DRV_pulse(uint8_t sequence) {
|
||||||
DRV_write(DRV_GO, 0x00);
|
DRV_write(DRV_GO, 0x00);
|
||||||
|
|
|
@ -28,13 +28,21 @@ uint8_t solenoid_dwell = SOLENOID_DEFAULT_DWELL;
|
||||||
|
|
||||||
extern haptic_config_t haptic_config;
|
extern haptic_config_t haptic_config;
|
||||||
|
|
||||||
void solenoid_buzz_on(void) { haptic_set_buzz(1); }
|
void solenoid_buzz_on(void) {
|
||||||
|
haptic_set_buzz(1);
|
||||||
|
}
|
||||||
|
|
||||||
void solenoid_buzz_off(void) { haptic_set_buzz(0); }
|
void solenoid_buzz_off(void) {
|
||||||
|
haptic_set_buzz(0);
|
||||||
|
}
|
||||||
|
|
||||||
void solenoid_set_buzz(int buzz) { haptic_set_buzz(buzz); }
|
void solenoid_set_buzz(int buzz) {
|
||||||
|
haptic_set_buzz(buzz);
|
||||||
|
}
|
||||||
|
|
||||||
void solenoid_set_dwell(uint8_t dwell) { solenoid_dwell = dwell; }
|
void solenoid_set_dwell(uint8_t dwell) {
|
||||||
|
solenoid_dwell = dwell;
|
||||||
|
}
|
||||||
|
|
||||||
void solenoid_stop(void) {
|
void solenoid_stop(void) {
|
||||||
SOLENOID_PIN_WRITE_INACTIVE();
|
SOLENOID_PIN_WRITE_INACTIVE();
|
||||||
|
@ -89,4 +97,6 @@ void solenoid_setup(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void solenoid_shutdown(void) { SOLENOID_PIN_WRITE_INACTIVE(); }
|
void solenoid_shutdown(void) {
|
||||||
|
SOLENOID_PIN_WRITE_INACTIVE();
|
||||||
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
// Addressing Setting Commands
|
// Addressing Setting Commands
|
||||||
#define PAM_SETCOLUMN_LSB 0x00
|
#define PAM_SETCOLUMN_LSB 0x00
|
||||||
#define PAM_SETCOLUMN_MSB 0x10
|
#define PAM_SETCOLUMN_MSB 0x10
|
||||||
#define PAM_PAGE_ADDR 0xB0 // 0xb0 -- 0xb7
|
#define PAM_PAGE_ADDR 0xB0 // 0xb0 -- 0xb7
|
||||||
|
|
||||||
// Hardware Configuration Commands
|
// Hardware Configuration Commands
|
||||||
#define DISPLAY_START_LINE 0x40
|
#define DISPLAY_START_LINE 0x40
|
||||||
|
@ -138,7 +138,9 @@ bool st7565_init(display_rotation_t rotation) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((weak)) display_rotation_t st7565_init_user(display_rotation_t rotation) { return rotation; }
|
__attribute__((weak)) display_rotation_t st7565_init_user(display_rotation_t rotation) {
|
||||||
|
return rotation;
|
||||||
|
}
|
||||||
|
|
||||||
void st7565_clear(void) {
|
void st7565_clear(void) {
|
||||||
memset(st7565_buffer, 0, sizeof(st7565_buffer));
|
memset(st7565_buffer, 0, sizeof(st7565_buffer));
|
||||||
|
@ -212,7 +214,8 @@ void st7565_advance_page(bool clearPageRemainder) {
|
||||||
remaining = remaining / ST7565_FONT_WIDTH;
|
remaining = remaining / ST7565_FONT_WIDTH;
|
||||||
|
|
||||||
// Write empty character until next line
|
// Write empty character until next line
|
||||||
while (remaining--) st7565_write_char(' ', false);
|
while (remaining--)
|
||||||
|
st7565_write_char(' ', false);
|
||||||
} else {
|
} else {
|
||||||
// Next page index out of bounds?
|
// Next page index out of bounds?
|
||||||
if (index + remaining >= ST7565_MATRIX_SIZE) {
|
if (index + remaining >= ST7565_MATRIX_SIZE) {
|
||||||
|
@ -263,7 +266,7 @@ void st7565_write_char(const char data, bool invert) {
|
||||||
_Static_assert(sizeof(font) >= ((ST7565_FONT_END + 1 - ST7565_FONT_START) * ST7565_FONT_WIDTH), "ST7565_FONT_END references outside array");
|
_Static_assert(sizeof(font) >= ((ST7565_FONT_END + 1 - ST7565_FONT_START) * ST7565_FONT_WIDTH), "ST7565_FONT_END references outside array");
|
||||||
|
|
||||||
// set the reder buffer data
|
// set the reder buffer data
|
||||||
uint8_t cast_data = (uint8_t)data; // font based on unsigned type for index
|
uint8_t cast_data = (uint8_t)data; // font based on unsigned type for index
|
||||||
if (cast_data < ST7565_FONT_START || cast_data > ST7565_FONT_END) {
|
if (cast_data < ST7565_FONT_START || cast_data > ST7565_FONT_END) {
|
||||||
memset(st7565_cursor, 0x00, ST7565_FONT_WIDTH);
|
memset(st7565_cursor, 0x00, ST7565_FONT_WIDTH);
|
||||||
} else {
|
} else {
|
||||||
|
@ -389,7 +392,7 @@ void st7565_write_raw_P(const char *data, uint16_t size) {
|
||||||
st7565_dirty |= ((ST7565_BLOCK_TYPE)1 << (i / ST7565_BLOCK_SIZE));
|
st7565_dirty |= ((ST7565_BLOCK_TYPE)1 << (i / ST7565_BLOCK_SIZE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // defined(__AVR__)
|
#endif // defined(__AVR__)
|
||||||
|
|
||||||
bool st7565_on(void) {
|
bool st7565_on(void) {
|
||||||
if (!st7565_initialized) {
|
if (!st7565_initialized) {
|
||||||
|
@ -429,7 +432,9 @@ bool st7565_off(void) {
|
||||||
|
|
||||||
__attribute__((weak)) void st7565_off_user(void) {}
|
__attribute__((weak)) void st7565_off_user(void) {}
|
||||||
|
|
||||||
bool st7565_is_on(void) { return st7565_active; }
|
bool st7565_is_on(void) {
|
||||||
|
return st7565_active;
|
||||||
|
}
|
||||||
|
|
||||||
bool st7565_invert(bool invert) {
|
bool st7565_invert(bool invert) {
|
||||||
if (!st7565_initialized) {
|
if (!st7565_initialized) {
|
||||||
|
@ -445,9 +450,13 @@ bool st7565_invert(bool invert) {
|
||||||
return st7565_inverted;
|
return st7565_inverted;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t st7565_max_chars(void) { return ST7565_DISPLAY_WIDTH / ST7565_FONT_WIDTH; }
|
uint8_t st7565_max_chars(void) {
|
||||||
|
return ST7565_DISPLAY_WIDTH / ST7565_FONT_WIDTH;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t st7565_max_lines(void) { return ST7565_DISPLAY_HEIGHT / ST7565_FONT_HEIGHT; }
|
uint8_t st7565_max_lines(void) {
|
||||||
|
return ST7565_DISPLAY_HEIGHT / ST7565_FONT_HEIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
void st7565_task(void) {
|
void st7565_task(void) {
|
||||||
if (!st7565_initialized) {
|
if (!st7565_initialized) {
|
||||||
|
|
|
@ -29,16 +29,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
# define ST7565_DISPLAY_HEIGHT 32
|
# define ST7565_DISPLAY_HEIGHT 32
|
||||||
#endif
|
#endif
|
||||||
#ifndef ST7565_MATRIX_SIZE
|
#ifndef ST7565_MATRIX_SIZE
|
||||||
# define ST7565_MATRIX_SIZE (ST7565_DISPLAY_HEIGHT / 8 * ST7565_DISPLAY_WIDTH) // 1024 (compile time mathed)
|
# define ST7565_MATRIX_SIZE (ST7565_DISPLAY_HEIGHT / 8 * ST7565_DISPLAY_WIDTH) // 1024 (compile time mathed)
|
||||||
#endif
|
#endif
|
||||||
#ifndef ST7565_BLOCK_TYPE
|
#ifndef ST7565_BLOCK_TYPE
|
||||||
# define ST7565_BLOCK_TYPE uint16_t
|
# define ST7565_BLOCK_TYPE uint16_t
|
||||||
#endif
|
#endif
|
||||||
#ifndef ST7565_BLOCK_COUNT
|
#ifndef ST7565_BLOCK_COUNT
|
||||||
# define ST7565_BLOCK_COUNT (sizeof(ST7565_BLOCK_TYPE) * 8) // 32 (compile time mathed)
|
# define ST7565_BLOCK_COUNT (sizeof(ST7565_BLOCK_TYPE) * 8) // 32 (compile time mathed)
|
||||||
#endif
|
#endif
|
||||||
#ifndef ST7565_BLOCK_SIZE
|
#ifndef ST7565_BLOCK_SIZE
|
||||||
# define ST7565_BLOCK_SIZE (ST7565_MATRIX_SIZE / ST7565_BLOCK_COUNT) // 32 (compile time mathed)
|
# define ST7565_BLOCK_SIZE (ST7565_MATRIX_SIZE / ST7565_BLOCK_COUNT) // 32 (compile time mathed)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// the column address corresponding to the first column in the display hardware
|
// the column address corresponding to the first column in the display hardware
|
||||||
|
@ -174,7 +174,7 @@ void st7565_write_raw_P(const char *data, uint16_t size);
|
||||||
# define st7565_write_P(data, invert) st7565_write(data, invert)
|
# define st7565_write_P(data, invert) st7565_write(data, invert)
|
||||||
# define st7565_write_ln_P(data, invert) st7565_write_ln(data, invert)
|
# define st7565_write_ln_P(data, invert) st7565_write_ln(data, invert)
|
||||||
# define st7565_write_raw_P(data, size) st7565_write_raw(data, size)
|
# define st7565_write_raw_P(data, size) st7565_write_raw(data, size)
|
||||||
#endif // defined(__AVR__)
|
#endif // defined(__AVR__)
|
||||||
|
|
||||||
// Can be used to manually turn on the screen if it is off
|
// Can be used to manually turn on the screen if it is off
|
||||||
// Returns true if the screen was on or turns on
|
// Returns true if the screen was on or turns on
|
||||||
|
|
|
@ -20,15 +20,15 @@
|
||||||
|
|
||||||
#ifndef APA102_NOPS
|
#ifndef APA102_NOPS
|
||||||
# if defined(__AVR__)
|
# if defined(__AVR__)
|
||||||
# define APA102_NOPS 0 // AVR at 16 MHz already spends 62.5 ns per clock, so no extra delay is needed
|
# define APA102_NOPS 0 // AVR at 16 MHz already spends 62.5 ns per clock, so no extra delay is needed
|
||||||
# elif defined(PROTOCOL_CHIBIOS)
|
# elif defined(PROTOCOL_CHIBIOS)
|
||||||
|
|
||||||
# include "hal.h"
|
# include "hal.h"
|
||||||
# if defined(STM32F0XX) || defined(STM32F1XX) || defined(STM32F3XX) || defined(STM32F4XX) || defined(STM32L0XX) || defined(GD32VF103)
|
# if defined(STM32F0XX) || defined(STM32F1XX) || defined(STM32F3XX) || defined(STM32F4XX) || defined(STM32L0XX) || defined(GD32VF103)
|
||||||
# define APA102_NOPS (100 / (1000000000L / (CPU_CLOCK / 4))) // This calculates how many loops of 4 nops to run to delay 100 ns
|
# define APA102_NOPS (100 / (1000000000L / (CPU_CLOCK / 4))) // This calculates how many loops of 4 nops to run to delay 100 ns
|
||||||
# else
|
# else
|
||||||
# error("APA102_NOPS configuration required")
|
# error("APA102_NOPS configuration required")
|
||||||
# define APA102_NOPS 0 // this just pleases the compile so the above error is easier to spot
|
# define APA102_NOPS 0 // this just pleases the compile so the above error is easier to spot
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -72,7 +72,9 @@ void apa102_setleds(LED_TYPE *start_led, uint16_t num_leds) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overwrite the default rgblight_call_driver to use apa102 driver
|
// Overwrite the default rgblight_call_driver to use apa102 driver
|
||||||
void rgblight_call_driver(LED_TYPE *start_led, uint8_t num_leds) { apa102_setleds(start_led, num_leds); }
|
void rgblight_call_driver(LED_TYPE *start_led, uint8_t num_leds) {
|
||||||
|
apa102_setleds(start_led, num_leds);
|
||||||
|
}
|
||||||
|
|
||||||
void static apa102_init(void) {
|
void static apa102_init(void) {
|
||||||
setPinOutput(RGB_DI_PIN);
|
setPinOutput(RGB_DI_PIN);
|
||||||
|
|
|
@ -23,17 +23,17 @@
|
||||||
*/
|
*/
|
||||||
#define AWINIC_ID 0b1010 << 4
|
#define AWINIC_ID 0b1010 << 4
|
||||||
|
|
||||||
#define AW_PAGE_FUNCTION 0x00 << 1 // PG0, Function registers
|
#define AW_PAGE_FUNCTION 0x00 << 1 // PG0, Function registers
|
||||||
#define AW_PAGE_PWM 0x01 << 1 // PG1, LED PWM control
|
#define AW_PAGE_PWM 0x01 << 1 // PG1, LED PWM control
|
||||||
#define AW_PAGE_SCALING 0x02 << 1 // PG2, LED current scaling control
|
#define AW_PAGE_SCALING 0x02 << 1 // PG2, LED current scaling control
|
||||||
#define AW_PAGE_PATCHOICE 0x03 << 1 // PG3, Pattern choice?
|
#define AW_PAGE_PATCHOICE 0x03 << 1 // PG3, Pattern choice?
|
||||||
#define AW_PAGE_PWMSCALING 0x04 << 1 // PG4, LED PWM + Scaling control?
|
#define AW_PAGE_PWMSCALING 0x04 << 1 // PG4, LED PWM + Scaling control?
|
||||||
|
|
||||||
#define AW_WRITE 0
|
#define AW_WRITE 0
|
||||||
#define AW_READ 1
|
#define AW_READ 1
|
||||||
|
|
||||||
#define AW_REG_CONFIGURATION 0x00 // PG0
|
#define AW_REG_CONFIGURATION 0x00 // PG0
|
||||||
#define AW_REG_GLOBALCURRENT 0x01 // PG0
|
#define AW_REG_GLOBALCURRENT 0x01 // PG0
|
||||||
|
|
||||||
// Default value of AW_REG_CONFIGURATION
|
// Default value of AW_REG_CONFIGURATION
|
||||||
// D7:D4 = 1011, SWSEL (SW1~SW12 active)
|
// D7:D4 = 1011, SWSEL (SW1~SW12 active)
|
||||||
|
|
|
@ -125,7 +125,16 @@ void CKLED2001_init(uint8_t addr) {
|
||||||
// Set CURRENT PAGE (Page 4)
|
// Set CURRENT PAGE (Page 4)
|
||||||
CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, CURRENT_TUNE_PAGE);
|
CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, CURRENT_TUNE_PAGE);
|
||||||
for (int i = 0; i < LED_CURRENT_TUNE_LENGTH; i++) {
|
for (int i = 0; i < LED_CURRENT_TUNE_LENGTH; i++) {
|
||||||
CKLED2001_write_register(addr, i, 0xFF);
|
switch (i) {
|
||||||
|
case 2:
|
||||||
|
case 5:
|
||||||
|
case 8:
|
||||||
|
case 11:
|
||||||
|
CKLED2001_write_register(addr, i, 0xA0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
CKLED2001_write_register(addr, i, 0xFF);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable LEDs ON/OFF
|
// Enable LEDs ON/OFF
|
||||||
|
|
|
@ -42,13 +42,13 @@
|
||||||
#define ISSI_REG_PICTUREFRAME 0x01
|
#define ISSI_REG_PICTUREFRAME 0x01
|
||||||
|
|
||||||
// Not defined in the datasheet -- See AN for IC
|
// Not defined in the datasheet -- See AN for IC
|
||||||
#define ISSI_REG_GHOST_IMAGE_PREVENTION 0xC2 // Set bit 4 to enable de-ghosting
|
#define ISSI_REG_GHOST_IMAGE_PREVENTION 0xC2 // Set bit 4 to enable de-ghosting
|
||||||
|
|
||||||
#define ISSI_REG_SHUTDOWN 0x0A
|
#define ISSI_REG_SHUTDOWN 0x0A
|
||||||
#define ISSI_REG_AUDIOSYNC 0x06
|
#define ISSI_REG_AUDIOSYNC 0x06
|
||||||
|
|
||||||
#define ISSI_COMMANDREGISTER 0xFD
|
#define ISSI_COMMANDREGISTER 0xFD
|
||||||
#define ISSI_BANK_FUNCTIONREG 0x0B // helpfully called 'page nine'
|
#define ISSI_BANK_FUNCTIONREG 0x0B // helpfully called 'page nine'
|
||||||
|
|
||||||
#ifndef ISSI_TIMEOUT
|
#ifndef ISSI_TIMEOUT
|
||||||
# define ISSI_TIMEOUT 100
|
# define ISSI_TIMEOUT 100
|
||||||
|
@ -148,7 +148,7 @@ void IS31FL3731_init(uint8_t addr) {
|
||||||
|
|
||||||
// enable software shutdown
|
// enable software shutdown
|
||||||
IS31FL3731_write_register(addr, ISSI_REG_SHUTDOWN, 0x00);
|
IS31FL3731_write_register(addr, ISSI_REG_SHUTDOWN, 0x00);
|
||||||
#ifdef ISSI_3731_DEGHOST // set to enable de-ghosting of the array
|
#ifdef ISSI_3731_DEGHOST // set to enable de-ghosting of the array
|
||||||
IS31FL3731_write_register(addr, ISSI_REG_GHOST_IMAGE_PREVENTION, 0x10);
|
IS31FL3731_write_register(addr, ISSI_REG_GHOST_IMAGE_PREVENTION, 0x10);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -41,13 +41,13 @@
|
||||||
#define ISSI_REG_PICTUREFRAME 0x01
|
#define ISSI_REG_PICTUREFRAME 0x01
|
||||||
|
|
||||||
// Not defined in the datasheet -- See AN for IC
|
// Not defined in the datasheet -- See AN for IC
|
||||||
#define ISSI_REG_GHOST_IMAGE_PREVENTION 0xC2 // Set bit 4 to enable de-ghosting
|
#define ISSI_REG_GHOST_IMAGE_PREVENTION 0xC2 // Set bit 4 to enable de-ghosting
|
||||||
|
|
||||||
#define ISSI_REG_SHUTDOWN 0x0A
|
#define ISSI_REG_SHUTDOWN 0x0A
|
||||||
#define ISSI_REG_AUDIOSYNC 0x06
|
#define ISSI_REG_AUDIOSYNC 0x06
|
||||||
|
|
||||||
#define ISSI_COMMANDREGISTER 0xFD
|
#define ISSI_COMMANDREGISTER 0xFD
|
||||||
#define ISSI_BANK_FUNCTIONREG 0x0B // helpfully called 'page nine'
|
#define ISSI_BANK_FUNCTIONREG 0x0B // helpfully called 'page nine'
|
||||||
|
|
||||||
#ifndef ISSI_TIMEOUT
|
#ifndef ISSI_TIMEOUT
|
||||||
# define ISSI_TIMEOUT 100
|
# define ISSI_TIMEOUT 100
|
||||||
|
@ -136,7 +136,7 @@ void IS31FL3731_init(uint8_t addr) {
|
||||||
|
|
||||||
// enable software shutdown
|
// enable software shutdown
|
||||||
IS31FL3731_write_register(addr, ISSI_REG_SHUTDOWN, 0x00);
|
IS31FL3731_write_register(addr, ISSI_REG_SHUTDOWN, 0x00);
|
||||||
#ifdef ISSI_3731_DEGHOST // set to enable de-ghosting of the array
|
#ifdef ISSI_3731_DEGHOST // set to enable de-ghosting of the array
|
||||||
IS31FL3731_write_register(addr, ISSI_REG_GHOST_IMAGE_PREVENTION, 0x10);
|
IS31FL3731_write_register(addr, ISSI_REG_GHOST_IMAGE_PREVENTION, 0x10);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
248
drivers/led/issi/is31fl3733-simple.c
Normal file
248
drivers/led/issi/is31fl3733-simple.c
Normal file
|
@ -0,0 +1,248 @@
|
||||||
|
/* Copyright 2017 Jason Williams
|
||||||
|
* Copyright 2018 Jack Humbert
|
||||||
|
* Copyright 2018 Yiancar
|
||||||
|
* Copyright 2021 Doni Crosby
|
||||||
|
* Copyright 2021 Leo Deng
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "is31fl3733-simple.h"
|
||||||
|
#include "i2c_master.h"
|
||||||
|
#include "wait.h"
|
||||||
|
|
||||||
|
// This is a 7-bit address, that gets left-shifted and bit 0
|
||||||
|
// set to 0 for write, 1 for read (as per I2C protocol)
|
||||||
|
// The address will vary depending on your wiring:
|
||||||
|
// 00 <-> GND
|
||||||
|
// 01 <-> SCL
|
||||||
|
// 10 <-> SDA
|
||||||
|
// 11 <-> VCC
|
||||||
|
// ADDR1 represents A1:A0 of the 7-bit address.
|
||||||
|
// ADDR2 represents A3:A2 of the 7-bit address.
|
||||||
|
// The result is: 0b101(ADDR2)(ADDR1)
|
||||||
|
#define ISSI_ADDR_DEFAULT 0x50
|
||||||
|
|
||||||
|
#define ISSI_COMMANDREGISTER 0xFD
|
||||||
|
#define ISSI_COMMANDREGISTER_WRITELOCK 0xFE
|
||||||
|
#define ISSI_INTERRUPTMASKREGISTER 0xF0
|
||||||
|
#define ISSI_INTERRUPTSTATUSREGISTER 0xF1
|
||||||
|
|
||||||
|
#define ISSI_PAGE_LEDCONTROL 0x00 // PG0
|
||||||
|
#define ISSI_PAGE_PWM 0x01 // PG1
|
||||||
|
#define ISSI_PAGE_AUTOBREATH 0x02 // PG2
|
||||||
|
#define ISSI_PAGE_FUNCTION 0x03 // PG3
|
||||||
|
|
||||||
|
#define ISSI_REG_CONFIGURATION 0x00 // PG3
|
||||||
|
#define ISSI_REG_GLOBALCURRENT 0x01 // PG3
|
||||||
|
#define ISSI_REG_RESET 0x11 // PG3
|
||||||
|
#define ISSI_REG_SWPULLUP 0x0F // PG3
|
||||||
|
#define ISSI_REG_CSPULLUP 0x10 // PG3
|
||||||
|
|
||||||
|
#ifndef ISSI_TIMEOUT
|
||||||
|
# define ISSI_TIMEOUT 100
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ISSI_PERSISTENCE
|
||||||
|
# define ISSI_PERSISTENCE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ISSI_PWM_FREQUENCY
|
||||||
|
# define ISSI_PWM_FREQUENCY 0b000 // PFS - IS31FL3733B only
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ISSI_SWPULLUP
|
||||||
|
# define ISSI_SWPULLUP PUR_0R
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ISSI_CSPULLUP
|
||||||
|
# define ISSI_CSPULLUP PUR_0R
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Transfer buffer for TWITransmitData()
|
||||||
|
uint8_t g_twi_transfer_buffer[20];
|
||||||
|
|
||||||
|
// These buffers match the IS31FL3733 PWM registers.
|
||||||
|
// The control buffers match the PG0 LED On/Off registers.
|
||||||
|
// Storing them like this is optimal for I2C transfers to the registers.
|
||||||
|
// We could optimize this and take out the unused registers from these
|
||||||
|
// buffers and the transfers in IS31FL3733_write_pwm_buffer() but it's
|
||||||
|
// probably not worth the extra complexity.
|
||||||
|
uint8_t g_pwm_buffer[LED_DRIVER_COUNT][192];
|
||||||
|
bool g_pwm_buffer_update_required[LED_DRIVER_COUNT] = {false};
|
||||||
|
|
||||||
|
/* There's probably a better way to init this... */
|
||||||
|
#if LED_DRIVER_COUNT == 1
|
||||||
|
uint8_t g_led_control_registers[LED_DRIVER_COUNT][24] = {{0}};
|
||||||
|
#elif LED_DRIVER_COUNT == 2
|
||||||
|
uint8_t g_led_control_registers[LED_DRIVER_COUNT][24] = {{0}, {0}};
|
||||||
|
#elif LED_DRIVER_COUNT == 3
|
||||||
|
uint8_t g_led_control_registers[LED_DRIVER_COUNT][24] = {{0}, {0}, {0}};
|
||||||
|
#elif LED_DRIVER_COUNT == 4
|
||||||
|
uint8_t g_led_control_registers[LED_DRIVER_COUNT][24] = {{0}, {0}, {0}, {0}};
|
||||||
|
#endif
|
||||||
|
bool g_led_control_registers_update_required[LED_DRIVER_COUNT] = {false};
|
||||||
|
|
||||||
|
bool IS31FL3733_write_register(uint8_t addr, uint8_t reg, uint8_t data) {
|
||||||
|
// If the transaction fails function returns false.
|
||||||
|
g_twi_transfer_buffer[0] = reg;
|
||||||
|
g_twi_transfer_buffer[1] = data;
|
||||||
|
|
||||||
|
#if ISSI_PERSISTENCE > 0
|
||||||
|
for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) {
|
||||||
|
if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IS31FL3733_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) {
|
||||||
|
// Assumes PG1 is already selected.
|
||||||
|
// If any of the transactions fails function returns false.
|
||||||
|
// Transmit PWM registers in 12 transfers of 16 bytes.
|
||||||
|
// g_twi_transfer_buffer[] is 20 bytes
|
||||||
|
|
||||||
|
// Iterate over the pwm_buffer contents at 16 byte intervals.
|
||||||
|
for (int i = 0; i < 192; i += 16) {
|
||||||
|
g_twi_transfer_buffer[0] = i;
|
||||||
|
// Copy the data from i to i+15.
|
||||||
|
// Device will auto-increment register for data after the first byte
|
||||||
|
// Thus this sets registers 0x00-0x0F, 0x10-0x1F, etc. in one transfer.
|
||||||
|
for (int j = 0; j < 16; j++) {
|
||||||
|
g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j];
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ISSI_PERSISTENCE > 0
|
||||||
|
for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) {
|
||||||
|
if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IS31FL3733_init(uint8_t addr, uint8_t sync) {
|
||||||
|
// In order to avoid the LEDs being driven with garbage data
|
||||||
|
// in the LED driver's PWM registers, shutdown is enabled last.
|
||||||
|
// Set up the mode and other settings, clear the PWM registers,
|
||||||
|
// then disable software shutdown.
|
||||||
|
// Sync is passed so set it according to the datasheet.
|
||||||
|
|
||||||
|
// Unlock the command register.
|
||||||
|
IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5);
|
||||||
|
|
||||||
|
// Select PG0
|
||||||
|
IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL);
|
||||||
|
// Turn off all LEDs.
|
||||||
|
for (int i = 0x00; i <= 0x17; i++) {
|
||||||
|
IS31FL3733_write_register(addr, i, 0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unlock the command register.
|
||||||
|
IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5);
|
||||||
|
|
||||||
|
// Select PG1
|
||||||
|
IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM);
|
||||||
|
// Set PWM on all LEDs to 0
|
||||||
|
// No need to setup Breath registers to PWM as that is the default.
|
||||||
|
for (int i = 0x00; i <= 0xBF; i++) {
|
||||||
|
IS31FL3733_write_register(addr, i, 0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unlock the command register.
|
||||||
|
IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5);
|
||||||
|
|
||||||
|
// Select PG3
|
||||||
|
IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_FUNCTION);
|
||||||
|
// Set de-ghost pull-up resistors (SWx)
|
||||||
|
IS31FL3733_write_register(addr, ISSI_REG_SWPULLUP, ISSI_SWPULLUP);
|
||||||
|
// Set de-ghost pull-down resistors (CSx)
|
||||||
|
IS31FL3733_write_register(addr, ISSI_REG_CSPULLUP, ISSI_CSPULLUP);
|
||||||
|
// Set global current to maximum.
|
||||||
|
IS31FL3733_write_register(addr, ISSI_REG_GLOBALCURRENT, 0xFF);
|
||||||
|
// Disable software shutdown.
|
||||||
|
IS31FL3733_write_register(addr, ISSI_REG_CONFIGURATION, ((sync & 0b11) << 6) | ((ISSI_PWM_FREQUENCY & 0b111) << 3) | 0x01);
|
||||||
|
|
||||||
|
// Wait 10ms to ensure the device has woken up.
|
||||||
|
wait_ms(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IS31FL3733_set_value(int index, uint8_t value) {
|
||||||
|
if (index >= 0 && index < DRIVER_LED_TOTAL) {
|
||||||
|
is31_led led = g_is31_leds[index];
|
||||||
|
|
||||||
|
g_pwm_buffer[led.driver][led.v] = value;
|
||||||
|
g_pwm_buffer_update_required[led.driver] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IS31FL3733_set_value_all(uint8_t value) {
|
||||||
|
for (int i = 0; i < DRIVER_LED_TOTAL; i++) {
|
||||||
|
IS31FL3733_set_value(i, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IS31FL3733_set_led_control_register(uint8_t index, bool value) {
|
||||||
|
is31_led led = g_is31_leds[index];
|
||||||
|
|
||||||
|
uint8_t control_register = led.v / 8;
|
||||||
|
uint8_t bit_value = led.v % 8;
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
g_led_control_registers[led.driver][control_register] |= (1 << bit_value);
|
||||||
|
} else {
|
||||||
|
g_led_control_registers[led.driver][control_register] &= ~(1 << bit_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_led_control_registers_update_required[led.driver] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IS31FL3733_update_pwm_buffers(uint8_t addr, uint8_t index) {
|
||||||
|
if (g_pwm_buffer_update_required[index]) {
|
||||||
|
// Firstly we need to unlock the command register and select PG1.
|
||||||
|
IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5);
|
||||||
|
IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM);
|
||||||
|
|
||||||
|
// If any of the transactions fail we risk writing dirty PG0,
|
||||||
|
// refresh page 0 just in case.
|
||||||
|
if (!IS31FL3733_write_pwm_buffer(addr, g_pwm_buffer[index])) {
|
||||||
|
g_led_control_registers_update_required[index] = true;
|
||||||
|
}
|
||||||
|
g_pwm_buffer_update_required[index] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IS31FL3733_update_led_control_registers(uint8_t addr, uint8_t index) {
|
||||||
|
if (g_led_control_registers_update_required[index]) {
|
||||||
|
// Firstly we need to unlock the command register and select PG0
|
||||||
|
IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5);
|
||||||
|
IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL);
|
||||||
|
for (int i = 0; i < 24; i++) {
|
||||||
|
IS31FL3733_write_register(addr, i, g_led_control_registers[index][i]);
|
||||||
|
}
|
||||||
|
g_led_control_registers_update_required[index] = false;
|
||||||
|
}
|
||||||
|
}
|
260
drivers/led/issi/is31fl3733-simple.h
Normal file
260
drivers/led/issi/is31fl3733-simple.h
Normal file
|
@ -0,0 +1,260 @@
|
||||||
|
/* Copyright 2017 Jason Williams
|
||||||
|
* Copyright 2018 Jack Humbert
|
||||||
|
* Copyright 2018 Yiancar
|
||||||
|
* Copyright 2021 Doni Crosby
|
||||||
|
* Copyright 2021 Leo Deng
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "progmem.h"
|
||||||
|
|
||||||
|
typedef struct is31_led {
|
||||||
|
uint8_t driver : 2;
|
||||||
|
uint8_t v;
|
||||||
|
} __attribute__((packed)) is31_led;
|
||||||
|
|
||||||
|
extern const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL];
|
||||||
|
|
||||||
|
void IS31FL3733_init(uint8_t addr, uint8_t sync);
|
||||||
|
bool IS31FL3733_write_register(uint8_t addr, uint8_t reg, uint8_t data);
|
||||||
|
bool IS31FL3733_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer);
|
||||||
|
|
||||||
|
void IS31FL3733_set_value(int index, uint8_t value);
|
||||||
|
void IS31FL3733_set_value_all(uint8_t value);
|
||||||
|
|
||||||
|
void IS31FL3733_set_led_control_register(uint8_t index, bool value);
|
||||||
|
|
||||||
|
// This should not be called from an interrupt
|
||||||
|
// (eg. from a timer interrupt).
|
||||||
|
// Call this while idle (in between matrix scans).
|
||||||
|
// If the buffer is dirty, it will update the driver with the buffer.
|
||||||
|
void IS31FL3733_update_pwm_buffers(uint8_t addr, uint8_t index);
|
||||||
|
void IS31FL3733_update_led_control_registers(uint8_t addr, uint8_t index);
|
||||||
|
|
||||||
|
#define PUR_0R 0x00 // No PUR resistor
|
||||||
|
#define PUR_05KR 0x02 // 0.5k Ohm resistor in t_NOL
|
||||||
|
#define PUR_3KR 0x03 // 3.0k Ohm resistor on all the time
|
||||||
|
#define PUR_4KR 0x04 // 4.0k Ohm resistor on all the time
|
||||||
|
#define PUR_8KR 0x05 // 8.0k Ohm resistor on all the time
|
||||||
|
#define PUR_16KR 0x06 // 16k Ohm resistor on all the time
|
||||||
|
#define PUR_32KR 0x07 // 32k Ohm resistor in t_NOL
|
||||||
|
|
||||||
|
#define A_1 0x00
|
||||||
|
#define A_2 0x01
|
||||||
|
#define A_3 0x02
|
||||||
|
#define A_4 0x03
|
||||||
|
#define A_5 0x04
|
||||||
|
#define A_6 0x05
|
||||||
|
#define A_7 0x06
|
||||||
|
#define A_8 0x07
|
||||||
|
#define A_9 0x08
|
||||||
|
#define A_10 0x09
|
||||||
|
#define A_11 0x0A
|
||||||
|
#define A_12 0x0B
|
||||||
|
#define A_13 0x0C
|
||||||
|
#define A_14 0x0D
|
||||||
|
#define A_15 0x0E
|
||||||
|
#define A_16 0x0F
|
||||||
|
|
||||||
|
#define B_1 0x10
|
||||||
|
#define B_2 0x11
|
||||||
|
#define B_3 0x12
|
||||||
|
#define B_4 0x13
|
||||||
|
#define B_5 0x14
|
||||||
|
#define B_6 0x15
|
||||||
|
#define B_7 0x16
|
||||||
|
#define B_8 0x17
|
||||||
|
#define B_9 0x18
|
||||||
|
#define B_10 0x19
|
||||||
|
#define B_11 0x1A
|
||||||
|
#define B_12 0x1B
|
||||||
|
#define B_13 0x1C
|
||||||
|
#define B_14 0x1D
|
||||||
|
#define B_15 0x1E
|
||||||
|
#define B_16 0x1F
|
||||||
|
|
||||||
|
#define C_1 0x20
|
||||||
|
#define C_2 0x21
|
||||||
|
#define C_3 0x22
|
||||||
|
#define C_4 0x23
|
||||||
|
#define C_5 0x24
|
||||||
|
#define C_6 0x25
|
||||||
|
#define C_7 0x26
|
||||||
|
#define C_8 0x27
|
||||||
|
#define C_9 0x28
|
||||||
|
#define C_10 0x29
|
||||||
|
#define C_11 0x2A
|
||||||
|
#define C_12 0x2B
|
||||||
|
#define C_13 0x2C
|
||||||
|
#define C_14 0x2D
|
||||||
|
#define C_15 0x2E
|
||||||
|
#define C_16 0x2F
|
||||||
|
|
||||||
|
#define D_1 0x30
|
||||||
|
#define D_2 0x31
|
||||||
|
#define D_3 0x32
|
||||||
|
#define D_4 0x33
|
||||||
|
#define D_5 0x34
|
||||||
|
#define D_6 0x35
|
||||||
|
#define D_7 0x36
|
||||||
|
#define D_8 0x37
|
||||||
|
#define D_9 0x38
|
||||||
|
#define D_10 0x39
|
||||||
|
#define D_11 0x3A
|
||||||
|
#define D_12 0x3B
|
||||||
|
#define D_13 0x3C
|
||||||
|
#define D_14 0x3D
|
||||||
|
#define D_15 0x3E
|
||||||
|
#define D_16 0x3F
|
||||||
|
|
||||||
|
#define E_1 0x40
|
||||||
|
#define E_2 0x41
|
||||||
|
#define E_3 0x42
|
||||||
|
#define E_4 0x43
|
||||||
|
#define E_5 0x44
|
||||||
|
#define E_6 0x45
|
||||||
|
#define E_7 0x46
|
||||||
|
#define E_8 0x47
|
||||||
|
#define E_9 0x48
|
||||||
|
#define E_10 0x49
|
||||||
|
#define E_11 0x4A
|
||||||
|
#define E_12 0x4B
|
||||||
|
#define E_13 0x4C
|
||||||
|
#define E_14 0x4D
|
||||||
|
#define E_15 0x4E
|
||||||
|
#define E_16 0x4F
|
||||||
|
|
||||||
|
#define F_1 0x50
|
||||||
|
#define F_2 0x51
|
||||||
|
#define F_3 0x52
|
||||||
|
#define F_4 0x53
|
||||||
|
#define F_5 0x54
|
||||||
|
#define F_6 0x55
|
||||||
|
#define F_7 0x56
|
||||||
|
#define F_8 0x57
|
||||||
|
#define F_9 0x58
|
||||||
|
#define F_10 0x59
|
||||||
|
#define F_11 0x5A
|
||||||
|
#define F_12 0x5B
|
||||||
|
#define F_13 0x5C
|
||||||
|
#define F_14 0x5D
|
||||||
|
#define F_15 0x5E
|
||||||
|
#define F_16 0x5F
|
||||||
|
|
||||||
|
#define G_1 0x60
|
||||||
|
#define G_2 0x61
|
||||||
|
#define G_3 0x62
|
||||||
|
#define G_4 0x63
|
||||||
|
#define G_5 0x64
|
||||||
|
#define G_6 0x65
|
||||||
|
#define G_7 0x66
|
||||||
|
#define G_8 0x67
|
||||||
|
#define G_9 0x68
|
||||||
|
#define G_10 0x69
|
||||||
|
#define G_11 0x6A
|
||||||
|
#define G_12 0x6B
|
||||||
|
#define G_13 0x6C
|
||||||
|
#define G_14 0x6D
|
||||||
|
#define G_15 0x6E
|
||||||
|
#define G_16 0x6F
|
||||||
|
|
||||||
|
#define H_1 0x70
|
||||||
|
#define H_2 0x71
|
||||||
|
#define H_3 0x72
|
||||||
|
#define H_4 0x73
|
||||||
|
#define H_5 0x74
|
||||||
|
#define H_6 0x75
|
||||||
|
#define H_7 0x76
|
||||||
|
#define H_8 0x77
|
||||||
|
#define H_9 0x78
|
||||||
|
#define H_10 0x79
|
||||||
|
#define H_11 0x7A
|
||||||
|
#define H_12 0x7B
|
||||||
|
#define H_13 0x7C
|
||||||
|
#define H_14 0x7D
|
||||||
|
#define H_15 0x7E
|
||||||
|
#define H_16 0x7F
|
||||||
|
|
||||||
|
#define I_1 0x80
|
||||||
|
#define I_2 0x81
|
||||||
|
#define I_3 0x82
|
||||||
|
#define I_4 0x83
|
||||||
|
#define I_5 0x84
|
||||||
|
#define I_6 0x85
|
||||||
|
#define I_7 0x86
|
||||||
|
#define I_8 0x87
|
||||||
|
#define I_9 0x88
|
||||||
|
#define I_10 0x89
|
||||||
|
#define I_11 0x8A
|
||||||
|
#define I_12 0x8B
|
||||||
|
#define I_13 0x8C
|
||||||
|
#define I_14 0x8D
|
||||||
|
#define I_15 0x8E
|
||||||
|
#define I_16 0x8F
|
||||||
|
|
||||||
|
#define J_1 0x90
|
||||||
|
#define J_2 0x91
|
||||||
|
#define J_3 0x92
|
||||||
|
#define J_4 0x93
|
||||||
|
#define J_5 0x94
|
||||||
|
#define J_6 0x95
|
||||||
|
#define J_7 0x96
|
||||||
|
#define J_8 0x97
|
||||||
|
#define J_9 0x98
|
||||||
|
#define J_10 0x99
|
||||||
|
#define J_11 0x9A
|
||||||
|
#define J_12 0x9B
|
||||||
|
#define J_13 0x9C
|
||||||
|
#define J_14 0x9D
|
||||||
|
#define J_15 0x9E
|
||||||
|
#define J_16 0x9F
|
||||||
|
|
||||||
|
#define K_1 0xA0
|
||||||
|
#define K_2 0xA1
|
||||||
|
#define K_3 0xA2
|
||||||
|
#define K_4 0xA3
|
||||||
|
#define K_5 0xA4
|
||||||
|
#define K_6 0xA5
|
||||||
|
#define K_7 0xA6
|
||||||
|
#define K_8 0xA7
|
||||||
|
#define K_9 0xA8
|
||||||
|
#define K_10 0xA9
|
||||||
|
#define K_11 0xAA
|
||||||
|
#define K_12 0xAB
|
||||||
|
#define K_13 0xAC
|
||||||
|
#define K_14 0xAD
|
||||||
|
#define K_15 0xAE
|
||||||
|
#define K_16 0xAF
|
||||||
|
|
||||||
|
#define L_1 0xB0
|
||||||
|
#define L_2 0xB1
|
||||||
|
#define L_3 0xB2
|
||||||
|
#define L_4 0xB3
|
||||||
|
#define L_5 0xB4
|
||||||
|
#define L_6 0xB5
|
||||||
|
#define L_7 0xB6
|
||||||
|
#define L_8 0xB7
|
||||||
|
#define L_9 0xB8
|
||||||
|
#define L_10 0xB9
|
||||||
|
#define L_11 0xBA
|
||||||
|
#define L_12 0xBB
|
||||||
|
#define L_13 0xBC
|
||||||
|
#define L_14 0xBD
|
||||||
|
#define L_15 0xBE
|
||||||
|
#define L_16 0xBF
|
|
@ -38,16 +38,16 @@
|
||||||
#define ISSI_INTERRUPTMASKREGISTER 0xF0
|
#define ISSI_INTERRUPTMASKREGISTER 0xF0
|
||||||
#define ISSI_INTERRUPTSTATUSREGISTER 0xF1
|
#define ISSI_INTERRUPTSTATUSREGISTER 0xF1
|
||||||
|
|
||||||
#define ISSI_PAGE_LEDCONTROL 0x00 // PG0
|
#define ISSI_PAGE_LEDCONTROL 0x00 // PG0
|
||||||
#define ISSI_PAGE_PWM 0x01 // PG1
|
#define ISSI_PAGE_PWM 0x01 // PG1
|
||||||
#define ISSI_PAGE_AUTOBREATH 0x02 // PG2
|
#define ISSI_PAGE_AUTOBREATH 0x02 // PG2
|
||||||
#define ISSI_PAGE_FUNCTION 0x03 // PG3
|
#define ISSI_PAGE_FUNCTION 0x03 // PG3
|
||||||
|
|
||||||
#define ISSI_REG_CONFIGURATION 0x00 // PG3
|
#define ISSI_REG_CONFIGURATION 0x00 // PG3
|
||||||
#define ISSI_REG_GLOBALCURRENT 0x01 // PG3
|
#define ISSI_REG_GLOBALCURRENT 0x01 // PG3
|
||||||
#define ISSI_REG_RESET 0x11 // PG3
|
#define ISSI_REG_RESET 0x11 // PG3
|
||||||
#define ISSI_REG_SWPULLUP 0x0F // PG3
|
#define ISSI_REG_SWPULLUP 0x0F // PG3
|
||||||
#define ISSI_REG_CSPULLUP 0x10 // PG3
|
#define ISSI_REG_CSPULLUP 0x10 // PG3
|
||||||
|
|
||||||
#ifndef ISSI_TIMEOUT
|
#ifndef ISSI_TIMEOUT
|
||||||
# define ISSI_TIMEOUT 100
|
# define ISSI_TIMEOUT 100
|
||||||
|
@ -58,7 +58,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ISSI_PWM_FREQUENCY
|
#ifndef ISSI_PWM_FREQUENCY
|
||||||
# define ISSI_PWM_FREQUENCY 0b000 // PFS - IS31FL3733B only
|
# define ISSI_PWM_FREQUENCY 0b000 // PFS - IS31FL3733B only
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ISSI_SWPULLUP
|
#ifndef ISSI_SWPULLUP
|
||||||
|
|
|
@ -48,13 +48,13 @@ void IS31FL3733_set_led_control_register(uint8_t index, bool red, bool green, bo
|
||||||
void IS31FL3733_update_pwm_buffers(uint8_t addr, uint8_t index);
|
void IS31FL3733_update_pwm_buffers(uint8_t addr, uint8_t index);
|
||||||
void IS31FL3733_update_led_control_registers(uint8_t addr, uint8_t index);
|
void IS31FL3733_update_led_control_registers(uint8_t addr, uint8_t index);
|
||||||
|
|
||||||
#define PUR_0R 0x00 // No PUR resistor
|
#define PUR_0R 0x00 // No PUR resistor
|
||||||
#define PUR_05KR 0x02 // 0.5k Ohm resistor in t_NOL
|
#define PUR_05KR 0x02 // 0.5k Ohm resistor in t_NOL
|
||||||
#define PUR_3KR 0x03 // 3.0k Ohm resistor on all the time
|
#define PUR_3KR 0x03 // 3.0k Ohm resistor on all the time
|
||||||
#define PUR_4KR 0x04 // 4.0k Ohm resistor on all the time
|
#define PUR_4KR 0x04 // 4.0k Ohm resistor on all the time
|
||||||
#define PUR_8KR 0x05 // 8.0k Ohm resistor on all the time
|
#define PUR_8KR 0x05 // 8.0k Ohm resistor on all the time
|
||||||
#define PUR_16KR 0x06 // 16k Ohm resistor on all the time
|
#define PUR_16KR 0x06 // 16k Ohm resistor on all the time
|
||||||
#define PUR_32KR 0x07 // 32k Ohm resistor in t_NOL
|
#define PUR_32KR 0x07 // 32k Ohm resistor in t_NOL
|
||||||
|
|
||||||
#define A_1 0x00
|
#define A_1 0x00
|
||||||
#define A_2 0x01
|
#define A_2 0x01
|
||||||
|
|
|
@ -36,16 +36,16 @@
|
||||||
#define ISSI_INTERRUPTMASKREGISTER 0xF0
|
#define ISSI_INTERRUPTMASKREGISTER 0xF0
|
||||||
#define ISSI_INTERRUPTSTATUSREGISTER 0xF1
|
#define ISSI_INTERRUPTSTATUSREGISTER 0xF1
|
||||||
|
|
||||||
#define ISSI_PAGE_LEDCONTROL 0x00 // PG0
|
#define ISSI_PAGE_LEDCONTROL 0x00 // PG0
|
||||||
#define ISSI_PAGE_PWM 0x01 // PG1
|
#define ISSI_PAGE_PWM 0x01 // PG1
|
||||||
#define ISSI_PAGE_AUTOBREATH 0x02 // PG2
|
#define ISSI_PAGE_AUTOBREATH 0x02 // PG2
|
||||||
#define ISSI_PAGE_FUNCTION 0x03 // PG3
|
#define ISSI_PAGE_FUNCTION 0x03 // PG3
|
||||||
|
|
||||||
#define ISSI_REG_CONFIGURATION 0x00 // PG3
|
#define ISSI_REG_CONFIGURATION 0x00 // PG3
|
||||||
#define ISSI_REG_GLOBALCURRENT 0x01 // PG3
|
#define ISSI_REG_GLOBALCURRENT 0x01 // PG3
|
||||||
#define ISSI_REG_RESET 0x11 // PG3
|
#define ISSI_REG_RESET 0x11 // PG3
|
||||||
#define ISSI_REG_SWPULLUP 0x0F // PG3
|
#define ISSI_REG_SWPULLUP 0x0F // PG3
|
||||||
#define ISSI_REG_CSPULLUP 0x10 // PG3
|
#define ISSI_REG_CSPULLUP 0x10 // PG3
|
||||||
|
|
||||||
#ifndef ISSI_TIMEOUT
|
#ifndef ISSI_TIMEOUT
|
||||||
# define ISSI_TIMEOUT 100
|
# define ISSI_TIMEOUT 100
|
||||||
|
|
|
@ -61,14 +61,14 @@ void IS31FL3736_mono_set_led_control_register(uint8_t index, bool enabled);
|
||||||
void IS31FL3736_update_pwm_buffers(uint8_t addr1, uint8_t addr2);
|
void IS31FL3736_update_pwm_buffers(uint8_t addr1, uint8_t addr2);
|
||||||
void IS31FL3736_update_led_control_registers(uint8_t addr1, uint8_t addr2);
|
void IS31FL3736_update_led_control_registers(uint8_t addr1, uint8_t addr2);
|
||||||
|
|
||||||
#define PUR_0R 0x00 // No PUR resistor
|
#define PUR_0R 0x00 // No PUR resistor
|
||||||
#define PUR_05KR 0x01 // 0.5k Ohm resistor
|
#define PUR_05KR 0x01 // 0.5k Ohm resistor
|
||||||
#define PUR_1KR 0x02 // 1.0k Ohm resistor
|
#define PUR_1KR 0x02 // 1.0k Ohm resistor
|
||||||
#define PUR_2KR 0x03 // 2.0k Ohm resistor
|
#define PUR_2KR 0x03 // 2.0k Ohm resistor
|
||||||
#define PUR_4KR 0x04 // 4.0k Ohm resistor
|
#define PUR_4KR 0x04 // 4.0k Ohm resistor
|
||||||
#define PUR_8KR 0x05 // 8.0k Ohm resistor
|
#define PUR_8KR 0x05 // 8.0k Ohm resistor
|
||||||
#define PUR_16KR 0x06 // 16k Ohm resistor
|
#define PUR_16KR 0x06 // 16k Ohm resistor
|
||||||
#define PUR_32KR 0x07 // 32k Ohm resistor
|
#define PUR_32KR 0x07 // 32k Ohm resistor
|
||||||
|
|
||||||
#define A_1 0x00
|
#define A_1 0x00
|
||||||
#define A_2 0x02
|
#define A_2 0x02
|
||||||
|
|
|
@ -38,16 +38,16 @@
|
||||||
#define ISSI_INTERRUPTMASKREGISTER 0xF0
|
#define ISSI_INTERRUPTMASKREGISTER 0xF0
|
||||||
#define ISSI_INTERRUPTSTATUSREGISTER 0xF1
|
#define ISSI_INTERRUPTSTATUSREGISTER 0xF1
|
||||||
|
|
||||||
#define ISSI_PAGE_LEDCONTROL 0x00 // PG0
|
#define ISSI_PAGE_LEDCONTROL 0x00 // PG0
|
||||||
#define ISSI_PAGE_PWM 0x01 // PG1
|
#define ISSI_PAGE_PWM 0x01 // PG1
|
||||||
#define ISSI_PAGE_AUTOBREATH 0x02 // PG2
|
#define ISSI_PAGE_AUTOBREATH 0x02 // PG2
|
||||||
#define ISSI_PAGE_FUNCTION 0x03 // PG3
|
#define ISSI_PAGE_FUNCTION 0x03 // PG3
|
||||||
|
|
||||||
#define ISSI_REG_CONFIGURATION 0x00 // PG3
|
#define ISSI_REG_CONFIGURATION 0x00 // PG3
|
||||||
#define ISSI_REG_GLOBALCURRENT 0x01 // PG3
|
#define ISSI_REG_GLOBALCURRENT 0x01 // PG3
|
||||||
#define ISSI_REG_RESET 0x11 // PG3
|
#define ISSI_REG_RESET 0x11 // PG3
|
||||||
#define ISSI_REG_SWPULLUP 0x0F // PG3
|
#define ISSI_REG_SWPULLUP 0x0F // PG3
|
||||||
#define ISSI_REG_CSPULLUP 0x10 // PG3
|
#define ISSI_REG_CSPULLUP 0x10 // PG3
|
||||||
|
|
||||||
#ifndef ISSI_TIMEOUT
|
#ifndef ISSI_TIMEOUT
|
||||||
# define ISSI_TIMEOUT 100
|
# define ISSI_TIMEOUT 100
|
||||||
|
|
|
@ -48,14 +48,14 @@ void IS31FL3737_set_led_control_register(uint8_t index, bool red, bool green, bo
|
||||||
void IS31FL3737_update_pwm_buffers(uint8_t addr1, uint8_t addr2);
|
void IS31FL3737_update_pwm_buffers(uint8_t addr1, uint8_t addr2);
|
||||||
void IS31FL3737_update_led_control_registers(uint8_t addr1, uint8_t addr2);
|
void IS31FL3737_update_led_control_registers(uint8_t addr1, uint8_t addr2);
|
||||||
|
|
||||||
#define PUR_0R 0x00 // No PUR resistor
|
#define PUR_0R 0x00 // No PUR resistor
|
||||||
#define PUR_05KR 0x01 // 0.5k Ohm resistor in t_NOL
|
#define PUR_05KR 0x01 // 0.5k Ohm resistor in t_NOL
|
||||||
#define PUR_1KR 0x02 // 1.0k Ohm resistor in t_NOL
|
#define PUR_1KR 0x02 // 1.0k Ohm resistor in t_NOL
|
||||||
#define PUR_2KR 0x03 // 2.0k Ohm resistor in t_NOL
|
#define PUR_2KR 0x03 // 2.0k Ohm resistor in t_NOL
|
||||||
#define PUR_4KR 0x04 // 4.0k Ohm resistor in t_NOL
|
#define PUR_4KR 0x04 // 4.0k Ohm resistor in t_NOL
|
||||||
#define PUR_8KR 0x05 // 8.0k Ohm resistor in t_NOL
|
#define PUR_8KR 0x05 // 8.0k Ohm resistor in t_NOL
|
||||||
#define PUR_16KR 0x06 // 16k Ohm resistor in t_NOL
|
#define PUR_16KR 0x06 // 16k Ohm resistor in t_NOL
|
||||||
#define PUR_32KR 0x07 // 32k Ohm resistor in t_NOL
|
#define PUR_32KR 0x07 // 32k Ohm resistor in t_NOL
|
||||||
|
|
||||||
#define A_1 0x00
|
#define A_1 0x00
|
||||||
#define A_2 0x01
|
#define A_2 0x01
|
||||||
|
|
|
@ -42,16 +42,16 @@
|
||||||
#define ISSI_INTERRUPTSTATUSREGISTER 0xF1
|
#define ISSI_INTERRUPTSTATUSREGISTER 0xF1
|
||||||
#define ISSI_IDREGISTER 0xFC
|
#define ISSI_IDREGISTER 0xFC
|
||||||
|
|
||||||
#define ISSI_PAGE_PWM0 0x00 // PG0
|
#define ISSI_PAGE_PWM0 0x00 // PG0
|
||||||
#define ISSI_PAGE_PWM1 0x01 // PG1
|
#define ISSI_PAGE_PWM1 0x01 // PG1
|
||||||
#define ISSI_PAGE_SCALING_0 0x02 // PG2
|
#define ISSI_PAGE_SCALING_0 0x02 // PG2
|
||||||
#define ISSI_PAGE_SCALING_1 0x03 // PG3
|
#define ISSI_PAGE_SCALING_1 0x03 // PG3
|
||||||
#define ISSI_PAGE_FUNCTION 0x04 // PG4
|
#define ISSI_PAGE_FUNCTION 0x04 // PG4
|
||||||
|
|
||||||
#define ISSI_REG_CONFIGURATION 0x00 // PG4
|
#define ISSI_REG_CONFIGURATION 0x00 // PG4
|
||||||
#define ISSI_REG_GLOBALCURRENT 0x01 // PG4
|
#define ISSI_REG_GLOBALCURRENT 0x01 // PG4
|
||||||
#define ISSI_REG_PULLDOWNUP 0x02 // PG4
|
#define ISSI_REG_PULLDOWNUP 0x02 // PG4
|
||||||
#define ISSI_REG_RESET 0x3F // PG4
|
#define ISSI_REG_RESET 0x3F // PG4
|
||||||
|
|
||||||
#ifndef ISSI_TIMEOUT
|
#ifndef ISSI_TIMEOUT
|
||||||
# define ISSI_TIMEOUT 100
|
# define ISSI_TIMEOUT 100
|
||||||
|
|
|
@ -51,14 +51,14 @@ void IS31FL3741_set_scaling_registers(const is31_led *pled, uint8_t red, uint8_t
|
||||||
|
|
||||||
void IS31FL3741_set_pwm_buffer(const is31_led *pled, uint8_t red, uint8_t green, uint8_t blue);
|
void IS31FL3741_set_pwm_buffer(const is31_led *pled, uint8_t red, uint8_t green, uint8_t blue);
|
||||||
|
|
||||||
#define PUR_0R 0x00 // No PUR resistor
|
#define PUR_0R 0x00 // No PUR resistor
|
||||||
#define PUR_05KR 0x01 // 0.5k Ohm resistor
|
#define PUR_05KR 0x01 // 0.5k Ohm resistor
|
||||||
#define PUR_1KR 0x02 // 1.0k Ohm resistor
|
#define PUR_1KR 0x02 // 1.0k Ohm resistor
|
||||||
#define PUR_2KR 0x03 // 2.0k Ohm resistor
|
#define PUR_2KR 0x03 // 2.0k Ohm resistor
|
||||||
#define PUR_4KR 0x04 // 4.0k Ohm resistor
|
#define PUR_4KR 0x04 // 4.0k Ohm resistor
|
||||||
#define PUR_8KR 0x05 // 8.0k Ohm resistor
|
#define PUR_8KR 0x05 // 8.0k Ohm resistor
|
||||||
#define PUR_16KR 0x06 // 16k Ohm resistor
|
#define PUR_16KR 0x06 // 16k Ohm resistor
|
||||||
#define PUR_32KR 0x07 // 32k Ohm resistor
|
#define PUR_32KR 0x07 // 32k Ohm resistor
|
||||||
|
|
||||||
#define CS1_SW1 0x00
|
#define CS1_SW1 0x00
|
||||||
#define CS2_SW1 0x01
|
#define CS2_SW1 0x01
|
||||||
|
|
299
drivers/led/issi/is31fl3742.h
Normal file
299
drivers/led/issi/is31fl3742.h
Normal file
|
@ -0,0 +1,299 @@
|
||||||
|
/* Copyright 2017 Jason Williams
|
||||||
|
* Copyright 2018 Jack Humbert
|
||||||
|
* Copyright 2018 Yiancar
|
||||||
|
* Copyright 2020 MelGeek
|
||||||
|
* Copyright 2021 MasterSpoon
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// This is a 7-bit address, that gets left-shifted and bit 0
|
||||||
|
// set to 0 for write, 1 for read (as per I2C protocol)
|
||||||
|
// The address will vary depending on your wiring:
|
||||||
|
// 00 <-> GND
|
||||||
|
// 01 <-> SCL
|
||||||
|
// 10 <-> SDA
|
||||||
|
// 11 <-> VCC
|
||||||
|
// ADDR represents A1:A0 of the 7-bit address.
|
||||||
|
// The result is: 0b01100(ADDR)
|
||||||
|
#ifndef DRIVER_ADDR_1
|
||||||
|
# define DRIVER_ADDR_1 0b0110000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Command Registers
|
||||||
|
#define ISSI_COMMANDREGISTER_WRITELOCK 0xFE
|
||||||
|
#define ISSI_COMMANDREGISTER 0xFD
|
||||||
|
#define ISSI_IDREGISTER 0xFC
|
||||||
|
#define ISSI_REGISTER_UNLOCK 0xC5
|
||||||
|
|
||||||
|
// Response Registers
|
||||||
|
#define ISSI_PAGE_PWM 0x00
|
||||||
|
#define ISSI_PAGE_SCALING 0x02
|
||||||
|
#define ISSI_PAGE_FUNCTION 0x04
|
||||||
|
|
||||||
|
// Registers under Function Register
|
||||||
|
#define ISSI_REG_CONFIGURATION 0x00
|
||||||
|
#define ISSI_REG_GLOBALCURRENT 0x01
|
||||||
|
#define ISSI_REG_PULLDOWNUP 0x02
|
||||||
|
#define ISSI_REG_SSR 0x41
|
||||||
|
#define ISSI_REG_RESET 0x3F
|
||||||
|
#define ISSI_REG_PWM_SET 0x36
|
||||||
|
|
||||||
|
// Set defaults for Function Registers
|
||||||
|
#ifndef ISSI_CONFIGURATION
|
||||||
|
# define ISSI_CONFIGURATION 0x31
|
||||||
|
#endif
|
||||||
|
#ifndef ISSI_GLOBALCURRENT
|
||||||
|
# define ISSI_GLOBALCURRENT 0xFF
|
||||||
|
#endif
|
||||||
|
#ifndef ISSI_PULLDOWNUP
|
||||||
|
# define ISSI_PULLDOWNUP 0x55
|
||||||
|
#endif
|
||||||
|
#ifndef ISSI_PWM_SET
|
||||||
|
# define ISSI_PWM_SET 0x00
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Set defaults for Spread Spectrum Register
|
||||||
|
#ifndef ISSI_SSR_1
|
||||||
|
# define ISSI_SSR_1 0x00
|
||||||
|
#endif
|
||||||
|
#ifndef ISSI_SSR_2
|
||||||
|
# define ISSI_SSR_2 0x00
|
||||||
|
#endif
|
||||||
|
#ifndef ISSI_SSR_3
|
||||||
|
# define ISSI_SSR_3 0x00
|
||||||
|
#endif
|
||||||
|
#ifndef ISSI_SSR_4
|
||||||
|
# define ISSI_SSR_4 0x00
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Set defaults for Scaling registers
|
||||||
|
#ifndef ISSI_SCAL_RED
|
||||||
|
# define ISSI_SCAL_RED 0xFF
|
||||||
|
#endif
|
||||||
|
#ifndef ISSI_SCAL_BLUE
|
||||||
|
# define ISSI_SCAL_BLUE 0xFF
|
||||||
|
#endif
|
||||||
|
#ifndef ISSI_SCAL_GREEN
|
||||||
|
# define ISSI_SCAL_GREEN 0xFF
|
||||||
|
#endif
|
||||||
|
#define ISSI_SCAL_RED_OFF 0x00
|
||||||
|
#define ISSI_SCAL_GREEN_OFF 0x00
|
||||||
|
#define ISSI_SCAL_BLUE_OFF 0x00
|
||||||
|
|
||||||
|
#ifndef ISSI_SCAL_LED
|
||||||
|
# define ISSI_SCAL_LED 0xFF
|
||||||
|
#endif
|
||||||
|
#define ISSI_SCAL_LED_OFF 0x00
|
||||||
|
|
||||||
|
// Set buffer sizes
|
||||||
|
#define ISSI_MAX_LEDS 180
|
||||||
|
#define ISSI_SCALING_SIZE 180
|
||||||
|
#define ISSI_PWM_TRF_SIZE 18
|
||||||
|
#define ISSI_SCALING_TRF_SIZE 18
|
||||||
|
|
||||||
|
// Location of 1st bit for PWM and Scaling registers
|
||||||
|
#define ISSI_PWM_REG_1ST 0x00
|
||||||
|
#define ISSI_SCL_REG_1ST 0x00
|
||||||
|
|
||||||
|
// Map CS SW locations to order in PWM / Scaling buffers
|
||||||
|
// This matches the ORDER in the Datasheet Register not the POSITION
|
||||||
|
// It will always count from 0x00 to (ISSI_MAX_LEDS - 1)
|
||||||
|
#define CS1_SW1 0x00
|
||||||
|
#define CS2_SW1 0x01
|
||||||
|
#define CS3_SW1 0x02
|
||||||
|
#define CS4_SW1 0x03
|
||||||
|
#define CS5_SW1 0x04
|
||||||
|
#define CS6_SW1 0x05
|
||||||
|
#define CS7_SW1 0x06
|
||||||
|
#define CS8_SW1 0x07
|
||||||
|
#define CS9_SW1 0x08
|
||||||
|
#define CS10_SW1 0x09
|
||||||
|
#define CS11_SW1 0x0A
|
||||||
|
#define CS12_SW1 0x0B
|
||||||
|
#define CS13_SW1 0x0C
|
||||||
|
#define CS14_SW1 0x0D
|
||||||
|
#define CS15_SW1 0x0E
|
||||||
|
#define CS16_SW1 0x0F
|
||||||
|
#define CS17_SW1 0x10
|
||||||
|
#define CS18_SW1 0x11
|
||||||
|
#define CS19_SW1 0x12
|
||||||
|
#define CS20_SW1 0x13
|
||||||
|
#define CS21_SW1 0x14
|
||||||
|
#define CS22_SW1 0x15
|
||||||
|
#define CS23_SW1 0x16
|
||||||
|
#define CS24_SW1 0x17
|
||||||
|
#define CS25_SW1 0x18
|
||||||
|
#define CS26_SW1 0x19
|
||||||
|
#define CS27_SW1 0x1A
|
||||||
|
#define CS28_SW1 0x1B
|
||||||
|
#define CS29_SW1 0x1C
|
||||||
|
#define CS30_SW1 0x1D
|
||||||
|
|
||||||
|
#define CS1_SW2 0x1E
|
||||||
|
#define CS2_SW2 0x1F
|
||||||
|
#define CS3_SW2 0x20
|
||||||
|
#define CS4_SW2 0x21
|
||||||
|
#define CS5_SW2 0x22
|
||||||
|
#define CS6_SW2 0x23
|
||||||
|
#define CS7_SW2 0x24
|
||||||
|
#define CS8_SW2 0x25
|
||||||
|
#define CS9_SW2 0x26
|
||||||
|
#define CS10_SW2 0x27
|
||||||
|
#define CS11_SW2 0x28
|
||||||
|
#define CS12_SW2 0x29
|
||||||
|
#define CS13_SW2 0x2A
|
||||||
|
#define CS14_SW2 0x2B
|
||||||
|
#define CS15_SW2 0x2C
|
||||||
|
#define CS16_SW2 0x2D
|
||||||
|
#define CS17_SW2 0x2E
|
||||||
|
#define CS18_SW2 0x2F
|
||||||
|
#define CS19_SW2 0x30
|
||||||
|
#define CS20_SW2 0x31
|
||||||
|
#define CS21_SW2 0x32
|
||||||
|
#define CS22_SW2 0x33
|
||||||
|
#define CS23_SW2 0x34
|
||||||
|
#define CS24_SW2 0x35
|
||||||
|
#define CS25_SW2 0x36
|
||||||
|
#define CS26_SW2 0x37
|
||||||
|
#define CS27_SW2 0x38
|
||||||
|
#define CS28_SW2 0x39
|
||||||
|
#define CS29_SW2 0x3A
|
||||||
|
#define CS30_SW2 0x3B
|
||||||
|
|
||||||
|
#define CS1_SW3 0x3C
|
||||||
|
#define CS2_SW3 0x3D
|
||||||
|
#define CS3_SW3 0x3E
|
||||||
|
#define CS4_SW3 0x3F
|
||||||
|
#define CS5_SW3 0x40
|
||||||
|
#define CS6_SW3 0x41
|
||||||
|
#define CS7_SW3 0x42
|
||||||
|
#define CS8_SW3 0x43
|
||||||
|
#define CS9_SW3 0x44
|
||||||
|
#define CS10_SW3 0x45
|
||||||
|
#define CS11_SW3 0x46
|
||||||
|
#define CS12_SW3 0x47
|
||||||
|
#define CS13_SW3 0x48
|
||||||
|
#define CS14_SW3 0x49
|
||||||
|
#define CS15_SW3 0x4A
|
||||||
|
#define CS16_SW3 0x4B
|
||||||
|
#define CS17_SW3 0x4C
|
||||||
|
#define CS18_SW3 0x4D
|
||||||
|
#define CS19_SW3 0x4E
|
||||||
|
#define CS20_SW3 0x4F
|
||||||
|
#define CS21_SW3 0x50
|
||||||
|
#define CS22_SW3 0x51
|
||||||
|
#define CS23_SW3 0x52
|
||||||
|
#define CS24_SW3 0x53
|
||||||
|
#define CS25_SW3 0x54
|
||||||
|
#define CS26_SW3 0x55
|
||||||
|
#define CS27_SW3 0x56
|
||||||
|
#define CS28_SW3 0x57
|
||||||
|
#define CS29_SW3 0x58
|
||||||
|
#define CS30_SW3 0x59
|
||||||
|
|
||||||
|
#define CS1_SW4 0x5A
|
||||||
|
#define CS2_SW4 0x5B
|
||||||
|
#define CS3_SW4 0x5C
|
||||||
|
#define CS4_SW4 0x5D
|
||||||
|
#define CS5_SW4 0x5E
|
||||||
|
#define CS6_SW4 0x5F
|
||||||
|
#define CS7_SW4 0x60
|
||||||
|
#define CS8_SW4 0x61
|
||||||
|
#define CS9_SW4 0x62
|
||||||
|
#define CS10_SW4 0x63
|
||||||
|
#define CS11_SW4 0x64
|
||||||
|
#define CS12_SW4 0x65
|
||||||
|
#define CS13_SW4 0x66
|
||||||
|
#define CS14_SW4 0x67
|
||||||
|
#define CS15_SW4 0x68
|
||||||
|
#define CS16_SW4 0x69
|
||||||
|
#define CS17_SW4 0x6A
|
||||||
|
#define CS18_SW4 0x6B
|
||||||
|
#define CS19_SW4 0x6C
|
||||||
|
#define CS20_SW4 0x6D
|
||||||
|
#define CS21_SW4 0x6E
|
||||||
|
#define CS22_SW4 0x6F
|
||||||
|
#define CS23_SW4 0x70
|
||||||
|
#define CS24_SW4 0x71
|
||||||
|
#define CS25_SW4 0x72
|
||||||
|
#define CS26_SW4 0x73
|
||||||
|
#define CS27_SW4 0x74
|
||||||
|
#define CS28_SW4 0x75
|
||||||
|
#define CS29_SW4 0x76
|
||||||
|
#define CS30_SW4 0x77
|
||||||
|
|
||||||
|
#define CS1_SW5 0x78
|
||||||
|
#define CS2_SW5 0x79
|
||||||
|
#define CS3_SW5 0x7A
|
||||||
|
#define CS4_SW5 0x7B
|
||||||
|
#define CS5_SW5 0x7C
|
||||||
|
#define CS6_SW5 0x7D
|
||||||
|
#define CS7_SW5 0x7E
|
||||||
|
#define CS8_SW5 0x7F
|
||||||
|
#define CS9_SW5 0x80
|
||||||
|
#define CS10_SW5 0x81
|
||||||
|
#define CS11_SW5 0x82
|
||||||
|
#define CS12_SW5 0x83
|
||||||
|
#define CS13_SW5 0x84
|
||||||
|
#define CS14_SW5 0x85
|
||||||
|
#define CS15_SW5 0x86
|
||||||
|
#define CS16_SW5 0x87
|
||||||
|
#define CS17_SW5 0x88
|
||||||
|
#define CS18_SW5 0x89
|
||||||
|
#define CS19_SW5 0x8A
|
||||||
|
#define CS20_SW5 0x8B
|
||||||
|
#define CS21_SW5 0x8C
|
||||||
|
#define CS22_SW5 0x8D
|
||||||
|
#define CS23_SW5 0x8E
|
||||||
|
#define CS24_SW5 0x8F
|
||||||
|
#define CS25_SW5 0x90
|
||||||
|
#define CS26_SW5 0x91
|
||||||
|
#define CS27_SW5 0x92
|
||||||
|
#define CS28_SW5 0x93
|
||||||
|
#define CS29_SW5 0x94
|
||||||
|
#define CS30_SW5 0x95
|
||||||
|
|
||||||
|
#define CS1_SW6 0x96
|
||||||
|
#define CS2_SW6 0x97
|
||||||
|
#define CS3_SW6 0x98
|
||||||
|
#define CS4_SW6 0x99
|
||||||
|
#define CS5_SW6 0x9A
|
||||||
|
#define CS6_SW6 0x9B
|
||||||
|
#define CS7_SW6 0x9C
|
||||||
|
#define CS8_SW6 0x9D
|
||||||
|
#define CS9_SW6 0x9E
|
||||||
|
#define CS10_SW6 0x9F
|
||||||
|
#define CS11_SW6 0xA0
|
||||||
|
#define CS12_SW6 0xA1
|
||||||
|
#define CS13_SW6 0xA2
|
||||||
|
#define CS14_SW6 0xA3
|
||||||
|
#define CS15_SW6 0xA4
|
||||||
|
#define CS16_SW6 0xA5
|
||||||
|
#define CS17_SW6 0xA6
|
||||||
|
#define CS18_SW6 0xA7
|
||||||
|
#define CS19_SW6 0xA8
|
||||||
|
#define CS20_SW6 0xA9
|
||||||
|
#define CS21_SW6 0xAA
|
||||||
|
#define CS22_SW6 0xAB
|
||||||
|
#define CS23_SW6 0xAC
|
||||||
|
#define CS24_SW6 0xAD
|
||||||
|
#define CS25_SW6 0xAE
|
||||||
|
#define CS26_SW6 0xAF
|
||||||
|
#define CS27_SW6 0xB0
|
||||||
|
#define CS28_SW6 0xB1
|
||||||
|
#define CS29_SW6 0xB2
|
||||||
|
#define CS30_SW6 0xB3
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue