Remerge 0.16.x' into firmware21
This commit is contained in:
@@ -5,6 +5,9 @@ AlignConsecutiveAssignments: 'true'
|
||||
AlignConsecutiveDeclarations: 'true'
|
||||
AlignOperands: 'true'
|
||||
AllowAllParametersOfDeclarationOnNextLine: 'false'
|
||||
AllowShortCaseLabelsOnASingleLine: 'false'
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortLoopsOnASingleLine: 'false'
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: 'false'
|
||||
@@ -20,6 +23,7 @@ SortIncludes: 'false'
|
||||
SpaceBeforeAssignmentOperators: 'true'
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: 'false'
|
||||
SpacesBeforeTrailingComments: 1
|
||||
TabWidth: '4'
|
||||
UseTab: Never
|
||||
|
||||
|
||||
113
.gitattributes
vendored
113
.gitattributes
vendored
@@ -2,69 +2,70 @@
|
||||
* text=auto
|
||||
|
||||
# sources
|
||||
*.c text
|
||||
*.cc text
|
||||
*.cxx text
|
||||
*.cpp text
|
||||
*.c++ text
|
||||
*.hpp text
|
||||
*.h text
|
||||
*.h++ text
|
||||
*.hh text
|
||||
*.bat text
|
||||
*.coffee text
|
||||
*.css text
|
||||
*.htm text
|
||||
*.html text
|
||||
*.inc text
|
||||
*.ini text
|
||||
*.js text
|
||||
*.jsx text
|
||||
*.json text
|
||||
*.less text
|
||||
*.php text
|
||||
*.pl text
|
||||
*.py text
|
||||
*.rb text
|
||||
*.sass text
|
||||
*.scm text
|
||||
*.scss text
|
||||
*.sh text
|
||||
*.sql text
|
||||
*.styl text
|
||||
*.ts text
|
||||
*.xml text
|
||||
*.xhtml text
|
||||
*.c text eol=lf
|
||||
*.cc text eol=lf
|
||||
*.cxx text eol=lf
|
||||
*.cpp text eol=lf
|
||||
*.c++ text eol=lf
|
||||
*.hpp text eol=lf
|
||||
*.h text eol=lf
|
||||
*.h++ text eol=lf
|
||||
*.hh text eol=lf
|
||||
*.bat text eol=crlf
|
||||
*.cmd text eol=crlf
|
||||
*.coffee text eol=lf
|
||||
*.css text eol=lf
|
||||
*.htm text eol=lf
|
||||
*.html text eol=lf
|
||||
*.inc text eol=lf
|
||||
*.ini text eol=crlf
|
||||
*.js text eol=lf
|
||||
*.jsx text eol=lf
|
||||
*.json text eol=lf
|
||||
*.less text eol=lf
|
||||
*.php text eol=lf
|
||||
*.pl text eol=lf
|
||||
*.py text eol=lf
|
||||
*.rb text eol=lf
|
||||
*.sass text eol=lf
|
||||
*.scm text eol=lf
|
||||
*.scss text eol=lf
|
||||
*.sh text eol=lf
|
||||
*.sql text eol=lf
|
||||
*.styl text eol=lf
|
||||
*.ts text eol=lf
|
||||
*.xml text eol=lf
|
||||
*.xhtml text eol=lf
|
||||
|
||||
# make files (need to always use lf for compatibility with Windows 10 bash)
|
||||
Makefile eol=lf
|
||||
*.mk eol=lf
|
||||
*.mk eol=lf
|
||||
|
||||
# make files (need to always use lf for compatibility with Windows 10 bash)
|
||||
*.sh eol=lf
|
||||
|
||||
# documentation
|
||||
*.markdown text
|
||||
*.md text
|
||||
*.mdwn text
|
||||
*.mdown text
|
||||
*.mkd text
|
||||
*.mkdn text
|
||||
*.mdtxt text
|
||||
*.mdtext text
|
||||
*.txt text
|
||||
AUTHORS text
|
||||
CHANGELOG text
|
||||
CHANGES text
|
||||
CONTRIBUTING text
|
||||
COPYING text
|
||||
INSTALL text
|
||||
license text
|
||||
LICENSE text
|
||||
NEWS text
|
||||
readme text
|
||||
*README* text
|
||||
TODO text
|
||||
*.markdown text eol=lf
|
||||
*.md text eol=lf
|
||||
*.mdwn text eol=lf
|
||||
*.mdown text eol=lf
|
||||
*.mkd text eol=lf
|
||||
*.mkdn text eol=lf
|
||||
*.mdtxt text eol=lf
|
||||
*.mdtext text eol=lf
|
||||
*.txt text eol=lf
|
||||
AUTHORS text eol=lf
|
||||
CHANGELOG text eol=lf
|
||||
CHANGES text eol=lf
|
||||
CONTRIBUTING text eol=lf
|
||||
COPYING text eol=lf
|
||||
INSTALL text eol=lf
|
||||
license text eol=lf
|
||||
LICENSE text eol=lf
|
||||
NEWS text eol=lf
|
||||
readme text eol=lf
|
||||
*README* text eol=lf
|
||||
TODO text eol=lf
|
||||
|
||||
GRAPHICS
|
||||
*.ai binary
|
||||
@@ -82,7 +83,7 @@ GRAPHICS
|
||||
*.png binary
|
||||
*.psb binary
|
||||
*.psd binary
|
||||
*.svg text
|
||||
*.svg text eol=lf
|
||||
*.svgz binary
|
||||
*.tif binary
|
||||
*.tiff binary
|
||||
|
||||
25
.github/ISSUE_TEMPLATE/bug_report.md
vendored
25
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -18,19 +18,18 @@ assignees: ''
|
||||
|
||||
## System Information
|
||||
|
||||
- Keyboard:
|
||||
- Revision (if applicable):
|
||||
- Operating system:
|
||||
- AVR GCC version:
|
||||
<!-- Run `avr-gcc --version` to find this out. -->
|
||||
- ARM GCC version:
|
||||
<!-- Run `arm-none-eabi-gcc --version` to find this out. -->
|
||||
- QMK Firmware version:
|
||||
<!-- Run `git describe --abbrev=0 --tags` to find this out. -->
|
||||
- Any keyboard related software installed?
|
||||
- [ ] AutoHotKey
|
||||
- [ ] Karabiner
|
||||
- [ ] Other:
|
||||
**Keyboard:**
|
||||
**Revision (if applicable):**
|
||||
**Operating system:**
|
||||
**`qmk doctor` output:**
|
||||
```
|
||||
(Paste output here)
|
||||
```
|
||||
|
||||
**Any keyboard related software installed?**
|
||||
- [ ] AutoHotKey (Windows)
|
||||
- [ ] Karabiner (macOS)
|
||||
- [ ] Other:
|
||||
|
||||
## Additional Context
|
||||
|
||||
|
||||
30
.github/workflows/develop_update.yml
vendored
Normal file
30
.github/workflows/develop_update.yml
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
name: Update develop after master merge
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
develop_update:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
if: github.repository == 'qmk/qmk_firmware'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
token: ${{ secrets.QMK_BOT_TOKEN }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Checkout develop
|
||||
run: |
|
||||
git fetch origin master develop
|
||||
git checkout develop
|
||||
|
||||
- name: Update develop from master
|
||||
run: |
|
||||
git config --global user.name "QMK Bot"
|
||||
git config --global user.email "hello@qmk.fm"
|
||||
git merge origin/master
|
||||
git push origin develop
|
||||
35
.github/workflows/feature_branch_update.yml
vendored
Normal file
35
.github/workflows/feature_branch_update.yml
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
name: Update feature branches after develop merge
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
|
||||
jobs:
|
||||
feature_branch_update:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
if: github.repository == 'qmk/qmk_firmware'
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
branch:
|
||||
- xap
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
token: ${{ secrets.QMK_BOT_TOKEN }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Checkout branch
|
||||
run: |
|
||||
git fetch origin develop ${{ matrix.branch }}
|
||||
git checkout ${{ matrix.branch }}
|
||||
|
||||
- name: Update branch from develop
|
||||
run: |
|
||||
git config --global user.name "QMK Bot"
|
||||
git config --global user.email "hello@qmk.fm"
|
||||
git merge origin/develop
|
||||
git push origin ${{ matrix.branch }}
|
||||
8
.github/workflows/format.yaml
vendored
8
.github/workflows/format.yaml
vendored
@@ -19,14 +19,14 @@ jobs:
|
||||
container: qmkfm/qmk_cli
|
||||
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
apt-get update && apt-get install -y dos2unix
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip3 install -r requirements-dev.txt
|
||||
|
||||
- uses: trilom/file-changes-action@v1.2.4
|
||||
id: file_changes
|
||||
with:
|
||||
|
||||
8
.github/workflows/format_push.yaml
vendored
8
.github/workflows/format_push.yaml
vendored
@@ -12,14 +12,14 @@ jobs:
|
||||
container: qmkfm/qmk_cli
|
||||
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
apt-get update && apt-get install -y dos2unix
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip3 install -r requirements-dev.txt
|
||||
|
||||
- name: Run qmk formatters
|
||||
shell: 'bash {0}'
|
||||
run: |
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -3,6 +3,7 @@
|
||||
*.swp
|
||||
*~
|
||||
.DS_Store
|
||||
._*
|
||||
|
||||
# Build artifacts
|
||||
.clang_complete
|
||||
@@ -18,7 +19,6 @@
|
||||
|
||||
# QMK-specific
|
||||
api_data/v1
|
||||
doxygen/
|
||||
quantum/version.h
|
||||
*.bin
|
||||
*.eep
|
||||
|
||||
6
Doxyfile
6
Doxyfile
@@ -21,7 +21,7 @@ DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = "QMK Firmware"
|
||||
PROJECT_NUMBER = https://github.com/qmk/qmk_firmware
|
||||
PROJECT_BRIEF = "Keyboard controller firmware for Atmel AVR and ARM USB families"
|
||||
OUTPUT_DIRECTORY = doxygen
|
||||
OUTPUT_DIRECTORY = .build/doxygen
|
||||
ALLOW_UNICODE_NAMES = NO
|
||||
OUTPUT_LANGUAGE = English
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
@@ -145,7 +145,7 @@ FILE_PATTERNS = *.c \
|
||||
RECURSIVE = YES
|
||||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
EXCLUDE_PATTERNS = */protocol/arm_atsam/*
|
||||
EXCLUDE_SYMBOLS =
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS = *
|
||||
@@ -209,7 +209,7 @@ EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED =
|
||||
PREDEFINED = __DOXYGEN__ PROGMEM
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
|
||||
|
||||
135
Makefile
135
Makefile
@@ -19,6 +19,10 @@ endif
|
||||
# Otherwise the [OK], [ERROR] and [WARN] messages won't be displayed correctly
|
||||
override SILENT := false
|
||||
|
||||
ifdef SKIP_VERSION
|
||||
SKIP_GIT := yes
|
||||
endif
|
||||
|
||||
ifndef SUB_IS_SILENT
|
||||
ifndef SKIP_GIT
|
||||
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_ROOT_DIR := $(dir $(ABS_ROOT_MAKEFILE))
|
||||
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
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
@@ -119,53 +87,20 @@ endef
|
||||
# a function that returns the value
|
||||
COMPARE_AND_REMOVE_FROM_RULE = $(eval $(call COMPARE_AND_REMOVE_FROM_RULE_HELPER,$1))$(RULE_FOUND)
|
||||
|
||||
|
||||
# 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
|
||||
# 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_HELPER
|
||||
BEST_MATCH :=
|
||||
$$(eval $$(call TRY_TO_MATCH_RULE_FROM_LIST_HELPER2,$1))
|
||||
ifneq ($$(BEST_MATCH),)
|
||||
# Split on ":", padding with empty strings to avoid indexing issues
|
||||
TOKEN1:=$$(shell python3 -c "import sys; print((sys.argv[1].split(':',1)+[''])[0])" $$(RULE))
|
||||
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 := $$(BEST_MATCH_RULE)
|
||||
MATCHED_ITEM := $$(BEST_MATCH)
|
||||
MATCHED_ITEM := $$(TOKEN1)
|
||||
else
|
||||
RULE_FOUND := false
|
||||
MATCHED_ITEM :=
|
||||
@@ -352,7 +287,7 @@ define PARSE_KEYMAP
|
||||
# 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)
|
||||
# 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
|
||||
MAKE_MSG := $$(MSG_MAKE_KB)
|
||||
# We run the command differently, depending on if we want more output or not
|
||||
@@ -394,12 +329,12 @@ define BUILD_TEST
|
||||
TEST_NAME := $$(notdir $$(TEST_PATH))
|
||||
MAKE_TARGET := $2
|
||||
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_MSG := $$(MSG_MAKE_TEST)
|
||||
$$(eval $$(call BUILD))
|
||||
ifneq ($$(MAKE_TARGET),clean)
|
||||
TEST_EXECUTABLE := $$(TEST_DIR)/$$(TEST_NAME).elf
|
||||
TEST_EXECUTABLE := $$(TEST_OUTPUT_DIR)/$$(TEST_NAME).elf
|
||||
TESTS += $$(TEST_NAME)
|
||||
TEST_MSG := $$(MSG_TEST)
|
||||
$$(TEST_NAME)_COMMAND := \
|
||||
@@ -416,6 +351,7 @@ define PARSE_TEST
|
||||
TESTS :=
|
||||
TEST_NAME := $$(firstword $$(subst :, ,$$(RULE)))
|
||||
TEST_TARGET := $$(subst $$(TEST_NAME),,$$(subst $$(TEST_NAME):,,$$(RULE)))
|
||||
include $(BUILDDEFS_PATH)/testlist.mk
|
||||
ifeq ($$(TEST_NAME),all)
|
||||
MATCHED_TESTS := $$(TEST_LIST)
|
||||
else
|
||||
@@ -438,7 +374,6 @@ define SET_SILENT_MODE
|
||||
endif
|
||||
endef
|
||||
|
||||
include paths.mk
|
||||
include $(BUILDDEFS_PATH)/message.mk
|
||||
|
||||
ifeq ($(strip $(BREAK_ON_ERRORS)), yes)
|
||||
@@ -508,14 +443,22 @@ git-submodule:
|
||||
git submodule sync --recursive
|
||||
git submodule update --init --recursive --progress
|
||||
|
||||
# Generate the version.h file
|
||||
ifdef SKIP_GIT
|
||||
VERSION_H_FLAGS := --skip-git
|
||||
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)
|
||||
.PHONY: list-keyboards
|
||||
list-keyboards:
|
||||
util/list_keyboards.sh | sort -u | tr '\n' ' '
|
||||
|
||||
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.'
|
||||
|
||||
46
book.json
46
book.json
@@ -1,46 +0,0 @@
|
||||
{
|
||||
"structure": {
|
||||
"summary": "_summary.md"
|
||||
},
|
||||
"plugins" : [
|
||||
"edit-link",
|
||||
"forkmegithub",
|
||||
"hints",
|
||||
"page-toc",
|
||||
"terminal",
|
||||
"toolbar",
|
||||
"bulk-redirect"
|
||||
],
|
||||
"pluginsConfig": {
|
||||
"edit-link": {
|
||||
"base": "https://github.com/qmk/qmk_firmware/edit/master/docs",
|
||||
"label": "Suggest an edit"
|
||||
},
|
||||
"forkmegithub": {
|
||||
"color": "red",
|
||||
"url": "https://github.com/qmk/qmk_firmware"
|
||||
},
|
||||
"page-toc": {
|
||||
"selector": ".markdown-section h1, .markdown-section h2"
|
||||
},
|
||||
"terminal": {
|
||||
"copyButtons": true,
|
||||
"fade": false,
|
||||
"style": "flat"
|
||||
},
|
||||
"toolbar": {
|
||||
"buttons": [
|
||||
{
|
||||
"label": "QMK Firmware",
|
||||
"icon": "fa fa-github",
|
||||
"url": "https://github.com/qmk/qmk_firmware"
|
||||
}
|
||||
]
|
||||
},
|
||||
"bulk-redirect": {
|
||||
"basepath": "/",
|
||||
"redirectsFile": "docs/redirects.json"
|
||||
}
|
||||
},
|
||||
"root": "./docs/"
|
||||
}
|
||||
@@ -30,6 +30,7 @@
|
||||
# bootloadhid HIDBootFlash compatible (ATmega32A)
|
||||
# usbasploader USBaspLoader (ATmega328P)
|
||||
# ARM:
|
||||
# halfkay PJRC Teensy
|
||||
# kiibohd Input:Club Kiibohd bootloader (only used on their boards)
|
||||
# stm32duino STM32Duino (STM32F103x8)
|
||||
# stm32-dfu STM32 USB DFU in ROM
|
||||
@@ -37,12 +38,23 @@
|
||||
# RISC-V:
|
||||
# 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
|
||||
# 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)
|
||||
OPT_DEFS += -DBOOTLOADER_ATMEL_DFU
|
||||
OPT_DEFS += -DBOOTLOADER_DFU
|
||||
BOOTLOADER_TYPE = dfu
|
||||
|
||||
ifneq (,$(filter $(MCU), at90usb162 atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647))
|
||||
BOOTLOADER_SIZE = 4096
|
||||
endif
|
||||
@@ -53,6 +65,8 @@ endif
|
||||
ifeq ($(strip $(BOOTLOADER)), lufa-dfu)
|
||||
OPT_DEFS += -DBOOTLOADER_LUFA_DFU
|
||||
OPT_DEFS += -DBOOTLOADER_DFU
|
||||
BOOTLOADER_TYPE = dfu
|
||||
|
||||
ifneq (,$(filter $(MCU), at90usb162 atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647))
|
||||
BOOTLOADER_SIZE ?= 4096
|
||||
endif
|
||||
@@ -63,6 +77,8 @@ endif
|
||||
ifeq ($(strip $(BOOTLOADER)), qmk-dfu)
|
||||
OPT_DEFS += -DBOOTLOADER_QMK_DFU
|
||||
OPT_DEFS += -DBOOTLOADER_DFU
|
||||
BOOTLOADER_TYPE = dfu
|
||||
|
||||
ifneq (,$(filter $(MCU), at90usb162 atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647))
|
||||
BOOTLOADER_SIZE ?= 4096
|
||||
endif
|
||||
@@ -73,10 +89,14 @@ endif
|
||||
ifeq ($(strip $(BOOTLOADER)), qmk-hid)
|
||||
OPT_DEFS += -DBOOTLOADER_QMK_HID
|
||||
OPT_DEFS += -DBOOTLOADER_HID
|
||||
BOOTLOADER_TYPE = dfu
|
||||
|
||||
BOOTLOADER_SIZE ?= 4096
|
||||
endif
|
||||
ifeq ($(strip $(BOOTLOADER)), halfkay)
|
||||
OPT_DEFS += -DBOOTLOADER_HALFKAY
|
||||
BOOTLOADER_TYPE = halfkay
|
||||
|
||||
ifeq ($(strip $(MCU)), atmega32u4)
|
||||
BOOTLOADER_SIZE = 512
|
||||
endif
|
||||
@@ -86,18 +106,26 @@ ifeq ($(strip $(BOOTLOADER)), halfkay)
|
||||
endif
|
||||
ifeq ($(strip $(BOOTLOADER)), caterina)
|
||||
OPT_DEFS += -DBOOTLOADER_CATERINA
|
||||
BOOTLOADER_TYPE = caterina
|
||||
|
||||
BOOTLOADER_SIZE = 4096
|
||||
endif
|
||||
ifneq (,$(filter $(BOOTLOADER), bootloadhid bootloadHID))
|
||||
OPT_DEFS += -DBOOTLOADER_BOOTLOADHID
|
||||
BOOTLOADER_TYPE = bootloadhid
|
||||
|
||||
BOOTLOADER_SIZE = 4096
|
||||
endif
|
||||
ifneq (,$(filter $(BOOTLOADER), usbasploader USBasp))
|
||||
OPT_DEFS += -DBOOTLOADER_USBASP
|
||||
BOOTLOADER_TYPE = usbasploader
|
||||
|
||||
BOOTLOADER_SIZE = 4096
|
||||
endif
|
||||
ifeq ($(strip $(BOOTLOADER)), lufa-ms)
|
||||
OPT_DEFS += -DBOOTLOADER_MS
|
||||
BOOTLOADER_TYPE = dfu
|
||||
|
||||
BOOTLOADER_SIZE ?= 8192
|
||||
FIRMWARE_FORMAT = bin
|
||||
cpfirmware: lufa_warning
|
||||
@@ -115,6 +143,7 @@ endif
|
||||
|
||||
ifeq ($(strip $(BOOTLOADER)), stm32-dfu)
|
||||
OPT_DEFS += -DBOOTLOADER_STM32_DFU
|
||||
BOOTLOADER_TYPE = stm32_dfu
|
||||
|
||||
# Options to pass to dfu-util when flashing
|
||||
DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave
|
||||
@@ -122,6 +151,7 @@ ifeq ($(strip $(BOOTLOADER)), stm32-dfu)
|
||||
endif
|
||||
ifeq ($(strip $(BOOTLOADER)), apm32-dfu)
|
||||
OPT_DEFS += -DBOOTLOADER_APM32_DFU
|
||||
BOOTLOADER_TYPE = stm32_dfu
|
||||
|
||||
# Options to pass to dfu-util when flashing
|
||||
DFU_ARGS ?= -d 314B:0106 -a 0 -s 0x08000000:leave
|
||||
@@ -129,6 +159,7 @@ ifeq ($(strip $(BOOTLOADER)), apm32-dfu)
|
||||
endif
|
||||
ifeq ($(strip $(BOOTLOADER)), gd32v-dfu)
|
||||
OPT_DEFS += -DBOOTLOADER_GD32V_DFU
|
||||
BOOTLOADER_TYPE = gd32v_dfu
|
||||
|
||||
# Options to pass to dfu-util when flashing
|
||||
DFU_ARGS ?= -d 28E9:0189 -a 0 -s 0x08000000:leave
|
||||
@@ -136,6 +167,8 @@ ifeq ($(strip $(BOOTLOADER)), gd32v-dfu)
|
||||
endif
|
||||
ifeq ($(strip $(BOOTLOADER)), kiibohd)
|
||||
OPT_DEFS += -DBOOTLOADER_KIIBOHD
|
||||
BOOTLOADER_TYPE = kiibohd
|
||||
|
||||
ifeq ($(strip $(MCU_ORIG)), MK20DX128)
|
||||
MCU_LDSCRIPT = MK20DX128BLDR4
|
||||
endif
|
||||
@@ -151,8 +184,7 @@ ifeq ($(strip $(BOOTLOADER)), stm32duino)
|
||||
OPT_DEFS += -DBOOTLOADER_STM32DUINO
|
||||
MCU_LDSCRIPT = STM32F103x8_stm32duino_bootloader
|
||||
BOARD = STM32_F103_STM32DUINO
|
||||
# STM32F103 does NOT have an USB bootloader in ROM (only serial), so setting anything here does not make much sense
|
||||
STM32_BOOTLOADER_ADDRESS = 0x80000000
|
||||
BOOTLOADER_TYPE = stm32duino
|
||||
|
||||
# Options to pass to dfu-util when flashing
|
||||
DFU_ARGS = -d 1EAF:0003 -a 2 -R
|
||||
@@ -160,4 +192,17 @@ ifeq ($(strip $(BOOTLOADER)), stm32duino)
|
||||
endif
|
||||
ifeq ($(strip $(BOOTLOADER)), 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
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
$(TEST)_INC := \
|
||||
tests\test_common\common_config.h
|
||||
tests/test_common/common_config.h
|
||||
|
||||
$(TEST)_SRC := \
|
||||
$(TMK_COMMON_SRC) \
|
||||
@@ -33,4 +33,4 @@ $(TEST)_DEFS := $(TMK_COMMON_DEFS) $(OPT_DEFS)
|
||||
|
||||
$(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
|
||||
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.
|
||||
KEYBOARD_FOLDER_PATH_1 := $(KEYBOARD)
|
||||
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)
|
||||
|
||||
# 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
|
||||
ifeq ("$(wildcard $(KEYMAP_PATH))", "")
|
||||
@@ -127,9 +138,9 @@ ifeq ("$(wildcard $(KEYMAP_PATH))", "")
|
||||
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_1)
|
||||
else ifneq ($(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
|
||||
$(error Could not find keymap)
|
||||
$(call CATASTROPHIC_ERROR,Invalid keymap,Could not find keymap)
|
||||
# this state should never be reached
|
||||
endif
|
||||
endif
|
||||
@@ -148,17 +159,21 @@ ifneq ("$(wildcard $(KEYMAP_JSON))", "")
|
||||
|
||||
# Add rules to generate the keymap files - indentation here is important
|
||||
$(KEYMAP_OUTPUT)/src/keymap.c: $(KEYMAP_JSON)
|
||||
$(QMK_BIN) json2c --quiet --output $(KEYMAP_C) $(KEYMAP_JSON)
|
||||
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
|
||||
$(eval CMD=$(QMK_BIN) json2c --quiet --output $(KEYMAP_C) $(KEYMAP_JSON))
|
||||
@$(BUILD_CMD)
|
||||
|
||||
$(KEYMAP_OUTPUT)/src/config.h: $(KEYMAP_JSON)
|
||||
$(QMK_BIN) generate-config-h --quiet --keyboard $(KEYBOARD) --keymap $(KEYMAP) --output $(KEYMAP_H)
|
||||
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
|
||||
$(eval CMD=$(QMK_BIN) generate-config-h --quiet --keyboard $(KEYBOARD) --keymap $(KEYMAP) --output $(KEYMAP_H))
|
||||
@$(BUILD_CMD)
|
||||
|
||||
generated-files: $(KEYMAP_OUTPUT)/src/config.h $(KEYMAP_OUTPUT)/src/keymap.c
|
||||
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(CTPC)), yes)
|
||||
CONVERT_TO_PROTON_C=yes
|
||||
CONVERT_TO_PROTON_C=yes
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(CONVERT_TO_PROTON_C)), yes)
|
||||
@@ -315,13 +330,19 @@ endif
|
||||
CONFIG_H += $(KEYBOARD_OUTPUT)/src/info_config.h $(KEYBOARD_OUTPUT)/src/layouts.h
|
||||
|
||||
$(KEYBOARD_OUTPUT)/src/info_config.h: $(INFO_JSON_FILES)
|
||||
$(QMK_BIN) generate-config-h --quiet --keyboard $(KEYBOARD) --output $(KEYBOARD_OUTPUT)/src/info_config.h
|
||||
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
|
||||
$(eval CMD=$(QMK_BIN) generate-config-h --quiet --keyboard $(KEYBOARD) --output $(KEYBOARD_OUTPUT)/src/info_config.h)
|
||||
@$(BUILD_CMD)
|
||||
|
||||
$(KEYBOARD_OUTPUT)/src/default_keyboard.h: $(INFO_JSON_FILES)
|
||||
$(QMK_BIN) generate-keyboard-h --quiet --keyboard $(KEYBOARD) --output $(KEYBOARD_OUTPUT)/src/default_keyboard.h
|
||||
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
|
||||
$(eval CMD=$(QMK_BIN) generate-keyboard-h --quiet --keyboard $(KEYBOARD) --output $(KEYBOARD_OUTPUT)/src/default_keyboard.h)
|
||||
@$(BUILD_CMD)
|
||||
|
||||
$(KEYBOARD_OUTPUT)/src/layouts.h: $(INFO_JSON_FILES)
|
||||
$(QMK_BIN) generate-layouts --quiet --keyboard $(KEYBOARD) --output $(KEYBOARD_OUTPUT)/src/layouts.h
|
||||
@$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD)
|
||||
$(eval CMD=$(QMK_BIN) generate-layouts --quiet --keyboard $(KEYBOARD) --output $(KEYBOARD_OUTPUT)/src/layouts.h)
|
||||
@$(BUILD_CMD)
|
||||
|
||||
generated-files: $(KEYBOARD_OUTPUT)/src/info_config.h $(KEYBOARD_OUTPUT)/src/default_keyboard.h $(KEYBOARD_OUTPUT)/src/layouts.h
|
||||
|
||||
@@ -384,8 +405,10 @@ VPATH += $(KEYMAP_PATH)
|
||||
VPATH += $(USER_PATH)
|
||||
VPATH += $(KEYBOARD_PATHS)
|
||||
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 $(TMK_PATH)/protocol.mk
|
||||
include $(PLATFORM_PATH)/common.mk
|
||||
@@ -425,8 +448,7 @@ OUTPUTS := $(KEYMAP_OUTPUT) $(KEYBOARD_OUTPUT)
|
||||
$(KEYMAP_OUTPUT)_SRC := $(SRC)
|
||||
$(KEYMAP_OUTPUT)_DEFS := $(OPT_DEFS) \
|
||||
-DQMK_KEYBOARD=\"$(KEYBOARD)\" -DQMK_KEYBOARD_H=\"$(QMK_KEYBOARD_H)\" \
|
||||
-DQMK_KEYMAP=\"$(KEYMAP)\" -DQMK_KEYMAP_H=\"$(KEYMAP).h\" -DQMK_KEYMAP_CONFIG_H=\"$(KEYMAP_PATH)/config.h\" \
|
||||
-DQMK_SUBPROJECT -DQMK_SUBPROJECT_H -DQMK_SUBPROJECT_CONFIG_H
|
||||
-DQMK_KEYMAP=\"$(KEYMAP)\" -DQMK_KEYMAP_H=\"$(KEYMAP).h\" -DQMK_KEYMAP_CONFIG_H=\"$(KEYMAP_PATH)/config.h\"
|
||||
$(KEYMAP_OUTPUT)_INC := $(VPATH) $(EXTRAINCDIRS)
|
||||
$(KEYMAP_OUTPUT)_CONFIG := $(CONFIG_H)
|
||||
$(KEYBOARD_OUTPUT)_SRC := $(PLATFORM_SRC)
|
||||
@@ -448,7 +470,7 @@ check-md5: build
|
||||
objs-size: build
|
||||
|
||||
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
|
||||
define GEN_FILES
|
||||
@@ -25,7 +25,7 @@ ifneq ($(FORCE_LAYOUT),)
|
||||
$(info Forcing layout: $(FORCE_LAYOUT))
|
||||
LAYOUTS := $(FORCE_LAYOUT)
|
||||
else
|
||||
$(error Forced layout does not exist)
|
||||
$(call CATASTROPHIC_ERROR,Invalid layout,Forced layout does not exist)
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -43,6 +43,7 @@ all: elf
|
||||
VPATH += $(COMMON_VPATH)
|
||||
PLATFORM:=TEST
|
||||
PLATFORM_KEY:=test
|
||||
BOOTLOADER_TYPE:=none
|
||||
|
||||
ifeq ($(strip $(DEBUG)), 1)
|
||||
CONSOLE_ENABLE = yes
|
||||
@@ -53,7 +54,7 @@ include tests/test_common/build.mk
|
||||
include $(TEST_PATH)/test.mk
|
||||
endif
|
||||
|
||||
include common_features.mk
|
||||
include $(BUILDDEFS_PATH)/common_features.mk
|
||||
include $(BUILDDEFS_PATH)/generic_features.mk
|
||||
include $(PLATFORM_PATH)/common.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 $(PLATFORM_PATH)/test/rules.mk
|
||||
ifneq ($(filter $(FULL_TESTS),$(TEST)),)
|
||||
include build_full_test.mk
|
||||
include $(BUILDDEFS_PATH)/build_full_test.mk
|
||||
endif
|
||||
|
||||
$(TEST)_SRC += \
|
||||
@@ -76,7 +77,7 @@ $(TEST_OBJ)/$(TEST)_DEFS := $($(TEST)_DEFS)
|
||||
$(TEST_OBJ)/$(TEST)_CONFIG := $($(TEST)_CONFIG)
|
||||
|
||||
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)
|
||||
@@ -20,7 +20,6 @@ QUANTUM_SRC += \
|
||||
$(QUANTUM_DIR)/led.c \
|
||||
$(QUANTUM_DIR)/action.c \
|
||||
$(QUANTUM_DIR)/action_layer.c \
|
||||
$(QUANTUM_DIR)/action_macro.c \
|
||||
$(QUANTUM_DIR)/action_tapping.c \
|
||||
$(QUANTUM_DIR)/action_util.c \
|
||||
$(QUANTUM_DIR)/eeconfig.c \
|
||||
@@ -109,11 +108,10 @@ ifeq ($(strip $(MOUSEKEY_ENABLE)), yes)
|
||||
SRC += $(QUANTUM_DIR)/mousekey.c
|
||||
endif
|
||||
|
||||
VALID_POINTING_DEVICE_DRIVER_TYPES := adns5050 adns9800 analog_joystick cirque_pinnacle_i2c cirque_pinnacle_spi pmw3360 pimoroni_trackball custom
|
||||
POINTING_DEVICE_DRIVER ?= custom
|
||||
VALID_POINTING_DEVICE_DRIVER_TYPES := adns5050 adns9800 analog_joystick cirque_pinnacle_i2c cirque_pinnacle_spi pmw3360 pmw3389 pimoroni_trackball custom
|
||||
ifeq ($(strip $(POINTING_DEVICE_ENABLE)), yes)
|
||||
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
|
||||
OPT_DEFS += -DPOINTING_DEVICE_ENABLE
|
||||
MOUSE_ENABLE := yes
|
||||
@@ -144,6 +142,9 @@ ifeq ($(strip $(POINTING_DEVICE_ENABLE)), yes)
|
||||
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), pmw3360)
|
||||
OPT_DEFS += -DSTM32_SPI -DHAL_USE_SPI=TRUE
|
||||
QUANTUM_LIB_SRC += spi_master.c
|
||||
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), pmw3389)
|
||||
OPT_DEFS += -DSTM32_SPI -DHAL_USE_SPI=TRUE
|
||||
QUANTUM_LIB_SRC += spi_master.c
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
@@ -151,56 +152,88 @@ endif
|
||||
VALID_EEPROM_DRIVER_TYPES := vendor custom transient i2c spi
|
||||
EEPROM_DRIVER ?= vendor
|
||||
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
|
||||
OPT_DEFS += -DEEPROM_ENABLE
|
||||
ifeq ($(strip $(EEPROM_DRIVER)), custom)
|
||||
# Custom EEPROM implementation -- only needs to implement init/erase/read_block/write_block
|
||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_CUSTOM
|
||||
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
||||
SRC += eeprom_driver.c
|
||||
else ifeq ($(strip $(EEPROM_DRIVER)), i2c)
|
||||
# External I2C EEPROM implementation
|
||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_I2C
|
||||
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
||||
QUANTUM_LIB_SRC += i2c_master.c
|
||||
SRC += eeprom_driver.c eeprom_i2c.c
|
||||
else ifeq ($(strip $(EEPROM_DRIVER)), spi)
|
||||
# External SPI EEPROM implementation
|
||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_SPI
|
||||
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
||||
QUANTUM_LIB_SRC += spi_master.c
|
||||
SRC += eeprom_driver.c eeprom_spi.c
|
||||
else ifeq ($(strip $(EEPROM_DRIVER)), transient)
|
||||
# Transient EEPROM implementation -- no data storage but provides runtime area for it
|
||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT
|
||||
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
||||
SRC += eeprom_driver.c eeprom_transient.c
|
||||
else ifeq ($(strip $(EEPROM_DRIVER)), vendor)
|
||||
# Vendor-implemented EEPROM
|
||||
OPT_DEFS += -DEEPROM_VENDOR
|
||||
ifeq ($(PLATFORM),AVR)
|
||||
# Automatically provided by avr-libc, nothing required
|
||||
else ifeq ($(PLATFORM),CHIBIOS)
|
||||
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
|
||||
SRC += eeprom_driver.c
|
||||
SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
|
||||
SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
|
||||
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 += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/eeprom
|
||||
SRC += eeprom_driver.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
|
||||
# This will effectively work the same as "transient" if not supported by the chip
|
||||
SRC += $(PLATFORM_COMMON_DIR)/eeprom_teensy.c
|
||||
# Fall back to transient, i.e. non-persistent
|
||||
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT
|
||||
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
||||
SRC += eeprom_driver.c eeprom_transient.c
|
||||
endif
|
||||
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)
|
||||
# Test harness "EEPROM"
|
||||
OPT_DEFS += -DEEPROM_TEST_HARNESS
|
||||
SRC += $(PLATFORM_COMMON_DIR)/eeprom.c
|
||||
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
|
||||
VALID_RGBLIGHT_TYPES := WS2812 APA102 custom
|
||||
|
||||
@@ -212,7 +245,7 @@ ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
|
||||
RGBLIGHT_DRIVER ?= WS2812
|
||||
|
||||
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
|
||||
COMMON_VPATH += $(QUANTUM_DIR)/rgblight
|
||||
POST_CONFIG_H += $(QUANTUM_DIR)/rgblight/rgblight_post_config.h
|
||||
@@ -237,12 +270,12 @@ ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
|
||||
endif
|
||||
|
||||
LED_MATRIX_ENABLE ?= no
|
||||
VALID_LED_MATRIX_TYPES := IS31FL3731 custom
|
||||
VALID_LED_MATRIX_TYPES := IS31FL3731 IS31FL3742A IS31FL3743A IS31FL3745 IS31FL3746A custom
|
||||
# TODO: IS31FL3733 IS31FL3737 IS31FL3741
|
||||
|
||||
ifeq ($(strip $(LED_MATRIX_ENABLE)), yes)
|
||||
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
|
||||
OPT_DEFS += -DLED_MATRIX_ENABLE
|
||||
ifneq (,$(filter $(MCU), atmega16u2 atmega32u2 at90usb162))
|
||||
@@ -264,14 +297,43 @@ endif
|
||||
SRC += is31fl3731-simple.c
|
||||
QUANTUM_LIB_SRC += i2c_master.c
|
||||
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
|
||||
|
||||
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 ($(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
|
||||
OPT_DEFS += -DRGB_MATRIX_ENABLE
|
||||
ifneq (,$(filter $(MCU), atmega16u2 atmega32u2 at90usb162))
|
||||
@@ -323,6 +385,34 @@ endif
|
||||
QUANTUM_LIB_SRC += i2c_master.c
|
||||
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)
|
||||
OPT_DEFS += -DCKLED2001 -DSTM32_I2C -DHAL_USE_I2C=TRUE
|
||||
COMMON_VPATH += $(DRIVER_PATH)/led
|
||||
@@ -356,7 +446,7 @@ endif
|
||||
ifeq ($(strip $(PRINTING_ENABLE)), yes)
|
||||
OPT_DEFS += -DPRINTING_ENABLE
|
||||
SRC += $(QUANTUM_DIR)/process_keycode/process_printer.c
|
||||
SRC += $(TMK_DIR)/protocol/serial_uart.c
|
||||
QUANTUM_LIB_SRC += uart.c
|
||||
endif
|
||||
|
||||
VARIABLE_TRACE ?= no
|
||||
@@ -385,7 +475,7 @@ else
|
||||
endif
|
||||
ifeq ($(strip $(BACKLIGHT_ENABLE)), yes)
|
||||
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
|
||||
|
||||
COMMON_VPATH += $(QUANTUM_DIR)/backlight
|
||||
@@ -410,7 +500,7 @@ VALID_WS2812_DRIVER_TYPES := bitbang pwm spi i2c
|
||||
WS2812_DRIVER ?= bitbang
|
||||
ifeq ($(strip $(WS2812_DRIVER_REQUIRED)), yes)
|
||||
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
|
||||
|
||||
OPT_DEFS += -DWS2812_DRIVER_$(strip $(shell echo $(WS2812_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
||||
@@ -471,7 +561,7 @@ VALID_MAGIC_TYPES := yes
|
||||
BOOTMAGIC_ENABLE ?= no
|
||||
ifneq ($(strip $(BOOTMAGIC_ENABLE)), no)
|
||||
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
|
||||
ifneq ($(strip $(BOOTMAGIC_ENABLE)), no)
|
||||
OPT_DEFS += -DBOOTMAGIC_LITE
|
||||
@@ -487,7 +577,7 @@ CUSTOM_MATRIX ?= no
|
||||
|
||||
ifneq ($(strip $(CUSTOM_MATRIX)), yes)
|
||||
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
|
||||
|
||||
# Include common stuff for all non custom matrix users
|
||||
@@ -570,7 +660,7 @@ VALID_OLED_DRIVER_TYPES := SSD1306 custom
|
||||
OLED_DRIVER ?= SSD1306
|
||||
ifeq ($(strip $(OLED_ENABLE)), yes)
|
||||
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
|
||||
OPT_DEFS += -DOLED_ENABLE
|
||||
COMMON_VPATH += $(DRIVER_PATH)/oled
|
||||
@@ -610,6 +700,7 @@ ifeq ($(strip $(UNICODE_ENABLE)), yes)
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(UNICODE_COMMON)), yes)
|
||||
OPT_DEFS += -DUNICODE_COMMON_ENABLE
|
||||
SRC += $(QUANTUM_DIR)/process_keycode/process_unicode_common.c
|
||||
endif
|
||||
|
||||
@@ -637,7 +728,7 @@ endif
|
||||
ifeq ($(strip $(PS2_USE_BUSYWAIT)), yes)
|
||||
PS2_ENABLE := yes
|
||||
SRC += ps2_busywait.c
|
||||
SRC += ps2_io_avr.c
|
||||
SRC += ps2_io.c
|
||||
OPT_DEFS += -DPS2_USE_BUSYWAIT
|
||||
endif
|
||||
|
||||
@@ -666,7 +757,7 @@ VALID_JOYSTICK_TYPES := analog digital
|
||||
JOYSTICK_DRIVER ?= analog
|
||||
ifeq ($(strip $(JOYSTICK_ENABLE)), yes)
|
||||
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
|
||||
OPT_DEFS += -DJOYSTICK_ENABLE
|
||||
SRC += $(QUANTUM_DIR)/process_keycode/process_joystick.c
|
||||
@@ -686,7 +777,7 @@ VALID_USBPD_DRIVER_TYPES = custom vendor
|
||||
USBPD_DRIVER ?= vendor
|
||||
ifeq ($(strip $(USBPD_ENABLE)), yes)
|
||||
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
|
||||
OPT_DEFS += -DUSBPD_ENABLE
|
||||
ifeq ($(strip $(USBPD_DRIVER)), vendor)
|
||||
@@ -696,7 +787,7 @@ ifeq ($(strip $(USBPD_ENABLE)), yes)
|
||||
OPT_DEFS += -DUSBPD_STM32G4
|
||||
SRC += usbpd_stm32g4.c
|
||||
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
|
||||
else ifeq ($(strip $(USBPD_DRIVER)), custom)
|
||||
OPT_DEFS += -DUSBPD_CUSTOM
|
||||
@@ -706,25 +797,26 @@ ifeq ($(strip $(USBPD_ENABLE)), yes)
|
||||
endif
|
||||
|
||||
BLUETOOTH_ENABLE ?= no
|
||||
VALID_BLUETOOTH_DRIVER_TYPES := AdafruitBLE RN42 custom
|
||||
VALID_BLUETOOTH_DRIVER_TYPES := BluefruitLE RN42 custom
|
||||
ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
|
||||
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
|
||||
OPT_DEFS += -DBLUETOOTH_ENABLE
|
||||
NO_USB_STARTUP_CHECK := yes
|
||||
COMMON_VPATH += $(DRIVER_PATH)/bluetooth
|
||||
SRC += outputselect.c
|
||||
|
||||
ifeq ($(strip $(BLUETOOTH_DRIVER)), AdafruitBLE)
|
||||
OPT_DEFS += -DMODULE_ADAFRUIT_BLE
|
||||
ifeq ($(strip $(BLUETOOTH_DRIVER)), BluefruitLE)
|
||||
OPT_DEFS += -DBLUETOOTH_BLUEFRUIT_LE
|
||||
SRC += analog.c
|
||||
SRC += $(DRIVER_PATH)/bluetooth/adafruit_ble.cpp
|
||||
SRC += $(DRIVER_PATH)/bluetooth/bluefruit_le.cpp
|
||||
QUANTUM_LIB_SRC += spi_master.c
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(BLUETOOTH_DRIVER)), RN42)
|
||||
OPT_DEFS += -DMODULE_RN42
|
||||
SRC += $(TMK_DIR)/protocol/serial_uart.c
|
||||
OPT_DEFS += -DBLUETOOTH_RN42
|
||||
SRC += $(DRIVER_PATH)/bluetooth/rn42.c
|
||||
QUANTUM_LIB_SRC += uart.c
|
||||
endif
|
||||
endif
|
||||
@@ -234,6 +234,7 @@ endif
|
||||
|
||||
# Define programs and commands.
|
||||
SHELL = sh
|
||||
SED = sed
|
||||
REMOVE = rm -f
|
||||
REMOVEDIR = rmdir
|
||||
COPY = cp
|
||||
@@ -292,17 +293,15 @@ sym: $(BUILD_DIR)/$(TARGET).sym
|
||||
LIBNAME=lib$(TARGET).a
|
||||
lib: $(LIBNAME)
|
||||
|
||||
# Display size of file.
|
||||
HEXSIZE = $(SIZE) --target=$(FORMAT) $(BUILD_DIR)/$(TARGET).hex
|
||||
#ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf
|
||||
ELFSIZE = $(SIZE) $(BUILD_DIR)/$(TARGET).elf
|
||||
# Display size of file, modifying the output so people don't mistakenly grab the hex output
|
||||
BINARY_SIZE = $(SIZE) --target=$(FORMAT) $(BUILD_DIR)/$(TARGET).hex | $(SED) -e 's/\.build\/.*$$/$(TARGET).$(FIRMWARE_FORMAT)/g'
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
# Display compiler version information.
|
||||
@@ -479,7 +478,7 @@ ifeq ($(findstring avr-gcc,$(CC)),avr-gcc)
|
||||
SIZE_MARGIN = 1024
|
||||
|
||||
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 FREE_SIZE=$(shell expr $(MAX_SIZE) - $(CURRENT_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
|
||||
USE_PROCESS_STACKSIZE = 0x600
|
||||
USE_EXCEPTIONS_STACKSIZE = 0x300
|
||||
|
||||
# Bootloader address for STM32 DFU
|
||||
STM32_BOOTLOADER_ADDRESS ?= 0x1FFFC400
|
||||
endif
|
||||
|
||||
ifneq ($(findstring STM32F072, $(MCU)),)
|
||||
@@ -175,6 +178,9 @@ ifneq ($(findstring STM32F072, $(MCU)),)
|
||||
|
||||
# UF2 settings
|
||||
UF2_FAMILY ?= STM32F0
|
||||
|
||||
# Bootloader address for STM32 DFU
|
||||
STM32_BOOTLOADER_ADDRESS ?= 0x1FFFC800
|
||||
endif
|
||||
|
||||
ifneq ($(findstring STM32F103, $(MCU)),)
|
||||
@@ -239,6 +245,9 @@ ifneq ($(findstring STM32F303, $(MCU)),)
|
||||
|
||||
# UF2 settings
|
||||
UF2_FAMILY ?= STM32F3
|
||||
|
||||
# Bootloader address for STM32 DFU
|
||||
STM32_BOOTLOADER_ADDRESS ?= 0x1FFFD800
|
||||
endif
|
||||
|
||||
ifneq ($(findstring STM32F401, $(MCU)),)
|
||||
@@ -276,6 +285,9 @@ ifneq ($(findstring STM32F401, $(MCU)),)
|
||||
|
||||
# UF2 settings
|
||||
UF2_FAMILY ?= STM32F4
|
||||
|
||||
# Bootloader address for STM32 DFU
|
||||
STM32_BOOTLOADER_ADDRESS ?= 0x1FFF0000
|
||||
endif
|
||||
|
||||
ifneq ($(findstring STM32F405, $(MCU)),)
|
||||
@@ -308,6 +320,9 @@ ifneq ($(findstring STM32F405, $(MCU)),)
|
||||
|
||||
# UF2 settings
|
||||
UF2_FAMILY ?= STM32F4
|
||||
|
||||
# Bootloader address for STM32 DFU
|
||||
STM32_BOOTLOADER_ADDRESS ?= 0x1FFF0000
|
||||
endif
|
||||
|
||||
ifneq ($(findstring STM32F407, $(MCU)),)
|
||||
@@ -340,6 +355,9 @@ ifneq ($(findstring STM32F407, $(MCU)),)
|
||||
|
||||
# UF2 settings
|
||||
UF2_FAMILY ?= STM32F4
|
||||
|
||||
# Bootloader address for STM32 DFU
|
||||
STM32_BOOTLOADER_ADDRESS ?= 0x1FFF0000
|
||||
endif
|
||||
|
||||
ifneq ($(findstring STM32F411, $(MCU)),)
|
||||
@@ -377,6 +395,9 @@ ifneq ($(findstring STM32F411, $(MCU)),)
|
||||
|
||||
# UF2 settings
|
||||
UF2_FAMILY ?= STM32F4
|
||||
|
||||
# Bootloader address for STM32 DFU
|
||||
STM32_BOOTLOADER_ADDRESS ?= 0x1FFF0000
|
||||
endif
|
||||
|
||||
ifneq ($(findstring STM32F446, $(MCU)),)
|
||||
@@ -406,6 +427,9 @@ ifneq ($(findstring STM32F446, $(MCU)),)
|
||||
BOARD ?= GENERIC_STM32_F446XE
|
||||
|
||||
USE_FPU ?= yes
|
||||
|
||||
# Bootloader address for STM32 DFU
|
||||
STM32_BOOTLOADER_ADDRESS ?= 0x1FFF0000
|
||||
endif
|
||||
|
||||
ifneq ($(findstring STM32G431, $(MCU)),)
|
||||
@@ -438,6 +462,9 @@ ifneq ($(findstring STM32G431, $(MCU)),)
|
||||
|
||||
# UF2 settings
|
||||
UF2_FAMILY ?= STM32G4
|
||||
|
||||
# Bootloader address for STM32 DFU
|
||||
STM32_BOOTLOADER_ADDRESS ?= 0x1FFF0000
|
||||
endif
|
||||
|
||||
ifneq ($(findstring STM32G474, $(MCU)),)
|
||||
@@ -470,6 +497,46 @@ ifneq ($(findstring STM32G474, $(MCU)),)
|
||||
|
||||
# UF2 settings
|
||||
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
|
||||
|
||||
ifneq (,$(filter $(MCU),STM32L433 STM32L443))
|
||||
@@ -504,6 +571,9 @@ ifneq (,$(filter $(MCU),STM32L433 STM32L443))
|
||||
|
||||
# UF2 settings
|
||||
UF2_FAMILY ?= STM32L4
|
||||
|
||||
# Bootloader address for STM32 DFU
|
||||
STM32_BOOTLOADER_ADDRESS ?= 0x1FFF0000
|
||||
endif
|
||||
|
||||
ifneq (,$(filter $(MCU),STM32L412 STM32L422))
|
||||
@@ -538,6 +608,9 @@ ifneq (,$(filter $(MCU),STM32L412 STM32L422))
|
||||
|
||||
# UF2 settings
|
||||
UF2_FAMILY ?= STM32L4
|
||||
|
||||
# Bootloader address for STM32 DFU
|
||||
STM32_BOOTLOADER_ADDRESS ?= 0x1FFF0000
|
||||
endif
|
||||
|
||||
ifneq ($(findstring WB32F3G71, $(MCU)),)
|
||||
@@ -567,6 +640,10 @@ ifneq ($(findstring WB32F3G71, $(MCU)),)
|
||||
BOARD ?= GENERIC_WB32_F3G71XX
|
||||
|
||||
USE_FPU ?= no
|
||||
|
||||
# Bootloader address for WB32 DFU
|
||||
STM32_BOOTLOADER_ADDRESS ?= 0x1FFFE000
|
||||
WB32_BOOTLOADER_ADDRESS ?= 0x1FFFE000
|
||||
endif
|
||||
|
||||
ifneq ($(findstring GD32VF103, $(MCU)),)
|
||||
|
||||
@@ -63,6 +63,7 @@ MSG_COMPILING_CXX = Compiling:
|
||||
MSG_ASSEMBLING = Assembling:
|
||||
MSG_CLEANING = Cleaning project:
|
||||
MSG_CREATING_LIBRARY = Creating library:
|
||||
MSG_GENERATING = Generating:
|
||||
MSG_SUBMODULE_DIRTY = $(WARN_COLOR)WARNING:$(NO_COLOR) Some git submodules are out of date or modified.\n\
|
||||
Please consider running $(BOLD)make git-submodule$(NO_COLOR).\n\n
|
||||
MSG_NO_CMP = $(ERROR_COLOR)Error:$(NO_COLOR)$(BOLD) cmp command not found, please install diffutils\n$(NO_COLOR)
|
||||
@@ -87,6 +88,7 @@ define GENERATE_MSG_AVAILABLE_KEYMAPS
|
||||
endef
|
||||
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_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
|
||||
@@ -97,6 +99,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
|
||||
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_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
|
||||
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
|
||||
ifneq ($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
|
||||
$$(eval $$(call VALIDATE_TEST_LIST,$$(firstword $2),$$(wordlist 2,9999,$2)))
|
||||
endif
|
||||
@@ -15,6 +15,8 @@
|
||||
"COMBO_TERM": {"info_key": "combo.term", "value_type": "int"},
|
||||
"DEBOUNCE": {"info_key": "debounce", "value_type": "int"},
|
||||
"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},
|
||||
"DIODE_DIRECTION": {"info_key": "diode_direction"},
|
||||
"FORCE_NKRO": {"info_key": "usb.force_nkro", "value_type": "bool"},
|
||||
|
||||
@@ -41,8 +41,14 @@
|
||||
'atom47/rev3': {
|
||||
target: 'maartenwut/atom47/rev3'
|
||||
},
|
||||
bakeneko60: {
|
||||
target: 'kkatano/bakeneko60'
|
||||
},
|
||||
bakeneko65: {
|
||||
target: 'bakeneko65/rev2'
|
||||
target: 'kkatano/bakeneko65/rev2'
|
||||
},
|
||||
bakeneko80: {
|
||||
target: 'kkatano/bakeneko80'
|
||||
},
|
||||
bear_face: {
|
||||
target: 'bear_face/v1'
|
||||
@@ -215,6 +221,9 @@
|
||||
LAYOUT: 'LAYOUT_all'
|
||||
}
|
||||
},
|
||||
idobo: {
|
||||
target: 'idobao/id75'
|
||||
},
|
||||
'jj40': {
|
||||
target: 'kprepublic/jj40'
|
||||
},
|
||||
@@ -260,6 +269,9 @@
|
||||
'lfkeyboards/smk65': {
|
||||
target: 'lfkeyboards/smk65/revb'
|
||||
},
|
||||
m3v3van: {
|
||||
target: 'matthewdias/m3n3van'
|
||||
},
|
||||
'maartenwut/atom47/rev2': {
|
||||
target: 'evyd13/atom47/rev2'
|
||||
},
|
||||
@@ -344,15 +356,24 @@
|
||||
'mechlovin/hannah65/mechlovin9': {
|
||||
target: 'mechlovin/mechlovin9/rev1'
|
||||
},
|
||||
'mechlovin/hex4b': {
|
||||
target: 'mechlovin/hex4b/rev1'
|
||||
},
|
||||
'melgeek/z70ultra': {
|
||||
target: 'melgeek/z70ultra/rev1'
|
||||
},
|
||||
'mechlovin/hannah65': {
|
||||
target: 'mechlovin/hannah65/rev1'
|
||||
},
|
||||
minim: {
|
||||
target: 'matthewdias/minim'
|
||||
},
|
||||
model01: {
|
||||
target: 'keyboardio/model01'
|
||||
},
|
||||
model_v: {
|
||||
target: 'matthewdias/model_v'
|
||||
},
|
||||
m0lly: {
|
||||
target: 'tkc/m0lly'
|
||||
},
|
||||
@@ -495,6 +516,9 @@
|
||||
'tokyo60': {
|
||||
target: 'tokyokeyboard/tokyo60'
|
||||
},
|
||||
'txuu': {
|
||||
target: 'matthewdias/txuu'
|
||||
},
|
||||
underscore33: {
|
||||
target: 'underscore33/rev1'
|
||||
},
|
||||
@@ -547,7 +571,7 @@
|
||||
target: 'xelus/valor/rev1'
|
||||
},
|
||||
yd60mq: {
|
||||
target: 'yd60mq/12led'
|
||||
target: 'ymdk/yd60mq/12led'
|
||||
},
|
||||
ymd75: {
|
||||
target: 'ymd75/rev1'
|
||||
@@ -560,5 +584,615 @@
|
||||
},
|
||||
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",
|
||||
"pattern": "^0x[0-9A-F]{4}$"
|
||||
},
|
||||
"bcd_version": {
|
||||
"type": "string",
|
||||
"pattern": "^[0-9]{1,2}\\.[0-9]\\.[0-9]$"
|
||||
},
|
||||
"text_identifier": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
@@ -29,7 +33,33 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"enum": ["LAYOUT", "LAYOUT_planck_1x2uC"]
|
||||
"enum": [
|
||||
"LAYOUT",
|
||||
"LAYOUT_1x2uC",
|
||||
"LAYOUT_1x2uL",
|
||||
"LAYOUT_1x2uR",
|
||||
"LAYOUT_2x2uC",
|
||||
"LAYOUT_2x3uC",
|
||||
"LAYOUT_625uC",
|
||||
"LAYOUT_ANSI_DEFAULT",
|
||||
"LAYOUT_JP",
|
||||
"LAYOUT_ortho_3x12_1x2uC",
|
||||
"LAYOUT_ortho_4x12_1x2uC",
|
||||
"LAYOUT_ortho_4x12_1x2uL",
|
||||
"LAYOUT_ortho_4x12_1x2uR",
|
||||
"LAYOUT_ortho_5x12_1x2uC",
|
||||
"LAYOUT_ortho_5x12_2x2uC",
|
||||
"LAYOUT_ortho_5x14_1x2uC",
|
||||
"LAYOUT_ortho_5x14_1x2uL",
|
||||
"LAYOUT_ortho_5x14_1x2uR",
|
||||
"LAYOUT_planck_1x2uC",
|
||||
"LAYOUT_planck_1x2uL",
|
||||
"LAYOUT_planck_1x2uR",
|
||||
"LAYOUT_preonic_1x2uC",
|
||||
"LAYOUT_preonic_1x2uL",
|
||||
"LAYOUT_preonic_1x2uR",
|
||||
"LAYOUT_reviung34_2uL"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
@@ -47,6 +77,10 @@
|
||||
},
|
||||
"mcu_pin": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"enum": ["NO_PIN"]
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^[A-K]\\d{1,2}$"
|
||||
@@ -70,13 +104,13 @@
|
||||
"signed_int": {
|
||||
"type": "number",
|
||||
"multipleOf": 1
|
||||
}
|
||||
},
|
||||
"signed_int_8": {
|
||||
"type": "number",
|
||||
"min": -127,
|
||||
"max": 127,
|
||||
"multipleOf": 1
|
||||
}
|
||||
},
|
||||
"string_array": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@@ -97,7 +131,7 @@
|
||||
"type": "number",
|
||||
"min": 0,
|
||||
"multipleOf": 1
|
||||
}
|
||||
},
|
||||
"unsigned_int_8": {
|
||||
"type": "number",
|
||||
"min": 0,
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
},
|
||||
"processor": {
|
||||
"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": {
|
||||
"type": "object",
|
||||
@@ -45,7 +45,7 @@
|
||||
"properties": {
|
||||
"driver": {
|
||||
"type": "string",
|
||||
"enum": ["AdafruitBLE", "RN42"]
|
||||
"enum": ["BluefruitLE", "RN42"]
|
||||
},
|
||||
"lto": {"type": "boolean"},
|
||||
}
|
||||
@@ -57,7 +57,7 @@
|
||||
},
|
||||
"bootloader": {
|
||||
"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": {
|
||||
"type": "string",
|
||||
@@ -69,7 +69,7 @@
|
||||
"properties": {
|
||||
"debounce_type": {
|
||||
"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": {
|
||||
"type": "string",
|
||||
@@ -109,6 +109,7 @@
|
||||
},
|
||||
"layouts": {
|
||||
"type": "object",
|
||||
"propertyNames": {"$ref": "qmk.definitions.v1#/layout_macro"},
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
@@ -320,7 +321,8 @@
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"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"},
|
||||
"pid": {"$ref": "qmk.definitions.v1#/hex_number_4d"},
|
||||
"vid": {"$ref": "qmk.definitions.v1#/hex_number_4d"},
|
||||
|
||||
@@ -53,5 +53,10 @@
|
||||
"type": "string",
|
||||
"description": "asdf"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"keyboard",
|
||||
"layout",
|
||||
"layers"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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,18 +0,0 @@
|
||||
# MCU name
|
||||
MCU = atmega32u4
|
||||
|
||||
# Bootloader selection
|
||||
BOOTLOADER = atmel-dfu
|
||||
|
||||
# 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
|
||||
NKRO_ENABLE = no # Enable N-Key Rollover
|
||||
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
|
||||
RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
|
||||
AUDIO_ENABLE = no # Audio output
|
||||
@@ -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": true,
|
||||
"command": false,
|
||||
"console": false,
|
||||
"extrakey": true,
|
||||
"mousekey": true,
|
||||
"nkro": true
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,20 @@
|
||||
# %(KEYBOARD)s
|
||||
# %KEYBOARD%
|
||||
|
||||

|
||||

|
||||
|
||||
*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 Availability: *Links to where you can find this hardware*
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
||||
make %(KEYBOARD)s:default
|
||||
make %KEYBOARD%:default
|
||||
|
||||
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).
|
||||
|
||||
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
|
||||
|
||||

|
||||
|
||||
*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
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "adafruit_ble.h"
|
||||
#include "bluefruit_le.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -16,20 +16,20 @@
|
||||
// These are the pin assignments for the 32u4 boards.
|
||||
// You may define them to something else in your config.h
|
||||
// if yours is wired up differently.
|
||||
#ifndef ADAFRUIT_BLE_RST_PIN
|
||||
# define ADAFRUIT_BLE_RST_PIN D4
|
||||
#ifndef BLUEFRUIT_LE_RST_PIN
|
||||
# define BLUEFRUIT_LE_RST_PIN D4
|
||||
#endif
|
||||
|
||||
#ifndef ADAFRUIT_BLE_CS_PIN
|
||||
# define ADAFRUIT_BLE_CS_PIN B4
|
||||
#ifndef BLUEFRUIT_LE_CS_PIN
|
||||
# define BLUEFRUIT_LE_CS_PIN B4
|
||||
#endif
|
||||
|
||||
#ifndef ADAFRUIT_BLE_IRQ_PIN
|
||||
# define ADAFRUIT_BLE_IRQ_PIN E6
|
||||
#ifndef BLUEFRUIT_LE_IRQ_PIN
|
||||
# define BLUEFRUIT_LE_IRQ_PIN E6
|
||||
#endif
|
||||
|
||||
#ifndef ADAFRUIT_BLE_SCK_DIVISOR
|
||||
# define ADAFRUIT_BLE_SCK_DIVISOR 2 // 4MHz SCK/8MHz CPU, calculated for Feather 32U4 BLE
|
||||
#ifndef BLUEFRUIT_LE_SCK_DIVISOR
|
||||
# define BLUEFRUIT_LE_SCK_DIVISOR 2 // 4MHz SCK/8MHz CPU, calculated for Feather 32U4 BLE
|
||||
#endif
|
||||
|
||||
#define SAMPLE_BATTERY
|
||||
@@ -77,10 +77,10 @@ struct sdep_msg {
|
||||
// information here.
|
||||
|
||||
enum queue_type {
|
||||
QTKeyReport, // 1-byte modifier + 6-byte key report
|
||||
QTConsumer, // 16-bit key code
|
||||
QTKeyReport, // 1-byte modifier + 6-byte key report
|
||||
QTConsumer, // 16-bit key code
|
||||
#ifdef MOUSE_ENABLE
|
||||
QTMouseMove, // 4-byte mouse report
|
||||
QTMouseMove, // 4-byte mouse report
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -115,8 +115,8 @@ enum sdep_type {
|
||||
SdepResponse = 0x20,
|
||||
SdepAlert = 0x40,
|
||||
SdepError = 0x80,
|
||||
SdepSlaveNotReady = 0xFE, // Try again later
|
||||
SdepSlaveOverflow = 0xFF, // You read more data than is available
|
||||
SdepSlaveNotReady = 0xFE, // Try again later
|
||||
SdepSlaveOverflow = 0xFF, // You read more data than is available
|
||||
};
|
||||
|
||||
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
|
||||
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();
|
||||
bool success = 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
|
||||
spi_stop();
|
||||
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);
|
||||
|
||||
if (ready) {
|
||||
@@ -190,7 +190,7 @@ static bool sdep_recv_pkt(struct sdep_msg *msg, uint16_t timeout) {
|
||||
bool ready = false;
|
||||
|
||||
do {
|
||||
ready = readPin(ADAFRUIT_BLE_IRQ_PIN);
|
||||
ready = readPin(BLUEFRUIT_LE_IRQ_PIN);
|
||||
if (ready) {
|
||||
break;
|
||||
}
|
||||
@@ -198,7 +198,7 @@ static bool sdep_recv_pkt(struct sdep_msg *msg, uint16_t timeout) {
|
||||
} while (timer_elapsed(timerStart) < timeout);
|
||||
|
||||
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 {
|
||||
// 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
|
||||
spi_stop();
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ static void resp_buf_read_one(bool greedy) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (readPin(ADAFRUIT_BLE_IRQ_PIN)) {
|
||||
if (readPin(BLUEFRUIT_LE_IRQ_PIN)) {
|
||||
struct sdep_msg msg;
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -295,24 +295,26 @@ static bool ble_init(void) {
|
||||
state.configured = false;
|
||||
state.is_connected = false;
|
||||
|
||||
setPinInput(ADAFRUIT_BLE_IRQ_PIN);
|
||||
setPinInput(BLUEFRUIT_LE_IRQ_PIN);
|
||||
|
||||
spi_init();
|
||||
|
||||
// Perform a hardware reset
|
||||
setPinOutput(ADAFRUIT_BLE_RST_PIN);
|
||||
writePinHigh(ADAFRUIT_BLE_RST_PIN);
|
||||
writePinLow(ADAFRUIT_BLE_RST_PIN);
|
||||
setPinOutput(BLUEFRUIT_LE_RST_PIN);
|
||||
writePinHigh(BLUEFRUIT_LE_RST_PIN);
|
||||
writePinLow(BLUEFRUIT_LE_RST_PIN);
|
||||
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;
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
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];
|
||||
|
||||
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];
|
||||
|
||||
if (!state.configured && !adafruit_ble_enable_keyboard()) {
|
||||
if (!state.configured && !bluefruit_le_enable_keyboard()) {
|
||||
return;
|
||||
}
|
||||
resp_buf_read_one(true);
|
||||
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
|
||||
if (at_command_P(PSTR("AT+EVENTSTATUS"), resbuf, sizeof(resbuf))) {
|
||||
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;
|
||||
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;
|
||||
|
||||
item.queue_type = QTConsumer;
|
||||
@@ -655,7 +659,7 @@ void adafruit_ble_send_consumer_key(uint16_t usage) {
|
||||
}
|
||||
|
||||
#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;
|
||||
|
||||
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
|
||||
|
||||
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) {
|
||||
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
|
||||
bool adafruit_ble_set_power_level(int8_t level) {
|
||||
bool bluefruit_le_set_power_level(int8_t level) {
|
||||
char cmd[46];
|
||||
if (!state.configured) {
|
||||
return false;
|
||||
@@ -16,43 +16,43 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* 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 */
|
||||
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.
|
||||
* This uses our cached understanding that is maintained by
|
||||
* 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 */
|
||||
extern void adafruit_ble_task(void);
|
||||
extern void bluefruit_le_task(void);
|
||||
|
||||
/* Generates keypress events for a set of keys.
|
||||
* The hid modifier mask specifies the state of the modifier keys for
|
||||
* this set of keys.
|
||||
* Also sends a key release indicator, so that the keys do not remain
|
||||
* 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.
|
||||
* (milliseconds) */
|
||||
extern void adafruit_ble_send_consumer_key(uint16_t usage);
|
||||
extern void bluefruit_le_send_consumer_key(uint16_t usage);
|
||||
|
||||
#ifdef MOUSE_ENABLE
|
||||
/* Send a mouse/wheel movement report.
|
||||
* The parameters are signed and indicate positive or negative direction
|
||||
* 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
|
||||
|
||||
/* Compute battery voltage by reading an analog pin.
|
||||
* 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 adafruit_ble_set_power_level(int8_t level);
|
||||
extern bool bluefruit_le_set_mode_leds(bool on);
|
||||
extern bool bluefruit_le_set_power_level(int8_t level);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@@ -13,13 +13,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "outputselect.h"
|
||||
#include "usb_util.h"
|
||||
|
||||
#if defined(PROTOCOL_LUFA)
|
||||
# include "lufa.h"
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_ADAFRUIT_BLE
|
||||
# include "adafruit_ble.h"
|
||||
#ifdef BLUETOOTH_BLUEFRUIT_LE
|
||||
# include "bluefruit_le.h"
|
||||
#endif
|
||||
|
||||
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) {}
|
||||
|
||||
static bool is_usb_configured(void) {
|
||||
#if defined(PROTOCOL_LUFA)
|
||||
return USB_DeviceState == DEVICE_STATE_Configured;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \brief Auto Detect Output
|
||||
*
|
||||
* FIXME: Needs doc
|
||||
*/
|
||||
uint8_t auto_detect_output(void) {
|
||||
if (is_usb_configured()) {
|
||||
if (usb_connected_state()) {
|
||||
return OUTPUT_USB;
|
||||
}
|
||||
|
||||
#ifdef MODULE_ADAFRUIT_BLE
|
||||
if (adafruit_ble_is_connected()) {
|
||||
#ifdef BLUETOOTH_BLUEFRUIT_LE
|
||||
if (bluefruit_le_is_connected()) {
|
||||
return OUTPUT_BLUETOOTH;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BLUETOOTH_ENABLE
|
||||
return OUTPUT_BLUETOOTH; // should check if BT is connected here
|
||||
return OUTPUT_BLUETOOTH; // should check if BT is connected here
|
||||
#endif
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2018-2020 Nick Brassel (@tzarc)
|
||||
/* 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
|
||||
@@ -14,10 +14,12 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Address for jumping to bootloader on STM32 chips. */
|
||||
/* It is chip dependent, the correct number can be looked up here (page 175):
|
||||
* http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf
|
||||
* This also requires a patch to chibios:
|
||||
* <tmk_dir>/tmk_core/tool/chibios/ch-bootloader-jump.patch
|
||||
*/
|
||||
#define STM32_BOOTLOADER_ADDRESS 0x1FFF0000
|
||||
#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;
|
||||
}
|
||||
|
||||
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) {
|
||||
uint8_t read_buf[len];
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
#if defined(CONSOLE_ENABLE) && defined(DEBUG_EEPROM_OUTPUT)
|
||||
# include "timer.h"
|
||||
# include "debug.h"
|
||||
#endif // DEBUG_EEPROM_OUTPUT
|
||||
#endif // DEBUG_EEPROM_OUTPUT
|
||||
|
||||
static inline void fill_target_address(uint8_t *buffer, const void *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("\n");
|
||||
#endif // DEBUG_EEPROM_OUTPUT
|
||||
#endif // DEBUG_EEPROM_OUTPUT
|
||||
}
|
||||
|
||||
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("\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);
|
||||
wait_ms(EXTERNAL_EEPROM_WRITE_TIME);
|
||||
|
||||
@@ -52,7 +52,9 @@
|
||||
# define EXTERNAL_EEPROM_SPI_TIMEOUT 100
|
||||
#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) {
|
||||
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) {
|
||||
#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("\n");
|
||||
#endif // DEBUG_EEPROM_OUTPUT
|
||||
#endif // DEBUG_EEPROM_OUTPUT
|
||||
|
||||
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("\n");
|
||||
#endif // DEBUG_EEPROM_OUTPUT
|
||||
#endif // DEBUG_EEPROM_OUTPUT
|
||||
|
||||
spi_write(CMD_WRITE);
|
||||
spi_eeprom_transmit_address(target_addr);
|
||||
|
||||
@@ -30,9 +30,13 @@ size_t clamp_length(intptr_t offset, size_t 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) {
|
||||
intptr_t offset = (intptr_t)addr;
|
||||
|
||||
@@ -21,5 +21,5 @@
|
||||
*/
|
||||
#ifndef TRANSIENT_EEPROM_SIZE
|
||||
# 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
|
||||
|
||||
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
|
||||
108
drivers/gpio/mcp23018.c
Normal file
108
drivers/gpio/mcp23018.c
Normal file
@@ -0,0 +1,108 @@
|
||||
// Copyright 2022 zvecr<git@zvecr.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "mcp23018.h"
|
||||
#include "i2c_master.h"
|
||||
#include "wait.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define SLAVE_TO_ADDR(n) (n << 1)
|
||||
#define TIMEOUT 100
|
||||
|
||||
enum {
|
||||
CMD_IODIRA = 0x00, // i/o direction register
|
||||
CMD_IODIRB = 0x01,
|
||||
CMD_GPPUA = 0x0C, // GPIO pull-up resistor register
|
||||
CMD_GPPUB = 0x0D,
|
||||
CMD_GPIOA = 0x12, // general purpose i/o port register (write modifies OLAT)
|
||||
CMD_GPIOB = 0x13,
|
||||
};
|
||||
|
||||
void mcp23018_init(uint8_t addr) {
|
||||
static uint8_t s_init = 0;
|
||||
if (!s_init) {
|
||||
i2c_init();
|
||||
wait_ms(1000);
|
||||
|
||||
s_init = 1;
|
||||
}
|
||||
}
|
||||
|
||||
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 cmdDirection = port ? CMD_IODIRB : CMD_IODIRA;
|
||||
uint8_t cmdPullup = port ? CMD_GPPUB : CMD_GPPUA;
|
||||
|
||||
i2c_status_t ret = i2c_writeReg(addr, cmdDirection, &conf, sizeof(conf), TIMEOUT);
|
||||
if (ret != I2C_STATUS_SUCCESS) {
|
||||
dprintf("mcp23018_set_config::directionFAILED::%u\n", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = i2c_writeReg(addr, cmdPullup, &conf, sizeof(conf), TIMEOUT);
|
||||
if (ret != I2C_STATUS_SUCCESS) {
|
||||
dprintf("mcp23018_set_config::pullupFAILED::%u\n", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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 cmd = port ? CMD_GPIOB : CMD_GPIOA;
|
||||
|
||||
i2c_status_t ret = i2c_writeReg(addr, cmd, &conf, sizeof(conf), TIMEOUT);
|
||||
if (ret != I2C_STATUS_SUCCESS) {
|
||||
dprintf("mcp23018_set_output::FAILED::%u\n", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mcp23018_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_GPIOA, &conf[0], sizeof(conf), TIMEOUT);
|
||||
if (ret != I2C_STATUS_SUCCESS) {
|
||||
dprintf("mcp23018_set_output::FAILED::%u\n", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mcp23018_readPins(uint8_t slave_addr, mcp23018_port_t port, uint8_t* out) {
|
||||
uint8_t addr = SLAVE_TO_ADDR(slave_addr);
|
||||
uint8_t cmd = port ? CMD_GPIOB : CMD_GPIOA;
|
||||
|
||||
i2c_status_t ret = i2c_readReg(addr, cmd, out, sizeof(uint8_t), TIMEOUT);
|
||||
if (ret != I2C_STATUS_SUCCESS) {
|
||||
dprintf("mcp23018_readPins::FAILED::%u\n", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mcp23018_readPins_all(uint8_t slave_addr, uint16_t* out) {
|
||||
uint8_t addr = SLAVE_TO_ADDR(slave_addr);
|
||||
|
||||
typedef union {
|
||||
uint8_t u8[2];
|
||||
uint16_t u16;
|
||||
} data16;
|
||||
|
||||
data16 data = {.u16 = 0};
|
||||
|
||||
i2c_status_t ret = i2c_readReg(addr, CMD_GPIOA, &data.u8[0], sizeof(data), TIMEOUT);
|
||||
if (ret != I2C_STATUS_SUCCESS) {
|
||||
dprintf("mcp23018_readPins::FAILED::%u\n", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
*out = data.u16;
|
||||
return true;
|
||||
}
|
||||
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
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General 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/>.
|
||||
*/
|
||||
// Copyright 2020 zvecr<git@zvecr.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "i2c_master.h"
|
||||
#include "pca9555.h"
|
||||
|
||||
@@ -45,39 +33,59 @@ void pca9555_init(uint8_t slave_addr) {
|
||||
// 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 cmd = port ? CMD_CONFIG_1 : CMD_CONFIG_0;
|
||||
|
||||
i2c_status_t ret = i2c_writeReg(addr, cmd, &conf, sizeof(conf), TIMEOUT);
|
||||
if (ret != I2C_STATUS_SUCCESS) {
|
||||
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 cmd = port ? CMD_OUTPUT_1 : CMD_OUTPUT_0;
|
||||
|
||||
i2c_status_t ret = i2c_writeReg(addr, cmd, &conf, sizeof(conf), TIMEOUT);
|
||||
if (ret != I2C_STATUS_SUCCESS) {
|
||||
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 cmd = port ? CMD_INPUT_1 : CMD_INPUT_0;
|
||||
|
||||
uint8_t data = 0;
|
||||
i2c_status_t ret = i2c_readReg(addr, cmd, &data, sizeof(data), TIMEOUT);
|
||||
i2c_status_t ret = i2c_readReg(addr, cmd, out, sizeof(uint8_t), TIMEOUT);
|
||||
if (ret != I2C_STATUS_SUCCESS) {
|
||||
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);
|
||||
|
||||
typedef union {
|
||||
@@ -85,11 +93,14 @@ uint16_t pca9555_readAllPins(uint8_t slave_addr) {
|
||||
uint16_t u16;
|
||||
} data16;
|
||||
|
||||
data16 data;
|
||||
data16 data = {.u16 = 0};
|
||||
|
||||
i2c_status_t ret = i2c_readReg(addr, CMD_INPUT_0, &data.u8[0], sizeof(data), TIMEOUT);
|
||||
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
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General 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/>.
|
||||
*/
|
||||
// Copyright 2020 zvecr<git@zvecr.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/*
|
||||
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
|
||||
#define ALL_LOW 0
|
||||
#define ALL_HIGH 0xFF
|
||||
/**
|
||||
* 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 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) {
|
||||
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_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) {
|
||||
DRV_write(DRV_GO, 0x00);
|
||||
|
||||
@@ -28,13 +28,21 @@ uint8_t solenoid_dwell = SOLENOID_DEFAULT_DWELL;
|
||||
|
||||
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) {
|
||||
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
|
||||
#define PAM_SETCOLUMN_LSB 0x00
|
||||
#define PAM_SETCOLUMN_MSB 0x10
|
||||
#define PAM_PAGE_ADDR 0xB0 // 0xb0 -- 0xb7
|
||||
#define PAM_PAGE_ADDR 0xB0 // 0xb0 -- 0xb7
|
||||
|
||||
// Hardware Configuration Commands
|
||||
#define DISPLAY_START_LINE 0x40
|
||||
@@ -138,7 +138,9 @@ bool st7565_init(display_rotation_t rotation) {
|
||||
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) {
|
||||
memset(st7565_buffer, 0, sizeof(st7565_buffer));
|
||||
@@ -212,7 +214,8 @@ void st7565_advance_page(bool clearPageRemainder) {
|
||||
remaining = remaining / ST7565_FONT_WIDTH;
|
||||
|
||||
// Write empty character until next line
|
||||
while (remaining--) st7565_write_char(' ', false);
|
||||
while (remaining--)
|
||||
st7565_write_char(' ', false);
|
||||
} else {
|
||||
// Next page index out of bounds?
|
||||
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");
|
||||
|
||||
// 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) {
|
||||
memset(st7565_cursor, 0x00, ST7565_FONT_WIDTH);
|
||||
} 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));
|
||||
}
|
||||
}
|
||||
#endif // defined(__AVR__)
|
||||
#endif // defined(__AVR__)
|
||||
|
||||
bool st7565_on(void) {
|
||||
if (!st7565_initialized) {
|
||||
@@ -429,7 +432,9 @@ bool st7565_off(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) {
|
||||
if (!st7565_initialized) {
|
||||
@@ -445,9 +450,13 @@ bool st7565_invert(bool invert) {
|
||||
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) {
|
||||
if (!st7565_initialized) {
|
||||
|
||||
@@ -29,16 +29,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# define ST7565_DISPLAY_HEIGHT 32
|
||||
#endif
|
||||
#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
|
||||
#ifndef ST7565_BLOCK_TYPE
|
||||
# define ST7565_BLOCK_TYPE uint16_t
|
||||
#endif
|
||||
#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
|
||||
#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
|
||||
|
||||
// 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_ln_P(data, invert) st7565_write_ln(data, invert)
|
||||
# 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
|
||||
// Returns true if the screen was on or turns on
|
||||
|
||||
@@ -20,15 +20,15 @@
|
||||
|
||||
#ifndef APA102_NOPS
|
||||
# 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)
|
||||
|
||||
# include "hal.h"
|
||||
# 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
|
||||
# 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
|
||||
@@ -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
|
||||
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) {
|
||||
setPinOutput(RGB_DI_PIN);
|
||||
|
||||
@@ -23,17 +23,17 @@
|
||||
*/
|
||||
#define AWINIC_ID 0b1010 << 4
|
||||
|
||||
#define AW_PAGE_FUNCTION 0x00 << 1 // PG0, Function registers
|
||||
#define AW_PAGE_PWM 0x01 << 1 // PG1, LED PWM control
|
||||
#define AW_PAGE_SCALING 0x02 << 1 // PG2, LED current scaling control
|
||||
#define AW_PAGE_PATCHOICE 0x03 << 1 // PG3, Pattern choice?
|
||||
#define AW_PAGE_PWMSCALING 0x04 << 1 // PG4, LED PWM + Scaling control?
|
||||
#define AW_PAGE_FUNCTION 0x00 << 1 // PG0, Function registers
|
||||
#define AW_PAGE_PWM 0x01 << 1 // PG1, LED PWM control
|
||||
#define AW_PAGE_SCALING 0x02 << 1 // PG2, LED current scaling control
|
||||
#define AW_PAGE_PATCHOICE 0x03 << 1 // PG3, Pattern choice?
|
||||
#define AW_PAGE_PWMSCALING 0x04 << 1 // PG4, LED PWM + Scaling control?
|
||||
|
||||
#define AW_WRITE 0
|
||||
#define AW_READ 1
|
||||
|
||||
#define AW_REG_CONFIGURATION 0x00 // PG0
|
||||
#define AW_REG_GLOBALCURRENT 0x01 // PG0
|
||||
#define AW_REG_CONFIGURATION 0x00 // PG0
|
||||
#define AW_REG_GLOBALCURRENT 0x01 // PG0
|
||||
|
||||
// Default value of AW_REG_CONFIGURATION
|
||||
// D7:D4 = 1011, SWSEL (SW1~SW12 active)
|
||||
|
||||
@@ -125,7 +125,16 @@ void CKLED2001_init(uint8_t addr) {
|
||||
// Set CURRENT PAGE (Page 4)
|
||||
CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, CURRENT_TUNE_PAGE);
|
||||
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
|
||||
|
||||
@@ -42,13 +42,13 @@
|
||||
#define ISSI_REG_PICTUREFRAME 0x01
|
||||
|
||||
// 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_AUDIOSYNC 0x06
|
||||
|
||||
#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
|
||||
# define ISSI_TIMEOUT 100
|
||||
@@ -148,7 +148,7 @@ void IS31FL3731_init(uint8_t addr) {
|
||||
|
||||
// enable software shutdown
|
||||
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);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -41,13 +41,13 @@
|
||||
#define ISSI_REG_PICTUREFRAME 0x01
|
||||
|
||||
// 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_AUDIOSYNC 0x06
|
||||
|
||||
#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
|
||||
# define ISSI_TIMEOUT 100
|
||||
@@ -136,7 +136,7 @@ void IS31FL3731_init(uint8_t addr) {
|
||||
|
||||
// enable software shutdown
|
||||
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);
|
||||
#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_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_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
|
||||
#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
|
||||
@@ -58,7 +58,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef ISSI_PWM_FREQUENCY
|
||||
# define ISSI_PWM_FREQUENCY 0b000 // PFS - IS31FL3733B only
|
||||
# define ISSI_PWM_FREQUENCY 0b000 // PFS - IS31FL3733B only
|
||||
#endif
|
||||
|
||||
#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_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 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
|
||||
|
||||
@@ -36,16 +36,16 @@
|
||||
#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_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
|
||||
#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
|
||||
|
||||
@@ -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_led_control_registers(uint8_t addr1, uint8_t addr2);
|
||||
|
||||
#define PUR_0R 0x00 // No PUR resistor
|
||||
#define PUR_05KR 0x01 // 0.5k Ohm resistor
|
||||
#define PUR_1KR 0x02 // 1.0k Ohm resistor
|
||||
#define PUR_2KR 0x03 // 2.0k Ohm resistor
|
||||
#define PUR_4KR 0x04 // 4.0k Ohm resistor
|
||||
#define PUR_8KR 0x05 // 8.0k Ohm resistor
|
||||
#define PUR_16KR 0x06 // 16k Ohm resistor
|
||||
#define PUR_32KR 0x07 // 32k Ohm resistor
|
||||
#define PUR_0R 0x00 // No PUR resistor
|
||||
#define PUR_05KR 0x01 // 0.5k Ohm resistor
|
||||
#define PUR_1KR 0x02 // 1.0k Ohm resistor
|
||||
#define PUR_2KR 0x03 // 2.0k Ohm resistor
|
||||
#define PUR_4KR 0x04 // 4.0k Ohm resistor
|
||||
#define PUR_8KR 0x05 // 8.0k Ohm resistor
|
||||
#define PUR_16KR 0x06 // 16k Ohm resistor
|
||||
#define PUR_32KR 0x07 // 32k Ohm resistor
|
||||
|
||||
#define A_1 0x00
|
||||
#define A_2 0x02
|
||||
|
||||
@@ -38,16 +38,16 @@
|
||||
#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_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
|
||||
#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
|
||||
|
||||
@@ -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_led_control_registers(uint8_t addr1, uint8_t addr2);
|
||||
|
||||
#define PUR_0R 0x00 // No PUR resistor
|
||||
#define PUR_05KR 0x01 // 0.5k 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_4KR 0x04 // 4.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_32KR 0x07 // 32k Ohm resistor in t_NOL
|
||||
#define PUR_0R 0x00 // No PUR resistor
|
||||
#define PUR_05KR 0x01 // 0.5k 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_4KR 0x04 // 4.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_32KR 0x07 // 32k Ohm resistor in t_NOL
|
||||
|
||||
#define A_1 0x00
|
||||
#define A_2 0x01
|
||||
|
||||
@@ -42,16 +42,16 @@
|
||||
#define ISSI_INTERRUPTSTATUSREGISTER 0xF1
|
||||
#define ISSI_IDREGISTER 0xFC
|
||||
|
||||
#define ISSI_PAGE_PWM0 0x00 // PG0
|
||||
#define ISSI_PAGE_PWM1 0x01 // PG1
|
||||
#define ISSI_PAGE_SCALING_0 0x02 // PG2
|
||||
#define ISSI_PAGE_SCALING_1 0x03 // PG3
|
||||
#define ISSI_PAGE_FUNCTION 0x04 // PG4
|
||||
#define ISSI_PAGE_PWM0 0x00 // PG0
|
||||
#define ISSI_PAGE_PWM1 0x01 // PG1
|
||||
#define ISSI_PAGE_SCALING_0 0x02 // PG2
|
||||
#define ISSI_PAGE_SCALING_1 0x03 // PG3
|
||||
#define ISSI_PAGE_FUNCTION 0x04 // PG4
|
||||
|
||||
#define ISSI_REG_CONFIGURATION 0x00 // PG4
|
||||
#define ISSI_REG_GLOBALCURRENT 0x01 // PG4
|
||||
#define ISSI_REG_PULLDOWNUP 0x02 // PG4
|
||||
#define ISSI_REG_RESET 0x3F // PG4
|
||||
#define ISSI_REG_CONFIGURATION 0x00 // PG4
|
||||
#define ISSI_REG_GLOBALCURRENT 0x01 // PG4
|
||||
#define ISSI_REG_PULLDOWNUP 0x02 // PG4
|
||||
#define ISSI_REG_RESET 0x3F // PG4
|
||||
|
||||
#ifndef ISSI_TIMEOUT
|
||||
# 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);
|
||||
|
||||
#define PUR_0R 0x00 // No PUR resistor
|
||||
#define PUR_05KR 0x01 // 0.5k Ohm resistor
|
||||
#define PUR_1KR 0x02 // 1.0k Ohm resistor
|
||||
#define PUR_2KR 0x03 // 2.0k Ohm resistor
|
||||
#define PUR_4KR 0x04 // 4.0k Ohm resistor
|
||||
#define PUR_8KR 0x05 // 8.0k Ohm resistor
|
||||
#define PUR_16KR 0x06 // 16k Ohm resistor
|
||||
#define PUR_32KR 0x07 // 32k Ohm resistor
|
||||
#define PUR_0R 0x00 // No PUR resistor
|
||||
#define PUR_05KR 0x01 // 0.5k Ohm resistor
|
||||
#define PUR_1KR 0x02 // 1.0k Ohm resistor
|
||||
#define PUR_2KR 0x03 // 2.0k Ohm resistor
|
||||
#define PUR_4KR 0x04 // 4.0k Ohm resistor
|
||||
#define PUR_8KR 0x05 // 8.0k Ohm resistor
|
||||
#define PUR_16KR 0x06 // 16k Ohm resistor
|
||||
#define PUR_32KR 0x07 // 32k Ohm resistor
|
||||
|
||||
#define CS1_SW1 0x00
|
||||
#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
|
||||
327
drivers/led/issi/is31fl3743.h
Normal file
327
drivers/led/issi/is31fl3743.h
Normal file
@@ -0,0 +1,327 @@
|
||||
/* 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
|
||||
// ADDR1 represents A1:A0 of the 7-bit address.
|
||||
// ADDR2 represents A3:A2 of the 7-bit address.
|
||||
// The result is: 0b010(ADDR2)(ADDR1)
|
||||
#ifndef DRIVER_ADDR_1
|
||||
# define DRIVER_ADDR_1 0b0100000
|
||||
#endif
|
||||
|
||||
// Set defaults for Spread Spectrum Register
|
||||
#ifndef ISSI_SSR_1
|
||||
# if DRIVER_COUNT == 1
|
||||
# define ISSI_SSR_1 0x00
|
||||
# else
|
||||
# define ISSI_SSR_1 0xC0
|
||||
# endif
|
||||
#endif
|
||||
#ifndef ISSI_SSR_2
|
||||
# define ISSI_SSR_2 0x80
|
||||
#endif
|
||||
#ifndef ISSI_SSR_3
|
||||
# define ISSI_SSR_3 0x80
|
||||
#endif
|
||||
#ifndef ISSI_SSR_4
|
||||
# define ISSI_SSR_4 0x80
|
||||
#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 0x01
|
||||
#define ISSI_PAGE_FUNCTION 0x02
|
||||
|
||||
// Registers under Function Register
|
||||
#define ISSI_REG_CONFIGURATION 0x00
|
||||
#define ISSI_REG_GLOBALCURRENT 0x01
|
||||
#define ISSI_REG_PULLDOWNUP 0x02
|
||||
#define ISSI_REG_TEMP 0x24
|
||||
#define ISSI_REG_SSR 0x25
|
||||
#define ISSI_REG_RESET 0x2F
|
||||
|
||||
// Set defaults for Function Registers
|
||||
#ifndef ISSI_CONFIGURATION
|
||||
# define ISSI_CONFIGURATION 0x01
|
||||
#endif
|
||||
#ifndef ISSI_GLOBALCURRENT
|
||||
# define ISSI_GLOBALCURRENT 0xFF
|
||||
#endif
|
||||
#ifndef ISSI_PULLDOWNUP
|
||||
# define ISSI_PULLDOWNUP 0x33
|
||||
#endif
|
||||
#ifndef ISSI_TEMP
|
||||
# define ISSI_TEMP 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 198
|
||||
#define ISSI_SCALING_SIZE 198
|
||||
#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 0x01
|
||||
#define ISSI_SCL_REG_1ST 0x01
|
||||
|
||||
// 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 CS1_SW2 0x12
|
||||
#define CS2_SW2 0x13
|
||||
#define CS3_SW2 0x14
|
||||
#define CS4_SW2 0x15
|
||||
#define CS5_SW2 0x16
|
||||
#define CS6_SW2 0x17
|
||||
#define CS7_SW2 0x18
|
||||
#define CS8_SW2 0x19
|
||||
#define CS9_SW2 0x1A
|
||||
#define CS10_SW2 0x1B
|
||||
#define CS11_SW2 0x1C
|
||||
#define CS12_SW2 0x1D
|
||||
#define CS13_SW2 0x1E
|
||||
#define CS14_SW2 0x1F
|
||||
#define CS15_SW2 0x20
|
||||
#define CS16_SW2 0x21
|
||||
#define CS17_SW2 0x22
|
||||
#define CS18_SW2 0x23
|
||||
|
||||
#define CS1_SW3 0x24
|
||||
#define CS2_SW3 0x25
|
||||
#define CS3_SW3 0x26
|
||||
#define CS4_SW3 0x27
|
||||
#define CS5_SW3 0x28
|
||||
#define CS6_SW3 0x29
|
||||
#define CS7_SW3 0x2A
|
||||
#define CS8_SW3 0x2B
|
||||
#define CS9_SW3 0x2C
|
||||
#define CS10_SW3 0x2D
|
||||
#define CS11_SW3 0x2E
|
||||
#define CS12_SW3 0x2F
|
||||
#define CS13_SW3 0x30
|
||||
#define CS14_SW3 0x31
|
||||
#define CS15_SW3 0x32
|
||||
#define CS16_SW3 0x33
|
||||
#define CS17_SW3 0x34
|
||||
#define CS18_SW3 0x35
|
||||
|
||||
#define CS1_SW4 0x36
|
||||
#define CS2_SW4 0x37
|
||||
#define CS3_SW4 0x38
|
||||
#define CS4_SW4 0x39
|
||||
#define CS5_SW4 0x3A
|
||||
#define CS6_SW4 0x3B
|
||||
#define CS7_SW4 0x3C
|
||||
#define CS8_SW4 0x3D
|
||||
#define CS9_SW4 0x3E
|
||||
#define CS10_SW4 0x3F
|
||||
#define CS11_SW4 0x40
|
||||
#define CS12_SW4 0x41
|
||||
#define CS13_SW4 0x42
|
||||
#define CS14_SW4 0x43
|
||||
#define CS15_SW4 0x44
|
||||
#define CS16_SW4 0x45
|
||||
#define CS17_SW4 0x46
|
||||
#define CS18_SW4 0x47
|
||||
|
||||
#define CS1_SW5 0x48
|
||||
#define CS2_SW5 0x49
|
||||
#define CS3_SW5 0x4A
|
||||
#define CS4_SW5 0x4B
|
||||
#define CS5_SW5 0x4C
|
||||
#define CS6_SW5 0x4D
|
||||
#define CS7_SW5 0x4E
|
||||
#define CS8_SW5 0x4F
|
||||
#define CS9_SW5 0x50
|
||||
#define CS10_SW5 0x51
|
||||
#define CS11_SW5 0x52
|
||||
#define CS12_SW5 0x53
|
||||
#define CS13_SW5 0x54
|
||||
#define CS14_SW5 0x55
|
||||
#define CS15_SW5 0x56
|
||||
#define CS16_SW5 0x57
|
||||
#define CS17_SW5 0x58
|
||||
#define CS18_SW5 0x59
|
||||
|
||||
#define CS1_SW6 0x5A
|
||||
#define CS2_SW6 0x5B
|
||||
#define CS3_SW6 0x5C
|
||||
#define CS4_SW6 0x5D
|
||||
#define CS5_SW6 0x5E
|
||||
#define CS6_SW6 0x5F
|
||||
#define CS7_SW6 0x60
|
||||
#define CS8_SW6 0x61
|
||||
#define CS9_SW6 0x62
|
||||
#define CS10_SW6 0x63
|
||||
#define CS11_SW6 0x64
|
||||
#define CS12_SW6 0x65
|
||||
#define CS13_SW6 0x66
|
||||
#define CS14_SW6 0x67
|
||||
#define CS15_SW6 0x68
|
||||
#define CS16_SW6 0x69
|
||||
#define CS17_SW6 0x6A
|
||||
#define CS18_SW6 0x6B
|
||||
|
||||
#define CS1_SW7 0x6C
|
||||
#define CS2_SW7 0x6D
|
||||
#define CS3_SW7 0x6E
|
||||
#define CS4_SW7 0x6F
|
||||
#define CS5_SW7 0x70
|
||||
#define CS6_SW7 0x71
|
||||
#define CS7_SW7 0x72
|
||||
#define CS8_SW7 0x73
|
||||
#define CS9_SW7 0x74
|
||||
#define CS10_SW7 0x75
|
||||
#define CS11_SW7 0x76
|
||||
#define CS12_SW7 0x77
|
||||
#define CS13_SW7 0x78
|
||||
#define CS14_SW7 0x79
|
||||
#define CS15_SW7 0x7A
|
||||
#define CS16_SW7 0x7B
|
||||
#define CS17_SW7 0x7C
|
||||
#define CS18_SW7 0x7D
|
||||
|
||||
#define CS1_SW8 0x7E
|
||||
#define CS2_SW8 0x7F
|
||||
#define CS3_SW8 0x80
|
||||
#define CS4_SW8 0x81
|
||||
#define CS5_SW8 0x82
|
||||
#define CS6_SW8 0x83
|
||||
#define CS7_SW8 0x84
|
||||
#define CS8_SW8 0x85
|
||||
#define CS9_SW8 0x86
|
||||
#define CS10_SW8 0x87
|
||||
#define CS11_SW8 0x88
|
||||
#define CS12_SW8 0x89
|
||||
#define CS13_SW8 0x8A
|
||||
#define CS14_SW8 0x8B
|
||||
#define CS15_SW8 0x8C
|
||||
#define CS16_SW8 0x8D
|
||||
#define CS17_SW8 0x8E
|
||||
#define CS18_SW8 0x8F
|
||||
|
||||
#define CS1_SW9 0x90
|
||||
#define CS2_SW9 0x91
|
||||
#define CS3_SW9 0x92
|
||||
#define CS4_SW9 0x93
|
||||
#define CS5_SW9 0x94
|
||||
#define CS6_SW9 0x95
|
||||
#define CS7_SW9 0x96
|
||||
#define CS8_SW9 0x97
|
||||
#define CS9_SW9 0x98
|
||||
#define CS10_SW9 0x99
|
||||
#define CS11_SW9 0x9A
|
||||
#define CS12_SW9 0x9B
|
||||
#define CS13_SW9 0x9C
|
||||
#define CS14_SW9 0x9D
|
||||
#define CS15_SW9 0x9E
|
||||
#define CS16_SW9 0x9F
|
||||
#define CS17_SW9 0xA0
|
||||
#define CS18_SW9 0xA1
|
||||
|
||||
#define CS1_SW10 0xA2
|
||||
#define CS2_SW10 0xA3
|
||||
#define CS3_SW10 0xA4
|
||||
#define CS4_SW10 0xA5
|
||||
#define CS5_SW10 0xA6
|
||||
#define CS6_SW10 0xA7
|
||||
#define CS7_SW10 0xA8
|
||||
#define CS8_SW10 0xA9
|
||||
#define CS9_SW10 0xAA
|
||||
#define CS10_SW10 0xAB
|
||||
#define CS11_SW10 0xAC
|
||||
#define CS12_SW10 0xAD
|
||||
#define CS13_SW10 0xAE
|
||||
#define CS14_SW10 0xAF
|
||||
#define CS15_SW10 0xB0
|
||||
#define CS16_SW10 0xB1
|
||||
#define CS17_SW10 0xB2
|
||||
#define CS18_SW10 0xB3
|
||||
|
||||
#define CS1_SW11 0xB4
|
||||
#define CS2_SW11 0xB5
|
||||
#define CS3_SW11 0xB6
|
||||
#define CS4_SW11 0xB7
|
||||
#define CS5_SW11 0xB8
|
||||
#define CS6_SW11 0xB9
|
||||
#define CS7_SW11 0xBA
|
||||
#define CS8_SW11 0xBB
|
||||
#define CS9_SW11 0xBC
|
||||
#define CS10_SW11 0xBD
|
||||
#define CS11_SW11 0xBE
|
||||
#define CS12_SW11 0xBF
|
||||
#define CS13_SW11 0xC0
|
||||
#define CS14_SW11 0xC1
|
||||
#define CS15_SW11 0xC2
|
||||
#define CS16_SW11 0xC3
|
||||
#define CS17_SW11 0xC4
|
||||
#define CS18_SW11 0xC5
|
||||
270
drivers/led/issi/is31fl3745.h
Normal file
270
drivers/led/issi/is31fl3745.h
Normal file
@@ -0,0 +1,270 @@
|
||||
/* 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
|
||||
// ADDR1 represents A1:A0 of the 7-bit address.
|
||||
// ADDR2 represents A3:A2 of the 7-bit address.
|
||||
// The result is: 0b010(ADDR2)(ADDR1)
|
||||
#ifndef DRIVER_ADDR_1
|
||||
# define DRIVER_ADDR_1 0b0100000
|
||||
#endif
|
||||
|
||||
// Set defaults for Spread Spectrum Register
|
||||
#ifndef ISSI_SSR_1
|
||||
# if DRIVER_COUNT == 1
|
||||
# define ISSI_SSR_1 0x00
|
||||
# else
|
||||
# define ISSI_SSR_1 0xC0
|
||||
# endif
|
||||
#endif
|
||||
#ifndef ISSI_SSR_2
|
||||
# define ISSI_SSR_2 0x80
|
||||
#endif
|
||||
#ifndef ISSI_SSR_3
|
||||
# define ISSI_SSR_3 0x80
|
||||
#endif
|
||||
#ifndef ISSI_SSR_4
|
||||
# define ISSI_SSR_4 0x80
|
||||
#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 0x01
|
||||
#define ISSI_PAGE_FUNCTION 0x02
|
||||
|
||||
// Registers under Function Register
|
||||
#define ISSI_REG_CONFIGURATION 0x00
|
||||
#define ISSI_REG_GLOBALCURRENT 0x01
|
||||
#define ISSI_REG_PULLDOWNUP 0x02
|
||||
#define ISSI_REG_TEMP 0x24
|
||||
#define ISSI_REG_SSR 0x25
|
||||
#define ISSI_REG_RESET 0x2F
|
||||
|
||||
// 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 0x33
|
||||
#endif
|
||||
#ifndef ISSI_TEMP
|
||||
# define ISSI_TEMP 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 144
|
||||
#define ISSI_SCALING_SIZE 144
|
||||
#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 0x01
|
||||
#define ISSI_SCL_REG_1ST 0x01
|
||||
|
||||
// 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 CS1_SW2 0x12
|
||||
#define CS2_SW2 0x13
|
||||
#define CS3_SW2 0x14
|
||||
#define CS4_SW2 0x15
|
||||
#define CS5_SW2 0x16
|
||||
#define CS6_SW2 0x17
|
||||
#define CS7_SW2 0x18
|
||||
#define CS8_SW2 0x19
|
||||
#define CS9_SW2 0x1A
|
||||
#define CS10_SW2 0x1B
|
||||
#define CS11_SW2 0x1C
|
||||
#define CS12_SW2 0x1D
|
||||
#define CS13_SW2 0x1E
|
||||
#define CS14_SW2 0x1F
|
||||
#define CS15_SW2 0x20
|
||||
#define CS16_SW2 0x21
|
||||
#define CS17_SW2 0x22
|
||||
#define CS18_SW2 0x23
|
||||
|
||||
#define CS1_SW3 0x24
|
||||
#define CS2_SW3 0x25
|
||||
#define CS3_SW3 0x26
|
||||
#define CS4_SW3 0x27
|
||||
#define CS5_SW3 0x28
|
||||
#define CS6_SW3 0x29
|
||||
#define CS7_SW3 0x2A
|
||||
#define CS8_SW3 0x2B
|
||||
#define CS9_SW3 0x2C
|
||||
#define CS10_SW3 0x2D
|
||||
#define CS11_SW3 0x2E
|
||||
#define CS12_SW3 0x2F
|
||||
#define CS13_SW3 0x30
|
||||
#define CS14_SW3 0x31
|
||||
#define CS15_SW3 0x32
|
||||
#define CS16_SW3 0x33
|
||||
#define CS17_SW3 0x34
|
||||
#define CS18_SW3 0x35
|
||||
|
||||
#define CS1_SW4 0x36
|
||||
#define CS2_SW4 0x37
|
||||
#define CS3_SW4 0x38
|
||||
#define CS4_SW4 0x39
|
||||
#define CS5_SW4 0x3A
|
||||
#define CS6_SW4 0x3B
|
||||
#define CS7_SW4 0x3C
|
||||
#define CS8_SW4 0x3D
|
||||
#define CS9_SW4 0x3E
|
||||
#define CS10_SW4 0x3F
|
||||
#define CS11_SW4 0x40
|
||||
#define CS12_SW4 0x41
|
||||
#define CS13_SW4 0x42
|
||||
#define CS14_SW4 0x43
|
||||
#define CS15_SW4 0x44
|
||||
#define CS16_SW4 0x45
|
||||
#define CS17_SW4 0x46
|
||||
#define CS18_SW4 0x47
|
||||
|
||||
#define CS1_SW5 0x48
|
||||
#define CS2_SW5 0x49
|
||||
#define CS3_SW5 0x4A
|
||||
#define CS4_SW5 0x4B
|
||||
#define CS5_SW5 0x4C
|
||||
#define CS6_SW5 0x4D
|
||||
#define CS7_SW5 0x4E
|
||||
#define CS8_SW5 0x4F
|
||||
#define CS9_SW5 0x50
|
||||
#define CS10_SW5 0x51
|
||||
#define CS11_SW5 0x52
|
||||
#define CS12_SW5 0x53
|
||||
#define CS13_SW5 0x54
|
||||
#define CS14_SW5 0x55
|
||||
#define CS15_SW5 0x56
|
||||
#define CS16_SW5 0x57
|
||||
#define CS17_SW5 0x58
|
||||
#define CS18_SW5 0x59
|
||||
|
||||
#define CS1_SW6 0x5A
|
||||
#define CS2_SW6 0x5B
|
||||
#define CS3_SW6 0x5C
|
||||
#define CS4_SW6 0x5D
|
||||
#define CS5_SW6 0x5E
|
||||
#define CS6_SW6 0x5F
|
||||
#define CS7_SW6 0x60
|
||||
#define CS8_SW6 0x61
|
||||
#define CS9_SW6 0x62
|
||||
#define CS10_SW6 0x63
|
||||
#define CS11_SW6 0x64
|
||||
#define CS12_SW6 0x65
|
||||
#define CS13_SW6 0x66
|
||||
#define CS14_SW6 0x67
|
||||
#define CS15_SW6 0x68
|
||||
#define CS16_SW6 0x69
|
||||
#define CS17_SW6 0x6A
|
||||
#define CS18_SW6 0x6B
|
||||
|
||||
#define CS1_SW7 0x6C
|
||||
#define CS2_SW7 0x6D
|
||||
#define CS3_SW7 0x6E
|
||||
#define CS4_SW7 0x6F
|
||||
#define CS5_SW7 0x70
|
||||
#define CS6_SW7 0x71
|
||||
#define CS7_SW7 0x72
|
||||
#define CS8_SW7 0x73
|
||||
#define CS9_SW7 0x74
|
||||
#define CS10_SW7 0x75
|
||||
#define CS11_SW7 0x76
|
||||
#define CS12_SW7 0x77
|
||||
#define CS13_SW7 0x78
|
||||
#define CS14_SW7 0x79
|
||||
#define CS15_SW7 0x7A
|
||||
#define CS16_SW7 0x7B
|
||||
#define CS17_SW7 0x7C
|
||||
#define CS18_SW7 0x7D
|
||||
|
||||
#define CS1_SW8 0x7E
|
||||
#define CS2_SW8 0x7F
|
||||
#define CS3_SW8 0x80
|
||||
#define CS4_SW8 0x81
|
||||
#define CS5_SW8 0x82
|
||||
#define CS6_SW8 0x83
|
||||
#define CS7_SW8 0x84
|
||||
#define CS8_SW8 0x85
|
||||
#define CS9_SW8 0x86
|
||||
#define CS10_SW8 0x87
|
||||
#define CS11_SW8 0x88
|
||||
#define CS12_SW8 0x89
|
||||
#define CS13_SW8 0x8A
|
||||
#define CS14_SW8 0x8B
|
||||
#define CS15_SW8 0x8C
|
||||
#define CS16_SW8 0x8D
|
||||
#define CS17_SW8 0x8E
|
||||
#define CS18_SW8 0x8F
|
||||
198
drivers/led/issi/is31fl3746.h
Normal file
198
drivers/led/issi/is31fl3746.h
Normal file
@@ -0,0 +1,198 @@
|
||||
/* 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
|
||||
// ADDR1 represents A1:A0 of the 7-bit address.
|
||||
// ADDR2 represents A3:A2 of the 7-bit address.
|
||||
// The result is: 0b110(ADDR2)(ADDR1)
|
||||
#ifndef DRIVER_ADDR_1
|
||||
# define DRIVER_ADDR_1 0b1100000
|
||||
#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
|
||||
|
||||
// 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 0x01
|
||||
#define ISSI_PAGE_FUNCTION 0x01
|
||||
|
||||
// Registers under Function Register
|
||||
#define ISSI_REG_CONFIGURATION 0x50
|
||||
#define ISSI_REG_GLOBALCURRENT 0x51
|
||||
#define ISSI_REG_PULLDOWNUP 0x52
|
||||
#define ISSI_REG_TEMP 0x5F
|
||||
#define ISSI_REG_SSR 0x60
|
||||
#define ISSI_REG_RESET 0x8F
|
||||
#define ISSI_REG_PWM_ENABLE 0xE0
|
||||
#define ISSI_REG_PWM_SET 0xE2
|
||||
|
||||
// Set defaults for Function Registers
|
||||
#ifndef ISSI_CONFIGURATION
|
||||
# define ISSI_CONFIGURATION 0x01
|
||||
#endif
|
||||
#ifndef ISSI_GLOBALCURRENT
|
||||
# define ISSI_GLOBALCURRENT 0xFF
|
||||
#endif
|
||||
#ifndef ISSI_PULLDOWNUP
|
||||
# define ISSI_PULLDOWNUP 0x33
|
||||
#endif
|
||||
#ifndef ISSI_TEMP
|
||||
# define ISSI_TEMP 0x00
|
||||
#endif
|
||||
#ifndef ISSI_PWM_ENABLE
|
||||
# define ISSI_PWM_ENABLE 0x00
|
||||
#endif
|
||||
#ifndef ISSI_PWM_SET
|
||||
# define ISSI_PWM_SET 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 72
|
||||
#define ISSI_SCALING_SIZE 72
|
||||
#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 0x01
|
||||
#define ISSI_SCL_REG_1ST 0x01
|
||||
|
||||
// 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 CS1_SW2 0x12
|
||||
#define CS2_SW2 0x13
|
||||
#define CS3_SW2 0x14
|
||||
#define CS4_SW2 0x15
|
||||
#define CS5_SW2 0x16
|
||||
#define CS6_SW2 0x17
|
||||
#define CS7_SW2 0x18
|
||||
#define CS8_SW2 0x19
|
||||
#define CS9_SW2 0x1A
|
||||
#define CS10_SW2 0x1B
|
||||
#define CS11_SW2 0x1C
|
||||
#define CS12_SW2 0x1D
|
||||
#define CS13_SW2 0x1E
|
||||
#define CS14_SW2 0x1F
|
||||
#define CS15_SW2 0x20
|
||||
#define CS16_SW2 0x21
|
||||
#define CS17_SW2 0x22
|
||||
#define CS18_SW2 0x23
|
||||
|
||||
#define CS1_SW3 0x24
|
||||
#define CS2_SW3 0x25
|
||||
#define CS3_SW3 0x26
|
||||
#define CS4_SW3 0x27
|
||||
#define CS5_SW3 0x28
|
||||
#define CS6_SW3 0x29
|
||||
#define CS7_SW3 0x2A
|
||||
#define CS8_SW3 0x2B
|
||||
#define CS9_SW3 0x2C
|
||||
#define CS10_SW3 0x2D
|
||||
#define CS11_SW3 0x2E
|
||||
#define CS12_SW3 0x2F
|
||||
#define CS13_SW3 0x30
|
||||
#define CS14_SW3 0x31
|
||||
#define CS15_SW3 0x32
|
||||
#define CS16_SW3 0x33
|
||||
#define CS17_SW3 0x34
|
||||
#define CS18_SW3 0x35
|
||||
|
||||
#define CS1_SW4 0x36
|
||||
#define CS2_SW4 0x37
|
||||
#define CS3_SW4 0x38
|
||||
#define CS4_SW4 0x39
|
||||
#define CS5_SW4 0x3A
|
||||
#define CS6_SW4 0x3B
|
||||
#define CS7_SW4 0x3C
|
||||
#define CS8_SW4 0x3D
|
||||
#define CS9_SW4 0x3E
|
||||
#define CS10_SW4 0x3F
|
||||
#define CS11_SW4 0x40
|
||||
#define CS12_SW4 0x41
|
||||
#define CS13_SW4 0x42
|
||||
#define CS14_SW4 0x43
|
||||
#define CS15_SW4 0x44
|
||||
#define CS16_SW4 0x45
|
||||
#define CS17_SW4 0x46
|
||||
#define CS18_SW4 0x47
|
||||
230
drivers/led/issi/is31flcommon.c
Normal file
230
drivers/led/issi/is31flcommon.c
Normal file
@@ -0,0 +1,230 @@
|
||||
/* 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/>.
|
||||
*/
|
||||
|
||||
#include "is31flcommon.h"
|
||||
#include "i2c_master.h"
|
||||
#include "wait.h"
|
||||
#include <string.h>
|
||||
|
||||
// Set defaults for Timeout and Persistence
|
||||
#ifndef ISSI_TIMEOUT
|
||||
# define ISSI_TIMEOUT 100
|
||||
#endif
|
||||
#ifndef ISSI_PERSISTENCE
|
||||
# define ISSI_PERSISTENCE 0
|
||||
#endif
|
||||
|
||||
// Transfer buffer for TWITransmitData()
|
||||
uint8_t g_twi_transfer_buffer[20];
|
||||
|
||||
// These buffers match the PWM & scaling registers.
|
||||
// Storing them like this is optimal for I2C transfers to the registers.
|
||||
uint8_t g_pwm_buffer[DRIVER_COUNT][ISSI_MAX_LEDS];
|
||||
bool g_pwm_buffer_update_required[DRIVER_COUNT] = {false};
|
||||
|
||||
uint8_t g_scaling_buffer[DRIVER_COUNT][ISSI_SCALING_SIZE];
|
||||
bool g_scaling_buffer_update_required[DRIVER_COUNT] = {false};
|
||||
|
||||
// For writing of single register entry
|
||||
void IS31FL_write_single_register(uint8_t addr, uint8_t reg, uint8_t data) {
|
||||
// Set register address and register data ready to write
|
||||
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) break;
|
||||
}
|
||||
#else
|
||||
i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT);
|
||||
#endif
|
||||
}
|
||||
|
||||
// For writing of mulitple register entries to make use of address auto increment
|
||||
// Once the controller has been called and we have written the first bit of data
|
||||
// the controller will move to the next register meaning we can write sequential blocks.
|
||||
bool IS31FL_write_multi_registers(uint8_t addr, uint8_t *source_buffer, uint8_t buffer_size, uint8_t transfer_size, uint8_t start_reg_addr) {
|
||||
// Split the buffer into chunks to transfer
|
||||
for (int i = 0; i < buffer_size; i += transfer_size) {
|
||||
// Set the first entry of transfer buffer to the first register we want to write
|
||||
g_twi_transfer_buffer[0] = i + start_reg_addr;
|
||||
// Copy the section of our source buffer into the transfer buffer after first register address
|
||||
memcpy(g_twi_transfer_buffer + 1, source_buffer + i, transfer_size);
|
||||
|
||||
#if ISSI_PERSISTENCE > 0
|
||||
for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) {
|
||||
if (i2c_transmit(addr << 1, g_twi_transfer_buffer, transfer_size + 1, ISSI_TIMEOUT) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (i2c_transmit(addr << 1, g_twi_transfer_buffer, transfer_size + 1, ISSI_TIMEOUT) != 0) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void IS31FL_unlock_register(uint8_t addr, uint8_t page) {
|
||||
// unlock the command register and select Page to write
|
||||
IS31FL_write_single_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, ISSI_REGISTER_UNLOCK);
|
||||
IS31FL_write_single_register(addr, ISSI_COMMANDREGISTER, page);
|
||||
}
|
||||
|
||||
void IS31FL_common_init(uint8_t addr, uint8_t ssr) {
|
||||
// Setup phase, need to take out of software shutdown and configure
|
||||
// ISSI_SSR_x is passed to allow Master / Slave setting where applicable
|
||||
|
||||
// Unlock the command register & select Function Register
|
||||
IS31FL_unlock_register(addr, ISSI_PAGE_FUNCTION);
|
||||
// Set Configuration Register to remove Software shutdown
|
||||
IS31FL_write_single_register(addr, ISSI_REG_CONFIGURATION, ISSI_CONFIGURATION);
|
||||
// Set Golbal Current Control Register
|
||||
IS31FL_write_single_register(addr, ISSI_REG_GLOBALCURRENT, ISSI_GLOBALCURRENT);
|
||||
// Set Pull up & Down for SWx CSy
|
||||
IS31FL_write_single_register(addr, ISSI_REG_PULLDOWNUP, ISSI_PULLDOWNUP);
|
||||
// Set Tempature Status
|
||||
#ifdef ISSI_REG_TEMP
|
||||
IS31FL_write_single_register(addr, ISSI_REG_TEMP, ISSI_TEMP);
|
||||
#endif
|
||||
// Set Spread Spectrum Register, passed through as sets SYNC function
|
||||
IS31FL_write_single_register(addr, ISSI_REG_SSR, ssr);
|
||||
// Set PWM Frequency Enable Register if applicable
|
||||
#ifdef ISSI_REG_PWM_ENABLE
|
||||
IS31FL_write_single_register(addr, ISSI_REG_PWM_ENABLE, ISSI_PWM_ENABLE);
|
||||
#endif
|
||||
// Set PWM Frequency Register if applicable
|
||||
#ifdef ISSI_REG_PWM_SET
|
||||
IS31FL_write_single_register(addr, ISSI_REG_PWM_SET, ISSI_PWM_SET);
|
||||
#endif
|
||||
|
||||
// Wait 10ms to ensure the device has woken up.
|
||||
wait_ms(10);
|
||||
}
|
||||
|
||||
void IS31FL_common_update_pwm_register(uint8_t addr, uint8_t index) {
|
||||
if (g_pwm_buffer_update_required[index]) {
|
||||
// Queue up the correct page
|
||||
IS31FL_unlock_register(addr, ISSI_PAGE_PWM);
|
||||
// Hand off the update to IS31FL_write_multi_registers
|
||||
IS31FL_write_multi_registers(addr, g_pwm_buffer[index], ISSI_MAX_LEDS, ISSI_PWM_TRF_SIZE, ISSI_PWM_REG_1ST);
|
||||
// Update flags that pwm_buffer has been updated
|
||||
g_pwm_buffer_update_required[index] = false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ISSI_MANUAL_SCALING
|
||||
void IS31FL_set_manual_scaling_buffer(void) {
|
||||
for (int i = 0; i < ISSI_MANUAL_SCALING; i++) {
|
||||
is31_led scale = g_is31_scaling[i];
|
||||
if (scale.driver >= 0 && scale.driver < DRIVER_LED_TOTAL) {
|
||||
is31_led led = g_is31_leds[scale.driver];
|
||||
|
||||
# ifdef RGB_MATRIX_ENABLE
|
||||
g_scaling_buffer[led.driver][led.r] = scale.r;
|
||||
g_scaling_buffer[led.driver][led.g] = scale.g;
|
||||
g_scaling_buffer[led.driver][led.b] = scale.b;
|
||||
# elif defined(LED_MATRIX_ENABLE)
|
||||
g_scaling_buffer[led.driver][led.v] = scale.v;
|
||||
# endif
|
||||
g_scaling_buffer_update_required[led.driver] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void IS31FL_common_update_scaling_register(uint8_t addr, uint8_t index) {
|
||||
if (g_scaling_buffer_update_required[index]) {
|
||||
// Queue up the correct page
|
||||
IS31FL_unlock_register(addr, ISSI_PAGE_SCALING);
|
||||
// Hand off the update to IS31FL_write_multi_registers
|
||||
IS31FL_write_multi_registers(addr, g_scaling_buffer[index], ISSI_SCALING_SIZE, ISSI_SCALING_TRF_SIZE, ISSI_SCL_REG_1ST);
|
||||
// Update flags that scaling_buffer has been updated
|
||||
g_scaling_buffer_update_required[index] = false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef RGB_MATRIX_ENABLE
|
||||
// Colour is set by adjusting PWM register
|
||||
void IS31FL_RGB_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
|
||||
if (index >= 0 && index < DRIVER_LED_TOTAL) {
|
||||
is31_led led = g_is31_leds[index];
|
||||
|
||||
g_pwm_buffer[led.driver][led.r] = red;
|
||||
g_pwm_buffer[led.driver][led.g] = green;
|
||||
g_pwm_buffer[led.driver][led.b] = blue;
|
||||
g_pwm_buffer_update_required[led.driver] = true;
|
||||
}
|
||||
}
|
||||
|
||||
void IS31FL_RGB_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
|
||||
for (int i = 0; i < DRIVER_LED_TOTAL; i++) {
|
||||
IS31FL_RGB_set_color(i, red, green, blue);
|
||||
}
|
||||
}
|
||||
|
||||
// Setup Scaling register that decides the peak current of each LED
|
||||
void IS31FL_RGB_set_scaling_buffer(uint8_t index, bool red, bool green, bool blue) {
|
||||
is31_led led = g_is31_leds[index];
|
||||
if (red) {
|
||||
g_scaling_buffer[led.driver][led.r] = ISSI_SCAL_RED;
|
||||
} else {
|
||||
g_scaling_buffer[led.driver][led.r] = ISSI_SCAL_RED_OFF;
|
||||
}
|
||||
if (green) {
|
||||
g_scaling_buffer[led.driver][led.g] = ISSI_SCAL_GREEN;
|
||||
} else {
|
||||
g_scaling_buffer[led.driver][led.g] = ISSI_SCAL_GREEN_OFF;
|
||||
}
|
||||
if (blue) {
|
||||
g_scaling_buffer[led.driver][led.b] = ISSI_SCAL_BLUE;
|
||||
} else {
|
||||
g_scaling_buffer[led.driver][led.b] = ISSI_SCAL_BLUE_OFF;
|
||||
}
|
||||
g_scaling_buffer_update_required[led.driver] = true;
|
||||
}
|
||||
|
||||
#elif defined(LED_MATRIX_ENABLE)
|
||||
// LED Matrix Specific scripts
|
||||
void IS31FL_simple_set_scaling_buffer(uint8_t index, bool value) {
|
||||
is31_led led = g_is31_leds[index];
|
||||
if (value) {
|
||||
g_scaling_buffer[led.driver][led.v] = ISSI_SCAL_LED;
|
||||
} else {
|
||||
g_scaling_buffer[led.driver][led.v] = ISSI_SCAL_LED_OFF;
|
||||
}
|
||||
g_scaling_buffer_update_required[led.driver] = true;
|
||||
}
|
||||
|
||||
void IS31FL_simple_set_brightness(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 IS31FL_simple_set_brigntness_all(uint8_t value) {
|
||||
for (int i = 0; i < DRIVER_LED_TOTAL; i++) {
|
||||
IS31FL_simple_set_brightness(i, value);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
78
drivers/led/issi/is31flcommon.h
Normal file
78
drivers/led/issi/is31flcommon.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/* 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
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "progmem.h"
|
||||
|
||||
// Which variant header file to use
|
||||
#ifdef IS31FL3742A
|
||||
# include "is31fl3742.h"
|
||||
#elif defined(IS31FL3743A)
|
||||
# include "is31fl3743.h"
|
||||
#elif defined(IS31FL3745)
|
||||
# include "is31fl3745.h"
|
||||
#elif defined(IS31FL3746A)
|
||||
# include "is31fl3746.h"
|
||||
#endif
|
||||
|
||||
#ifdef RGB_MATRIX_ENABLE
|
||||
typedef struct is31_led {
|
||||
uint8_t driver;
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
} __attribute__((packed)) is31_led;
|
||||
|
||||
#elif defined(LED_MATRIX_ENABLE)
|
||||
typedef struct is31_led {
|
||||
uint8_t driver;
|
||||
uint8_t v;
|
||||
} __attribute__((packed)) is31_led;
|
||||
#endif
|
||||
|
||||
#ifdef ISSI_MANUAL_SCALING
|
||||
extern const is31_led __flash g_is31_scaling[];
|
||||
void IS31FL_set_manual_scaling_buffer(void);
|
||||
#endif
|
||||
|
||||
extern const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL];
|
||||
|
||||
void IS31FL_write_single_register(uint8_t addr, uint8_t reg, uint8_t data);
|
||||
bool IS31FL_write_multi_registers(uint8_t addr, uint8_t *source_buffer, uint8_t buffer_size, uint8_t transfer_size, uint8_t start_reg_addr);
|
||||
void IS31FL_unlock_register(uint8_t addr, uint8_t page);
|
||||
void IS31FL_common_init(uint8_t addr, uint8_t ssr);
|
||||
|
||||
void IS31FL_common_update_pwm_register(uint8_t addr, uint8_t index);
|
||||
void IS31FL_common_update_scaling_register(uint8_t addr, uint8_t index);
|
||||
|
||||
#ifdef RGB_MATRIX_ENABLE
|
||||
// RGB Matrix Specific scripts
|
||||
void IS31FL_RGB_set_color(int index, uint8_t red, uint8_t green, uint8_t blue);
|
||||
void IS31FL_RGB_set_color_all(uint8_t red, uint8_t green, uint8_t blue);
|
||||
void IS31FL_RGB_set_scaling_buffer(uint8_t index, bool red, bool green, bool blue);
|
||||
#elif defined(LED_MATRIX_ENABLE)
|
||||
// LED Matrix Specific scripts
|
||||
void IS31FL_simple_set_scaling_buffer(uint8_t index, bool value);
|
||||
void IS31FL_simple_set_brightness(int index, uint8_t value);
|
||||
void IS31FL_simple_set_brigntness_all(uint8_t value);
|
||||
#endif
|
||||
@@ -34,16 +34,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# define OLED_DISPLAY_HEIGHT 64
|
||||
# endif
|
||||
# ifndef OLED_MATRIX_SIZE
|
||||
# define OLED_MATRIX_SIZE (OLED_DISPLAY_HEIGHT / 8 * OLED_DISPLAY_WIDTH) // 1024 (compile time mathed)
|
||||
# define OLED_MATRIX_SIZE (OLED_DISPLAY_HEIGHT / 8 * OLED_DISPLAY_WIDTH) // 1024 (compile time mathed)
|
||||
# endif
|
||||
# ifndef OLED_BLOCK_TYPE
|
||||
# define OLED_BLOCK_TYPE uint16_t
|
||||
# endif
|
||||
# ifndef OLED_BLOCK_COUNT
|
||||
# define OLED_BLOCK_COUNT (sizeof(OLED_BLOCK_TYPE) * 8) // 32 (compile time mathed)
|
||||
# define OLED_BLOCK_COUNT (sizeof(OLED_BLOCK_TYPE) * 8) // 32 (compile time mathed)
|
||||
# endif
|
||||
# ifndef OLED_BLOCK_SIZE
|
||||
# define OLED_BLOCK_SIZE (OLED_MATRIX_SIZE / OLED_BLOCK_COUNT) // 32 (compile time mathed)
|
||||
# define OLED_BLOCK_SIZE (OLED_MATRIX_SIZE / OLED_BLOCK_COUNT) // 32 (compile time mathed)
|
||||
# endif
|
||||
# ifndef OLED_COM_PINS
|
||||
# define OLED_COM_PINS COM_PINS_ALT
|
||||
@@ -68,7 +68,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
// If OLED_BLOCK_TYPE is uint8_t, these tables would look like:
|
||||
// #define OLED_SOURCE_MAP { 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120 }
|
||||
// #define OLED_TARGET_MAP { 56, 120, 48, 112, 40, 104, 32, 96, 24, 88, 16, 80, 8, 72, 0, 64 }
|
||||
#else // defined(OLED_DISPLAY_128X64)
|
||||
#else // defined(OLED_DISPLAY_128X64)
|
||||
// Default 128x32
|
||||
# ifndef OLED_DISPLAY_WIDTH
|
||||
# define OLED_DISPLAY_WIDTH 128
|
||||
@@ -77,16 +77,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# define OLED_DISPLAY_HEIGHT 32
|
||||
# endif
|
||||
# ifndef OLED_MATRIX_SIZE
|
||||
# define OLED_MATRIX_SIZE (OLED_DISPLAY_HEIGHT / 8 * OLED_DISPLAY_WIDTH) // 512 (compile time mathed)
|
||||
# define OLED_MATRIX_SIZE (OLED_DISPLAY_HEIGHT / 8 * OLED_DISPLAY_WIDTH) // 512 (compile time mathed)
|
||||
# endif
|
||||
# ifndef OLED_BLOCK_TYPE
|
||||
# define OLED_BLOCK_TYPE uint16_t // Type to use for segmenting the oled display for smart rendering, use unsigned types only
|
||||
# define OLED_BLOCK_TYPE uint16_t // Type to use for segmenting the oled display for smart rendering, use unsigned types only
|
||||
# endif
|
||||
# ifndef OLED_BLOCK_COUNT
|
||||
# define OLED_BLOCK_COUNT (sizeof(OLED_BLOCK_TYPE) * 8) // 16 (compile time mathed)
|
||||
# define OLED_BLOCK_COUNT (sizeof(OLED_BLOCK_TYPE) * 8) // 16 (compile time mathed)
|
||||
# endif
|
||||
# ifndef OLED_BLOCK_SIZE
|
||||
# define OLED_BLOCK_SIZE (OLED_MATRIX_SIZE / OLED_BLOCK_COUNT) // 32 (compile time mathed)
|
||||
# define OLED_BLOCK_SIZE (OLED_MATRIX_SIZE / OLED_BLOCK_COUNT) // 32 (compile time mathed)
|
||||
# endif
|
||||
# ifndef OLED_COM_PINS
|
||||
# define OLED_COM_PINS COM_PINS_SEQ
|
||||
@@ -105,7 +105,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
// If OLED_BLOCK_TYPE is uint8_t, these tables would look like:
|
||||
// #define OLED_SOURCE_MAP { 0, 8, 16, 24, 32, 40, 48, 56 }
|
||||
// #define OLED_TARGET_MAP { 48, 32, 16, 0, 56, 40, 24, 8 }
|
||||
#endif // defined(OLED_DISPLAY_CUSTOM)
|
||||
#endif // defined(OLED_DISPLAY_CUSTOM)
|
||||
|
||||
#if !defined(OLED_IC)
|
||||
# define OLED_IC OLED_IC_SSD1306
|
||||
@@ -180,7 +180,7 @@ typedef enum {
|
||||
OLED_ROTATION_0 = 0,
|
||||
OLED_ROTATION_90 = 1,
|
||||
OLED_ROTATION_180 = 2,
|
||||
OLED_ROTATION_270 = 3, // OLED_ROTATION_90 | OLED_ROTATION_180
|
||||
OLED_ROTATION_270 = 3, // OLED_ROTATION_90 | OLED_ROTATION_180
|
||||
} oled_rotation_t;
|
||||
|
||||
// Initialize the oled display, rotating the rendered output based on the define passed in.
|
||||
@@ -262,7 +262,7 @@ void oled_write_raw_P(const char *data, uint16_t size);
|
||||
# define oled_write_P(data, invert) oled_write(data, invert)
|
||||
# define oled_write_ln_P(data, invert) oled_write(data, invert)
|
||||
# define oled_write_raw_P(data, size) oled_write_raw(data, size)
|
||||
#endif // defined(__AVR__)
|
||||
#endif // defined(__AVR__)
|
||||
|
||||
// Can be used to manually turn on the screen if it is off
|
||||
// Returns true if the screen was on or turns on
|
||||
|
||||
@@ -53,7 +53,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define PAGE_ADDR 0x22
|
||||
#define PAM_SETCOLUMN_LSB 0x00
|
||||
#define PAM_SETCOLUMN_MSB 0x10
|
||||
#define PAM_PAGE_ADDR 0xB0 // 0xb0 -- 0xb7
|
||||
#define PAM_PAGE_ADDR 0xB0 // 0xb0 -- 0xb7
|
||||
|
||||
// Hardware Configuration Commands
|
||||
#define DISPLAY_START_LINE 0x40
|
||||
@@ -97,9 +97,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define I2C_DATA 0x40
|
||||
#if defined(__AVR__)
|
||||
# define I2C_TRANSMIT_P(data) i2c_transmit_P((OLED_DISPLAY_ADDRESS << 1), &data[0], sizeof(data), OLED_I2C_TIMEOUT)
|
||||
#else // defined(__AVR__)
|
||||
#else // defined(__AVR__)
|
||||
# define I2C_TRANSMIT_P(data) i2c_transmit((OLED_DISPLAY_ADDRESS << 1), &data[0], sizeof(data), OLED_I2C_TIMEOUT)
|
||||
#endif // defined(__AVR__)
|
||||
#endif // defined(__AVR__)
|
||||
#define I2C_TRANSMIT(data) i2c_transmit((OLED_DISPLAY_ADDRESS << 1), &data[0], sizeof(data), OLED_I2C_TIMEOUT)
|
||||
#define I2C_WRITE_REG(mode, data, size) i2c_writeReg((OLED_DISPLAY_ADDRESS << 1), mode, data, size, OLED_I2C_TIMEOUT)
|
||||
|
||||
@@ -119,7 +119,7 @@ bool oled_inverted = false;
|
||||
uint8_t oled_brightness = OLED_BRIGHTNESS;
|
||||
oled_rotation_t oled_rotation = 0;
|
||||
uint8_t oled_rotation_width = 0;
|
||||
uint8_t oled_scroll_speed = 0; // this holds the speed after being remapped to ssd1306 internal values
|
||||
uint8_t oled_scroll_speed = 0; // this holds the speed after being remapped to ssd1306 internal values
|
||||
uint8_t oled_scroll_start = 0;
|
||||
uint8_t oled_scroll_end = 7;
|
||||
#if OLED_TIMEOUT > 0
|
||||
@@ -190,7 +190,7 @@ bool oled_init(oled_rotation_t rotation) {
|
||||
#if (OLED_IC != OLED_IC_SH1106)
|
||||
// MEMORY_MODE is unsupported on SH1106 (Page Addressing only)
|
||||
MEMORY_MODE,
|
||||
0x00, // Horizontal addressing mode
|
||||
0x00, // Horizontal addressing mode
|
||||
#endif
|
||||
};
|
||||
if (I2C_TRANSMIT_P(display_setup1) != I2C_STATUS_SUCCESS) {
|
||||
@@ -232,8 +232,12 @@ bool oled_init(oled_rotation_t rotation) {
|
||||
return true;
|
||||
}
|
||||
|
||||
__attribute__((weak)) oled_rotation_t oled_init_kb(oled_rotation_t rotation) { return rotation; }
|
||||
__attribute__((weak)) oled_rotation_t oled_init_user(oled_rotation_t rotation) { return rotation; }
|
||||
__attribute__((weak)) oled_rotation_t oled_init_kb(oled_rotation_t rotation) {
|
||||
return rotation;
|
||||
}
|
||||
__attribute__((weak)) oled_rotation_t oled_init_user(oled_rotation_t rotation) {
|
||||
return rotation;
|
||||
}
|
||||
|
||||
void oled_clear(void) {
|
||||
memset(oled_buffer, 0, sizeof(oled_buffer));
|
||||
@@ -306,9 +310,9 @@ void oled_render(void) {
|
||||
// Set column & page position
|
||||
static uint8_t display_start[] = {I2C_CMD, COLUMN_ADDR, 0, OLED_DISPLAY_WIDTH - 1, PAGE_ADDR, 0, OLED_DISPLAY_HEIGHT / 8 - 1};
|
||||
if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) {
|
||||
calc_bounds(update_start, &display_start[1]); // Offset from I2C_CMD byte at the start
|
||||
calc_bounds(update_start, &display_start[1]); // Offset from I2C_CMD byte at the start
|
||||
} else {
|
||||
calc_bounds_90(update_start, &display_start[1]); // Offset from I2C_CMD byte at the start
|
||||
calc_bounds_90(update_start, &display_start[1]); // Offset from I2C_CMD byte at the start
|
||||
}
|
||||
|
||||
// Send column & page position
|
||||
@@ -368,7 +372,8 @@ void oled_advance_page(bool clearPageRemainder) {
|
||||
remaining = remaining / OLED_FONT_WIDTH;
|
||||
|
||||
// Write empty character until next line
|
||||
while (remaining--) oled_write_char(' ', false);
|
||||
while (remaining--)
|
||||
oled_write_char(' ', false);
|
||||
} else {
|
||||
// Next page index out of bounds?
|
||||
if (index + remaining >= OLED_MATRIX_SIZE) {
|
||||
@@ -419,7 +424,7 @@ void oled_write_char(const char data, bool invert) {
|
||||
_Static_assert(sizeof(font) >= ((OLED_FONT_END + 1 - OLED_FONT_START) * OLED_FONT_WIDTH), "OLED_FONT_END references outside array");
|
||||
|
||||
// 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 < OLED_FONT_START || cast_data > OLED_FONT_END) {
|
||||
memset(oled_cursor, 0x00, OLED_FONT_WIDTH);
|
||||
} else {
|
||||
@@ -545,7 +550,7 @@ void oled_write_raw_P(const char *data, uint16_t size) {
|
||||
oled_dirty |= ((OLED_BLOCK_TYPE)1 << (i / OLED_BLOCK_SIZE));
|
||||
}
|
||||
}
|
||||
#endif // defined(__AVR__)
|
||||
#endif // defined(__AVR__)
|
||||
|
||||
bool oled_on(void) {
|
||||
if (!oled_initialized) {
|
||||
@@ -595,7 +600,9 @@ bool oled_off(void) {
|
||||
return !oled_active;
|
||||
}
|
||||
|
||||
bool is_oled_on(void) { return oled_active; }
|
||||
bool is_oled_on(void) {
|
||||
return oled_active;
|
||||
}
|
||||
|
||||
uint8_t oled_set_brightness(uint8_t level) {
|
||||
if (!oled_initialized) {
|
||||
@@ -613,7 +620,9 @@ uint8_t oled_set_brightness(uint8_t level) {
|
||||
return oled_brightness;
|
||||
}
|
||||
|
||||
uint8_t oled_get_brightness(void) { return oled_brightness; }
|
||||
uint8_t oled_get_brightness(void) {
|
||||
return oled_brightness;
|
||||
}
|
||||
|
||||
// Set the specific 8 lines rows of the screen to scroll.
|
||||
// 0 is the default for start, and 7 for end, which is the entire
|
||||
@@ -693,7 +702,9 @@ bool oled_scroll_off(void) {
|
||||
return !oled_scrolling;
|
||||
}
|
||||
|
||||
bool is_oled_scrolling(void) { return oled_scrolling; }
|
||||
bool is_oled_scrolling(void) {
|
||||
return oled_scrolling;
|
||||
}
|
||||
|
||||
bool oled_invert(bool invert) {
|
||||
if (!oled_initialized) {
|
||||
@@ -777,5 +788,9 @@ void oled_task(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
__attribute__((weak)) bool oled_task_kb(void) { return oled_task_user(); }
|
||||
__attribute__((weak)) bool oled_task_user(void) { return true; }
|
||||
__attribute__((weak)) bool oled_task_kb(void) {
|
||||
return oled_task_user();
|
||||
}
|
||||
__attribute__((weak)) bool oled_task_user(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -71,12 +71,12 @@ uint8_t ps2_host_send(uint8_t data) {
|
||||
|
||||
/* terminate a transmission if we have */
|
||||
inhibit();
|
||||
wait_us(100); // 100us [4]p.13, [5]p.50
|
||||
wait_us(100); // 100us [4]p.13, [5]p.50
|
||||
|
||||
/* 'Request to Send' and Start bit */
|
||||
data_lo();
|
||||
clock_hi();
|
||||
WAIT(clock_lo, 10000, 10); // 10ms [5]p.50
|
||||
WAIT(clock_lo, 10000, 10); // 10ms [5]p.50
|
||||
|
||||
/* Data bit */
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
@@ -125,11 +125,10 @@ uint8_t ps2_host_recv_response(void) {
|
||||
// Command may take 25ms/20ms at most([5]p.46, [3]p.21)
|
||||
// 250 * 100us(wait for start bit in ps2_host_recv)
|
||||
uint8_t data = 0;
|
||||
uint8_t try
|
||||
= 250;
|
||||
uint8_t try = 250;
|
||||
do {
|
||||
data = ps2_host_recv();
|
||||
} while (try --&&ps2_error);
|
||||
} while (try-- && ps2_error);
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -143,7 +142,7 @@ uint8_t ps2_host_recv(void) {
|
||||
idle();
|
||||
|
||||
/* start bit [1] */
|
||||
WAIT(clock_lo, 100, 1); // TODO: this is enough?
|
||||
WAIT(clock_lo, 100, 1); // TODO: this is enough?
|
||||
WAIT(data_lo, 1, 2);
|
||||
WAIT(clock_hi, 50, 3);
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#if defined(__AVR__)
|
||||
# include <avr/interrupt.h>
|
||||
#elif defined(PROTOCOL_CHIBIOS) // TODO: or STM32 ?
|
||||
#elif defined(PROTOCOL_CHIBIOS) // TODO: or STM32 ?
|
||||
// chibiOS headers
|
||||
# include "ch.h"
|
||||
# include "hal.h"
|
||||
@@ -71,7 +71,9 @@ static inline void pbuf_clear(void);
|
||||
|
||||
#if defined(PROTOCOL_CHIBIOS)
|
||||
void ps2_interrupt_service_routine(void);
|
||||
void palCallback(void *arg) { ps2_interrupt_service_routine(); }
|
||||
void palCallback(void *arg) {
|
||||
ps2_interrupt_service_routine();
|
||||
}
|
||||
|
||||
# define PS2_INT_INIT() \
|
||||
{ palSetLineMode(PS2_CLOCK_PIN, PAL_MODE_INPUT); } \
|
||||
@@ -85,7 +87,7 @@ void palCallback(void *arg) { ps2_interrupt_service_routine(); }
|
||||
# define PS2_INT_OFF() \
|
||||
{ palDisableLineEvent(PS2_CLOCK_PIN); } \
|
||||
while (0)
|
||||
#endif // PROTOCOL_CHIBIOS
|
||||
#endif // PROTOCOL_CHIBIOS
|
||||
|
||||
void ps2_host_init(void) {
|
||||
idle();
|
||||
@@ -103,12 +105,12 @@ uint8_t ps2_host_send(uint8_t data) {
|
||||
|
||||
/* terminate a transmission if we have */
|
||||
inhibit();
|
||||
wait_us(100); // 100us [4]p.13, [5]p.50
|
||||
wait_us(100); // 100us [4]p.13, [5]p.50
|
||||
|
||||
/* 'Request to Send' and Start bit */
|
||||
data_lo();
|
||||
clock_hi();
|
||||
WAIT(clock_lo, 10000, 10); // 10ms [5]p.50
|
||||
WAIT(clock_lo, 10000, 10); // 10ms [5]p.50
|
||||
|
||||
/* Data bit[2-9] */
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
@@ -244,7 +246,9 @@ RETURN:
|
||||
}
|
||||
|
||||
#if defined(__AVR__)
|
||||
ISR(PS2_INT_VECT) { ps2_interrupt_service_routine(); }
|
||||
ISR(PS2_INT_VECT) {
|
||||
ps2_interrupt_service_routine();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* send LED state to keyboard */
|
||||
|
||||
@@ -42,7 +42,7 @@ static inline void ps2_mouse_scroll_button_task(report_mouse_t *mouse_report);
|
||||
void ps2_mouse_init(void) {
|
||||
ps2_host_init();
|
||||
|
||||
wait_ms(PS2_MOUSE_INIT_DELAY); // wait for powering up
|
||||
wait_ms(PS2_MOUSE_INIT_DELAY); // wait for powering up
|
||||
|
||||
PS2_MOUSE_SEND(PS2_MOUSE_RESET, "ps2_mouse_init: sending reset");
|
||||
|
||||
@@ -113,9 +113,13 @@ void ps2_mouse_task(void) {
|
||||
ps2_mouse_clear_report(&mouse_report);
|
||||
}
|
||||
|
||||
void ps2_mouse_disable_data_reporting(void) { PS2_MOUSE_SEND(PS2_MOUSE_DISABLE_DATA_REPORTING, "ps2 mouse disable data reporting"); }
|
||||
void ps2_mouse_disable_data_reporting(void) {
|
||||
PS2_MOUSE_SEND(PS2_MOUSE_DISABLE_DATA_REPORTING, "ps2 mouse disable data reporting");
|
||||
}
|
||||
|
||||
void ps2_mouse_enable_data_reporting(void) { PS2_MOUSE_SEND(PS2_MOUSE_ENABLE_DATA_REPORTING, "ps2 mouse enable data reporting"); }
|
||||
void ps2_mouse_enable_data_reporting(void) {
|
||||
PS2_MOUSE_SEND(PS2_MOUSE_ENABLE_DATA_REPORTING, "ps2 mouse enable data reporting");
|
||||
}
|
||||
|
||||
void ps2_mouse_set_remote_mode(void) {
|
||||
PS2_MOUSE_SEND_SAFE(PS2_MOUSE_SET_REMOTE_MODE, "ps2 mouse set remote mode");
|
||||
@@ -127,13 +131,21 @@ void ps2_mouse_set_stream_mode(void) {
|
||||
ps2_mouse_mode = PS2_MOUSE_STREAM_MODE;
|
||||
}
|
||||
|
||||
void ps2_mouse_set_scaling_2_1(void) { PS2_MOUSE_SEND_SAFE(PS2_MOUSE_SET_SCALING_2_1, "ps2 mouse set scaling 2:1"); }
|
||||
void ps2_mouse_set_scaling_2_1(void) {
|
||||
PS2_MOUSE_SEND_SAFE(PS2_MOUSE_SET_SCALING_2_1, "ps2 mouse set scaling 2:1");
|
||||
}
|
||||
|
||||
void ps2_mouse_set_scaling_1_1(void) { PS2_MOUSE_SEND_SAFE(PS2_MOUSE_SET_SCALING_1_1, "ps2 mouse set scaling 1:1"); }
|
||||
void ps2_mouse_set_scaling_1_1(void) {
|
||||
PS2_MOUSE_SEND_SAFE(PS2_MOUSE_SET_SCALING_1_1, "ps2 mouse set scaling 1:1");
|
||||
}
|
||||
|
||||
void ps2_mouse_set_resolution(ps2_mouse_resolution_t resolution) { PS2_MOUSE_SET_SAFE(PS2_MOUSE_SET_RESOLUTION, resolution, "ps2 mouse set resolution"); }
|
||||
void ps2_mouse_set_resolution(ps2_mouse_resolution_t resolution) {
|
||||
PS2_MOUSE_SET_SAFE(PS2_MOUSE_SET_RESOLUTION, resolution, "ps2 mouse set resolution");
|
||||
}
|
||||
|
||||
void ps2_mouse_set_sample_rate(ps2_mouse_sample_rate_t sample_rate) { PS2_MOUSE_SET_SAFE(PS2_MOUSE_SET_SAMPLE_RATE, sample_rate, "ps2 mouse set sample rate"); }
|
||||
void ps2_mouse_set_sample_rate(ps2_mouse_sample_rate_t sample_rate) {
|
||||
PS2_MOUSE_SET_SAFE(PS2_MOUSE_SET_SAMPLE_RATE, sample_rate, "ps2 mouse set sample rate");
|
||||
}
|
||||
|
||||
/* ============================= HELPERS ============================ */
|
||||
|
||||
@@ -165,7 +177,7 @@ static inline void ps2_mouse_convert_report_to_hid(report_mouse_t *mouse_report)
|
||||
#ifdef PS2_MOUSE_INVERT_X
|
||||
mouse_report->x = -mouse_report->x;
|
||||
#endif
|
||||
#ifndef PS2_MOUSE_INVERT_Y // NOTE if not!
|
||||
#ifndef PS2_MOUSE_INVERT_Y // NOTE if not!
|
||||
// invert coordinate of y to conform to USB HID mouse
|
||||
mouse_report->y = -mouse_report->y;
|
||||
#endif
|
||||
|
||||
@@ -74,9 +74,13 @@ void adns5050_sync(void) {
|
||||
writePinHigh(ADNS5050_CS_PIN);
|
||||
}
|
||||
|
||||
void adns5050_cs_select(void) { writePinLow(ADNS5050_CS_PIN); }
|
||||
void adns5050_cs_select(void) {
|
||||
writePinLow(ADNS5050_CS_PIN);
|
||||
}
|
||||
|
||||
void adns5050_cs_deselect(void) { writePinHigh(ADNS5050_CS_PIN); }
|
||||
void adns5050_cs_deselect(void) {
|
||||
writePinHigh(ADNS5050_CS_PIN);
|
||||
}
|
||||
|
||||
uint8_t adns5050_serial_read(void) {
|
||||
setPinInput(ADNS5050_SDIO_PIN);
|
||||
@@ -190,7 +194,7 @@ int8_t convert_twoscomp(uint8_t data) {
|
||||
|
||||
// Don't forget to use the definitions for CPI in the header file.
|
||||
void adns5050_set_cpi(uint16_t cpi) {
|
||||
uint8_t cpival = constrain((cpi / 125), 0x1, 0xD); // limits to 0--119
|
||||
uint8_t cpival = constrain((cpi / 125), 0x1, 0xD); // limits to 0--119
|
||||
|
||||
adns5050_write_reg(REG_MOUSE_CONTROL2, 0b10000 | cpival);
|
||||
}
|
||||
|
||||
@@ -77,7 +77,9 @@
|
||||
#define MSB1 0x80
|
||||
// clang-format on
|
||||
|
||||
void adns9800_spi_start(void) { spi_start(ADNS9800_CS_PIN, false, ADNS9800_SPI_MODE, ADNS9800_SPI_DIVISOR); }
|
||||
void adns9800_spi_start(void) {
|
||||
spi_start(ADNS9800_CS_PIN, false, ADNS9800_SPI_MODE, ADNS9800_SPI_DIVISOR);
|
||||
}
|
||||
|
||||
void adns9800_write(uint8_t reg_addr, uint8_t data) {
|
||||
adns9800_spi_start();
|
||||
@@ -135,10 +137,8 @@ void adns9800_init() {
|
||||
wait_us(15);
|
||||
|
||||
// send all bytes of the firmware
|
||||
unsigned char c;
|
||||
for (int i = 0; i < FIRMWARE_LENGTH; i++) {
|
||||
c = (unsigned char)pgm_read_byte(adns9800_firmware_data + i);
|
||||
spi_write(c);
|
||||
for (uint16_t i = 0; i < FIRMWARE_LENGTH; i++) {
|
||||
spi_write(pgm_read_byte(firmware_data + i));
|
||||
wait_us(15);
|
||||
}
|
||||
|
||||
@@ -154,8 +154,8 @@ void adns9800_init() {
|
||||
}
|
||||
|
||||
config_adns9800_t adns9800_get_config(void) {
|
||||
uint8_t config_1 = adns9800_read(REG_Configuration_I);
|
||||
return (config_adns9800_t){(config_1 & 0xFF) * CPI_STEP};
|
||||
uint8_t cpival = adns9800_read(REG_Configuration_I);
|
||||
return (config_adns9800_t){(cpival & 0xFF) * CPI_STEP};
|
||||
}
|
||||
|
||||
void adns9800_set_config(config_adns9800_t config) {
|
||||
@@ -164,8 +164,8 @@ void adns9800_set_config(config_adns9800_t config) {
|
||||
}
|
||||
|
||||
uint16_t adns9800_get_cpi(void) {
|
||||
uint8_t config_1 = adns9800_read(REG_Configuration_I);
|
||||
return (uint16_t){(config_1 & 0xFF) * CPI_STEP};
|
||||
uint8_t cpival = adns9800_read(REG_Configuration_I);
|
||||
return (uint16_t)(cpival & 0xFF) * CPI_STEP;
|
||||
}
|
||||
|
||||
void adns9800_set_cpi(uint16_t cpi) {
|
||||
@@ -184,7 +184,7 @@ static int16_t convertDeltaToInt(uint8_t high, uint8_t low) {
|
||||
}
|
||||
|
||||
report_adns9800_t adns9800_get_report(void) {
|
||||
report_adns9800_t report = {0, 0};
|
||||
report_adns9800_t report = {0};
|
||||
|
||||
adns9800_spi_start();
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
// clang-format off
|
||||
|
||||
const uint8_t adns9800_firmware_data[FIRMWARE_LENGTH] PROGMEM = {
|
||||
const uint8_t firmware_data[FIRMWARE_LENGTH] PROGMEM = {
|
||||
0x03, 0xA6, 0x68, 0x1E, 0x7D, 0x10, 0x7E, 0x7E, 0x5F, 0x1C, 0xB8, 0xF2, 0x47, 0x0C, 0x7B, 0x74,
|
||||
0x4B, 0x14, 0x8B, 0x75, 0x66, 0x51, 0x0B, 0x8C, 0x76, 0x74, 0x4B, 0x14, 0xAA, 0xD6, 0x0F, 0x9C,
|
||||
0xBA, 0xF6, 0x6E, 0x3F, 0xDD, 0x38, 0xD5, 0x02, 0x80, 0x9B, 0x82, 0x6D, 0x58, 0x13, 0xA4, 0xAB,
|
||||
|
||||
@@ -18,19 +18,21 @@
|
||||
#include "analog.h"
|
||||
#include "gpio.h"
|
||||
#include "wait.h"
|
||||
#include "timer.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
// Set Parameters
|
||||
uint16_t minAxisValue = ANALOG_JOYSTICK_AXIS_MIN;
|
||||
uint16_t maxAxisValue = ANALOG_JOYSTICK_AXIS_MAX;
|
||||
|
||||
uint8_t maxCursorSpeed = ANALOG_JOYSTICK_SPEED_MAX;
|
||||
uint8_t speedRegulator = ANALOG_JOYSTICK_SPEED_REGULATOR; // Lower Values Create Faster Movement
|
||||
uint8_t speedRegulator = ANALOG_JOYSTICK_SPEED_REGULATOR; // Lower Values Create Faster Movement
|
||||
|
||||
int16_t xOrigin, yOrigin;
|
||||
|
||||
uint16_t lastCursor = 0;
|
||||
|
||||
int16_t axisCoordinate(uint8_t pin, uint16_t origin) {
|
||||
int16_t axisCoordinate(pin_t pin, uint16_t origin) {
|
||||
int8_t direction;
|
||||
int16_t distanceFromOrigin;
|
||||
int16_t range;
|
||||
@@ -60,7 +62,7 @@ int16_t axisCoordinate(uint8_t pin, uint16_t origin) {
|
||||
}
|
||||
}
|
||||
|
||||
int8_t axisToMouseComponent(uint8_t pin, int16_t origin, uint8_t maxSpeed) {
|
||||
int8_t axisToMouseComponent(pin_t pin, int16_t origin, uint8_t maxSpeed) {
|
||||
int16_t coordinate = axisCoordinate(pin, origin);
|
||||
if (coordinate != 0) {
|
||||
float percent = (float)coordinate / 100;
|
||||
|
||||
@@ -54,7 +54,9 @@ void RAP_ReadBytes(uint8_t address, uint8_t* data, uint8_t count);
|
||||
void RAP_Write(uint8_t address, uint8_t data);
|
||||
|
||||
#ifdef CONSOLE_ENABLE
|
||||
void print_byte(uint8_t byte) { xprintf("%c%c%c%c%c%c%c%c|", (byte & 0x80 ? '1' : '0'), (byte & 0x40 ? '1' : '0'), (byte & 0x20 ? '1' : '0'), (byte & 0x10 ? '1' : '0'), (byte & 0x08 ? '1' : '0'), (byte & 0x04 ? '1' : '0'), (byte & 0x02 ? '1' : '0'), (byte & 0x01 ? '1' : '0')); }
|
||||
void print_byte(uint8_t byte) {
|
||||
xprintf("%c%c%c%c%c%c%c%c|", (byte & 0x80 ? '1' : '0'), (byte & 0x40 ? '1' : '0'), (byte & 0x20 ? '1' : '0'), (byte & 0x10 ? '1' : '0'), (byte & 0x08 ? '1' : '0'), (byte & 0x04 ? '1' : '0'), (byte & 0x02 ? '1' : '0'), (byte & 0x01 ? '1' : '0'));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Logical Scaling Functions */
|
||||
@@ -73,8 +75,12 @@ void ClipCoordinates(pinnacle_data_t* coordinates) {
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t cirque_pinnacle_get_scale(void) { return scale_data; }
|
||||
void cirque_pinnacle_set_scale(uint16_t scale) { scale_data = scale; }
|
||||
uint16_t cirque_pinnacle_get_scale(void) {
|
||||
return scale_data;
|
||||
}
|
||||
void cirque_pinnacle_set_scale(uint16_t scale) {
|
||||
scale_data = scale;
|
||||
}
|
||||
|
||||
// Scales data to desired X & Y resolution
|
||||
void cirque_pinnacle_scale_data(pinnacle_data_t* coordinates, uint16_t xResolution, uint16_t yResolution) {
|
||||
@@ -105,13 +111,13 @@ void cirque_pinnacle_clear_flags() {
|
||||
void cirque_pinnacle_enable_feed(bool feedEnable) {
|
||||
uint8_t temp;
|
||||
|
||||
RAP_ReadBytes(FEEDCONFIG_1, &temp, 1); // Store contents of FeedConfig1 register
|
||||
RAP_ReadBytes(FEEDCONFIG_1, &temp, 1); // Store contents of FeedConfig1 register
|
||||
|
||||
if (feedEnable) {
|
||||
temp |= 0x01; // Set Feed Enable bit
|
||||
temp |= 0x01; // Set Feed Enable bit
|
||||
RAP_Write(0x04, temp);
|
||||
} else {
|
||||
temp &= ~0x01; // Clear Feed Enable bit
|
||||
temp &= ~0x01; // Clear Feed Enable bit
|
||||
RAP_Write(0x04, temp);
|
||||
}
|
||||
}
|
||||
@@ -122,13 +128,13 @@ void cirque_pinnacle_enable_feed(bool feedEnable) {
|
||||
void ERA_ReadBytes(uint16_t address, uint8_t* data, uint16_t count) {
|
||||
uint8_t ERAControlValue = 0xFF;
|
||||
|
||||
cirque_pinnacle_enable_feed(false); // Disable feed
|
||||
cirque_pinnacle_enable_feed(false); // Disable feed
|
||||
|
||||
RAP_Write(ERA_HIGH_BYTE, (uint8_t)(address >> 8)); // Send upper byte of ERA address
|
||||
RAP_Write(ERA_LOW_BYTE, (uint8_t)(address & 0x00FF)); // Send lower byte of ERA address
|
||||
RAP_Write(ERA_HIGH_BYTE, (uint8_t)(address >> 8)); // Send upper byte of ERA address
|
||||
RAP_Write(ERA_LOW_BYTE, (uint8_t)(address & 0x00FF)); // Send lower byte of ERA address
|
||||
|
||||
for (uint16_t i = 0; i < count; i++) {
|
||||
RAP_Write(ERA_CONTROL, 0x05); // Signal ERA-read (auto-increment) to Pinnacle
|
||||
RAP_Write(ERA_CONTROL, 0x05); // Signal ERA-read (auto-increment) to Pinnacle
|
||||
|
||||
// Wait for status register 0x1E to clear
|
||||
do {
|
||||
@@ -145,14 +151,14 @@ void ERA_ReadBytes(uint16_t address, uint8_t* data, uint16_t count) {
|
||||
void ERA_WriteByte(uint16_t address, uint8_t data) {
|
||||
uint8_t ERAControlValue = 0xFF;
|
||||
|
||||
cirque_pinnacle_enable_feed(false); // Disable feed
|
||||
cirque_pinnacle_enable_feed(false); // Disable feed
|
||||
|
||||
RAP_Write(ERA_VALUE, data); // Send data byte to be written
|
||||
RAP_Write(ERA_VALUE, data); // Send data byte to be written
|
||||
|
||||
RAP_Write(ERA_HIGH_BYTE, (uint8_t)(address >> 8)); // Upper byte of ERA address
|
||||
RAP_Write(ERA_LOW_BYTE, (uint8_t)(address & 0x00FF)); // Lower byte of ERA address
|
||||
RAP_Write(ERA_HIGH_BYTE, (uint8_t)(address >> 8)); // Upper byte of ERA address
|
||||
RAP_Write(ERA_LOW_BYTE, (uint8_t)(address & 0x00FF)); // Lower byte of ERA address
|
||||
|
||||
RAP_Write(ERA_CONTROL, 0x02); // Signal an ERA-write to Pinnacle
|
||||
RAP_Write(ERA_CONTROL, 0x02); // Signal an ERA-write to Pinnacle
|
||||
|
||||
// Wait for status register 0x1E to clear
|
||||
do {
|
||||
@@ -166,7 +172,7 @@ void cirque_pinnacle_set_adc_attenuation(uint8_t adcGain) {
|
||||
uint8_t temp = 0x00;
|
||||
|
||||
ERA_ReadBytes(0x0187, &temp, 1);
|
||||
temp &= 0x3F; // clear top two bits
|
||||
temp &= 0x3F; // clear top two bits
|
||||
temp |= adcGain;
|
||||
ERA_WriteByte(0x0187, temp);
|
||||
ERA_ReadBytes(0x0187, &temp, 1);
|
||||
|
||||
@@ -26,16 +26,16 @@ void cirque_pinnacle_set_scale(uint16_t scale);
|
||||
|
||||
// Coordinate scaling values
|
||||
#ifndef CIRQUE_PINNACLE_X_LOWER
|
||||
# define CIRQUE_PINNACLE_X_LOWER 127 // min "reachable" X value
|
||||
# define CIRQUE_PINNACLE_X_LOWER 127 // min "reachable" X value
|
||||
#endif
|
||||
#ifndef CIRQUE_PINNACLE_X_UPPER
|
||||
# define CIRQUE_PINNACLE_X_UPPER 1919 // max "reachable" X value
|
||||
# define CIRQUE_PINNACLE_X_UPPER 1919 // max "reachable" X value
|
||||
#endif
|
||||
#ifndef CIRQUE_PINNACLE_Y_LOWER
|
||||
# define CIRQUE_PINNACLE_Y_LOWER 63 // min "reachable" Y value
|
||||
# define CIRQUE_PINNACLE_Y_LOWER 63 // min "reachable" Y value
|
||||
#endif
|
||||
#ifndef CIRQUE_PINNACLE_Y_UPPER
|
||||
# define CIRQUE_PINNACLE_Y_UPPER 1471 // max "reachable" Y value
|
||||
# define CIRQUE_PINNACLE_Y_UPPER 1471 // max "reachable" Y value
|
||||
#endif
|
||||
#ifndef CIRQUE_PINNACLE_X_RANGE
|
||||
# define CIRQUE_PINNACLE_X_RANGE (CIRQUE_PINNACLE_X_UPPER - CIRQUE_PINNACLE_X_LOWER)
|
||||
|
||||
@@ -14,7 +14,7 @@ extern bool touchpad_init;
|
||||
/* RAP Functions */
|
||||
// Reads <count> Pinnacle registers starting at <address>
|
||||
void RAP_ReadBytes(uint8_t address, uint8_t* data, uint8_t count) {
|
||||
uint8_t cmdByte = READ_MASK | address; // Form the READ command byte
|
||||
uint8_t cmdByte = READ_MASK | address; // Form the READ command byte
|
||||
if (touchpad_init) {
|
||||
i2c_writeReg(CIRQUE_PINNACLE_ADDR << 1, cmdByte, NULL, 0, CIRQUE_PINNACLE_TIMEOUT);
|
||||
if (i2c_readReg(CIRQUE_PINNACLE_ADDR << 1, cmdByte, data, count, CIRQUE_PINNACLE_TIMEOUT) != I2C_STATUS_SUCCESS) {
|
||||
@@ -29,7 +29,7 @@ void RAP_ReadBytes(uint8_t address, uint8_t* data, uint8_t count) {
|
||||
|
||||
// Writes single-byte <data> to <address>
|
||||
void RAP_Write(uint8_t address, uint8_t data) {
|
||||
uint8_t cmdByte = WRITE_MASK | address; // Form the WRITE command byte
|
||||
uint8_t cmdByte = WRITE_MASK | address; // Form the WRITE command byte
|
||||
|
||||
if (touchpad_init) {
|
||||
if (i2c_writeReg(CIRQUE_PINNACLE_ADDR << 1, cmdByte, &data, sizeof(data), CIRQUE_PINNACLE_TIMEOUT) != I2C_STATUS_SUCCESS) {
|
||||
|
||||
@@ -13,14 +13,14 @@ extern bool touchpad_init;
|
||||
/* RAP Functions */
|
||||
// Reads <count> Pinnacle registers starting at <address>
|
||||
void RAP_ReadBytes(uint8_t address, uint8_t* data, uint8_t count) {
|
||||
uint8_t cmdByte = READ_MASK | address; // Form the READ command byte
|
||||
uint8_t cmdByte = READ_MASK | address; // Form the READ command byte
|
||||
if (touchpad_init) {
|
||||
if (spi_start(CIRQUE_PINNACLE_SPI_CS_PIN, CIRQUE_PINNACLE_SPI_LSBFIRST, CIRQUE_PINNACLE_SPI_MODE, CIRQUE_PINNACLE_SPI_DIVISOR)) {
|
||||
spi_write(cmdByte);
|
||||
spi_read(); // filler
|
||||
spi_read(); // filler
|
||||
spi_read(); // filler
|
||||
spi_read(); // filler
|
||||
for (uint8_t i = 0; i < count; i++) {
|
||||
data[i] = spi_read(); // each sepsequent read gets another register's contents
|
||||
data[i] = spi_read(); // each sepsequent read gets another register's contents
|
||||
}
|
||||
} else {
|
||||
#ifdef CONSOLE_ENABLE
|
||||
@@ -34,7 +34,7 @@ void RAP_ReadBytes(uint8_t address, uint8_t* data, uint8_t count) {
|
||||
|
||||
// Writes single-byte <data> to <address>
|
||||
void RAP_Write(uint8_t address, uint8_t data) {
|
||||
uint8_t cmdByte = WRITE_MASK | address; // Form the WRITE command byte
|
||||
uint8_t cmdByte = WRITE_MASK | address; // Form the WRITE command byte
|
||||
|
||||
if (touchpad_init) {
|
||||
if (spi_start(CIRQUE_PINNACLE_SPI_CS_PIN, CIRQUE_PINNACLE_SPI_LSBFIRST, CIRQUE_PINNACLE_SPI_MODE, CIRQUE_PINNACLE_SPI_DIVISOR)) {
|
||||
|
||||
@@ -33,8 +33,26 @@
|
||||
|
||||
static uint16_t precision = 128;
|
||||
|
||||
float pimoroni_trackball_get_precision(void) { return ((float)precision / 128); }
|
||||
void pimoroni_trackball_set_precision(float floatprecision) { precision = (floatprecision * 128); }
|
||||
uint16_t pimoroni_trackball_get_cpi(void) {
|
||||
return (precision * 125);
|
||||
}
|
||||
/**
|
||||
* @brief Sets the scaling value for pimoroni trackball
|
||||
*
|
||||
* Sets a scaling value for pimoroni trackball to allow runtime adjustment. This isn't used by the sensor and is an
|
||||
* approximation so the functions are consistent across drivers.
|
||||
*
|
||||
* NOTE: This rounds down to the nearest number divisable by 125 that's a positive integer, values below 125 are clamped to 125.
|
||||
*
|
||||
* @param cpi uint16_t
|
||||
*/
|
||||
void pimoroni_trackball_set_cpi(uint16_t cpi) {
|
||||
if (cpi < 249) {
|
||||
precision = 1;
|
||||
} else {
|
||||
precision = (cpi - (cpi % 125)) / 125;
|
||||
}
|
||||
}
|
||||
|
||||
void pimoroni_trackball_set_rgbw(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
|
||||
uint8_t data[4] = {r, g, b, w};
|
||||
@@ -60,7 +78,7 @@ i2c_status_t read_pimoroni_trackball(pimoroni_data_t* data) {
|
||||
return status;
|
||||
}
|
||||
|
||||
__attribute__((weak)) void pimironi_trackball_device_init(void) {
|
||||
__attribute__((weak)) void pimoroni_trackball_device_init(void) {
|
||||
i2c_init();
|
||||
pimoroni_trackball_set_rgbw(0x00, 0x00, 0x00, 0x00);
|
||||
}
|
||||
|
||||
@@ -23,9 +23,6 @@
|
||||
#ifndef PIMORONI_TRACKBALL_ADDRESS
|
||||
# define PIMORONI_TRACKBALL_ADDRESS 0x0A
|
||||
#endif
|
||||
#ifndef PIMORONI_TRACKBALL_INTERVAL_MS
|
||||
# define PIMORONI_TRACKBALL_INTERVAL_MS 8
|
||||
#endif
|
||||
#ifndef PIMORONI_TRACKBALL_SCALE
|
||||
# define PIMORONI_TRACKBALL_SCALE 5
|
||||
#endif
|
||||
@@ -52,10 +49,10 @@ typedef struct {
|
||||
uint8_t click;
|
||||
} pimoroni_data_t;
|
||||
|
||||
void pimironi_trackball_device_init(void);
|
||||
void pimoroni_trackball_device_init(void);
|
||||
void pimoroni_trackball_set_rgbw(uint8_t red, uint8_t green, uint8_t blue, uint8_t white);
|
||||
int16_t pimoroni_trackball_get_offsets(uint8_t negative_dir, uint8_t positive_dir, uint8_t scale);
|
||||
void pimoroni_trackball_adapt_values(int8_t* mouse, int16_t* offset);
|
||||
float pimoroni_trackball_get_precision(void);
|
||||
void pimoroni_trackball_set_precision(float precision);
|
||||
uint16_t pimoroni_trackball_get_cpi(void);
|
||||
void pimoroni_trackball_set_cpi(uint16_t cpi);
|
||||
i2c_status_t read_pimoroni_trackball(pimoroni_data_t* data);
|
||||
|
||||
@@ -16,136 +16,126 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "spi_master.h"
|
||||
#include "pmw3360.h"
|
||||
#include "wait.h"
|
||||
#include "debug.h"
|
||||
#include "print.h"
|
||||
#include PMW3360_FIRMWARE_H
|
||||
#include "pmw3360_firmware.h"
|
||||
|
||||
// Registers
|
||||
// clang-format off
|
||||
#define REG_Product_ID 0x00
|
||||
#define REG_Revision_ID 0x01
|
||||
#define REG_Motion 0x02
|
||||
#define REG_Delta_X_L 0x03
|
||||
#define REG_Delta_X_H 0x04
|
||||
#define REG_Delta_Y_L 0x05
|
||||
#define REG_Delta_Y_H 0x06
|
||||
#define REG_SQUAL 0x07
|
||||
#define REG_Raw_Data_Sum 0x08
|
||||
#define REG_Maximum_Raw_data 0x09
|
||||
#define REG_Minimum_Raw_data 0x0A
|
||||
#define REG_Shutter_Lower 0x0B
|
||||
#define REG_Shutter_Upper 0x0C
|
||||
#define REG_Control 0x0D
|
||||
#define REG_Config1 0x0F
|
||||
#define REG_Config2 0x10
|
||||
#define REG_Angle_Tune 0x11
|
||||
#define REG_Frame_Capture 0x12
|
||||
#define REG_SROM_Enable 0x13
|
||||
#define REG_Run_Downshift 0x14
|
||||
#define REG_Rest1_Rate_Lower 0x15
|
||||
#define REG_Rest1_Rate_Upper 0x16
|
||||
#define REG_Rest1_Downshift 0x17
|
||||
#define REG_Rest2_Rate_Lower 0x18
|
||||
#define REG_Rest2_Rate_Upper 0x19
|
||||
#define REG_Rest2_Downshift 0x1A
|
||||
#define REG_Rest3_Rate_Lower 0x1B
|
||||
#define REG_Rest3_Rate_Upper 0x1C
|
||||
#define REG_Observation 0x24
|
||||
#define REG_Data_Out_Lower 0x25
|
||||
#define REG_Data_Out_Upper 0x26
|
||||
#define REG_Raw_Data_Dump 0x29
|
||||
#define REG_SROM_ID 0x2A
|
||||
#define REG_Min_SQ_Run 0x2B
|
||||
#define REG_Raw_Data_Threshold 0x2C
|
||||
#define REG_Config5 0x2F
|
||||
#define REG_Power_Up_Reset 0x3A
|
||||
#define REG_Shutdown 0x3B
|
||||
#define REG_Inverse_Product_ID 0x3F
|
||||
#define REG_LiftCutoff_Tune3 0x41
|
||||
#define REG_Angle_Snap 0x42
|
||||
#define REG_LiftCutoff_Tune1 0x4A
|
||||
#define REG_Motion_Burst 0x50
|
||||
#define REG_LiftCutoff_Tune_Timeout 0x58
|
||||
#define REG_LiftCutoff_Tune_Min_Length 0x5A
|
||||
#define REG_SROM_Load_Burst 0x62
|
||||
#define REG_Lift_Config 0x63
|
||||
#define REG_Raw_Data_Burst 0x64
|
||||
#define REG_LiftCutoff_Tune2 0x65
|
||||
#define REG_Product_ID 0x00
|
||||
#define REG_Revision_ID 0x01
|
||||
#define REG_Motion 0x02
|
||||
#define REG_Delta_X_L 0x03
|
||||
#define REG_Delta_X_H 0x04
|
||||
#define REG_Delta_Y_L 0x05
|
||||
#define REG_Delta_Y_H 0x06
|
||||
#define REG_SQUAL 0x07
|
||||
#define REG_Raw_Data_Sum 0x08
|
||||
#define REG_Maximum_Raw_data 0x09
|
||||
#define REG_Minimum_Raw_data 0x0a
|
||||
#define REG_Shutter_Lower 0x0b
|
||||
#define REG_Shutter_Upper 0x0c
|
||||
#define REG_Control 0x0d
|
||||
#define REG_Config1 0x0f
|
||||
#define REG_Config2 0x10
|
||||
#define REG_Angle_Tune 0x11
|
||||
#define REG_Frame_Capture 0x12
|
||||
#define REG_SROM_Enable 0x13
|
||||
#define REG_Run_Downshift 0x14
|
||||
#define REG_Rest1_Rate_Lower 0x15
|
||||
#define REG_Rest1_Rate_Upper 0x16
|
||||
#define REG_Rest1_Downshift 0x17
|
||||
#define REG_Rest2_Rate_Lower 0x18
|
||||
#define REG_Rest2_Rate_Upper 0x19
|
||||
#define REG_Rest2_Downshift 0x1a
|
||||
#define REG_Rest3_Rate_Lower 0x1b
|
||||
#define REG_Rest3_Rate_Upper 0x1c
|
||||
#define REG_Observation 0x24
|
||||
#define REG_Data_Out_Lower 0x25
|
||||
#define REG_Data_Out_Upper 0x26
|
||||
#define REG_Raw_Data_Dump 0x29
|
||||
#define REG_SROM_ID 0x2a
|
||||
#define REG_Min_SQ_Run 0x2b
|
||||
#define REG_Raw_Data_Threshold 0x2c
|
||||
#define REG_Config5 0x2f
|
||||
#define REG_Power_Up_Reset 0x3a
|
||||
#define REG_Shutdown 0x3b
|
||||
#define REG_Inverse_Product_ID 0x3f
|
||||
#define REG_LiftCutoff_Tune3 0x41
|
||||
#define REG_Angle_Snap 0x42
|
||||
#define REG_LiftCutoff_Tune1 0x4a
|
||||
#define REG_Motion_Burst 0x50
|
||||
#define REG_LiftCutoff_Tune_Timeout 0x58
|
||||
#define REG_LiftCutoff_Tune_Min_Length 0x5a
|
||||
#define REG_SROM_Load_Burst 0x62
|
||||
#define REG_Lift_Config 0x63
|
||||
#define REG_Raw_Data_Burst 0x64
|
||||
#define REG_LiftCutoff_Tune2 0x65
|
||||
|
||||
#define CPI_STEP 100
|
||||
// clang-format on
|
||||
|
||||
// limits to 0--119, resulting in a CPI range of 100 -- 12000 (as only steps of 100 are possible).
|
||||
#ifndef MAX_CPI
|
||||
# define MAX_CPI 0x77 // limits to 0--119, should be max cpi/100
|
||||
# define MAX_CPI 0x77
|
||||
#endif
|
||||
|
||||
bool _inBurst = false;
|
||||
|
||||
#ifdef CONSOLE_ENABLE
|
||||
void print_byte(uint8_t byte) { dprintf("%c%c%c%c%c%c%c%c|", (byte & 0x80 ? '1' : '0'), (byte & 0x40 ? '1' : '0'), (byte & 0x20 ? '1' : '0'), (byte & 0x10 ? '1' : '0'), (byte & 0x08 ? '1' : '0'), (byte & 0x04 ? '1' : '0'), (byte & 0x02 ? '1' : '0'), (byte & 0x01 ? '1' : '0')); }
|
||||
void print_byte(uint8_t byte) {
|
||||
dprintf("%c%c%c%c%c%c%c%c|", (byte & 0x80 ? '1' : '0'), (byte & 0x40 ? '1' : '0'), (byte & 0x20 ? '1' : '0'), (byte & 0x10 ? '1' : '0'), (byte & 0x08 ? '1' : '0'), (byte & 0x04 ? '1' : '0'), (byte & 0x02 ? '1' : '0'), (byte & 0x01 ? '1' : '0'));
|
||||
}
|
||||
#endif
|
||||
#define constrain(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt)))
|
||||
|
||||
bool spi_start_adv(void) {
|
||||
bool pmw3360_spi_start(void) {
|
||||
bool status = spi_start(PMW3360_CS_PIN, PMW3360_SPI_LSBFIRST, PMW3360_SPI_MODE, PMW3360_SPI_DIVISOR);
|
||||
// tNCS-SCLK, 120ns
|
||||
wait_us(1);
|
||||
return status;
|
||||
}
|
||||
|
||||
void spi_stop_adv(void) {
|
||||
wait_us(1);
|
||||
spi_stop();
|
||||
}
|
||||
spi_status_t pmw3360_write(uint8_t reg_addr, uint8_t data) {
|
||||
pmw3360_spi_start();
|
||||
|
||||
spi_status_t spi_write_adv(uint8_t reg_addr, uint8_t data) {
|
||||
if (reg_addr != REG_Motion_Burst) {
|
||||
_inBurst = false;
|
||||
}
|
||||
|
||||
spi_start_adv();
|
||||
// send address of the register, with MSBit = 1 to indicate it's a write
|
||||
spi_status_t status = spi_write(reg_addr | 0x80);
|
||||
status = spi_write(data);
|
||||
|
||||
// tSCLK-NCS for write operation
|
||||
wait_us(20);
|
||||
|
||||
// tSWW/tSWR (=120us) minus tSCLK-NCS. Could be shortened, but is looks like a safe lower bound
|
||||
wait_us(100);
|
||||
// tSCLK-NCS for write operation is 35us
|
||||
wait_us(35);
|
||||
spi_stop();
|
||||
|
||||
// tSWW/tSWR (=180us) minus tSCLK-NCS. Could be shortened, but is looks like a safe lower bound
|
||||
wait_us(145);
|
||||
return status;
|
||||
}
|
||||
|
||||
uint8_t spi_read_adv(uint8_t reg_addr) {
|
||||
spi_start_adv();
|
||||
uint8_t pmw3360_read(uint8_t reg_addr) {
|
||||
pmw3360_spi_start();
|
||||
// send adress of the register, with MSBit = 0 to indicate it's a read
|
||||
spi_write(reg_addr & 0x7f);
|
||||
|
||||
// tSRAD (=160us)
|
||||
wait_us(160);
|
||||
uint8_t data = spi_read();
|
||||
|
||||
// tSCLK-NCS for read operation is 120ns
|
||||
wait_us(1);
|
||||
spi_stop();
|
||||
|
||||
// tSRW/tSRR (=20us) minus tSCLK-NCS
|
||||
wait_us(19);
|
||||
|
||||
spi_stop();
|
||||
return data;
|
||||
}
|
||||
|
||||
void pmw3360_set_cpi(uint16_t cpi) {
|
||||
uint8_t cpival = constrain((cpi / 100) - 1, 0, MAX_CPI);
|
||||
|
||||
spi_start_adv();
|
||||
spi_write_adv(REG_Config1, cpival);
|
||||
spi_stop();
|
||||
}
|
||||
|
||||
uint16_t pmw3360_get_cpi(void) {
|
||||
uint8_t cpival = spi_read_adv(REG_Config1);
|
||||
return (uint16_t)((cpival + 1) & 0xFF) * 100;
|
||||
}
|
||||
|
||||
bool pmw3360_init(void) {
|
||||
setPinOutput(PMW3360_CS_PIN);
|
||||
|
||||
@@ -153,42 +143,51 @@ bool pmw3360_init(void) {
|
||||
_inBurst = false;
|
||||
|
||||
spi_stop();
|
||||
spi_start_adv();
|
||||
pmw3360_spi_start();
|
||||
spi_stop();
|
||||
|
||||
spi_write_adv(REG_Shutdown, 0xb6); // Shutdown first
|
||||
pmw3360_write(REG_Shutdown, 0xb6); // Shutdown first
|
||||
wait_ms(300);
|
||||
|
||||
spi_start_adv();
|
||||
pmw3360_spi_start();
|
||||
wait_us(40);
|
||||
spi_stop_adv();
|
||||
spi_stop();
|
||||
wait_us(40);
|
||||
|
||||
spi_write_adv(REG_Power_Up_Reset, 0x5a);
|
||||
// power up, need to first drive NCS high then low, see above.
|
||||
pmw3360_write(REG_Power_Up_Reset, 0x5a);
|
||||
wait_ms(50);
|
||||
|
||||
spi_read_adv(REG_Motion);
|
||||
spi_read_adv(REG_Delta_X_L);
|
||||
spi_read_adv(REG_Delta_X_H);
|
||||
spi_read_adv(REG_Delta_Y_L);
|
||||
spi_read_adv(REG_Delta_Y_H);
|
||||
// read registers and discard
|
||||
pmw3360_read(REG_Motion);
|
||||
pmw3360_read(REG_Delta_X_L);
|
||||
pmw3360_read(REG_Delta_X_H);
|
||||
pmw3360_read(REG_Delta_Y_L);
|
||||
pmw3360_read(REG_Delta_Y_H);
|
||||
|
||||
pmw3360_upload_firmware();
|
||||
|
||||
spi_stop_adv();
|
||||
spi_stop();
|
||||
|
||||
wait_ms(10);
|
||||
pmw3360_set_cpi(PMW3360_CPI);
|
||||
|
||||
wait_ms(1);
|
||||
|
||||
spi_write_adv(REG_Config2, 0x00);
|
||||
pmw3360_write(REG_Config2, 0x00);
|
||||
|
||||
spi_write_adv(REG_Angle_Tune, constrain(ROTATIONAL_TRANSFORM_ANGLE, -30, 30));
|
||||
pmw3360_write(REG_Angle_Tune, constrain(ROTATIONAL_TRANSFORM_ANGLE, -127, 127));
|
||||
|
||||
spi_write_adv(REG_Lift_Config, PMW3360_LIFTOFF_DISTANCE);
|
||||
pmw3360_write(REG_Lift_Config, PMW3360_LIFTOFF_DISTANCE);
|
||||
|
||||
bool init_success = pmw3360_check_signature();
|
||||
#ifdef CONSOLE_ENABLE
|
||||
if (init_success) {
|
||||
dprintf("pmw3360 signature verified");
|
||||
} else {
|
||||
dprintf("pmw3360 signature verification failed!");
|
||||
}
|
||||
#endif
|
||||
|
||||
writePinLow(PMW3360_CS_PIN);
|
||||
|
||||
@@ -196,86 +195,94 @@ bool pmw3360_init(void) {
|
||||
}
|
||||
|
||||
void pmw3360_upload_firmware(void) {
|
||||
spi_write_adv(REG_SROM_Enable, 0x1d);
|
||||
// Datasheet claims we need to disable REST mode first, but during startup
|
||||
// it's already disabled and we're not turning it on ...
|
||||
// pmw3360_write(REG_Config2, 0x00); // disable REST mode
|
||||
pmw3360_write(REG_SROM_Enable, 0x1d);
|
||||
|
||||
wait_ms(10);
|
||||
|
||||
spi_write_adv(REG_SROM_Enable, 0x18);
|
||||
pmw3360_write(REG_SROM_Enable, 0x18);
|
||||
|
||||
spi_start_adv();
|
||||
pmw3360_spi_start();
|
||||
spi_write(REG_SROM_Load_Burst | 0x80);
|
||||
wait_us(15);
|
||||
|
||||
unsigned char c;
|
||||
for (int i = 0; i < FIRMWARE_LENGTH; i++) {
|
||||
c = (unsigned char)pgm_read_byte(firmware_data + i);
|
||||
spi_write(c);
|
||||
for (uint16_t i = 0; i < FIRMWARE_LENGTH; i++) {
|
||||
spi_write(pgm_read_byte(firmware_data + i));
|
||||
#ifndef PMW3360_FIRMWARE_UPLOAD_FAST
|
||||
wait_us(15);
|
||||
#endif
|
||||
}
|
||||
wait_us(200);
|
||||
|
||||
spi_read_adv(REG_SROM_ID);
|
||||
|
||||
spi_write_adv(REG_Config2, 0x00);
|
||||
|
||||
spi_stop();
|
||||
wait_ms(10);
|
||||
pmw3360_read(REG_SROM_ID);
|
||||
pmw3360_write(REG_Config2, 0x00);
|
||||
}
|
||||
|
||||
bool pmw3360_check_signature(void) {
|
||||
uint8_t pid = spi_read_adv(REG_Product_ID);
|
||||
uint8_t iv_pid = spi_read_adv(REG_Inverse_Product_ID);
|
||||
uint8_t SROM_ver = spi_read_adv(REG_SROM_ID);
|
||||
return (pid == firmware_signature[0] && iv_pid == firmware_signature[1] && SROM_ver == firmware_signature[2]); // signature for SROM 0x04
|
||||
uint8_t pid = pmw3360_read(REG_Product_ID);
|
||||
uint8_t iv_pid = pmw3360_read(REG_Inverse_Product_ID);
|
||||
uint8_t SROM_ver = pmw3360_read(REG_SROM_ID);
|
||||
return (pid == firmware_signature[0] && iv_pid == firmware_signature[1] && SROM_ver == firmware_signature[2]); // signature for SROM 0x04
|
||||
}
|
||||
|
||||
uint16_t pmw3360_get_cpi(void) {
|
||||
uint8_t cpival = pmw3360_read(REG_Config1);
|
||||
return (uint16_t)((cpival + 1) & 0xFF) * CPI_STEP;
|
||||
}
|
||||
|
||||
void pmw3360_set_cpi(uint16_t cpi) {
|
||||
uint8_t cpival = constrain((cpi / CPI_STEP) - 1, 0, MAX_CPI);
|
||||
pmw3360_write(REG_Config1, cpival);
|
||||
}
|
||||
|
||||
report_pmw3360_t pmw3360_read_burst(void) {
|
||||
report_pmw3360_t report = {0};
|
||||
|
||||
if (!_inBurst) {
|
||||
#ifdef CONSOLE_ENABLE
|
||||
dprintf("burst on");
|
||||
#endif
|
||||
spi_write_adv(REG_Motion_Burst, 0x00);
|
||||
pmw3360_write(REG_Motion_Burst, 0x00);
|
||||
_inBurst = true;
|
||||
}
|
||||
|
||||
spi_start_adv();
|
||||
pmw3360_spi_start();
|
||||
spi_write(REG_Motion_Burst);
|
||||
wait_us(35); // waits for tSRAD
|
||||
wait_us(35); // waits for tSRAD_MOTBR
|
||||
|
||||
report_pmw3360_t data = {0};
|
||||
report.motion = spi_read();
|
||||
spi_read(); // skip Observation
|
||||
// delta registers
|
||||
report.dx = spi_read();
|
||||
report.mdx = spi_read();
|
||||
report.dy = spi_read();
|
||||
report.mdy = spi_read();
|
||||
|
||||
data.motion = spi_read();
|
||||
spi_write(0x00); // skip Observation
|
||||
data.dx = spi_read();
|
||||
data.mdx = spi_read();
|
||||
data.dy = spi_read();
|
||||
data.mdy = spi_read();
|
||||
if (report.motion & 0b111) { // panic recovery, sometimes burst mode works weird.
|
||||
_inBurst = false;
|
||||
}
|
||||
|
||||
spi_stop();
|
||||
|
||||
#ifdef CONSOLE_ENABLE
|
||||
if (debug_mouse) {
|
||||
print_byte(data.motion);
|
||||
print_byte(data.dx);
|
||||
print_byte(data.mdx);
|
||||
print_byte(data.dy);
|
||||
print_byte(data.mdy);
|
||||
print_byte(report.motion);
|
||||
print_byte(report.dx);
|
||||
print_byte(report.mdx);
|
||||
print_byte(report.dy);
|
||||
print_byte(report.mdy);
|
||||
dprintf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
data.isMotion = (data.motion & 0x80) != 0;
|
||||
data.isOnSurface = (data.motion & 0x08) == 0;
|
||||
data.dx |= (data.mdx << 8);
|
||||
data.dx = data.dx * -1;
|
||||
data.dy |= (data.mdy << 8);
|
||||
data.dy = data.dy * -1;
|
||||
report.isMotion = (report.motion & 0x80) != 0;
|
||||
report.isOnSurface = (report.motion & 0x08) == 0;
|
||||
report.dx |= (report.mdx << 8);
|
||||
report.dx = report.dx * -1;
|
||||
report.dy |= (report.mdy << 8);
|
||||
report.dy = report.dy * -1;
|
||||
|
||||
spi_stop();
|
||||
|
||||
if (data.motion & 0b111) { // panic recovery, sometimes burst mode works weird.
|
||||
_inBurst = false;
|
||||
}
|
||||
|
||||
return data;
|
||||
return report;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user