Merge commit '6d0a62920410f50d7f6707960ca1ca0c8fd1d1fa' into firmware21
This commit is contained in:
1
.github/labeler.yml
vendored
1
.github/labeler.yml
vendored
@@ -22,7 +22,6 @@ keymap:
|
||||
via:
|
||||
- keyboards/**/keymaps/via/*
|
||||
cli:
|
||||
- bin/qmk
|
||||
- requirements.txt
|
||||
- lib/python/**/*
|
||||
python:
|
||||
|
||||
3
.github/workflows/cli.yml
vendored
3
.github/workflows/cli.yml
vendored
@@ -4,11 +4,10 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- future
|
||||
- develop
|
||||
pull_request:
|
||||
paths:
|
||||
- 'lib/python/**'
|
||||
- 'bin/qmk'
|
||||
- 'requirements.txt'
|
||||
- '.github/workflows/cli.yml'
|
||||
|
||||
|
||||
23
.github/workflows/format.yaml
vendored
23
.github/workflows/format.yaml
vendored
@@ -19,7 +19,9 @@ jobs:
|
||||
container: qmkfm/qmk_cli
|
||||
|
||||
steps:
|
||||
- uses: rlespinasse/github-slug-action@v3.x
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
apt-get update && apt-get install -y dos2unix
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
@@ -31,12 +33,19 @@ jobs:
|
||||
output: ' '
|
||||
fileOutput: ' '
|
||||
|
||||
- name: Run qmk format-c and qmk format-python
|
||||
- name: Run qmk formatters
|
||||
shell: 'bash {0}'
|
||||
run: |
|
||||
qmk format-c --core-only -n $(< ~/files.txt)
|
||||
format_c_exit=$?
|
||||
qmk format-python -n
|
||||
format_python_exit=$?
|
||||
cat ~/files_added.txt ~/files_modified.txt > ~/files_changed.txt
|
||||
qmk format-c --core-only $(< ~/files_changed.txt) || true
|
||||
qmk format-python $(< ~/files_changed.txt) || true
|
||||
qmk format-text $(< ~/files_changed.txt) || true
|
||||
|
||||
exit $((format_c_exit + format_python_exit))
|
||||
- name: Fail when formatting required
|
||||
run: |
|
||||
git diff
|
||||
for file in $(git diff --name-only); do
|
||||
echo "File '${file}' Requires Formatting"
|
||||
echo "::error file=${file}::Requires Formatting"
|
||||
done
|
||||
test -z "$(git diff --name-only)"
|
||||
|
||||
49
.github/workflows/format_push.yaml
vendored
Normal file
49
.github/workflows/format_push.yaml
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
name: Lint Format
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
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: Run qmk formatters
|
||||
shell: 'bash {0}'
|
||||
run: |
|
||||
qmk format-c -a
|
||||
qmk format-python -a
|
||||
qmk format-text -a
|
||||
git diff
|
||||
|
||||
- uses: rlespinasse/github-slug-action@v3.x
|
||||
|
||||
- name: Become QMK Bot
|
||||
run: |
|
||||
git config user.name 'QMK Bot'
|
||||
git config user.email 'hello@qmk.fm'
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v3
|
||||
if: ${{ github.repository == 'qmk/qmk_firmware'}}
|
||||
with:
|
||||
token: ${{ secrets.QMK_BOT_TOKEN }}
|
||||
delete-branch: true
|
||||
branch: bugfix/format_${{ env.GITHUB_REF_SLUG }}
|
||||
author: QMK Bot <hello@qmk.fm>
|
||||
committer: QMK Bot <hello@qmk.fm>
|
||||
commit-message: Format code according to conventions
|
||||
title: '[CI] Format code according to conventions'
|
||||
30
.github/workflows/unit_test.yml
vendored
Normal file
30
.github/workflows/unit_test.yml
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
name: Unit Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
pull_request:
|
||||
paths:
|
||||
- 'builddefs/**'
|
||||
- 'quantum/**'
|
||||
- 'platforms/**'
|
||||
- 'tmk_core/**'
|
||||
- 'tests/**'
|
||||
- '*.mk'
|
||||
- 'Makefile'
|
||||
- '.github/workflows/unit_test.yml'
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
container: qmkfm/base_container
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Run tests
|
||||
run: make test:all
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -84,3 +84,8 @@ user_song_list.h
|
||||
/util/win_downloaded
|
||||
/users/
|
||||
/layouts/
|
||||
|
||||
# clangd
|
||||
compile_commands.json
|
||||
.clangd/
|
||||
.cache/
|
||||
|
||||
4
.gitmodules
vendored
4
.gitmodules
vendored
@@ -6,10 +6,6 @@
|
||||
path = lib/chibios-contrib
|
||||
url = https://github.com/qmk/ChibiOS-Contrib
|
||||
branch = master
|
||||
[submodule "lib/ugfx"]
|
||||
path = lib/ugfx
|
||||
url = https://github.com/qmk/uGFX
|
||||
branch = master
|
||||
[submodule "lib/googletest"]
|
||||
path = lib/googletest
|
||||
url = https://github.com/qmk/googletest
|
||||
|
||||
46
Makefile
46
Makefile
@@ -30,11 +30,7 @@ endif
|
||||
endif
|
||||
|
||||
# Determine which qmk cli to use
|
||||
ifeq (,$(shell which qmk))
|
||||
QMK_BIN = bin/qmk
|
||||
else
|
||||
QMK_BIN = qmk
|
||||
endif
|
||||
QMK_BIN := qmk
|
||||
|
||||
# avoid 'Entering|Leaving directory' messages
|
||||
MAKEFLAGS += --no-print-directory
|
||||
@@ -58,8 +54,6 @@ BUILD_DIR := $(ROOT_DIR)/.build
|
||||
TEST_DIR := $(BUILD_DIR)/test
|
||||
ERROR_FILE := $(BUILD_DIR)/error_occurred
|
||||
|
||||
MAKEFILE_INCLUDED=yes
|
||||
|
||||
# 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
|
||||
@@ -97,31 +91,8 @@ distclean: clean
|
||||
rm -f *.bin *.hex *.uf2
|
||||
echo 'done.'
|
||||
|
||||
#Compatibility with the old make variables, anything you specify directly on the command line
|
||||
# always overrides the detected folders
|
||||
ifdef keyboard
|
||||
KEYBOARD := $(keyboard)
|
||||
endif
|
||||
ifdef keymap
|
||||
KEYMAP := $(keymap)
|
||||
endif
|
||||
|
||||
# Uncomment these for debugging
|
||||
# $(info Keyboard: $(KEYBOARD))
|
||||
# $(info Keymap: $(KEYMAP))
|
||||
|
||||
|
||||
# Set the default goal depending on where we are running make from
|
||||
# this handles the case where you run make without any arguments
|
||||
.DEFAULT_GOAL := all:all
|
||||
ifneq ($(KEYMAP),)
|
||||
.DEFAULT_GOAL := $(KEYBOARD):$(KEYMAP)
|
||||
else ifneq ($(KEYBOARD),)
|
||||
# Inside a keyboard folder, build all keymaps for all subprojects
|
||||
# Note that this is different from the old behaviour, which would
|
||||
# build only the default keymap of the default keyboard
|
||||
.DEFAULT_GOAL := $(KEYBOARD):all
|
||||
endif
|
||||
|
||||
|
||||
# Compare the start of the RULE variable with the first argument($1)
|
||||
@@ -257,10 +228,6 @@ define PARSE_RULE
|
||||
else ifeq ($$(call TRY_TO_MATCH_RULE_FROM_LIST,$$(shell util/list_keyboards.sh | sort -u)),true)
|
||||
KEYBOARD_RULE=$$(MATCHED_ITEM)
|
||||
$$(eval $$(call PARSE_KEYBOARD,$$(MATCHED_ITEM)))
|
||||
# Otherwise use the KEYBOARD variable, which is determined either by
|
||||
# the current directory you run make from, or passed in as an argument
|
||||
else ifneq ($$(KEYBOARD),)
|
||||
$$(eval $$(call PARSE_KEYBOARD,$$(KEYBOARD)))
|
||||
else
|
||||
$$(info make: *** No rule to make target '$1'. Stop.)
|
||||
$$(info |)
|
||||
@@ -423,11 +390,12 @@ define PARSE_ALL_KEYMAPS
|
||||
endef
|
||||
|
||||
define BUILD_TEST
|
||||
TEST_NAME := $1
|
||||
TEST_PATH := $1
|
||||
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_VARS := TEST=$$(TEST_NAME) FULL_TESTS="$$(FULL_TESTS)"
|
||||
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)
|
||||
@@ -451,7 +419,7 @@ define PARSE_TEST
|
||||
ifeq ($$(TEST_NAME),all)
|
||||
MATCHED_TESTS := $$(TEST_LIST)
|
||||
else
|
||||
MATCHED_TESTS := $$(foreach TEST,$$(TEST_LIST),$$(if $$(findstring $$(TEST_NAME),$$(TEST)),$$(TEST),))
|
||||
MATCHED_TESTS := $$(foreach TEST, $$(TEST_LIST),$$(if $$(findstring $$(TEST_NAME), $$(notdir $$(TEST))), $$(TEST),))
|
||||
endif
|
||||
$$(foreach TEST,$$(MATCHED_TESTS),$$(eval $$(call BUILD_TEST,$$(TEST),$$(TEST_TARGET))))
|
||||
endef
|
||||
@@ -470,7 +438,8 @@ define SET_SILENT_MODE
|
||||
endif
|
||||
endef
|
||||
|
||||
include $(ROOT_DIR)/message.mk
|
||||
include paths.mk
|
||||
include $(BUILDDEFS_PATH)/message.mk
|
||||
|
||||
ifeq ($(strip $(BREAK_ON_ERRORS)), yes)
|
||||
HANDLE_ERROR = exit 1
|
||||
@@ -506,7 +475,6 @@ endef
|
||||
ifndef SKIP_GIT
|
||||
if [ ! -e lib/chibios ]; then git submodule sync lib/chibios && git submodule update --depth 50 --init lib/chibios; fi
|
||||
if [ ! -e lib/chibios-contrib ]; then git submodule sync lib/chibios-contrib && git submodule update --depth 50 --init lib/chibios-contrib; fi
|
||||
if [ ! -e lib/ugfx ]; then git submodule sync lib/ugfx && git submodule update --depth 50 --init lib/ugfx; fi
|
||||
if [ ! -e lib/lufa ]; then git submodule sync lib/lufa && git submodule update --depth 50 --init lib/lufa; fi
|
||||
if [ ! -e lib/vusb ]; then git submodule sync lib/vusb && git submodule update --depth 50 --init lib/vusb; fi
|
||||
if [ ! -e lib/printf ]; then git submodule sync lib/printf && git submodule update --depth 50 --init lib/printf; fi
|
||||
|
||||
58
bin/qmk
58
bin/qmk
@@ -1,58 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""CLI wrapper for running QMK commands.
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Add the QMK python libs to our path
|
||||
script_dir = Path(os.path.realpath(__file__)).parent
|
||||
qmk_dir = script_dir.parent
|
||||
python_lib_dir = Path(qmk_dir / 'lib' / 'python').resolve()
|
||||
sys.path.append(str(python_lib_dir))
|
||||
|
||||
# Setup the CLI
|
||||
import milc # noqa
|
||||
|
||||
milc.EMOJI_LOGLEVELS['INFO'] = '{fg_blue}Ψ{style_reset_all}'
|
||||
|
||||
|
||||
@milc.cli.entrypoint('QMK Helper Script')
|
||||
def qmk_main(cli):
|
||||
"""The function that gets run when no subcommand is provided.
|
||||
"""
|
||||
cli.print_help()
|
||||
|
||||
|
||||
def main():
|
||||
"""Setup our environment and then call the CLI entrypoint.
|
||||
"""
|
||||
# Change to the root of our checkout
|
||||
os.environ['ORIG_CWD'] = os.getcwd()
|
||||
os.environ['DEPRECATED_BIN_QMK'] = '1'
|
||||
os.chdir(qmk_dir)
|
||||
|
||||
print('Warning: The bin/qmk script is being deprecated. Please install the QMK CLI: python3 -m pip install qmk', file=sys.stderr)
|
||||
|
||||
# Import the subcommands
|
||||
import milc.subcommand.config # noqa
|
||||
import qmk.cli # noqa
|
||||
|
||||
# Execute
|
||||
return_code = milc.cli()
|
||||
|
||||
if return_code is False:
|
||||
exit(1)
|
||||
|
||||
elif return_code is not True and isinstance(return_code, int):
|
||||
if return_code < 0 or return_code > 255:
|
||||
milc.cli.log.error('Invalid return_code: %d', return_code)
|
||||
exit(255)
|
||||
|
||||
exit(return_code)
|
||||
|
||||
exit(0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -13,21 +13,24 @@
|
||||
# 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 $(TMK_PATH)/protocol.mk
|
||||
$(TEST)_INC := \
|
||||
tests\test_common\common_config.h
|
||||
|
||||
TEST_PATH=tests/$(TEST)
|
||||
|
||||
$(TEST)_SRC= \
|
||||
$(TEST_PATH)/keymap.c \
|
||||
$(TEST)_SRC := \
|
||||
$(TMK_COMMON_SRC) \
|
||||
$(QUANTUM_SRC) \
|
||||
$(SRC) \
|
||||
tests/test_common/keymap.c \
|
||||
tests/test_common/matrix.c \
|
||||
tests/test_common/test_driver.cpp \
|
||||
tests/test_common/keyboard_report_util.cpp \
|
||||
tests/test_common/test_fixture.cpp
|
||||
$(TEST)_SRC += $(patsubst $(ROOTDIR)/%,%,$(wildcard $(TEST_PATH)/*.cpp))
|
||||
tests/test_common/test_fixture.cpp \
|
||||
tests/test_common/test_keymap_key.cpp \
|
||||
tests/test_common/test_logger.cpp \
|
||||
$(patsubst $(ROOTDIR)/%,%,$(wildcard $(TEST_PATH)/*.cpp))
|
||||
|
||||
$(TEST)_DEFS := $(TMK_COMMON_DEFS) $(OPT_DEFS)
|
||||
|
||||
$(TEST)_CONFIG := $(TEST_PATH)/config.h
|
||||
|
||||
$(TEST)_DEFS=$(TMK_COMMON_DEFS) $(OPT_DEFS)
|
||||
$(TEST)_CONFIG=$(TEST_PATH)/config.h
|
||||
VPATH += $(TOP_DIR)/tests/test_common
|
||||
@@ -10,7 +10,8 @@ endif
|
||||
|
||||
.DEFAULT_GOAL := all
|
||||
|
||||
include common.mk
|
||||
include paths.mk
|
||||
include $(BUILDDEFS_PATH)/message.mk
|
||||
|
||||
# Set the qmk cli to use
|
||||
QMK_BIN ?= qmk
|
||||
@@ -32,20 +33,6 @@ endif
|
||||
# this an empty or blank macro!
|
||||
KEYMAP_OUTPUT := $(BUILD_DIR)/obj_$(TARGET)
|
||||
|
||||
# For split boards we need to set a master half.
|
||||
MASTER ?= left
|
||||
ifdef master
|
||||
MASTER = $(master)
|
||||
endif
|
||||
|
||||
ifeq ($(MASTER),right)
|
||||
OPT_DEFS += -DMASTER_IS_ON_RIGHT
|
||||
else
|
||||
ifneq ($(MASTER),left)
|
||||
$(error MASTER does not have a valid value(left/right))
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef SKIP_VERSION
|
||||
OPT_DEFS += -DSKIP_VERSION
|
||||
endif
|
||||
@@ -115,6 +102,7 @@ include $(INFO_RULES_MK)
|
||||
# Check for keymap.json first, so we can regenerate keymap.c
|
||||
include build_json.mk
|
||||
|
||||
# Pull in keymap level rules.mk
|
||||
ifeq ("$(wildcard $(KEYMAP_PATH))", "")
|
||||
# Look through the possible keymap folders until we find a matching keymap.c
|
||||
ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_5)/keymap.c)","")
|
||||
@@ -177,7 +165,7 @@ ifeq ($(strip $(CONVERT_TO_PROTON_C)), yes)
|
||||
include platforms/chibios/boards/QMK_PROTON_C/convert_to_proton_c.mk
|
||||
endif
|
||||
|
||||
include quantum/mcu_selection.mk
|
||||
include $(BUILDDEFS_PATH)/mcu_selection.mk
|
||||
|
||||
# Find all the C source files to be compiled in subfolders.
|
||||
KEYBOARD_SRC :=
|
||||
@@ -345,6 +333,7 @@ ifeq ("$(USER_NAME)","")
|
||||
endif
|
||||
USER_PATH := users/$(USER_NAME)
|
||||
|
||||
# Pull in user level rules.mk
|
||||
-include $(USER_PATH)/rules.mk
|
||||
ifneq ("$(wildcard $(USER_PATH)/config.h)","")
|
||||
CONFIG_H += $(USER_PATH)/config.h
|
||||
@@ -354,7 +343,24 @@ ifneq ("$(wildcard $(USER_PATH)/post_config.h)","")
|
||||
endif
|
||||
|
||||
# Disable features that a keyboard doesn't support
|
||||
-include disable_features.mk
|
||||
-include $(BUILDDEFS_PATH)/disable_features.mk
|
||||
|
||||
# Pull in post_rules.mk files from all our subfolders
|
||||
ifneq ("$(wildcard $(KEYBOARD_PATH_1)/post_rules.mk)","")
|
||||
include $(KEYBOARD_PATH_1)/post_rules.mk
|
||||
endif
|
||||
ifneq ("$(wildcard $(KEYBOARD_PATH_2)/post_rules.mk)","")
|
||||
include $(KEYBOARD_PATH_2)/post_rules.mk
|
||||
endif
|
||||
ifneq ("$(wildcard $(KEYBOARD_PATH_3)/post_rules.mk)","")
|
||||
include $(KEYBOARD_PATH_3)/post_rules.mk
|
||||
endif
|
||||
ifneq ("$(wildcard $(KEYBOARD_PATH_4)/post_rules.mk)","")
|
||||
include $(KEYBOARD_PATH_4)/post_rules.mk
|
||||
endif
|
||||
ifneq ("$(wildcard $(KEYBOARD_PATH_5)/post_rules.mk)","")
|
||||
include $(KEYBOARD_PATH_5)/post_rules.mk
|
||||
endif
|
||||
|
||||
ifneq ("$(wildcard $(KEYMAP_PATH)/config.h)","")
|
||||
CONFIG_H += $(KEYMAP_PATH)/config.h
|
||||
@@ -380,9 +386,10 @@ VPATH += $(KEYBOARD_PATHS)
|
||||
VPATH += $(COMMON_VPATH)
|
||||
|
||||
include common_features.mk
|
||||
include $(BUILDDEFS_PATH)/generic_features.mk
|
||||
include $(TMK_PATH)/protocol.mk
|
||||
include $(TMK_PATH)/common.mk
|
||||
include bootloader.mk
|
||||
include $(PLATFORM_PATH)/common.mk
|
||||
include $(BUILDDEFS_PATH)/bootloader.mk
|
||||
|
||||
SRC += $(patsubst %.c,%.clib,$(LIB_SRC))
|
||||
SRC += $(patsubst %.c,%.clib,$(QUANTUM_LIB_SRC))
|
||||
@@ -397,39 +404,34 @@ ifneq ($(REQUIRE_PLATFORM_KEY),)
|
||||
endif
|
||||
endif
|
||||
|
||||
include $(TMK_PATH)/$(PLATFORM_KEY).mk
|
||||
include $(PLATFORM_PATH)/$(PLATFORM_KEY)/platform.mk
|
||||
-include $(PLATFORM_PATH)/$(PLATFORM_KEY)/flash.mk
|
||||
|
||||
ifneq ($(strip $(PROTOCOL)),)
|
||||
include $(TMK_PATH)/protocol/$(strip $(shell echo $(PROTOCOL) | tr '[:upper:]' '[:lower:]')).mk
|
||||
else
|
||||
include $(TMK_PATH)/protocol/$(PLATFORM_KEY).mk
|
||||
endif
|
||||
-include $(TOP_DIR)/platforms/$(PLATFORM_KEY)/flash.mk
|
||||
|
||||
# TODO: remove this bodge?
|
||||
PROJECT_DEFS := $(OPT_DEFS)
|
||||
PROJECT_INC := $(VPATH) $(EXTRAINCDIRS) $(KEYBOARD_PATHS)
|
||||
PROJECT_CONFIG := $(CONFIG_H)
|
||||
|
||||
ifeq ($(strip $(VISUALIZER_ENABLE)), yes)
|
||||
VISUALIZER_DIR = $(QUANTUM_DIR)/visualizer
|
||||
VISUALIZER_PATH = $(QUANTUM_PATH)/visualizer
|
||||
include $(VISUALIZER_PATH)/visualizer.mk
|
||||
endif
|
||||
|
||||
CONFIG_H += $(POST_CONFIG_H)
|
||||
ALL_CONFIGS := $(PROJECT_CONFIG) $(CONFIG_H)
|
||||
|
||||
OUTPUTS := $(KEYMAP_OUTPUT) $(KEYBOARD_OUTPUT)
|
||||
$(KEYMAP_OUTPUT)_SRC := $(SRC)
|
||||
$(KEYMAP_OUTPUT)_DEFS := $(OPT_DEFS) $(GFXDEFS) \
|
||||
$(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
|
||||
$(KEYMAP_OUTPUT)_INC := $(VPATH) $(EXTRAINCDIRS)
|
||||
$(KEYMAP_OUTPUT)_CONFIG := $(CONFIG_H)
|
||||
$(KEYBOARD_OUTPUT)_SRC := $(CHIBISRC) $(GFXSRC)
|
||||
$(KEYBOARD_OUTPUT)_DEFS := $(PROJECT_DEFS) $(GFXDEFS)
|
||||
$(KEYBOARD_OUTPUT)_INC := $(PROJECT_INC) $(GFXINC)
|
||||
$(KEYBOARD_OUTPUT)_SRC := $(PLATFORM_SRC)
|
||||
$(KEYBOARD_OUTPUT)_DEFS := $(PROJECT_DEFS)
|
||||
$(KEYBOARD_OUTPUT)_INC := $(PROJECT_INC)
|
||||
$(KEYBOARD_OUTPUT)_CONFIG := $(PROJECT_CONFIG)
|
||||
|
||||
# Default target.
|
||||
@@ -445,7 +447,7 @@ check-size: build
|
||||
check-md5: build
|
||||
objs-size: build
|
||||
|
||||
include show_options.mk
|
||||
include $(BUILDDEFS_PATH)/show_options.mk
|
||||
include $(TMK_PATH)/rules.mk
|
||||
|
||||
# Ensure we have generated files available for each of the objects
|
||||
|
||||
@@ -4,7 +4,8 @@ endif
|
||||
|
||||
.DEFAULT_GOAL := all
|
||||
|
||||
include common.mk
|
||||
include paths.mk
|
||||
include $(BUILDDEFS_PATH)/message.mk
|
||||
|
||||
TARGET=test/$(TEST)
|
||||
|
||||
@@ -16,7 +17,7 @@ OUTPUTS := $(TEST_OBJ)/$(TEST) $(GTEST_OUTPUT)
|
||||
|
||||
GTEST_INC := \
|
||||
$(LIB_PATH)/googletest/googletest/include \
|
||||
$(LIB_PATH)/googletest/googlemock/include\
|
||||
$(LIB_PATH)/googletest/googlemock/include
|
||||
|
||||
GTEST_INTERNAL_INC := \
|
||||
$(LIB_PATH)/googletest/googletest \
|
||||
@@ -48,15 +49,18 @@ CONSOLE_ENABLE = yes
|
||||
endif
|
||||
|
||||
ifneq ($(filter $(FULL_TESTS),$(TEST)),)
|
||||
include tests/$(TEST)/rules.mk
|
||||
include tests/test_common/build.mk
|
||||
include $(TEST_PATH)/test.mk
|
||||
endif
|
||||
|
||||
include common_features.mk
|
||||
include $(TMK_PATH)/common.mk
|
||||
include $(BUILDDEFS_PATH)/generic_features.mk
|
||||
include $(PLATFORM_PATH)/common.mk
|
||||
include $(TMK_PATH)/protocol.mk
|
||||
include $(QUANTUM_PATH)/debounce/tests/rules.mk
|
||||
include $(QUANTUM_PATH)/encoder/tests/rules.mk
|
||||
include $(QUANTUM_PATH)/sequencer/tests/rules.mk
|
||||
include $(QUANTUM_PATH)/serial_link/tests/rules.mk
|
||||
include $(TMK_PATH)/common/test/rules.mk
|
||||
include $(PLATFORM_PATH)/test/rules.mk
|
||||
ifneq ($(filter $(FULL_TESTS),$(TEST)),)
|
||||
include build_full_test.mk
|
||||
endif
|
||||
@@ -71,7 +75,7 @@ $(TEST_OBJ)/$(TEST)_INC := $($(TEST)_INC) $(VPATH) $(GTEST_INC)
|
||||
$(TEST_OBJ)/$(TEST)_DEFS := $($(TEST)_DEFS)
|
||||
$(TEST_OBJ)/$(TEST)_CONFIG := $($(TEST)_CONFIG)
|
||||
|
||||
include $(TMK_PATH)/native.mk
|
||||
include $(PLATFORM_PATH)/$(PLATFORM_KEY)/platform.mk
|
||||
include $(TMK_PATH)/rules.mk
|
||||
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
# stm32duino STM32Duino (STM32F103x8)
|
||||
# stm32-dfu STM32 USB DFU in ROM
|
||||
# apm32-dfu APM32 USB DFU in ROM
|
||||
# RISC-V:
|
||||
# gd32v-dfu GD32V USB DFU in ROM
|
||||
#
|
||||
# BOOTLOADER_SIZE can still be defined manually, but it's recommended
|
||||
# you add any possible configuration to this list
|
||||
@@ -125,6 +127,13 @@ ifeq ($(strip $(BOOTLOADER)), apm32-dfu)
|
||||
DFU_ARGS ?= -d 314B:0106 -a 0 -s 0x08000000:leave
|
||||
DFU_SUFFIX_ARGS ?= -v 314B -p 0106
|
||||
endif
|
||||
ifeq ($(strip $(BOOTLOADER)), gd32v-dfu)
|
||||
OPT_DEFS += -DBOOTLOADER_GD32V_DFU
|
||||
|
||||
# Options to pass to dfu-util when flashing
|
||||
DFU_ARGS ?= -d 28E9:0189 -a 0 -s 0x08000000:leave
|
||||
DFU_SUFFIX_ARGS ?= -v 28E9 -p 0189
|
||||
endif
|
||||
ifeq ($(strip $(BOOTLOADER)), kiibohd)
|
||||
OPT_DEFS += -DBOOTLOADER_KIIBOHD
|
||||
ifeq ($(strip $(MCU_ORIG)), MK20DX128)
|
||||
@@ -1,7 +1,6 @@
|
||||
# Unconditionally disable features that a keyboard advertises it doesn't support
|
||||
|
||||
FEATURE_NAMES :=
|
||||
FEATURE_NAMES += ADAFRUIT_BLE
|
||||
FEATURE_NAMES += AUDIO
|
||||
FEATURE_NAMES += BACKLIGHT
|
||||
FEATURE_NAMES += BLUETOOTH
|
||||
@@ -20,10 +19,8 @@ FEATURE_NAMES += PS2_MOUSE
|
||||
FEATURE_NAMES += RGBLIGHT
|
||||
FEATURE_NAMES += RGB_MATRIX
|
||||
FEATURE_NAMES += SLEEP_LED
|
||||
FEATURE_NAMES += SERIAL_LINK
|
||||
FEATURE_NAMES += STENO
|
||||
FEATURE_NAMES += SWAP_HANDS
|
||||
FEATURE_NAMES += VISUALIZER
|
||||
FEATURE_NAMES += WATCHDOG
|
||||
FEATURE_NAMES += XT
|
||||
|
||||
52
builddefs/generic_features.mk
Normal file
52
builddefs/generic_features.mk
Normal file
@@ -0,0 +1,52 @@
|
||||
# Copyright 2021 QMK
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
SPACE_CADET_ENABLE ?= yes
|
||||
GRAVE_ESC_ENABLE ?= yes
|
||||
|
||||
GENERIC_FEATURES = \
|
||||
COMBO \
|
||||
COMMAND \
|
||||
DEFERRED_EXEC \
|
||||
DIGITIZER \
|
||||
DIP_SWITCH \
|
||||
DYNAMIC_KEYMAP \
|
||||
DYNAMIC_MACRO \
|
||||
ENCODER \
|
||||
GRAVE_ESC \
|
||||
HAPTIC \
|
||||
KEY_LOCK \
|
||||
KEY_OVERRIDE \
|
||||
LEADER \
|
||||
PROGRAMMABLE_BUTTON \
|
||||
SPACE_CADET \
|
||||
SWAP_HANDS \
|
||||
TAP_DANCE \
|
||||
VELOCIKEY \
|
||||
WPM \
|
||||
DYNAMIC_TAPPING_TERM \
|
||||
|
||||
define HANDLE_GENERIC_FEATURE
|
||||
# $$(info "Processing: $1_ENABLE $2.c")
|
||||
SRC += $$(wildcard $$(QUANTUM_DIR)/process_keycode/process_$2.c)
|
||||
SRC += $$(wildcard $$(QUANTUM_DIR)/$2.c)
|
||||
OPT_DEFS += -D$1_ENABLE
|
||||
endef
|
||||
|
||||
$(foreach F,$(GENERIC_FEATURES),\
|
||||
$(if $(filter yes, $(strip $($(F)_ENABLE))),\
|
||||
$(eval $(call HANDLE_GENERIC_FEATURE,$(F),$(shell echo $(F) | tr '[:upper:]' '[:lower:]'))) \
|
||||
) \
|
||||
)
|
||||
@@ -81,7 +81,7 @@ ifneq ($(findstring MK20DX256, $(MCU)),)
|
||||
BOARD ?= PJRC_TEENSY_3_1
|
||||
endif
|
||||
|
||||
ifneq ($(findstring MK66F18, $(MCU)),)
|
||||
ifneq ($(findstring MK66FX1M0, $(MCU)),)
|
||||
# Cortex version
|
||||
MCU = cortex-m4
|
||||
|
||||
@@ -122,7 +122,7 @@ ifneq ($(findstring STM32F042, $(MCU)),)
|
||||
MCU_SERIES = STM32F0xx
|
||||
|
||||
# Linker script to use
|
||||
# - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
|
||||
# - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/
|
||||
# or <keyboard_dir>/ld/
|
||||
MCU_LDSCRIPT ?= STM32F042x6
|
||||
|
||||
@@ -138,6 +138,11 @@ ifneq ($(findstring STM32F042, $(MCU)),)
|
||||
|
||||
# UF2 settings
|
||||
UF2_FAMILY ?= STM32F0
|
||||
|
||||
# Stack sizes: Since this chip has limited RAM capacity, the stack area needs to be reduced.
|
||||
# This ensures that the EEPROM page buffer fits into RAM
|
||||
USE_PROCESS_STACKSIZE = 0x600
|
||||
USE_EXCEPTIONS_STACKSIZE = 0x300
|
||||
endif
|
||||
|
||||
ifneq ($(findstring STM32F072, $(MCU)),)
|
||||
@@ -154,7 +159,7 @@ ifneq ($(findstring STM32F072, $(MCU)),)
|
||||
MCU_SERIES = STM32F0xx
|
||||
|
||||
# Linker script to use
|
||||
# - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
|
||||
# - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/
|
||||
# or <keyboard_dir>/ld/
|
||||
MCU_LDSCRIPT ?= STM32F072xB
|
||||
|
||||
@@ -186,7 +191,7 @@ ifneq ($(findstring STM32F103, $(MCU)),)
|
||||
MCU_SERIES = STM32F1xx
|
||||
|
||||
# Linker script to use
|
||||
# - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
|
||||
# - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/
|
||||
# or <keyboard_dir>/ld/
|
||||
MCU_LDSCRIPT ?= STM32F103x8
|
||||
|
||||
@@ -218,7 +223,7 @@ ifneq ($(findstring STM32F303, $(MCU)),)
|
||||
MCU_SERIES = STM32F3xx
|
||||
|
||||
# Linker script to use
|
||||
# - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
|
||||
# - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/
|
||||
# or <keyboard_dir>/ld/
|
||||
MCU_LDSCRIPT ?= STM32F303xC
|
||||
|
||||
@@ -250,7 +255,7 @@ ifneq ($(findstring STM32F401, $(MCU)),)
|
||||
MCU_SERIES = STM32F4xx
|
||||
|
||||
# Linker script to use
|
||||
# - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
|
||||
# - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/
|
||||
# or <keyboard_dir>/ld/
|
||||
ifeq ($(strip $(BOOTLOADER)), tinyuf2)
|
||||
MCU_LDSCRIPT ?= STM32F401xC_tinyuf2
|
||||
@@ -273,7 +278,7 @@ ifneq ($(findstring STM32F401, $(MCU)),)
|
||||
UF2_FAMILY ?= STM32F4
|
||||
endif
|
||||
|
||||
ifneq ($(findstring STM32F407, $(MCU)),)
|
||||
ifneq ($(findstring STM32F405, $(MCU)),)
|
||||
# Cortex version
|
||||
MCU = cortex-m4
|
||||
|
||||
@@ -289,6 +294,38 @@ ifneq ($(findstring STM32F407, $(MCU)),)
|
||||
# Linker script to use
|
||||
# - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
|
||||
# or <keyboard_dir>/ld/
|
||||
MCU_LDSCRIPT ?= STM32F405xG
|
||||
|
||||
# Startup code to use
|
||||
# - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/
|
||||
MCU_STARTUP ?= stm32f4xx
|
||||
|
||||
# Board: it should exist either in <chibios>/os/hal/boards/,
|
||||
# <keyboard_dir>/boards/, or drivers/boards/
|
||||
BOARD ?= GENERIC_STM32_F405XG
|
||||
|
||||
USE_FPU ?= yes
|
||||
|
||||
# UF2 settings
|
||||
UF2_FAMILY ?= STM32F4
|
||||
endif
|
||||
|
||||
ifneq ($(findstring STM32F407, $(MCU)),)
|
||||
# Cortex version
|
||||
MCU = cortex-m4
|
||||
|
||||
# ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7
|
||||
ARMV = 7
|
||||
|
||||
## chip/board settings
|
||||
# - the next two should match the directories in
|
||||
# <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
|
||||
MCU_FAMILY = STM32
|
||||
MCU_SERIES = STM32F4xx
|
||||
|
||||
# Linker script to use
|
||||
# - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/
|
||||
# or <keyboard_dir>/ld/
|
||||
MCU_LDSCRIPT ?= STM32F407xE
|
||||
|
||||
# Startup code to use
|
||||
@@ -319,7 +356,7 @@ ifneq ($(findstring STM32F411, $(MCU)),)
|
||||
MCU_SERIES = STM32F4xx
|
||||
|
||||
# Linker script to use
|
||||
# - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
|
||||
# - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/
|
||||
# or <keyboard_dir>/ld/
|
||||
ifeq ($(strip $(BOOTLOADER)), tinyuf2)
|
||||
MCU_LDSCRIPT ?= STM32F411xE_tinyuf2
|
||||
@@ -356,8 +393,7 @@ ifneq ($(findstring STM32F446, $(MCU)),)
|
||||
MCU_SERIES = STM32F4xx
|
||||
|
||||
# Linker script to use
|
||||
# - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
|
||||
# or <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/
|
||||
# - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/
|
||||
# or <keyboard_dir>/ld/
|
||||
MCU_LDSCRIPT ?= STM32F446xE
|
||||
|
||||
@@ -386,7 +422,7 @@ ifneq ($(findstring STM32G431, $(MCU)),)
|
||||
MCU_SERIES = STM32G4xx
|
||||
|
||||
# Linker script to use
|
||||
# - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
|
||||
# - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/
|
||||
# or <keyboard_dir>/ld/
|
||||
MCU_LDSCRIPT ?= STM32G431xB
|
||||
|
||||
@@ -418,7 +454,7 @@ ifneq ($(findstring STM32G474, $(MCU)),)
|
||||
MCU_SERIES = STM32G4xx
|
||||
|
||||
# Linker script to use
|
||||
# - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
|
||||
# - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/
|
||||
# or <keyboard_dir>/ld/
|
||||
MCU_LDSCRIPT ?= STM32G474xE
|
||||
|
||||
@@ -450,7 +486,7 @@ ifneq (,$(filter $(MCU),STM32L433 STM32L443))
|
||||
MCU_SERIES = STM32L4xx
|
||||
|
||||
# Linker script to use
|
||||
# - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
|
||||
# - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/
|
||||
# or <keyboard_dir>/ld/
|
||||
MCU_LDSCRIPT ?= STM32L432xC
|
||||
|
||||
@@ -484,7 +520,7 @@ ifneq (,$(filter $(MCU),STM32L412 STM32L422))
|
||||
MCU_SERIES = STM32L4xx
|
||||
|
||||
# Linker script to use
|
||||
# - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
|
||||
# - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/
|
||||
# or <keyboard_dir>/ld/
|
||||
MCU_LDSCRIPT ?= STM32L412xB
|
||||
|
||||
@@ -504,6 +540,66 @@ ifneq (,$(filter $(MCU),STM32L412 STM32L422))
|
||||
UF2_FAMILY ?= STM32L4
|
||||
endif
|
||||
|
||||
ifneq ($(findstring WB32F3G71, $(MCU)),)
|
||||
# Cortex version
|
||||
MCU = cortex-m3
|
||||
|
||||
# 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 = WB32
|
||||
MCU_SERIES = WB32F3G71xx
|
||||
|
||||
# Linker script to use
|
||||
# - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
|
||||
# or <keyboard_dir>/ld/
|
||||
MCU_LDSCRIPT ?= WB32F3G71x9
|
||||
|
||||
# Startup code to use
|
||||
# - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/
|
||||
MCU_STARTUP ?= wb32f3g71xx
|
||||
|
||||
# Board: it should exist either in <chibios>/os/hal/boards/,
|
||||
# <keyboard_dir>/boards/, or drivers/boards/
|
||||
BOARD ?= GENERIC_WB32_F3G71XX
|
||||
|
||||
USE_FPU ?= no
|
||||
endif
|
||||
|
||||
ifneq ($(findstring GD32VF103, $(MCU)),)
|
||||
# RISC-V
|
||||
MCU = risc-v
|
||||
|
||||
# RISC-V extensions and abi configuration
|
||||
MCU_ARCH = rv32imac
|
||||
MCU_ABI = ilp32
|
||||
MCU_CMODEL = medlow
|
||||
|
||||
## chip/board settings
|
||||
# - the next two should match the directories in
|
||||
# <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
|
||||
MCU_FAMILY = GD32V
|
||||
MCU_SERIES = GD32VF103
|
||||
|
||||
# Linker script to use
|
||||
# - it should exist either in <chibios>/os/common/startup/RISCV-ECLIC/compilers/GCC/ld/
|
||||
# or <keyboard_dir>/ld/
|
||||
MCU_LDSCRIPT ?= GD32VF103xB
|
||||
|
||||
# Startup code to use
|
||||
# - it should exist in <chibios>/os/common/startup/RISCV-ECLIC/compilers/GCC/mk/
|
||||
MCU_STARTUP ?= gd32vf103
|
||||
|
||||
# Board: it should exist either in <chibios>/os/hal/boards/,
|
||||
# <keyboard_dir>/boards/, or drivers/boards/
|
||||
BOARD ?= SIPEED_LONGAN_NANO
|
||||
|
||||
USE_FPU ?= no
|
||||
endif
|
||||
|
||||
ifneq (,$(filter $(MCU),at90usb162 atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647 at90usb1286 at90usb1287))
|
||||
PROTOCOL = LUFA
|
||||
|
||||
@@ -21,17 +21,15 @@ HARDWARE_OPTION_NAMES = \
|
||||
RGBLIGHT_CUSTOM_DRIVER \
|
||||
RGB_MATRIX_ENABLE \
|
||||
RGB_MATRIX_DRIVER \
|
||||
SERIAL_LINK_ENABLE \
|
||||
CIE1931_CURVE \
|
||||
MIDI_ENABLE \
|
||||
BLUETOOTH_ENABLE \
|
||||
BLUETOOTH_DRIVER \
|
||||
AUDIO_ENABLE \
|
||||
HD44780_ENABLE \
|
||||
ENCODER_ENABLE \
|
||||
LCD_ENABLE \
|
||||
LED_TABLES \
|
||||
POINTING_DEVICE_ENABLE \
|
||||
VISUALIZER_ENABLE \
|
||||
DIP_SWITCH_ENABLE
|
||||
|
||||
OTHER_OPTION_NAMES = \
|
||||
@@ -39,9 +37,9 @@ OTHER_OPTION_NAMES = \
|
||||
UCIS_ENABLE \
|
||||
UNICODEMAP_ENABLE \
|
||||
UNICODE_COMMON \
|
||||
API_SYSEX_ENABLE \
|
||||
AUTO_SHIFT_ENABLE \
|
||||
AUTO_SHIFT_MODIFIERS \
|
||||
DYNAMIC_TAPPING_TERM_ENABLE \
|
||||
COMBO_ENABLE \
|
||||
KEY_LOCK_ENABLE \
|
||||
KEY_OVERRIDE_ENABLE \
|
||||
@@ -57,7 +55,6 @@ OTHER_OPTION_NAMES = \
|
||||
LED_ANIMATIONS \
|
||||
IOS_DEVICE_ENABLE \
|
||||
HELIX ZINC \
|
||||
ADAFRUIT_BLE_ENABLE \
|
||||
AUTOLOG_ENABLE \
|
||||
DEBUG_ENABLE \
|
||||
ENCODER_ENABLE_CUSTOM \
|
||||
@@ -65,7 +62,6 @@ OTHER_OPTION_NAMES = \
|
||||
HAPTIC_ENABLE \
|
||||
HHKB_RN42_ENABLE \
|
||||
ISSI_ENABLE \
|
||||
KEYBOARD_LOCK_ENABLE \
|
||||
KEYLOGGER_ENABLE \
|
||||
LCD_BACKLIGHT_ENABLE \
|
||||
MACROS_ENABLED \
|
||||
@@ -74,7 +70,6 @@ OTHER_OPTION_NAMES = \
|
||||
SWAP_HANDS_ENABLE \
|
||||
RING_BUFFERED_6KRO_REPORT_ENABLE \
|
||||
WATCHDOG_ENABLE \
|
||||
XT_ENABLE \
|
||||
ERGOINU \
|
||||
NO_USB_STARTUP_CHECK \
|
||||
DISABLE_PROMICRO_LEDs \
|
||||
@@ -83,7 +78,8 @@ OTHER_OPTION_NAMES = \
|
||||
RGB_MATRIX_KEYPRESSES \
|
||||
LED_MIRRORED \
|
||||
RGBLIGHT_FULL_POWER \
|
||||
LTO_ENABLE
|
||||
LTO_ENABLE \
|
||||
PROGRAMMABLE_BUTTON_ENABLE
|
||||
|
||||
define NAME_ECHO
|
||||
@printf " %-30s = %-16s # %s\\n" "$1" "$($1)" "$(origin $1)"
|
||||
@@ -13,8 +13,6 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
SERIAL_PATH := $(QUANTUM_PATH)/serial_link
|
||||
|
||||
QUANTUM_SRC += \
|
||||
$(QUANTUM_DIR)/quantum.c \
|
||||
$(QUANTUM_DIR)/send_string.c \
|
||||
@@ -29,13 +27,16 @@ QUANTUM_SRC += \
|
||||
$(QUANTUM_DIR)/keyboard.c \
|
||||
$(QUANTUM_DIR)/keymap_common.c \
|
||||
$(QUANTUM_DIR)/keycode_config.c \
|
||||
$(QUANTUM_DIR)/sync_timer.c \
|
||||
$(QUANTUM_DIR)/logging/debug.c \
|
||||
$(QUANTUM_DIR)/logging/sendchar.c \
|
||||
|
||||
VPATH += $(QUANTUM_DIR)/logging
|
||||
# Fall back to lib/printf if there is no platform provided print
|
||||
ifeq ("$(wildcard $(TMK_PATH)/common/$(PLATFORM_KEY)/printf.mk)","")
|
||||
ifeq ("$(wildcard $(PLATFORM_PATH)/$(PLATFORM_KEY)/printf.mk)","")
|
||||
include $(QUANTUM_PATH)/logging/print.mk
|
||||
else
|
||||
include $(PLATFORM_PATH)/$(PLATFORM_KEY)/printf.mk
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(DEBUG_MATRIX_SCAN_RATE_ENABLE)), yes)
|
||||
@@ -45,19 +46,6 @@ else ifeq ($(strip $(DEBUG_MATRIX_SCAN_RATE_ENABLE)), api)
|
||||
OPT_DEFS += -DDEBUG_MATRIX_SCAN_RATE
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(API_SYSEX_ENABLE)), yes)
|
||||
OPT_DEFS += -DAPI_SYSEX_ENABLE
|
||||
OPT_DEFS += -DAPI_ENABLE
|
||||
MIDI_ENABLE=yes
|
||||
SRC += $(QUANTUM_DIR)/api/api_sysex.c
|
||||
SRC += $(QUANTUM_DIR)/api.c
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(COMMAND_ENABLE)), yes)
|
||||
SRC += $(QUANTUM_DIR)/command.c
|
||||
OPT_DEFS += -DCOMMAND_ENABLE
|
||||
endif
|
||||
|
||||
AUDIO_ENABLE ?= no
|
||||
ifeq ($(strip $(AUDIO_ENABLE)), yes)
|
||||
ifeq ($(PLATFORM),CHIBIOS)
|
||||
@@ -82,7 +70,7 @@ ifeq ($(strip $(AUDIO_ENABLE)), yes)
|
||||
SRC += $(QUANTUM_DIR)/process_keycode/process_audio.c
|
||||
SRC += $(QUANTUM_DIR)/process_keycode/process_clicky.c
|
||||
SRC += $(QUANTUM_DIR)/audio/audio.c ## common audio code, hardware agnostic
|
||||
SRC += $(QUANTUM_DIR)/audio/driver_$(PLATFORM_KEY)_$(strip $(AUDIO_DRIVER)).c
|
||||
SRC += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/audio_$(strip $(AUDIO_DRIVER)).c
|
||||
SRC += $(QUANTUM_DIR)/audio/voices.c
|
||||
SRC += $(QUANTUM_DIR)/audio/luts.c
|
||||
endif
|
||||
@@ -121,10 +109,43 @@ 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
|
||||
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)
|
||||
else
|
||||
OPT_DEFS += -DPOINTING_DEVICE_ENABLE
|
||||
MOUSE_ENABLE := yes
|
||||
SRC += $(QUANTUM_DIR)/pointing_device.c
|
||||
SRC += $(QUANTUM_DIR)/pointing_device_drivers.c
|
||||
ifneq ($(strip $(POINTING_DEVICE_DRIVER)), custom)
|
||||
SRC += drivers/sensors/$(strip $(POINTING_DEVICE_DRIVER)).c
|
||||
OPT_DEFS += -DPOINTING_DEVICE_DRIVER_$(strip $(shell echo $(POINTING_DEVICE_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
||||
endif
|
||||
OPT_DEFS += -DPOINTING_DEVICE_DRIVER_$(strip $(POINTING_DEVICE_DRIVER))
|
||||
ifeq ($(strip $(POINTING_DEVICE_DRIVER)), adns9800)
|
||||
OPT_DEFS += -DSTM32_SPI -DHAL_USE_SPI=TRUE
|
||||
QUANTUM_LIB_SRC += spi_master.c
|
||||
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), analog_joystick)
|
||||
OPT_DEFS += -DSTM32_ADC -DHAL_USE_ADC=TRUE
|
||||
LIB_SRC += analog.c
|
||||
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), cirque_pinnacle_i2c)
|
||||
OPT_DEFS += -DSTM32_I2C -DHAL_USE_I2C=TRUE
|
||||
SRC += drivers/sensors/cirque_pinnacle.c
|
||||
QUANTUM_LIB_SRC += i2c_master.c
|
||||
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), cirque_pinnacle_spi)
|
||||
OPT_DEFS += -DSTM32_SPI -DHAL_USE_SPI=TRUE
|
||||
SRC += drivers/sensors/cirque_pinnacle.c
|
||||
QUANTUM_LIB_SRC += spi_master.c
|
||||
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), pimoroni_trackball)
|
||||
OPT_DEFS += -DSTM32_SPI -DHAL_USE_I2C=TRUE
|
||||
QUANTUM_LIB_SRC += i2c_master.c
|
||||
else ifeq ($(strip $(POINTING_DEVICE_DRIVER)), pmw3360)
|
||||
OPT_DEFS += -DSTM32_SPI -DHAL_USE_SPI=TRUE
|
||||
QUANTUM_LIB_SRC += spi_master.c
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
VALID_EEPROM_DRIVER_TYPES := vendor custom transient i2c spi
|
||||
@@ -156,36 +177,18 @@ else
|
||||
ifeq ($(PLATFORM),AVR)
|
||||
# Automatically provided by avr-libc, nothing required
|
||||
else ifeq ($(PLATFORM),CHIBIOS)
|
||||
ifeq ($(MCU_SERIES), STM32F3xx)
|
||||
ifneq ($(filter STM32F3xx_% STM32F1xx_% %_STM32F401xC %_STM32F401xE %_STM32F405xG %_STM32F411xE %_STM32F072xB %_STM32F042x6 %_GD32VF103xB %_GD32VF103x8, $(MCU_SERIES)_$(MCU_LDSCRIPT)),)
|
||||
OPT_DEFS += -DEEPROM_DRIVER
|
||||
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
||||
SRC += eeprom_driver.c
|
||||
SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
|
||||
SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
|
||||
OPT_DEFS += -DEEPROM_EMU_STM32F303xC
|
||||
OPT_DEFS += -DSTM32_EEPROM_ENABLE
|
||||
else ifeq ($(MCU_SERIES), STM32F1xx)
|
||||
SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
|
||||
SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
|
||||
OPT_DEFS += -DEEPROM_EMU_STM32F103xB
|
||||
OPT_DEFS += -DSTM32_EEPROM_ENABLE
|
||||
else ifeq ($(MCU_SERIES)_$(MCU_LDSCRIPT), STM32F0xx_STM32F072xB)
|
||||
SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
|
||||
SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
|
||||
OPT_DEFS += -DEEPROM_EMU_STM32F072xB
|
||||
OPT_DEFS += -DSTM32_EEPROM_ENABLE
|
||||
else ifeq ($(MCU_SERIES)_$(MCU_LDSCRIPT), STM32F0xx_STM32F042x6)
|
||||
|
||||
# Stack sizes: Since this chip has limited RAM capacity, the stack area needs to be reduced.
|
||||
# This ensures that the EEPROM page buffer fits into RAM
|
||||
USE_PROCESS_STACKSIZE = 0x600
|
||||
USE_EXCEPTIONS_STACKSIZE = 0x300
|
||||
SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
|
||||
SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
|
||||
OPT_DEFS += -DEEPROM_EMU_STM32F042x6
|
||||
OPT_DEFS += -DSTM32_EEPROM_ENABLE
|
||||
else ifneq ($(filter $(MCU_SERIES),STM32L0xx STM32L1xx),)
|
||||
OPT_DEFS += -DEEPROM_DRIVER
|
||||
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
||||
COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/eeprom
|
||||
SRC += eeprom_driver.c eeprom_stm32_L0_L1.c
|
||||
SRC += eeprom_driver.c
|
||||
SRC += eeprom_stm32_L0_L1.c
|
||||
else
|
||||
# This will effectively work the same as "transient" if not supported by the chip
|
||||
SRC += $(PLATFORM_COMMON_DIR)/eeprom_teensy.c
|
||||
@@ -264,7 +267,7 @@ endif
|
||||
endif
|
||||
|
||||
RGB_MATRIX_ENABLE ?= no
|
||||
VALID_RGB_MATRIX_TYPES := AW20216 IS31FL3731 IS31FL3733 IS31FL3737 IS31FL3741 WS2812 custom
|
||||
VALID_RGB_MATRIX_TYPES := AW20216 IS31FL3731 IS31FL3733 IS31FL3737 IS31FL3741 CKLED2001 WS2812 custom
|
||||
|
||||
ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
|
||||
ifeq ($(filter $(RGB_MATRIX_DRIVER),$(VALID_RGB_MATRIX_TYPES)),)
|
||||
@@ -320,6 +323,13 @@ endif
|
||||
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
|
||||
SRC += ckled2001.c
|
||||
QUANTUM_LIB_SRC += i2c_master.c
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(RGB_MATRIX_DRIVER)), WS2812)
|
||||
OPT_DEFS += -DWS2812
|
||||
WS2812_DRIVER_REQUIRED := yes
|
||||
@@ -349,17 +359,6 @@ ifeq ($(strip $(PRINTING_ENABLE)), yes)
|
||||
SRC += $(TMK_DIR)/protocol/serial_uart.c
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(SERIAL_LINK_ENABLE)), yes)
|
||||
SERIAL_SRC := $(wildcard $(SERIAL_PATH)/protocol/*.c)
|
||||
SERIAL_SRC += $(wildcard $(SERIAL_PATH)/system/*.c)
|
||||
SERIAL_DEFS += -DSERIAL_LINK_ENABLE
|
||||
COMMON_VPATH += $(SERIAL_PATH)
|
||||
|
||||
SRC += $(patsubst $(QUANTUM_PATH)/%,%,$(SERIAL_SRC))
|
||||
OPT_DEFS += $(SERIAL_DEFS)
|
||||
VAPTH += $(SERIAL_PATH)
|
||||
endif
|
||||
|
||||
VARIABLE_TRACE ?= no
|
||||
ifneq ($(strip $(VARIABLE_TRACE)),no)
|
||||
SRC += $(QUANTUM_DIR)/variable_trace.c
|
||||
@@ -369,8 +368,11 @@ ifneq ($(strip $(VARIABLE_TRACE)),no)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(LCD_ENABLE)), yes)
|
||||
CIE1931_CURVE := yes
|
||||
ifeq ($(strip $(SLEEP_LED_ENABLE)), yes)
|
||||
SRC += $(PLATFORM_COMMON_DIR)/sleep_led.c
|
||||
OPT_DEFS += -DSLEEP_LED_ENABLE
|
||||
|
||||
NO_SUSPEND_POWER_DOWN := yes
|
||||
endif
|
||||
|
||||
VALID_BACKLIGHT_TYPES := pwm timer software custom
|
||||
@@ -436,10 +438,6 @@ ifeq ($(strip $(APA102_DRIVER_REQUIRED)), yes)
|
||||
SRC += apa102.c
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(VISUALIZER_ENABLE)), yes)
|
||||
CIE1931_CURVE := yes
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(CIE1931_CURVE)), yes)
|
||||
OPT_DEFS += -DUSE_CIE1931_CURVE
|
||||
LED_TABLES := yes
|
||||
@@ -455,21 +453,6 @@ ifeq ($(strip $(TERMINAL_ENABLE)), yes)
|
||||
OPT_DEFS += -DUSER_PRINT
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(WPM_ENABLE)), yes)
|
||||
SRC += $(QUANTUM_DIR)/wpm.c
|
||||
OPT_DEFS += -DWPM_ENABLE
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(ENCODER_ENABLE)), yes)
|
||||
SRC += $(QUANTUM_DIR)/encoder.c
|
||||
OPT_DEFS += -DENCODER_ENABLE
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(VELOCIKEY_ENABLE)), yes)
|
||||
OPT_DEFS += -DVELOCIKEY_ENABLE
|
||||
SRC += $(QUANTUM_DIR)/velocikey.c
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(ORYX_ENABLE)), yes)
|
||||
WEBUSB_ENABLE := yes
|
||||
SRC += $(QUANTUM_DIR)/oryx.c
|
||||
@@ -479,22 +462,12 @@ endif
|
||||
ifeq ($(strip $(VIA_ENABLE)), yes)
|
||||
DYNAMIC_KEYMAP_ENABLE := yes
|
||||
RAW_ENABLE := yes
|
||||
BOOTMAGIC_ENABLE := lite
|
||||
BOOTMAGIC_ENABLE := yes
|
||||
SRC += $(QUANTUM_DIR)/via.c
|
||||
OPT_DEFS += -DVIA_ENABLE
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(DYNAMIC_KEYMAP_ENABLE)), yes)
|
||||
OPT_DEFS += -DDYNAMIC_KEYMAP_ENABLE
|
||||
SRC += $(QUANTUM_DIR)/dynamic_keymap.c
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(DIP_SWITCH_ENABLE)), yes)
|
||||
OPT_DEFS += -DDIP_SWITCH_ENABLE
|
||||
SRC += $(QUANTUM_DIR)/dip_switch.c
|
||||
endif
|
||||
|
||||
VALID_MAGIC_TYPES := yes lite
|
||||
VALID_MAGIC_TYPES := yes
|
||||
BOOTMAGIC_ENABLE ?= no
|
||||
ifneq ($(strip $(BOOTMAGIC_ENABLE)), no)
|
||||
ifeq ($(filter $(BOOTMAGIC_ENABLE),$(VALID_MAGIC_TYPES)),)
|
||||
@@ -573,24 +546,20 @@ ifeq ($(strip $(CRC_ENABLE)), yes)
|
||||
SRC += crc.c
|
||||
endif
|
||||
|
||||
HAPTIC_ENABLE ?= no
|
||||
ifneq ($(strip $(HAPTIC_ENABLE)),no)
|
||||
ifeq ($(strip $(HAPTIC_ENABLE)),yes)
|
||||
COMMON_VPATH += $(DRIVER_PATH)/haptic
|
||||
OPT_DEFS += -DHAPTIC_ENABLE
|
||||
SRC += $(QUANTUM_DIR)/haptic.c
|
||||
SRC += $(QUANTUM_DIR)/process_keycode/process_haptic.c
|
||||
endif
|
||||
|
||||
ifneq ($(filter DRV2605L, $(HAPTIC_ENABLE)), )
|
||||
ifneq ($(filter DRV2605L, $(HAPTIC_DRIVER)), )
|
||||
SRC += DRV2605L.c
|
||||
QUANTUM_LIB_SRC += i2c_master.c
|
||||
OPT_DEFS += -DDRV2605L
|
||||
endif
|
||||
|
||||
ifneq ($(filter SOLENOID, $(HAPTIC_ENABLE)), )
|
||||
ifneq ($(filter SOLENOID, $(HAPTIC_DRIVER)), )
|
||||
SRC += solenoid.c
|
||||
OPT_DEFS += -DSOLENOID_ENABLE
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(HD44780_ENABLE)), yes)
|
||||
SRC += platforms/avr/drivers/hd44780.c
|
||||
@@ -622,8 +591,6 @@ ifeq ($(strip $(ST7565_ENABLE)), yes)
|
||||
SRC += st7565.c
|
||||
endif
|
||||
|
||||
include $(DRIVER_PATH)/qwiic/qwiic.mk
|
||||
|
||||
ifeq ($(strip $(UCIS_ENABLE)), yes)
|
||||
OPT_DEFS += -DUCIS_ENABLE
|
||||
UNICODE_COMMON := yes
|
||||
@@ -646,54 +613,12 @@ ifeq ($(strip $(UNICODE_COMMON)), yes)
|
||||
SRC += $(QUANTUM_DIR)/process_keycode/process_unicode_common.c
|
||||
endif
|
||||
|
||||
SPACE_CADET_ENABLE ?= yes
|
||||
ifeq ($(strip $(SPACE_CADET_ENABLE)), yes)
|
||||
SRC += $(QUANTUM_DIR)/process_keycode/process_space_cadet.c
|
||||
OPT_DEFS += -DSPACE_CADET_ENABLE
|
||||
endif
|
||||
|
||||
MAGIC_ENABLE ?= yes
|
||||
ifeq ($(strip $(MAGIC_ENABLE)), yes)
|
||||
SRC += $(QUANTUM_DIR)/process_keycode/process_magic.c
|
||||
OPT_DEFS += -DMAGIC_KEYCODE_ENABLE
|
||||
endif
|
||||
|
||||
GRAVE_ESC_ENABLE ?= yes
|
||||
ifeq ($(strip $(GRAVE_ESC_ENABLE)), yes)
|
||||
SRC += $(QUANTUM_DIR)/process_keycode/process_grave_esc.c
|
||||
OPT_DEFS += -DGRAVE_ESC_ENABLE
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(DYNAMIC_MACRO_ENABLE)), yes)
|
||||
SRC += $(QUANTUM_DIR)/process_keycode/process_dynamic_macro.c
|
||||
OPT_DEFS += -DDYNAMIC_MACRO_ENABLE
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(COMBO_ENABLE)), yes)
|
||||
SRC += $(QUANTUM_DIR)/process_keycode/process_combo.c
|
||||
OPT_DEFS += -DCOMBO_ENABLE
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(KEY_OVERRIDE_ENABLE)), yes)
|
||||
SRC += $(QUANTUM_DIR)/process_keycode/process_key_override.c
|
||||
OPT_DEFS += -DKEY_OVERRIDE_ENABLE
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(TAP_DANCE_ENABLE)), yes)
|
||||
SRC += $(QUANTUM_DIR)/process_keycode/process_tap_dance.c
|
||||
OPT_DEFS += -DTAP_DANCE_ENABLE
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(KEY_LOCK_ENABLE)), yes)
|
||||
SRC += $(QUANTUM_DIR)/process_keycode/process_key_lock.c
|
||||
OPT_DEFS += -DKEY_LOCK_ENABLE
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(LEADER_ENABLE)), yes)
|
||||
SRC += $(QUANTUM_DIR)/process_keycode/process_leader.c
|
||||
OPT_DEFS += -DLEADER_ENABLE
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(AUTO_SHIFT_ENABLE)), yes)
|
||||
SRC += $(QUANTUM_DIR)/process_keycode/process_auto_shift.c
|
||||
OPT_DEFS += -DAUTO_SHIFT_ENABLE
|
||||
@@ -702,6 +627,40 @@ ifeq ($(strip $(AUTO_SHIFT_ENABLE)), yes)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(PS2_MOUSE_ENABLE)), yes)
|
||||
PS2_ENABLE := yes
|
||||
SRC += ps2_mouse.c
|
||||
OPT_DEFS += -DPS2_MOUSE_ENABLE
|
||||
OPT_DEFS += -DMOUSE_ENABLE
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(PS2_USE_BUSYWAIT)), yes)
|
||||
PS2_ENABLE := yes
|
||||
SRC += ps2_busywait.c
|
||||
SRC += ps2_io_avr.c
|
||||
OPT_DEFS += -DPS2_USE_BUSYWAIT
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(PS2_USE_INT)), yes)
|
||||
PS2_ENABLE := yes
|
||||
SRC += ps2_interrupt.c
|
||||
SRC += ps2_io.c
|
||||
OPT_DEFS += -DPS2_USE_INT
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(PS2_USE_USART)), yes)
|
||||
PS2_ENABLE := yes
|
||||
SRC += ps2_usart.c
|
||||
SRC += ps2_io.c
|
||||
OPT_DEFS += -DPS2_USE_USART
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(PS2_ENABLE)), yes)
|
||||
COMMON_VPATH += $(DRIVER_PATH)/ps2
|
||||
COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/ps2
|
||||
OPT_DEFS += -DPS2_ENABLE
|
||||
endif
|
||||
|
||||
JOYSTICK_ENABLE ?= no
|
||||
VALID_JOYSTICK_TYPES := analog digital
|
||||
JOYSTICK_DRIVER ?= analog
|
||||
@@ -722,11 +681,6 @@ ifeq ($(strip $(JOYSTICK_ENABLE)), yes)
|
||||
endif
|
||||
endif
|
||||
|
||||
DIGITIZER_ENABLE ?= no
|
||||
ifneq ($(strip $(DIGITIZER_ENABLE)), no)
|
||||
SRC += $(QUANTUM_DIR)/digitizer.c
|
||||
endif
|
||||
|
||||
USBPD_ENABLE ?= no
|
||||
VALID_USBPD_DRIVER_TYPES = custom vendor
|
||||
USBPD_DRIVER ?= vendor
|
||||
@@ -750,3 +704,27 @@ ifeq ($(strip $(USBPD_ENABLE)), yes)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
BLUETOOTH_ENABLE ?= no
|
||||
VALID_BLUETOOTH_DRIVER_TYPES := AdafruitBLE 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)
|
||||
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
|
||||
SRC += analog.c
|
||||
SRC += $(DRIVER_PATH)/bluetooth/adafruit_ble.cpp
|
||||
QUANTUM_LIB_SRC += spi_master.c
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(BLUETOOTH_DRIVER)), RN42)
|
||||
OPT_DEFS += -DMODULE_RN42
|
||||
SRC += $(TMK_DIR)/protocol/serial_uart.c
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
"RGBLIGHT_SLEEP": {"info_key": "rgblight.sleep", "value_type": "bool"},
|
||||
"RGBLIGHT_SPLIT": {"info_key": "rgblight.split", "value_type": "bool"},
|
||||
"RGBW": {"info_key": "rgblight.rgbw", "value_type": "bool"},
|
||||
"PRODUCT": {"info_key": "keyboard_folder", "to_json": false},
|
||||
"PRODUCT": {"info_key": "keyboard_name", "warn_duplicate": false},
|
||||
"PRODUCT_ID": {"info_key": "usb.pid", "value_type": "hex"},
|
||||
"VENDOR_ID": {"info_key": "usb.vid", "value_type": "hex"},
|
||||
"QMK_ESC_OUTPUT": {"info_key": "qmk_lufa_bootloader.esc_output"},
|
||||
@@ -76,6 +76,7 @@
|
||||
"QMK_KEYS_PER_SCAN": {"info_key": "qmk.keys_per_scan", "value_type": "int"},
|
||||
"QMK_LED": {"info_key": "qmk_lufa_bootloader.led"},
|
||||
"QMK_SPEAKER": {"info_key": "qmk_lufa_bootloader.speaker"},
|
||||
"SENDSTRING_BELL": {"info_key": "audio.macro_beep", "value_type": "bool"},
|
||||
"SPLIT_MODS_ENABLE": {"info_key": "split.transport.sync_modifiers", "value_type": "bool"},
|
||||
"SPLIT_TRANSPORT_MIRROR": {"info_key": "split.transport.sync_matrix_state", "value_type": "bool"},
|
||||
"SPLIT_USB_DETECT": {"info_key": "split.usb_detect.enabled", "value_type": "bool"},
|
||||
|
||||
@@ -13,12 +13,13 @@
|
||||
},
|
||||
"processor": {
|
||||
"type": "string",
|
||||
"enum": ["cortex-m0", "cortex-m0plus", "cortex-m3", "cortex-m4", "MKL26Z64", "MK20DX128", "MK20DX256", "MK66F18", "STM32F042", "STM32F072", "STM32F103", "STM32F303", "STM32F401", "STM32F407", "STM32F411", "STM32F446", "STM32G431", "STM32G474", "STM32L412", "STM32L422", "STM32L433", "STM32L443", "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", "STM32L433", "STM32L443", "GD32VF103", "WB32F3G71", "atmega16u2", "atmega32u2", "atmega16u4", "atmega32u4", "at90usb162", "at90usb646", "at90usb647", "at90usb1286", "at90usb1287", "atmega32a", "atmega328p", "atmega328", "attiny85", "unknown"]
|
||||
},
|
||||
"audio": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"macro_beep": {"type": "boolean"},
|
||||
"pins": {"$ref": "qmk.definitions.v1#/mcu_pin_array"},
|
||||
"voices": {"type": "boolean"}
|
||||
}
|
||||
@@ -56,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", "unknown", "usbasploader", "USBasp", "tinyuf2"],
|
||||
"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"],
|
||||
},
|
||||
"bootloader_instructions": {
|
||||
"type": "string",
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"author": {"type": "string"},
|
||||
"host_language": {"$ref": "qmk.definitions.v1#/text_identifier"},
|
||||
"keyboard": {"$ref": "qmk.definitions.v1#/text_identifier"},
|
||||
"keymap": {"$ref": "qmk.definitions.v1#/text_identifier"},
|
||||
"layout": {"$ref": "qmk.definitions.v1#/layout_macro"},
|
||||
@@ -15,6 +16,38 @@
|
||||
"items": {"type": "string"}
|
||||
}
|
||||
},
|
||||
"macros": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
"enum": ['beep', 'delay', 'down', 'tap', 'up']
|
||||
},
|
||||
"keycodes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "qmk.definitions.v1#/text_identifier"
|
||||
}
|
||||
},
|
||||
"duration": {
|
||||
"$ref": "qmk.definitions.v1#/unsigned_int"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"config": {"$ref": "qmk.keyboard.v1"},
|
||||
"notes": {
|
||||
"type": "string",
|
||||
|
||||
@@ -1,19 +1,5 @@
|
||||
/*
|
||||
Copyright %YEAR% %YOUR_NAME%
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General 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 %(YEAR)s %(YOUR_NAME)s (@%(USER_NAME)s)
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -23,8 +9,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define VENDOR_ID 0xFEED
|
||||
#define PRODUCT_ID 0x0000
|
||||
#define DEVICE_VER 0x0001
|
||||
#define MANUFACTURER %YOUR_NAME%
|
||||
#define PRODUCT %KEYBOARD%
|
||||
#define MANUFACTURER %(USER_NAME)s
|
||||
#define PRODUCT %(KEYBOARD)s
|
||||
|
||||
/* key matrix size */
|
||||
#define MATRIX_ROWS 2
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
# %KEYBOARD%
|
||||
# %(KEYBOARD)s
|
||||
|
||||

|
||||

|
||||
|
||||
*A short description of the keyboard/project*
|
||||
|
||||
* Keyboard Maintainer: [%YOUR_NAME%](https://github.com/yourusername)
|
||||
* Keyboard Maintainer: [%(YOUR_NAME)s](https://github.com/%(USER_NAME)s)
|
||||
* 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%:default
|
||||
make %(KEYBOARD)s:default
|
||||
|
||||
Flashing example for this keyboard:
|
||||
|
||||
make %KEYBOARD%:default:flash
|
||||
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).
|
||||
|
||||
|
||||
@@ -12,8 +12,6 @@ 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
|
||||
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
|
||||
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
|
||||
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
|
||||
NKRO_ENABLE = no # USB Nkey Rollover
|
||||
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
|
||||
|
||||
4
data/templates/base/%(KEYBOARD)s.c
Normal file
4
data/templates/base/%(KEYBOARD)s.c
Normal file
@@ -0,0 +1,4 @@
|
||||
// Copyright %(YEAR)s %(YOUR_NAME)s (@%(USER_NAME)s)
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "%(KEYBOARD)s.h"
|
||||
22
data/templates/base/%(KEYBOARD)s.h
Normal file
22
data/templates/base/%(KEYBOARD)s.h
Normal file
@@ -0,0 +1,22 @@
|
||||
// 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,7 +1,7 @@
|
||||
{
|
||||
"keyboard_name": "%KEYBOARD%",
|
||||
"keyboard_name": "%(KEYBOARD)s",
|
||||
"url": "",
|
||||
"maintainer": "%YOUR_NAME%",
|
||||
"maintainer": "%(USER_NAME)s",
|
||||
"layouts": {
|
||||
"LAYOUT": {
|
||||
"layout": [
|
||||
|
||||
@@ -1,18 +1,6 @@
|
||||
/* Copyright %YEAR% %YOUR_NAME%
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General 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 %(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
|
||||
@@ -21,15 +9,6 @@ enum layer_names {
|
||||
_FN
|
||||
};
|
||||
|
||||
// Defines the keycodes used by our macros in process_record_user
|
||||
enum custom_keycodes {
|
||||
QMKBEST = SAFE_RANGE,
|
||||
QMKURL
|
||||
};
|
||||
|
||||
// Defines the keycodes used by our macros in process_record_user
|
||||
enum custom_keycodes { QMKBEST = SAFE_RANGE, QMKURL };
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
/* Base */
|
||||
[_BASE] = LAYOUT(
|
||||
@@ -37,29 +16,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
KC_TAB, KC_SPC
|
||||
),
|
||||
[_FN] = LAYOUT(
|
||||
QMKBEST, QMKURL, _______,
|
||||
_______, _______, _______,
|
||||
RESET, XXXXXXX
|
||||
)
|
||||
};
|
||||
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
switch (keycode) {
|
||||
case QMKBEST:
|
||||
if (record->event.pressed) {
|
||||
// when keycode QMKBEST is pressed
|
||||
SEND_STRING("QMK is the best thing ever!");
|
||||
} else {
|
||||
// when keycode QMKBEST is released
|
||||
}
|
||||
break;
|
||||
case QMKURL:
|
||||
if (record->event.pressed) {
|
||||
// when keycode QMKURL is pressed
|
||||
SEND_STRING("https://qmk.fm/\n");
|
||||
} else {
|
||||
// when keycode QMKURL is released
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
# The default keymap for %KEYBOARD%
|
||||
# The default keymap for %(KEYBOARD)s
|
||||
|
||||
@@ -1,19 +1,5 @@
|
||||
/*
|
||||
Copyright %YEAR% %YOUR_NAME%
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General 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 %(YEAR)s %(YOUR_NAME)s (@%(USER_NAME)s)
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -23,8 +9,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define VENDOR_ID 0xFEED
|
||||
#define PRODUCT_ID 0x0000
|
||||
#define DEVICE_VER 0x0001
|
||||
#define MANUFACTURER %YOUR_NAME%
|
||||
#define PRODUCT %KEYBOARD%
|
||||
#define MANUFACTURER %(USER_NAME)s
|
||||
#define PRODUCT %(KEYBOARD)s
|
||||
|
||||
/* key matrix size */
|
||||
#define MATRIX_ROWS 8
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
# %KEYBOARD%
|
||||
# %(KEYBOARD)s
|
||||
|
||||

|
||||

|
||||
|
||||
*A short description of the keyboard/project*
|
||||
|
||||
* Keyboard Maintainer: [%YOUR_NAME%](https://github.com/yourusername)
|
||||
* 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%:default
|
||||
make %(KEYBOARD)s:default
|
||||
|
||||
Flashing example for this keyboard ([after setting up the bootloadHID flashing environment](https://docs.qmk.fm/#/flashing_bootloadhid))
|
||||
|
||||
make %KEYBOARD%:default:flash
|
||||
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).
|
||||
|
||||
|
||||
@@ -12,8 +12,6 @@ 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
|
||||
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
|
||||
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
|
||||
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
|
||||
RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
|
||||
WS2812_DRIVER = i2c
|
||||
|
||||
14
doxygen-todo
14
doxygen-todo
@@ -6,22 +6,8 @@ tmk_core/protocol/midi/bytequeue
|
||||
tmk_core/protocol/midi/Config
|
||||
tmk_core/protocol/usb_hid
|
||||
tmk_core/protocol/vusb
|
||||
tmk_core/tool
|
||||
tmk_core/tool/chibios
|
||||
quantum
|
||||
quantum/api
|
||||
quantum/audio
|
||||
quantum/keymap_extras
|
||||
quantum/process_keycode
|
||||
quantum/serial_link
|
||||
quantum/serial_link/protocol
|
||||
quantum/serial_link/system
|
||||
quantum/serial_link/tests
|
||||
quantum/tools
|
||||
quantum/visualizer
|
||||
quantum/visualizer/resources
|
||||
drivers
|
||||
drivers/ugfx
|
||||
drivers/ugfx/gdisp
|
||||
drivers/ugfx/gdisp/is31fl3731c
|
||||
drivers/ugfx/gdisp/st7565
|
||||
|
||||
@@ -16,24 +16,22 @@
|
||||
// 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 AdafruitBleResetPin
|
||||
# define AdafruitBleResetPin D4
|
||||
#ifndef ADAFRUIT_BLE_RST_PIN
|
||||
# define ADAFRUIT_BLE_RST_PIN D4
|
||||
#endif
|
||||
|
||||
#ifndef AdafruitBleCSPin
|
||||
# define AdafruitBleCSPin B4
|
||||
#ifndef ADAFRUIT_BLE_CS_PIN
|
||||
# define ADAFRUIT_BLE_CS_PIN B4
|
||||
#endif
|
||||
|
||||
#ifndef AdafruitBleIRQPin
|
||||
# define AdafruitBleIRQPin E6
|
||||
#ifndef ADAFRUIT_BLE_IRQ_PIN
|
||||
# define ADAFRUIT_BLE_IRQ_PIN E6
|
||||
#endif
|
||||
|
||||
#ifndef AdafruitBleSpiClockSpeed
|
||||
# define AdafruitBleSpiClockSpeed 4000000UL // SCK frequency
|
||||
#ifndef ADAFRUIT_BLE_SCK_DIVISOR
|
||||
# define ADAFRUIT_BLE_SCK_DIVISOR 2 // 4MHz SCK/8MHz CPU, calculated for Feather 32U4 BLE
|
||||
#endif
|
||||
|
||||
#define SCK_DIVISOR (F_CPU / AdafruitBleSpiClockSpeed)
|
||||
|
||||
#define SAMPLE_BATTERY
|
||||
#define ConnectionUpdateInterval 1000 /* milliseconds */
|
||||
|
||||
@@ -145,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(AdafruitBleCSPin, false, 0, SCK_DIVISOR);
|
||||
spi_start(ADAFRUIT_BLE_CS_PIN, false, 0, ADAFRUIT_BLE_SCK_DIVISOR);
|
||||
uint16_t timerStart = timer_read();
|
||||
bool success = false;
|
||||
bool ready = false;
|
||||
@@ -159,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(AdafruitBleCSPin, false, 0, SCK_DIVISOR);
|
||||
spi_start(ADAFRUIT_BLE_CS_PIN, false, 0, ADAFRUIT_BLE_SCK_DIVISOR);
|
||||
} while (timer_elapsed(timerStart) < timeout);
|
||||
|
||||
if (ready) {
|
||||
@@ -192,7 +190,7 @@ static bool sdep_recv_pkt(struct sdep_msg *msg, uint16_t timeout) {
|
||||
bool ready = false;
|
||||
|
||||
do {
|
||||
ready = readPin(AdafruitBleIRQPin);
|
||||
ready = readPin(ADAFRUIT_BLE_IRQ_PIN);
|
||||
if (ready) {
|
||||
break;
|
||||
}
|
||||
@@ -200,7 +198,7 @@ static bool sdep_recv_pkt(struct sdep_msg *msg, uint16_t timeout) {
|
||||
} while (timer_elapsed(timerStart) < timeout);
|
||||
|
||||
if (ready) {
|
||||
spi_start(AdafruitBleCSPin, false, 0, SCK_DIVISOR);
|
||||
spi_start(ADAFRUIT_BLE_CS_PIN, false, 0, ADAFRUIT_BLE_SCK_DIVISOR);
|
||||
|
||||
do {
|
||||
// Read the command type, waiting for the data to be ready
|
||||
@@ -209,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(AdafruitBleCSPin, false, 0, SCK_DIVISOR);
|
||||
spi_start(ADAFRUIT_BLE_CS_PIN, false, 0, ADAFRUIT_BLE_SCK_DIVISOR);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -235,7 +233,7 @@ static void resp_buf_read_one(bool greedy) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (readPin(AdafruitBleIRQPin)) {
|
||||
if (readPin(ADAFRUIT_BLE_IRQ_PIN)) {
|
||||
struct sdep_msg msg;
|
||||
|
||||
again:
|
||||
@@ -246,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(AdafruitBleIRQPin)) {
|
||||
if (greedy && resp_buf.peek(last_send) && readPin(ADAFRUIT_BLE_IRQ_PIN)) {
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
@@ -297,16 +295,16 @@ static bool ble_init(void) {
|
||||
state.configured = false;
|
||||
state.is_connected = false;
|
||||
|
||||
setPinInput(AdafruitBleIRQPin);
|
||||
setPinInput(ADAFRUIT_BLE_IRQ_PIN);
|
||||
|
||||
spi_init();
|
||||
|
||||
// Perform a hardware reset
|
||||
setPinOutput(AdafruitBleResetPin);
|
||||
writePinHigh(AdafruitBleResetPin);
|
||||
writePinLow(AdafruitBleResetPin);
|
||||
setPinOutput(ADAFRUIT_BLE_RST_PIN);
|
||||
writePinHigh(ADAFRUIT_BLE_RST_PIN);
|
||||
writePinLow(ADAFRUIT_BLE_RST_PIN);
|
||||
wait_ms(10);
|
||||
writePinHigh(AdafruitBleResetPin);
|
||||
writePinHigh(ADAFRUIT_BLE_RST_PIN);
|
||||
|
||||
wait_ms(1000); // Give it a second to initialize
|
||||
|
||||
@@ -509,7 +507,7 @@ void adafruit_ble_task(void) {
|
||||
resp_buf_read_one(true);
|
||||
send_buf_send_one(SdepShortTimeout);
|
||||
|
||||
if (resp_buf.empty() && (state.event_flags & UsingEvents) && readPin(AdafruitBleIRQPin)) {
|
||||
if (resp_buf.empty() && (state.event_flags & UsingEvents) && readPin(ADAFRUIT_BLE_IRQ_PIN)) {
|
||||
// Must be an event update
|
||||
if (at_command_P(PSTR("AT+EVENTSTATUS"), resbuf, sizeof(resbuf))) {
|
||||
uint32_t mask = strtoul(resbuf, NULL, 16);
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "solenoid.h"
|
||||
#include "haptic.h"
|
||||
#include "gpio.h"
|
||||
#include "usb_device_state.h"
|
||||
|
||||
bool solenoid_on = false;
|
||||
bool solenoid_buzzing = false;
|
||||
@@ -36,7 +37,7 @@ void solenoid_set_buzz(int buzz) { haptic_set_buzz(buzz); }
|
||||
void solenoid_set_dwell(uint8_t dwell) { solenoid_dwell = dwell; }
|
||||
|
||||
void solenoid_stop(void) {
|
||||
writePinLow(SOLENOID_PIN);
|
||||
SOLENOID_PIN_WRITE_INACTIVE();
|
||||
solenoid_on = false;
|
||||
solenoid_buzzing = false;
|
||||
}
|
||||
@@ -48,7 +49,7 @@ void solenoid_fire(void) {
|
||||
solenoid_on = true;
|
||||
solenoid_buzzing = true;
|
||||
solenoid_start = timer_read();
|
||||
writePinHigh(SOLENOID_PIN);
|
||||
SOLENOID_PIN_WRITE_ACTIVE();
|
||||
}
|
||||
|
||||
void solenoid_check(void) {
|
||||
@@ -69,20 +70,23 @@ void solenoid_check(void) {
|
||||
if ((elapsed % (SOLENOID_BUZZ_ACTUATED + SOLENOID_BUZZ_NONACTUATED)) < SOLENOID_BUZZ_ACTUATED) {
|
||||
if (!solenoid_buzzing) {
|
||||
solenoid_buzzing = true;
|
||||
writePinHigh(SOLENOID_PIN);
|
||||
SOLENOID_PIN_WRITE_ACTIVE();
|
||||
}
|
||||
} else {
|
||||
if (solenoid_buzzing) {
|
||||
solenoid_buzzing = false;
|
||||
writePinLow(SOLENOID_PIN);
|
||||
SOLENOID_PIN_WRITE_INACTIVE();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void solenoid_setup(void) {
|
||||
SOLENOID_PIN_WRITE_INACTIVE();
|
||||
setPinOutput(SOLENOID_PIN);
|
||||
if ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state == USB_DEVICE_STATE_CONFIGURED)) {
|
||||
solenoid_fire();
|
||||
}
|
||||
}
|
||||
|
||||
void solenoid_shutdown(void) { writePinLow(SOLENOID_PIN); }
|
||||
void solenoid_shutdown(void) { SOLENOID_PIN_WRITE_INACTIVE(); }
|
||||
|
||||
@@ -49,6 +49,14 @@
|
||||
# error SOLENOID_PIN not defined
|
||||
#endif
|
||||
|
||||
#ifdef SOLENOID_PIN_ACTIVE_LOW
|
||||
# define SOLENOID_PIN_WRITE_ACTIVE() writePinLow(SOLENOID_PIN)
|
||||
# define SOLENOID_PIN_WRITE_INACTIVE() writePinHigh(SOLENOID_PIN)
|
||||
#else
|
||||
# define SOLENOID_PIN_WRITE_ACTIVE() writePinHigh(SOLENOID_PIN)
|
||||
# define SOLENOID_PIN_WRITE_INACTIVE() writePinLow(SOLENOID_PIN)
|
||||
#endif
|
||||
|
||||
void solenoid_buzz_on(void);
|
||||
void solenoid_buzz_off(void);
|
||||
void solenoid_set_buzz(int buzz);
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
# elif defined(PROTOCOL_CHIBIOS)
|
||||
|
||||
# include "hal.h"
|
||||
# if defined(STM32F0XX) || defined(STM32F1XX) || defined(STM32F3XX) || defined(STM32F4XX) || defined(STM32L0XX)
|
||||
# define APA102_NOPS (100 / (1000000000L / (STM32_SYSCLK / 4))) // This calculates how many loops of 4 nops to run to delay 100 ns
|
||||
# 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
|
||||
# else
|
||||
# error("APA102_NOPS configuration required")
|
||||
# define APA102_NOPS 0 // this just pleases the compile so the above error is easier to spot
|
||||
|
||||
@@ -119,7 +119,8 @@ void AW20216_init(pin_t cs_pin, pin_t en_pin) {
|
||||
}
|
||||
|
||||
void AW20216_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
|
||||
aw_led led = g_aw_leds[index];
|
||||
aw_led led;
|
||||
memcpy_P(&led, (&g_aw_leds[index]), sizeof(led));
|
||||
|
||||
g_pwm_buffer[led.driver][led.r] = red;
|
||||
g_pwm_buffer[led.driver][led.g] = green;
|
||||
|
||||
@@ -28,7 +28,7 @@ typedef struct aw_led {
|
||||
uint8_t b;
|
||||
} aw_led;
|
||||
|
||||
extern const aw_led __flash g_aw_leds[DRIVER_LED_TOTAL];
|
||||
extern const aw_led PROGMEM g_aw_leds[DRIVER_LED_TOTAL];
|
||||
|
||||
void AW20216_init(pin_t cs_pin, pin_t en_pin);
|
||||
void AW20216_set_color(int index, uint8_t red, uint8_t green, uint8_t blue);
|
||||
|
||||
228
drivers/led/ckled2001.c
Normal file
228
drivers/led/ckled2001.c
Normal file
@@ -0,0 +1,228 @@
|
||||
/* Copyright 2021 @ Keychron (https://www.keychron.com)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ckled2001.h"
|
||||
#include "i2c_master.h"
|
||||
#include "wait.h"
|
||||
|
||||
#ifndef CKLED2001_TIMEOUT
|
||||
# define CKLED2001_TIMEOUT 100
|
||||
#endif
|
||||
|
||||
#ifndef CKLED2001_PERSISTENCE
|
||||
# define CKLED2001_PERSISTENCE 0
|
||||
#endif
|
||||
|
||||
#ifndef PHASE_CHANNEL
|
||||
# define PHASE_CHANNEL MSKPHASE_12CHANNEL
|
||||
#endif
|
||||
|
||||
// Transfer buffer for TWITransmitData()
|
||||
uint8_t g_twi_transfer_buffer[20];
|
||||
|
||||
// These buffers match the CKLED2001 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 CKLED2001_write_pwm_buffer() but it's
|
||||
// probably not worth the extra complexity.
|
||||
uint8_t g_pwm_buffer[DRIVER_COUNT][192];
|
||||
bool g_pwm_buffer_update_required[DRIVER_COUNT] = {false};
|
||||
|
||||
uint8_t g_led_control_registers[DRIVER_COUNT][24] = {0};
|
||||
bool g_led_control_registers_update_required[DRIVER_COUNT] = {false};
|
||||
|
||||
bool CKLED2001_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 CKLED2001_PERSISTENCE > 0
|
||||
for (uint8_t i = 0; i < CKLED2001_PERSISTENCE; i++) {
|
||||
if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, CKLED2001_TIMEOUT) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, CKLED2001_TIMEOUT) != 0) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CKLED2001_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 CKLED2001_PERSISTENCE > 0
|
||||
for (uint8_t i = 0; i < CKLED2001_PERSISTENCE; i++) {
|
||||
if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, CKLED2001_TIMEOUT) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, CKLED2001_TIMEOUT) != 0) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CKLED2001_init(uint8_t addr) {
|
||||
// Select to function page
|
||||
CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE);
|
||||
// Setting LED driver to shutdown mode
|
||||
CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_SHUT_DOWN_MODE);
|
||||
// Setting internal channel pulldown/pullup
|
||||
CKLED2001_write_register(addr, PDU_REG, MSKSET_CA_CB_CHANNEL);
|
||||
// Select number of scan phase
|
||||
CKLED2001_write_register(addr, SCAN_PHASE_REG, PHASE_CHANNEL);
|
||||
// Setting PWM Delay Phase
|
||||
CKLED2001_write_register(addr, SLEW_RATE_CONTROL_MODE1_REG, MSKPWM_DELAY_PHASE_ENABLE);
|
||||
// Setting Driving/Sinking Channel Slew Rate
|
||||
CKLED2001_write_register(addr, SLEW_RATE_CONTROL_MODE2_REG, MSKDRIVING_SINKING_CHHANNEL_SLEWRATE_ENABLE);
|
||||
// Setting Iref
|
||||
CKLED2001_write_register(addr, SOFTWARE_SLEEP_REG, MSKSLEEP_DISABLE);
|
||||
// Set LED CONTROL PAGE (Page 0)
|
||||
CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_CONTROL_PAGE);
|
||||
for (int i = 0; i < LED_CONTROL_ON_OFF_LENGTH; i++) {
|
||||
CKLED2001_write_register(addr, i, 0x00);
|
||||
}
|
||||
|
||||
// Set PWM PAGE (Page 1)
|
||||
CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_PWM_PAGE);
|
||||
for (int i = 0; i < LED_CURRENT_TUNE_LENGTH; i++) {
|
||||
CKLED2001_write_register(addr, i, 0x00);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// Enable LEDs ON/OFF
|
||||
CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_CONTROL_PAGE);
|
||||
for (int i = 0; i < LED_CONTROL_ON_OFF_LENGTH; i++) {
|
||||
CKLED2001_write_register(addr, i, 0xFF);
|
||||
}
|
||||
|
||||
// Select to function page
|
||||
CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE);
|
||||
// Setting LED driver to normal mode
|
||||
CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_NORMAL_MODE);
|
||||
}
|
||||
|
||||
void CKLED2001_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
|
||||
ckled2001_led led;
|
||||
if (index >= 0 && index < DRIVER_LED_TOTAL) {
|
||||
memcpy_P(&led, (&g_ckled2001_leds[index]), sizeof(led));
|
||||
|
||||
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 CKLED2001_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
|
||||
for (int i = 0; i < DRIVER_LED_TOTAL; i++) {
|
||||
CKLED2001_set_color(i, red, green, blue);
|
||||
}
|
||||
}
|
||||
|
||||
void CKLED2001_set_led_control_register(uint8_t index, bool red, bool green, bool blue) {
|
||||
ckled2001_led led;
|
||||
memcpy_P(&led, (&g_ckled2001_leds[index]), sizeof(led));
|
||||
|
||||
uint8_t control_register_r = led.r / 8;
|
||||
uint8_t control_register_g = led.g / 8;
|
||||
uint8_t control_register_b = led.b / 8;
|
||||
uint8_t bit_r = led.r % 8;
|
||||
uint8_t bit_g = led.g % 8;
|
||||
uint8_t bit_b = led.b % 8;
|
||||
|
||||
if (red) {
|
||||
g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r);
|
||||
} else {
|
||||
g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r);
|
||||
}
|
||||
if (green) {
|
||||
g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g);
|
||||
} else {
|
||||
g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g);
|
||||
}
|
||||
if (blue) {
|
||||
g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b);
|
||||
} else {
|
||||
g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b);
|
||||
}
|
||||
|
||||
g_led_control_registers_update_required[led.driver] = true;
|
||||
}
|
||||
|
||||
void CKLED2001_update_pwm_buffers(uint8_t addr, uint8_t index) {
|
||||
if (g_pwm_buffer_update_required[index]) {
|
||||
CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_PWM_PAGE);
|
||||
|
||||
// If any of the transactions fail we risk writing dirty PG0,
|
||||
// refresh page 0 just in case.
|
||||
if (!CKLED2001_write_pwm_buffer(addr, g_pwm_buffer[index])) {
|
||||
g_led_control_registers_update_required[index] = true;
|
||||
}
|
||||
}
|
||||
g_pwm_buffer_update_required[index] = false;
|
||||
}
|
||||
|
||||
void CKLED2001_update_led_control_registers(uint8_t addr, uint8_t index) {
|
||||
if (g_led_control_registers_update_required[index]) {
|
||||
CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_CONTROL_PAGE);
|
||||
for (int i = 0; i < 24; i++) {
|
||||
CKLED2001_write_register(addr, i, g_led_control_registers[index][i]);
|
||||
}
|
||||
}
|
||||
g_led_control_registers_update_required[index] = false;
|
||||
}
|
||||
|
||||
void CKLED2001_return_normal(uint8_t addr) {
|
||||
// Select to function page
|
||||
CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE);
|
||||
// Setting LED driver to normal mode
|
||||
CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_NORMAL_MODE);
|
||||
}
|
||||
|
||||
void CKLED2001_shutdown(uint8_t addr) {
|
||||
// Select to function page
|
||||
CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE);
|
||||
// Setting LED driver to shutdown mode
|
||||
CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_SHUT_DOWN_MODE);
|
||||
// Write SW Sleep Register
|
||||
CKLED2001_write_register(addr, SOFTWARE_SLEEP_REG, MSKSLEEP_ENABLE);
|
||||
}
|
||||
339
drivers/led/ckled2001.h
Normal file
339
drivers/led/ckled2001.h
Normal file
@@ -0,0 +1,339 @@
|
||||
/* Copyright 2021 @ Keychron (https://www.keychron.com)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "progmem.h"
|
||||
|
||||
typedef struct ckled2001_led {
|
||||
uint8_t driver : 2;
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
} __attribute__((packed)) ckled2001_led;
|
||||
|
||||
extern const ckled2001_led PROGMEM g_ckled2001_leds[DRIVER_LED_TOTAL];
|
||||
|
||||
void CKLED2001_init(uint8_t addr);
|
||||
bool CKLED2001_write_register(uint8_t addr, uint8_t reg, uint8_t data);
|
||||
bool CKLED2001_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer);
|
||||
|
||||
void CKLED2001_set_color(int index, uint8_t red, uint8_t green, uint8_t blue);
|
||||
void CKLED2001_set_color_all(uint8_t red, uint8_t green, uint8_t blue);
|
||||
|
||||
void CKLED2001_set_led_control_register(uint8_t index, bool red, bool green, bool blue);
|
||||
|
||||
// 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 CKLED2001_update_pwm_buffers(uint8_t addr, uint8_t index);
|
||||
void CKLED2001_update_led_control_registers(uint8_t addr, uint8_t index);
|
||||
|
||||
void CKLED2001_return_normal(uint8_t addr);
|
||||
void CKLED2001_shutdown(uint8_t addr);
|
||||
|
||||
// Registers Page Define
|
||||
#define CONFIGURE_CMD_PAGE 0xFD
|
||||
#define LED_CONTROL_PAGE 0x00
|
||||
#define LED_PWM_PAGE 0x01
|
||||
#define FUNCTION_PAGE 0x03
|
||||
#define CURRENT_TUNE_PAGE 0x04
|
||||
|
||||
// Function Register: address 0x00
|
||||
#define CONFIGURATION_REG 0x00
|
||||
#define MSKSW_SHUT_DOWN_MODE (0x0 << 0)
|
||||
#define MSKSW_NORMAL_MODE (0x1 << 0)
|
||||
|
||||
#define DRIVER_ID_REG 0x11
|
||||
#define CKLED2001_ID 0x8A
|
||||
|
||||
#define PDU_REG 0x13
|
||||
#define MSKSET_CA_CB_CHANNEL 0xAA
|
||||
#define MSKCLR_CA_CB_CHANNEL 0x00
|
||||
|
||||
#define SCAN_PHASE_REG 0x14
|
||||
#define MSKPHASE_12CHANNEL 0x00
|
||||
#define MSKPHASE_11CHANNEL 0x01
|
||||
#define MSKPHASE_10CHANNEL 0x02
|
||||
#define MSKPHASE_9CHANNEL 0x03
|
||||
#define MSKPHASE_8CHANNEL 0x04
|
||||
#define MSKPHASE_7CHANNEL 0x05
|
||||
#define MSKPHASE_6CHANNEL 0x06
|
||||
#define MSKPHASE_5CHANNEL 0x07
|
||||
#define MSKPHASE_4CHANNEL 0x08
|
||||
#define MSKPHASE_3CHANNEL 0x09
|
||||
#define MSKPHASE_2CHANNEL 0x0A
|
||||
#define MSKPHASE_1CHANNEL 0x0B
|
||||
|
||||
#define SLEW_RATE_CONTROL_MODE1_REG 0x15
|
||||
#define MSKPWM_DELAY_PHASE_ENABLE 0x04
|
||||
#define MSKPWM_DELAY_PHASE_DISABLE 0x00
|
||||
|
||||
#define SLEW_RATE_CONTROL_MODE2_REG 0x16
|
||||
#define MSKDRIVING_SINKING_CHHANNEL_SLEWRATE_ENABLE 0xC0
|
||||
#define MSKDRIVING_SINKING_CHHANNEL_SLEWRATE_DISABLE 0x00
|
||||
|
||||
#define OPEN_SHORT_ENABLE_REG 0x17
|
||||
#define MSKOPEN_DETECTION_ENABLE (0x01 << 7)
|
||||
#define MSKOPEN_DETECTION_DISABLE (0x00)
|
||||
|
||||
#define MSKSHORT_DETECTION_ENABLE (0x01 << 6)
|
||||
#define MSKSHORT_DETECTION_DISABLE (0x00)
|
||||
|
||||
#define OPEN_SHORT_DUTY_REG 0x18
|
||||
#define OPEN_SHORT_FLAG_REG 0x19
|
||||
|
||||
#define MSKOPEN_DETECTION_INTERRUPT_ENABLE (0x01 << 7)
|
||||
#define MSKOPEN_DETECTION_INTERRUPT_DISABLE (0x00)
|
||||
|
||||
#define MSKSHORT_DETECTION_INTERRUPT_ENABLE (0x01 << 6)
|
||||
#define MSKSHORT_DETECTION_INTERRUPT_DISABLE (0x00)
|
||||
|
||||
#define SOFTWARE_SLEEP_REG 0x1A
|
||||
#define MSKSLEEP_ENABLE 0x02
|
||||
#define MSKSLEEP_DISABLE 0x00
|
||||
|
||||
// LED Control Registers
|
||||
#define LED_CONTROL_ON_OFF_FIRST_ADDR 0x0
|
||||
#define LED_CONTROL_ON_OFF_LAST_ADDR 0x17
|
||||
#define LED_CONTROL_ON_OFF_LENGTH ((LED_CONTROL_ON_OFF_LAST_ADDR - LED_CONTROL_ON_OFF_FIRST_ADDR) + 1)
|
||||
|
||||
#define LED_CONTROL_OPEN_FIRST_ADDR 0x18
|
||||
#define LED_CONTROL_OPEN_LAST_ADDR 0x2F
|
||||
#define LED_CONTROL_OPEN_LENGTH ((LED_CONTROL_OPEN_LAST_ADDR - LED_CONTROL_OPEN_FIRST_ADDR) + 1)
|
||||
|
||||
#define LED_CONTROL_SHORT_FIRST_ADDR 0x30
|
||||
#define LED_CONTROL_SHORT_LAST_ADDR 0x47
|
||||
#define LED_CONTROL_SHORT_LENGTH ((LED_CONTROL_SHORT_LAST_ADDR - LED_CONTROL_SHORT_FIRST_ADDR) + 1)
|
||||
|
||||
#define LED_CONTROL_PAGE_LENGTH 0x48
|
||||
|
||||
// LED Control Registers
|
||||
#define LED_PWM_FIRST_ADDR 0x00
|
||||
#define LED_PWM_LAST_ADDR 0xBF
|
||||
#define LED_PWM_LENGTH 0xC0
|
||||
|
||||
// Current Tune Registers
|
||||
#define LED_CURRENT_TUNE_FIRST_ADDR 0x00
|
||||
#define LED_CURRENT_TUNE_LAST_ADDR 0x0B
|
||||
#define LED_CURRENT_TUNE_LENGTH 0x0C
|
||||
|
||||
#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
|
||||
@@ -1,6 +1,7 @@
|
||||
/* Copyright 2017 Jason Williams
|
||||
* Copyright 2018 Jack Humbert
|
||||
* Copyright 2019 Clueboard
|
||||
* Copyright 2021 Doni Crosby
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -40,6 +41,9 @@
|
||||
|
||||
#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_SHUTDOWN 0x0A
|
||||
#define ISSI_REG_AUDIOSYNC 0x06
|
||||
|
||||
@@ -144,6 +148,9 @@ 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
|
||||
IS31FL3731_write_register(addr, ISSI_REG_GHOST_IMAGE_PREVENTION, 0x10);
|
||||
#endif
|
||||
|
||||
// this delay was copied from other drivers, might not be needed
|
||||
wait_ms(10);
|
||||
@@ -186,8 +193,9 @@ void IS31FL3731_init(uint8_t addr) {
|
||||
}
|
||||
|
||||
void IS31FL3731_set_value(int index, uint8_t value) {
|
||||
is31_led led;
|
||||
if (index >= 0 && index < DRIVER_LED_TOTAL) {
|
||||
is31_led led = g_is31_leds[index];
|
||||
memcpy_P(&led, (&g_is31_leds[index]), sizeof(led));
|
||||
|
||||
// Subtract 0x24 to get the second index of g_pwm_buffer
|
||||
g_pwm_buffer[led.driver][led.v - 0x24] = value;
|
||||
@@ -202,7 +210,8 @@ void IS31FL3731_set_value_all(uint8_t value) {
|
||||
}
|
||||
|
||||
void IS31FL3731_set_led_control_register(uint8_t index, bool value) {
|
||||
is31_led led = g_is31_leds[index];
|
||||
is31_led led;
|
||||
memcpy_P(&led, (&g_is31_leds[index]), sizeof(led));
|
||||
|
||||
uint8_t control_register = (led.v - 0x24) / 8;
|
||||
uint8_t bit_value = (led.v - 0x24) % 8;
|
||||
|
||||
@@ -27,7 +27,7 @@ typedef struct is31_led {
|
||||
uint8_t v;
|
||||
} __attribute__((packed)) is31_led;
|
||||
|
||||
extern const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL];
|
||||
extern const is31_led PROGMEM g_is31_leds[DRIVER_LED_TOTAL];
|
||||
|
||||
void IS31FL3731_init(uint8_t addr);
|
||||
void IS31FL3731_write_register(uint8_t addr, uint8_t reg, uint8_t data);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* Copyright 2017 Jason Williams
|
||||
* Copyright 2018 Jack Humbert
|
||||
* Copyright 2021 Doni Crosby
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -39,6 +40,9 @@
|
||||
|
||||
#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_SHUTDOWN 0x0A
|
||||
#define ISSI_REG_AUDIOSYNC 0x06
|
||||
|
||||
@@ -132,6 +136,9 @@ 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
|
||||
IS31FL3731_write_register(addr, ISSI_REG_GHOST_IMAGE_PREVENTION, 0x10);
|
||||
#endif
|
||||
|
||||
// this delay was copied from other drivers, might not be needed
|
||||
wait_ms(10);
|
||||
@@ -174,8 +181,9 @@ void IS31FL3731_init(uint8_t addr) {
|
||||
}
|
||||
|
||||
void IS31FL3731_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
|
||||
is31_led led;
|
||||
if (index >= 0 && index < DRIVER_LED_TOTAL) {
|
||||
is31_led led = g_is31_leds[index];
|
||||
memcpy_P(&led, (&g_is31_leds[index]), sizeof(led));
|
||||
|
||||
// Subtract 0x24 to get the second index of g_pwm_buffer
|
||||
g_pwm_buffer[led.driver][led.r - 0x24] = red;
|
||||
@@ -192,7 +200,8 @@ void IS31FL3731_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
|
||||
}
|
||||
|
||||
void IS31FL3731_set_led_control_register(uint8_t index, bool red, bool green, bool blue) {
|
||||
is31_led led = g_is31_leds[index];
|
||||
is31_led led;
|
||||
memcpy_P(&led, (&g_is31_leds[index]), sizeof(led));
|
||||
|
||||
uint8_t control_register_r = (led.r - 0x24) / 8;
|
||||
uint8_t control_register_g = (led.g - 0x24) / 8;
|
||||
|
||||
@@ -28,7 +28,7 @@ typedef struct is31_led {
|
||||
uint8_t b;
|
||||
} __attribute__((packed)) is31_led;
|
||||
|
||||
extern const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL];
|
||||
extern const is31_led PROGMEM g_is31_leds[DRIVER_LED_TOTAL];
|
||||
|
||||
void IS31FL3731_init(uint8_t addr);
|
||||
void IS31FL3731_write_register(uint8_t addr, uint8_t reg, uint8_t data);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* Copyright 2017 Jason Williams
|
||||
* Copyright 2018 Jack Humbert
|
||||
* Copyright 2018 Yiancar
|
||||
* Copyright 2021 Doni Crosby
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -56,6 +57,18 @@
|
||||
# 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];
|
||||
|
||||
@@ -154,18 +167,23 @@ void IS31FL3733_init(uint8_t addr, uint8_t sync) {
|
||||
|
||||
// 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 << 6) | 0x01);
|
||||
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_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
|
||||
is31_led led;
|
||||
if (index >= 0 && index < DRIVER_LED_TOTAL) {
|
||||
is31_led led = g_is31_leds[index];
|
||||
memcpy_P(&led, (&g_is31_leds[index]), sizeof(led));
|
||||
|
||||
g_pwm_buffer[led.driver][led.r] = red;
|
||||
g_pwm_buffer[led.driver][led.g] = green;
|
||||
@@ -181,7 +199,8 @@ void IS31FL3733_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
|
||||
}
|
||||
|
||||
void IS31FL3733_set_led_control_register(uint8_t index, bool red, bool green, bool blue) {
|
||||
is31_led led = g_is31_leds[index];
|
||||
is31_led led;
|
||||
memcpy_P(&led, (&g_is31_leds[index]), sizeof(led));
|
||||
|
||||
uint8_t control_register_r = led.r / 8;
|
||||
uint8_t control_register_g = led.g / 8;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* Copyright 2017 Jason Williams
|
||||
* Copyright 2018 Jack Humbert
|
||||
* Copyright 2018 Yiancar
|
||||
* Copyright 2021 Doni Crosby
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -29,7 +30,7 @@ typedef struct is31_led {
|
||||
uint8_t b;
|
||||
} __attribute__((packed)) is31_led;
|
||||
|
||||
extern const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL];
|
||||
extern const is31_led PROGMEM 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);
|
||||
@@ -47,6 +48,14 @@ 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 A_1 0x00
|
||||
#define A_2 0x01
|
||||
#define A_3 0x02
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/* Copyright 2018 Jason Williams (Wilba)
|
||||
* Copyright 2021 Doni Crosby
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -54,6 +55,14 @@
|
||||
# define ISSI_PERSISTENCE 0
|
||||
#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];
|
||||
|
||||
@@ -140,6 +149,10 @@ void IS31FL3736_init(uint8_t addr) {
|
||||
|
||||
// Select PG3
|
||||
IS31FL3736_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_FUNCTION);
|
||||
// Set de-ghost pull-up resistors (SWx)
|
||||
IS31FL3736_write_register(addr, ISSI_REG_SWPULLUP, ISSI_SWPULLUP);
|
||||
// Set de-ghost pull-down resistors (CSx)
|
||||
IS31FL3736_write_register(addr, ISSI_REG_CSPULLUP, ISSI_CSPULLUP);
|
||||
// Set global current to maximum.
|
||||
IS31FL3736_write_register(addr, ISSI_REG_GLOBALCURRENT, 0xFF);
|
||||
// Disable software shutdown.
|
||||
@@ -150,8 +163,9 @@ void IS31FL3736_init(uint8_t addr) {
|
||||
}
|
||||
|
||||
void IS31FL3736_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
|
||||
is31_led led;
|
||||
if (index >= 0 && index < DRIVER_LED_TOTAL) {
|
||||
is31_led led = g_is31_leds[index];
|
||||
memcpy_P(&led, (&g_is31_leds[index]), sizeof(led));
|
||||
|
||||
g_pwm_buffer[led.driver][led.r] = red;
|
||||
g_pwm_buffer[led.driver][led.g] = green;
|
||||
@@ -167,7 +181,8 @@ void IS31FL3736_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
|
||||
}
|
||||
|
||||
void IS31FL3736_set_led_control_register(uint8_t index, bool red, bool green, bool blue) {
|
||||
is31_led led = g_is31_leds[index];
|
||||
is31_led led;
|
||||
memcpy_P(&led, (&g_is31_leds[index]), sizeof(led));
|
||||
|
||||
// IS31FL3733
|
||||
// The PWM register for a matrix position (0x00 to 0xBF) can be
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/* Copyright 2018 Jason Williams (Wilba)
|
||||
* Copyright 2021 Doni Crosby
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -38,7 +39,7 @@ typedef struct is31_led {
|
||||
uint8_t b;
|
||||
} __attribute__((packed)) is31_led;
|
||||
|
||||
extern const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL];
|
||||
extern const is31_led PROGMEM g_is31_leds[DRIVER_LED_TOTAL];
|
||||
|
||||
void IS31FL3736_init(uint8_t addr);
|
||||
void IS31FL3736_write_register(uint8_t addr, uint8_t reg, uint8_t data);
|
||||
@@ -60,6 +61,15 @@ 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 A_1 0x00
|
||||
#define A_2 0x02
|
||||
#define A_3 0x04
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* Copyright 2017 Jason Williams
|
||||
* Copyright 2018 Jack Humbert
|
||||
* Copyright 2018 Yiancar
|
||||
* Copyright 2021 Doni Crosby
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -56,6 +57,14 @@
|
||||
# define ISSI_PERSISTENCE 0
|
||||
#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];
|
||||
|
||||
@@ -143,6 +152,10 @@ void IS31FL3737_init(uint8_t addr) {
|
||||
|
||||
// Select PG3
|
||||
IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_FUNCTION);
|
||||
// Set de-ghost pull-up resistors (SWx)
|
||||
IS31FL3737_write_register(addr, ISSI_REG_SWPULLUP, ISSI_SWPULLUP);
|
||||
// Set de-ghost pull-down resistors (CSx)
|
||||
IS31FL3737_write_register(addr, ISSI_REG_CSPULLUP, ISSI_CSPULLUP);
|
||||
// Set global current to maximum.
|
||||
IS31FL3737_write_register(addr, ISSI_REG_GLOBALCURRENT, 0xFF);
|
||||
// Disable software shutdown.
|
||||
@@ -153,8 +166,9 @@ void IS31FL3737_init(uint8_t addr) {
|
||||
}
|
||||
|
||||
void IS31FL3737_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
|
||||
is31_led led;
|
||||
if (index >= 0 && index < DRIVER_LED_TOTAL) {
|
||||
is31_led led = g_is31_leds[index];
|
||||
memcpy_P(&led, (&g_is31_leds[index]), sizeof(led));
|
||||
|
||||
g_pwm_buffer[led.driver][led.r] = red;
|
||||
g_pwm_buffer[led.driver][led.g] = green;
|
||||
@@ -170,7 +184,8 @@ void IS31FL3737_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
|
||||
}
|
||||
|
||||
void IS31FL3737_set_led_control_register(uint8_t index, bool red, bool green, bool blue) {
|
||||
is31_led led = g_is31_leds[index];
|
||||
is31_led led;
|
||||
memcpy_P(&led, (&g_is31_leds[index]), sizeof(led));
|
||||
|
||||
uint8_t control_register_r = led.r / 8;
|
||||
uint8_t control_register_g = led.g / 8;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* Copyright 2017 Jason Williams
|
||||
* Copyright 2018 Jack Humbert
|
||||
* Copyright 2018 Yiancar
|
||||
* Copyright 2021 Doni Crosby
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -29,7 +30,7 @@ typedef struct is31_led {
|
||||
uint8_t b;
|
||||
} __attribute__((packed)) is31_led;
|
||||
|
||||
extern const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL];
|
||||
extern const is31_led PROGMEM g_is31_leds[DRIVER_LED_TOTAL];
|
||||
|
||||
void IS31FL3737_init(uint8_t addr);
|
||||
void IS31FL3737_write_register(uint8_t addr, uint8_t reg, uint8_t data);
|
||||
@@ -47,6 +48,15 @@ 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 A_1 0x00
|
||||
#define A_2 0x01
|
||||
#define A_3 0x02
|
||||
|
||||
@@ -61,6 +61,14 @@
|
||||
# define ISSI_PERSISTENCE 0
|
||||
#endif
|
||||
|
||||
#ifndef ISSI_SWPULLUP
|
||||
# define ISSI_SWPULLUP PUR_32KR
|
||||
#endif
|
||||
|
||||
#ifndef ISSI_CSPULLUP
|
||||
# define ISSI_CSPULLUP PUR_32KR
|
||||
#endif
|
||||
|
||||
#define ISSI_MAX_LEDS 351
|
||||
|
||||
// Transfer buffer for TWITransmitData()
|
||||
@@ -157,7 +165,7 @@ void IS31FL3741_init(uint8_t addr) {
|
||||
// Set Golbal Current Control Register
|
||||
IS31FL3741_write_register(addr, ISSI_REG_GLOBALCURRENT, 0xFF);
|
||||
// Set Pull up & Down for SWx CSy
|
||||
IS31FL3741_write_register(addr, ISSI_REG_PULLDOWNUP, 0x77);
|
||||
IS31FL3741_write_register(addr, ISSI_REG_PULLDOWNUP, ((ISSI_CSPULLUP << 4) | ISSI_SWPULLUP));
|
||||
|
||||
// IS31FL3741_update_led_scaling_registers(addr, 0xFF, 0xFF, 0xFF);
|
||||
|
||||
@@ -166,8 +174,9 @@ void IS31FL3741_init(uint8_t addr) {
|
||||
}
|
||||
|
||||
void IS31FL3741_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
|
||||
is31_led led;
|
||||
if (index >= 0 && index < DRIVER_LED_TOTAL) {
|
||||
is31_led led = g_is31_leds[index];
|
||||
memcpy_P(&led, (&g_is31_leds[index]), sizeof(led));
|
||||
|
||||
g_pwm_buffer[led.driver][led.r] = red;
|
||||
g_pwm_buffer[led.driver][led.g] = green;
|
||||
@@ -183,7 +192,8 @@ void IS31FL3741_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
|
||||
}
|
||||
|
||||
void IS31FL3741_set_led_control_register(uint8_t index, bool red, bool green, bool blue) {
|
||||
is31_led led = g_is31_leds[index];
|
||||
is31_led led;
|
||||
memcpy_P(&led, (&g_is31_leds[index]), sizeof(led));
|
||||
|
||||
if (red) {
|
||||
g_scaling_registers[led.driver][led.r] = 0xFF;
|
||||
|
||||
@@ -30,7 +30,7 @@ typedef struct is31_led {
|
||||
uint32_t b : 10;
|
||||
} __attribute__((packed)) is31_led;
|
||||
|
||||
extern const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL];
|
||||
extern const is31_led PROGMEM g_is31_leds[DRIVER_LED_TOTAL];
|
||||
|
||||
void IS31FL3741_init(uint8_t addr);
|
||||
void IS31FL3741_write_register(uint8_t addr, uint8_t reg, uint8_t data);
|
||||
@@ -51,6 +51,15 @@ 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 CS1_SW1 0x00
|
||||
#define CS2_SW1 0x01
|
||||
#define CS3_SW1 0x02
|
||||
|
||||
@@ -190,6 +190,7 @@ bool oled_init(oled_rotation_t rotation);
|
||||
// Called at the start of oled_init, weak function overridable by the user
|
||||
// rotation - the value passed into oled_init
|
||||
// Return new oled_rotation_t if you want to override default rotation
|
||||
oled_rotation_t oled_init_kb(oled_rotation_t rotation);
|
||||
oled_rotation_t oled_init_user(oled_rotation_t rotation);
|
||||
|
||||
// Clears the display buffer, resets cursor position to 0, and sets the buffer to dirty for rendering
|
||||
@@ -285,7 +286,8 @@ uint8_t oled_get_brightness(void);
|
||||
void oled_task(void);
|
||||
|
||||
// Called at the start of oled_task, weak function overridable by the user
|
||||
void oled_task_user(void);
|
||||
bool oled_task_kb(void);
|
||||
bool oled_task_user(void);
|
||||
|
||||
// Set the specific 8 lines rows of the screen to scroll.
|
||||
// 0 is the default for start, and 7 for end, which is the entire
|
||||
|
||||
@@ -167,7 +167,7 @@ bool oled_init(oled_rotation_t rotation) {
|
||||
}
|
||||
#endif
|
||||
|
||||
oled_rotation = oled_init_user(rotation);
|
||||
oled_rotation = oled_init_user(oled_init_kb(rotation));
|
||||
if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) {
|
||||
oled_rotation_width = OLED_DISPLAY_WIDTH;
|
||||
} else {
|
||||
@@ -232,6 +232,7 @@ 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; }
|
||||
|
||||
void oled_clear(void) {
|
||||
@@ -741,11 +742,11 @@ void oled_task(void) {
|
||||
if (timer_elapsed(oled_update_timeout) >= OLED_UPDATE_INTERVAL) {
|
||||
oled_update_timeout = timer_read();
|
||||
oled_set_cursor(0, 0);
|
||||
oled_task_user();
|
||||
oled_task_kb();
|
||||
}
|
||||
#else
|
||||
oled_set_cursor(0, 0);
|
||||
oled_task_user();
|
||||
oled_task_kb();
|
||||
#endif
|
||||
|
||||
#if OLED_SCROLL_TIMEOUT > 0
|
||||
@@ -776,4 +777,5 @@ void oled_task(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
__attribute__((weak)) void oled_task_user(void) {}
|
||||
__attribute__((weak)) bool oled_task_kb(void) { return oled_task_user(); }
|
||||
__attribute__((weak)) bool oled_task_user(void) { return true; }
|
||||
|
||||
@@ -74,16 +74,16 @@ void ps2_interrupt_service_routine(void);
|
||||
void palCallback(void *arg) { ps2_interrupt_service_routine(); }
|
||||
|
||||
# define PS2_INT_INIT() \
|
||||
{ palSetLineMode(PS2_CLOCK, PAL_MODE_INPUT); } \
|
||||
{ palSetLineMode(PS2_CLOCK_PIN, PAL_MODE_INPUT); } \
|
||||
while (0)
|
||||
# define PS2_INT_ON() \
|
||||
{ \
|
||||
palEnableLineEvent(PS2_CLOCK, PAL_EVENT_MODE_FALLING_EDGE); \
|
||||
palSetLineCallback(PS2_CLOCK, palCallback, NULL); \
|
||||
palEnableLineEvent(PS2_CLOCK_PIN, PAL_EVENT_MODE_FALLING_EDGE); \
|
||||
palSetLineCallback(PS2_CLOCK_PIN, palCallback, NULL); \
|
||||
} \
|
||||
while (0)
|
||||
# define PS2_INT_OFF() \
|
||||
{ palDisableLineEvent(PS2_CLOCK); } \
|
||||
{ palDisableLineEvent(PS2_CLOCK_PIN); } \
|
||||
while (0)
|
||||
#endif // PROTOCOL_CHIBIOS
|
||||
|
||||
@@ -16,13 +16,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#if defined(__AVR__)
|
||||
# include <avr/io.h>
|
||||
#endif
|
||||
|
||||
#include "ps2_mouse.h"
|
||||
#include "wait.h"
|
||||
#include "gpio.h"
|
||||
#include "host.h"
|
||||
#include "timer.h"
|
||||
#include "print.h"
|
||||
@@ -1,482 +0,0 @@
|
||||
/* Jim Lindblom @ SparkFun Electronics
|
||||
* October 26, 2014
|
||||
* https://github.com/sparkfun/Micro_OLED_Breakout/tree/master/Firmware/Arduino/libraries/SFE_MicroOLED
|
||||
*
|
||||
* Modified by:
|
||||
* Emil Varughese @ Edwin Robotics Pvt. Ltd.
|
||||
* July 27, 2015
|
||||
* https://github.com/emil01/SparkFun_Micro_OLED_Arduino_Library/
|
||||
*
|
||||
* This code was heavily based around the MicroView library, written by GeekAmmo
|
||||
* (https://github.com/geekammo/MicroView-Arduino-Library).
|
||||
*
|
||||
* Adapted for QMK by:
|
||||
* Jack Humbert <jack.humb@gmail.com>
|
||||
* October 11, 2018
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "micro_oled.h"
|
||||
#include "print.h"
|
||||
#include <stdlib.h>
|
||||
#include "util/font5x7.h"
|
||||
#include "util/font8x16.h"
|
||||
#include <string.h>
|
||||
|
||||
#define TOTALFONTS 2
|
||||
const unsigned char* fonts_pointer[] = {font5x7, font8x16};
|
||||
|
||||
uint8_t foreColor, drawMode, fontWidth, fontHeight, fontType, fontStartChar, fontTotalChar, cursorX, cursorY;
|
||||
uint16_t fontMapWidth;
|
||||
|
||||
#ifndef _BV
|
||||
# define _BV(x) (1 << (x))
|
||||
#endif
|
||||
|
||||
#define swap(a, b) \
|
||||
{ \
|
||||
uint8_t t = a; \
|
||||
a = b; \
|
||||
b = t; \
|
||||
}
|
||||
|
||||
uint8_t micro_oled_transfer_buffer[20];
|
||||
static uint8_t micro_oled_screen_current[LCDWIDTH * LCDHEIGHT / 8] = {0};
|
||||
|
||||
/* LCD Memory organised in 64 horizontal pixel and 6 rows of byte
|
||||
B B .............B -----
|
||||
y y .............y \
|
||||
t t .............t \
|
||||
e e .............e \
|
||||
0 1 .............63 \
|
||||
\
|
||||
D0 D0.............D0 \
|
||||
D1 D1.............D1 / ROW 0
|
||||
D2 D2.............D2 /
|
||||
D3 D3.............D3 /
|
||||
D4 D4.............D4 /
|
||||
D5 D5.............D5 /
|
||||
D6 D6.............D6 /
|
||||
D7 D7.............D7 ----
|
||||
*/
|
||||
#ifdef NO_LCD_SPLASH
|
||||
// do not initialize with a splash screen
|
||||
static uint8_t micro_oled_screen_buffer[LCDWIDTH * LCDHEIGHT / 8] = {0};
|
||||
#else
|
||||
# if LCDWIDTH == 64
|
||||
# if LCDHEIGHT == 48
|
||||
static uint8_t micro_oled_screen_buffer[] = {
|
||||
// QMK Logo - generated at http://www.majer.ch/lcd/adf_bitmap.php
|
||||
// 64x48 image
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0xF8, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xF8, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x8C, 0x8C, 0x8C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8C, 0x8C, 0x8C, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x31, 0x31, 0x31, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF8, 0xF1, 0xE3, 0xE7, 0xCF, 0xCF, 0xCF, 0xCF, 0x00, 0x00, 0xCF, 0xCF, 0xCF, 0xC7, 0xE7, 0xE3, 0xF1, 0xF8, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x31, 0x31, 0x31, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x1F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x1F, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
# endif
|
||||
# elif LCDWIDTH == 128
|
||||
# if LCDHEIGHT == 32
|
||||
static uint8_t micro_oled_screen_buffer[LCDWIDTH * LCDHEIGHT / 8] = {
|
||||
// 128x32 qmk image
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xE0, 0xFC, 0xFC, 0xE0, 0xFC, 0xFC, 0xE0, 0xF0, 0xFC, 0xE0, 0xE0, 0xFC, 0xE0, 0xE0, 0xFC, 0xFC, 0xE0, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x10, 0x10, 0x30, 0xE0, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xB2, 0xB2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x03, 0xFF, 0xFF, 0xFF, 0x03, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xB7, 0xB2, 0xB2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x02, 0x02, 0x03, 0x01, 0x00, 0x06, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x06, 0x00, 0x03, 0x1E, 0x18, 0x0F, 0x01, 0x0F, 0x18, 0x1E, 0x01, 0x00, 0x0F, 0x1F, 0x12, 0x02, 0x12, 0x13, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x0E, 0x1F, 0x12, 0x02, 0x12, 0x13, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x4D, 0x4D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xF8, 0xF9, 0xF3, 0xF3, 0xC0, 0x80, 0xF3, 0xF3, 0xF3, 0xF9, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, 0x4D, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x20, 0x10, 0x10, 0xE0, 0xC0, 0x00, 0x70, 0xC0, 0x00, 0x80, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0C, 0x04, 0x04, 0x04, 0x04, 0x1C, 0xF0, 0x00, 0x00, 0xFC, 0x0C, 0x38, 0xE0, 0x00, 0x00, 0xC0, 0x38, 0x0C, 0xFC, 0x00, 0x00, 0xFC, 0xFC, 0x60, 0x90, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x3F, 0x3F, 0x07, 0x3F, 0x3F, 0x07, 0x0F, 0x3F, 0x07, 0x07, 0x3F, 0x07, 0x07, 0x3F, 0x3F, 0x07, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x06, 0x04, 0x04, 0x07, 0x01, 0x00, 0x00, 0x13, 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x04, 0x04, 0x04, 0x04, 0x07, 0x0D, 0x08, 0x00, 0x07, 0x00, 0x00, 0x01, 0x07, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x07, 0x00, 0x01, 0x03, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
# elif LCDHEIGHT == 64
|
||||
static uint8_t micro_oled_screen_buffer[LCDWIDTH * LCDHEIGHT / 8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xF8, 0xFC, 0xFC, 0xFE, 0xFE, 0xFF, 0x7F, 0x7E, 0xFE, 0xFF, 0xFF, 0xFE, 0xFE, 0x7F, 0x7F, 0xFE, 0xFE, 0xFF, 0xFF, 0xFE, 0x7E, 0x7F, 0xFF, 0xFE, 0xFE, 0xFC, 0xFC, 0xF8, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x88, 0xDD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDD, 0x88, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x99, 0x99, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xF8, 0xF0, 0xF3, 0xF3, 0xE7, 0xE7, 0x00, 0x00, 0xE7, 0xE7, 0xF3, 0xF3, 0xF0, 0xF8, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0x99, 0x99, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x0F, 0x1F, 0x3F, 0x3F, 0x3F, 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xFF, 0x3F, 0x3F, 0x3F, 0x1F, 0x0F, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x03, 0x01, 0x00, 0x80, 0x03, 0x03, 0x00, 0x00, 0x01, 0x03, 0x00, 0x80, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x11, 0x11, 0x11, 0x0E, 0x00, 0x70, 0x88, 0x04, 0x04, 0x04, 0xF8, 0x00, 0x00, 0x3C, 0xE0, 0xC0, 0x38, 0x1C, 0xE0, 0x80, 0x70, 0x0C, 0x00, 0xF8, 0xAC, 0x24, 0x24, 0x3C, 0x30, 0x00, 0x00, 0xFC, 0x0C, 0x04, 0x00, 0xF8, 0xAC, 0x24, 0x24, 0x2C, 0x30, 0x00, 0x70, 0xDC, 0x04, 0x04, 0x88, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x8C, 0x04, 0x04, 0xF8, 0x00, 0x04, 0x3C, 0xE0, 0x80, 0xF0, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x83, 0x01, 0x01, 0x01, 0x81, 0xFE, 0x3C, 0x00, 0x00, 0xFF, 0x03, 0x0E, 0x70, 0xC0, 0xE0, 0x38, 0x06, 0x03, 0xFF, 0x00, 0x00, 0xFF, 0x18, 0x38, 0x66, 0xC3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
// TODO: generate bitmap of QMK logo here
|
||||
# endif
|
||||
# else
|
||||
// catchall for custom screen sizes
|
||||
static uint8_t micro_oled_screen_buffer[LCDWIDTH * LCDHEIGHT / 8] = {0};
|
||||
# endif
|
||||
#endif
|
||||
|
||||
void micro_oled_init(void) {
|
||||
i2c_init();
|
||||
|
||||
#ifdef __AVR__
|
||||
i2c_start(I2C_ADDRESS_SA0_1, 100);
|
||||
#else
|
||||
i2c_start(I2C_ADDRESS_SA0_1);
|
||||
#endif
|
||||
|
||||
// Display Init sequence for 64x48 OLED module
|
||||
send_command(DISPLAYOFF); // 0xAE
|
||||
|
||||
send_command(SETDISPLAYCLOCKDIV); // 0xD5
|
||||
send_command(0x80); // the suggested ratio 0x80
|
||||
|
||||
send_command(SETMULTIPLEX); // 0xA8
|
||||
send_command(LCDHEIGHT - 1);
|
||||
|
||||
send_command(SETDISPLAYOFFSET); // 0xD3
|
||||
send_command(0x00); // no offset
|
||||
|
||||
send_command(SETSTARTLINE | 0x00); // line #0
|
||||
|
||||
send_command(CHARGEPUMP); // enable charge pump
|
||||
send_command(0x14);
|
||||
|
||||
send_command(NORMALDISPLAY); // 0xA6
|
||||
send_command(DISPLAYALLONRESUME); // 0xA4
|
||||
|
||||
// display at regular orientation
|
||||
send_command(SEGREMAP | 0x1);
|
||||
send_command(COMSCANDEC);
|
||||
|
||||
// rotate display 180
|
||||
#ifdef micro_oled_rotate_180
|
||||
send_command(SEGREMAP);
|
||||
send_command(COMSCANINC);
|
||||
#endif
|
||||
|
||||
send_command(MEMORYMODE);
|
||||
send_command(0x02); // 0x02 = 10b, Page addressing mode
|
||||
|
||||
send_command(SETCOMPINS); // 0xDA
|
||||
if (LCDHEIGHT > 32) {
|
||||
send_command(0x12);
|
||||
} else {
|
||||
send_command(0x02);
|
||||
}
|
||||
send_command(SETCONTRAST); // 0x81
|
||||
send_command(0x8F);
|
||||
|
||||
send_command(SETPRECHARGE); // 0xd9
|
||||
send_command(0xF1);
|
||||
|
||||
send_command(SETVCOMDESELECT); // 0xDB
|
||||
send_command(0x40);
|
||||
|
||||
send_command(DISPLAYON); //--turn on oled panel
|
||||
clear_screen(); // Erase hardware memory inside the OLED controller to avoid random data in memory.
|
||||
send_buffer();
|
||||
}
|
||||
|
||||
void send_command(uint8_t command) {
|
||||
micro_oled_transfer_buffer[0] = I2C_COMMAND;
|
||||
micro_oled_transfer_buffer[1] = command;
|
||||
i2c_transmit(I2C_ADDRESS_SA0_1 << 1, micro_oled_transfer_buffer, 2, 100);
|
||||
}
|
||||
|
||||
void send_data(uint8_t data) {
|
||||
micro_oled_transfer_buffer[0] = I2C_DATA;
|
||||
micro_oled_transfer_buffer[1] = data;
|
||||
i2c_transmit(I2C_ADDRESS_SA0_1 << 1, micro_oled_transfer_buffer, 2, 100);
|
||||
}
|
||||
|
||||
/** \brief Set SSD1306 page address.
|
||||
Send page address command and address to the SSD1306 OLED controller.
|
||||
*/
|
||||
void set_page_address(uint8_t address) {
|
||||
address = (0xB0 | address);
|
||||
send_command(address);
|
||||
}
|
||||
|
||||
/** \brief Set SSD1306 column address.
|
||||
Send column address command and address to the SSD1306 OLED controller.
|
||||
*/
|
||||
void set_column_address(uint8_t address) {
|
||||
send_command((0x10 | (address >> 4)) + ((128 - LCDWIDTH) >> 8));
|
||||
send_command(0x0F & address);
|
||||
}
|
||||
|
||||
/** \brief Clear SSD1306's memory.
|
||||
To clear GDRAM inside the LCD controller.
|
||||
*/
|
||||
void clear_screen(void) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
set_page_address(i);
|
||||
set_column_address(0);
|
||||
for (int j = 0; j < 0x80; j++) {
|
||||
send_data(0);
|
||||
}
|
||||
}
|
||||
|
||||
memset(micro_oled_screen_current, 0, LCDWIDTH * LCDHEIGHT / 8);
|
||||
}
|
||||
|
||||
/** \brief Clear SSD1306's memory.
|
||||
To clear GDRAM inside the LCD controller.
|
||||
*/
|
||||
void clear_buffer(void) {
|
||||
// 384
|
||||
memset(micro_oled_screen_buffer, 0, LCDWIDTH * LCDHEIGHT / 8);
|
||||
}
|
||||
|
||||
/** \brief Invert display.
|
||||
The PIXEL_ON color of the display will turn to PIXEL_OFF and the PIXEL_OFF will turn to PIXEL_ON.
|
||||
*/
|
||||
void invert_screen(bool invert) {
|
||||
if (invert) {
|
||||
send_command(INVERTDISPLAY);
|
||||
} else {
|
||||
send_command(NORMALDISPLAY);
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief Set contrast.
|
||||
OLED contract value from 0 to 255. Note: Contrast level is not very obvious.
|
||||
*/
|
||||
void set_contrast(uint8_t contrast) {
|
||||
send_command(SETCONTRAST); // 0x81
|
||||
send_command(contrast);
|
||||
}
|
||||
|
||||
/** \brief Transfer display buffer.
|
||||
Sends the updated buffer to the controller - the current status is checked before to save i2c exectution time
|
||||
*/
|
||||
void send_buffer(void) {
|
||||
uint8_t i, j;
|
||||
|
||||
uint8_t page_addr = 0xFF;
|
||||
for (i = 0; i < LCDHEIGHT / 8; i++) {
|
||||
uint8_t col_addr = 0xFF;
|
||||
for (j = 0; j < LCDWIDTH; j++) {
|
||||
if (micro_oled_screen_buffer[i * LCDWIDTH + j] != micro_oled_screen_current[i * LCDWIDTH + j]) {
|
||||
if (page_addr != i) {
|
||||
set_page_address(i);
|
||||
page_addr = i;
|
||||
}
|
||||
if (col_addr != j) {
|
||||
set_column_address(j);
|
||||
col_addr = j + 1;
|
||||
}
|
||||
send_data(micro_oled_screen_buffer[i * LCDWIDTH + j]);
|
||||
micro_oled_screen_current[i * LCDWIDTH + j] = micro_oled_screen_buffer[i * LCDWIDTH + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief Draw pixel with color and mode.
|
||||
Draw color pixel in the screen buffer's x,y position with NORM or XOR draw mode.
|
||||
*/
|
||||
void draw_pixel(uint8_t x, uint8_t y, uint8_t color, uint8_t mode) {
|
||||
if ((x < 0) || (x >= LCDWIDTH) || (y < 0) || (y >= LCDHEIGHT)) return;
|
||||
|
||||
if (mode == XOR) {
|
||||
if (color == PIXEL_ON) micro_oled_screen_buffer[x + (y / 8) * LCDWIDTH] ^= _BV((y % 8));
|
||||
} else {
|
||||
if (color == PIXEL_ON)
|
||||
micro_oled_screen_buffer[x + (y / 8) * LCDWIDTH] |= _BV((y % 8));
|
||||
else
|
||||
micro_oled_screen_buffer[x + (y / 8) * LCDWIDTH] &= ~_BV((y % 8));
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief Draw line with color and mode.
|
||||
Draw line using color and mode from x0,y0 to x1,y1 of the screen buffer.
|
||||
*/
|
||||
void draw_line(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t color, uint8_t mode) {
|
||||
uint8_t steep = abs(y1 - y0) > abs(x1 - x0);
|
||||
if (steep) {
|
||||
swap(x0, y0);
|
||||
swap(x1, y1);
|
||||
}
|
||||
|
||||
if (x0 > x1) {
|
||||
swap(x0, x1);
|
||||
swap(y0, y1);
|
||||
}
|
||||
|
||||
uint8_t dx, dy;
|
||||
dx = x1 - x0;
|
||||
dy = abs(y1 - y0);
|
||||
|
||||
int8_t err = dx / 2;
|
||||
int8_t ystep;
|
||||
|
||||
if (y0 < y1) {
|
||||
ystep = 1;
|
||||
} else {
|
||||
ystep = -1;
|
||||
}
|
||||
|
||||
for (; x0 < x1; x0++) {
|
||||
if (steep) {
|
||||
draw_pixel(y0, x0, color, mode);
|
||||
} else {
|
||||
draw_pixel(x0, y0, color, mode);
|
||||
}
|
||||
err -= dy;
|
||||
if (err < 0) {
|
||||
y0 += ystep;
|
||||
err += dx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief Draw horizontal line with color and mode.
|
||||
Draw horizontal line using color and mode from x,y to x+width,y of the screen buffer.
|
||||
*/
|
||||
void draw_line_hori(uint8_t x, uint8_t y, uint8_t width, uint8_t color, uint8_t mode) { draw_line(x, y, x + width, y, color, mode); }
|
||||
|
||||
/** \brief Draw vertical line.
|
||||
Draw vertical line using current fore color and current draw mode from x,y to x,y+height of the screen buffer.
|
||||
*/
|
||||
void draw_line_vert(uint8_t x, uint8_t y, uint8_t height, bool color, uint8_t mode) { draw_line(x, y, x, y + height, color, mode); }
|
||||
|
||||
/** \brief Draw rectangle with color and mode.
|
||||
Draw rectangle using color and mode from x,y to x+width,y+height of the screen buffer.
|
||||
*/
|
||||
void draw_rect(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode) {
|
||||
uint8_t tempHeight;
|
||||
|
||||
draw_line_hori(x, y, width, color, mode);
|
||||
draw_line_hori(x, y + height - 1, width, color, mode);
|
||||
|
||||
tempHeight = height - 2;
|
||||
|
||||
// skip drawing vertical lines to avoid overlapping of pixel that will
|
||||
// affect XOR plot if no pixel in between horizontal lines
|
||||
if (tempHeight < 1) return;
|
||||
|
||||
draw_line_vert(x, y + 1, tempHeight, color, mode);
|
||||
draw_line_vert(x + width - 1, y + 1, tempHeight, color, mode);
|
||||
}
|
||||
|
||||
/** \brief Draw rectangle with color and mode.
|
||||
Draw rectangle using color and mode from x,y to x+width,y+height of the screen buffer.
|
||||
*/
|
||||
void draw_rect_soft(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode) {
|
||||
uint8_t tempHeight;
|
||||
|
||||
draw_line_hori(x + 1, y, width - 2, color, mode);
|
||||
draw_line_hori(x + 1, y + height - 1, width - 2, color, mode);
|
||||
|
||||
tempHeight = height - 2;
|
||||
|
||||
// skip drawing vertical lines to avoid overlapping of pixel that will
|
||||
// affect XOR plot if no pixel in between horizontal lines
|
||||
if (tempHeight < 1) return;
|
||||
|
||||
draw_line_vert(x, y + 1, tempHeight, color, mode);
|
||||
draw_line_vert(x + width - 1, y + 1, tempHeight, color, mode);
|
||||
}
|
||||
|
||||
/** \brief Draw filled rectangle with color and mode.
|
||||
Draw filled rectangle using color and mode from x,y to x+width,y+height of the screen buffer.
|
||||
*/
|
||||
void draw_rect_filled(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode) {
|
||||
// TODO - need to optimise the memory map draw so that this function will not call pixel one by one
|
||||
for (int i = x; i < x + width; i++) {
|
||||
draw_line_vert(i, y, height, color, mode);
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief Draw filled rectangle with color and mode.
|
||||
Draw filled rectangle using color and mode from x,y to x+width,y+height of the screen buffer.
|
||||
*/
|
||||
void draw_rect_filled_soft(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode) {
|
||||
// TODO - need to optimise the memory map draw so that this function will not call pixel one by one
|
||||
for (int i = x; i < x + width; i++) {
|
||||
if (i == x || i == (x + width - 1))
|
||||
draw_line_vert(i, y + 1, height - 2, color, mode);
|
||||
else
|
||||
draw_line_vert(i, y, height, color, mode);
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief Draw character with color and mode.
|
||||
Draw character c using color and draw mode at x,y.
|
||||
*/
|
||||
void draw_char(uint8_t x, uint8_t y, uint8_t c, uint8_t color, uint8_t mode, uint8_t font) {
|
||||
// TODO - New routine to take font of any height, at the moment limited to font height in multiple of 8 pixels
|
||||
|
||||
uint8_t rowsToDraw, row, tempC;
|
||||
uint8_t i, j, temp;
|
||||
uint16_t charPerBitmapRow, charColPositionOnBitmap, charRowPositionOnBitmap, charBitmapStartPosition;
|
||||
|
||||
if ((font >= TOTALFONTS) || (font < 0)) return;
|
||||
|
||||
uint8_t fontType = font;
|
||||
uint8_t fontWidth = pgm_read_byte(fonts_pointer[fontType] + 0);
|
||||
uint8_t fontHeight = pgm_read_byte(fonts_pointer[fontType] + 1);
|
||||
uint8_t fontStartChar = pgm_read_byte(fonts_pointer[fontType] + 2);
|
||||
uint8_t fontTotalChar = pgm_read_byte(fonts_pointer[fontType] + 3);
|
||||
uint16_t fontMapWidth = (pgm_read_byte(fonts_pointer[fontType] + 4) * 100) + pgm_read_byte(fonts_pointer[fontType] + 5); // two bytes values into integer 16
|
||||
|
||||
if ((c < fontStartChar) || (c > (fontStartChar + fontTotalChar - 1))) // no bitmap for the required c
|
||||
return;
|
||||
|
||||
tempC = c - fontStartChar;
|
||||
|
||||
// each row (in datasheet is call page) is 8 bits high, 16 bit high character will have 2 rows to be drawn
|
||||
rowsToDraw = fontHeight / 8; // 8 is LCD's page size, see SSD1306 datasheet
|
||||
if (rowsToDraw <= 1) rowsToDraw = 1;
|
||||
|
||||
// the following draw function can draw anywhere on the screen, but SLOW pixel by pixel draw
|
||||
if (rowsToDraw == 1) {
|
||||
for (i = 0; i < fontWidth + 1; i++) {
|
||||
if (i == fontWidth) // this is done in a weird way because for 5x7 font, there is no margin, this code add a margin after col 5
|
||||
temp = 0;
|
||||
else
|
||||
temp = pgm_read_byte(fonts_pointer[fontType] + FONTHEADERSIZE + (tempC * fontWidth) + i);
|
||||
|
||||
for (j = 0; j < 8; j++) { // 8 is the LCD's page height (see datasheet for explanation)
|
||||
if (temp & 0x1) {
|
||||
draw_pixel(x + i, y + j, color, mode);
|
||||
} else {
|
||||
draw_pixel(x + i, y + j, !color, mode);
|
||||
}
|
||||
|
||||
temp >>= 1;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// font height over 8 bit
|
||||
// take character "0" ASCII 48 as example
|
||||
charPerBitmapRow = fontMapWidth / fontWidth; // 256/8 =32 char per row
|
||||
charColPositionOnBitmap = tempC % charPerBitmapRow; // =16
|
||||
charRowPositionOnBitmap = (int)(tempC / charPerBitmapRow); // =1
|
||||
charBitmapStartPosition = (charRowPositionOnBitmap * fontMapWidth * (fontHeight / 8)) + (charColPositionOnBitmap * fontWidth);
|
||||
|
||||
// each row on LCD is 8 bit height (see datasheet for explanation)
|
||||
for (row = 0; row < rowsToDraw; row++) {
|
||||
for (i = 0; i < fontWidth; i++) {
|
||||
temp = pgm_read_byte(fonts_pointer[fontType] + FONTHEADERSIZE + (charBitmapStartPosition + i + (row * fontMapWidth)));
|
||||
for (j = 0; j < 8; j++) { // 8 is the LCD's page height (see datasheet for explanation)
|
||||
if (temp & 0x1) {
|
||||
draw_pixel(x + i, y + j + (row * 8), color, mode);
|
||||
} else {
|
||||
draw_pixel(x + i, y + j + (row * 8), !color, mode);
|
||||
}
|
||||
temp >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw_string(uint8_t x, uint8_t y, char* string, uint8_t color, uint8_t mode, uint8_t font) {
|
||||
if ((font >= TOTALFONTS) || (font < 0)) return;
|
||||
|
||||
uint8_t fontType = font;
|
||||
uint8_t fontWidth = pgm_read_byte(fonts_pointer[fontType] + 0);
|
||||
|
||||
uint8_t cur_x = x;
|
||||
for (int i = 0; i < strlen(string); i++) {
|
||||
draw_char(cur_x, y, string[i], color, mode, font);
|
||||
cur_x += fontWidth + 1;
|
||||
}
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
/* Jim Lindblom @ SparkFun Electronics
|
||||
* October 26, 2014
|
||||
* https://github.com/sparkfun/Micro_OLED_Breakout/tree/master/Firmware/Arduino/libraries/SFE_MicroOLED
|
||||
*
|
||||
* Modified by:
|
||||
* Emil Varughese @ Edwin Robotics Pvt. Ltd.
|
||||
* July 27, 2015
|
||||
* https://github.com/emil01/SparkFun_Micro_OLED_Arduino_Library/
|
||||
*
|
||||
* This code was heavily based around the MicroView library, written by GeekAmmo
|
||||
* (https://github.com/geekammo/MicroView-Arduino-Library).
|
||||
*
|
||||
* Adapted for QMK by:
|
||||
* Jack Humbert <jack.humb@gmail.com>
|
||||
* October 11, 2018
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "qwiic.h"
|
||||
|
||||
void micro_oled_init(void);
|
||||
|
||||
void send_command(uint8_t command);
|
||||
void send_data(uint8_t data);
|
||||
void set_page_address(uint8_t address);
|
||||
void set_column_address(uint8_t address);
|
||||
void clear_screen(void);
|
||||
void clear_buffer(void);
|
||||
void send_buffer(void);
|
||||
void draw_pixel(uint8_t x, uint8_t y, uint8_t color, uint8_t mode);
|
||||
void draw_line(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t color, uint8_t mode);
|
||||
void draw_line_hori(uint8_t x, uint8_t y, uint8_t width, uint8_t color, uint8_t mode);
|
||||
void draw_line_vert(uint8_t x, uint8_t y, uint8_t height, bool color, uint8_t mode);
|
||||
void draw_rect(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode);
|
||||
void draw_rect_soft(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode);
|
||||
void draw_rect_filled(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode);
|
||||
void draw_rect_filled_soft(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode);
|
||||
void draw_char(uint8_t x, uint8_t y, uint8_t c, uint8_t color, uint8_t mode, uint8_t font);
|
||||
void draw_string(uint8_t x, uint8_t y, char* string, uint8_t color, uint8_t mode, uint8_t font);
|
||||
|
||||
#define I2C_ADDRESS_SA0_0 0b0111100
|
||||
#ifndef I2C_ADDRESS_SA0_1
|
||||
# define I2C_ADDRESS_SA0_1 0b0111101
|
||||
#endif
|
||||
#define I2C_COMMAND 0x00
|
||||
#define I2C_DATA 0x40
|
||||
#define PIXEL_OFF 0
|
||||
#define PIXEL_ON 1
|
||||
|
||||
#ifndef LCDWIDTH
|
||||
# define LCDWIDTH 64
|
||||
#endif
|
||||
#ifndef LCDHEIGHT
|
||||
# define LCDHEIGHT 48
|
||||
#endif
|
||||
#define FONTHEADERSIZE 6
|
||||
|
||||
#define NORM 0
|
||||
#define XOR 1
|
||||
|
||||
#define PAGE 0
|
||||
#define ALL 1
|
||||
|
||||
#define WIDGETSTYLE0 0
|
||||
#define WIDGETSTYLE1 1
|
||||
#define WIDGETSTYLE2 2
|
||||
|
||||
#define SETCONTRAST 0x81
|
||||
#define DISPLAYALLONRESUME 0xA4
|
||||
#define DISPLAYALLON 0xA5
|
||||
#define NORMALDISPLAY 0xA6
|
||||
#define INVERTDISPLAY 0xA7
|
||||
#define DISPLAYOFF 0xAE
|
||||
#define DISPLAYON 0xAF
|
||||
#define SETDISPLAYOFFSET 0xD3
|
||||
#define SETCOMPINS 0xDA
|
||||
#define SETVCOMDESELECT 0xDB
|
||||
#define SETDISPLAYCLOCKDIV 0xD5
|
||||
#define SETPRECHARGE 0xD9
|
||||
#define SETMULTIPLEX 0xA8
|
||||
#define SETLOWCOLUMN 0x00
|
||||
#define SETHIGHCOLUMN 0x10
|
||||
#define SETSTARTLINE 0x40
|
||||
#define MEMORYMODE 0x20
|
||||
#define COMSCANINC 0xC0
|
||||
#define COMSCANDEC 0xC8
|
||||
#define SEGREMAP 0xA0
|
||||
#define CHARGEPUMP 0x8D
|
||||
#define EXTERNALVCC 0x01
|
||||
#define SWITCHCAPVCC 0x02
|
||||
|
||||
// Scroll
|
||||
#define ACTIVATESCROLL 0x2F
|
||||
#define DEACTIVATESCROLL 0x2E
|
||||
#define SETVERTICALSCROLLAREA 0xA3
|
||||
#define RIGHTHORIZONTALSCROLL 0x26
|
||||
#define LEFT_HORIZONTALSCROLL 0x27
|
||||
#define VERTICALRIGHTHORIZONTALSCROLL 0x29
|
||||
#define VERTICALLEFTHORIZONTALSCROLL 0x2A
|
||||
|
||||
typedef enum CMD {
|
||||
CMD_CLEAR, // 0
|
||||
CMD_INVERT, // 1
|
||||
CMD_CONTRAST, // 2
|
||||
CMD_DISPLAY, // 3
|
||||
CMD_SETCURSOR, // 4
|
||||
CMD_PIXEL, // 5
|
||||
CMD_LINE, // 6
|
||||
CMD_LINEH, // 7
|
||||
CMD_LINEV, // 8
|
||||
CMD_RECT, // 9
|
||||
CMD_RECTFILL, // 10
|
||||
CMD_CIRCLE, // 11
|
||||
CMD_CIRCLEFILL, // 12
|
||||
CMD_DRAWCHAR, // 13
|
||||
CMD_DRAWBITMAP, // 14
|
||||
CMD_GETLCDWIDTH, // 15
|
||||
CMD_GETLCDHEIGHT, // 16
|
||||
CMD_SETCOLOR, // 17
|
||||
CMD_SETDRAWMODE // 18
|
||||
} commCommand_t;
|
||||
@@ -1,17 +0,0 @@
|
||||
ifeq ($(strip $(QWIIC_ENABLE)),yes)
|
||||
COMMON_VPATH += $(DRIVER_PATH)/qwiic
|
||||
OPT_DEFS += -DQWIIC_ENABLE
|
||||
SRC += qwiic.c
|
||||
QUANTUM_LIB_SRC += i2c_master.c
|
||||
|
||||
ifneq ($(filter JOYSTIIC, $(QWIIC_DRIVERS)),)
|
||||
OPT_DEFS += -DQWIIC_JOYSTIIC_ENABLE
|
||||
SRC += joystiic.c
|
||||
endif
|
||||
|
||||
ifneq ($(filter MICRO_OLED, $(QWIIC_DRIVERS)),)
|
||||
OPT_DEFS += -DQWIIC_MICRO_OLED_ENABLE
|
||||
SRC += micro_oled.c
|
||||
endif
|
||||
|
||||
endif
|
||||
@@ -1,39 +0,0 @@
|
||||
/******************************************************************************
|
||||
font5x7.h
|
||||
Definition for small font
|
||||
|
||||
This file was imported from the MicroView library, written by GeekAmmo
|
||||
(https://github.com/geekammo/MicroView-Arduino-Library), and released under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Modified by:
|
||||
Emil Varughese @ Edwin Robotics Pvt. Ltd.
|
||||
July 27, 2015
|
||||
https://github.com/emil01/SparkFun_Micro_OLED_Arduino_Library/
|
||||
|
||||
******************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include "progmem.h"
|
||||
|
||||
// Standard ASCII 5x7 font
|
||||
static const unsigned char font5x7[] PROGMEM = {
|
||||
// first row defines - FONTWIDTH, FONTHEIGHT, ASCII START CHAR, TOTAL CHARACTERS, FONT MAP WIDTH HIGH, FONT MAP WIDTH LOW (2,56 meaning 256)
|
||||
5, 8, 0, 255, 12, 75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x18, 0x3C, 0x7E, 0x3C, 0x18, 0x1C, 0x57, 0x7D, 0x57, 0x1C, 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00, 0x18, 0x3C, 0x18, 0x00, 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00, 0x18, 0x24, 0x18, 0x00, 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x30, 0x48, 0x3A, 0x06, 0x0E, 0x26, 0x29, 0x79, 0x29, 0x26, 0x40, 0x7F, 0x05, 0x05, 0x07, 0x40, 0x7F, 0x05, 0x25, 0x3F, 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 0x7F, 0x3E, 0x1C, 0x1C, 0x08, 0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x14, 0x22, 0x7F, 0x22, 0x14, 0x5F, 0x5F, 0x00, 0x5F, 0x5F, 0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00, 0x66, 0x89, 0x95, 0x6A, 0x60, 0x60, 0x60, 0x60, 0x60, 0x94, 0xA2, 0xFF, 0xA2, 0x94, 0x08, 0x04, 0x7E, 0x04, 0x08, 0x10, 0x20, 0x7E, 0x20, 0x10, 0x08, 0x08, 0x2A, 0x1C, 0x08, 0x08, 0x1C, 0x2A, 0x08, 0x08, 0x1E, 0x10, 0x10, 0x10, 0x10, 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 0x30, 0x38, 0x3E, 0x38, 0x30,
|
||||
0x06, 0x0E, 0x3E, 0x0E, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x23, 0x13, 0x08, 0x64, 0x62, 0x36, 0x49, 0x56, 0x20, 0x50, 0x00, 0x08, 0x07, 0x03, 0x00, 0x00, 0x1C, 0x22, 0x41, 0x00, 0x00, 0x41, 0x22, 0x1C, 0x00, 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, 0x80, 0x70, 0x30, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x60, 0x60, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, 0x42, 0x7F, 0x40, 0x00, 0x72, 0x49, 0x49, 0x49, 0x46, 0x21, 0x41, 0x49, 0x4D, 0x33, 0x18, 0x14, 0x12, 0x7F, 0x10, 0x27, 0x45, 0x45, 0x45, 0x39, 0x3C, 0x4A, 0x49, 0x49, 0x31, 0x41, 0x21, 0x11, 0x09, 0x07, 0x36, 0x49, 0x49, 0x49, 0x36, 0x46, 0x49, 0x49, 0x29, 0x1E, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x40, 0x34, 0x00, 0x00, 0x00, 0x08, 0x14, 0x22, 0x41, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, 0x41, 0x22, 0x14, 0x08, 0x02,
|
||||
0x01, 0x59, 0x09, 0x06, 0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x7C, 0x12, 0x11, 0x12, 0x7C, 0x7F, 0x49, 0x49, 0x49, 0x36, 0x3E, 0x41, 0x41, 0x41, 0x22, 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x7F, 0x49, 0x49, 0x49, 0x41, 0x7F, 0x09, 0x09, 0x09, 0x01, 0x3E, 0x41, 0x41, 0x51, 0x73, 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, 0x41, 0x7F, 0x41, 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01, 0x7F, 0x08, 0x14, 0x22, 0x41, 0x7F, 0x40, 0x40, 0x40, 0x40, 0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x7F, 0x09, 0x09, 0x09, 0x06, 0x3E, 0x41, 0x51, 0x21, 0x5E, 0x7F, 0x09, 0x19, 0x29, 0x46, 0x26, 0x49, 0x49, 0x49, 0x32, 0x03, 0x01, 0x7F, 0x01, 0x03, 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x3F, 0x40, 0x38, 0x40, 0x3F, 0x63, 0x14, 0x08, 0x14, 0x63, 0x03, 0x04, 0x78, 0x04, 0x03, 0x61, 0x59, 0x49, 0x4D, 0x43, 0x00, 0x7F, 0x41, 0x41, 0x41, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x41, 0x41, 0x41, 0x7F, 0x04, 0x02, 0x01, 0x02, 0x04, 0x40, 0x40,
|
||||
0x40, 0x40, 0x40, 0x00, 0x03, 0x07, 0x08, 0x00, 0x20, 0x54, 0x54, 0x78, 0x40, 0x7F, 0x28, 0x44, 0x44, 0x38, 0x38, 0x44, 0x44, 0x44, 0x28, 0x38, 0x44, 0x44, 0x28, 0x7F, 0x38, 0x54, 0x54, 0x54, 0x18, 0x00, 0x08, 0x7E, 0x09, 0x02, 0x18, 0xA4, 0xA4, 0x9C, 0x78, 0x7F, 0x08, 0x04, 0x04, 0x78, 0x00, 0x44, 0x7D, 0x40, 0x00, 0x20, 0x40, 0x40, 0x3D, 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00, 0x00, 0x41, 0x7F, 0x40, 0x00, 0x7C, 0x04, 0x78, 0x04, 0x78, 0x7C, 0x08, 0x04, 0x04, 0x78, 0x38, 0x44, 0x44, 0x44, 0x38, 0xFC, 0x18, 0x24, 0x24, 0x18, 0x18, 0x24, 0x24, 0x18, 0xFC, 0x7C, 0x08, 0x04, 0x04, 0x08, 0x48, 0x54, 0x54, 0x54, 0x24, 0x04, 0x04, 0x3F, 0x44, 0x24, 0x3C, 0x40, 0x40, 0x20, 0x7C, 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x3C, 0x40, 0x30, 0x40, 0x3C, 0x44, 0x28, 0x10, 0x28, 0x44, 0x4C, 0x90, 0x90, 0x90, 0x7C, 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00, 0x08, 0x36, 0x41, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x41, 0x36, 0x08, 0x00, 0x02, 0x01, 0x02, 0x04, 0x02, 0x3C, 0x26, 0x23,
|
||||
0x26, 0x3C, 0x1E, 0xA1, 0xA1, 0x61, 0x12, 0x3A, 0x40, 0x40, 0x20, 0x7A, 0x38, 0x54, 0x54, 0x55, 0x59, 0x21, 0x55, 0x55, 0x79, 0x41, 0x21, 0x54, 0x54, 0x78, 0x41, 0x21, 0x55, 0x54, 0x78, 0x40, 0x20, 0x54, 0x55, 0x79, 0x40, 0x0C, 0x1E, 0x52, 0x72, 0x12, 0x39, 0x55, 0x55, 0x55, 0x59, 0x39, 0x54, 0x54, 0x54, 0x59, 0x39, 0x55, 0x54, 0x54, 0x58, 0x00, 0x00, 0x45, 0x7C, 0x41, 0x00, 0x02, 0x45, 0x7D, 0x42, 0x00, 0x01, 0x45, 0x7C, 0x40, 0xF0, 0x29, 0x24, 0x29, 0xF0, 0xF0, 0x28, 0x25, 0x28, 0xF0, 0x7C, 0x54, 0x55, 0x45, 0x00, 0x20, 0x54, 0x54, 0x7C, 0x54, 0x7C, 0x0A, 0x09, 0x7F, 0x49, 0x32, 0x49, 0x49, 0x49, 0x32, 0x32, 0x48, 0x48, 0x48, 0x32, 0x32, 0x4A, 0x48, 0x48, 0x30, 0x3A, 0x41, 0x41, 0x21, 0x7A, 0x3A, 0x42, 0x40, 0x20, 0x78, 0x00, 0x9D, 0xA0, 0xA0, 0x7D, 0x39, 0x44, 0x44, 0x44, 0x39, 0x3D, 0x40, 0x40, 0x40, 0x3D, 0x3C, 0x24, 0xFF, 0x24, 0x24, 0x48, 0x7E, 0x49, 0x43, 0x66, 0x2B, 0x2F, 0xFC, 0x2F, 0x2B, 0xFF, 0x09, 0x29, 0xF6, 0x20, 0xC0, 0x88, 0x7E, 0x09,
|
||||
0x03, 0x20, 0x54, 0x54, 0x79, 0x41, 0x00, 0x00, 0x44, 0x7D, 0x41, 0x30, 0x48, 0x48, 0x4A, 0x32, 0x38, 0x40, 0x40, 0x22, 0x7A, 0x00, 0x7A, 0x0A, 0x0A, 0x72, 0x7D, 0x0D, 0x19, 0x31, 0x7D, 0x26, 0x29, 0x29, 0x2F, 0x28, 0x26, 0x29, 0x29, 0x29, 0x26, 0x30, 0x48, 0x4D, 0x40, 0x20, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x2F, 0x10, 0xC8, 0xAC, 0xBA, 0x2F, 0x10, 0x28, 0x34, 0xFA, 0x00, 0x00, 0x7B, 0x00, 0x00, 0x08, 0x14, 0x2A, 0x14, 0x22, 0x22, 0x14, 0x2A, 0x14, 0x08, 0xAA, 0x00, 0x55, 0x00, 0xAA, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x10, 0x10, 0x10, 0xFF, 0x00, 0x14, 0x14, 0x14, 0xFF, 0x00, 0x10, 0x10, 0xFF, 0x00, 0xFF, 0x10, 0x10, 0xF0, 0x10, 0xF0, 0x14, 0x14, 0x14, 0xFC, 0x00, 0x14, 0x14, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x14, 0x14, 0xF4, 0x04, 0xFC, 0x14, 0x14, 0x17, 0x10, 0x1F, 0x10, 0x10, 0x1F, 0x10, 0x1F, 0x14, 0x14, 0x14, 0x1F, 0x00, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10,
|
||||
0x10, 0x10, 0x10, 0x1F, 0x10, 0x10, 0x10, 0x10, 0xF0, 0x10, 0x00, 0x00, 0x00, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xFF, 0x14, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x1F, 0x10, 0x17, 0x00, 0x00, 0xFC, 0x04, 0xF4, 0x14, 0x14, 0x17, 0x10, 0x17, 0x14, 0x14, 0xF4, 0x04, 0xF4, 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0xF7, 0x00, 0xF7, 0x14, 0x14, 0x14, 0x17, 0x14, 0x10, 0x10, 0x1F, 0x10, 0x1F, 0x14, 0x14, 0x14, 0xF4, 0x14, 0x10, 0x10, 0xF0, 0x10, 0xF0, 0x00, 0x00, 0x1F, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x14, 0x00, 0x00, 0x00, 0xFC, 0x14, 0x00, 0x00, 0xF0, 0x10, 0xF0, 0x10, 0x10, 0xFF, 0x10, 0xFF, 0x14, 0x14, 0x14, 0xFF, 0x14, 0x10, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x38, 0x44, 0x44, 0x38, 0x44, 0x7C,
|
||||
0x2A, 0x2A, 0x3E, 0x14, 0x7E, 0x02, 0x02, 0x06, 0x06, 0x02, 0x7E, 0x02, 0x7E, 0x02, 0x63, 0x55, 0x49, 0x41, 0x63, 0x38, 0x44, 0x44, 0x3C, 0x04, 0x40, 0x7E, 0x20, 0x1E, 0x20, 0x06, 0x02, 0x7E, 0x02, 0x02, 0x99, 0xA5, 0xE7, 0xA5, 0x99, 0x1C, 0x2A, 0x49, 0x2A, 0x1C, 0x4C, 0x72, 0x01, 0x72, 0x4C, 0x30, 0x4A, 0x4D, 0x4D, 0x30, 0x30, 0x48, 0x78, 0x48, 0x30, 0xBC, 0x62, 0x5A, 0x46, 0x3D, 0x3E, 0x49, 0x49, 0x49, 0x00, 0x7E, 0x01, 0x01, 0x01, 0x7E, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x44, 0x44, 0x5F, 0x44, 0x44, 0x40, 0x51, 0x4A, 0x44, 0x40, 0x40, 0x44, 0x4A, 0x51, 0x40, 0x00, 0x00, 0xFF, 0x01, 0x03, 0xE0, 0x80, 0xFF, 0x00, 0x00, 0x08, 0x08, 0x6B, 0x6B, 0x08, 0x36, 0x12, 0x36, 0x24, 0x36, 0x06, 0x0F, 0x09, 0x0F, 0x06, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x30, 0x40, 0xFF, 0x01, 0x01, 0x00, 0x1F, 0x01, 0x01, 0x1E, 0x00, 0x19, 0x1D, 0x17, 0x12, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
@@ -1,39 +0,0 @@
|
||||
/******************************************************************************
|
||||
font8x16.h
|
||||
Definition for medium font
|
||||
|
||||
This file was imported from the MicroView library, written by GeekAmmo
|
||||
(https://github.com/geekammo/MicroView-Arduino-Library), and released under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Modified by:
|
||||
Emil Varughese @ Edwin Robotics Pvt. Ltd.
|
||||
July 27, 2015
|
||||
https://github.com/emil01/SparkFun_Micro_OLED_Arduino_Library/
|
||||
******************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include "progmem.h"
|
||||
|
||||
static const unsigned char font8x16[] PROGMEM = {
|
||||
// first row defines - FONTWIDTH, FONTHEIGHT, ASCII START CHAR, TOTAL CHARACTERS, FONT MAP WIDTH HIGH, FONT MAP WIDTH LOW (2,56 meaning 256)
|
||||
8, 16, 32, 96, 2, 56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xBE, 0x90, 0xD0, 0xBE, 0x90, 0x00, 0x00, 0x1C, 0x62, 0xFF, 0xC2, 0x80, 0x00, 0x00, 0x0C, 0x12, 0x92, 0x4C, 0xB0, 0x88, 0x06, 0x00, 0x80, 0x7C, 0x62, 0xB2, 0x1C, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x18, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x02, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, 0x00, 0x24, 0x18, 0x7E, 0x18, 0x24, 0x00, 0x00, 0x80, 0x80, 0x80, 0xF0, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x06, 0x00, 0x00, 0xF8, 0x04, 0xC2, 0x32, 0x0C, 0xF8, 0x00, 0x00, 0x00, 0x04, 0x04, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x42, 0x22,
|
||||
0x1C, 0x00, 0x00, 0x00, 0x02, 0x22, 0x22, 0x22, 0xDC, 0x00, 0x00, 0xC0, 0xA0, 0x98, 0x84, 0xFE, 0x80, 0x80, 0x00, 0x00, 0x1E, 0x12, 0x12, 0x22, 0xC2, 0x00, 0x00, 0xF8, 0x44, 0x22, 0x22, 0x22, 0xC0, 0x00, 0x00, 0x00, 0x02, 0x02, 0xC2, 0x32, 0x0A, 0x06, 0x00, 0x00, 0x8C, 0x52, 0x22, 0x52, 0x8C, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x26, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x02, 0x82, 0x42, 0x22, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x0F, 0x04, 0x03, 0x00, 0x00, 0x04, 0x02, 0x01, 0x03, 0x04, 0x04, 0x03, 0x00,
|
||||
0x03, 0x04, 0x04, 0x04, 0x05, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x08, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10, 0x10, 0x08, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x04, 0x04, 0x07, 0x04, 0x04, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x04, 0x04,
|
||||
0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x04, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x04, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x04, 0x72, 0x8A, 0xFA, 0x84, 0x78, 0x00, 0x00, 0xC0, 0x38, 0x06, 0x38, 0xC0, 0x00, 0x00, 0x00, 0xFE, 0x22, 0x22, 0x22, 0xDC, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x04, 0xF8, 0x00, 0x00, 0x00, 0xFE, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0xFE, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x02, 0x22, 0xE2, 0x00, 0x00, 0xFE, 0x20, 0x20, 0x20, 0x20, 0xFE, 0x00, 0x00, 0x00, 0x02, 0x02, 0xFE, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0xFE, 0x00, 0x00, 0xFE, 0x40, 0xB0, 0x08, 0x04, 0x02, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFE, 0x0C, 0x70, 0x80, 0x70, 0x0C, 0xFE, 0x00, 0xFE, 0x0C, 0x30, 0xC0, 0x00, 0xFE, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x02, 0x04, 0xF8, 0x00, 0x00, 0xFE, 0x42, 0x42, 0x42, 0x22, 0x1C, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x02, 0x04, 0xF8, 0x00, 0x00, 0x00, 0xFE, 0x42, 0x42, 0xA2, 0x1C, 0x00, 0x00, 0x00, 0x1C, 0x22, 0x42, 0x42, 0x80, 0x00, 0x00, 0x02, 0x02, 0x02, 0xFE, 0x02, 0x02, 0x02, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x06, 0x38, 0xC0, 0x00, 0xC0, 0x38, 0x06, 0x00, 0x3E, 0xC0, 0xF0, 0x0E, 0xF0, 0xC0, 0x3E, 0x00, 0x00, 0x06, 0x98, 0x60, 0x98, 0x06, 0x00, 0x00, 0x00, 0x06, 0x18, 0xE0, 0x18, 0x06, 0x00, 0x00, 0x02, 0x02, 0xC2, 0x32, 0x0A, 0x06, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x06, 0x18, 0x60, 0x80, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x40, 0x30, 0x0C, 0x0C, 0x30, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x02, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x04, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x04, 0x07, 0x04, 0x04, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x07, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x0C, 0x12, 0x11, 0x10, 0x00, 0x00, 0x07, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04,
|
||||
0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x01, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, 0x00, 0xFE, 0x20, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xFE, 0x00, 0x00, 0x00, 0xE0, 0x90, 0x90, 0x90, 0xE0, 0x00, 0x00, 0x00, 0x20, 0xFC, 0x22, 0x22, 0x22, 0x02,
|
||||
0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, 0x00, 0xFE, 0x20, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x10, 0x10, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0xF2, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x80, 0x40, 0x20, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x20, 0x10, 0xF0, 0x20, 0x10, 0xF0, 0x00, 0x00, 0xF0, 0x20, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x00, 0xF0, 0x20, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0x20, 0x10, 0x10, 0x70, 0x00, 0x00, 0x00, 0x60, 0x90, 0x90, 0x90, 0x20, 0x00, 0x00, 0x00, 0x20, 0x20, 0xFC, 0x20, 0x20, 0x20, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x70, 0x80, 0x00, 0x80, 0x70, 0x00, 0x00, 0xF0, 0x00, 0xC0, 0x30, 0xC0, 0x00, 0xF0, 0x00, 0x00, 0x30, 0xC0, 0xC0, 0x30, 0x00, 0x00, 0x00, 0x00, 0x30, 0xC0, 0x00, 0x80, 0x70, 0x00, 0x00, 0x00, 0x10,
|
||||
0x10, 0x90, 0x50, 0x30, 0x00, 0x00, 0x00, 0x80, 0x80, 0x7E, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x7E, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x02, 0x07, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x02, 0x07, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x24, 0x24, 0x22, 0x1F, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00,
|
||||
0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x3F, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x02, 0x3F, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x00, 0x00, 0x03, 0x04, 0x04, 0x02, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x03, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x00, 0x01, 0x06, 0x01, 0x00, 0x00, 0x06, 0x01, 0x01, 0x06, 0x00, 0x00, 0x00, 0x20, 0x20, 0x31, 0x0E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
@@ -17,89 +17,98 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "adns5050.h"
|
||||
#include "wait.h"
|
||||
#include "debug.h"
|
||||
#include "print.h"
|
||||
#include "gpio.h"
|
||||
|
||||
#ifndef OPTIC_ROTATED
|
||||
# define OPTIC_ROTATED false
|
||||
#endif
|
||||
|
||||
// Definitions for the ADNS serial line.
|
||||
#ifndef ADNS_SCLK_PIN
|
||||
# define ADNS_SCLK_PIN B7
|
||||
#endif
|
||||
|
||||
#ifndef ADNS_SDIO_PIN
|
||||
# define ADNS_SDIO_PIN C6
|
||||
#endif
|
||||
|
||||
#ifndef ADNS_CS_PIN
|
||||
# define ADNS_CS_PIN B4
|
||||
#endif
|
||||
|
||||
#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')); }
|
||||
#endif
|
||||
// Registers
|
||||
// clang-format off
|
||||
#define REG_PRODUCT_ID 0x00
|
||||
#define REG_REVISION_ID 0x01
|
||||
#define REG_MOTION 0x02
|
||||
#define REG_DELTA_X 0x03
|
||||
#define REG_DELTA_Y 0x04
|
||||
#define REG_SQUAL 0x05
|
||||
#define REG_SHUTTER_UPPER 0x06
|
||||
#define REG_SHUTTER_LOWER 0x07
|
||||
#define REG_MAXIMUM_PIXEL 0x08
|
||||
#define REG_PIXEL_SUM 0x09
|
||||
#define REG_MINIMUM_PIXEL 0x0a
|
||||
#define REG_PIXEL_GRAB 0x0b
|
||||
#define REG_MOUSE_CONTROL 0x0d
|
||||
#define REG_MOUSE_CONTROL2 0x19
|
||||
#define REG_LED_DC_MODE 0x22
|
||||
#define REG_CHIP_RESET 0x3a
|
||||
#define REG_PRODUCT_ID2 0x3e
|
||||
#define REG_INV_REV_ID 0x3f
|
||||
#define REG_MOTION_BURST 0x63
|
||||
// clang-format on
|
||||
|
||||
void adns5050_init(void) {
|
||||
// Initialize the ADNS serial pins.
|
||||
void adns_init(void) {
|
||||
setPinOutput(ADNS_SCLK_PIN);
|
||||
setPinOutput(ADNS_SDIO_PIN);
|
||||
setPinOutput(ADNS_CS_PIN);
|
||||
setPinOutput(ADNS5050_SCLK_PIN);
|
||||
setPinOutput(ADNS5050_SDIO_PIN);
|
||||
setPinOutput(ADNS5050_CS_PIN);
|
||||
|
||||
// reboot the adns.
|
||||
// if the adns hasn't initialized yet, this is harmless.
|
||||
adns5050_write_reg(REG_CHIP_RESET, 0x5a);
|
||||
|
||||
// wait maximum time before adns is ready.
|
||||
// this ensures that the adns is actuall ready after reset.
|
||||
wait_ms(55);
|
||||
|
||||
// read a burst from the adns and then discard it.
|
||||
// gets the adns ready for write commands
|
||||
// (for example, setting the dpi).
|
||||
adns5050_read_burst();
|
||||
}
|
||||
|
||||
// Perform a synchronization with the ADNS.
|
||||
// Just as with the serial protocol, this is used by the slave to send a
|
||||
// synchronization signal to the master.
|
||||
void adns_sync(void) {
|
||||
writePinLow(ADNS_CS_PIN);
|
||||
void adns5050_sync(void) {
|
||||
writePinLow(ADNS5050_CS_PIN);
|
||||
wait_us(1);
|
||||
writePinHigh(ADNS_CS_PIN);
|
||||
writePinHigh(ADNS5050_CS_PIN);
|
||||
}
|
||||
|
||||
void adns_cs_select(void) {
|
||||
writePinLow(ADNS_CS_PIN);
|
||||
}
|
||||
void adns5050_cs_select(void) { writePinLow(ADNS5050_CS_PIN); }
|
||||
|
||||
void adns_cs_deselect(void) {
|
||||
writePinHigh(ADNS_CS_PIN);
|
||||
}
|
||||
void adns5050_cs_deselect(void) { writePinHigh(ADNS5050_CS_PIN); }
|
||||
|
||||
uint8_t adns_serial_read(void) {
|
||||
setPinInput(ADNS_SDIO_PIN);
|
||||
uint8_t adns5050_serial_read(void) {
|
||||
setPinInput(ADNS5050_SDIO_PIN);
|
||||
uint8_t byte = 0;
|
||||
|
||||
for (uint8_t i = 0; i < 8; ++i) {
|
||||
writePinLow(ADNS_SCLK_PIN);
|
||||
writePinLow(ADNS5050_SCLK_PIN);
|
||||
wait_us(1);
|
||||
|
||||
byte = (byte << 1) | readPin(ADNS_SDIO_PIN);
|
||||
byte = (byte << 1) | readPin(ADNS5050_SDIO_PIN);
|
||||
|
||||
writePinHigh(ADNS_SCLK_PIN);
|
||||
writePinHigh(ADNS5050_SCLK_PIN);
|
||||
wait_us(1);
|
||||
}
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
void adns_serial_write(uint8_t data) {
|
||||
setPinOutput(ADNS_SDIO_PIN);
|
||||
void adns5050_serial_write(uint8_t data) {
|
||||
setPinOutput(ADNS5050_SDIO_PIN);
|
||||
|
||||
for (int8_t b = 7; b >= 0; b--) {
|
||||
writePinLow(ADNS_SCLK_PIN);
|
||||
writePinLow(ADNS5050_SCLK_PIN);
|
||||
|
||||
if (data & (1 << b))
|
||||
writePinHigh(ADNS_SDIO_PIN);
|
||||
writePinHigh(ADNS5050_SDIO_PIN);
|
||||
else
|
||||
writePinLow(ADNS_SDIO_PIN);
|
||||
writePinLow(ADNS5050_SDIO_PIN);
|
||||
|
||||
wait_us(2);
|
||||
|
||||
writePinHigh(ADNS_SCLK_PIN);
|
||||
writePinHigh(ADNS5050_SCLK_PIN);
|
||||
}
|
||||
|
||||
// tSWR. See page 15 of the ADNS spec sheet.
|
||||
@@ -113,17 +122,17 @@ void adns_serial_write(uint8_t data) {
|
||||
|
||||
// Read a byte of data from a register on the ADNS.
|
||||
// Don't forget to use the register map (as defined in the header file).
|
||||
uint8_t adns_read_reg(uint8_t reg_addr) {
|
||||
adns_cs_select();
|
||||
uint8_t adns5050_read_reg(uint8_t reg_addr) {
|
||||
adns5050_cs_select();
|
||||
|
||||
adns_serial_write(reg_addr);
|
||||
adns5050_serial_write(reg_addr);
|
||||
|
||||
// We don't need a minimum tSRAD here. That's because a 4ms wait time is
|
||||
// already included in adns_serial_write(), so we're good.
|
||||
// already included in adns5050_serial_write(), so we're good.
|
||||
// See page 10 and 15 of the ADNS spec sheet.
|
||||
// wait_us(4);
|
||||
|
||||
uint8_t byte = adns_serial_read();
|
||||
uint8_t byte = adns5050_serial_read();
|
||||
|
||||
// tSRW & tSRR. See page 15 of the ADNS spec sheet.
|
||||
// Technically, this is only necessary if the next operation is an SDIO
|
||||
@@ -131,38 +140,38 @@ uint8_t adns_read_reg(uint8_t reg_addr) {
|
||||
// Honestly, this wait could probably be removed.
|
||||
wait_us(1);
|
||||
|
||||
adns_cs_deselect();
|
||||
adns5050_cs_deselect();
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
void adns_write_reg(uint8_t reg_addr, uint8_t data) {
|
||||
adns_cs_select();
|
||||
adns_serial_write( 0b10000000 | reg_addr );
|
||||
adns_serial_write(data);
|
||||
adns_cs_deselect();
|
||||
void adns5050_write_reg(uint8_t reg_addr, uint8_t data) {
|
||||
adns5050_cs_select();
|
||||
adns5050_serial_write(0b10000000 | reg_addr);
|
||||
adns5050_serial_write(data);
|
||||
adns5050_cs_deselect();
|
||||
}
|
||||
|
||||
report_adns_t adns_read_burst(void) {
|
||||
adns_cs_select();
|
||||
report_adns5050_t adns5050_read_burst(void) {
|
||||
adns5050_cs_select();
|
||||
|
||||
report_adns_t data;
|
||||
report_adns5050_t data;
|
||||
data.dx = 0;
|
||||
data.dy = 0;
|
||||
|
||||
adns_serial_write(REG_MOTION_BURST);
|
||||
adns5050_serial_write(REG_MOTION_BURST);
|
||||
|
||||
// We don't need a minimum tSRAD here. That's because a 4ms wait time is
|
||||
// already included in adns_serial_write(), so we're good.
|
||||
// already included in adns5050_serial_write(), so we're good.
|
||||
// See page 10 and 15 of the ADNS spec sheet.
|
||||
// wait_us(4);
|
||||
|
||||
uint8_t x = adns_serial_read();
|
||||
uint8_t y = adns_serial_read();
|
||||
uint8_t x = adns5050_serial_read();
|
||||
uint8_t y = adns5050_serial_read();
|
||||
|
||||
// Burst mode returns a bunch of other shit that we don't really need.
|
||||
// Setting CS to high ends burst mode early.
|
||||
adns_cs_deselect();
|
||||
adns5050_cs_deselect();
|
||||
|
||||
data.dx = convert_twoscomp(x);
|
||||
data.dy = convert_twoscomp(y);
|
||||
@@ -180,14 +189,21 @@ int8_t convert_twoscomp(uint8_t data) {
|
||||
}
|
||||
|
||||
// Don't forget to use the definitions for CPI in the header file.
|
||||
void adns_set_cpi(uint8_t cpi) {
|
||||
adns_write_reg(REG_MOUSE_CONTROL2, cpi);
|
||||
void adns5050_set_cpi(uint16_t cpi) {
|
||||
uint8_t cpival = constrain((cpi / 125), 0x1, 0xD); // limits to 0--119
|
||||
|
||||
adns5050_write_reg(REG_MOUSE_CONTROL2, 0b10000 | cpival);
|
||||
}
|
||||
|
||||
bool adns_check_signature(void) {
|
||||
uint8_t pid = adns_read_reg(REG_PRODUCT_ID);
|
||||
uint8_t rid = adns_read_reg(REG_REVISION_ID);
|
||||
uint8_t pid2 = adns_read_reg(REG_PRODUCT_ID2);
|
||||
uint16_t adns5050_get_cpi(void) {
|
||||
uint8_t cpival = adns5050_read_reg(REG_MOUSE_CONTROL2);
|
||||
return (uint16_t)((cpival & 0b10000) * 125);
|
||||
}
|
||||
|
||||
bool adns5050_check_signature(void) {
|
||||
uint8_t pid = adns5050_read_reg(REG_PRODUCT_ID);
|
||||
uint8_t rid = adns5050_read_reg(REG_REVISION_ID);
|
||||
uint8_t pid2 = adns5050_read_reg(REG_PRODUCT_ID2);
|
||||
|
||||
return (pid == 0x12 && rid == 0x01 && pid2 == 0x26);
|
||||
}
|
||||
|
||||
@@ -21,28 +21,8 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
// Registers
|
||||
#define REG_PRODUCT_ID 0x00
|
||||
#define REG_REVISION_ID 0x01
|
||||
#define REG_MOTION 0x02
|
||||
#define REG_DELTA_X 0x03
|
||||
#define REG_DELTA_Y 0x04
|
||||
#define REG_SQUAL 0x05
|
||||
#define REG_SHUTTER_UPPER 0x06
|
||||
#define REG_SHUTTER_LOWER 0x07
|
||||
#define REG_MAXIMUM_PIXEL 0x08
|
||||
#define REG_PIXEL_SUM 0x09
|
||||
#define REG_MINIMUM_PIXEL 0x0a
|
||||
#define REG_PIXEL_GRAB 0x0b
|
||||
#define REG_MOUSE_CONTROL 0x0d
|
||||
#define REG_MOUSE_CONTROL2 0x19
|
||||
#define REG_LED_DC_MODE 0x22
|
||||
#define REG_CHIP_RESET 0x3a
|
||||
#define REG_PRODUCT_ID2 0x3e
|
||||
#define REG_INV_REV_ID 0x3f
|
||||
#define REG_MOTION_BURST 0x63
|
||||
|
||||
// CPI values
|
||||
// clang-format off
|
||||
#define CPI125 0x11
|
||||
#define CPI250 0x12
|
||||
#define CPI375 0x13
|
||||
@@ -54,26 +34,39 @@
|
||||
#define CPI1125 0x19
|
||||
#define CPI1250 0x1a
|
||||
#define CPI1375 0x1b
|
||||
// clang-format on
|
||||
|
||||
#ifdef CONSOLE_ENABLE
|
||||
void print_byte(uint8_t byte);
|
||||
#define constrain(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt)))
|
||||
|
||||
// Definitions for the ADNS serial line.
|
||||
#ifndef ADNS5050_SCLK_PIN
|
||||
# error "No clock pin defined -- missing ADNS5050_SCLK_PIN"
|
||||
#endif
|
||||
|
||||
#ifndef ADNS5050_SDIO_PIN
|
||||
# error "No data pin defined -- missing ADNS5050_SDIO_PIN"
|
||||
#endif
|
||||
|
||||
#ifndef ADNS5050_CS_PIN
|
||||
# error "No chip select pin defined -- missing ADNS5050_CS_PIN"
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int8_t dx;
|
||||
int8_t dy;
|
||||
} report_adns_t;
|
||||
} report_adns5050_t;
|
||||
|
||||
// A bunch of functions to implement the ADNS5050-specific serial protocol.
|
||||
// Note that the "serial.h" driver is insufficient, because it does not
|
||||
// manually manipulate a serial clock signal.
|
||||
void adns_init(void);
|
||||
void adns_sync(void);
|
||||
uint8_t adns_serial_read(void);
|
||||
void adns_serial_write(uint8_t data);
|
||||
uint8_t adns_read_reg(uint8_t reg_addr);
|
||||
void adns_write_reg(uint8_t reg_addr, uint8_t data);
|
||||
report_adns_t adns_read_burst(void);
|
||||
void adns5050_init(void);
|
||||
void adns5050_sync(void);
|
||||
uint8_t adns5050_serial_read(void);
|
||||
void adns5050_serial_write(uint8_t data);
|
||||
uint8_t adns5050_read_reg(uint8_t reg_addr);
|
||||
void adns5050_write_reg(uint8_t reg_addr, uint8_t data);
|
||||
report_adns5050_t adns5050_read_burst(void);
|
||||
void adns5050_set_cpi(uint16_t cpi);
|
||||
uint16_t adns5050_get_cpi(void);
|
||||
int8_t convert_twoscomp(uint8_t data);
|
||||
void adns_set_cpi(uint8_t cpi);
|
||||
bool adns_check_signature(void);
|
||||
bool adns5050_check_signature(void);
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
*/
|
||||
|
||||
#include "spi_master.h"
|
||||
#include "quantum.h"
|
||||
#include "adns9800_srom_A6.h"
|
||||
#include "adns9800.h"
|
||||
#include "wait.h"
|
||||
|
||||
// registers
|
||||
// clang-format off
|
||||
#define REG_Product_ID 0x00
|
||||
#define REG_Revision_ID 0x01
|
||||
#define REG_Motion 0x02
|
||||
@@ -66,37 +67,28 @@
|
||||
#define REG_SROM_Load_Burst 0x62
|
||||
#define REG_Pixel_Burst 0x64
|
||||
|
||||
#define ADNS_CLOCK_SPEED 2000000
|
||||
#define MIN_CPI 200
|
||||
#define MAX_CPI 8200
|
||||
#define CPI_STEP 200
|
||||
#define CLAMP_CPI(value) value<MIN_CPI ? MIN_CPI : value> MAX_CPI ? MAX_CPI : value
|
||||
#define SPI_MODE 3
|
||||
#define SPI_DIVISOR (F_CPU / ADNS_CLOCK_SPEED)
|
||||
#define US_BETWEEN_WRITES 120
|
||||
#define US_BETWEEN_READS 20
|
||||
#define US_BEFORE_MOTION 100
|
||||
#define MSB1 0x80
|
||||
// clang-format on
|
||||
|
||||
extern const uint16_t adns_firmware_length;
|
||||
extern const uint8_t adns_firmware_data[];
|
||||
void adns9800_spi_start(void) { spi_start(ADNS9800_CS_PIN, false, ADNS9800_SPI_MODE, ADNS9800_SPI_DIVISOR); }
|
||||
|
||||
void adns_spi_start(void){
|
||||
spi_start(SPI_SS_PIN, false, SPI_MODE, SPI_DIVISOR);
|
||||
}
|
||||
|
||||
void adns_write(uint8_t reg_addr, uint8_t data){
|
||||
|
||||
adns_spi_start();
|
||||
void adns9800_write(uint8_t reg_addr, uint8_t data) {
|
||||
adns9800_spi_start();
|
||||
spi_write(reg_addr | MSB1);
|
||||
spi_write(data);
|
||||
spi_stop();
|
||||
wait_us(US_BETWEEN_WRITES);
|
||||
}
|
||||
|
||||
uint8_t adns_read(uint8_t reg_addr){
|
||||
|
||||
adns_spi_start();
|
||||
uint8_t adns9800_read(uint8_t reg_addr) {
|
||||
adns9800_spi_start();
|
||||
spi_write(reg_addr & 0x7f);
|
||||
uint8_t data = spi_read();
|
||||
spi_stop();
|
||||
@@ -105,48 +97,47 @@ uint8_t adns_read(uint8_t reg_addr){
|
||||
return data;
|
||||
}
|
||||
|
||||
void adns_init() {
|
||||
|
||||
setPinOutput(SPI_SS_PIN);
|
||||
void adns9800_init() {
|
||||
setPinOutput(ADNS9800_CS_PIN);
|
||||
|
||||
spi_init();
|
||||
|
||||
// reboot
|
||||
adns_write(REG_Power_Up_Reset, 0x5a);
|
||||
adns9800_write(REG_Power_Up_Reset, 0x5a);
|
||||
wait_ms(50);
|
||||
|
||||
// read registers and discard
|
||||
adns_read(REG_Motion);
|
||||
adns_read(REG_Delta_X_L);
|
||||
adns_read(REG_Delta_X_H);
|
||||
adns_read(REG_Delta_Y_L);
|
||||
adns_read(REG_Delta_Y_H);
|
||||
adns9800_read(REG_Motion);
|
||||
adns9800_read(REG_Delta_X_L);
|
||||
adns9800_read(REG_Delta_X_H);
|
||||
adns9800_read(REG_Delta_Y_L);
|
||||
adns9800_read(REG_Delta_Y_H);
|
||||
|
||||
// upload firmware
|
||||
|
||||
// 3k firmware mode
|
||||
adns_write(REG_Configuration_IV, 0x02);
|
||||
adns9800_write(REG_Configuration_IV, 0x02);
|
||||
|
||||
// enable initialisation
|
||||
adns_write(REG_SROM_Enable, 0x1d);
|
||||
adns9800_write(REG_SROM_Enable, 0x1d);
|
||||
|
||||
// wait a frame
|
||||
wait_ms(10);
|
||||
|
||||
// start SROM download
|
||||
adns_write(REG_SROM_Enable, 0x18);
|
||||
adns9800_write(REG_SROM_Enable, 0x18);
|
||||
|
||||
// write the SROM file
|
||||
|
||||
adns_spi_start();
|
||||
adns9800_spi_start();
|
||||
|
||||
spi_write(REG_SROM_Load_Burst | 0x80);
|
||||
wait_us(15);
|
||||
|
||||
// send all bytes of the firmware
|
||||
unsigned char c;
|
||||
for(int i = 0; i < adns_firmware_length; i++){
|
||||
c = (unsigned char)pgm_read_byte(adns_firmware_data + i);
|
||||
for (int i = 0; i < FIRMWARE_LENGTH; i++) {
|
||||
c = (unsigned char)pgm_read_byte(adns9800_firmware_data + i);
|
||||
spi_write(c);
|
||||
wait_us(15);
|
||||
}
|
||||
@@ -156,37 +147,46 @@ void adns_init() {
|
||||
wait_ms(10);
|
||||
|
||||
// enable laser
|
||||
uint8_t laser_ctrl0 = adns_read(REG_LASER_CTRL0);
|
||||
adns_write(REG_LASER_CTRL0, laser_ctrl0 & 0xf0);
|
||||
uint8_t laser_ctrl0 = adns9800_read(REG_LASER_CTRL0);
|
||||
adns9800_write(REG_LASER_CTRL0, laser_ctrl0 & 0xf0);
|
||||
|
||||
adns9800_set_cpi(ADNS9800_CPI);
|
||||
}
|
||||
|
||||
config_adns_t adns_get_config(void) {
|
||||
uint8_t config_1 = adns_read(REG_Configuration_I);
|
||||
return (config_adns_t){ (config_1 & 0xFF) * CPI_STEP };
|
||||
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};
|
||||
}
|
||||
|
||||
void adns_set_config(config_adns_t config) {
|
||||
void adns9800_set_config(config_adns9800_t config) {
|
||||
uint8_t config_1 = (CLAMP_CPI(config.cpi) / CPI_STEP) & 0xFF;
|
||||
adns_write(REG_Configuration_I, config_1);
|
||||
adns9800_write(REG_Configuration_I, config_1);
|
||||
}
|
||||
|
||||
uint16_t adns9800_get_cpi(void) {
|
||||
uint8_t config_1 = adns9800_read(REG_Configuration_I);
|
||||
return (uint16_t){(config_1 & 0xFF) * CPI_STEP};
|
||||
}
|
||||
|
||||
void adns9800_set_cpi(uint16_t cpi) {
|
||||
uint8_t config_1 = (CLAMP_CPI(cpi) / CPI_STEP) & 0xFF;
|
||||
adns9800_write(REG_Configuration_I, config_1);
|
||||
}
|
||||
|
||||
static int16_t convertDeltaToInt(uint8_t high, uint8_t low) {
|
||||
|
||||
// join bytes into twos compliment
|
||||
uint16_t twos_comp = (high << 8) | low;
|
||||
|
||||
// convert twos comp to int
|
||||
if (twos_comp & 0x8000)
|
||||
return -1 * (~twos_comp + 1);
|
||||
if (twos_comp & 0x8000) return -1 * (~twos_comp + 1);
|
||||
|
||||
return twos_comp;
|
||||
}
|
||||
|
||||
report_adns_t adns_get_report(void) {
|
||||
report_adns9800_t adns9800_get_report(void) {
|
||||
report_adns9800_t report = {0, 0};
|
||||
|
||||
report_adns_t report = {0, 0};
|
||||
|
||||
adns_spi_start();
|
||||
adns9800_spi_start();
|
||||
|
||||
// start burst mode
|
||||
spi_write(REG_Motion_Burst & 0x7f);
|
||||
@@ -196,7 +196,6 @@ report_adns_t adns_get_report(void) {
|
||||
uint8_t motion = spi_read();
|
||||
|
||||
if (motion & 0x80) {
|
||||
|
||||
// clear observation register
|
||||
spi_read();
|
||||
|
||||
|
||||
@@ -18,18 +18,48 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef ADNS9800_CPI
|
||||
# define ADNS9800_CPI 1600
|
||||
#endif
|
||||
|
||||
#ifndef ADNS9800_CLOCK_SPEED
|
||||
# define ADNS9800_CLOCK_SPEED 2000000
|
||||
#endif
|
||||
|
||||
#ifndef ADNS9800_SPI_LSBFIRST
|
||||
# define ADNS9800_SPI_LSBFIRST false
|
||||
#endif
|
||||
|
||||
#ifndef ADNS9800_SPI_MODE
|
||||
# define ADNS9800_SPI_MODE 3
|
||||
#endif
|
||||
|
||||
#ifndef ADNS9800_SPI_DIVISOR
|
||||
# ifdef __AVR__
|
||||
# define ADNS9800_SPI_DIVISOR (F_CPU / ADNS9800_CLOCK_SPEED)
|
||||
# else
|
||||
# define ADNS9800_SPI_DIVISOR 64
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ADNS9800_CS_PIN
|
||||
# error "No chip select pin defined -- missing ADNS9800_CS_PIN"
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
/* 200 - 8200 CPI supported */
|
||||
uint16_t cpi;
|
||||
} config_adns_t;
|
||||
} config_adns9800_t;
|
||||
|
||||
typedef struct {
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
} report_adns_t;
|
||||
} report_adns9800_t;
|
||||
|
||||
void adns_init(void);
|
||||
config_adns_t adns_get_config(void);
|
||||
void adns_set_config(config_adns_t);
|
||||
void adns9800_init(void);
|
||||
config_adns9800_t adns9800_get_config(void);
|
||||
void adns9800_set_config(config_adns9800_t);
|
||||
uint16_t adns9800_get_cpi(void);
|
||||
void adns9800_set_cpi(uint16_t cpi);
|
||||
/* Reads and clears the current delta values on the ADNS sensor */
|
||||
report_adns_t adns_get_report(void);
|
||||
report_adns9800_t adns9800_get_report(void);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
94
drivers/sensors/analog_joystick.c
Normal file
94
drivers/sensors/analog_joystick.c
Normal file
@@ -0,0 +1,94 @@
|
||||
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "analog_joystick.h"
|
||||
#include "analog.h"
|
||||
#include "gpio.h"
|
||||
#include "wait.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
|
||||
|
||||
int16_t xOrigin, yOrigin;
|
||||
|
||||
uint16_t lastCursor = 0;
|
||||
|
||||
int16_t axisCoordinate(uint8_t pin, uint16_t origin) {
|
||||
int8_t direction;
|
||||
int16_t distanceFromOrigin;
|
||||
int16_t range;
|
||||
|
||||
int16_t position = analogReadPin(pin);
|
||||
|
||||
if (origin == position) {
|
||||
return 0;
|
||||
} else if (origin > position) {
|
||||
distanceFromOrigin = origin - position;
|
||||
range = origin - minAxisValue;
|
||||
direction = -1;
|
||||
} else {
|
||||
distanceFromOrigin = position - origin;
|
||||
range = maxAxisValue - origin;
|
||||
direction = 1;
|
||||
}
|
||||
|
||||
float percent = (float)distanceFromOrigin / range;
|
||||
int16_t coordinate = (int16_t)(percent * 100);
|
||||
if (coordinate < 0) {
|
||||
return 0;
|
||||
} else if (coordinate > 100) {
|
||||
return 100 * direction;
|
||||
} else {
|
||||
return coordinate * direction;
|
||||
}
|
||||
}
|
||||
|
||||
int8_t axisToMouseComponent(uint8_t pin, int16_t origin, uint8_t maxSpeed) {
|
||||
int16_t coordinate = axisCoordinate(pin, origin);
|
||||
if (coordinate != 0) {
|
||||
float percent = (float)coordinate / 100;
|
||||
return percent * maxCursorSpeed * (abs(coordinate) / speedRegulator);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
report_analog_joystick_t analog_joystick_read(void) {
|
||||
report_analog_joystick_t report = {0};
|
||||
|
||||
if (timer_elapsed(lastCursor) > ANALOG_JOYSTICK_READ_INTERVAL) {
|
||||
lastCursor = timer_read();
|
||||
report.x = axisToMouseComponent(ANALOG_JOYSTICK_X_AXIS_PIN, xOrigin, maxCursorSpeed);
|
||||
report.y = axisToMouseComponent(ANALOG_JOYSTICK_Y_AXIS_PIN, yOrigin, maxCursorSpeed);
|
||||
}
|
||||
#ifdef ANALOG_JOYSTICK_CLICK_PIN
|
||||
report.button = !readPin(ANALOG_JOYSTICK_CLICK_PIN);
|
||||
#endif
|
||||
return report;
|
||||
}
|
||||
|
||||
void analog_joystick_init(void) {
|
||||
#ifdef ANALOG_JOYSTICK_CLICK_PIN
|
||||
setPinInputHigh(ANALOG_JOYSTICK_CLICK_PIN);
|
||||
#endif
|
||||
// Account for drift
|
||||
xOrigin = analogReadPin(ANALOG_JOYSTICK_X_AXIS_PIN);
|
||||
yOrigin = analogReadPin(ANALOG_JOYSTICK_Y_AXIS_PIN);
|
||||
}
|
||||
51
drivers/sensors/analog_joystick.h
Normal file
51
drivers/sensors/analog_joystick.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef ANALOG_JOYSTICK_X_AXIS_PIN
|
||||
# error No pin specified for X Axis
|
||||
#endif
|
||||
#ifndef ANALOG_JOYSTICK_Y_AXIS_PIN
|
||||
# error No pin specified for Y Axis
|
||||
#endif
|
||||
|
||||
#ifndef ANALOG_JOYSTICK_AXIS_MIN
|
||||
# define ANALOG_JOYSTICK_AXIS_MIN 0
|
||||
#endif
|
||||
#ifndef ANALOG_JOYSTICK_AXIS_MAX
|
||||
# define ANALOG_JOYSTICK_AXIS_MAX 1023
|
||||
#endif
|
||||
#ifndef ANALOG_JOYSTICK_SPEED_REGULATOR
|
||||
# define ANALOG_JOYSTICK_SPEED_REGULATOR 20
|
||||
#endif
|
||||
#ifndef ANALOG_JOYSTICK_READ_INTERVAL
|
||||
# define ANALOG_JOYSTICK_READ_INTERVAL 10
|
||||
#endif
|
||||
#ifndef ANALOG_JOYSTICK_SPEED_MAX
|
||||
# define ANALOG_JOYSTICK_SPEED_MAX 2
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int8_t x;
|
||||
int8_t y;
|
||||
bool button;
|
||||
} report_analog_joystick_t;
|
||||
report_analog_joystick_t analog_joystick_read(void);
|
||||
void analog_joystick_init(void);
|
||||
232
drivers/sensors/cirque_pinnacle.c
Normal file
232
drivers/sensors/cirque_pinnacle.c
Normal file
@@ -0,0 +1,232 @@
|
||||
// Copyright (c) 2018 Cirque Corp. Restrictions apply. See: www.cirque.com/sw-license
|
||||
#include "cirque_pinnacle.h"
|
||||
#include "print.h"
|
||||
#include "debug.h"
|
||||
#include "wait.h"
|
||||
|
||||
// Registers for RAP
|
||||
// clang-format off
|
||||
#define FIRMWARE_ID 0x00
|
||||
#define FIRMWARE_VERSION_C 0x01
|
||||
#define STATUS_1 0x02
|
||||
#define SYSCONFIG_1 0x03
|
||||
#define FEEDCONFIG_1 0x04
|
||||
#define FEEDCONFIG_2 0x05
|
||||
#define CALIBRATION_CONFIG_1 0x07
|
||||
#define PS2_AU_CONTROL 0x08
|
||||
#define SAMPLE_RATE 0x09
|
||||
#define Z_IDLE_COUNT 0x0A
|
||||
#define Z_SCALER 0x0B
|
||||
#define SLEEP_INTERVAL 0x0C
|
||||
#define SLEEP_TIMER 0x0D
|
||||
#define PACKET_BYTE_0 0x12
|
||||
#define PACKET_BYTE_1 0x13
|
||||
#define PACKET_BYTE_2 0x14
|
||||
#define PACKET_BYTE_3 0x15
|
||||
#define PACKET_BYTE_4 0x16
|
||||
#define PACKET_BYTE_5 0x17
|
||||
|
||||
#define ERA_VALUE 0x1B
|
||||
#define ERA_HIGH_BYTE 0x1C
|
||||
#define ERA_LOW_BYTE 0x1D
|
||||
#define ERA_CONTROL 0x1E
|
||||
|
||||
// ADC-attenuation settings (held in BIT_7 and BIT_6)
|
||||
// 1X = most sensitive, 4X = least sensitive
|
||||
#define ADC_ATTENUATE_1X 0x00
|
||||
#define ADC_ATTENUATE_2X 0x40
|
||||
#define ADC_ATTENUATE_3X 0x80
|
||||
#define ADC_ATTENUATE_4X 0xC0
|
||||
|
||||
// Register config values for this demo
|
||||
#define SYSCONFIG_1_VALUE 0x00
|
||||
#define FEEDCONFIG_1_VALUE 0x03 // 0x03 for absolute mode 0x01 for relative mode
|
||||
#define FEEDCONFIG_2_VALUE 0x1C // 0x1F for normal functionality 0x1E for intellimouse disabled
|
||||
#define Z_IDLE_COUNT_VALUE 0x05
|
||||
// clang-format on
|
||||
|
||||
bool touchpad_init;
|
||||
uint16_t scale_data = 1024;
|
||||
|
||||
void cirque_pinnacle_clear_flags(void);
|
||||
void cirque_pinnacle_enable_feed(bool feedEnable);
|
||||
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')); }
|
||||
#endif
|
||||
|
||||
/* Logical Scaling Functions */
|
||||
// Clips raw coordinates to "reachable" window of sensor
|
||||
// NOTE: values outside this window can only appear as a result of noise
|
||||
void ClipCoordinates(pinnacle_data_t* coordinates) {
|
||||
if (coordinates->xValue < CIRQUE_PINNACLE_X_LOWER) {
|
||||
coordinates->xValue = CIRQUE_PINNACLE_X_LOWER;
|
||||
} else if (coordinates->xValue > CIRQUE_PINNACLE_X_UPPER) {
|
||||
coordinates->xValue = CIRQUE_PINNACLE_X_UPPER;
|
||||
}
|
||||
if (coordinates->yValue < CIRQUE_PINNACLE_Y_LOWER) {
|
||||
coordinates->yValue = CIRQUE_PINNACLE_Y_LOWER;
|
||||
} else if (coordinates->yValue > CIRQUE_PINNACLE_Y_UPPER) {
|
||||
coordinates->yValue = CIRQUE_PINNACLE_Y_UPPER;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
uint32_t xTemp = 0;
|
||||
uint32_t yTemp = 0;
|
||||
|
||||
ClipCoordinates(coordinates);
|
||||
|
||||
xTemp = coordinates->xValue;
|
||||
yTemp = coordinates->yValue;
|
||||
|
||||
// translate coordinates to (0, 0) reference by subtracting edge-offset
|
||||
xTemp -= CIRQUE_PINNACLE_X_LOWER;
|
||||
yTemp -= CIRQUE_PINNACLE_Y_LOWER;
|
||||
|
||||
// scale coordinates to (xResolution, yResolution) range
|
||||
coordinates->xValue = (uint16_t)(xTemp * xResolution / CIRQUE_PINNACLE_X_RANGE);
|
||||
coordinates->yValue = (uint16_t)(yTemp * yResolution / CIRQUE_PINNACLE_Y_RANGE);
|
||||
}
|
||||
|
||||
// Clears Status1 register flags (SW_CC and SW_DR)
|
||||
void cirque_pinnacle_clear_flags() {
|
||||
RAP_Write(STATUS_1, 0x00);
|
||||
wait_us(50);
|
||||
}
|
||||
|
||||
// Enables/Disables the feed
|
||||
void cirque_pinnacle_enable_feed(bool feedEnable) {
|
||||
uint8_t temp;
|
||||
|
||||
RAP_ReadBytes(FEEDCONFIG_1, &temp, 1); // Store contents of FeedConfig1 register
|
||||
|
||||
if (feedEnable) {
|
||||
temp |= 0x01; // Set Feed Enable bit
|
||||
RAP_Write(0x04, temp);
|
||||
} else {
|
||||
temp &= ~0x01; // Clear Feed Enable bit
|
||||
RAP_Write(0x04, temp);
|
||||
}
|
||||
}
|
||||
|
||||
/* ERA (Extended Register Access) Functions */
|
||||
// Reads <count> bytes from an extended register at <address> (16-bit address),
|
||||
// stores values in <*data>
|
||||
void ERA_ReadBytes(uint16_t address, uint8_t* data, uint16_t count) {
|
||||
uint8_t ERAControlValue = 0xFF;
|
||||
|
||||
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
|
||||
|
||||
for (uint16_t i = 0; i < count; i++) {
|
||||
RAP_Write(ERA_CONTROL, 0x05); // Signal ERA-read (auto-increment) to Pinnacle
|
||||
|
||||
// Wait for status register 0x1E to clear
|
||||
do {
|
||||
RAP_ReadBytes(ERA_CONTROL, &ERAControlValue, 1);
|
||||
} while (ERAControlValue != 0x00);
|
||||
|
||||
RAP_ReadBytes(ERA_VALUE, data + i, 1);
|
||||
|
||||
cirque_pinnacle_clear_flags();
|
||||
}
|
||||
}
|
||||
|
||||
// Writes a byte, <data>, to an extended register at <address> (16-bit address)
|
||||
void ERA_WriteByte(uint16_t address, uint8_t data) {
|
||||
uint8_t ERAControlValue = 0xFF;
|
||||
|
||||
cirque_pinnacle_enable_feed(false); // Disable feed
|
||||
|
||||
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_CONTROL, 0x02); // Signal an ERA-write to Pinnacle
|
||||
|
||||
// Wait for status register 0x1E to clear
|
||||
do {
|
||||
RAP_ReadBytes(ERA_CONTROL, &ERAControlValue, 1);
|
||||
} while (ERAControlValue != 0x00);
|
||||
|
||||
cirque_pinnacle_clear_flags();
|
||||
}
|
||||
|
||||
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 |= adcGain;
|
||||
ERA_WriteByte(0x0187, temp);
|
||||
ERA_ReadBytes(0x0187, &temp, 1);
|
||||
}
|
||||
|
||||
// Changes thresholds to improve detection of fingers
|
||||
void cirque_pinnacle_tune_edge_sensitivity(void) {
|
||||
uint8_t temp = 0x00;
|
||||
|
||||
ERA_ReadBytes(0x0149, &temp, 1);
|
||||
ERA_WriteByte(0x0149, 0x04);
|
||||
ERA_ReadBytes(0x0149, &temp, 1);
|
||||
|
||||
ERA_ReadBytes(0x0168, &temp, 1);
|
||||
ERA_WriteByte(0x0168, 0x03);
|
||||
ERA_ReadBytes(0x0168, &temp, 1);
|
||||
}
|
||||
|
||||
/* Pinnacle-based TM040040 Functions */
|
||||
void cirque_pinnacle_init(void) {
|
||||
#if defined(POINTING_DEVICE_DRIVER_cirque_pinnacle_spi)
|
||||
spi_init();
|
||||
#elif defined(POINTING_DEVICE_DRIVER_cirque_pinnacle_i2c)
|
||||
i2c_init();
|
||||
#endif
|
||||
|
||||
touchpad_init = true;
|
||||
// Host clears SW_CC flag
|
||||
cirque_pinnacle_clear_flags();
|
||||
|
||||
// Host configures bits of registers 0x03 and 0x05
|
||||
RAP_Write(SYSCONFIG_1, SYSCONFIG_1_VALUE);
|
||||
RAP_Write(FEEDCONFIG_2, FEEDCONFIG_2_VALUE);
|
||||
|
||||
// Host enables preferred output mode (absolute)
|
||||
RAP_Write(FEEDCONFIG_1, FEEDCONFIG_1_VALUE);
|
||||
|
||||
// Host sets z-idle packet count to 5 (default is 30)
|
||||
RAP_Write(Z_IDLE_COUNT, Z_IDLE_COUNT_VALUE);
|
||||
|
||||
cirque_pinnacle_set_adc_attenuation(0xFF);
|
||||
cirque_pinnacle_tune_edge_sensitivity();
|
||||
cirque_pinnacle_enable_feed(true);
|
||||
}
|
||||
|
||||
// Reads XYZ data from Pinnacle registers 0x14 through 0x17
|
||||
// Stores result in pinnacle_data_t struct with xValue, yValue, and zValue members
|
||||
pinnacle_data_t cirque_pinnacle_read_data(void) {
|
||||
uint8_t data[6] = {0};
|
||||
pinnacle_data_t result = {0};
|
||||
RAP_ReadBytes(PACKET_BYTE_0, data, 6);
|
||||
|
||||
cirque_pinnacle_clear_flags();
|
||||
|
||||
result.buttonFlags = data[0] & 0x3F;
|
||||
result.xValue = data[2] | ((data[4] & 0x0F) << 8);
|
||||
result.yValue = data[3] | ((data[4] & 0xF0) << 4);
|
||||
result.zValue = data[5] & 0x3F;
|
||||
|
||||
result.touchDown = (result.xValue != 0 || result.yValue != 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
74
drivers/sensors/cirque_pinnacle.h
Normal file
74
drivers/sensors/cirque_pinnacle.h
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright (c) 2018 Cirque Corp. Restrictions apply. See: www.cirque.com/sw-license
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// Convenient way to store and access measurements
|
||||
typedef struct {
|
||||
uint16_t xValue;
|
||||
uint16_t yValue;
|
||||
uint16_t zValue;
|
||||
uint8_t buttonFlags;
|
||||
bool touchDown;
|
||||
} pinnacle_data_t;
|
||||
|
||||
void cirque_pinnacle_init(void);
|
||||
pinnacle_data_t cirque_pinnacle_read_data(void);
|
||||
void cirque_pinnacle_scale_data(pinnacle_data_t* coordinates, uint16_t xResolution, uint16_t yResolution);
|
||||
uint16_t cirque_pinnacle_get_scale(void);
|
||||
void cirque_pinnacle_set_scale(uint16_t scale);
|
||||
|
||||
#ifndef CIRQUE_PINNACLE_TIMEOUT
|
||||
# define CIRQUE_PINNACLE_TIMEOUT 20
|
||||
#endif
|
||||
|
||||
// Coordinate scaling values
|
||||
#ifndef CIRQUE_PINNACLE_X_LOWER
|
||||
# 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
|
||||
#endif
|
||||
#ifndef CIRQUE_PINNACLE_Y_LOWER
|
||||
# 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
|
||||
#endif
|
||||
#ifndef CIRQUE_PINNACLE_X_RANGE
|
||||
# define CIRQUE_PINNACLE_X_RANGE (CIRQUE_PINNACLE_X_UPPER - CIRQUE_PINNACLE_X_LOWER)
|
||||
#endif
|
||||
#ifndef CIRQUE_PINNACLE_Y_RANGE
|
||||
# define CIRQUE_PINNACLE_Y_RANGE (CIRQUE_PINNACLE_Y_UPPER - CIRQUE_PINNACLE_Y_LOWER)
|
||||
#endif
|
||||
|
||||
#if defined(POINTING_DEVICE_DRIVER_cirque_pinnacle_i2c)
|
||||
# include "i2c_master.h"
|
||||
// Cirque's 7-bit I2C Slave Address
|
||||
# ifndef CIRQUE_PINNACLE_ADDR
|
||||
# define CIRQUE_PINNACLE_ADDR 0x2A
|
||||
# endif
|
||||
#elif defined(POINTING_DEVICE_DRIVER_cirque_pinnacle_spi)
|
||||
# include "spi_master.h"
|
||||
# ifndef CIRQUE_PINNACLE_CLOCK_SPEED
|
||||
# define CIRQUE_PINNACLE_CLOCK_SPEED 10000000
|
||||
# endif
|
||||
# ifndef CIRQUE_PINNACLE_SPI_LSBFIRST
|
||||
# define CIRQUE_PINNACLE_SPI_LSBFIRST false
|
||||
# endif
|
||||
# ifndef CIRQUE_PINNACLE_SPI_MODE
|
||||
# define CIRQUE_PINNACLE_SPI_MODE 1
|
||||
# endif
|
||||
# ifndef CIRQUE_PINNACLE_SPI_DIVISOR
|
||||
# ifdef __AVR__
|
||||
# define CIRQUE_PINNACLE_SPI_DIVISOR (F_CPU / CIRQUE_PINNACLE_CLOCK_SPEED)
|
||||
# else
|
||||
# define CIRQUE_PINNACLE_SPI_DIVISOR 64
|
||||
# endif
|
||||
# ifndef CIRQUE_PINNACLE_SPI_CS_PIN
|
||||
# error "No Chip Select pin has been defined -- missing CIRQUE_PINNACLE_SPI_CS_PIN define"
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
43
drivers/sensors/cirque_pinnacle_i2c.c
Normal file
43
drivers/sensors/cirque_pinnacle_i2c.c
Normal file
@@ -0,0 +1,43 @@
|
||||
// Copyright (c) 2018 Cirque Corp. Restrictions apply. See: www.cirque.com/sw-license
|
||||
#include "cirque_pinnacle.h"
|
||||
#include "i2c_master.h"
|
||||
#include "print.h"
|
||||
#include "debug.h"
|
||||
#include "stdio.h"
|
||||
|
||||
// Masks for Cirque Register Access Protocol (RAP)
|
||||
#define WRITE_MASK 0x80
|
||||
#define READ_MASK 0xA0
|
||||
|
||||
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
|
||||
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) {
|
||||
#ifdef CONSOLE_ENABLE
|
||||
dprintf("error right touchpad\n");
|
||||
#endif
|
||||
touchpad_init = false;
|
||||
}
|
||||
i2c_stop();
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
if (touchpad_init) {
|
||||
if (i2c_writeReg(CIRQUE_PINNACLE_ADDR << 1, cmdByte, &data, sizeof(data), CIRQUE_PINNACLE_TIMEOUT) != I2C_STATUS_SUCCESS) {
|
||||
#ifdef CONSOLE_ENABLE
|
||||
dprintf("error right touchpad\n");
|
||||
#endif
|
||||
touchpad_init = false;
|
||||
}
|
||||
i2c_stop();
|
||||
}
|
||||
}
|
||||
52
drivers/sensors/cirque_pinnacle_spi.c
Normal file
52
drivers/sensors/cirque_pinnacle_spi.c
Normal file
@@ -0,0 +1,52 @@
|
||||
// Copyright (c) 2018 Cirque Corp. Restrictions apply. See: www.cirque.com/sw-license
|
||||
#include "cirque_pinnacle.h"
|
||||
#include "spi_master.h"
|
||||
#include "print.h"
|
||||
#include "debug.h"
|
||||
|
||||
// Masks for Cirque Register Access Protocol (RAP)
|
||||
#define WRITE_MASK 0x80
|
||||
#define READ_MASK 0xA0
|
||||
|
||||
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
|
||||
if (touchpad_init) {
|
||||
if (spi_start(CIRQUE_PINNACLE_SPI_CS_PIN, CIRQUE_TRACKPAD_SPI_LSBFIRST, CIRQUE_PINNACLE_SPI_MODE, CIRQUE_PINNACLE_SPI_DIVISOR)) {
|
||||
spi_write(cmdByte);
|
||||
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
|
||||
}
|
||||
} else {
|
||||
#ifdef CONSOLE_ENABLE
|
||||
dprintf("error right touchpad\n");
|
||||
#endif
|
||||
touchpad_init = false;
|
||||
j
|
||||
}
|
||||
spi_stop();
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
if (touchpad_init) {
|
||||
if (spi_start(CIRQUE_PINNACLE_SPI_CS_PIN, CIRQUE_TRACKPAD_SPI_LSBFIRST, CIRQUE_PINNACLE_SPI_MODE, CIRQUE_PINNACLE_SPI_DIVISOR)) {
|
||||
spi_write(cmdByte);
|
||||
spi_write(data);
|
||||
} else {
|
||||
#ifdef CONSOLE_ENABLE
|
||||
dprintf("error right touchpad\n");
|
||||
#endif
|
||||
touchpad_init = false;
|
||||
}
|
||||
spi_stop();
|
||||
}
|
||||
}
|
||||
@@ -17,73 +17,55 @@
|
||||
#include "pimoroni_trackball.h"
|
||||
#include "i2c_master.h"
|
||||
#include "print.h"
|
||||
#include "debug.h"
|
||||
#include "timer.h"
|
||||
|
||||
#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_MOUSE_SCALE
|
||||
# define PIMORONI_TRACKBALL_MOUSE_SCALE 5
|
||||
#endif
|
||||
#ifndef PIMORONI_TRACKBALL_SCROLL_SCALE
|
||||
# define PIMORONI_TRACKBALL_SCROLL_SCALE 1
|
||||
#endif
|
||||
#ifndef PIMORONI_TRACKBALL_DEBOUNCE_CYCLES
|
||||
# define PIMORONI_TRACKBALL_DEBOUNCE_CYCLES 20
|
||||
#endif
|
||||
#ifndef PIMORONI_TRACKBALL_ERROR_COUNT
|
||||
# define PIMORONI_TRACKBALL_ERROR_COUNT 10
|
||||
#endif
|
||||
// clang-format off
|
||||
#define PIMORONI_TRACKBALL_REG_LED_RED 0x00
|
||||
#define PIMORONI_TRACKBALL_REG_LED_GRN 0x01
|
||||
#define PIMORONI_TRACKBALL_REG_LED_BLU 0x02
|
||||
#define PIMORONI_TRACKBALL_REG_LED_WHT 0x03
|
||||
#define PIMORONI_TRACKBALL_REG_LEFT 0x04
|
||||
#define PIMORONI_TRACKBALL_REG_RIGHT 0x05
|
||||
#define PIMORONI_TRACKBALL_REG_UP 0x06
|
||||
#define PIMORONI_TRACKBALL_REG_DOWN 0x07
|
||||
// clang-format on
|
||||
|
||||
#define TRACKBALL_TIMEOUT 100
|
||||
#define TRACKBALL_REG_LED_RED 0x00
|
||||
#define TRACKBALL_REG_LED_GRN 0x01
|
||||
#define TRACKBALL_REG_LED_BLU 0x02
|
||||
#define TRACKBALL_REG_LED_WHT 0x03
|
||||
#define TRACKBALL_REG_LEFT 0x04
|
||||
#define TRACKBALL_REG_RIGHT 0x05
|
||||
#define TRACKBALL_REG_UP 0x06
|
||||
#define TRACKBALL_REG_DOWN 0x07
|
||||
|
||||
static pimoroni_data current_pimoroni_data;
|
||||
static report_mouse_t mouse_report;
|
||||
static bool scrolling = false;
|
||||
static int16_t x_offset = 0;
|
||||
static int16_t y_offset = 0;
|
||||
static int16_t h_offset = 0;
|
||||
static int16_t v_offset = 0;
|
||||
static uint16_t precision = 128;
|
||||
static uint8_t error_count = 0;
|
||||
|
||||
float trackball_get_precision(void) { return ((float)precision / 128); }
|
||||
void trackball_set_precision(float floatprecision) { precision = (floatprecision * 128); }
|
||||
bool trackball_is_scrolling(void) { return scrolling; }
|
||||
void trackball_set_scrolling(bool scroll) { scrolling = scroll; }
|
||||
float pimoroni_trackball_get_precision(void) { return ((float)precision / 128); }
|
||||
void pimoroni_trackball_set_precision(float floatprecision) { precision = (floatprecision * 128); }
|
||||
|
||||
void trackball_set_rgbw(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
|
||||
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};
|
||||
__attribute__((unused)) i2c_status_t status = i2c_writeReg(PIMORONI_TRACKBALL_ADDRESS << 1, TRACKBALL_REG_LED_RED, data, sizeof(data), TRACKBALL_TIMEOUT);
|
||||
#ifdef TRACKBALL_DEBUG
|
||||
dprintf("Trackball RGBW i2c_status_t: %d\n", status);
|
||||
__attribute__((unused)) i2c_status_t status = i2c_writeReg(PIMORONI_TRACKBALL_ADDRESS << 1, PIMORONI_TRACKBALL_REG_LED_RED, data, sizeof(data), PIMORONI_TRACKBALL_TIMEOUT);
|
||||
|
||||
#ifdef CONSOLE_ENABLE
|
||||
if (debug_mouse) dprintf("Trackball RGBW i2c_status_t: %d\n", status);
|
||||
#endif
|
||||
}
|
||||
|
||||
i2c_status_t read_pimoroni_trackball(pimoroni_data* data) {
|
||||
i2c_status_t status = i2c_readReg(PIMORONI_TRACKBALL_ADDRESS << 1, TRACKBALL_REG_LEFT, (uint8_t*)data, sizeof(*data), TRACKBALL_TIMEOUT);
|
||||
#ifdef TRACKBALL_DEBUG
|
||||
dprintf("Trackball READ i2c_status_t: %d\nLeft: %d\nRight: %d\nUp: %d\nDown: %d\nSwtich: %d\n", status, data->left, data->right, data->up, data->down, data->click);
|
||||
i2c_status_t read_pimoroni_trackball(pimoroni_data_t* data) {
|
||||
i2c_status_t status = i2c_readReg(PIMORONI_TRACKBALL_ADDRESS << 1, PIMORONI_TRACKBALL_REG_LEFT, (uint8_t*)data, sizeof(*data), PIMORONI_TRACKBALL_TIMEOUT);
|
||||
#ifdef CONSOLE_ENABLE
|
||||
if (debug_mouse) {
|
||||
static uint16_t d_timer;
|
||||
if (timer_elapsed(d_timer) > PIMORONI_TRACKBALL_DEBUG_INTERVAL) {
|
||||
dprintf("Trackball READ i2c_status_t: %d L: %d R: %d Up: %d D: %d SW: %d\n", status, data->left, data->right, data->up, data->down, data->click);
|
||||
d_timer = timer_read();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
__attribute__((weak)) void pointing_device_init(void) {
|
||||
__attribute__((weak)) void pimironi_trackball_device_init(void) {
|
||||
i2c_init();
|
||||
trackball_set_rgbw(0x00, 0x00, 0x00, 0x00);
|
||||
pimoroni_trackball_set_rgbw(0x00, 0x00, 0x00, 0x00);
|
||||
}
|
||||
|
||||
int16_t trackball_get_offsets(uint8_t negative_dir, uint8_t positive_dir, uint8_t scale) {
|
||||
int16_t pimoroni_trackball_get_offsets(uint8_t negative_dir, uint8_t positive_dir, uint8_t scale) {
|
||||
uint8_t offset = 0;
|
||||
bool isnegative = false;
|
||||
if (negative_dir > positive_dir) {
|
||||
@@ -96,7 +78,7 @@ int16_t trackball_get_offsets(uint8_t negative_dir, uint8_t positive_dir, uint8_
|
||||
return isnegative ? -(int16_t)(magnitude) : (int16_t)(magnitude);
|
||||
}
|
||||
|
||||
void trackball_adapt_values(int8_t* mouse, int16_t* offset) {
|
||||
void pimoroni_trackball_adapt_values(int8_t* mouse, int16_t* offset) {
|
||||
if (*offset > 127) {
|
||||
*mouse = 127;
|
||||
*offset -= 127;
|
||||
@@ -108,94 +90,3 @@ void trackball_adapt_values(int8_t* mouse, int16_t* offset) {
|
||||
*offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((weak)) void trackball_click(bool pressed, report_mouse_t* mouse) {
|
||||
#ifdef PIMORONI_TRACKBALL_CLICK
|
||||
if (pressed) {
|
||||
mouse->buttons |= MOUSE_BTN1;
|
||||
} else {
|
||||
mouse->buttons &= ~MOUSE_BTN1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
__attribute__((weak)) bool pointing_device_task_user(pimoroni_data* trackball_data) { return true; };
|
||||
|
||||
__attribute__((weak)) void pointing_device_task() {
|
||||
static fast_timer_t throttle = 0;
|
||||
static uint16_t debounce = 0;
|
||||
|
||||
if (error_count < PIMORONI_TRACKBALL_ERROR_COUNT && timer_elapsed_fast(throttle) >= PIMORONI_TRACKBALL_INTERVAL_MS) {
|
||||
i2c_status_t status = read_pimoroni_trackball(¤t_pimoroni_data);
|
||||
|
||||
if (status == I2C_STATUS_SUCCESS) {
|
||||
error_count = 0;
|
||||
|
||||
if (pointing_device_task_user(¤t_pimoroni_data)) {
|
||||
mouse_report = pointing_device_get_report();
|
||||
|
||||
if (!(current_pimoroni_data.click & 128)) {
|
||||
trackball_click(false, &mouse_report);
|
||||
if (!debounce) {
|
||||
if (scrolling) {
|
||||
#ifdef PIMORONI_TRACKBALL_INVERT_X
|
||||
h_offset += trackball_get_offsets(current_pimoroni_data.right, current_pimoroni_data.left, PIMORONI_TRACKBALL_SCROLL_SCALE);
|
||||
#else
|
||||
h_offset -= trackball_get_offsets(current_pimoroni_data.right, current_pimoroni_data.left, PIMORONI_TRACKBALL_SCROLL_SCALE);
|
||||
#endif
|
||||
#ifdef PIMORONI_TRACKBALL_INVERT_Y
|
||||
v_offset += trackball_get_offsets(current_pimoroni_data.down, current_pimoroni_data.up, PIMORONI_TRACKBALL_SCROLL_SCALE);
|
||||
#else
|
||||
v_offset -= trackball_get_offsets(current_pimoroni_data.down, current_pimoroni_data.up, PIMORONI_TRACKBALL_SCROLL_SCALE);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef PIMORONI_TRACKBALL_INVERT_X
|
||||
x_offset -= trackball_get_offsets(current_pimoroni_data.right, current_pimoroni_data.left, PIMORONI_TRACKBALL_MOUSE_SCALE);
|
||||
#else
|
||||
x_offset += trackball_get_offsets(current_pimoroni_data.right, current_pimoroni_data.left, PIMORONI_TRACKBALL_MOUSE_SCALE);
|
||||
#endif
|
||||
#ifdef PIMORONI_TRACKBALL_INVERT_Y
|
||||
y_offset -= trackball_get_offsets(current_pimoroni_data.down, current_pimoroni_data.up, PIMORONI_TRACKBALL_MOUSE_SCALE);
|
||||
#else
|
||||
y_offset += trackball_get_offsets(current_pimoroni_data.down, current_pimoroni_data.up, PIMORONI_TRACKBALL_MOUSE_SCALE);
|
||||
#endif
|
||||
}
|
||||
if (scrolling) {
|
||||
#ifndef PIMORONI_TRACKBALL_ROTATE
|
||||
trackball_adapt_values(&mouse_report.h, &h_offset);
|
||||
trackball_adapt_values(&mouse_report.v, &v_offset);
|
||||
#else
|
||||
trackball_adapt_values(&mouse_report.h, &v_offset);
|
||||
trackball_adapt_values(&mouse_report.v, &h_offset);
|
||||
#endif
|
||||
mouse_report.x = 0;
|
||||
mouse_report.y = 0;
|
||||
} else {
|
||||
#ifndef PIMORONI_TRACKBALL_ROTATE
|
||||
trackball_adapt_values(&mouse_report.x, &x_offset);
|
||||
trackball_adapt_values(&mouse_report.y, &y_offset);
|
||||
#else
|
||||
trackball_adapt_values(&mouse_report.x, &y_offset);
|
||||
trackball_adapt_values(&mouse_report.y, &x_offset);
|
||||
#endif
|
||||
mouse_report.h = 0;
|
||||
mouse_report.v = 0;
|
||||
}
|
||||
} else {
|
||||
debounce--;
|
||||
}
|
||||
} else {
|
||||
trackball_click(true, &mouse_report);
|
||||
debounce = PIMORONI_TRACKBALL_DEBOUNCE_CYCLES;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error_count++;
|
||||
}
|
||||
|
||||
pointing_device_set_report(mouse_report);
|
||||
pointing_device_send();
|
||||
|
||||
throttle = timer_read_fast();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,22 +16,46 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "quantum.h"
|
||||
#include "pointing_device.h"
|
||||
#include <stdint.h>
|
||||
#include "report.h"
|
||||
#include "i2c_master.h"
|
||||
|
||||
typedef struct pimoroni_data {
|
||||
#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
|
||||
#ifndef PIMORONI_TRACKBALL_DEBOUNCE_CYCLES
|
||||
# define PIMORONI_TRACKBALL_DEBOUNCE_CYCLES 20
|
||||
#endif
|
||||
#ifndef PIMORONI_TRACKBALL_ERROR_COUNT
|
||||
# define PIMORONI_TRACKBALL_ERROR_COUNT 10
|
||||
#endif
|
||||
|
||||
#ifndef PIMORONI_TRACKBALL_TIMEOUT
|
||||
# define PIMORONI_TRACKBALL_TIMEOUT 100
|
||||
#endif
|
||||
|
||||
#ifndef PIMORONI_TRACKBALL_DEBUG_INTERVAL
|
||||
# define PIMORONI_TRACKBALL_DEBUG_INTERVAL 100
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint8_t left;
|
||||
uint8_t right;
|
||||
uint8_t up;
|
||||
uint8_t down;
|
||||
uint8_t click;
|
||||
} pimoroni_data;
|
||||
} pimoroni_data_t;
|
||||
|
||||
void trackball_set_rgbw(uint8_t red, uint8_t green, uint8_t blue, uint8_t white);
|
||||
void trackball_click(bool pressed, report_mouse_t* mouse);
|
||||
int16_t trackball_get_offsets(uint8_t negative_dir, uint8_t positive_dir, uint8_t scale);
|
||||
void trackball_adapt_values(int8_t* mouse, int16_t* offset);
|
||||
float trackball_get_precision(void);
|
||||
void trackball_set_precision(float precision);
|
||||
bool trackball_is_scrolling(void);
|
||||
void trackball_set_scrolling(bool scroll);
|
||||
void pimironi_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);
|
||||
i2c_status_t read_pimoroni_trackball(pimoroni_data_t* data);
|
||||
|
||||
@@ -20,9 +20,10 @@
|
||||
#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
|
||||
@@ -72,10 +73,18 @@
|
||||
#define REG_Lift_Config 0x63
|
||||
#define REG_Raw_Data_Burst 0x64
|
||||
#define REG_LiftCutoff_Tune2 0x65
|
||||
// clang-format on
|
||||
|
||||
#ifndef MAX_CPI
|
||||
# define MAX_CPI 0x77 // limits to 0--119, should be max cpi/100
|
||||
#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')); }
|
||||
#endif
|
||||
#define constrain(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt)))
|
||||
|
||||
bool spi_start_adv(void) {
|
||||
bool status = spi_start(PMW3360_CS_PIN, PMW3360_SPI_LSBFIRST, PMW3360_SPI_MODE, PMW3360_SPI_DIVISOR);
|
||||
@@ -124,20 +133,20 @@ uint8_t spi_read_adv(uint8_t reg_addr) {
|
||||
return data;
|
||||
}
|
||||
|
||||
void pmw_set_cpi(uint16_t cpi) {
|
||||
uint8_t cpival = constrain((cpi / 100) - 1, 0, 0x77); // limits to 0--119
|
||||
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 pmw_get_cpi(void) {
|
||||
uint16_t pmw3360_get_cpi(void) {
|
||||
uint8_t cpival = spi_read_adv(REG_Config1);
|
||||
return (uint16_t)(cpival & 0xFF) * 100;
|
||||
}
|
||||
|
||||
bool pmw_spi_init(void) {
|
||||
bool pmw3360_init(void) {
|
||||
setPinOutput(PMW3360_CS_PIN);
|
||||
|
||||
spi_init();
|
||||
@@ -164,12 +173,12 @@ bool pmw_spi_init(void) {
|
||||
spi_read_adv(REG_Delta_Y_L);
|
||||
spi_read_adv(REG_Delta_Y_H);
|
||||
|
||||
pmw_upload_firmware();
|
||||
pmw3360_upload_firmware();
|
||||
|
||||
spi_stop_adv();
|
||||
|
||||
wait_ms(10);
|
||||
pmw_set_cpi(PMW3360_CPI);
|
||||
pmw3360_set_cpi(PMW3360_CPI);
|
||||
|
||||
wait_ms(1);
|
||||
|
||||
@@ -177,14 +186,14 @@ bool pmw_spi_init(void) {
|
||||
|
||||
spi_write_adv(REG_Angle_Tune, constrain(ROTATIONAL_TRANSFORM_ANGLE, -30, 30));
|
||||
|
||||
bool init_success = pmw_check_signature();
|
||||
bool init_success = pmw3360_check_signature();
|
||||
|
||||
writePinLow(PMW3360_CS_PIN);
|
||||
|
||||
return init_success;
|
||||
}
|
||||
|
||||
void pmw_upload_firmware(void) {
|
||||
void pmw3360_upload_firmware(void) {
|
||||
spi_write_adv(REG_SROM_Enable, 0x1d);
|
||||
|
||||
wait_ms(10);
|
||||
@@ -196,7 +205,7 @@ void pmw_upload_firmware(void) {
|
||||
wait_us(15);
|
||||
|
||||
unsigned char c;
|
||||
for (int i = 0; i < firmware_length; i++) {
|
||||
for (int i = 0; i < FIRMWARE_LENGTH; i++) {
|
||||
c = (unsigned char)pgm_read_byte(firmware_data + i);
|
||||
spi_write(c);
|
||||
wait_us(15);
|
||||
@@ -211,16 +220,18 @@ void pmw_upload_firmware(void) {
|
||||
wait_ms(10);
|
||||
}
|
||||
|
||||
bool pmw_check_signature(void) {
|
||||
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 == 0x42 && iv_pid == 0xBD && SROM_ver == 0x04); // signature for SROM 0x04
|
||||
return (pid == firmware_signature[0] && iv_pid == firmware_signature[1] && SROM_ver == firmware_signature[2]); // signature for SROM 0x04
|
||||
}
|
||||
|
||||
report_pmw_t pmw_read_burst(void) {
|
||||
report_pmw3360_t pmw3360_read_burst(void) {
|
||||
if (!_inBurst) {
|
||||
#ifdef CONSOLE_ENABLE
|
||||
dprintf("burst on");
|
||||
#endif
|
||||
spi_write_adv(REG_Motion_Burst, 0x00);
|
||||
_inBurst = true;
|
||||
}
|
||||
@@ -229,12 +240,7 @@ report_pmw_t pmw_read_burst(void) {
|
||||
spi_write(REG_Motion_Burst);
|
||||
wait_us(35); // waits for tSRAD
|
||||
|
||||
report_pmw_t data;
|
||||
data.motion = 0;
|
||||
data.dx = 0;
|
||||
data.mdx = 0;
|
||||
data.dy = 0;
|
||||
data.mdx = 0;
|
||||
report_pmw3360_t data = {0};
|
||||
|
||||
data.motion = spi_read();
|
||||
spi_write(0x00); // skip Observation
|
||||
@@ -245,6 +251,7 @@ report_pmw_t pmw_read_burst(void) {
|
||||
|
||||
spi_stop();
|
||||
|
||||
#ifdef CONSOLE_ENABLE
|
||||
if (debug_mouse) {
|
||||
print_byte(data.motion);
|
||||
print_byte(data.dx);
|
||||
@@ -253,6 +260,7 @@ report_pmw_t pmw_read_burst(void) {
|
||||
print_byte(data.mdy);
|
||||
dprintf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
data.isMotion = (data.motion & 0x80) != 0;
|
||||
data.isOnSurface = (data.motion & 0x08) == 0;
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "report.h"
|
||||
#include "spi_master.h"
|
||||
|
||||
#ifndef PMW3360_CPI
|
||||
@@ -25,7 +27,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef PMW3360_CLOCK_SPEED
|
||||
# define PMW3360_CLOCK_SPEED 70000000
|
||||
# define PMW3360_CLOCK_SPEED 2000000
|
||||
#endif
|
||||
|
||||
#ifndef PMW3360_SPI_LSBFIRST
|
||||
@@ -52,6 +54,17 @@
|
||||
# error "No chip select pin defined -- missing PMW3360_CS_PIN"
|
||||
#endif
|
||||
|
||||
/*
|
||||
The pmw33660 and pmw3389 use the same registers and timing and such.
|
||||
The only differences between the two is the firmware used, and the
|
||||
range for the DPI. So add a semi-secret hack to allow use of the
|
||||
pmw3389's firmware blob. Also, can set the max cpi range too.
|
||||
This should work for the 3390 and 3391 too, in theory.
|
||||
*/
|
||||
#ifndef PMW3360_FIRMWARE_H
|
||||
# define PMW3360_FIRMWARE_H "pmw3360_firmware.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONSOLE_ENABLE
|
||||
void print_byte(uint8_t byte);
|
||||
#endif
|
||||
@@ -64,22 +77,18 @@ typedef struct {
|
||||
int8_t mdx;
|
||||
int16_t dy; // displacement on y directions.
|
||||
int8_t mdy;
|
||||
} report_pmw_t;
|
||||
|
||||
|
||||
} report_pmw3360_t;
|
||||
|
||||
bool spi_start_adv(void);
|
||||
void spi_stop_adv(void);
|
||||
spi_status_t spi_write_adv(uint8_t reg_addr, uint8_t data);
|
||||
uint8_t spi_read_adv(uint8_t reg_addr);
|
||||
bool pmw_spi_init(void);
|
||||
void pmw_set_cpi(uint16_t cpi);
|
||||
uint16_t pmw_get_cpi(void);
|
||||
void pmw_upload_firmware(void);
|
||||
bool pmw_check_signature(void);
|
||||
report_pmw_t pmw_read_burst(void);
|
||||
|
||||
bool pmw3360_init(void);
|
||||
void pmw3360_set_cpi(uint16_t cpi);
|
||||
uint16_t pmw3360_get_cpi(void);
|
||||
void pmw3360_upload_firmware(void);
|
||||
bool pmw3360_check_signature(void);
|
||||
report_pmw3360_t pmw3360_read_burst(void);
|
||||
|
||||
#define degToRad(angleInDegrees) ((angleInDegrees)*M_PI / 180.0)
|
||||
#define radToDeg(angleInRadians) ((angleInRadians)*180.0 / M_PI)
|
||||
#define constrain(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt)))
|
||||
|
||||
@@ -18,283 +18,271 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
// clang-format off
|
||||
#include "progmem.h"
|
||||
|
||||
// PID, Inverse PID, SROM version
|
||||
const uint8_t firmware_signature[] PROGMEM = {0x42, 0xBD, 0x04};
|
||||
|
||||
#define FIRMWARE_LENGTH 4094
|
||||
|
||||
// Firmware Blob foor PMW3360
|
||||
const uint16_t firmware_length = 4094;
|
||||
// clang-format off
|
||||
const uint8_t firmware_data[] PROGMEM = { // SROM 0x04
|
||||
0x01, 0x04, 0x8e, 0x96, 0x6e, 0x77, 0x3e, 0xfe, 0x7e, 0x5f, 0x1d, 0xb8, 0xf2, 0x66, 0x4e,
|
||||
0xff, 0x5d, 0x19, 0xb0, 0xc2, 0x04, 0x69, 0x54, 0x2a, 0xd6, 0x2e, 0xbf, 0xdd, 0x19, 0xb0,
|
||||
0xc3, 0xe5, 0x29, 0xb1, 0xe0, 0x23, 0xa5, 0xa9, 0xb1, 0xc1, 0x00, 0x82, 0x67, 0x4c, 0x1a,
|
||||
0x97, 0x8d, 0x79, 0x51, 0x20, 0xc7, 0x06, 0x8e, 0x7c, 0x7c, 0x7a, 0x76, 0x4f, 0xfd, 0x59,
|
||||
0x30, 0xe2, 0x46, 0x0e, 0x9e, 0xbe, 0xdf, 0x1d, 0x99, 0x91, 0xa0, 0xa5, 0xa1, 0xa9, 0xd0,
|
||||
0x22, 0xc6, 0xef, 0x5c, 0x1b, 0x95, 0x89, 0x90, 0xa2, 0xa7, 0xcc, 0xfb, 0x55, 0x28, 0xb3,
|
||||
0xe4, 0x4a, 0xf7, 0x6c, 0x3b, 0xf4, 0x6a, 0x56, 0x2e, 0xde, 0x1f, 0x9d, 0xb8, 0xd3, 0x05,
|
||||
0x88, 0x92, 0xa6, 0xce, 0x1e, 0xbe, 0xdf, 0x1d, 0x99, 0xb0, 0xe2, 0x46, 0xef, 0x5c, 0x07,
|
||||
0x11, 0x5d, 0x98, 0x0b, 0x9d, 0x94, 0x97, 0xee, 0x4e, 0x45, 0x33, 0x6b, 0x44, 0xc7, 0x29,
|
||||
0x56, 0x27, 0x30, 0xc6, 0xa7, 0xd5, 0xf2, 0x56, 0xdf, 0xb4, 0x38, 0x62, 0xcb, 0xa0, 0xb6,
|
||||
0xe3, 0x0f, 0x84, 0x06, 0x24, 0x05, 0x65, 0x6f, 0x76, 0x89, 0xb5, 0x77, 0x41, 0x27, 0x82,
|
||||
0x66, 0x65, 0x82, 0xcc, 0xd5, 0xe6, 0x20, 0xd5, 0x27, 0x17, 0xc5, 0xf8, 0x03, 0x23, 0x7c,
|
||||
0x5f, 0x64, 0xa5, 0x1d, 0xc1, 0xd6, 0x36, 0xcb, 0x4c, 0xd4, 0xdb, 0x66, 0xd7, 0x8b, 0xb1,
|
||||
0x99, 0x7e, 0x6f, 0x4c, 0x36, 0x40, 0x06, 0xd6, 0xeb, 0xd7, 0xa2, 0xe4, 0xf4, 0x95, 0x51,
|
||||
0x5a, 0x54, 0x96, 0xd5, 0x53, 0x44, 0xd7, 0x8c, 0xe0, 0xb9, 0x40, 0x68, 0xd2, 0x18, 0xe9,
|
||||
0xdd, 0x9a, 0x23, 0x92, 0x48, 0xee, 0x7f, 0x43, 0xaf, 0xea, 0x77, 0x38, 0x84, 0x8c, 0x0a,
|
||||
0x72, 0xaf, 0x69, 0xf8, 0xdd, 0xf1, 0x24, 0x83, 0xa3, 0xf8, 0x4a, 0xbf, 0xf5, 0x94, 0x13,
|
||||
0xdb, 0xbb, 0xd8, 0xb4, 0xb3, 0xa0, 0xfb, 0x45, 0x50, 0x60, 0x30, 0x59, 0x12, 0x31, 0x71,
|
||||
0xa2, 0xd3, 0x13, 0xe7, 0xfa, 0xe7, 0xce, 0x0f, 0x63, 0x15, 0x0b, 0x6b, 0x94, 0xbb, 0x37,
|
||||
0x83, 0x26, 0x05, 0x9d, 0xfb, 0x46, 0x92, 0xfc, 0x0a, 0x15, 0xd1, 0x0d, 0x73, 0x92, 0xd6,
|
||||
0x8c, 0x1b, 0x8c, 0xb8, 0x55, 0x8a, 0xce, 0xbd, 0xfe, 0x8e, 0xfc, 0xed, 0x09, 0x12, 0x83,
|
||||
0x91, 0x82, 0x51, 0x31, 0x23, 0xfb, 0xb4, 0x0c, 0x76, 0xad, 0x7c, 0xd9, 0xb4, 0x4b, 0xb2,
|
||||
0x67, 0x14, 0x09, 0x9c, 0x7f, 0x0c, 0x18, 0xba, 0x3b, 0xd6, 0x8e, 0x14, 0x2a, 0xe4, 0x1b,
|
||||
0x52, 0x9f, 0x2b, 0x7d, 0xe1, 0xfb, 0x6a, 0x33, 0x02, 0xfa, 0xac, 0x5a, 0xf2, 0x3e, 0x88,
|
||||
0x7e, 0xae, 0xd1, 0xf3, 0x78, 0xe8, 0x05, 0xd1, 0xe3, 0xdc, 0x21, 0xf6, 0xe1, 0x9a, 0xbd,
|
||||
0x17, 0x0e, 0xd9, 0x46, 0x9b, 0x88, 0x03, 0xea, 0xf6, 0x66, 0xbe, 0x0e, 0x1b, 0x50, 0x49,
|
||||
0x96, 0x40, 0x97, 0xf1, 0xf1, 0xe4, 0x80, 0xa6, 0x6e, 0xe8, 0x77, 0x34, 0xbf, 0x29, 0x40,
|
||||
0x44, 0xc2, 0xff, 0x4e, 0x98, 0xd3, 0x9c, 0xa3, 0x32, 0x2b, 0x76, 0x51, 0x04, 0x09, 0xe7,
|
||||
0xa9, 0xd1, 0xa6, 0x32, 0xb1, 0x23, 0x53, 0xe2, 0x47, 0xab, 0xd6, 0xf5, 0x69, 0x5c, 0x3e,
|
||||
0x5f, 0xfa, 0xae, 0x45, 0x20, 0xe5, 0xd2, 0x44, 0xff, 0x39, 0x32, 0x6d, 0xfd, 0x27, 0x57,
|
||||
0x5c, 0xfd, 0xf0, 0xde, 0xc1, 0xb5, 0x99, 0xe5, 0xf5, 0x1c, 0x77, 0x01, 0x75, 0xc5, 0x6d,
|
||||
0x58, 0x92, 0xf2, 0xb2, 0x47, 0x00, 0x01, 0x26, 0x96, 0x7a, 0x30, 0xff, 0xb7, 0xf0, 0xef,
|
||||
0x77, 0xc1, 0x8a, 0x5d, 0xdc, 0xc0, 0xd1, 0x29, 0x30, 0x1e, 0x77, 0x38, 0x7a, 0x94, 0xf1,
|
||||
0xb8, 0x7a, 0x7e, 0xef, 0xa4, 0xd1, 0xac, 0x31, 0x4a, 0xf2, 0x5d, 0x64, 0x3d, 0xb2, 0xe2,
|
||||
0xf0, 0x08, 0x99, 0xfc, 0x70, 0xee, 0x24, 0xa7, 0x7e, 0xee, 0x1e, 0x20, 0x69, 0x7d, 0x44,
|
||||
0xbf, 0x87, 0x42, 0xdf, 0x88, 0x3b, 0x0c, 0xda, 0x42, 0xc9, 0x04, 0xf9, 0x45, 0x50, 0xfc,
|
||||
0x83, 0x8f, 0x11, 0x6a, 0x72, 0xbc, 0x99, 0x95, 0xf0, 0xac, 0x3d, 0xa7, 0x3b, 0xcd, 0x1c,
|
||||
0xe2, 0x88, 0x79, 0x37, 0x11, 0x5f, 0x39, 0x89, 0x95, 0x0a, 0x16, 0x84, 0x7a, 0xf6, 0x8a,
|
||||
0xa4, 0x28, 0xe4, 0xed, 0x83, 0x80, 0x3b, 0xb1, 0x23, 0xa5, 0x03, 0x10, 0xf4, 0x66, 0xea,
|
||||
0xbb, 0x0c, 0x0f, 0xc5, 0xec, 0x6c, 0x69, 0xc5, 0xd3, 0x24, 0xab, 0xd4, 0x2a, 0xb7, 0x99,
|
||||
0x88, 0x76, 0x08, 0xa0, 0xa8, 0x95, 0x7c, 0xd8, 0x38, 0x6d, 0xcd, 0x59, 0x02, 0x51, 0x4b,
|
||||
0xf1, 0xb5, 0x2b, 0x50, 0xe3, 0xb6, 0xbd, 0xd0, 0x72, 0xcf, 0x9e, 0xfd, 0x6e, 0xbb, 0x44,
|
||||
0xc8, 0x24, 0x8a, 0x77, 0x18, 0x8a, 0x13, 0x06, 0xef, 0x97, 0x7d, 0xfa, 0x81, 0xf0, 0x31,
|
||||
0xe6, 0xfa, 0x77, 0xed, 0x31, 0x06, 0x31, 0x5b, 0x54, 0x8a, 0x9f, 0x30, 0x68, 0xdb, 0xe2,
|
||||
0x40, 0xf8, 0x4e, 0x73, 0xfa, 0xab, 0x74, 0x8b, 0x10, 0x58, 0x13, 0xdc, 0xd2, 0xe6, 0x78,
|
||||
0xd1, 0x32, 0x2e, 0x8a, 0x9f, 0x2c, 0x58, 0x06, 0x48, 0x27, 0xc5, 0xa9, 0x5e, 0x81, 0x47,
|
||||
0x89, 0x46, 0x21, 0x91, 0x03, 0x70, 0xa4, 0x3e, 0x88, 0x9c, 0xda, 0x33, 0x0a, 0xce, 0xbc,
|
||||
0x8b, 0x8e, 0xcf, 0x9f, 0xd3, 0x71, 0x80, 0x43, 0xcf, 0x6b, 0xa9, 0x51, 0x83, 0x76, 0x30,
|
||||
0x82, 0xc5, 0x6a, 0x85, 0x39, 0x11, 0x50, 0x1a, 0x82, 0xdc, 0x1e, 0x1c, 0xd5, 0x7d, 0xa9,
|
||||
0x71, 0x99, 0x33, 0x47, 0x19, 0x97, 0xb3, 0x5a, 0xb1, 0xdf, 0xed, 0xa4, 0xf2, 0xe6, 0x26,
|
||||
0x84, 0xa2, 0x28, 0x9a, 0x9e, 0xdf, 0xa6, 0x6a, 0xf4, 0xd6, 0xfc, 0x2e, 0x5b, 0x9d, 0x1a,
|
||||
0x2a, 0x27, 0x68, 0xfb, 0xc1, 0x83, 0x21, 0x4b, 0x90, 0xe0, 0x36, 0xdd, 0x5b, 0x31, 0x42,
|
||||
0x55, 0xa0, 0x13, 0xf7, 0xd0, 0x89, 0x53, 0x71, 0x99, 0x57, 0x09, 0x29, 0xc5, 0xf3, 0x21,
|
||||
0xf8, 0x37, 0x2f, 0x40, 0xf3, 0xd4, 0xaf, 0x16, 0x08, 0x36, 0x02, 0xfc, 0x77, 0xc5, 0x8b,
|
||||
0x04, 0x90, 0x56, 0xb9, 0xc9, 0x67, 0x9a, 0x99, 0xe8, 0x00, 0xd3, 0x86, 0xff, 0x97, 0x2d,
|
||||
0x08, 0xe9, 0xb7, 0xb3, 0x91, 0xbc, 0xdf, 0x45, 0xc6, 0xed, 0x0f, 0x8c, 0x4c, 0x1e, 0xe6,
|
||||
0x5b, 0x6e, 0x38, 0x30, 0xe4, 0xaa, 0xe3, 0x95, 0xde, 0xb9, 0xe4, 0x9a, 0xf5, 0xb2, 0x55,
|
||||
0x9a, 0x87, 0x9b, 0xf6, 0x6a, 0xb2, 0xf2, 0x77, 0x9a, 0x31, 0xf4, 0x7a, 0x31, 0xd1, 0x1d,
|
||||
0x04, 0xc0, 0x7c, 0x32, 0xa2, 0x9e, 0x9a, 0xf5, 0x62, 0xf8, 0x27, 0x8d, 0xbf, 0x51, 0xff,
|
||||
0xd3, 0xdf, 0x64, 0x37, 0x3f, 0x2a, 0x6f, 0x76, 0x3a, 0x7d, 0x77, 0x06, 0x9e, 0x77, 0x7f,
|
||||
0x5e, 0xeb, 0x32, 0x51, 0xf9, 0x16, 0x66, 0x9a, 0x09, 0xf3, 0xb0, 0x08, 0xa4, 0x70, 0x96,
|
||||
0x46, 0x30, 0xff, 0xda, 0x4f, 0xe9, 0x1b, 0xed, 0x8d, 0xf8, 0x74, 0x1f, 0x31, 0x92, 0xb3,
|
||||
0x73, 0x17, 0x36, 0xdb, 0x91, 0x30, 0xd6, 0x88, 0x55, 0x6b, 0x34, 0x77, 0x87, 0x7a, 0xe7,
|
||||
0xee, 0x06, 0xc6, 0x1c, 0x8c, 0x19, 0x0c, 0x48, 0x46, 0x23, 0x5e, 0x9c, 0x07, 0x5c, 0xbf,
|
||||
0xb4, 0x7e, 0xd6, 0x4f, 0x74, 0x9c, 0xe2, 0xc5, 0x50, 0x8b, 0xc5, 0x8b, 0x15, 0x90, 0x60,
|
||||
0x62, 0x57, 0x29, 0xd0, 0x13, 0x43, 0xa1, 0x80, 0x88, 0x91, 0x00, 0x44, 0xc7, 0x4d, 0x19,
|
||||
0x86, 0xcc, 0x2f, 0x2a, 0x75, 0x5a, 0xfc, 0xeb, 0x97, 0x2a, 0x70, 0xe3, 0x78, 0xd8, 0x91,
|
||||
0xb0, 0x4f, 0x99, 0x07, 0xa3, 0x95, 0xea, 0x24, 0x21, 0xd5, 0xde, 0x51, 0x20, 0x93, 0x27,
|
||||
0x0a, 0x30, 0x73, 0xa8, 0xff, 0x8a, 0x97, 0xe9, 0xa7, 0x6a, 0x8e, 0x0d, 0xe8, 0xf0, 0xdf,
|
||||
0xec, 0xea, 0xb4, 0x6c, 0x1d, 0x39, 0x2a, 0x62, 0x2d, 0x3d, 0x5a, 0x8b, 0x65, 0xf8, 0x90,
|
||||
0x05, 0x2e, 0x7e, 0x91, 0x2c, 0x78, 0xef, 0x8e, 0x7a, 0xc1, 0x2f, 0xac, 0x78, 0xee, 0xaf,
|
||||
0x28, 0x45, 0x06, 0x4c, 0x26, 0xaf, 0x3b, 0xa2, 0xdb, 0xa3, 0x93, 0x06, 0xb5, 0x3c, 0xa5,
|
||||
0xd8, 0xee, 0x8f, 0xaf, 0x25, 0xcc, 0x3f, 0x85, 0x68, 0x48, 0xa9, 0x62, 0xcc, 0x97, 0x8f,
|
||||
0x7f, 0x2a, 0xea, 0xe0, 0x15, 0x0a, 0xad, 0x62, 0x07, 0xbd, 0x45, 0xf8, 0x41, 0xd8, 0x36,
|
||||
0xcb, 0x4c, 0xdb, 0x6e, 0xe6, 0x3a, 0xe7, 0xda, 0x15, 0xe9, 0x29, 0x1e, 0x12, 0x10, 0xa0,
|
||||
0x14, 0x2c, 0x0e, 0x3d, 0xf4, 0xbf, 0x39, 0x41, 0x92, 0x75, 0x0b, 0x25, 0x7b, 0xa3, 0xce,
|
||||
0x39, 0x9c, 0x15, 0x64, 0xc8, 0xfa, 0x3d, 0xef, 0x73, 0x27, 0xfe, 0x26, 0x2e, 0xce, 0xda,
|
||||
0x6e, 0xfd, 0x71, 0x8e, 0xdd, 0xfe, 0x76, 0xee, 0xdc, 0x12, 0x5c, 0x02, 0xc5, 0x3a, 0x4e,
|
||||
0x4e, 0x4f, 0xbf, 0xca, 0x40, 0x15, 0xc7, 0x6e, 0x8d, 0x41, 0xf1, 0x10, 0xe0, 0x4f, 0x7e,
|
||||
0x97, 0x7f, 0x1c, 0xae, 0x47, 0x8e, 0x6b, 0xb1, 0x25, 0x31, 0xb0, 0x73, 0xc7, 0x1b, 0x97,
|
||||
0x79, 0xf9, 0x80, 0xd3, 0x66, 0x22, 0x30, 0x07, 0x74, 0x1e, 0xe4, 0xd0, 0x80, 0x21, 0xd6,
|
||||
0xee, 0x6b, 0x6c, 0x4f, 0xbf, 0xf5, 0xb7, 0xd9, 0x09, 0x87, 0x2f, 0xa9, 0x14, 0xbe, 0x27,
|
||||
0xd9, 0x72, 0x50, 0x01, 0xd4, 0x13, 0x73, 0xa6, 0xa7, 0x51, 0x02, 0x75, 0x25, 0xe1, 0xb3,
|
||||
0x45, 0x34, 0x7d, 0xa8, 0x8e, 0xeb, 0xf3, 0x16, 0x49, 0xcb, 0x4f, 0x8c, 0xa1, 0xb9, 0x36,
|
||||
0x85, 0x39, 0x75, 0x5d, 0x08, 0x00, 0xae, 0xeb, 0xf6, 0xea, 0xd7, 0x13, 0x3a, 0x21, 0x5a,
|
||||
0x5f, 0x30, 0x84, 0x52, 0x26, 0x95, 0xc9, 0x14, 0xf2, 0x57, 0x55, 0x6b, 0xb1, 0x10, 0xc2,
|
||||
0xe1, 0xbd, 0x3b, 0x51, 0xc0, 0xb7, 0x55, 0x4c, 0x71, 0x12, 0x26, 0xc7, 0x0d, 0xf9, 0x51,
|
||||
0xa4, 0x38, 0x02, 0x05, 0x7f, 0xb8, 0xf1, 0x72, 0x4b, 0xbf, 0x71, 0x89, 0x14, 0xf3, 0x77,
|
||||
0x38, 0xd9, 0x71, 0x24, 0xf3, 0x00, 0x11, 0xa1, 0xd8, 0xd4, 0x69, 0x27, 0x08, 0x37, 0x35,
|
||||
0xc9, 0x11, 0x9d, 0x90, 0x1c, 0x0e, 0xe7, 0x1c, 0xff, 0x2d, 0x1e, 0xe8, 0x92, 0xe1, 0x18,
|
||||
0x10, 0x95, 0x7c, 0xe0, 0x80, 0xf4, 0x96, 0x43, 0x21, 0xf9, 0x75, 0x21, 0x64, 0x38, 0xdd,
|
||||
0x9f, 0x1e, 0x95, 0x16, 0xda, 0x56, 0x1d, 0x4f, 0x9a, 0x53, 0xb2, 0xe2, 0xe4, 0x18, 0xcb,
|
||||
0x6b, 0x1a, 0x65, 0xeb, 0x56, 0xc6, 0x3b, 0xe5, 0xfe, 0xd8, 0x26, 0x3f, 0x3a, 0x84, 0x59,
|
||||
0x72, 0x66, 0xa2, 0xf3, 0x75, 0xff, 0xfb, 0x60, 0xb3, 0x22, 0xad, 0x3f, 0x2d, 0x6b, 0xf9,
|
||||
0xeb, 0xea, 0x05, 0x7c, 0xd8, 0x8f, 0x6d, 0x2c, 0x98, 0x9e, 0x2b, 0x93, 0xf1, 0x5e, 0x46,
|
||||
0xf0, 0x87, 0x49, 0x29, 0x73, 0x68, 0xd7, 0x7f, 0xf9, 0xf0, 0xe5, 0x7d, 0xdb, 0x1d, 0x75,
|
||||
0x19, 0xf3, 0xc4, 0x58, 0x9b, 0x17, 0x88, 0xa8, 0x92, 0xe0, 0xbe, 0xbd, 0x8b, 0x1d, 0x8d,
|
||||
0x9f, 0x56, 0x76, 0xad, 0xaf, 0x29, 0xe2, 0xd9, 0xd5, 0x52, 0xf6, 0xb5, 0x56, 0x35, 0x57,
|
||||
0x3a, 0xc8, 0xe1, 0x56, 0x43, 0x19, 0x94, 0xd3, 0x04, 0x9b, 0x6d, 0x35, 0xd8, 0x0b, 0x5f,
|
||||
0x4d, 0x19, 0x8e, 0xec, 0xfa, 0x64, 0x91, 0x0a, 0x72, 0x20, 0x2b, 0xbc, 0x1a, 0x4a, 0xfe,
|
||||
0x8b, 0xfd, 0xbb, 0xed, 0x1b, 0x23, 0xea, 0xad, 0x72, 0x82, 0xa1, 0x29, 0x99, 0x71, 0xbd,
|
||||
0xf0, 0x95, 0xc1, 0x03, 0xdd, 0x7b, 0xc2, 0xb2, 0x3c, 0x28, 0x54, 0xd3, 0x68, 0xa4, 0x72,
|
||||
0xc8, 0x66, 0x96, 0xe0, 0xd1, 0xd8, 0x7f, 0xf8, 0xd1, 0x26, 0x2b, 0xf7, 0xad, 0xba, 0x55,
|
||||
0xca, 0x15, 0xb9, 0x32, 0xc3, 0xe5, 0x88, 0x97, 0x8e, 0x5c, 0xfb, 0x92, 0x25, 0x8b, 0xbf,
|
||||
0xa2, 0x45, 0x55, 0x7a, 0xa7, 0x6f, 0x8b, 0x57, 0x5b, 0xcf, 0x0e, 0xcb, 0x1d, 0xfb, 0x20,
|
||||
0x82, 0x77, 0xa8, 0x8c, 0xcc, 0x16, 0xce, 0x1d, 0xfa, 0xde, 0xcc, 0x0b, 0x62, 0xfe, 0xcc,
|
||||
0xe1, 0xb7, 0xf0, 0xc3, 0x81, 0x64, 0x73, 0x40, 0xa0, 0xc2, 0x4d, 0x89, 0x11, 0x75, 0x33,
|
||||
0x55, 0x33, 0x8d, 0xe8, 0x4a, 0xfd, 0xea, 0x6e, 0x30, 0x0b, 0xd7, 0x31, 0x2c, 0xde, 0x47,
|
||||
0xe3, 0xbf, 0xf8, 0x55, 0x42, 0xe2, 0x7f, 0x59, 0xe5, 0x17, 0xef, 0x99, 0x34, 0x69, 0x91,
|
||||
0xb1, 0x23, 0x8e, 0x20, 0x87, 0x2d, 0xa8, 0xfe, 0xd5, 0x8a, 0xf3, 0x84, 0x3a, 0xf0, 0x37,
|
||||
0xe4, 0x09, 0x00, 0x54, 0xee, 0x67, 0x49, 0x93, 0xe4, 0x81, 0x70, 0xe3, 0x90, 0x4d, 0xef,
|
||||
0xfe, 0x41, 0xb7, 0x99, 0x7b, 0xc1, 0x83, 0xba, 0x62, 0x12, 0x6f, 0x7d, 0xde, 0x6b, 0xaf,
|
||||
0xda, 0x16, 0xf9, 0x55, 0x51, 0xee, 0xa6, 0x0c, 0x2b, 0x02, 0xa3, 0xfd, 0x8d, 0xfb, 0x30,
|
||||
0x17, 0xe4, 0x6f, 0xdf, 0x36, 0x71, 0xc4, 0xca, 0x87, 0x25, 0x48, 0xb0, 0x47, 0xec, 0xea,
|
||||
0xb4, 0xbf, 0xa5, 0x4d, 0x9b, 0x9f, 0x02, 0x93, 0xc4, 0xe3, 0xe4, 0xe8, 0x42, 0x2d, 0x68,
|
||||
0x81, 0x15, 0x0a, 0xeb, 0x84, 0x5b, 0xd6, 0xa8, 0x74, 0xfb, 0x7d, 0x1d, 0xcb, 0x2c, 0xda,
|
||||
0x46, 0x2a, 0x76, 0x62, 0xce, 0xbc, 0x5c, 0x9e, 0x8b, 0xe7, 0xcf, 0xbe, 0x78, 0xf5, 0x7c,
|
||||
0xeb, 0xb3, 0x3a, 0x9c, 0xaa, 0x6f, 0xcc, 0x72, 0xd1, 0x59, 0xf2, 0x11, 0x23, 0xd6, 0x3f,
|
||||
0x48, 0xd1, 0xb7, 0xce, 0xb0, 0xbf, 0xcb, 0xea, 0x80, 0xde, 0x57, 0xd4, 0x5e, 0x97, 0x2f,
|
||||
0x75, 0xd1, 0x50, 0x8e, 0x80, 0x2c, 0x66, 0x79, 0xbf, 0x72, 0x4b, 0xbd, 0x8a, 0x81, 0x6c,
|
||||
0xd3, 0xe1, 0x01, 0xdc, 0xd2, 0x15, 0x26, 0xc5, 0x36, 0xda, 0x2c, 0x1a, 0xc0, 0x27, 0x94,
|
||||
0xed, 0xb7, 0x9b, 0x85, 0x0b, 0x5e, 0x80, 0x97, 0xc5, 0xec, 0x4f, 0xec, 0x88, 0x5d, 0x50,
|
||||
0x07, 0x35, 0x47, 0xdc, 0x0b, 0x3b, 0x3d, 0xdd, 0x60, 0xaf, 0xa8, 0x5d, 0x81, 0x38, 0x24,
|
||||
0x25, 0x5d, 0x5c, 0x15, 0xd1, 0xde, 0xb3, 0xab, 0xec, 0x05, 0x69, 0xef, 0x83, 0xed, 0x57,
|
||||
0x54, 0xb8, 0x64, 0x64, 0x11, 0x16, 0x32, 0x69, 0xda, 0x9f, 0x2d, 0x7f, 0x36, 0xbb, 0x44,
|
||||
0x5a, 0x34, 0xe8, 0x7f, 0xbf, 0x03, 0xeb, 0x00, 0x7f, 0x59, 0x68, 0x22, 0x79, 0xcf, 0x73,
|
||||
0x6c, 0x2c, 0x29, 0xa7, 0xa1, 0x5f, 0x38, 0xa1, 0x1d, 0xf0, 0x20, 0x53, 0xe0, 0x1a, 0x63,
|
||||
0x14, 0x58, 0x71, 0x10, 0xaa, 0x08, 0x0c, 0x3e, 0x16, 0x1a, 0x60, 0x22, 0x82, 0x7f, 0xba,
|
||||
0xa4, 0x43, 0xa0, 0xd0, 0xac, 0x1b, 0xd5, 0x6b, 0x64, 0xb5, 0x14, 0x93, 0x31, 0x9e, 0x53,
|
||||
0x50, 0xd0, 0x57, 0x66, 0xee, 0x5a, 0x4f, 0xfb, 0x03, 0x2a, 0x69, 0x58, 0x76, 0xf1, 0x83,
|
||||
0xf7, 0x4e, 0xba, 0x8c, 0x42, 0x06, 0x60, 0x5d, 0x6d, 0xce, 0x60, 0x88, 0xae, 0xa4, 0xc3,
|
||||
0xf1, 0x03, 0xa5, 0x4b, 0x98, 0xa1, 0xff, 0x67, 0xe1, 0xac, 0xa2, 0xb8, 0x62, 0xd7, 0x6f,
|
||||
0xa0, 0x31, 0xb4, 0xd2, 0x77, 0xaf, 0x21, 0x10, 0x06, 0xc6, 0x9a, 0xff, 0x1d, 0x09, 0x17,
|
||||
0x0e, 0x5f, 0xf1, 0xaa, 0x54, 0x34, 0x4b, 0x45, 0x8a, 0x87, 0x63, 0xa6, 0xdc, 0xf9, 0x24,
|
||||
0x30, 0x67, 0xc6, 0xb2, 0xd6, 0x61, 0x33, 0x69, 0xee, 0x50, 0x61, 0x57, 0x28, 0xe7, 0x7e,
|
||||
0xee, 0xec, 0x3a, 0x5a, 0x73, 0x4e, 0xa8, 0x8d, 0xe4, 0x18, 0xea, 0xec, 0x41, 0x64, 0xc8,
|
||||
0xe2, 0xe8, 0x66, 0xb6, 0x2d, 0xb6, 0xfb, 0x6a, 0x6c, 0x16, 0xb3, 0xdd, 0x46, 0x43, 0xb9,
|
||||
0x73, 0x00, 0x6a, 0x71, 0xed, 0x4e, 0x9d, 0x25, 0x1a, 0xc3, 0x3c, 0x4a, 0x95, 0x15, 0x99,
|
||||
0x35, 0x81, 0x14, 0x02, 0xd6, 0x98, 0x9b, 0xec, 0xd8, 0x23, 0x3b, 0x84, 0x29, 0xaf, 0x0c,
|
||||
0x99, 0x83, 0xa6, 0x9a, 0x34, 0x4f, 0xfa, 0xe8, 0xd0, 0x3c, 0x4b, 0xd0, 0xfb, 0xb6, 0x68,
|
||||
0xb8, 0x9e, 0x8f, 0xcd, 0xf7, 0x60, 0x2d, 0x7a, 0x22, 0xe5, 0x7d, 0xab, 0x65, 0x1b, 0x95,
|
||||
0xa7, 0xa8, 0x7f, 0xb6, 0x77, 0x47, 0x7b, 0x5f, 0x8b, 0x12, 0x72, 0xd0, 0xd4, 0x91, 0xef,
|
||||
0xde, 0x19, 0x50, 0x3c, 0xa7, 0x8b, 0xc4, 0xa9, 0xb3, 0x23, 0xcb, 0x76, 0xe6, 0x81, 0xf0,
|
||||
0xc1, 0x04, 0x8f, 0xa3, 0xb8, 0x54, 0x5b, 0x97, 0xac, 0x19, 0xff, 0x3f, 0x55, 0x27, 0x2f,
|
||||
0xe0, 0x1d, 0x42, 0x9b, 0x57, 0xfc, 0x4b, 0x4e, 0x0f, 0xce, 0x98, 0xa9, 0x43, 0x57, 0x03,
|
||||
0xbd, 0xe7, 0xc8, 0x94, 0xdf, 0x6e, 0x36, 0x73, 0x32, 0xb4, 0xef, 0x2e, 0x85, 0x7a, 0x6e,
|
||||
0xfc, 0x6c, 0x18, 0x82, 0x75, 0x35, 0x90, 0x07, 0xf3, 0xe4, 0x9f, 0x3e, 0xdc, 0x68, 0xf3,
|
||||
0xb5, 0xf3, 0x19, 0x80, 0x92, 0x06, 0x99, 0xa2, 0xe8, 0x6f, 0xff, 0x2e, 0x7f, 0xae, 0x42,
|
||||
0xa4, 0x5f, 0xfb, 0xd4, 0x0e, 0x81, 0x2b, 0xc3, 0x04, 0xff, 0x2b, 0xb3, 0x74, 0x4e, 0x36,
|
||||
0x5b, 0x9c, 0x15, 0x00, 0xc6, 0x47, 0x2b, 0xe8, 0x8b, 0x3d, 0xf1, 0x9c, 0x03, 0x9a, 0x58,
|
||||
0x7f, 0x9b, 0x9c, 0xbf, 0x85, 0x49, 0x79, 0x35, 0x2e, 0x56, 0x7b, 0x41, 0x14, 0x39, 0x47,
|
||||
0x83, 0x26, 0xaa, 0x07, 0x89, 0x98, 0x11, 0x1b, 0x86, 0xe7, 0x73, 0x7a, 0xd8, 0x7d, 0x78,
|
||||
0x61, 0x53, 0xe9, 0x79, 0xf5, 0x36, 0x8d, 0x44, 0x92, 0x84, 0xf9, 0x13, 0x50, 0x58, 0x3b,
|
||||
0xa4, 0x6a, 0x36, 0x65, 0x49, 0x8e, 0x3c, 0x0e, 0xf1, 0x6f, 0xd2, 0x84, 0xc4, 0x7e, 0x8e,
|
||||
0x3f, 0x39, 0xae, 0x7c, 0x84, 0xf1, 0x63, 0x37, 0x8e, 0x3c, 0xcc, 0x3e, 0x44, 0x81, 0x45,
|
||||
0xf1, 0x4b, 0xb9, 0xed, 0x6b, 0x36, 0x5d, 0xbb, 0x20, 0x60, 0x1a, 0x0f, 0xa3, 0xaa, 0x55,
|
||||
0x77, 0x3a, 0xa9, 0xae, 0x37, 0x4d, 0xba, 0xb8, 0x86, 0x6b, 0xbc, 0x08, 0x50, 0xf6, 0xcc,
|
||||
0xa4, 0xbd, 0x1d, 0x40, 0x72, 0xa5, 0x86, 0xfa, 0xe2, 0x10, 0xae, 0x3d, 0x58, 0x4b, 0x97,
|
||||
0xf3, 0x43, 0x74, 0xa9, 0x9e, 0xeb, 0x21, 0xb7, 0x01, 0xa4, 0x86, 0x93, 0x97, 0xee, 0x2f,
|
||||
0x4f, 0x3b, 0x86, 0xa1, 0x41, 0x6f, 0x41, 0x26, 0x90, 0x78, 0x5c, 0x7f, 0x30, 0x38, 0x4b,
|
||||
0x3f, 0xaa, 0xec, 0xed, 0x5c, 0x6f, 0x0e, 0xad, 0x43, 0x87, 0xfd, 0x93, 0x35, 0xe6, 0x01,
|
||||
0xef, 0x41, 0x26, 0x90, 0x99, 0x9e, 0xfb, 0x19, 0x5b, 0xad, 0xd2, 0x91, 0x8a, 0xe0, 0x46,
|
||||
0xaf, 0x65, 0xfa, 0x4f, 0x84, 0xc1, 0xa1, 0x2d, 0xcf, 0x45, 0x8b, 0xd3, 0x85, 0x50, 0x55,
|
||||
0x7c, 0xf9, 0x67, 0x88, 0xd4, 0x4e, 0xe9, 0xd7, 0x6b, 0x61, 0x54, 0xa1, 0xa4, 0xa6, 0xa2,
|
||||
0xc2, 0xbf, 0x30, 0x9c, 0x40, 0x9f, 0x5f, 0xd7, 0x69, 0x2b, 0x24, 0x82, 0x5e, 0xd9, 0xd6,
|
||||
0xa7, 0x12, 0x54, 0x1a, 0xf7, 0x55, 0x9f, 0x76, 0x50, 0xa9, 0x95, 0x84, 0xe6, 0x6b, 0x6d,
|
||||
0xb5, 0x96, 0x54, 0xd6, 0xcd, 0xb3, 0xa1, 0x9b, 0x46, 0xa7, 0x94, 0x4d, 0xc4, 0x94, 0xb4,
|
||||
0x98, 0xe3, 0xe1, 0xe2, 0x34, 0xd5, 0x33, 0x16, 0x07, 0x54, 0xcd, 0xb7, 0x77, 0x53, 0xdb,
|
||||
0x4f, 0x4d, 0x46, 0x9d, 0xe9, 0xd4, 0x9c, 0x8a, 0x36, 0xb6, 0xb8, 0x38, 0x26, 0x6c, 0x0e,
|
||||
0xff, 0x9c, 0x1b, 0x43, 0x8b, 0x80, 0xcc, 0xb9, 0x3d, 0xda, 0xc7, 0xf1, 0x8a, 0xf2, 0x6d,
|
||||
0xb8, 0xd7, 0x74, 0x2f, 0x7e, 0x1e, 0xb7, 0xd3, 0x4a, 0xb4, 0xac, 0xfc, 0x79, 0x48, 0x6c,
|
||||
0xbc, 0x96, 0xb6, 0x94, 0x46, 0x57, 0x2d, 0xb0, 0xa3, 0xfc, 0x1e, 0xb9, 0x52, 0x60, 0x85,
|
||||
0x2d, 0x41, 0xd0, 0x43, 0x01, 0x1e, 0x1c, 0xd5, 0x7d, 0xfc, 0xf3, 0x96, 0x0d, 0xc7, 0xcb,
|
||||
0x2a, 0x29, 0x9a, 0x93, 0xdd, 0x88, 0x2d, 0x37, 0x5d, 0xaa, 0xfb, 0x49, 0x68, 0xa0, 0x9c,
|
||||
0x50, 0x86, 0x7f, 0x68, 0x56, 0x57, 0xf9, 0x79, 0x18, 0x39, 0xd4, 0xe0, 0x01, 0x84, 0x33,
|
||||
0x61, 0xca, 0xa5, 0xd2, 0xd6, 0xe4, 0xc9, 0x8a, 0x4a, 0x23, 0x44, 0x4e, 0xbc, 0xf0, 0xdc,
|
||||
0x24, 0xa1, 0xa0, 0xc4, 0xe2, 0x07, 0x3c, 0x10, 0xc4, 0xb5, 0x25, 0x4b, 0x65, 0x63, 0xf4,
|
||||
0x80, 0xe7, 0xcf, 0x61, 0xb1, 0x71, 0x82, 0x21, 0x87, 0x2c, 0xf5, 0x91, 0x00, 0x32, 0x0c,
|
||||
0xec, 0xa9, 0xb5, 0x9a, 0x74, 0x85, 0xe3, 0x36, 0x8f, 0x76, 0x4f, 0x9c, 0x6d, 0xce, 0xbc,
|
||||
0xad, 0x0a, 0x4b, 0xed, 0x76, 0x04, 0xcb, 0xc3, 0xb9, 0x33, 0x9e, 0x01, 0x93, 0x96, 0x69,
|
||||
0x7d, 0xc5, 0xa2, 0x45, 0x79, 0x9b, 0x04, 0x5c, 0x84, 0x09, 0xed, 0x88, 0x43, 0xc7, 0xab,
|
||||
0x93, 0x14, 0x26, 0xa1, 0x40, 0xb5, 0xce, 0x4e, 0xbf, 0x2a, 0x42, 0x85, 0x3e, 0x2c, 0x3b,
|
||||
0x54, 0xe8, 0x12, 0x1f, 0x0e, 0x97, 0x59, 0xb2, 0x27, 0x89, 0xfa, 0xf2, 0xdf, 0x8e, 0x68,
|
||||
0x59, 0xdc, 0x06, 0xbc, 0xb6, 0x85, 0x0d, 0x06, 0x22, 0xec, 0xb1, 0xcb, 0xe5, 0x04, 0xe6,
|
||||
0x3d, 0xb3, 0xb0, 0x41, 0x73, 0x08, 0x3f, 0x3c, 0x58, 0x86, 0x63, 0xeb, 0x50, 0xee, 0x1d,
|
||||
0x2c, 0x37, 0x74, 0xa9, 0xd3, 0x18, 0xa3, 0x47, 0x6e, 0x93, 0x54, 0xad, 0x0a, 0x5d, 0xb8,
|
||||
0x2a, 0x55, 0x5d, 0x78, 0xf6, 0xee, 0xbe, 0x8e, 0x3c, 0x76, 0x69, 0xb9, 0x40, 0xc2, 0x34,
|
||||
0xec, 0x2a, 0xb9, 0xed, 0x7e, 0x20, 0xe4, 0x8d, 0x00, 0x38, 0xc7, 0xe6, 0x8f, 0x44, 0xa8,
|
||||
0x86, 0xce, 0xeb, 0x2a, 0xe9, 0x90, 0xf1, 0x4c, 0xdf, 0x32, 0xfb, 0x73, 0x1b, 0x6d, 0x92,
|
||||
0x1e, 0x95, 0xfe, 0xb4, 0xdb, 0x65, 0xdf, 0x4d, 0x23, 0x54, 0x89, 0x48, 0xbf, 0x4a, 0x2e,
|
||||
0x70, 0xd6, 0xd7, 0x62, 0xb4, 0x33, 0x29, 0xb1, 0x3a, 0x33, 0x4c, 0x23, 0x6d, 0xa6, 0x76,
|
||||
0xa5, 0x21, 0x63, 0x48, 0xe6, 0x90, 0x5d, 0xed, 0x90, 0x95, 0x0b, 0x7a, 0x84, 0xbe, 0xb8,
|
||||
0x0d, 0x5e, 0x63, 0x0c, 0x62, 0x26, 0x4c, 0x14, 0x5a, 0xb3, 0xac, 0x23, 0xa4, 0x74, 0xa7,
|
||||
0x6f, 0x33, 0x30, 0x05, 0x60, 0x01, 0x42, 0xa0, 0x28, 0xb7, 0xee, 0x19, 0x38, 0xf1, 0x64,
|
||||
0x80, 0x82, 0x43, 0xe1, 0x41, 0x27, 0x1f, 0x1f, 0x90, 0x54, 0x7a, 0xd5, 0x23, 0x2e, 0xd1,
|
||||
0x3d, 0xcb, 0x28, 0xba, 0x58, 0x7f, 0xdc, 0x7c, 0x91, 0x24, 0xe9, 0x28, 0x51, 0x83, 0x6e,
|
||||
0xc5, 0x56, 0x21, 0x42, 0xed, 0xa0, 0x56, 0x22, 0xa1, 0x40, 0x80, 0x6b, 0xa8, 0xf7, 0x94,
|
||||
0xca, 0x13, 0x6b, 0x0c, 0x39, 0xd9, 0xfd, 0xe9, 0xf3, 0x6f, 0xa6, 0x9e, 0xfc, 0x70, 0x8a,
|
||||
0xb3, 0xbc, 0x59, 0x3c, 0x1e, 0x1d, 0x6c, 0xf9, 0x7c, 0xaf, 0xf9, 0x88, 0x71, 0x95, 0xeb,
|
||||
0x57, 0x00, 0xbd, 0x9f, 0x8c, 0x4f, 0xe1, 0x24, 0x83, 0xc5, 0x22, 0xea, 0xfd, 0xd3, 0x0c,
|
||||
0xe2, 0x17, 0x18, 0x7c, 0x6a, 0x4c, 0xde, 0x77, 0xb4, 0x53, 0x9b, 0x4c, 0x81, 0xcd, 0x23,
|
||||
0x60, 0xaa, 0x0e, 0x25, 0x73, 0x9c, 0x02, 0x79, 0x32, 0x30, 0xdf, 0x74, 0xdf, 0x75, 0x19,
|
||||
0xf4, 0xa5, 0x14, 0x5c, 0xf7, 0x7a, 0xa8, 0xa5, 0x91, 0x84, 0x7c, 0x60, 0x03, 0x06, 0x3b,
|
||||
0xcd, 0x50, 0xb6, 0x27, 0x9c, 0xfe, 0xb1, 0xdd, 0xcc, 0xd3, 0xb0, 0x59, 0x24, 0xb2, 0xca,
|
||||
0xe2, 0x1c, 0x81, 0x22, 0x9d, 0x07, 0x8f, 0x8e, 0xb9, 0xbe, 0x4e, 0xfa, 0xfc, 0x39, 0x65,
|
||||
0xba, 0xbf, 0x9d, 0x12, 0x37, 0x5e, 0x97, 0x7e, 0xf3, 0x89, 0xf5, 0x5d, 0xf5, 0xe3, 0x09,
|
||||
0x8c, 0x62, 0xb5, 0x20, 0x9d, 0x0c, 0x53, 0x8a, 0x68, 0x1b, 0xd2, 0x8f, 0x75, 0x17, 0x5d,
|
||||
0xd4, 0xe5, 0xda, 0x75, 0x62, 0x19, 0x14, 0x6a, 0x26, 0x2d, 0xeb, 0xf8, 0xaf, 0x37, 0xf0,
|
||||
0x6c, 0xa4, 0x55, 0xb1, 0xbc, 0xe2, 0x33, 0xc0, 0x9a, 0xca, 0xb0, 0x11, 0x49, 0x4f, 0x68,
|
||||
0x9b, 0x3b, 0x6b, 0x3c, 0xcc, 0x13, 0xf6, 0xc7, 0x85, 0x61, 0x68, 0x42, 0xae, 0xbb, 0xdd,
|
||||
0xcd, 0x45, 0x16, 0x29, 0x1d, 0xea, 0xdb, 0xc8, 0x03, 0x94, 0x3c, 0xee, 0x4f, 0x82, 0x11,
|
||||
0xc3, 0xec, 0x28, 0xbd, 0x97, 0x05, 0x99, 0xde, 0xd7, 0xbb, 0x5e, 0x22, 0x1f, 0xd4, 0xeb,
|
||||
0x64, 0xd9, 0x92, 0xd9, 0x85, 0xb7, 0x6a, 0x05, 0x6a, 0xe4, 0x24, 0x41, 0xf1, 0xcd, 0xf0,
|
||||
0xd8, 0x3f, 0xf8, 0x9e, 0x0e, 0xcd, 0x0b, 0x7a, 0x70, 0x6b, 0x5a, 0x75, 0x0a, 0x6a, 0x33,
|
||||
0x88, 0xec, 0x17, 0x75, 0x08, 0x70, 0x10, 0x2f, 0x24, 0xcf, 0xc4, 0xe9, 0x42, 0x00, 0x61,
|
||||
0x94, 0xca, 0x1f, 0x3a, 0x76, 0x06, 0xfa, 0xd2, 0x48, 0x81, 0xf0, 0x77, 0x60, 0x03, 0x45,
|
||||
0xd9, 0x61, 0xf4, 0xa4, 0x6f, 0x3d, 0xd9, 0x30, 0xc3, 0x04, 0x6b, 0x54, 0x2a, 0xb7, 0xec,
|
||||
0x3b, 0xf4, 0x4b, 0xf5, 0x68, 0x52, 0x26, 0xce, 0xff, 0x5d, 0x19, 0x91, 0xa0, 0xa3, 0xa5,
|
||||
0xa9, 0xb1, 0xe0, 0x23, 0xc4, 0x0a, 0x77, 0x4d, 0xf9, 0x51, 0x20, 0xa3, 0xa5, 0xa9, 0xb1,
|
||||
0xc1, 0x00, 0x82, 0x86, 0x8e, 0x7f, 0x5d, 0x19, 0x91, 0xa0, 0xa3, 0xc4, 0xeb, 0x54, 0x0b,
|
||||
0x75, 0x68, 0x52, 0x07, 0x8c, 0x9a, 0x97, 0x8d, 0x79, 0x70, 0x62, 0x46, 0xef, 0x5c, 0x1b,
|
||||
0x95, 0x89, 0x71, 0x41, 0xe1, 0x21, 0xa1, 0xa1, 0xa1, 0xc0, 0x02, 0x67, 0x4c, 0x1a, 0xb6,
|
||||
0xcf, 0xfd, 0x78, 0x53, 0x24, 0xab, 0xb5, 0xc9, 0xf1, 0x60, 0x23, 0xa5, 0xc8, 0x12, 0x87,
|
||||
0x6d, 0x58, 0x13, 0x85, 0x88, 0x92, 0x87, 0x6d, 0x58, 0x32, 0xc7, 0x0c, 0x9a, 0x97, 0xac,
|
||||
0xda, 0x36, 0xee, 0x5e, 0x3e, 0xdf, 0x1d, 0xb8, 0xf2, 0x66, 0x2f, 0xbd, 0xf8, 0x72, 0x47,
|
||||
0xed, 0x58, 0x13, 0x85, 0x88, 0x92, 0x87, 0x8c, 0x7b, 0x55, 0x09, 0x90, 0xa2, 0xc6, 0xef,
|
||||
0x3d, 0xf8, 0x53, 0x24, 0xab, 0xd4, 0x2a, 0xb7, 0xec, 0x5a, 0x36, 0xee, 0x5e, 0x3e, 0xdf,
|
||||
0x3c, 0xfa, 0x76, 0x4f, 0xfd, 0x59, 0x30, 0xe2, 0x46, 0xef, 0x3d, 0xf8, 0x53, 0x05, 0x69,
|
||||
0x31, 0xc1, 0x00, 0x82, 0x86, 0x8e, 0x7f, 0x5d, 0x19, 0xb0, 0xe2, 0x27, 0xcc, 0xfb, 0x74,
|
||||
0x4b, 0x14, 0x8b, 0x94, 0x8b, 0x75, 0x68, 0x33, 0xc5, 0x08, 0x92, 0x87, 0x8c, 0x9a, 0xb6,
|
||||
0xcf, 0x1c, 0xba, 0xd7, 0x0d, 0x98, 0xb2, 0xe6, 0x2f, 0xdc, 0x1b, 0x95, 0x89, 0x71, 0x60,
|
||||
0x23, 0xc4, 0x0a, 0x96, 0x8f, 0x9c, 0xba, 0xf6, 0x6e, 0x3f, 0xfc, 0x5b, 0x15, 0xa8, 0xd2,
|
||||
0x26, 0xaf, 0xbd, 0xf8, 0x72, 0x66, 0x2f, 0xdc, 0x1b, 0xb4, 0xcb, 0x14, 0x8b, 0x94, 0xaa,
|
||||
0xb7, 0xcd, 0xf9, 0x51, 0x01, 0x80, 0x82, 0x86, 0x6f, 0x3d, 0xd9, 0x30, 0xe2, 0x27, 0xcc,
|
||||
0xfb, 0x74, 0x4b, 0x14, 0xaa, 0xb7, 0xcd, 0xf9, 0x70, 0x43, 0x04, 0x6b, 0x35, 0xc9, 0xf1,
|
||||
0x60, 0x23, 0xa5, 0xc8, 0xf3, 0x45, 0x08, 0x92, 0x87, 0x6d, 0x58, 0x32, 0xe6, 0x2f, 0xbd,
|
||||
0xf8, 0x72, 0x66, 0x4e, 0x1e, 0xbe, 0xfe, 0x7e, 0x7e, 0x7e, 0x5f, 0x1d, 0x99, 0x91, 0xa0,
|
||||
0xa3, 0xc4, 0x0a, 0x77, 0x4d, 0x18, 0x93, 0xa4, 0xab, 0xd4, 0x0b, 0x75, 0x49, 0x10, 0xa2,
|
||||
0xc6, 0xef, 0x3d, 0xf8, 0x53, 0x24, 0xab, 0xb5, 0xe8, 0x33, 0xe4, 0x4a, 0x16, 0xae, 0xde,
|
||||
0x1f, 0xbc, 0xdb, 0x15, 0xa8, 0xb3, 0xc5, 0x08, 0x73, 0x45, 0xe9, 0x31, 0xc1, 0xe1, 0x21,
|
||||
0xa1, 0xa1, 0xa1, 0xc0, 0x02, 0x86, 0x6f, 0x5c, 0x3a, 0xd7, 0x0d, 0x98, 0x93, 0xa4, 0xca,
|
||||
0x16, 0xae, 0xde, 0x1f, 0x9d, 0x99, 0xb0, 0xe2, 0x46, 0xef, 0x3d, 0xf8, 0x72, 0x47, 0x0c,
|
||||
0x9a, 0xb6, 0xcf, 0xfd, 0x59, 0x11, 0xa0, 0xa3, 0xa5, 0xc8, 0xf3, 0x45, 0x08, 0x92, 0x87,
|
||||
0x6d, 0x39, 0xf0, 0x43, 0x04, 0x8a, 0x96, 0xae, 0xde, 0x3e, 0xdf, 0x1d, 0x99, 0x91, 0xa0,
|
||||
0xc2, 0x06, 0x6f, 0x3d, 0xf8, 0x72, 0x47, 0x0c, 0x9a, 0x97, 0x8d, 0x98, 0x93, 0x85, 0x88,
|
||||
0x73, 0x45, 0xe9, 0x31, 0xe0, 0x23, 0xa5, 0xa9, 0xd0, 0x03, 0x84, 0x8a, 0x96, 0xae, 0xde,
|
||||
0x1f, 0xbc, 0xdb, 0x15, 0xa8, 0xd2, 0x26, 0xce, 0xff, 0x5d, 0x19, 0x91, 0x81, 0x80, 0x82,
|
||||
0x67, 0x2d, 0xd8, 0x13, 0xa4, 0xab, 0xd4, 0x0b, 0x94, 0xaa, 0xb7, 0xcd, 0xf9, 0x51, 0x20,
|
||||
0xa3, 0xa5, 0xc8, 0xf3, 0x45, 0xe9, 0x50, 0x22, 0xc6, 0xef, 0x5c, 0x3a, 0xd7, 0x0d, 0x98,
|
||||
0x93, 0x85, 0x88, 0x73, 0x64, 0x4a, 0xf7, 0x4d, 0xf9, 0x51, 0x20, 0xa3, 0xc4, 0x0a, 0x96,
|
||||
0xae, 0xde, 0x3e, 0xfe, 0x7e, 0x7e, 0x7e, 0x5f, 0x3c, 0xfa, 0x76, 0x4f, 0xfd, 0x78, 0x72,
|
||||
0x66, 0x2f, 0xbd, 0xd9, 0x30, 0xc3, 0xe5, 0x48, 0x12, 0x87, 0x8c, 0x7b, 0x55, 0x28, 0xd2,
|
||||
0x07, 0x8c, 0x9a, 0x97, 0xac, 0xda, 0x17, 0x8d, 0x79, 0x51, 0x20, 0xa3, 0xc4, 0xeb, 0x54,
|
||||
0x0b, 0x94, 0x8b, 0x94, 0xaa, 0xd6, 0x2e, 0xbf, 0xfc, 0x5b, 0x15, 0xa8, 0xd2, 0x26, 0xaf,
|
||||
0xdc, 0x1b, 0xb4, 0xea, 0x37, 0xec, 0x3b, 0xf4, 0x6a, 0x37, 0xcd, 0x18, 0x93, 0x85, 0x69,
|
||||
0x31, 0xc1, 0xe1, 0x40, 0xe3, 0x25, 0xc8, 0x12, 0x87, 0x8c, 0x9a, 0xb6, 0xcf, 0xfd, 0x59,
|
||||
0x11, 0xa0, 0xc2, 0x06, 0x8e, 0x7f, 0x5d, 0x38, 0xf2, 0x47, 0x0c, 0x7b, 0x74, 0x6a, 0x37,
|
||||
0xec, 0x5a, 0x36, 0xee, 0x3f, 0xfc, 0x7a, 0x76, 0x4f, 0x1c, 0x9b, 0x95, 0x89, 0x71, 0x41,
|
||||
0x00, 0x63, 0x44, 0xeb, 0x54, 0x2a, 0xd6, 0x0f, 0x9c, 0xba, 0xd7, 0x0d, 0x98, 0x93, 0x85,
|
||||
0x69, 0x31, 0xc1, 0x00, 0x82, 0x86, 0x8e, 0x9e, 0xbe, 0xdf, 0x3c, 0xfa, 0x57, 0x2c, 0xda,
|
||||
0x36, 0xee, 0x3f, 0xfc, 0x5b, 0x15, 0x89, 0x71, 0x41, 0x00, 0x82, 0x86, 0x8e, 0x7f, 0x5d,
|
||||
0x38, 0xf2, 0x47, 0xed, 0x58, 0x13, 0xa4, 0xca, 0xf7, 0x4d, 0xf9, 0x51, 0x01, 0x80, 0x63,
|
||||
0x44, 0xeb, 0x54, 0x2a, 0xd6, 0x2e, 0xbf, 0xdd, 0x19, 0x91, 0xa0, 0xa3, 0xa5, 0xa9, 0xb1,
|
||||
0xe0, 0x42, 0x06, 0x8e, 0x7f, 0x5d, 0x19, 0x91, 0xa0, 0xa3, 0xc4, 0x0a, 0x96, 0x8f, 0x7d,
|
||||
0x78, 0x72, 0x47, 0x0c, 0x7b, 0x74, 0x6a, 0x56, 0x2e, 0xde, 0x1f, 0xbc, 0xfa, 0x57, 0x0d,
|
||||
0x79, 0x51, 0x01, 0x61, 0x21, 0xa1, 0xc0, 0xe3, 0x25, 0xa9, 0xb1, 0xc1, 0xe1, 0x40, 0x02,
|
||||
0x67, 0x4c, 0x1a, 0x97, 0x8d, 0x98, 0x93, 0xa4, 0xab, 0xd4, 0x2a, 0xd6, 0x0f, 0x9c, 0x9b,
|
||||
0xb4, 0xcb, 0x14, 0xaa, 0xb7, 0xcd, 0xf9, 0x51, 0x20, 0xa3, 0xc4, 0xeb, 0x35, 0xc9, 0xf1,
|
||||
0x60, 0x42, 0x06, 0x8e, 0x7f, 0x7c, 0x7a, 0x76, 0x6e, 0x3f, 0xfc, 0x7a, 0x76, 0x6e, 0x5e,
|
||||
0x3e, 0xfe, 0x7e, 0x5f, 0x3c, 0xdb, 0x15, 0x89, 0x71, 0x41, 0xe1, 0x21, 0xc0, 0xe3, 0x44,
|
||||
0xeb, 0x54, 0x2a, 0xb7, 0xcd, 0xf9, 0x70, 0x62, 0x27, 0xad, 0xd8, 0x32, 0xc7, 0x0c, 0x7b,
|
||||
0x74, 0x4b, 0x14, 0xaa, 0xb7, 0xec, 0x3b, 0xd5, 0x28, 0xd2, 0x07, 0x6d, 0x39, 0xd1, 0x20,
|
||||
0xc2, 0xe7, 0x4c, 0x1a, 0x97, 0x8d, 0x98, 0xb2, 0xc7, 0x0c, 0x59, 0x28, 0xf3, 0x9b };
|
||||
|
||||
// clang-format off
|
||||
const uint8_t firmware_data[FIRMWARE_LENGTH] PROGMEM = {
|
||||
0x01, 0x04, 0x8E, 0x96, 0x6E, 0x77, 0x3E, 0xFE, 0x7E, 0x5F, 0x1D, 0xB8, 0xF2, 0x66, 0x4E, 0xFF,
|
||||
0x5D, 0x19, 0xB0, 0xC2, 0x04, 0x69, 0x54, 0x2A, 0xD6, 0x2E, 0xBF, 0xDD, 0x19, 0xB0, 0xC3, 0xE5,
|
||||
0x29, 0xB1, 0xE0, 0x23, 0xA5, 0xA9, 0xB1, 0xC1, 0x00, 0x82, 0x67, 0x4C, 0x1A, 0x97, 0x8D, 0x79,
|
||||
0x51, 0x20, 0xC7, 0x06, 0x8E, 0x7C, 0x7C, 0x7A, 0x76, 0x4F, 0xFD, 0x59, 0x30, 0xE2, 0x46, 0x0E,
|
||||
0x9E, 0xBE, 0xDF, 0x1D, 0x99, 0x91, 0xA0, 0xA5, 0xA1, 0xA9, 0xD0, 0x22, 0xC6, 0xEF, 0x5C, 0x1B,
|
||||
0x95, 0x89, 0x90, 0xA2, 0xA7, 0xCC, 0xFB, 0x55, 0x28, 0xB3, 0xE4, 0x4A, 0xF7, 0x6C, 0x3B, 0xF4,
|
||||
0x6A, 0x56, 0x2E, 0xDE, 0x1F, 0x9D, 0xB8, 0xD3, 0x05, 0x88, 0x92, 0xA6, 0xCE, 0x1E, 0xBE, 0xDF,
|
||||
0x1D, 0x99, 0xB0, 0xE2, 0x46, 0xEF, 0x5C, 0x07, 0x11, 0x5D, 0x98, 0x0B, 0x9D, 0x94, 0x97, 0xEE,
|
||||
0x4E, 0x45, 0x33, 0x6B, 0x44, 0xC7, 0x29, 0x56, 0x27, 0x30, 0xC6, 0xA7, 0xD5, 0xF2, 0x56, 0xDF,
|
||||
0xB4, 0x38, 0x62, 0xCB, 0xA0, 0xB6, 0xE3, 0x0F, 0x84, 0x06, 0x24, 0x05, 0x65, 0x6F, 0x76, 0x89,
|
||||
0xB5, 0x77, 0x41, 0x27, 0x82, 0x66, 0x65, 0x82, 0xCC, 0xD5, 0xE6, 0x20, 0xD5, 0x27, 0x17, 0xC5,
|
||||
0xF8, 0x03, 0x23, 0x7C, 0x5F, 0x64, 0xA5, 0x1D, 0xC1, 0xD6, 0x36, 0xCB, 0x4C, 0xD4, 0xDB, 0x66,
|
||||
0xD7, 0x8B, 0xB1, 0x99, 0x7E, 0x6F, 0x4C, 0x36, 0x40, 0x06, 0xD6, 0xEB, 0xD7, 0xA2, 0xE4, 0xF4,
|
||||
0x95, 0x51, 0x5A, 0x54, 0x96, 0xD5, 0x53, 0x44, 0xD7, 0x8C, 0xE0, 0xB9, 0x40, 0x68, 0xD2, 0x18,
|
||||
0xE9, 0xDD, 0x9A, 0x23, 0x92, 0x48, 0xEE, 0x7F, 0x43, 0xAF, 0xEA, 0x77, 0x38, 0x84, 0x8C, 0x0A,
|
||||
0x72, 0xAF, 0x69, 0xF8, 0xDD, 0xF1, 0x24, 0x83, 0xA3, 0xF8, 0x4A, 0xBF, 0xF5, 0x94, 0x13, 0xDB,
|
||||
0xBB, 0xD8, 0xB4, 0xB3, 0xA0, 0xFB, 0x45, 0x50, 0x60, 0x30, 0x59, 0x12, 0x31, 0x71, 0xA2, 0xD3,
|
||||
0x13, 0xE7, 0xFA, 0xE7, 0xCE, 0x0F, 0x63, 0x15, 0x0B, 0x6B, 0x94, 0xBB, 0x37, 0x83, 0x26, 0x05,
|
||||
0x9D, 0xFB, 0x46, 0x92, 0xFC, 0x0A, 0x15, 0xD1, 0x0D, 0x73, 0x92, 0xD6, 0x8C, 0x1B, 0x8C, 0xB8,
|
||||
0x55, 0x8A, 0xCE, 0xBD, 0xFE, 0x8E, 0xFC, 0xED, 0x09, 0x12, 0x83, 0x91, 0x82, 0x51, 0x31, 0x23,
|
||||
0xFB, 0xB4, 0x0C, 0x76, 0xAD, 0x7C, 0xD9, 0xB4, 0x4B, 0xB2, 0x67, 0x14, 0x09, 0x9C, 0x7F, 0x0C,
|
||||
0x18, 0xBA, 0x3B, 0xD6, 0x8E, 0x14, 0x2A, 0xE4, 0x1B, 0x52, 0x9F, 0x2B, 0x7D, 0xE1, 0xFB, 0x6A,
|
||||
0x33, 0x02, 0xFA, 0xAC, 0x5A, 0xF2, 0x3E, 0x88, 0x7E, 0xAE, 0xD1, 0xF3, 0x78, 0xE8, 0x05, 0xD1,
|
||||
0xE3, 0xDC, 0x21, 0xF6, 0xE1, 0x9A, 0xBD, 0x17, 0x0E, 0xD9, 0x46, 0x9B, 0x88, 0x03, 0xEA, 0xF6,
|
||||
0x66, 0xBE, 0x0E, 0x1B, 0x50, 0x49, 0x96, 0x40, 0x97, 0xF1, 0xF1, 0xE4, 0x80, 0xA6, 0x6E, 0xE8,
|
||||
0x77, 0x34, 0xBF, 0x29, 0x40, 0x44, 0xC2, 0xFF, 0x4E, 0x98, 0xD3, 0x9C, 0xA3, 0x32, 0x2B, 0x76,
|
||||
0x51, 0x04, 0x09, 0xE7, 0xA9, 0xD1, 0xA6, 0x32, 0xB1, 0x23, 0x53, 0xE2, 0x47, 0xAB, 0xD6, 0xF5,
|
||||
0x69, 0x5C, 0x3E, 0x5F, 0xFA, 0xAE, 0x45, 0x20, 0xE5, 0xD2, 0x44, 0xFF, 0x39, 0x32, 0x6D, 0xFD,
|
||||
0x27, 0x57, 0x5C, 0xFD, 0xF0, 0xDE, 0xC1, 0xB5, 0x99, 0xE5, 0xF5, 0x1C, 0x77, 0x01, 0x75, 0xC5,
|
||||
0x6D, 0x58, 0x92, 0xF2, 0xB2, 0x47, 0x00, 0x01, 0x26, 0x96, 0x7A, 0x30, 0xFF, 0xB7, 0xF0, 0xEF,
|
||||
0x77, 0xC1, 0x8A, 0x5D, 0xDC, 0xC0, 0xD1, 0x29, 0x30, 0x1E, 0x77, 0x38, 0x7A, 0x94, 0xF1, 0xB8,
|
||||
0x7A, 0x7E, 0xEF, 0xA4, 0xD1, 0xAC, 0x31, 0x4A, 0xF2, 0x5D, 0x64, 0x3D, 0xB2, 0xE2, 0xF0, 0x08,
|
||||
0x99, 0xFC, 0x70, 0xEE, 0x24, 0xA7, 0x7E, 0xEE, 0x1E, 0x20, 0x69, 0x7D, 0x44, 0xBF, 0x87, 0x42,
|
||||
0xDF, 0x88, 0x3B, 0x0C, 0xDA, 0x42, 0xC9, 0x04, 0xF9, 0x45, 0x50, 0xFC, 0x83, 0x8F, 0x11, 0x6A,
|
||||
0x72, 0xBC, 0x99, 0x95, 0xF0, 0xAC, 0x3D, 0xA7, 0x3B, 0xCD, 0x1C, 0xE2, 0x88, 0x79, 0x37, 0x11,
|
||||
0x5F, 0x39, 0x89, 0x95, 0x0A, 0x16, 0x84, 0x7A, 0xF6, 0x8A, 0xA4, 0x28, 0xE4, 0xED, 0x83, 0x80,
|
||||
0x3B, 0xB1, 0x23, 0xA5, 0x03, 0x10, 0xF4, 0x66, 0xEA, 0xBB, 0x0C, 0x0F, 0xC5, 0xEC, 0x6C, 0x69,
|
||||
0xC5, 0xD3, 0x24, 0xAB, 0xD4, 0x2A, 0xB7, 0x99, 0x88, 0x76, 0x08, 0xA0, 0xA8, 0x95, 0x7C, 0xD8,
|
||||
0x38, 0x6D, 0xCD, 0x59, 0x02, 0x51, 0x4B, 0xF1, 0xB5, 0x2B, 0x50, 0xE3, 0xB6, 0xBD, 0xD0, 0x72,
|
||||
0xCF, 0x9E, 0xFD, 0x6E, 0xBB, 0x44, 0xC8, 0x24, 0x8A, 0x77, 0x18, 0x8A, 0x13, 0x06, 0xEF, 0x97,
|
||||
0x7D, 0xFA, 0x81, 0xF0, 0x31, 0xE6, 0xFA, 0x77, 0xED, 0x31, 0x06, 0x31, 0x5B, 0x54, 0x8A, 0x9F,
|
||||
0x30, 0x68, 0xDB, 0xE2, 0x40, 0xF8, 0x4E, 0x73, 0xFA, 0xAB, 0x74, 0x8B, 0x10, 0x58, 0x13, 0xDC,
|
||||
0xD2, 0xE6, 0x78, 0xD1, 0x32, 0x2E, 0x8A, 0x9F, 0x2C, 0x58, 0x06, 0x48, 0x27, 0xC5, 0xA9, 0x5E,
|
||||
0x81, 0x47, 0x89, 0x46, 0x21, 0x91, 0x03, 0x70, 0xA4, 0x3E, 0x88, 0x9C, 0xDA, 0x33, 0x0A, 0xCE,
|
||||
0xBC, 0x8B, 0x8E, 0xCF, 0x9F, 0xD3, 0x71, 0x80, 0x43, 0xCF, 0x6B, 0xA9, 0x51, 0x83, 0x76, 0x30,
|
||||
0x82, 0xC5, 0x6A, 0x85, 0x39, 0x11, 0x50, 0x1A, 0x82, 0xDC, 0x1E, 0x1C, 0xD5, 0x7D, 0xA9, 0x71,
|
||||
0x99, 0x33, 0x47, 0x19, 0x97, 0xB3, 0x5A, 0xB1, 0xDF, 0xED, 0xA4, 0xF2, 0xE6, 0x26, 0x84, 0xA2,
|
||||
0x28, 0x9A, 0x9E, 0xDF, 0xA6, 0x6A, 0xF4, 0xD6, 0xFC, 0x2E, 0x5B, 0x9D, 0x1A, 0x2A, 0x27, 0x68,
|
||||
0xFB, 0xC1, 0x83, 0x21, 0x4B, 0x90, 0xE0, 0x36, 0xDD, 0x5B, 0x31, 0x42, 0x55, 0xA0, 0x13, 0xF7,
|
||||
0xD0, 0x89, 0x53, 0x71, 0x99, 0x57, 0x09, 0x29, 0xC5, 0xF3, 0x21, 0xF8, 0x37, 0x2F, 0x40, 0xF3,
|
||||
0xD4, 0xAF, 0x16, 0x08, 0x36, 0x02, 0xFC, 0x77, 0xC5, 0x8B, 0x04, 0x90, 0x56, 0xB9, 0xC9, 0x67,
|
||||
0x9A, 0x99, 0xE8, 0x00, 0xD3, 0x86, 0xFF, 0x97, 0x2D, 0x08, 0xE9, 0xB7, 0xB3, 0x91, 0xBC, 0xDF,
|
||||
0x45, 0xC6, 0xED, 0x0F, 0x8C, 0x4C, 0x1E, 0xE6, 0x5B, 0x6E, 0x38, 0x30, 0xE4, 0xAA, 0xE3, 0x95,
|
||||
0xDE, 0xB9, 0xE4, 0x9A, 0xF5, 0xB2, 0x55, 0x9A, 0x87, 0x9B, 0xF6, 0x6A, 0xB2, 0xF2, 0x77, 0x9A,
|
||||
0x31, 0xF4, 0x7A, 0x31, 0xD1, 0x1D, 0x04, 0xC0, 0x7C, 0x32, 0xA2, 0x9E, 0x9A, 0xF5, 0x62, 0xF8,
|
||||
0x27, 0x8D, 0xBF, 0x51, 0xFF, 0xD3, 0xDF, 0x64, 0x37, 0x3F, 0x2A, 0x6F, 0x76, 0x3A, 0x7D, 0x77,
|
||||
0x06, 0x9E, 0x77, 0x7F, 0x5E, 0xEB, 0x32, 0x51, 0xF9, 0x16, 0x66, 0x9A, 0x09, 0xF3, 0xB0, 0x08,
|
||||
0xA4, 0x70, 0x96, 0x46, 0x30, 0xFF, 0xDA, 0x4F, 0xE9, 0x1B, 0xED, 0x8D, 0xF8, 0x74, 0x1F, 0x31,
|
||||
0x92, 0xB3, 0x73, 0x17, 0x36, 0xDB, 0x91, 0x30, 0xD6, 0x88, 0x55, 0x6B, 0x34, 0x77, 0x87, 0x7A,
|
||||
0xE7, 0xEE, 0x06, 0xC6, 0x1C, 0x8C, 0x19, 0x0C, 0x48, 0x46, 0x23, 0x5E, 0x9C, 0x07, 0x5C, 0xBF,
|
||||
0xB4, 0x7E, 0xD6, 0x4F, 0x74, 0x9C, 0xE2, 0xC5, 0x50, 0x8B, 0xC5, 0x8B, 0x15, 0x90, 0x60, 0x62,
|
||||
0x57, 0x29, 0xD0, 0x13, 0x43, 0xA1, 0x80, 0x88, 0x91, 0x00, 0x44, 0xC7, 0x4D, 0x19, 0x86, 0xCC,
|
||||
0x2F, 0x2A, 0x75, 0x5A, 0xFC, 0xEB, 0x97, 0x2A, 0x70, 0xE3, 0x78, 0xD8, 0x91, 0xB0, 0x4F, 0x99,
|
||||
0x07, 0xA3, 0x95, 0xEA, 0x24, 0x21, 0xD5, 0xDE, 0x51, 0x20, 0x93, 0x27, 0x0A, 0x30, 0x73, 0xA8,
|
||||
0xFF, 0x8A, 0x97, 0xE9, 0xA7, 0x6A, 0x8E, 0x0D, 0xE8, 0xF0, 0xDF, 0xEC, 0xEA, 0xB4, 0x6C, 0x1D,
|
||||
0x39, 0x2A, 0x62, 0x2D, 0x3D, 0x5A, 0x8B, 0x65, 0xF8, 0x90, 0x05, 0x2E, 0x7E, 0x91, 0x2C, 0x78,
|
||||
0xEF, 0x8E, 0x7A, 0xC1, 0x2F, 0xAC, 0x78, 0xEE, 0xAF, 0x28, 0x45, 0x06, 0x4C, 0x26, 0xAF, 0x3B,
|
||||
0xA2, 0xDB, 0xA3, 0x93, 0x06, 0xB5, 0x3C, 0xA5, 0xD8, 0xEE, 0x8F, 0xAF, 0x25, 0xCC, 0x3F, 0x85,
|
||||
0x68, 0x48, 0xA9, 0x62, 0xCC, 0x97, 0x8F, 0x7F, 0x2A, 0xEA, 0xE0, 0x15, 0x0A, 0xAD, 0x62, 0x07,
|
||||
0xBD, 0x45, 0xF8, 0x41, 0xD8, 0x36, 0xCB, 0x4C, 0xDB, 0x6E, 0xE6, 0x3A, 0xE7, 0xDA, 0x15, 0xE9,
|
||||
0x29, 0x1E, 0x12, 0x10, 0xA0, 0x14, 0x2C, 0x0E, 0x3D, 0xF4, 0xBF, 0x39, 0x41, 0x92, 0x75, 0x0B,
|
||||
0x25, 0x7B, 0xA3, 0xCE, 0x39, 0x9C, 0x15, 0x64, 0xC8, 0xFA, 0x3D, 0xEF, 0x73, 0x27, 0xFE, 0x26,
|
||||
0x2E, 0xCE, 0xDA, 0x6E, 0xFD, 0x71, 0x8E, 0xDD, 0xFE, 0x76, 0xEE, 0xDC, 0x12, 0x5C, 0x02, 0xC5,
|
||||
0x3A, 0x4E, 0x4E, 0x4F, 0xBF, 0xCA, 0x40, 0x15, 0xC7, 0x6E, 0x8D, 0x41, 0xF1, 0x10, 0xE0, 0x4F,
|
||||
0x7E, 0x97, 0x7F, 0x1C, 0xAE, 0x47, 0x8E, 0x6B, 0xB1, 0x25, 0x31, 0xB0, 0x73, 0xC7, 0x1B, 0x97,
|
||||
0x79, 0xF9, 0x80, 0xD3, 0x66, 0x22, 0x30, 0x07, 0x74, 0x1E, 0xE4, 0xD0, 0x80, 0x21, 0xD6, 0xEE,
|
||||
0x6B, 0x6C, 0x4F, 0xBF, 0xF5, 0xB7, 0xD9, 0x09, 0x87, 0x2F, 0xA9, 0x14, 0xBE, 0x27, 0xD9, 0x72,
|
||||
0x50, 0x01, 0xD4, 0x13, 0x73, 0xA6, 0xA7, 0x51, 0x02, 0x75, 0x25, 0xE1, 0xB3, 0x45, 0x34, 0x7D,
|
||||
0xA8, 0x8E, 0xEB, 0xF3, 0x16, 0x49, 0xCB, 0x4F, 0x8C, 0xA1, 0xB9, 0x36, 0x85, 0x39, 0x75, 0x5D,
|
||||
0x08, 0x00, 0xAE, 0xEB, 0xF6, 0xEA, 0xD7, 0x13, 0x3A, 0x21, 0x5A, 0x5F, 0x30, 0x84, 0x52, 0x26,
|
||||
0x95, 0xC9, 0x14, 0xF2, 0x57, 0x55, 0x6B, 0xB1, 0x10, 0xC2, 0xE1, 0xBD, 0x3B, 0x51, 0xC0, 0xB7,
|
||||
0x55, 0x4C, 0x71, 0x12, 0x26, 0xC7, 0x0D, 0xF9, 0x51, 0xA4, 0x38, 0x02, 0x05, 0x7F, 0xB8, 0xF1,
|
||||
0x72, 0x4B, 0xBF, 0x71, 0x89, 0x14, 0xF3, 0x77, 0x38, 0xD9, 0x71, 0x24, 0xF3, 0x00, 0x11, 0xA1,
|
||||
0xD8, 0xD4, 0x69, 0x27, 0x08, 0x37, 0x35, 0xC9, 0x11, 0x9D, 0x90, 0x1C, 0x0E, 0xE7, 0x1C, 0xFF,
|
||||
0x2D, 0x1E, 0xE8, 0x92, 0xE1, 0x18, 0x10, 0x95, 0x7C, 0xE0, 0x80, 0xF4, 0x96, 0x43, 0x21, 0xF9,
|
||||
0x75, 0x21, 0x64, 0x38, 0xDD, 0x9F, 0x1E, 0x95, 0x16, 0xDA, 0x56, 0x1D, 0x4F, 0x9A, 0x53, 0xB2,
|
||||
0xE2, 0xE4, 0x18, 0xCB, 0x6B, 0x1A, 0x65, 0xEB, 0x56, 0xC6, 0x3B, 0xE5, 0xFE, 0xD8, 0x26, 0x3F,
|
||||
0x3A, 0x84, 0x59, 0x72, 0x66, 0xA2, 0xF3, 0x75, 0xFF, 0xFB, 0x60, 0xB3, 0x22, 0xAD, 0x3F, 0x2D,
|
||||
0x6B, 0xF9, 0xEB, 0xEA, 0x05, 0x7C, 0xD8, 0x8F, 0x6D, 0x2C, 0x98, 0x9E, 0x2B, 0x93, 0xF1, 0x5E,
|
||||
0x46, 0xF0, 0x87, 0x49, 0x29, 0x73, 0x68, 0xD7, 0x7F, 0xF9, 0xF0, 0xE5, 0x7D, 0xDB, 0x1D, 0x75,
|
||||
0x19, 0xF3, 0xC4, 0x58, 0x9B, 0x17, 0x88, 0xA8, 0x92, 0xE0, 0xBE, 0xBD, 0x8B, 0x1D, 0x8D, 0x9F,
|
||||
0x56, 0x76, 0xAD, 0xAF, 0x29, 0xE2, 0xD9, 0xD5, 0x52, 0xF6, 0xB5, 0x56, 0x35, 0x57, 0x3A, 0xC8,
|
||||
0xE1, 0x56, 0x43, 0x19, 0x94, 0xD3, 0x04, 0x9B, 0x6D, 0x35, 0xD8, 0x0B, 0x5F, 0x4D, 0x19, 0x8E,
|
||||
0xEC, 0xFA, 0x64, 0x91, 0x0A, 0x72, 0x20, 0x2B, 0xBC, 0x1A, 0x4A, 0xFE, 0x8B, 0xFD, 0xBB, 0xED,
|
||||
0x1B, 0x23, 0xEA, 0xAD, 0x72, 0x82, 0xA1, 0x29, 0x99, 0x71, 0xBD, 0xF0, 0x95, 0xC1, 0x03, 0xDD,
|
||||
0x7B, 0xC2, 0xB2, 0x3C, 0x28, 0x54, 0xD3, 0x68, 0xA4, 0x72, 0xC8, 0x66, 0x96, 0xE0, 0xD1, 0xD8,
|
||||
0x7F, 0xF8, 0xD1, 0x26, 0x2B, 0xF7, 0xAD, 0xBA, 0x55, 0xCA, 0x15, 0xB9, 0x32, 0xC3, 0xE5, 0x88,
|
||||
0x97, 0x8E, 0x5C, 0xFB, 0x92, 0x25, 0x8B, 0xBF, 0xA2, 0x45, 0x55, 0x7A, 0xA7, 0x6F, 0x8B, 0x57,
|
||||
0x5B, 0xCF, 0x0E, 0xCB, 0x1D, 0xFB, 0x20, 0x82, 0x77, 0xA8, 0x8C, 0xCC, 0x16, 0xCE, 0x1D, 0xFA,
|
||||
0xDE, 0xCC, 0x0B, 0x62, 0xFE, 0xCC, 0xE1, 0xB7, 0xF0, 0xC3, 0x81, 0x64, 0x73, 0x40, 0xA0, 0xC2,
|
||||
0x4D, 0x89, 0x11, 0x75, 0x33, 0x55, 0x33, 0x8D, 0xE8, 0x4A, 0xFD, 0xEA, 0x6E, 0x30, 0x0B, 0xD7,
|
||||
0x31, 0x2C, 0xDE, 0x47, 0xE3, 0xBF, 0xF8, 0x55, 0x42, 0xE2, 0x7F, 0x59, 0xE5, 0x17, 0xEF, 0x99,
|
||||
0x34, 0x69, 0x91, 0xB1, 0x23, 0x8E, 0x20, 0x87, 0x2D, 0xA8, 0xFE, 0xD5, 0x8A, 0xF3, 0x84, 0x3A,
|
||||
0xF0, 0x37, 0xE4, 0x09, 0x00, 0x54, 0xEE, 0x67, 0x49, 0x93, 0xE4, 0x81, 0x70, 0xE3, 0x90, 0x4D,
|
||||
0xEF, 0xFE, 0x41, 0xB7, 0x99, 0x7B, 0xC1, 0x83, 0xBA, 0x62, 0x12, 0x6F, 0x7D, 0xDE, 0x6B, 0xAF,
|
||||
0xDA, 0x16, 0xF9, 0x55, 0x51, 0xEE, 0xA6, 0x0C, 0x2B, 0x02, 0xA3, 0xFD, 0x8D, 0xFB, 0x30, 0x17,
|
||||
0xE4, 0x6F, 0xDF, 0x36, 0x71, 0xC4, 0xCA, 0x87, 0x25, 0x48, 0xB0, 0x47, 0xEC, 0xEA, 0xB4, 0xBF,
|
||||
0xA5, 0x4D, 0x9B, 0x9F, 0x02, 0x93, 0xC4, 0xE3, 0xE4, 0xE8, 0x42, 0x2D, 0x68, 0x81, 0x15, 0x0A,
|
||||
0xEB, 0x84, 0x5B, 0xD6, 0xA8, 0x74, 0xFB, 0x7D, 0x1D, 0xCB, 0x2C, 0xDA, 0x46, 0x2A, 0x76, 0x62,
|
||||
0xCE, 0xBC, 0x5C, 0x9E, 0x8B, 0xE7, 0xCF, 0xBE, 0x78, 0xF5, 0x7C, 0xEB, 0xB3, 0x3A, 0x9C, 0xAA,
|
||||
0x6F, 0xCC, 0x72, 0xD1, 0x59, 0xF2, 0x11, 0x23, 0xD6, 0x3F, 0x48, 0xD1, 0xB7, 0xCE, 0xB0, 0xBF,
|
||||
0xCB, 0xEA, 0x80, 0xDE, 0x57, 0xD4, 0x5E, 0x97, 0x2F, 0x75, 0xD1, 0x50, 0x8E, 0x80, 0x2C, 0x66,
|
||||
0x79, 0xBF, 0x72, 0x4B, 0xBD, 0x8A, 0x81, 0x6C, 0xD3, 0xE1, 0x01, 0xDC, 0xD2, 0x15, 0x26, 0xC5,
|
||||
0x36, 0xDA, 0x2C, 0x1A, 0xC0, 0x27, 0x94, 0xED, 0xB7, 0x9B, 0x85, 0x0B, 0x5E, 0x80, 0x97, 0xC5,
|
||||
0xEC, 0x4F, 0xEC, 0x88, 0x5D, 0x50, 0x07, 0x35, 0x47, 0xDC, 0x0B, 0x3B, 0x3D, 0xDD, 0x60, 0xAF,
|
||||
0xA8, 0x5D, 0x81, 0x38, 0x24, 0x25, 0x5D, 0x5C, 0x15, 0xD1, 0xDE, 0xB3, 0xAB, 0xEC, 0x05, 0x69,
|
||||
0xEF, 0x83, 0xED, 0x57, 0x54, 0xB8, 0x64, 0x64, 0x11, 0x16, 0x32, 0x69, 0xDA, 0x9F, 0x2D, 0x7F,
|
||||
0x36, 0xBB, 0x44, 0x5A, 0x34, 0xE8, 0x7F, 0xBF, 0x03, 0xEB, 0x00, 0x7F, 0x59, 0x68, 0x22, 0x79,
|
||||
0xCF, 0x73, 0x6C, 0x2C, 0x29, 0xA7, 0xA1, 0x5F, 0x38, 0xA1, 0x1D, 0xF0, 0x20, 0x53, 0xE0, 0x1A,
|
||||
0x63, 0x14, 0x58, 0x71, 0x10, 0xAA, 0x08, 0x0C, 0x3E, 0x16, 0x1A, 0x60, 0x22, 0x82, 0x7F, 0xBA,
|
||||
0xA4, 0x43, 0xA0, 0xD0, 0xAC, 0x1B, 0xD5, 0x6B, 0x64, 0xB5, 0x14, 0x93, 0x31, 0x9E, 0x53, 0x50,
|
||||
0xD0, 0x57, 0x66, 0xEE, 0x5A, 0x4F, 0xFB, 0x03, 0x2A, 0x69, 0x58, 0x76, 0xF1, 0x83, 0xF7, 0x4E,
|
||||
0xBA, 0x8C, 0x42, 0x06, 0x60, 0x5D, 0x6D, 0xCE, 0x60, 0x88, 0xAE, 0xA4, 0xC3, 0xF1, 0x03, 0xA5,
|
||||
0x4B, 0x98, 0xA1, 0xFF, 0x67, 0xE1, 0xAC, 0xA2, 0xB8, 0x62, 0xD7, 0x6F, 0xA0, 0x31, 0xB4, 0xD2,
|
||||
0x77, 0xAF, 0x21, 0x10, 0x06, 0xC6, 0x9A, 0xFF, 0x1D, 0x09, 0x17, 0x0E, 0x5F, 0xF1, 0xAA, 0x54,
|
||||
0x34, 0x4B, 0x45, 0x8A, 0x87, 0x63, 0xA6, 0xDC, 0xF9, 0x24, 0x30, 0x67, 0xC6, 0xB2, 0xD6, 0x61,
|
||||
0x33, 0x69, 0xEE, 0x50, 0x61, 0x57, 0x28, 0xE7, 0x7E, 0xEE, 0xEC, 0x3A, 0x5A, 0x73, 0x4E, 0xA8,
|
||||
0x8D, 0xE4, 0x18, 0xEA, 0xEC, 0x41, 0x64, 0xC8, 0xE2, 0xE8, 0x66, 0xB6, 0x2D, 0xB6, 0xFB, 0x6A,
|
||||
0x6C, 0x16, 0xB3, 0xDD, 0x46, 0x43, 0xB9, 0x73, 0x00, 0x6A, 0x71, 0xED, 0x4E, 0x9D, 0x25, 0x1A,
|
||||
0xC3, 0x3C, 0x4A, 0x95, 0x15, 0x99, 0x35, 0x81, 0x14, 0x02, 0xD6, 0x98, 0x9B, 0xEC, 0xD8, 0x23,
|
||||
0x3B, 0x84, 0x29, 0xAF, 0x0C, 0x99, 0x83, 0xA6, 0x9A, 0x34, 0x4F, 0xFA, 0xE8, 0xD0, 0x3C, 0x4B,
|
||||
0xD0, 0xFB, 0xB6, 0x68, 0xB8, 0x9E, 0x8F, 0xCD, 0xF7, 0x60, 0x2D, 0x7A, 0x22, 0xE5, 0x7D, 0xAB,
|
||||
0x65, 0x1B, 0x95, 0xA7, 0xA8, 0x7F, 0xB6, 0x77, 0x47, 0x7B, 0x5F, 0x8B, 0x12, 0x72, 0xD0, 0xD4,
|
||||
0x91, 0xEF, 0xDE, 0x19, 0x50, 0x3C, 0xA7, 0x8B, 0xC4, 0xA9, 0xB3, 0x23, 0xCB, 0x76, 0xE6, 0x81,
|
||||
0xF0, 0xC1, 0x04, 0x8F, 0xA3, 0xB8, 0x54, 0x5B, 0x97, 0xAC, 0x19, 0xFF, 0x3F, 0x55, 0x27, 0x2F,
|
||||
0xE0, 0x1D, 0x42, 0x9B, 0x57, 0xFC, 0x4B, 0x4E, 0x0F, 0xCE, 0x98, 0xA9, 0x43, 0x57, 0x03, 0xBD,
|
||||
0xE7, 0xC8, 0x94, 0xDF, 0x6E, 0x36, 0x73, 0x32, 0xB4, 0xEF, 0x2E, 0x85, 0x7A, 0x6E, 0xFC, 0x6C,
|
||||
0x18, 0x82, 0x75, 0x35, 0x90, 0x07, 0xF3, 0xE4, 0x9F, 0x3E, 0xDC, 0x68, 0xF3, 0xB5, 0xF3, 0x19,
|
||||
0x80, 0x92, 0x06, 0x99, 0xA2, 0xE8, 0x6F, 0xFF, 0x2E, 0x7F, 0xAE, 0x42, 0xA4, 0x5F, 0xFB, 0xD4,
|
||||
0x0E, 0x81, 0x2B, 0xC3, 0x04, 0xFF, 0x2B, 0xB3, 0x74, 0x4E, 0x36, 0x5B, 0x9C, 0x15, 0x00, 0xC6,
|
||||
0x47, 0x2B, 0xE8, 0x8B, 0x3D, 0xF1, 0x9C, 0x03, 0x9A, 0x58, 0x7F, 0x9B, 0x9C, 0xBF, 0x85, 0x49,
|
||||
0x79, 0x35, 0x2E, 0x56, 0x7B, 0x41, 0x14, 0x39, 0x47, 0x83, 0x26, 0xAA, 0x07, 0x89, 0x98, 0x11,
|
||||
0x1B, 0x86, 0xE7, 0x73, 0x7A, 0xD8, 0x7D, 0x78, 0x61, 0x53, 0xE9, 0x79, 0xF5, 0x36, 0x8D, 0x44,
|
||||
0x92, 0x84, 0xF9, 0x13, 0x50, 0x58, 0x3B, 0xA4, 0x6A, 0x36, 0x65, 0x49, 0x8E, 0x3C, 0x0E, 0xF1,
|
||||
0x6F, 0xD2, 0x84, 0xC4, 0x7E, 0x8E, 0x3F, 0x39, 0xAE, 0x7C, 0x84, 0xF1, 0x63, 0x37, 0x8E, 0x3C,
|
||||
0xCC, 0x3E, 0x44, 0x81, 0x45, 0xF1, 0x4B, 0xB9, 0xED, 0x6B, 0x36, 0x5D, 0xBB, 0x20, 0x60, 0x1A,
|
||||
0x0F, 0xA3, 0xAA, 0x55, 0x77, 0x3A, 0xA9, 0xAE, 0x37, 0x4D, 0xBA, 0xB8, 0x86, 0x6B, 0xBC, 0x08,
|
||||
0x50, 0xF6, 0xCC, 0xA4, 0xBD, 0x1D, 0x40, 0x72, 0xA5, 0x86, 0xFA, 0xE2, 0x10, 0xAE, 0x3D, 0x58,
|
||||
0x4B, 0x97, 0xF3, 0x43, 0x74, 0xA9, 0x9E, 0xEB, 0x21, 0xB7, 0x01, 0xA4, 0x86, 0x93, 0x97, 0xEE,
|
||||
0x2F, 0x4F, 0x3B, 0x86, 0xA1, 0x41, 0x6F, 0x41, 0x26, 0x90, 0x78, 0x5C, 0x7F, 0x30, 0x38, 0x4B,
|
||||
0x3F, 0xAA, 0xEC, 0xED, 0x5C, 0x6F, 0x0E, 0xAD, 0x43, 0x87, 0xFD, 0x93, 0x35, 0xE6, 0x01, 0xEF,
|
||||
0x41, 0x26, 0x90, 0x99, 0x9E, 0xFB, 0x19, 0x5B, 0xAD, 0xD2, 0x91, 0x8A, 0xE0, 0x46, 0xAF, 0x65,
|
||||
0xFA, 0x4F, 0x84, 0xC1, 0xA1, 0x2D, 0xCF, 0x45, 0x8B, 0xD3, 0x85, 0x50, 0x55, 0x7C, 0xF9, 0x67,
|
||||
0x88, 0xD4, 0x4E, 0xE9, 0xD7, 0x6B, 0x61, 0x54, 0xA1, 0xA4, 0xA6, 0xA2, 0xC2, 0xBF, 0x30, 0x9C,
|
||||
0x40, 0x9F, 0x5F, 0xD7, 0x69, 0x2B, 0x24, 0x82, 0x5E, 0xD9, 0xD6, 0xA7, 0x12, 0x54, 0x1A, 0xF7,
|
||||
0x55, 0x9F, 0x76, 0x50, 0xA9, 0x95, 0x84, 0xE6, 0x6B, 0x6D, 0xB5, 0x96, 0x54, 0xD6, 0xCD, 0xB3,
|
||||
0xA1, 0x9B, 0x46, 0xA7, 0x94, 0x4D, 0xC4, 0x94, 0xB4, 0x98, 0xE3, 0xE1, 0xE2, 0x34, 0xD5, 0x33,
|
||||
0x16, 0x07, 0x54, 0xCD, 0xB7, 0x77, 0x53, 0xDB, 0x4F, 0x4D, 0x46, 0x9D, 0xE9, 0xD4, 0x9C, 0x8A,
|
||||
0x36, 0xB6, 0xB8, 0x38, 0x26, 0x6C, 0x0E, 0xFF, 0x9C, 0x1B, 0x43, 0x8B, 0x80, 0xCC, 0xB9, 0x3D,
|
||||
0xDA, 0xC7, 0xF1, 0x8A, 0xF2, 0x6D, 0xB8, 0xD7, 0x74, 0x2F, 0x7E, 0x1E, 0xB7, 0xD3, 0x4A, 0xB4,
|
||||
0xAC, 0xFC, 0x79, 0x48, 0x6C, 0xBC, 0x96, 0xB6, 0x94, 0x46, 0x57, 0x2D, 0xB0, 0xA3, 0xFC, 0x1E,
|
||||
0xB9, 0x52, 0x60, 0x85, 0x2D, 0x41, 0xD0, 0x43, 0x01, 0x1E, 0x1C, 0xD5, 0x7D, 0xFC, 0xF3, 0x96,
|
||||
0x0D, 0xC7, 0xCB, 0x2A, 0x29, 0x9A, 0x93, 0xDD, 0x88, 0x2D, 0x37, 0x5D, 0xAA, 0xFB, 0x49, 0x68,
|
||||
0xA0, 0x9C, 0x50, 0x86, 0x7F, 0x68, 0x56, 0x57, 0xF9, 0x79, 0x18, 0x39, 0xD4, 0xE0, 0x01, 0x84,
|
||||
0x33, 0x61, 0xCA, 0xA5, 0xD2, 0xD6, 0xE4, 0xC9, 0x8A, 0x4A, 0x23, 0x44, 0x4E, 0xBC, 0xF0, 0xDC,
|
||||
0x24, 0xA1, 0xA0, 0xC4, 0xE2, 0x07, 0x3C, 0x10, 0xC4, 0xB5, 0x25, 0x4B, 0x65, 0x63, 0xF4, 0x80,
|
||||
0xE7, 0xCF, 0x61, 0xB1, 0x71, 0x82, 0x21, 0x87, 0x2C, 0xF5, 0x91, 0x00, 0x32, 0x0C, 0xEC, 0xA9,
|
||||
0xB5, 0x9A, 0x74, 0x85, 0xE3, 0x36, 0x8F, 0x76, 0x4F, 0x9C, 0x6D, 0xCE, 0xBC, 0xAD, 0x0A, 0x4B,
|
||||
0xED, 0x76, 0x04, 0xCB, 0xC3, 0xB9, 0x33, 0x9E, 0x01, 0x93, 0x96, 0x69, 0x7D, 0xC5, 0xA2, 0x45,
|
||||
0x79, 0x9B, 0x04, 0x5C, 0x84, 0x09, 0xED, 0x88, 0x43, 0xC7, 0xAB, 0x93, 0x14, 0x26, 0xA1, 0x40,
|
||||
0xB5, 0xCE, 0x4E, 0xBF, 0x2A, 0x42, 0x85, 0x3E, 0x2C, 0x3B, 0x54, 0xE8, 0x12, 0x1F, 0x0E, 0x97,
|
||||
0x59, 0xB2, 0x27, 0x89, 0xFA, 0xF2, 0xDF, 0x8E, 0x68, 0x59, 0xDC, 0x06, 0xBC, 0xB6, 0x85, 0x0D,
|
||||
0x06, 0x22, 0xEC, 0xB1, 0xCB, 0xE5, 0x04, 0xE6, 0x3D, 0xB3, 0xB0, 0x41, 0x73, 0x08, 0x3F, 0x3C,
|
||||
0x58, 0x86, 0x63, 0xEB, 0x50, 0xEE, 0x1D, 0x2C, 0x37, 0x74, 0xA9, 0xD3, 0x18, 0xA3, 0x47, 0x6E,
|
||||
0x93, 0x54, 0xAD, 0x0A, 0x5D, 0xB8, 0x2A, 0x55, 0x5D, 0x78, 0xF6, 0xEE, 0xBE, 0x8E, 0x3C, 0x76,
|
||||
0x69, 0xB9, 0x40, 0xC2, 0x34, 0xEC, 0x2A, 0xB9, 0xED, 0x7E, 0x20, 0xE4, 0x8D, 0x00, 0x38, 0xC7,
|
||||
0xE6, 0x8F, 0x44, 0xA8, 0x86, 0xCE, 0xEB, 0x2A, 0xE9, 0x90, 0xF1, 0x4C, 0xDF, 0x32, 0xFB, 0x73,
|
||||
0x1B, 0x6D, 0x92, 0x1E, 0x95, 0xFE, 0xB4, 0xDB, 0x65, 0xDF, 0x4D, 0x23, 0x54, 0x89, 0x48, 0xBF,
|
||||
0x4A, 0x2E, 0x70, 0xD6, 0xD7, 0x62, 0xB4, 0x33, 0x29, 0xB1, 0x3A, 0x33, 0x4C, 0x23, 0x6D, 0xA6,
|
||||
0x76, 0xA5, 0x21, 0x63, 0x48, 0xE6, 0x90, 0x5D, 0xED, 0x90, 0x95, 0x0B, 0x7A, 0x84, 0xBE, 0xB8,
|
||||
0x0D, 0x5E, 0x63, 0x0C, 0x62, 0x26, 0x4C, 0x14, 0x5A, 0xB3, 0xAC, 0x23, 0xA4, 0x74, 0xA7, 0x6F,
|
||||
0x33, 0x30, 0x05, 0x60, 0x01, 0x42, 0xA0, 0x28, 0xB7, 0xEE, 0x19, 0x38, 0xF1, 0x64, 0x80, 0x82,
|
||||
0x43, 0xE1, 0x41, 0x27, 0x1F, 0x1F, 0x90, 0x54, 0x7A, 0xD5, 0x23, 0x2E, 0xD1, 0x3D, 0xCB, 0x28,
|
||||
0xBA, 0x58, 0x7F, 0xDC, 0x7C, 0x91, 0x24, 0xE9, 0x28, 0x51, 0x83, 0x6E, 0xC5, 0x56, 0x21, 0x42,
|
||||
0xED, 0xA0, 0x56, 0x22, 0xA1, 0x40, 0x80, 0x6B, 0xA8, 0xF7, 0x94, 0xCA, 0x13, 0x6B, 0x0C, 0x39,
|
||||
0xD9, 0xFD, 0xE9, 0xF3, 0x6F, 0xA6, 0x9E, 0xFC, 0x70, 0x8A, 0xB3, 0xBC, 0x59, 0x3C, 0x1E, 0x1D,
|
||||
0x6C, 0xF9, 0x7C, 0xAF, 0xF9, 0x88, 0x71, 0x95, 0xEB, 0x57, 0x00, 0xBD, 0x9F, 0x8C, 0x4F, 0xE1,
|
||||
0x24, 0x83, 0xC5, 0x22, 0xEA, 0xFD, 0xD3, 0x0C, 0xE2, 0x17, 0x18, 0x7C, 0x6A, 0x4C, 0xDE, 0x77,
|
||||
0xB4, 0x53, 0x9B, 0x4C, 0x81, 0xCD, 0x23, 0x60, 0xAA, 0x0E, 0x25, 0x73, 0x9C, 0x02, 0x79, 0x32,
|
||||
0x30, 0xDF, 0x74, 0xDF, 0x75, 0x19, 0xF4, 0xA5, 0x14, 0x5C, 0xF7, 0x7A, 0xA8, 0xA5, 0x91, 0x84,
|
||||
0x7C, 0x60, 0x03, 0x06, 0x3B, 0xCD, 0x50, 0xB6, 0x27, 0x9C, 0xFE, 0xB1, 0xDD, 0xCC, 0xD3, 0xB0,
|
||||
0x59, 0x24, 0xB2, 0xCA, 0xE2, 0x1C, 0x81, 0x22, 0x9D, 0x07, 0x8F, 0x8E, 0xB9, 0xBE, 0x4E, 0xFA,
|
||||
0xFC, 0x39, 0x65, 0xBA, 0xBF, 0x9D, 0x12, 0x37, 0x5E, 0x97, 0x7E, 0xF3, 0x89, 0xF5, 0x5D, 0xF5,
|
||||
0xE3, 0x09, 0x8C, 0x62, 0xB5, 0x20, 0x9D, 0x0C, 0x53, 0x8A, 0x68, 0x1B, 0xD2, 0x8F, 0x75, 0x17,
|
||||
0x5D, 0xD4, 0xE5, 0xDA, 0x75, 0x62, 0x19, 0x14, 0x6A, 0x26, 0x2D, 0xEB, 0xF8, 0xAF, 0x37, 0xF0,
|
||||
0x6C, 0xA4, 0x55, 0xB1, 0xBC, 0xE2, 0x33, 0xC0, 0x9A, 0xCA, 0xB0, 0x11, 0x49, 0x4F, 0x68, 0x9B,
|
||||
0x3B, 0x6B, 0x3C, 0xCC, 0x13, 0xF6, 0xC7, 0x85, 0x61, 0x68, 0x42, 0xAE, 0xBB, 0xDD, 0xCD, 0x45,
|
||||
0x16, 0x29, 0x1D, 0xEA, 0xDB, 0xC8, 0x03, 0x94, 0x3C, 0xEE, 0x4F, 0x82, 0x11, 0xC3, 0xEC, 0x28,
|
||||
0xBD, 0x97, 0x05, 0x99, 0xDE, 0xD7, 0xBB, 0x5E, 0x22, 0x1F, 0xD4, 0xEB, 0x64, 0xD9, 0x92, 0xD9,
|
||||
0x85, 0xB7, 0x6A, 0x05, 0x6A, 0xE4, 0x24, 0x41, 0xF1, 0xCD, 0xF0, 0xD8, 0x3F, 0xF8, 0x9E, 0x0E,
|
||||
0xCD, 0x0B, 0x7A, 0x70, 0x6B, 0x5A, 0x75, 0x0A, 0x6A, 0x33, 0x88, 0xEC, 0x17, 0x75, 0x08, 0x70,
|
||||
0x10, 0x2F, 0x24, 0xCF, 0xC4, 0xE9, 0x42, 0x00, 0x61, 0x94, 0xCA, 0x1F, 0x3A, 0x76, 0x06, 0xFA,
|
||||
0xD2, 0x48, 0x81, 0xF0, 0x77, 0x60, 0x03, 0x45, 0xD9, 0x61, 0xF4, 0xA4, 0x6F, 0x3D, 0xD9, 0x30,
|
||||
0xC3, 0x04, 0x6B, 0x54, 0x2A, 0xB7, 0xEC, 0x3B, 0xF4, 0x4B, 0xF5, 0x68, 0x52, 0x26, 0xCE, 0xFF,
|
||||
0x5D, 0x19, 0x91, 0xA0, 0xA3, 0xA5, 0xA9, 0xB1, 0xE0, 0x23, 0xC4, 0x0A, 0x77, 0x4D, 0xF9, 0x51,
|
||||
0x20, 0xA3, 0xA5, 0xA9, 0xB1, 0xC1, 0x00, 0x82, 0x86, 0x8E, 0x7F, 0x5D, 0x19, 0x91, 0xA0, 0xA3,
|
||||
0xC4, 0xEB, 0x54, 0x0B, 0x75, 0x68, 0x52, 0x07, 0x8C, 0x9A, 0x97, 0x8D, 0x79, 0x70, 0x62, 0x46,
|
||||
0xEF, 0x5C, 0x1B, 0x95, 0x89, 0x71, 0x41, 0xE1, 0x21, 0xA1, 0xA1, 0xA1, 0xC0, 0x02, 0x67, 0x4C,
|
||||
0x1A, 0xB6, 0xCF, 0xFD, 0x78, 0x53, 0x24, 0xAB, 0xB5, 0xC9, 0xF1, 0x60, 0x23, 0xA5, 0xC8, 0x12,
|
||||
0x87, 0x6D, 0x58, 0x13, 0x85, 0x88, 0x92, 0x87, 0x6D, 0x58, 0x32, 0xC7, 0x0C, 0x9A, 0x97, 0xAC,
|
||||
0xDA, 0x36, 0xEE, 0x5E, 0x3E, 0xDF, 0x1D, 0xB8, 0xF2, 0x66, 0x2F, 0xBD, 0xF8, 0x72, 0x47, 0xED,
|
||||
0x58, 0x13, 0x85, 0x88, 0x92, 0x87, 0x8C, 0x7B, 0x55, 0x09, 0x90, 0xA2, 0xC6, 0xEF, 0x3D, 0xF8,
|
||||
0x53, 0x24, 0xAB, 0xD4, 0x2A, 0xB7, 0xEC, 0x5A, 0x36, 0xEE, 0x5E, 0x3E, 0xDF, 0x3C, 0xFA, 0x76,
|
||||
0x4F, 0xFD, 0x59, 0x30, 0xE2, 0x46, 0xEF, 0x3D, 0xF8, 0x53, 0x05, 0x69, 0x31, 0xC1, 0x00, 0x82,
|
||||
0x86, 0x8E, 0x7F, 0x5D, 0x19, 0xB0, 0xE2, 0x27, 0xCC, 0xFB, 0x74, 0x4B, 0x14, 0x8B, 0x94, 0x8B,
|
||||
0x75, 0x68, 0x33, 0xC5, 0x08, 0x92, 0x87, 0x8C, 0x9A, 0xB6, 0xCF, 0x1C, 0xBA, 0xD7, 0x0D, 0x98,
|
||||
0xB2, 0xE6, 0x2F, 0xDC, 0x1B, 0x95, 0x89, 0x71, 0x60, 0x23, 0xC4, 0x0A, 0x96, 0x8F, 0x9C, 0xBA,
|
||||
0xF6, 0x6E, 0x3F, 0xFC, 0x5B, 0x15, 0xA8, 0xD2, 0x26, 0xAF, 0xBD, 0xF8, 0x72, 0x66, 0x2F, 0xDC,
|
||||
0x1B, 0xB4, 0xCB, 0x14, 0x8B, 0x94, 0xAA, 0xB7, 0xCD, 0xF9, 0x51, 0x01, 0x80, 0x82, 0x86, 0x6F,
|
||||
0x3D, 0xD9, 0x30, 0xE2, 0x27, 0xCC, 0xFB, 0x74, 0x4B, 0x14, 0xAA, 0xB7, 0xCD, 0xF9, 0x70, 0x43,
|
||||
0x04, 0x6B, 0x35, 0xC9, 0xF1, 0x60, 0x23, 0xA5, 0xC8, 0xF3, 0x45, 0x08, 0x92, 0x87, 0x6D, 0x58,
|
||||
0x32, 0xE6, 0x2F, 0xBD, 0xF8, 0x72, 0x66, 0x4E, 0x1E, 0xBE, 0xFE, 0x7E, 0x7E, 0x7E, 0x5F, 0x1D,
|
||||
0x99, 0x91, 0xA0, 0xA3, 0xC4, 0x0A, 0x77, 0x4D, 0x18, 0x93, 0xA4, 0xAB, 0xD4, 0x0B, 0x75, 0x49,
|
||||
0x10, 0xA2, 0xC6, 0xEF, 0x3D, 0xF8, 0x53, 0x24, 0xAB, 0xB5, 0xE8, 0x33, 0xE4, 0x4A, 0x16, 0xAE,
|
||||
0xDE, 0x1F, 0xBC, 0xDB, 0x15, 0xA8, 0xB3, 0xC5, 0x08, 0x73, 0x45, 0xE9, 0x31, 0xC1, 0xE1, 0x21,
|
||||
0xA1, 0xA1, 0xA1, 0xC0, 0x02, 0x86, 0x6F, 0x5C, 0x3A, 0xD7, 0x0D, 0x98, 0x93, 0xA4, 0xCA, 0x16,
|
||||
0xAE, 0xDE, 0x1F, 0x9D, 0x99, 0xB0, 0xE2, 0x46, 0xEF, 0x3D, 0xF8, 0x72, 0x47, 0x0C, 0x9A, 0xB6,
|
||||
0xCF, 0xFD, 0x59, 0x11, 0xA0, 0xA3, 0xA5, 0xC8, 0xF3, 0x45, 0x08, 0x92, 0x87, 0x6D, 0x39, 0xF0,
|
||||
0x43, 0x04, 0x8A, 0x96, 0xAE, 0xDE, 0x3E, 0xDF, 0x1D, 0x99, 0x91, 0xA0, 0xC2, 0x06, 0x6F, 0x3D,
|
||||
0xF8, 0x72, 0x47, 0x0C, 0x9A, 0x97, 0x8D, 0x98, 0x93, 0x85, 0x88, 0x73, 0x45, 0xE9, 0x31, 0xE0,
|
||||
0x23, 0xA5, 0xA9, 0xD0, 0x03, 0x84, 0x8A, 0x96, 0xAE, 0xDE, 0x1F, 0xBC, 0xDB, 0x15, 0xA8, 0xD2,
|
||||
0x26, 0xCE, 0xFF, 0x5D, 0x19, 0x91, 0x81, 0x80, 0x82, 0x67, 0x2D, 0xD8, 0x13, 0xA4, 0xAB, 0xD4,
|
||||
0x0B, 0x94, 0xAA, 0xB7, 0xCD, 0xF9, 0x51, 0x20, 0xA3, 0xA5, 0xC8, 0xF3, 0x45, 0xE9, 0x50, 0x22,
|
||||
0xC6, 0xEF, 0x5C, 0x3A, 0xD7, 0x0D, 0x98, 0x93, 0x85, 0x88, 0x73, 0x64, 0x4A, 0xF7, 0x4D, 0xF9,
|
||||
0x51, 0x20, 0xA3, 0xC4, 0x0A, 0x96, 0xAE, 0xDE, 0x3E, 0xFE, 0x7E, 0x7E, 0x7E, 0x5F, 0x3C, 0xFA,
|
||||
0x76, 0x4F, 0xFD, 0x78, 0x72, 0x66, 0x2F, 0xBD, 0xD9, 0x30, 0xC3, 0xE5, 0x48, 0x12, 0x87, 0x8C,
|
||||
0x7B, 0x55, 0x28, 0xD2, 0x07, 0x8C, 0x9A, 0x97, 0xAC, 0xDA, 0x17, 0x8D, 0x79, 0x51, 0x20, 0xA3,
|
||||
0xC4, 0xEB, 0x54, 0x0B, 0x94, 0x8B, 0x94, 0xAA, 0xD6, 0x2E, 0xBF, 0xFC, 0x5B, 0x15, 0xA8, 0xD2,
|
||||
0x26, 0xAF, 0xDC, 0x1B, 0xB4, 0xEA, 0x37, 0xEC, 0x3B, 0xF4, 0x6A, 0x37, 0xCD, 0x18, 0x93, 0x85,
|
||||
0x69, 0x31, 0xC1, 0xE1, 0x40, 0xE3, 0x25, 0xC8, 0x12, 0x87, 0x8C, 0x9A, 0xB6, 0xCF, 0xFD, 0x59,
|
||||
0x11, 0xA0, 0xC2, 0x06, 0x8E, 0x7F, 0x5D, 0x38, 0xF2, 0x47, 0x0C, 0x7B, 0x74, 0x6A, 0x37, 0xEC,
|
||||
0x5A, 0x36, 0xEE, 0x3F, 0xFC, 0x7A, 0x76, 0x4F, 0x1C, 0x9B, 0x95, 0x89, 0x71, 0x41, 0x00, 0x63,
|
||||
0x44, 0xEB, 0x54, 0x2A, 0xD6, 0x0F, 0x9C, 0xBA, 0xD7, 0x0D, 0x98, 0x93, 0x85, 0x69, 0x31, 0xC1,
|
||||
0x00, 0x82, 0x86, 0x8E, 0x9E, 0xBE, 0xDF, 0x3C, 0xFA, 0x57, 0x2C, 0xDA, 0x36, 0xEE, 0x3F, 0xFC,
|
||||
0x5B, 0x15, 0x89, 0x71, 0x41, 0x00, 0x82, 0x86, 0x8E, 0x7F, 0x5D, 0x38, 0xF2, 0x47, 0xED, 0x58,
|
||||
0x13, 0xA4, 0xCA, 0xF7, 0x4D, 0xF9, 0x51, 0x01, 0x80, 0x63, 0x44, 0xEB, 0x54, 0x2A, 0xD6, 0x2E,
|
||||
0xBF, 0xDD, 0x19, 0x91, 0xA0, 0xA3, 0xA5, 0xA9, 0xB1, 0xE0, 0x42, 0x06, 0x8E, 0x7F, 0x5D, 0x19,
|
||||
0x91, 0xA0, 0xA3, 0xC4, 0x0A, 0x96, 0x8F, 0x7D, 0x78, 0x72, 0x47, 0x0C, 0x7B, 0x74, 0x6A, 0x56,
|
||||
0x2E, 0xDE, 0x1F, 0xBC, 0xFA, 0x57, 0x0D, 0x79, 0x51, 0x01, 0x61, 0x21, 0xA1, 0xC0, 0xE3, 0x25,
|
||||
0xA9, 0xB1, 0xC1, 0xE1, 0x40, 0x02, 0x67, 0x4C, 0x1A, 0x97, 0x8D, 0x98, 0x93, 0xA4, 0xAB, 0xD4,
|
||||
0x2A, 0xD6, 0x0F, 0x9C, 0x9B, 0xB4, 0xCB, 0x14, 0xAA, 0xB7, 0xCD, 0xF9, 0x51, 0x20, 0xA3, 0xC4,
|
||||
0xEB, 0x35, 0xC9, 0xF1, 0x60, 0x42, 0x06, 0x8E, 0x7F, 0x7C, 0x7A, 0x76, 0x6E, 0x3F, 0xFC, 0x7A,
|
||||
0x76, 0x6E, 0x5E, 0x3E, 0xFE, 0x7E, 0x5F, 0x3C, 0xDB, 0x15, 0x89, 0x71, 0x41, 0xE1, 0x21, 0xC0,
|
||||
0xE3, 0x44, 0xEB, 0x54, 0x2A, 0xB7, 0xCD, 0xF9, 0x70, 0x62, 0x27, 0xAD, 0xD8, 0x32, 0xC7, 0x0C,
|
||||
0x7B, 0x74, 0x4B, 0x14, 0xAA, 0xB7, 0xEC, 0x3B, 0xD5, 0x28, 0xD2, 0x07, 0x6D, 0x39, 0xD1, 0x20,
|
||||
0xC2, 0xE7, 0x4C, 0x1A, 0x97, 0x8D, 0x98, 0xB2, 0xC7, 0x0C, 0x59, 0x28, 0xF3, 0x9B
|
||||
};
|
||||
|
||||
303
drivers/sensors/pmw3389_firmware.h
Normal file
303
drivers/sensors/pmw3389_firmware.h
Normal file
@@ -0,0 +1,303 @@
|
||||
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
|
||||
* Copyright 2019 Sunjun Kim
|
||||
* Copyright 2020 Ploopy Corporation
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General 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
|
||||
|
||||
// PID, Inverse PID, SROM version
|
||||
const uint8_t firmware_signature[] PROGMEM = {0x42, 0xBD, 0x04};
|
||||
|
||||
// clang-format off
|
||||
// Firmware Blob foor PMW3389
|
||||
const uint16_t firmware_length = 4094;
|
||||
// clang-format off
|
||||
const uint8_t firmware_data[] PROGMEM = { // SROM 0x04
|
||||
0x01, 0xe8, 0xba, 0x26, 0x0b, 0xb2, 0xbe, 0xfe, 0x7e, 0x5f, 0x3c, 0xdb, 0x15, 0xa8, 0xb3,
|
||||
0xe4, 0x2b, 0xb5, 0xe8, 0x53, 0x07, 0x6d, 0x3b, 0xd1, 0x20, 0xc2, 0x06, 0x6f, 0x3d, 0xd9,
|
||||
0x11, 0xa0, 0xc2, 0xe7, 0x2d, 0xb9, 0xd1, 0x20, 0xa3, 0xa5, 0xc8, 0xf3, 0x64, 0x4a, 0xf7,
|
||||
0x4d, 0x18, 0x93, 0xa4, 0xca, 0xf7, 0x6c, 0x5a, 0x36, 0xee, 0x5e, 0x3e, 0xfe, 0x7e, 0x7e,
|
||||
0x5f, 0x1d, 0x99, 0xb0, 0xc3, 0xe5, 0x29, 0xd3, 0x03, 0x65, 0x48, 0x12, 0x87, 0x6d, 0x58,
|
||||
0x32, 0xe6, 0x2f, 0xdc, 0x3a, 0xf2, 0x4f, 0xfd, 0x59, 0x11, 0x81, 0x61, 0x21, 0xc0, 0x02,
|
||||
0x86, 0x8e, 0x7f, 0x5d, 0x38, 0xf2, 0x47, 0x0c, 0x7b, 0x55, 0x28, 0xb3, 0xe4, 0x4a, 0x16,
|
||||
0xab, 0xbf, 0xdd, 0x38, 0xf2, 0x66, 0x4e, 0xff, 0x5d, 0x19, 0x91, 0xa0, 0xa3, 0xa5, 0xc8,
|
||||
0x12, 0xa6, 0xaf, 0xdc, 0x3a, 0xd1, 0x41, 0x60, 0x75, 0x58, 0x24, 0x92, 0xd4, 0x72, 0x6c,
|
||||
0xe0, 0x2f, 0xfd, 0x23, 0x8d, 0x1c, 0x5b, 0xb2, 0x97, 0x36, 0x3d, 0x0b, 0xa2, 0x49, 0xb1,
|
||||
0x58, 0xf2, 0x1f, 0xc0, 0xcb, 0xf8, 0x41, 0x4f, 0xcd, 0x1e, 0x6b, 0x39, 0xa7, 0x2b, 0xe9,
|
||||
0x30, 0x16, 0x83, 0xd2, 0x0e, 0x47, 0x8f, 0xe3, 0xb1, 0xdf, 0xa2, 0x15, 0xdb, 0x5d, 0x30,
|
||||
0xc5, 0x1a, 0xab, 0x31, 0x99, 0xf3, 0xfa, 0xb2, 0x86, 0x69, 0xad, 0x7a, 0xe8, 0xa7, 0x18,
|
||||
0x6a, 0xcc, 0xc8, 0x65, 0x23, 0x87, 0xa8, 0x5f, 0xf5, 0x21, 0x59, 0x75, 0x09, 0x71, 0x45,
|
||||
0x55, 0x25, 0x4b, 0xda, 0xa1, 0xc3, 0xf7, 0x41, 0xab, 0x59, 0xd9, 0x74, 0x12, 0x55, 0x5f,
|
||||
0xbc, 0xaf, 0xd9, 0xfd, 0xb0, 0x1e, 0xa3, 0x0f, 0xff, 0xde, 0x11, 0x16, 0x6a, 0xae, 0x0e,
|
||||
0xe1, 0x5d, 0x3c, 0x10, 0x43, 0x9a, 0xa1, 0x0b, 0x24, 0x8f, 0x0d, 0x7f, 0x0b, 0x5e, 0x4c,
|
||||
0x42, 0xa4, 0x84, 0x2c, 0x40, 0xd0, 0x55, 0x39, 0xe6, 0x4b, 0xf8, 0x9b, 0x2f, 0xdc, 0x28,
|
||||
0xff, 0xfa, 0xb5, 0x85, 0x19, 0xe5, 0x28, 0xa1, 0x77, 0xaa, 0x73, 0xf3, 0x03, 0xc7, 0x62,
|
||||
0xa6, 0x91, 0x18, 0xc9, 0xb0, 0xcd, 0x05, 0xdc, 0xca, 0x81, 0x26, 0x1a, 0x47, 0x40, 0xda,
|
||||
0x36, 0x7d, 0x6a, 0x53, 0xc8, 0x5a, 0x77, 0x5d, 0x19, 0xa4, 0x1b, 0x23, 0x83, 0xd0, 0xb2,
|
||||
0xaa, 0x0e, 0xbf, 0x77, 0x4e, 0x3a, 0x3b, 0x59, 0x00, 0x31, 0x0d, 0x02, 0x1b, 0x88, 0x7a,
|
||||
0xd4, 0xbd, 0x9d, 0xcc, 0x58, 0x04, 0x69, 0xf6, 0x3b, 0xca, 0x42, 0xe2, 0xfd, 0xc3, 0x3d,
|
||||
0x39, 0xc5, 0xd0, 0x71, 0xe4, 0xc8, 0xb7, 0x3e, 0x3f, 0xc8, 0xe9, 0xca, 0xc9, 0x3f, 0x04,
|
||||
0x4e, 0x1b, 0x79, 0xca, 0xa5, 0x61, 0xc2, 0xed, 0x1d, 0xa6, 0xda, 0x5a, 0xe9, 0x7f, 0x65,
|
||||
0x8c, 0xbe, 0x12, 0x6e, 0xa4, 0x5b, 0x33, 0x2f, 0x84, 0x28, 0x9c, 0x1c, 0x88, 0x2d, 0xff,
|
||||
0x07, 0xbf, 0xa6, 0xd7, 0x5a, 0x88, 0x86, 0xb0, 0x3f, 0xf6, 0x31, 0x5b, 0x11, 0x6d, 0xf5,
|
||||
0x58, 0xeb, 0x58, 0x02, 0x9e, 0xb5, 0x9a, 0xb1, 0xff, 0x25, 0x9d, 0x8b, 0x4f, 0xb6, 0x0a,
|
||||
0xf9, 0xea, 0x3e, 0x3f, 0x21, 0x09, 0x65, 0x21, 0x22, 0xfe, 0x3d, 0x4e, 0x11, 0x5b, 0x9e,
|
||||
0x5a, 0x59, 0x8b, 0xdd, 0xd8, 0xce, 0xd6, 0xd9, 0x59, 0xd2, 0x1e, 0xfd, 0xef, 0x0d, 0x1b,
|
||||
0xd9, 0x61, 0x7f, 0xd7, 0x2d, 0xad, 0x62, 0x09, 0xe5, 0x22, 0x63, 0xea, 0xc7, 0x31, 0xd9,
|
||||
0xa1, 0x38, 0x80, 0x5c, 0xa7, 0x32, 0x82, 0xec, 0x1b, 0xa2, 0x49, 0x5a, 0x06, 0xd2, 0x7c,
|
||||
0xc9, 0x96, 0x57, 0xbb, 0x17, 0x75, 0xfc, 0x7a, 0x8f, 0x0d, 0x77, 0xb5, 0x7a, 0x8e, 0x3e,
|
||||
0xf4, 0xba, 0x2f, 0x69, 0x13, 0x26, 0xd6, 0xd9, 0x21, 0x60, 0x2f, 0x21, 0x3e, 0x87, 0xee,
|
||||
0xfd, 0x87, 0x16, 0x0d, 0xc8, 0x08, 0x00, 0x25, 0x71, 0xac, 0x2c, 0x03, 0x2a, 0x37, 0x2d,
|
||||
0xb3, 0x34, 0x09, 0x91, 0xe3, 0x06, 0x2c, 0x38, 0x37, 0x95, 0x3b, 0x17, 0x7a, 0xaf, 0xac,
|
||||
0x99, 0x55, 0xab, 0x41, 0x39, 0x5f, 0x8e, 0xa6, 0x43, 0x80, 0x03, 0x88, 0x6f, 0x7d, 0xbd,
|
||||
0x5a, 0xb4, 0x2b, 0x32, 0x23, 0x5a, 0xa9, 0x31, 0x32, 0x39, 0x4c, 0x5b, 0xf4, 0x6b, 0xaf,
|
||||
0x66, 0x6f, 0x3c, 0x8e, 0x2d, 0x82, 0x97, 0x9f, 0x4a, 0x01, 0xdc, 0x99, 0x98, 0x00, 0xec,
|
||||
0x38, 0x7a, 0x79, 0x70, 0xa6, 0x85, 0xd6, 0x21, 0x63, 0x0d, 0x45, 0x9a, 0x2e, 0x5e, 0xa7,
|
||||
0xb1, 0xea, 0x66, 0x6a, 0xbc, 0x62, 0x2d, 0x7b, 0x7d, 0x85, 0xea, 0x95, 0x2f, 0xc0, 0xe8,
|
||||
0x6f, 0x35, 0xa0, 0x3a, 0x02, 0x25, 0xbc, 0xb2, 0x5f, 0x5c, 0x43, 0x96, 0xcc, 0x26, 0xd2,
|
||||
0x16, 0xb4, 0x96, 0x73, 0xd7, 0x13, 0xc7, 0xae, 0x53, 0x15, 0x31, 0x89, 0x68, 0x66, 0x6d,
|
||||
0x2c, 0x92, 0x1f, 0xcc, 0x5b, 0xa7, 0x8f, 0x5d, 0xbb, 0xc9, 0xdb, 0xe8, 0x3b, 0x9d, 0x61,
|
||||
0x74, 0x8b, 0x05, 0xa1, 0x58, 0x52, 0x68, 0xee, 0x3d, 0x39, 0x79, 0xa0, 0x9b, 0xdd, 0xe1,
|
||||
0x55, 0xc9, 0x60, 0xeb, 0xad, 0xb8, 0x5b, 0xc2, 0x5a, 0xb5, 0x2c, 0x18, 0x55, 0xa9, 0x50,
|
||||
0xc3, 0xf6, 0x72, 0x5f, 0xcc, 0xe2, 0xf4, 0x55, 0xb5, 0xd6, 0xb5, 0x4a, 0x99, 0xa5, 0x28,
|
||||
0x74, 0x97, 0x18, 0xe8, 0xc0, 0x84, 0x89, 0x50, 0x03, 0x86, 0x4d, 0x1a, 0xb7, 0x09, 0x90,
|
||||
0xa2, 0x01, 0x04, 0xbb, 0x73, 0x62, 0xcb, 0x97, 0x22, 0x70, 0x5d, 0x52, 0x41, 0x8e, 0xd9,
|
||||
0x90, 0x15, 0xaa, 0xab, 0x0a, 0x31, 0x65, 0xb4, 0xda, 0xd0, 0xee, 0x24, 0xc9, 0x41, 0x91,
|
||||
0x1e, 0xbc, 0x46, 0x70, 0x40, 0x9d, 0xda, 0x0e, 0x2a, 0xe4, 0xb2, 0x4c, 0x9f, 0xf2, 0xfc,
|
||||
0xf3, 0x84, 0x17, 0x44, 0x1e, 0xd7, 0xca, 0x23, 0x1f, 0x3f, 0x5a, 0x22, 0x3d, 0xaf, 0x9b,
|
||||
0x2d, 0xfc, 0x41, 0xad, 0x26, 0xb4, 0x45, 0x67, 0x0b, 0x80, 0x0e, 0xf9, 0x61, 0x37, 0xec,
|
||||
0x3b, 0xf4, 0x4b, 0x14, 0xdf, 0x5a, 0x0c, 0x3a, 0x50, 0x0b, 0x14, 0x0c, 0x72, 0xae, 0xc6,
|
||||
0xc5, 0xec, 0x35, 0x53, 0x2d, 0x59, 0xed, 0x91, 0x74, 0xe2, 0xc4, 0xc8, 0xf2, 0x25, 0x6b,
|
||||
0x97, 0x6f, 0xc9, 0x76, 0xce, 0xa9, 0xb1, 0x99, 0x8f, 0x5a, 0x92, 0x3b, 0xc4, 0x8d, 0x54,
|
||||
0x50, 0x40, 0x72, 0xd6, 0x90, 0x83, 0xfc, 0xe5, 0x49, 0x8b, 0x17, 0xf5, 0xfd, 0x6b, 0x8d,
|
||||
0x32, 0x02, 0xe9, 0x0a, 0xfe, 0xbf, 0x00, 0x6b, 0xa3, 0xad, 0x5f, 0x09, 0x4b, 0x97, 0x2b,
|
||||
0x00, 0x58, 0x65, 0x2e, 0x07, 0x49, 0x0a, 0x3b, 0x6b, 0x2e, 0x50, 0x6c, 0x1d, 0xac, 0xb7,
|
||||
0x6a, 0x26, 0xd8, 0x13, 0xa4, 0xca, 0x16, 0xae, 0xab, 0x93, 0xb9, 0x1c, 0x1c, 0xb4, 0x47,
|
||||
0x6a, 0x38, 0x36, 0x17, 0x27, 0xc9, 0x7f, 0xc7, 0x64, 0xcb, 0x89, 0x58, 0xc5, 0x61, 0xc2,
|
||||
0xc6, 0xea, 0x15, 0x0b, 0x34, 0x0c, 0x5d, 0x61, 0x76, 0x6e, 0x2b, 0x62, 0x40, 0x92, 0xa3,
|
||||
0x6c, 0xef, 0xf4, 0xe4, 0xc3, 0xa1, 0xa8, 0xf5, 0x94, 0x79, 0x0d, 0xd1, 0x3d, 0xcb, 0x3d,
|
||||
0x40, 0xb6, 0xd0, 0xf0, 0x10, 0x54, 0xd8, 0x47, 0x25, 0x51, 0xc5, 0x41, 0x79, 0x00, 0xe5,
|
||||
0xa0, 0x72, 0xde, 0xbb, 0x3b, 0x62, 0x17, 0xf6, 0xbc, 0x5d, 0x00, 0x76, 0x2e, 0xa7, 0x3b,
|
||||
0xb6, 0xf1, 0x98, 0x72, 0x59, 0x2a, 0x73, 0xb0, 0x21, 0xd6, 0x49, 0xe0, 0xc0, 0xd5, 0xeb,
|
||||
0x02, 0x7d, 0x4b, 0x41, 0x28, 0x70, 0x2d, 0xec, 0x2b, 0x71, 0x1f, 0x0b, 0xb9, 0x71, 0x63,
|
||||
0x06, 0xe6, 0xbc, 0x60, 0xbb, 0xf4, 0x9a, 0x62, 0x43, 0x09, 0x18, 0x4e, 0x93, 0x06, 0x4d,
|
||||
0x76, 0xfa, 0x7f, 0xbd, 0x02, 0xe4, 0x50, 0x91, 0x12, 0xe5, 0x86, 0xff, 0x64, 0x1e, 0xaf,
|
||||
0x7e, 0xb3, 0xb2, 0xde, 0x89, 0xc1, 0xa2, 0x6f, 0x40, 0x7b, 0x41, 0x51, 0x63, 0xea, 0x25,
|
||||
0xd1, 0x97, 0x57, 0x92, 0xa8, 0x45, 0xa1, 0xa5, 0x45, 0x21, 0x43, 0x7f, 0x83, 0x15, 0x29,
|
||||
0xd0, 0x30, 0x53, 0x32, 0xb4, 0x5a, 0x17, 0x96, 0xbc, 0xc2, 0x68, 0xa9, 0xb7, 0xaf, 0xac,
|
||||
0xdf, 0xf1, 0xe3, 0x89, 0xba, 0x24, 0x79, 0x54, 0xc6, 0x14, 0x07, 0x1c, 0x1e, 0x0d, 0x3a,
|
||||
0x6b, 0xe5, 0x3d, 0x4e, 0x10, 0x60, 0x96, 0xec, 0x6c, 0xda, 0x47, 0xae, 0x03, 0x25, 0x39,
|
||||
0x1d, 0x74, 0xc8, 0xac, 0x6a, 0xf2, 0x6b, 0x05, 0x2a, 0x9a, 0xe7, 0xe8, 0x92, 0xd6, 0xc2,
|
||||
0x6d, 0xfa, 0xe8, 0xa7, 0x9d, 0x5f, 0x48, 0xc9, 0x75, 0xf1, 0x66, 0x6a, 0xdb, 0x5d, 0x9a,
|
||||
0xcd, 0x27, 0xdd, 0xb9, 0x24, 0x04, 0x9c, 0x18, 0xc2, 0x6d, 0x0c, 0x91, 0x34, 0x48, 0x42,
|
||||
0x6f, 0xe9, 0x59, 0x70, 0xc4, 0x7e, 0x81, 0x0e, 0x32, 0x0a, 0x93, 0x48, 0xb0, 0xc0, 0x15,
|
||||
0x9e, 0x05, 0xac, 0x36, 0x16, 0xcb, 0x59, 0x65, 0xa0, 0x83, 0xdf, 0x3e, 0xda, 0xfb, 0x1d,
|
||||
0x1a, 0xdb, 0x65, 0xec, 0x9a, 0xc6, 0xc3, 0x8e, 0x3c, 0x45, 0xfd, 0xc8, 0xf5, 0x1c, 0x6a,
|
||||
0x67, 0x0d, 0x8f, 0x99, 0x7d, 0x30, 0x21, 0x8c, 0xea, 0x22, 0x87, 0x65, 0xc9, 0xb2, 0x4c,
|
||||
0xe4, 0x1b, 0x46, 0xba, 0x54, 0xbd, 0x7c, 0xca, 0xd5, 0x8f, 0x5b, 0xa5, 0x01, 0x04, 0xd8,
|
||||
0x0a, 0x16, 0xbf, 0xb9, 0x50, 0x2e, 0x37, 0x2f, 0x64, 0xf3, 0x70, 0x11, 0x02, 0x05, 0x31,
|
||||
0x9b, 0xa0, 0xb2, 0x01, 0x5e, 0x4f, 0x19, 0xc9, 0xd4, 0xea, 0xa1, 0x79, 0x54, 0x53, 0xa7,
|
||||
0xde, 0x2f, 0x49, 0xd3, 0xd1, 0x63, 0xb5, 0x03, 0x15, 0x4e, 0xbf, 0x04, 0xb3, 0x26, 0x8b,
|
||||
0x20, 0xb2, 0x45, 0xcf, 0xcd, 0x5b, 0x82, 0x32, 0x88, 0x61, 0xa7, 0xa8, 0xb2, 0xa0, 0x72,
|
||||
0x96, 0xc0, 0xdb, 0x2b, 0xe2, 0x5f, 0xba, 0xe3, 0xf5, 0x8a, 0xde, 0xf1, 0x18, 0x01, 0x16,
|
||||
0x40, 0xd9, 0x86, 0x12, 0x09, 0x18, 0x1b, 0x05, 0x0c, 0xb1, 0xb5, 0x47, 0xe2, 0x43, 0xab,
|
||||
0xfe, 0x92, 0x63, 0x7e, 0x95, 0x2b, 0xf0, 0xaf, 0xe1, 0xf1, 0xc3, 0x4a, 0xff, 0x2b, 0x09,
|
||||
0xbb, 0x4a, 0x0e, 0x9a, 0xc4, 0xd8, 0x64, 0x7d, 0x83, 0xa0, 0x4f, 0x44, 0xdb, 0xc4, 0xa8,
|
||||
0x58, 0xef, 0xfc, 0x9e, 0x77, 0xf9, 0xa6, 0x8f, 0x58, 0x8b, 0x12, 0xf4, 0xe9, 0x81, 0x12,
|
||||
0x47, 0x51, 0x41, 0x83, 0xef, 0xf6, 0x73, 0xbc, 0x8e, 0x0f, 0x4c, 0x8f, 0x4e, 0x69, 0x90,
|
||||
0x77, 0x29, 0x5d, 0x92, 0xb0, 0x6d, 0x06, 0x67, 0x29, 0x60, 0xbd, 0x4b, 0x17, 0xc8, 0x89,
|
||||
0x69, 0x28, 0x29, 0xd6, 0x78, 0xcb, 0x11, 0x4c, 0xba, 0x8b, 0x68, 0xae, 0x7e, 0x9f, 0xef,
|
||||
0x95, 0xda, 0xe2, 0x9e, 0x7f, 0xe9, 0x55, 0xe5, 0xe1, 0xe2, 0xb7, 0xe6, 0x5f, 0xbb, 0x2c,
|
||||
0xa2, 0xe6, 0xee, 0xc7, 0x0a, 0x60, 0xa9, 0xd1, 0x80, 0xdf, 0x7f, 0xd6, 0x97, 0xab, 0x1d,
|
||||
0x22, 0x25, 0xfc, 0x79, 0x23, 0xe0, 0xae, 0xc5, 0xef, 0x16, 0xa4, 0xa1, 0x0f, 0x92, 0xa9,
|
||||
0xc7, 0xe3, 0x3a, 0x55, 0xdf, 0x62, 0x49, 0xd9, 0xf5, 0x84, 0x49, 0xc5, 0x90, 0x34, 0xd3,
|
||||
0xe1, 0xac, 0x99, 0x21, 0xb1, 0x02, 0x76, 0x4a, 0xfa, 0xd4, 0xbb, 0xa4, 0x9c, 0xa2, 0xe2,
|
||||
0xcb, 0x3d, 0x3b, 0x14, 0x75, 0x60, 0xd1, 0x02, 0xb4, 0xa3, 0xb4, 0x72, 0x06, 0xf9, 0x19,
|
||||
0x9c, 0xe2, 0xe4, 0xa7, 0x0f, 0x25, 0x88, 0xc6, 0x86, 0xd6, 0x8c, 0x74, 0x4e, 0x6e, 0xfc,
|
||||
0xa8, 0x48, 0x9e, 0xa7, 0x9d, 0x1a, 0x4b, 0x37, 0x09, 0xc8, 0xb0, 0x10, 0xbe, 0x6f, 0xfe,
|
||||
0xa3, 0xc4, 0x7a, 0xb5, 0x3d, 0xe8, 0x30, 0xf1, 0x0d, 0xa0, 0xb2, 0x44, 0xfc, 0x9b, 0x8c,
|
||||
0xf8, 0x61, 0xed, 0x81, 0xd1, 0x62, 0x11, 0xb4, 0xe1, 0xd5, 0x39, 0x52, 0x89, 0xd3, 0xa8,
|
||||
0x49, 0x31, 0xdf, 0xb6, 0xf9, 0x91, 0xf4, 0x1c, 0x9d, 0x09, 0x95, 0x40, 0x56, 0xe7, 0xe3,
|
||||
0xcd, 0x5c, 0x92, 0xc1, 0x1d, 0x6b, 0xe9, 0x78, 0x6f, 0x8e, 0x94, 0x42, 0x66, 0xa2, 0xaa,
|
||||
0xd3, 0xc8, 0x2e, 0xe3, 0xf6, 0x07, 0x72, 0x0b, 0x6b, 0x1e, 0x7b, 0xb9, 0x7c, 0xe0, 0xa0,
|
||||
0xbc, 0xd9, 0x25, 0xdf, 0x87, 0xa8, 0x5f, 0x9c, 0xcc, 0xf0, 0xdb, 0x42, 0x8e, 0x07, 0x31,
|
||||
0x13, 0x01, 0x66, 0x32, 0xd1, 0xb8, 0xd6, 0xe3, 0x5e, 0x12, 0x76, 0x61, 0xd3, 0x38, 0x89,
|
||||
0xe6, 0x17, 0x6f, 0xa5, 0xf2, 0x71, 0x0e, 0xa5, 0xe2, 0x88, 0x30, 0xbb, 0xbe, 0x8a, 0xea,
|
||||
0xc7, 0x62, 0xc4, 0xcf, 0xb8, 0xcd, 0x33, 0x8d, 0x3d, 0x3e, 0xb5, 0x60, 0x3a, 0x03, 0x92,
|
||||
0xe4, 0x6d, 0x1b, 0xe0, 0xb4, 0x84, 0x08, 0x55, 0x88, 0xa7, 0x3a, 0xb9, 0x3d, 0x43, 0xc3,
|
||||
0xc0, 0xfa, 0x07, 0x6a, 0xca, 0x94, 0xad, 0x99, 0x55, 0xf1, 0xf1, 0xc0, 0x23, 0x87, 0x1d,
|
||||
0x3d, 0x1c, 0xd1, 0x66, 0xa0, 0x57, 0x10, 0x52, 0xa2, 0x7f, 0xbe, 0xf9, 0x88, 0xb6, 0x02,
|
||||
0xbf, 0x08, 0x23, 0xa9, 0x0c, 0x63, 0x17, 0x2a, 0xae, 0xf5, 0xf7, 0xb7, 0x21, 0x83, 0x92,
|
||||
0x31, 0x23, 0x0d, 0x20, 0xc3, 0xc2, 0x05, 0x21, 0x62, 0x8e, 0x45, 0xe8, 0x14, 0xc1, 0xda,
|
||||
0x75, 0xb8, 0xf8, 0x92, 0x01, 0xd0, 0x5d, 0x18, 0x9f, 0x99, 0x11, 0x19, 0xf5, 0x35, 0xe8,
|
||||
0x7f, 0x20, 0x88, 0x8c, 0x05, 0x75, 0xf5, 0xd7, 0x40, 0x17, 0xbb, 0x1e, 0x36, 0x52, 0xd9,
|
||||
0xa4, 0x9c, 0xc2, 0x9d, 0x42, 0x81, 0xd8, 0xc7, 0x8a, 0xe7, 0x4c, 0x81, 0xe0, 0xb7, 0x57,
|
||||
0xed, 0x48, 0x8b, 0xf0, 0x97, 0x15, 0x61, 0xd9, 0x2c, 0x7c, 0x45, 0xaf, 0xc2, 0xcd, 0xfc,
|
||||
0xaa, 0x13, 0xad, 0x59, 0xcc, 0xb2, 0xb2, 0x6e, 0xdd, 0x63, 0x9c, 0x32, 0x0f, 0xec, 0x83,
|
||||
0xbe, 0x78, 0xac, 0x91, 0x44, 0x1a, 0x1f, 0xea, 0xfd, 0x5d, 0x8e, 0xb4, 0xc0, 0x84, 0xd4,
|
||||
0xac, 0xb4, 0x87, 0x5f, 0xac, 0xef, 0xdf, 0xcd, 0x12, 0x56, 0xc8, 0xcd, 0xfe, 0xc5, 0xda,
|
||||
0xd3, 0xc1, 0x69, 0xf3, 0x61, 0x05, 0xea, 0x25, 0xe2, 0x12, 0x05, 0x8f, 0x39, 0x08, 0x08,
|
||||
0x7c, 0x37, 0xb6, 0x7e, 0x5b, 0xd8, 0xb1, 0x0e, 0xf2, 0xdb, 0x4b, 0xf1, 0xad, 0x90, 0x01,
|
||||
0x57, 0xcd, 0xa0, 0xb4, 0x52, 0xe8, 0xf3, 0xd7, 0x8a, 0xbd, 0x4f, 0x9f, 0x21, 0x40, 0x72,
|
||||
0xa4, 0xfc, 0x0b, 0x01, 0x2b, 0x2f, 0xb6, 0x4c, 0x95, 0x2d, 0x35, 0x33, 0x41, 0x6b, 0xa0,
|
||||
0x93, 0xe7, 0x2c, 0xf2, 0xd3, 0x72, 0x8b, 0xf4, 0x4f, 0x15, 0x3c, 0xaf, 0xd6, 0x12, 0xde,
|
||||
0x3f, 0x83, 0x3f, 0xff, 0xf8, 0x7f, 0xf6, 0xcc, 0xa6, 0x7f, 0xc9, 0x9a, 0x6e, 0x1f, 0xc1,
|
||||
0x0c, 0xfb, 0xee, 0x9c, 0xe7, 0xaf, 0xc9, 0x26, 0x54, 0xef, 0xb0, 0x39, 0xef, 0xb2, 0xe9,
|
||||
0x23, 0xc4, 0xef, 0xd1, 0xa1, 0xa4, 0x25, 0x24, 0x6f, 0x8d, 0x6a, 0xe5, 0x8a, 0x32, 0x3a,
|
||||
0xaf, 0xfc, 0xda, 0xce, 0x18, 0x25, 0x42, 0x07, 0x4d, 0x45, 0x8b, 0xdf, 0x85, 0xcf, 0x55,
|
||||
0xb2, 0x24, 0xfe, 0x9c, 0x69, 0x74, 0xa7, 0x6e, 0xa0, 0xce, 0xc0, 0x39, 0xf4, 0x86, 0xc6,
|
||||
0x8d, 0xae, 0xb9, 0x48, 0x64, 0x13, 0x0b, 0x40, 0x81, 0xa2, 0xc9, 0xa8, 0x85, 0x51, 0xee,
|
||||
0x9f, 0xcf, 0xa2, 0x8c, 0x19, 0x52, 0x48, 0xe2, 0xc1, 0xa8, 0x58, 0xb4, 0x10, 0x24, 0x06,
|
||||
0x58, 0x51, 0xfc, 0xb9, 0x12, 0xec, 0xfd, 0x73, 0xb4, 0x6d, 0x84, 0xfa, 0x06, 0x8b, 0x05,
|
||||
0x0b, 0x2d, 0xd6, 0xd6, 0x1f, 0x29, 0x82, 0x9f, 0x19, 0x12, 0x1e, 0xb2, 0x04, 0x8f, 0x7f,
|
||||
0x4d, 0xbd, 0x30, 0x2e, 0xe3, 0xe0, 0x88, 0x29, 0xc5, 0x93, 0xd6, 0x6c, 0x1f, 0x29, 0x45,
|
||||
0x91, 0xa7, 0x58, 0xcd, 0x05, 0x17, 0xd6, 0x6d, 0xb3, 0xca, 0x66, 0xcc, 0x3c, 0x4a, 0x74,
|
||||
0xfd, 0x08, 0x10, 0xa6, 0x99, 0x92, 0x10, 0xd2, 0x85, 0xab, 0x6e, 0x1d, 0x0e, 0x8b, 0x26,
|
||||
0x46, 0xd1, 0x6c, 0x84, 0xc0, 0x26, 0x43, 0x59, 0x68, 0xf0, 0x13, 0x1d, 0xfb, 0xe3, 0xd1,
|
||||
0xd2, 0xb4, 0x71, 0x9e, 0xf2, 0x59, 0x6a, 0x33, 0x29, 0x79, 0xd2, 0xd7, 0x26, 0xf1, 0xae,
|
||||
0x78, 0x9e, 0x1f, 0x0f, 0x3f, 0xe3, 0xe8, 0xd0, 0x27, 0x78, 0x77, 0xf6, 0xac, 0x9c, 0x56,
|
||||
0x39, 0x73, 0x8a, 0x6b, 0x2f, 0x34, 0x78, 0xb1, 0x11, 0xdb, 0xa4, 0x5c, 0x80, 0x01, 0x71,
|
||||
0x6a, 0xc2, 0xd1, 0x2e, 0x5e, 0x76, 0x28, 0x70, 0x93, 0xae, 0x3e, 0x78, 0xb0, 0x1f, 0x0f,
|
||||
0xda, 0xbf, 0xfb, 0x8a, 0x67, 0x65, 0x4f, 0x91, 0xed, 0x49, 0x75, 0x78, 0x62, 0xa2, 0x93,
|
||||
0xb5, 0x70, 0x7f, 0x4d, 0x08, 0x4e, 0x79, 0x61, 0xa8, 0x5f, 0x7f, 0xb4, 0x65, 0x9f, 0x91,
|
||||
0x54, 0x3a, 0xe8, 0x50, 0x33, 0xd3, 0xd5, 0x8a, 0x7c, 0xf3, 0x9e, 0x8b, 0x77, 0x7b, 0xc6,
|
||||
0xc6, 0x0c, 0x45, 0x95, 0x1f, 0xb0, 0xd0, 0x0b, 0x27, 0x4a, 0xfd, 0xc7, 0xf7, 0x0d, 0x5a,
|
||||
0x43, 0xc9, 0x7d, 0x35, 0xb0, 0x7d, 0xc4, 0x9c, 0x57, 0x1e, 0x76, 0x0d, 0xf1, 0x95, 0x30,
|
||||
0x71, 0xcc, 0xb3, 0x66, 0x3b, 0x63, 0xa8, 0x6c, 0xa3, 0x43, 0xa0, 0x24, 0xcc, 0xb7, 0x53,
|
||||
0xfe, 0xfe, 0xbc, 0x6e, 0x60, 0x89, 0xaf, 0x16, 0x21, 0xc8, 0x91, 0x6a, 0x89, 0xce, 0x80,
|
||||
0x2c, 0xf1, 0x59, 0xce, 0xc3, 0x60, 0x61, 0x3b, 0x0b, 0x19, 0xfe, 0x99, 0xac, 0x65, 0x90,
|
||||
0x15, 0x12, 0x05, 0xac, 0x7e, 0xff, 0x98, 0x7b, 0x66, 0x64, 0x0e, 0x4b, 0x5b, 0xaa, 0x8d,
|
||||
0x3b, 0xd2, 0x56, 0xcf, 0x99, 0x39, 0xee, 0x22, 0x81, 0xd0, 0x60, 0x06, 0x66, 0x20, 0x81,
|
||||
0x48, 0x3c, 0x6f, 0x3a, 0x77, 0xba, 0xcb, 0x52, 0xac, 0x79, 0x56, 0xaf, 0xe9, 0x16, 0x17,
|
||||
0x0a, 0xa3, 0x82, 0x08, 0xd5, 0x3c, 0x97, 0xcb, 0x09, 0xff, 0x7f, 0xf9, 0x4f, 0x60, 0x05,
|
||||
0xb9, 0x53, 0x26, 0xaa, 0xb8, 0x50, 0xaa, 0x19, 0x25, 0xae, 0x5f, 0xea, 0x8a, 0xd0, 0x89,
|
||||
0x12, 0x80, 0x43, 0x50, 0x24, 0x12, 0x21, 0x14, 0xcd, 0x77, 0xeb, 0x21, 0xcc, 0x5c, 0x09,
|
||||
0x64, 0xf3, 0xc7, 0xcb, 0xc5, 0x4b, 0xc3, 0xe7, 0xed, 0xe7, 0x86, 0x2c, 0x1d, 0x8e, 0x19,
|
||||
0x52, 0x9b, 0x2a, 0x0c, 0x18, 0x72, 0x0b, 0x1e, 0x1b, 0xb0, 0x0f, 0x42, 0x99, 0x04, 0xae,
|
||||
0xd5, 0xb7, 0x89, 0x1a, 0xb9, 0x4f, 0xd6, 0xaf, 0xf3, 0xc9, 0x93, 0x6f, 0xb0, 0x60, 0x83,
|
||||
0x6e, 0x6b, 0xd1, 0x5f, 0x3f, 0x1a, 0x83, 0x1e, 0x24, 0x00, 0x87, 0xb5, 0x3e, 0xdb, 0xf9,
|
||||
0x4d, 0xa7, 0x16, 0x2e, 0x19, 0x5b, 0x8f, 0x1b, 0x0d, 0x47, 0x72, 0x42, 0xe9, 0x0a, 0x11,
|
||||
0x08, 0x2d, 0x88, 0x1c, 0xbc, 0xc7, 0xb4, 0xbe, 0x29, 0x4d, 0x03, 0x5e, 0xec, 0xdf, 0xf3,
|
||||
0x3d, 0x2f, 0xe8, 0x1d, 0x9a, 0xd2, 0xd1, 0xab, 0x41, 0x3d, 0x87, 0x11, 0x45, 0xb0, 0x0d,
|
||||
0x46, 0xf5, 0xe8, 0x95, 0x62, 0x1c, 0x68, 0xf7, 0xa6, 0x5b, 0x39, 0x4e, 0xbf, 0x47, 0xba,
|
||||
0x5d, 0x7f, 0xb7, 0x6a, 0xf4, 0xba, 0x1d, 0x69, 0xf6, 0xa4, 0xe7, 0xe4, 0x6b, 0x3b, 0x0d,
|
||||
0x23, 0x16, 0x4a, 0xb2, 0x68, 0xf0, 0xb2, 0x0d, 0x09, 0x17, 0x6a, 0x63, 0x8c, 0x83, 0xd3,
|
||||
0xbd, 0x05, 0xc9, 0xf6, 0xf0, 0xa1, 0x31, 0x0b, 0x2c, 0xac, 0x83, 0xac, 0x80, 0x34, 0x32,
|
||||
0xb4, 0xec, 0xd0, 0xbc, 0x54, 0x82, 0x9a, 0xc8, 0xf6, 0xa0, 0x7d, 0xc6, 0x79, 0x73, 0xf4,
|
||||
0x20, 0x99, 0xf3, 0xb4, 0x01, 0xde, 0x91, 0x27, 0xf2, 0xc0, 0xdc, 0x81, 0x00, 0x4e, 0x7e,
|
||||
0x07, 0x99, 0xc8, 0x3a, 0x51, 0xbc, 0x38, 0xd6, 0x8a, 0xa2, 0xde, 0x3b, 0x6a, 0x8c, 0x1a,
|
||||
0x7c, 0x81, 0x0f, 0x3a, 0x1f, 0xe4, 0x05, 0x7b, 0x20, 0x35, 0x6b, 0xa5, 0x6a, 0xa7, 0xe7,
|
||||
0xbc, 0x9c, 0x20, 0xec, 0x00, 0x15, 0xe2, 0x51, 0xaf, 0x77, 0xeb, 0x29, 0x3c, 0x7d, 0x2e,
|
||||
0x00, 0x5c, 0x81, 0x21, 0xfa, 0x35, 0x6f, 0x40, 0xef, 0xfb, 0xd1, 0x3f, 0xcc, 0x9d, 0x55,
|
||||
0x53, 0xfb, 0x5a, 0xa5, 0x56, 0x89, 0x0b, 0x52, 0xeb, 0x57, 0x73, 0x4f, 0x1b, 0x67, 0x24,
|
||||
0xcb, 0xb8, 0x6a, 0x10, 0x69, 0xd6, 0xfb, 0x52, 0x40, 0xff, 0x20, 0xa5, 0xf3, 0x72, 0xe1,
|
||||
0x3d, 0xa4, 0x8c, 0x81, 0x66, 0x16, 0x0d, 0x5d, 0xad, 0xa8, 0x50, 0x25, 0x78, 0x31, 0x77,
|
||||
0x0c, 0x57, 0xe4, 0xe9, 0x15, 0x2d, 0xdb, 0x07, 0x87, 0xc8, 0xb0, 0x43, 0xde, 0xfc, 0xfe,
|
||||
0xa9, 0xeb, 0xf5, 0xb0, 0xd3, 0x7b, 0xe9, 0x1f, 0x6e, 0xca, 0xe4, 0x03, 0x95, 0xc5, 0xd1,
|
||||
0x59, 0x72, 0x63, 0xf0, 0x86, 0x54, 0xe8, 0x16, 0x62, 0x0b, 0x35, 0x29, 0xc2, 0x68, 0xd0,
|
||||
0xd6, 0x3e, 0x90, 0x60, 0x57, 0x1d, 0xc9, 0xed, 0x3f, 0xed, 0xb0, 0x2f, 0x7e, 0x97, 0x02,
|
||||
0x51, 0xec, 0xee, 0x6f, 0x82, 0x74, 0x76, 0x7f, 0xfb, 0xd6, 0xc4, 0xc3, 0xdd, 0xe8, 0xb1,
|
||||
0x60, 0xfc, 0xc6, 0xb9, 0x0d, 0x6a, 0x33, 0x78, 0xc6, 0xc1, 0xbf, 0x86, 0x2c, 0x50, 0xcc,
|
||||
0x9a, 0x70, 0x8e, 0x7b, 0xec, 0xab, 0x95, 0xac, 0x53, 0xa0, 0x4b, 0x07, 0x88, 0xaf, 0x42,
|
||||
0xed, 0x19, 0x8d, 0xf6, 0x32, 0x17, 0x48, 0x47, 0x1d, 0x41, 0x6f, 0xfe, 0x2e, 0xa7, 0x8f,
|
||||
0x4b, 0xa0, 0x51, 0xf3, 0xbf, 0x02, 0x0a, 0x48, 0x58, 0xf7, 0xa1, 0x6d, 0xea, 0xa5, 0x13,
|
||||
0x5a, 0x5b, 0xea, 0x0c, 0x9e, 0x52, 0x4f, 0x9e, 0xb9, 0x71, 0x7f, 0x23, 0x83, 0xda, 0x1b,
|
||||
0x86, 0x9a, 0x41, 0x29, 0xda, 0x70, 0xe7, 0x64, 0xa1, 0x7b, 0xd5, 0x0a, 0x22, 0x0d, 0x5c,
|
||||
0x40, 0xc4, 0x81, 0x07, 0x25, 0x35, 0x4a, 0x1c, 0x10, 0xdb, 0x45, 0x0a, 0xff, 0x36, 0xd4,
|
||||
0xe0, 0xeb, 0x5f, 0x68, 0xd6, 0x67, 0xc6, 0xd0, 0x8b, 0x76, 0x1a, 0x7d, 0x59, 0x42, 0xa1,
|
||||
0xcb, 0x96, 0x4d, 0x84, 0x09, 0x9a, 0x3d, 0xe0, 0x52, 0x85, 0x6e, 0x48, 0x90, 0x85, 0x2a,
|
||||
0x63, 0xb2, 0x69, 0xd2, 0x00, 0x43, 0x31, 0x37, 0xb3, 0x52, 0xaf, 0x62, 0xfa, 0xc1, 0xe0,
|
||||
0x03, 0xfb, 0x62, 0xaa, 0x88, 0xc9, 0xb2, 0x2c, 0xd5, 0xa8, 0xf5, 0xa5, 0x4c, 0x12, 0x59,
|
||||
0x4e, 0x06, 0x5e, 0x9b, 0x15, 0x66, 0x11, 0xb2, 0x27, 0x92, 0xdc, 0x98, 0x59, 0xde, 0xdf,
|
||||
0xfa, 0x9a, 0x32, 0x2e, 0xc0, 0x5d, 0x3c, 0x33, 0x41, 0x6d, 0xaf, 0xb2, 0x25, 0x23, 0x14,
|
||||
0xa5, 0x7b, 0xc7, 0x9b, 0x68, 0xf3, 0xda, 0xeb, 0xe3, 0xa9, 0xe2, 0x6f, 0x0e, 0x1d, 0x1c,
|
||||
0xba, 0x55, 0xb6, 0x34, 0x6a, 0x93, 0x1f, 0x1f, 0xb8, 0x34, 0xc8, 0x84, 0x08, 0xb1, 0x6b,
|
||||
0x6a, 0x28, 0x74, 0x74, 0xe5, 0xeb, 0x75, 0xe9, 0x7c, 0xd8, 0xba, 0xd8, 0x42, 0xa5, 0xee,
|
||||
0x1f, 0x80, 0xd9, 0x96, 0xb2, 0x2e, 0xe7, 0xbf, 0xba, 0xeb, 0xd1, 0x69, 0xbb, 0x8f, 0xfd,
|
||||
0x5a, 0x63, 0x8f, 0x39, 0x7f, 0xdf, 0x1d, 0x37, 0xd2, 0x18, 0x35, 0x9d, 0xb6, 0xcc, 0xe4,
|
||||
0x27, 0x81, 0x89, 0x38, 0x38, 0x68, 0x33, 0xe7, 0x78, 0xd8, 0x76, 0xf5, 0xee, 0xd0, 0x4a,
|
||||
0x07, 0x69, 0x19, 0x7a, 0xad, 0x18, 0xb1, 0x94, 0x61, 0x45, 0x53, 0xa2, 0x48, 0xda, 0x96,
|
||||
0x4a, 0xf9, 0xee, 0x94, 0x2a, 0x1f, 0x6e, 0x18, 0x3c, 0x92, 0x46, 0xd1, 0x1a, 0x28, 0x18,
|
||||
0x32, 0x1f, 0x3a, 0x45, 0xbe, 0x04, 0x35, 0x92, 0xe5, 0xa3, 0xcb, 0xb5, 0x2e, 0x32, 0x43,
|
||||
0xac, 0x65, 0x17, 0x89, 0x99, 0x15, 0x03, 0x9e, 0xb1, 0x23, 0x2f, 0xed, 0x76, 0x4d, 0xd8,
|
||||
0xac, 0x21, 0x40, 0xc4, 0x99, 0x4e, 0x65, 0x71, 0x2c, 0xb3, 0x45, 0xab, 0xfb, 0xe7, 0x72,
|
||||
0x39, 0x56, 0x30, 0x6d, 0xfb, 0x74, 0xeb, 0x99, 0xf3, 0xcd, 0x57, 0x5c, 0x78, 0x75, 0xe9,
|
||||
0x8d, 0xc3, 0xa2, 0xfb, 0x5d, 0xe0, 0x90, 0xc5, 0x55, 0xad, 0x91, 0x53, 0x4e, 0x9e, 0xbd,
|
||||
0x8c, 0x49, 0xa4, 0xa4, 0x69, 0x10, 0x0c, 0xc5, 0x76, 0xe9, 0x25, 0x86, 0x8d, 0x66, 0x23,
|
||||
0xa8, 0xdb, 0x5c, 0xe8, 0xd9, 0x30, 0xe1, 0x15, 0x7b, 0xc0, 0x99, 0x0f, 0x03, 0xec, 0xaa,
|
||||
0x12, 0xef, 0xce, 0xd4, 0xea, 0x55, 0x5c, 0x08, 0x86, 0xf4, 0xf4, 0xb0, 0x83, 0x42, 0x95,
|
||||
0x37, 0xb6, 0x38, 0xe0, 0x2b, 0x54, 0x89, 0xbd, 0x4e, 0x20, 0x9d, 0x3f, 0xc3, 0x4b, 0xb7,
|
||||
0xec, 0xfa, 0x5a, 0x14, 0x03, 0xcb, 0x64, 0xc8, 0x34, 0x4a, 0x4b, 0x6e, 0xf8, 0x6e, 0x56,
|
||||
0xf6, 0xdd, 0x5f, 0xa1, 0x24, 0xe2, 0xd4, 0xd0, 0x82, 0x64, 0x1f, 0x8e, 0x9b, 0xfa, 0xb4,
|
||||
0xcb, 0xdb, 0x0a, 0xe8, 0x15, 0xfc, 0x15, 0xab, 0x4b, 0x18, 0xbf, 0xd4, 0x42, 0x14, 0x48,
|
||||
0x82, 0x85, 0xdd, 0xeb, 0x49, 0x1b, 0x0b, 0x0b, 0x05, 0xe9, 0xb4, 0xa1, 0x33, 0x0a, 0x5d,
|
||||
0x0e, 0x6c, 0x4b, 0xc0, 0xd6, 0x6c, 0x7c, 0xfb, 0x69, 0x0b, 0x53, 0x19, 0xe4, 0xf3, 0x35,
|
||||
0xfc, 0xbe, 0xa1, 0x34, 0x02, 0x09, 0x4f, 0x74, 0x86, 0x92, 0xcd, 0x5d, 0x1a, 0xc1, 0x27,
|
||||
0x0c, 0xf2, 0xc5, 0xcf, 0xdd, 0x23, 0x93, 0x02, 0xbd, 0x41, 0x5e, 0x42, 0xf0, 0xa0, 0x9d,
|
||||
0x0c, 0x72, 0xc8, 0xec, 0x32, 0x0a, 0x8a, 0xfd, 0x3d, 0x5a, 0x41, 0x27, 0x0c, 0x88, 0x59,
|
||||
0xad, 0x94, 0x2e, 0xef, 0x5d, 0x8f, 0xc7, 0xdf, 0x66, 0xe4, 0xdd, 0x56, 0x6c, 0x7b, 0xca,
|
||||
0x55, 0x81, 0xae, 0xae, 0x5c, 0x1b, 0x1a, 0xab, 0xae, 0x99, 0x8d, 0xcc, 0x42, 0x97, 0x59,
|
||||
0xf4, 0x14, 0x3f, 0x75, 0xc6, 0xd1, 0x88, 0xba, 0xaa, 0x84, 0x4a, 0xd0, 0x34, 0x08, 0x3b,
|
||||
0x7d, 0xdb, 0x15, 0x06, 0xb0, 0x5c, 0xbd, 0x40, 0xf5, 0xa8, 0xec, 0xae, 0x36, 0x40, 0xdd,
|
||||
0x90, 0x1c, 0x3e, 0x0d, 0x7e, 0x73, 0xc7, 0xc2, 0xc5, 0x6a, 0xff, 0x52, 0x05, 0x7f, 0xbe,
|
||||
0xd0, 0x92, 0xfd, 0xb3, 0x6f, 0xff, 0x5d, 0xb7, 0x97, 0x64, 0x73, 0x7b, 0xca, 0xd1, 0x98,
|
||||
0x24, 0x6b, 0x0b, 0x01, 0x68, 0xdd, 0x27, 0x85, 0x85, 0xb5, 0x83, 0xc1, 0xe0, 0x50, 0x64,
|
||||
0xc7, 0xaf, 0xf1, 0xc6, 0x4d, 0xb1, 0xef, 0xc9, 0xb4, 0x0a, 0x6d, 0x65, 0xf3, 0x47, 0xcc,
|
||||
0xa3, 0x02, 0x21, 0x0c, 0xbe, 0x22, 0x29, 0x05, 0xcf, 0x5f, 0xe8, 0x94, 0x6c, 0xe5, 0xdc,
|
||||
0xc4, 0xdf, 0xbe, 0x3e, 0xa8, 0xb4, 0x18, 0xb0, 0x99, 0xb8, 0x6f, 0xff, 0x5d, 0xb9, 0xfd,
|
||||
0x3b, 0x5d, 0x16, 0xbf, 0x3e, 0xd8, 0xb3, 0xd8, 0x08, 0x34, 0xf6, 0x47, 0x35, 0x5b, 0x72,
|
||||
0x1a, 0x33, 0xad, 0x52, 0x5d, 0xb8, 0xd0, 0x77, 0xc6, 0xab, 0xba, 0x55, 0x09, 0x5f, 0x02,
|
||||
0xf8, 0xd4, 0x5f, 0x53, 0x06, 0x91, 0xcd, 0x74, 0x42, 0xae, 0x54, 0x91, 0x81, 0x62, 0x13,
|
||||
0x6f, 0xd8, 0xa9, 0x77, 0xc3, 0x6c, 0xcb, 0xf1, 0x29, 0x5a, 0xcc, 0xda, 0x35, 0xbd, 0x52,
|
||||
0x23, 0xbe, 0x59, 0xeb, 0x12, 0x6d, 0xb7, 0x53, 0xee, 0xfc, 0xb4, 0x1b, 0x13, 0x5e, 0xba,
|
||||
0x16, 0x7c, 0xc5, 0xf3, 0xe3, 0x6d, 0x07, 0x78, 0xf5, 0x2b, 0x21, 0x05, 0x88, 0x4c, 0xc0,
|
||||
0xa1, 0xe3, 0x36, 0x10, 0xf8, 0x1b, 0xd8, 0x17, 0xfb, 0x6a, 0x4e, 0xd8, 0xb3, 0x47, 0x2d,
|
||||
0x99, 0xbd, 0xbb, 0x5d, 0x37, 0x7d, 0xba, 0xf1, 0xe1, 0x7c, 0xc0, 0xc5, 0x54, 0x62, 0x7f,
|
||||
0xcf, 0x5a, 0x4a, 0x93, 0xcc, 0xf1, 0x1b, 0x34, 0xc8, 0xa6, 0x05, 0x4c, 0x55, 0x8b, 0x54,
|
||||
0x84, 0xd5, 0x77, 0xeb, 0xc0, 0x6d, 0x3a, 0x29, 0xbd, 0x75, 0x61, 0x09, 0x9a, 0x2c, 0xbb,
|
||||
0xf7, 0x18, 0x79, 0x34, 0x90, 0x24, 0xa5, 0x81, 0x70, 0x87, 0xc5, 0x02, 0x7c, 0xba, 0xd4,
|
||||
0x5e, 0x14, 0x8e, 0xe4, 0xed, 0xa2, 0x61, 0x6a, 0xb9, 0x6e, 0xb5, 0x4a, 0xb9, 0x01, 0x46,
|
||||
0xf4, 0xcf, 0xbc, 0x09, 0x2f, 0x27, 0x4b, 0xbd, 0x86, 0x7a, 0x10, 0xe1, 0xd4, 0xc8, 0xd9,
|
||||
0x20, 0x8d, 0x8a, 0x63, 0x00, 0x63, 0x44, 0xeb, 0x54, 0x0b, 0x75, 0x49, 0x10, 0xa2, 0xa7,
|
||||
0xad, 0xb9, 0xd1, 0x01, 0x80, 0x63, 0x25, 0xc8, 0x12, 0xa6, 0xce, 0x1e, 0xbe, 0xfe, 0x7e,
|
||||
0x5f, 0x3c, 0xdb, 0x34, 0xea, 0x37, 0xec, 0x3b, 0xd5, 0x28, 0xd2, 0x07, 0x8c, 0x9a, 0xb6,
|
||||
0xee, 0x5e, 0x3e, 0xdf, 0x1d, 0x99, 0xb0, 0xe2, 0x46, 0xef, 0x5c, 0x1b, 0xb4, 0xea, 0x56,
|
||||
0x2e, 0xde, 0x1f, 0x9d, 0xb8, 0xd3, 0x24, 0xab, 0xd4, 0x2a, 0xd6, 0x2e, 0xde, 0x1f, 0x9d,
|
||||
0xb8, 0xf2, 0x66, 0x2f, 0xbd, 0xf8, 0x72, 0x66, 0x4e, 0x1e, 0x9f, 0x9d, 0xb8, 0xf2, 0x47,
|
||||
0x0c, 0x9a, 0xb6, 0xee, 0x3f, 0xfc, 0x7a, 0x57, 0x0d, 0x79, 0x70, 0x62, 0x27, 0xad, 0xb9,
|
||||
0xd1, 0x01, 0x61, 0x40, 0x02, 0x67, 0x2d, 0xd8, 0x32, 0xe6, 0x2f, 0xdc, 0x3a, 0xd7, 0x2c,
|
||||
0xbb, 0xf4, 0x4b, 0xf5, 0x49, 0xf1, 0x60, 0x23, 0xc4, 0x0a, 0x77, 0x4d, 0xf9, 0x51, 0x01,
|
||||
0x80, 0x63, 0x25, 0xa9, 0xb1, 0xe0, 0x42, 0xe7, 0x4c, 0x1a, 0x97, 0xac, 0xbb, 0xf4, 0x6a,
|
||||
0x37, 0xcd, 0x18, 0xb2, 0xe6, 0x2f, 0xdc, 0x1b, 0x95, 0xa8, 0xd2, 0x07, 0x6d, 0x58, 0x32,
|
||||
0xe6, 0x4e, 0x1e, 0x9f, 0xbc, 0xfa, 0x57, 0x0d, 0x79, 0x51, 0x20, 0xc2, 0x06, 0x6f, 0x5c,
|
||||
0x1b, 0x95, 0xa8, 0xb3, 0xc5, 0xe9, 0x31, 0xe0, 0x23, 0xc4, 0x0a, 0x77, 0x4d, 0x18, 0x93,
|
||||
0x85, 0x69, 0x31, 0xc1, 0xe1, 0x21, 0xc0, 0xe3, 0x44, 0x0a, 0x77, 0x6c, 0x5a, 0x17, 0x8d,
|
||||
0x98, 0x93, 0xa4, 0xab, 0xd4, 0x2a, 0xb7, 0xec, 0x5a, 0x17, 0xac, 0xbb, 0xf4, 0x4b, 0x14,
|
||||
0xaa, 0xb7, 0xec, 0x3b, 0xd5, 0x28, 0xb3, 0xc5, 0xe9, 0x31, 0xc1, 0x00, 0x82, 0x67, 0x4c,
|
||||
0xfb, 0x55, 0x28, 0xd2, 0x26, 0xaf, 0xbd, 0xd9, 0x11, 0x81, 0x61, 0x21, 0xa1, 0xa1, 0xc0,
|
||||
0x02, 0x86, 0x6f, 0x5c, 0x1b, 0xb4, 0xcb, 0x14, 0x8b, 0x94, 0xaa, 0xd6, 0x2e, 0xbf, 0xdd,
|
||||
0x19, 0xb0, 0xe2, 0x46, 0x0e, 0x7f, 0x7c, 0x5b, 0x15, 0x89, 0x90, 0x83, 0x84, 0x6b, 0x54,
|
||||
0x0b, 0x75, 0x68, 0x52, 0x07, 0x6d, 0x58, 0x32, 0xc7, 0xed, 0x58, 0x32, 0xc7, 0xed, 0x58,
|
||||
0x32, 0xe6, 0x4e, 0xff, 0x7c, 0x7a, 0x76, 0x6e, 0x3f, 0xdd, 0x38, 0xd3, 0x05, 0x88, 0x92,
|
||||
0xa6, 0xaf, 0xdc, 0x1b, 0xb4, 0xcb, 0xf5, 0x68, 0x52, 0x07, 0x8c, 0x7b, 0x55, 0x09, 0x90,
|
||||
0x83, 0x84, 0x6b, 0x54, 0x2a, 0xb7, 0xec, 0x3b, 0xd5, 0x09, 0x90, 0xa2, 0xc6, 0x0e, 0x7f,
|
||||
0x7c, 0x7a, 0x57, 0x0d, 0x98, 0xb2, 0xc7, 0xed, 0x58, 0x32, 0xc7, 0x0c, 0x7b, 0x74, 0x4b,
|
||||
0x14, 0x8b, 0x94, 0xaa, 0xb7, 0xcd, 0x18, 0x93, 0xa4, 0xca, 0x16, 0xae, 0xbf, 0xdd, 0x19,
|
||||
0xb0, 0xe2, 0x46, 0x0e, 0x7f, 0x5d, 0x19, 0x91, 0x81, 0x80, 0x63, 0x44, 0xeb, 0x35, 0xc9,
|
||||
0x10, 0x83, 0x65, 0x48, 0x12, 0xa6, 0xce, 0x1e, 0x9f, 0xbc, 0xdb, 0x15, 0x89, 0x71, 0x60,
|
||||
0x23, 0xc4, 0xeb, 0x54, 0x2a, 0xb7, 0xec, 0x5a, 0x36, 0xcf, 0x81, 0x10, 0xac, 0x74 };
|
||||
|
||||
// clang-format off
|
||||
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 Fred Sundvik <fsundvik@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _GDISP_LLD_BOARD_H
|
||||
#define _GDISP_LLD_BOARD_H
|
||||
|
||||
static const I2CConfig i2ccfg = {
|
||||
400000 // clock speed (Hz); 400kHz max for IS31
|
||||
};
|
||||
|
||||
static const uint8_t led_mask[] = {
|
||||
0xFF, 0x00, /* C1-1 -> C1-16 */
|
||||
0xFF, 0x00, /* C2-1 -> C2-16 */
|
||||
0xFF, 0x00, /* C3-1 -> C3-16 */
|
||||
0xFF, 0x00, /* C4-1 -> C4-16 */
|
||||
0x3F, 0x00, /* C5-1 -> C5-16 */
|
||||
0x00, 0x00, /* C6-1 -> C6-16 */
|
||||
0x00, 0x00, /* C7-1 -> C7-16 */
|
||||
0x00, 0x00, /* C8-1 -> C8-16 */
|
||||
0x00, 0x00, /* C9-1 -> C9-16 */
|
||||
};
|
||||
|
||||
// The address of the LED
|
||||
#define LA(c, r) (c + r * 16)
|
||||
// Need to be an address that is not mapped, but inside the range of the controller matrix
|
||||
#define NA LA(8, 8)
|
||||
|
||||
// The numbers in the comments are the led numbers DXX on the PCB
|
||||
// The mapping is taken from the schematic of left hand side
|
||||
static const uint8_t led_mapping[GDISP_SCREEN_HEIGHT][GDISP_SCREEN_WIDTH] = {
|
||||
// 45 44 43 42 41 40 39
|
||||
{LA(1, 1), LA(1, 0), LA(0, 4), LA(0, 3), LA(0, 2), LA(0, 1), LA(0, 0)},
|
||||
// 52 51 50 49 48 47 46
|
||||
{LA(2, 3), LA(2, 2), LA(2, 1), LA(2, 0), LA(1, 4), LA(1, 3), LA(1, 2)},
|
||||
// 58 57 56 55 54 53 N/A
|
||||
{LA(3, 4), LA(3, 3), LA(3, 2), LA(3, 1), LA(3, 0), LA(2, 4), NA},
|
||||
// 67 66 65 64 63 62 61
|
||||
{LA(5, 3), LA(5, 2), LA(5, 1), LA(5, 0), LA(4, 4), LA(4, 3), LA(4, 2)},
|
||||
// 76 75 74 73 72 60 59
|
||||
{LA(7, 3), LA(7, 2), LA(7, 1), LA(7, 0), LA(6, 3), LA(4, 1), LA(4, 0)},
|
||||
// N/A N/A N/A N/A N/A N/A 68
|
||||
{NA, NA, NA, NA, NA, NA, LA(5, 4)},
|
||||
// N/A N/A N/A N/A 71 70 69
|
||||
{NA, NA, NA, NA, LA(6, 2), LA(6, 1), LA(6, 0)},
|
||||
};
|
||||
|
||||
#define IS31_ADDR_DEFAULT 0x74 // AD connected to GND
|
||||
#define IS31_TIMEOUT 5000
|
||||
|
||||
static GFXINLINE void init_board(GDisplay* g) {
|
||||
(void)g;
|
||||
/* I2C pins */
|
||||
palSetPadMode(GPIOB, 0, PAL_MODE_ALTERNATIVE_2); // PTB0/I2C0/SCL
|
||||
palSetPadMode(GPIOB, 1, PAL_MODE_ALTERNATIVE_2); // PTB1/I2C0/SDA
|
||||
palSetPadMode(GPIOB, 16, PAL_MODE_OUTPUT_PUSHPULL);
|
||||
palClearPad(GPIOB, 16);
|
||||
/* start I2C */
|
||||
i2cStart(&I2CD1, &i2ccfg);
|
||||
// try high drive (from kiibohd)
|
||||
I2CD1.i2c->C2 |= I2Cx_C2_HDRS;
|
||||
// try glitch fixing (from kiibohd)
|
||||
I2CD1.i2c->FLT = 4;
|
||||
}
|
||||
|
||||
static GFXINLINE void post_init_board(GDisplay* g) { (void)g; }
|
||||
|
||||
static GFXINLINE const uint8_t* get_led_mask(GDisplay* g) {
|
||||
(void)g;
|
||||
return led_mask;
|
||||
}
|
||||
|
||||
static GFXINLINE uint8_t get_led_address(GDisplay* g, uint16_t x, uint16_t y) {
|
||||
(void)g;
|
||||
return led_mapping[y][x];
|
||||
}
|
||||
|
||||
static GFXINLINE void set_hardware_shutdown(GDisplay* g, bool shutdown) {
|
||||
(void)g;
|
||||
if (!shutdown) {
|
||||
palSetPad(GPIOB, 16);
|
||||
} else {
|
||||
palClearPad(GPIOB, 16);
|
||||
}
|
||||
}
|
||||
|
||||
static GFXINLINE void write_data(GDisplay* g, uint8_t* data, uint16_t length) {
|
||||
(void)g;
|
||||
i2cMasterTransmitTimeout(&I2CD1, IS31_ADDR_DEFAULT, data, length, 0, 0, US2ST(IS31_TIMEOUT));
|
||||
}
|
||||
|
||||
#endif /* _GDISP_LLD_BOARD_H */
|
||||
@@ -1,3 +0,0 @@
|
||||
GFXINC += drivers/ugfx/gdisp/is31fl3731c
|
||||
GFXSRC += drivers/ugfx/gdisp/is31fl3731c/gdisp_is31fl3731c.c
|
||||
GDISP_DRIVER_LIST += GDISPVMT_IS31FL3731C_QMK
|
||||
@@ -1,302 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 Fred Sundvik <fsundvik@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "gfx.h"
|
||||
|
||||
#if GFX_USE_GDISP
|
||||
|
||||
# define GDISP_DRIVER_VMT GDISPVMT_IS31FL3731C_QMK
|
||||
# define GDISP_SCREEN_HEIGHT LED_HEIGHT
|
||||
# define GDISP_SCREEN_WIDTH LED_WIDTH
|
||||
|
||||
# include "gdisp_lld_config.h"
|
||||
# include "src/gdisp/gdisp_driver.h"
|
||||
|
||||
# include "board_is31fl3731c.h"
|
||||
|
||||
// Can't include led_tables from here
|
||||
extern const uint8_t CIE1931_CURVE[];
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
# ifndef GDISP_INITIAL_CONTRAST
|
||||
# define GDISP_INITIAL_CONTRAST 0
|
||||
# endif
|
||||
# ifndef GDISP_INITIAL_BACKLIGHT
|
||||
# define GDISP_INITIAL_BACKLIGHT 0
|
||||
# endif
|
||||
|
||||
# define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER << 0)
|
||||
|
||||
# define IS31_ADDR_DEFAULT 0x74
|
||||
|
||||
# define IS31_REG_CONFIG 0x00
|
||||
// bits in reg
|
||||
# define IS31_REG_CONFIG_PICTUREMODE 0x00
|
||||
# define IS31_REG_CONFIG_AUTOPLAYMODE 0x08
|
||||
# define IS31_REG_CONFIG_AUDIOPLAYMODE 0x18
|
||||
// D2:D0 bits are starting frame for autoplay mode
|
||||
|
||||
# define IS31_REG_PICTDISP 0x01 // D2:D0 frame select for picture mode
|
||||
|
||||
# define IS31_REG_AUTOPLAYCTRL1 0x02
|
||||
// D6:D4 number of loops (000=infty)
|
||||
// D2:D0 number of frames to be used
|
||||
|
||||
# define IS31_REG_AUTOPLAYCTRL2 0x03 // D5:D0 delay time (*11ms)
|
||||
|
||||
# define IS31_REG_DISPLAYOPT 0x05
|
||||
# define IS31_REG_DISPLAYOPT_INTENSITY_SAME 0x20 // same intensity for all frames
|
||||
# define IS31_REG_DISPLAYOPT_BLINK_ENABLE 0x8
|
||||
// D2:D0 bits blink period time (*0.27s)
|
||||
|
||||
# define IS31_REG_AUDIOSYNC 0x06
|
||||
# define IS31_REG_AUDIOSYNC_ENABLE 0x1
|
||||
|
||||
# define IS31_REG_FRAMESTATE 0x07
|
||||
|
||||
# define IS31_REG_BREATHCTRL1 0x08
|
||||
// D6:D4 fade out time (26ms*2^i)
|
||||
// D2:D0 fade in time (26ms*2^i)
|
||||
|
||||
# define IS31_REG_BREATHCTRL2 0x09
|
||||
# define IS31_REG_BREATHCTRL2_ENABLE 0x10
|
||||
// D2:D0 extinguish time (3.5ms*2^i)
|
||||
|
||||
# define IS31_REG_SHUTDOWN 0x0A
|
||||
# define IS31_REG_SHUTDOWN_OFF 0x0
|
||||
# define IS31_REG_SHUTDOWN_ON 0x1
|
||||
|
||||
# define IS31_REG_AGCCTRL 0x0B
|
||||
# define IS31_REG_ADCRATE 0x0C
|
||||
|
||||
# define IS31_COMMANDREGISTER 0xFD
|
||||
# define IS31_FUNCTIONREG 0x0B // helpfully called 'page nine'
|
||||
# define IS31_FUNCTIONREG_SIZE 0xD
|
||||
|
||||
# define IS31_FRAME_SIZE 0xB4
|
||||
|
||||
# define IS31_PWM_REG 0x24
|
||||
# define IS31_PWM_SIZE 0x90
|
||||
|
||||
# define IS31_LED_MASK_SIZE 0x12
|
||||
|
||||
# define IS31
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
typedef struct {
|
||||
uint8_t write_buffer_offset;
|
||||
uint8_t write_buffer[IS31_FRAME_SIZE];
|
||||
uint8_t frame_buffer[GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH];
|
||||
uint8_t page;
|
||||
} __attribute__((__packed__)) PrivData;
|
||||
|
||||
// Some common routines and macros
|
||||
# define PRIV(g) ((PrivData *)g->priv)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
static GFXINLINE void write_page(GDisplay *g, uint8_t page) {
|
||||
uint8_t tx[2] __attribute__((aligned(2)));
|
||||
tx[0] = IS31_COMMANDREGISTER;
|
||||
tx[1] = page;
|
||||
write_data(g, tx, 2);
|
||||
}
|
||||
|
||||
static GFXINLINE void write_register(GDisplay *g, uint8_t page, uint8_t reg, uint8_t data) {
|
||||
uint8_t tx[2] __attribute__((aligned(2)));
|
||||
tx[0] = reg;
|
||||
tx[1] = data;
|
||||
write_page(g, page);
|
||||
write_data(g, tx, 2);
|
||||
}
|
||||
|
||||
static GFXINLINE void write_ram(GDisplay *g, uint8_t page, uint16_t offset, uint16_t length) {
|
||||
PRIV(g)->write_buffer_offset = offset;
|
||||
write_page(g, page);
|
||||
write_data(g, (uint8_t *)PRIV(g), length + 1);
|
||||
}
|
||||
|
||||
LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||
// The private area is the display surface.
|
||||
g->priv = gfxAlloc(sizeof(PrivData));
|
||||
__builtin_memset(PRIV(g), 0, sizeof(PrivData));
|
||||
PRIV(g)->page = 0;
|
||||
|
||||
// Initialise the board interface
|
||||
init_board(g);
|
||||
gfxSleepMilliseconds(10);
|
||||
|
||||
// zero function page, all registers (assuming full_page is all zeroes)
|
||||
write_ram(g, IS31_FUNCTIONREG, 0, IS31_FUNCTIONREG_SIZE);
|
||||
set_hardware_shutdown(g, false);
|
||||
gfxSleepMilliseconds(10);
|
||||
// software shutdown
|
||||
write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_OFF);
|
||||
gfxSleepMilliseconds(10);
|
||||
// zero function page, all registers
|
||||
write_ram(g, IS31_FUNCTIONREG, 0, IS31_FUNCTIONREG_SIZE);
|
||||
gfxSleepMilliseconds(10);
|
||||
|
||||
// zero all LED registers on all 8 pages, and enable the mask
|
||||
__builtin_memcpy(PRIV(g)->write_buffer, get_led_mask(g), IS31_LED_MASK_SIZE);
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
write_ram(g, i, 0, IS31_FRAME_SIZE);
|
||||
gfxSleepMilliseconds(1);
|
||||
}
|
||||
|
||||
// software shutdown disable (i.e. turn stuff on)
|
||||
write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_OFF);
|
||||
gfxSleepMilliseconds(10);
|
||||
|
||||
// Finish Init
|
||||
post_init_board(g);
|
||||
|
||||
/* Initialise the GDISP structure */
|
||||
g->g.Width = GDISP_SCREEN_WIDTH;
|
||||
g->g.Height = GDISP_SCREEN_HEIGHT;
|
||||
g->g.Orientation = GDISP_ROTATE_0;
|
||||
g->g.Powermode = powerOff;
|
||||
g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
|
||||
g->g.Contrast = GDISP_INITIAL_CONTRAST;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
# if GDISP_HARDWARE_FLUSH
|
||||
LLDSPEC void gdisp_lld_flush(GDisplay *g) {
|
||||
// Don't flush if we don't need it.
|
||||
if (!(g->flags & GDISP_FLG_NEEDFLUSH)) return;
|
||||
|
||||
PRIV(g)->page++;
|
||||
PRIV(g)->page %= 2;
|
||||
// TODO: some smarter algorithm for this
|
||||
// We should run only one physical page at a time
|
||||
// This way we don't need to send so much data, and
|
||||
// we could use slightly less memory
|
||||
uint8_t *src = PRIV(g)->frame_buffer;
|
||||
for (int y = 0; y < GDISP_SCREEN_HEIGHT; y++) {
|
||||
for (int x = 0; x < GDISP_SCREEN_WIDTH; x++) {
|
||||
uint8_t val = (uint16_t)*src * g->g.Backlight / 100;
|
||||
PRIV(g)->write_buffer[get_led_address(g, x, y)] = CIE1931_CURVE[val];
|
||||
++src;
|
||||
}
|
||||
}
|
||||
write_ram(g, PRIV(g)->page, IS31_PWM_REG, IS31_PWM_SIZE);
|
||||
gfxSleepMilliseconds(1);
|
||||
write_register(g, IS31_FUNCTIONREG, IS31_REG_PICTDISP, PRIV(g)->page);
|
||||
|
||||
g->flags &= ~GDISP_FLG_NEEDFLUSH;
|
||||
}
|
||||
# endif
|
||||
|
||||
# if GDISP_HARDWARE_DRAWPIXEL
|
||||
LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
|
||||
coord_t x, y;
|
||||
|
||||
switch (g->g.Orientation) {
|
||||
default:
|
||||
case GDISP_ROTATE_0:
|
||||
x = g->p.x;
|
||||
y = g->p.y;
|
||||
break;
|
||||
case GDISP_ROTATE_180:
|
||||
x = GDISP_SCREEN_WIDTH - 1 - g->p.x;
|
||||
y = g->p.y;
|
||||
break;
|
||||
}
|
||||
PRIV(g)->frame_buffer[y * GDISP_SCREEN_WIDTH + x] = gdispColor2Native(g->p.color);
|
||||
g->flags |= GDISP_FLG_NEEDFLUSH;
|
||||
}
|
||||
# endif
|
||||
|
||||
# if GDISP_HARDWARE_PIXELREAD
|
||||
LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) {
|
||||
coord_t x, y;
|
||||
|
||||
switch (g->g.Orientation) {
|
||||
default:
|
||||
case GDISP_ROTATE_0:
|
||||
x = g->p.x;
|
||||
y = g->p.y;
|
||||
break;
|
||||
case GDISP_ROTATE_180:
|
||||
x = GDISP_SCREEN_WIDTH - 1 - g->p.x;
|
||||
y = g->p.y;
|
||||
break;
|
||||
}
|
||||
return gdispNative2Color(PRIV(g)->frame_buffer[y * GDISP_SCREEN_WIDTH + x]);
|
||||
}
|
||||
# endif
|
||||
|
||||
# if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
|
||||
LLDSPEC void gdisp_lld_control(GDisplay *g) {
|
||||
switch (g->p.x) {
|
||||
case GDISP_CONTROL_POWER:
|
||||
if (g->g.Powermode == (powermode_t)g->p.ptr) return;
|
||||
switch ((powermode_t)g->p.ptr) {
|
||||
case powerOff:
|
||||
case powerSleep:
|
||||
case powerDeepSleep:
|
||||
write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_OFF);
|
||||
break;
|
||||
case powerOn:
|
||||
write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_ON);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
g->g.Powermode = (powermode_t)g->p.ptr;
|
||||
return;
|
||||
|
||||
case GDISP_CONTROL_ORIENTATION:
|
||||
if (g->g.Orientation == (orientation_t)g->p.ptr) return;
|
||||
switch ((orientation_t)g->p.ptr) {
|
||||
/* Rotation is handled by the drawing routines */
|
||||
case GDISP_ROTATE_0:
|
||||
case GDISP_ROTATE_180:
|
||||
g->g.Height = GDISP_SCREEN_HEIGHT;
|
||||
g->g.Width = GDISP_SCREEN_WIDTH;
|
||||
break;
|
||||
case GDISP_ROTATE_90:
|
||||
case GDISP_ROTATE_270:
|
||||
g->g.Height = GDISP_SCREEN_WIDTH;
|
||||
g->g.Width = GDISP_SCREEN_HEIGHT;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
g->g.Orientation = (orientation_t)g->p.ptr;
|
||||
return;
|
||||
|
||||
case GDISP_CONTROL_BACKLIGHT:
|
||||
if (g->g.Backlight == (unsigned)g->p.ptr) return;
|
||||
unsigned val = (unsigned)g->p.ptr;
|
||||
g->g.Backlight = val > 100 ? 100 : val;
|
||||
g->flags |= GDISP_FLG_NEEDFLUSH;
|
||||
return;
|
||||
}
|
||||
}
|
||||
# endif // GDISP_NEED_CONTROL
|
||||
|
||||
#endif // GFX_USE_GDISP
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 Fred Sundvik <fsundvik@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _GDISP_LLD_CONFIG_H
|
||||
#define _GDISP_LLD_CONFIG_H
|
||||
|
||||
#if GFX_USE_GDISP
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver hardware support. */
|
||||
/*===========================================================================*/
|
||||
|
||||
# define GDISP_HARDWARE_FLUSH GFXON // This controller requires flushing
|
||||
# define GDISP_HARDWARE_DRAWPIXEL GFXON
|
||||
# define GDISP_HARDWARE_PIXELREAD GFXON
|
||||
# define GDISP_HARDWARE_CONTROL GFXON
|
||||
|
||||
# define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_GRAY256
|
||||
|
||||
#endif /* GFX_USE_GDISP */
|
||||
|
||||
#endif /* _GDISP_LLD_CONFIG_H */
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* This file is subject to the terms of the GFX License. If a copy of
|
||||
* the license was not distributed with this file, you can obtain one at:
|
||||
*
|
||||
* http://ugfx.org/license.html
|
||||
*/
|
||||
|
||||
#ifndef _GDISP_LLD_BOARD_H
|
||||
#define _GDISP_LLD_BOARD_H
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
#define ST7565_LCD_BIAS ST7565_LCD_BIAS_7
|
||||
#define ST7565_COM_SCAN ST7565_COM_SCAN_DEC
|
||||
#define ST7565_PAGE_ORDER 0, 1, 2, 3
|
||||
/*
|
||||
* Custom page order for several LCD boards, e.g. HEM12864-99
|
||||
* #define ST7565_PAGE_ORDER 4,5,6,7,0,1,2,3
|
||||
*/
|
||||
|
||||
#define ST7565_A0_PIN C7
|
||||
#define ST7565_RST_PIN C8
|
||||
#define ST7565_MOSI_PIN C6
|
||||
#define ST7565_SCLK_PIN C5
|
||||
#define ST7565_SS_PIN C4
|
||||
|
||||
// DSPI Clock and Transfer Attributes
|
||||
// Frame Size: 8 bits
|
||||
// MSB First
|
||||
// CLK Low by default
|
||||
static const SPIConfig spi1config = {
|
||||
// Operation complete callback or @p NULL.
|
||||
.end_cb = NULL,
|
||||
// The chip select line port - when not using pcs.
|
||||
.ssport = PAL_PORT(ST7565_SS_PIN),
|
||||
// brief The chip select line pad number - when not using pcs.
|
||||
.sspad = PAL_PAD(ST7565_SS_PIN),
|
||||
// SPI initialization data.
|
||||
.tar0 = SPIx_CTARn_FMSZ(7) // Frame size = 8 bytes
|
||||
| SPIx_CTARn_ASC(1) // After SCK Delay Scaler (min 50 ns) = 55.56ns
|
||||
| SPIx_CTARn_DT(0) // Delay After Transfer Scaler (no minimum)= 27.78ns
|
||||
| SPIx_CTARn_CSSCK(0) // PCS to SCK Delay Scaler (min 20 ns) = 27.78ns
|
||||
| SPIx_CTARn_PBR(0) // Baud Rate Prescaler = 2
|
||||
| SPIx_CTARn_BR(0) // Baud rate (min 50ns) = 55.56ns
|
||||
};
|
||||
|
||||
static GFXINLINE void acquire_bus(GDisplay *g) {
|
||||
(void)g;
|
||||
// Only the LCD is using the SPI bus, so no need to acquire
|
||||
// spiAcquireBus(&SPID1);
|
||||
spiSelect(&SPID1);
|
||||
}
|
||||
|
||||
static GFXINLINE void release_bus(GDisplay *g) {
|
||||
(void)g;
|
||||
// Only the LCD is using the SPI bus, so no need to release
|
||||
// spiReleaseBus(&SPID1);
|
||||
spiUnselect(&SPID1);
|
||||
}
|
||||
|
||||
static GFXINLINE void init_board(GDisplay *g) {
|
||||
(void)g;
|
||||
setPinOutput(ST7565_A0_PIN);
|
||||
writePinHigh(ST7565_A0_PIN);
|
||||
setPinOutput(ST7565_RST_PIN);
|
||||
writePinHigh(ST7565_RST_PIN);
|
||||
setPinOutput(ST7565_SS_PIN);
|
||||
|
||||
palSetPadMode(PAL_PORT(ST7565_MOSI_PIN), PAL_PAD(ST7565_MOSI_PIN), PAL_MODE_ALTERNATIVE_2);
|
||||
palSetPadMode(PAL_PORT(ST7565_SCLK_PIN), PAL_PAD(ST7565_SCLK_PIN), PAL_MODE_ALTERNATIVE_2);
|
||||
|
||||
spiInit();
|
||||
spiStart(&SPID1, &spi1config);
|
||||
release_bus(g);
|
||||
}
|
||||
|
||||
static GFXINLINE void post_init_board(GDisplay *g) { (void)g; }
|
||||
|
||||
static GFXINLINE void setpin_reset(GDisplay *g, bool_t state) {
|
||||
(void)g;
|
||||
writePin(ST7565_RST_PIN, !state);
|
||||
}
|
||||
|
||||
static GFXINLINE void write_cmd(GDisplay *g, gU8 cmd) {
|
||||
(void)g;
|
||||
writePinLow(ST7565_A0_PIN);
|
||||
spiSend(&SPID1, 1, &cmd);
|
||||
}
|
||||
|
||||
static GFXINLINE void write_data(GDisplay *g, gU8 *data, gU16 length) {
|
||||
(void)g;
|
||||
writePinHigh(ST7565_A0_PIN);
|
||||
spiSend(&SPID1, length, data);
|
||||
}
|
||||
|
||||
#endif /* _GDISP_LLD_BOARD_H */
|
||||
@@ -1,3 +0,0 @@
|
||||
GFXINC += drivers/ugfx/gdisp/st7565
|
||||
GFXSRC += drivers/ugfx/gdisp/st7565/gdisp_lld_ST7565.c
|
||||
GDISP_DRIVER_LIST += GDISPVMT_ST7565_QMK
|
||||
@@ -1,314 +0,0 @@
|
||||
/*
|
||||
* This file is subject to the terms of the GFX License. If a copy of
|
||||
* the license was not distributed with this file, you can obtain one at:
|
||||
*
|
||||
* http://ugfx.org/license.html
|
||||
*/
|
||||
|
||||
#include "gfx.h"
|
||||
|
||||
#if GFX_USE_GDISP
|
||||
|
||||
# define GDISP_DRIVER_VMT GDISPVMT_ST7565_QMK
|
||||
# include "gdisp_lld_config.h"
|
||||
# include "src/gdisp/gdisp_driver.h"
|
||||
|
||||
# include "board_st7565.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
# ifndef GDISP_SCREEN_HEIGHT
|
||||
# define GDISP_SCREEN_HEIGHT LCD_HEIGHT
|
||||
# endif
|
||||
# ifndef GDISP_SCREEN_WIDTH
|
||||
# define GDISP_SCREEN_WIDTH LCD_WIDTH
|
||||
# endif
|
||||
# ifndef GDISP_INITIAL_CONTRAST
|
||||
# define GDISP_INITIAL_CONTRAST 35
|
||||
# endif
|
||||
# ifndef GDISP_INITIAL_BACKLIGHT
|
||||
# define GDISP_INITIAL_BACKLIGHT 100
|
||||
# endif
|
||||
|
||||
# define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER << 0)
|
||||
|
||||
# include "st7565.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver config defaults for backward compatibility. */
|
||||
/*===========================================================================*/
|
||||
# ifndef ST7565_LCD_BIAS
|
||||
# define ST7565_LCD_BIAS ST7565_LCD_BIAS_7
|
||||
# endif
|
||||
# ifndef ST7565_ADC
|
||||
# define ST7565_ADC ST7565_ADC_NORMAL
|
||||
# endif
|
||||
# ifndef ST7565_COM_SCAN
|
||||
# define ST7565_COM_SCAN ST7565_COM_SCAN_INC
|
||||
# endif
|
||||
# ifndef ST7565_PAGE_ORDER
|
||||
# define ST7565_PAGE_ORDER 0, 1, 2, 3, 4, 5, 6, 7
|
||||
# endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
// Some common routines and macros
|
||||
# define RAM(g) ((gU8 *)g->priv)
|
||||
# define write_cmd2(g, cmd1, cmd2) \
|
||||
{ \
|
||||
write_cmd(g, cmd1); \
|
||||
write_cmd(g, cmd2); \
|
||||
}
|
||||
# define write_cmd3(g, cmd1, cmd2, cmd3) \
|
||||
{ \
|
||||
write_cmd(g, cmd1); \
|
||||
write_cmd(g, cmd2); \
|
||||
write_cmd(g, cmd3); \
|
||||
}
|
||||
|
||||
// Some common routines and macros
|
||||
# define delay(us) gfxSleepMicroseconds(us)
|
||||
# define delay_ms(ms) gfxSleepMilliseconds(ms)
|
||||
|
||||
# define xyaddr(x, y) ((x) + ((y) >> 3) * GDISP_SCREEN_WIDTH)
|
||||
# define xybit(y) (1 << ((y)&7))
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*
|
||||
* As this controller can't update on a pixel boundary we need to maintain the
|
||||
* the entire display surface in memory so that we can do the necessary bit
|
||||
* operations. Fortunately it is a small display in monochrome.
|
||||
* 64 * 128 / 8 = 1024 bytes.
|
||||
*/
|
||||
|
||||
LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||
// The private area is the display surface.
|
||||
g->priv = gfxAlloc(GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH / 8);
|
||||
if (!g->priv) {
|
||||
return gFalse;
|
||||
}
|
||||
|
||||
// Initialise the board interface
|
||||
init_board(g);
|
||||
|
||||
// Hardware reset
|
||||
setpin_reset(g, TRUE);
|
||||
gfxSleepMilliseconds(20);
|
||||
setpin_reset(g, FALSE);
|
||||
gfxSleepMilliseconds(20);
|
||||
acquire_bus(g);
|
||||
|
||||
write_cmd(g, ST7565_LCD_BIAS);
|
||||
write_cmd(g, ST7565_ADC);
|
||||
write_cmd(g, ST7565_COM_SCAN);
|
||||
|
||||
write_cmd(g, ST7565_START_LINE | 0);
|
||||
|
||||
write_cmd2(g, ST7565_CONTRAST, GDISP_INITIAL_CONTRAST * 64 / 101);
|
||||
write_cmd(g, ST7565_RESISTOR_RATIO | 0x1);
|
||||
|
||||
// turn on voltage converter (VC=1, VR=0, VF=0)
|
||||
write_cmd(g, ST7565_POWER_CONTROL | 0x04);
|
||||
delay_ms(50);
|
||||
|
||||
// turn on voltage regulator (VC=1, VR=1, VF=0)
|
||||
write_cmd(g, ST7565_POWER_CONTROL | 0x06);
|
||||
delay_ms(50);
|
||||
|
||||
// turn on voltage follower (VC=1, VR=1, VF=1)
|
||||
write_cmd(g, ST7565_POWER_CONTROL | 0x07);
|
||||
delay_ms(50);
|
||||
|
||||
write_cmd(g, ST7565_DISPLAY_ON);
|
||||
write_cmd(g, ST7565_ALLON_NORMAL);
|
||||
write_cmd(g, ST7565_INVERT_DISPLAY); // Disable Inversion of display.
|
||||
|
||||
write_cmd(g, ST7565_RMW);
|
||||
|
||||
// Finish Init
|
||||
post_init_board(g);
|
||||
|
||||
// Release the bus
|
||||
release_bus(g);
|
||||
|
||||
/* Initialise the GDISP structure */
|
||||
g->g.Width = GDISP_SCREEN_WIDTH;
|
||||
g->g.Height = GDISP_SCREEN_HEIGHT;
|
||||
g->g.Orientation = GDISP_ROTATE_0;
|
||||
g->g.Powermode = powerOff;
|
||||
g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
|
||||
g->g.Contrast = GDISP_INITIAL_CONTRAST;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
# if GDISP_HARDWARE_FLUSH
|
||||
LLDSPEC void gdisp_lld_flush(GDisplay *g) {
|
||||
unsigned p;
|
||||
|
||||
// Don't flush if we don't need it.
|
||||
if (!(g->flags & GDISP_FLG_NEEDFLUSH)) return;
|
||||
|
||||
acquire_bus(g);
|
||||
gU8 pagemap[] = {ST7565_PAGE_ORDER};
|
||||
for (p = 0; p < sizeof(pagemap); p++) {
|
||||
write_cmd(g, ST7565_PAGE | pagemap[p]);
|
||||
write_cmd(g, ST7565_COLUMN_MSB | 0);
|
||||
write_cmd(g, ST7565_COLUMN_LSB | 0);
|
||||
write_cmd(g, ST7565_RMW);
|
||||
write_data(g, RAM(g) + (p * GDISP_SCREEN_WIDTH), GDISP_SCREEN_WIDTH);
|
||||
}
|
||||
release_bus(g);
|
||||
|
||||
g->flags &= ~GDISP_FLG_NEEDFLUSH;
|
||||
}
|
||||
# endif
|
||||
|
||||
# if GDISP_HARDWARE_DRAWPIXEL
|
||||
LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
|
||||
coord_t x, y;
|
||||
|
||||
switch (g->g.Orientation) {
|
||||
default:
|
||||
case GDISP_ROTATE_0:
|
||||
x = g->p.x;
|
||||
y = g->p.y;
|
||||
break;
|
||||
case GDISP_ROTATE_90:
|
||||
x = g->p.y;
|
||||
y = GDISP_SCREEN_HEIGHT - 1 - g->p.x;
|
||||
break;
|
||||
case GDISP_ROTATE_180:
|
||||
x = GDISP_SCREEN_WIDTH - 1 - g->p.x;
|
||||
y = GDISP_SCREEN_HEIGHT - 1 - g->p.y;
|
||||
break;
|
||||
case GDISP_ROTATE_270:
|
||||
x = GDISP_SCREEN_HEIGHT - 1 - g->p.y;
|
||||
y = g->p.x;
|
||||
break;
|
||||
}
|
||||
if (gdispColor2Native(g->p.color) != Black)
|
||||
RAM(g)[xyaddr(x, y)] |= xybit(y);
|
||||
else
|
||||
RAM(g)[xyaddr(x, y)] &= ~xybit(y);
|
||||
g->flags |= GDISP_FLG_NEEDFLUSH;
|
||||
}
|
||||
# endif
|
||||
|
||||
# if GDISP_HARDWARE_PIXELREAD
|
||||
LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) {
|
||||
coord_t x, y;
|
||||
|
||||
switch (g->g.Orientation) {
|
||||
default:
|
||||
case GDISP_ROTATE_0:
|
||||
x = g->p.x;
|
||||
y = g->p.y;
|
||||
break;
|
||||
case GDISP_ROTATE_90:
|
||||
x = g->p.y;
|
||||
y = GDISP_SCREEN_HEIGHT - 1 - g->p.x;
|
||||
break;
|
||||
case GDISP_ROTATE_180:
|
||||
x = GDISP_SCREEN_WIDTH - 1 - g->p.x;
|
||||
y = GDISP_SCREEN_HEIGHT - 1 - g->p.y;
|
||||
break;
|
||||
case GDISP_ROTATE_270:
|
||||
x = GDISP_SCREEN_HEIGHT - 1 - g->p.y;
|
||||
y = g->p.x;
|
||||
break;
|
||||
}
|
||||
return (RAM(g)[xyaddr(x, y)] & xybit(y)) ? White : Black;
|
||||
}
|
||||
# endif
|
||||
|
||||
# if GDISP_HARDWARE_BITFILLS
|
||||
LLDSPEC void gdisp_lld_blit_area(GDisplay *g) {
|
||||
uint8_t *buffer = (uint8_t *)g->p.ptr;
|
||||
int linelength = g->p.cx;
|
||||
for (int i = 0; i < g->p.cy; i++) {
|
||||
unsigned dstx = g->p.x;
|
||||
unsigned dsty = g->p.y + i;
|
||||
unsigned srcx = g->p.x1;
|
||||
unsigned srcy = g->p.y1 + i;
|
||||
unsigned srcbit = srcy * g->p.x2 + srcx;
|
||||
for (int j = 0; j < linelength; j++) {
|
||||
uint8_t src = buffer[srcbit / 8];
|
||||
uint8_t bit = 7 - (srcbit % 8);
|
||||
uint8_t bitset = (src >> bit) & 1;
|
||||
uint8_t *dst = &(RAM(g)[xyaddr(dstx, dsty)]);
|
||||
if (bitset) {
|
||||
*dst |= xybit(dsty);
|
||||
} else {
|
||||
*dst &= ~xybit(dsty);
|
||||
}
|
||||
dstx++;
|
||||
srcbit++;
|
||||
}
|
||||
}
|
||||
g->flags |= GDISP_FLG_NEEDFLUSH;
|
||||
}
|
||||
# endif
|
||||
|
||||
# if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
|
||||
LLDSPEC void gdisp_lld_control(GDisplay *g) {
|
||||
switch (g->p.x) {
|
||||
case GDISP_CONTROL_POWER:
|
||||
if (g->g.Powermode == (powermode_t)g->p.ptr) return;
|
||||
switch ((powermode_t)g->p.ptr) {
|
||||
case powerOff:
|
||||
case powerSleep:
|
||||
case powerDeepSleep:
|
||||
acquire_bus(g);
|
||||
write_cmd(g, ST7565_DISPLAY_OFF);
|
||||
release_bus(g);
|
||||
break;
|
||||
case powerOn:
|
||||
acquire_bus(g);
|
||||
write_cmd(g, ST7565_DISPLAY_ON);
|
||||
release_bus(g);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
g->g.Powermode = (powermode_t)g->p.ptr;
|
||||
return;
|
||||
|
||||
case GDISP_CONTROL_ORIENTATION:
|
||||
if (g->g.Orientation == (orientation_t)g->p.ptr) return;
|
||||
switch ((orientation_t)g->p.ptr) {
|
||||
/* Rotation is handled by the drawing routines */
|
||||
case GDISP_ROTATE_0:
|
||||
case GDISP_ROTATE_180:
|
||||
g->g.Height = GDISP_SCREEN_HEIGHT;
|
||||
g->g.Width = GDISP_SCREEN_WIDTH;
|
||||
break;
|
||||
case GDISP_ROTATE_90:
|
||||
case GDISP_ROTATE_270:
|
||||
g->g.Height = GDISP_SCREEN_WIDTH;
|
||||
g->g.Width = GDISP_SCREEN_HEIGHT;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
g->g.Orientation = (orientation_t)g->p.ptr;
|
||||
return;
|
||||
|
||||
case GDISP_CONTROL_CONTRAST:
|
||||
if ((unsigned)g->p.ptr > 100) g->p.ptr = (void *)100;
|
||||
acquire_bus(g);
|
||||
write_cmd2(g, ST7565_CONTRAST, ((((unsigned)g->p.ptr) << 6) / 101) & 0x3F);
|
||||
release_bus(g);
|
||||
g->g.Contrast = (unsigned)g->p.ptr;
|
||||
return;
|
||||
}
|
||||
}
|
||||
# endif // GDISP_NEED_CONTROL
|
||||
|
||||
#endif // GFX_USE_GDISP
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* This file is subject to the terms of the GFX License. If a copy of
|
||||
* the license was not distributed with this file, you can obtain one at:
|
||||
*
|
||||
* http://ugfx.org/license.html
|
||||
*/
|
||||
|
||||
#ifndef _GDISP_LLD_CONFIG_H
|
||||
#define _GDISP_LLD_CONFIG_H
|
||||
|
||||
#if GFX_USE_GDISP
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver hardware support. */
|
||||
/*===========================================================================*/
|
||||
|
||||
# define GDISP_HARDWARE_FLUSH GFXON // This controller requires flushing
|
||||
# define GDISP_HARDWARE_DRAWPIXEL GFXON
|
||||
# define GDISP_HARDWARE_PIXELREAD GFXON
|
||||
# define GDISP_HARDWARE_CONTROL GFXON
|
||||
# define GDISP_HARDWARE_BITFILLS GFXON
|
||||
|
||||
# define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_MONO
|
||||
|
||||
#endif /* GFX_USE_GDISP */
|
||||
|
||||
#endif /* _GDISP_LLD_CONFIG_H */
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* This file is subject to the terms of the GFX License. If a copy of
|
||||
* the license was not distributed with this file, you can obtain one at:
|
||||
*
|
||||
* http://ugfx.org/license.html
|
||||
*/
|
||||
|
||||
#ifndef _ST7565_H
|
||||
#define _ST7565_H
|
||||
|
||||
#define ST7565_CONTRAST 0x81
|
||||
#define ST7565_ALLON_NORMAL 0xA4
|
||||
#define ST7565_ALLON 0xA5
|
||||
#define ST7565_POSITIVE_DISPLAY 0xA6
|
||||
#define ST7565_INVERT_DISPLAY 0xA7
|
||||
#define ST7565_DISPLAY_OFF 0xAE
|
||||
#define ST7565_DISPLAY_ON 0xAF
|
||||
|
||||
#define ST7565_LCD_BIAS_7 0xA3
|
||||
#define ST7565_LCD_BIAS_9 0xA2
|
||||
|
||||
#define ST7565_ADC_NORMAL 0xA0
|
||||
#define ST7565_ADC_REVERSE 0xA1
|
||||
|
||||
#define ST7565_COM_SCAN_INC 0xC0
|
||||
#define ST7565_COM_SCAN_DEC 0xC8
|
||||
|
||||
#define ST7565_START_LINE 0x40
|
||||
#define ST7565_PAGE 0xB0
|
||||
#define ST7565_COLUMN_MSB 0x10
|
||||
#define ST7565_COLUMN_LSB 0x00
|
||||
#define ST7565_RMW 0xE0
|
||||
|
||||
#define ST7565_RESISTOR_RATIO 0x20
|
||||
#define ST7565_POWER_CONTROL 0x28
|
||||
|
||||
#define ST7565_RESET 0xE2
|
||||
|
||||
#endif /* _ST7565_H */
|
||||
@@ -1,32 +1,25 @@
|
||||
/*
|
||||
Copyright 2018 Massdrop Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General 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 2021 QMK
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _USB2422_H_
|
||||
#define _USB2422_H_
|
||||
|
||||
#define REV_USB2422 0x100
|
||||
|
||||
#define USB2422_ADDR 0x58 // I2C device address, one instance
|
||||
|
||||
#define USB2422_HUB_ACTIVE_GROUP 0 // PA
|
||||
#define USB2422_HUB_ACTIVE_PIN 18 // 18
|
||||
#include <string.h>
|
||||
#include "usb2422.h"
|
||||
#include "i2c_master.h"
|
||||
#include "wait.h"
|
||||
#include "gpio.h"
|
||||
|
||||
/* -------- USB2422_VID : (USB2422L Offset: 0x00) (R/W 16) Vendor ID -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint16_t VID_LSB : 8;
|
||||
@@ -34,10 +27,8 @@ typedef union {
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint16_t reg; /*!< Type used for register access */
|
||||
} USB2422_VID_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_PID : (USB2422L Offset: 0x02) (R/W 16) Product ID -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint16_t PID_LSB : 8;
|
||||
@@ -45,10 +36,8 @@ typedef union {
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint16_t reg; /*!< Type used for register access */
|
||||
} USB2422_PID_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_DID : (USB2422L Offset: 0x04) (R/W 16) Device ID -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint16_t DID_LSB : 8;
|
||||
@@ -56,10 +45,8 @@ typedef union {
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint16_t reg; /*!< Type used for register access */
|
||||
} USB2422_DID_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_CFG1 : (USB2422L Offset: 0x06) (R/W 8) Configuration Data Byte 1-------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t PORT_PWR : 1;
|
||||
@@ -72,10 +59,8 @@ typedef union {
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_CFG1_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_CFG2 : (USB2422L Offset: 0x07) (R/W 8) Configuration Data Byte 2-------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t : 3;
|
||||
@@ -86,10 +71,8 @@ typedef union {
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_CFG2_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_CFG3 : (USB2422L Offset: 0x08) (R/W 16) Configuration Data Byte 3-------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t STRING_EN : 1;
|
||||
@@ -99,10 +82,8 @@ typedef union {
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_CFG3_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_NRD : (USB2422L Offset: 0x09) (R/W 8) Non Removable Device -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t : 5;
|
||||
@@ -112,10 +93,8 @@ typedef union {
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_NRD_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_PDS : (USB2422L Offset: 0x0A) (R/W 8) Port Diable for Self-Powered Operation -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t : 1;
|
||||
@@ -125,10 +104,9 @@ typedef union {
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_PDS_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_PDB : (USB2422L Offset: 0x0B) (R/W 8) Port Diable for Bus-Powered Operation -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t : 1;
|
||||
@@ -138,125 +116,98 @@ typedef union {
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_PDB_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_MAXPS : (USB2422L Offset: 0x0C) (R/W 8) Max Power for Self-Powered Operation -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t MAX_PWR_SP : 8;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_MAXPS_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_MAXPB : (USB2422L Offset: 0x0D) (R/W 8) Max Power for Bus-Powered Operation -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t MAX_PWR_BP : 8;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_MAXPB_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_HCMCS : (USB2422L Offset: 0x0E) (R/W 8) Hub Controller Max Current for Self-Powered Operation -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t HC_MAX_C_SP : 8;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_HCMCS_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_HCMCB : (USB2422L Offset: 0x0F) (R/W 8) Hub Controller Max Current for Bus-Powered Operation -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t HC_MAX_C_BP : 8;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_HCMCB_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_PWRT : (USB2422L Offset: 0x10) (R/W 8) Power On Time -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t POWER_ON_TIME : 8;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_PWRT_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_LANGID LSB : (USB2422L Offset: 0x11) (R/W 16) Language ID -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t LANGID_LSB : 8;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_LANGID_LSB_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_LANGID MSB : (USB2422L Offset: 0x12) (R/W 16) Language ID -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t LANGID_MSB : 8;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_LANGID_MSB_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_MFRSL : (USB2422L Offset: 0x13) (R/W 8) Manufacturer String Length -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t MFR_STR_LEN : 8;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_MFRSL_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_PRDSL : (USB2422L Offset: 0x14) (R/W 8) Product String Length -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t PRD_STR_LEN : 8;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_PRDSL_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_SERSL : (USB2422L Offset: 0x15) (R/W 8) Serial String Length -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t SER_STR_LEN : 8;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_SERSL_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_MFRSTR : (USB2422L Offset: 0x16-53) (R/W 8) Maufacturer String -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef uint16_t USB2422_MFRSTR_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_PRDSTR : (USB2422L Offset: 0x54-91) (R/W 8) Product String -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef uint16_t USB2422_PRDSTR_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_SERSTR : (USB2422L Offset: 0x92-CF) (R/W 8) Serial String -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef uint16_t USB2422_SERSTR_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_BCEN : (USB2422L Offset: 0xD0) (R/W 8) Battery Charging Enable -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t : 1;
|
||||
@@ -266,10 +217,8 @@ typedef union {
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_BCEN_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_BOOSTUP : (USB2422L Offset: 0xF6) (R/W 8) Boost Upstream -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t BOOST : 2;
|
||||
@@ -277,10 +226,8 @@ typedef union {
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_BOOSTUP_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_BOOSTDOWN : (USB2422L Offset: 0xF8) (R/W 8) Boost Downstream -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t BOOST1 : 2;
|
||||
@@ -289,10 +236,8 @@ typedef union {
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_BOOSTDOWN_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_PRTSP : (USB2422L Offset: 0xFA) (R/W 8) Port Swap -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t : 1;
|
||||
@@ -302,10 +247,8 @@ typedef union {
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_PRTSP_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_PRTR12 : (USB2422L Offset: 0xFB) (R/W 8) Port 1/2 Remap -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t PORT1_REMAP : 4;
|
||||
@@ -313,7 +256,7 @@ typedef union {
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_PRTR12_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
#define USB2422_PRTR12_DISABLE 0
|
||||
#define USB2422_PRT12_P2TOL1 1
|
||||
#define USB2422_PRT12_P2XTOL2 2
|
||||
@@ -321,7 +264,6 @@ typedef union {
|
||||
#define USB2422_PRT12_P1XTOL2 2
|
||||
|
||||
/* -------- USB2422_STCD : (USB2422L Offset: 0xFF) (R/W 8) Status Command -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t USB_ATTACH : 1;
|
||||
@@ -331,10 +273,8 @@ typedef union {
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_STCD_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/** \brief USB2422 device hardware registers */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef struct {
|
||||
USB2422_VID_Type VID; /**< \brief Offset: 0x00*/
|
||||
USB2422_PID_Type PID; /**< \brief Offset: 0x02*/
|
||||
@@ -368,35 +308,95 @@ typedef struct {
|
||||
USB2422_PRTR12_Type PRTR12; /**< \brief Offset: 0xFB*/
|
||||
uint8_t Reserved4[0x3];
|
||||
USB2422_STCD_Type STCD; /**< \brief Offset: 0xFF*/
|
||||
} Usb2422;
|
||||
} Usb2422_t;
|
||||
|
||||
// ***************************************************************
|
||||
|
||||
static Usb2422_t config;
|
||||
|
||||
// ***************************************************************
|
||||
|
||||
/** \brief Handle the conversion to allow simple strings
|
||||
*/
|
||||
static void USB2422_strcpy(const char* str, USB2422_MFRSTR_Type* dest, uint8_t len) {
|
||||
for (uint8_t i = 0; i < len; i++) {
|
||||
dest[i] = str[i];
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief Handle the conversion to allow simple strings
|
||||
*/
|
||||
static void USB2422_write_block(void) {
|
||||
static unsigned char i2c0_buf[34];
|
||||
|
||||
unsigned char* dest = i2c0_buf;
|
||||
unsigned char* src;
|
||||
unsigned char* base = (unsigned char*)&config;
|
||||
|
||||
for (src = base; src < base + 256; src += 32) {
|
||||
dest[0] = src - base;
|
||||
dest[1] = 32;
|
||||
memcpy(&dest[2], src, 32);
|
||||
i2c_transmit(USB2422_ADDRESS, dest, 34, 50000);
|
||||
wait_us(100);
|
||||
}
|
||||
}
|
||||
|
||||
// ***************************************************************
|
||||
|
||||
void USB2422_init() {
|
||||
#ifdef USB2422_RESET_PIN
|
||||
setPinOutput(USB2422_RESET_PIN);
|
||||
#endif
|
||||
#ifdef USB2422_ACTIVE_PIN
|
||||
setPinInput(USB2422_ACTIVE_PIN);
|
||||
#endif
|
||||
|
||||
#define PORT_DETECT_RETRY_INTERVAL 2000
|
||||
i2c_init(); // IC2 clk must be high at USB2422 reset release time to signal SMB configuration
|
||||
}
|
||||
|
||||
#define USB_EXTRA_ADC_THRESHOLD 900
|
||||
void USB2422_configure() {
|
||||
static const char SERNAME[] = "Unavailable";
|
||||
|
||||
#define USB_EXTRA_STATE_DISABLED 0
|
||||
#define USB_EXTRA_STATE_ENABLED 1
|
||||
#define USB_EXTRA_STATE_UNKNOWN 2
|
||||
#define USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG 3
|
||||
memset(&config, 0, sizeof(Usb2422_t));
|
||||
|
||||
#define USB_HOST_PORT_1 0
|
||||
#define USB_HOST_PORT_2 1
|
||||
#define USB_HOST_PORT_UNKNOWN 2
|
||||
// configure Usb2422 registers
|
||||
config.VID.reg = USB2422_VENDOR_ID;
|
||||
config.PID.reg = USB2422_PRODUCT_ID;
|
||||
config.DID.reg = USB2422_DEVICE_VER; // BCD format, eg 01.01
|
||||
config.CFG1.bit.SELF_BUS_PWR = 1; // self powered for now
|
||||
config.CFG1.bit.HS_DISABLE = 1; // full or high speed
|
||||
// config.CFG2.bit.COMPOUND = 0; // compound device
|
||||
config.CFG3.bit.STRING_EN = 1; // strings enabled
|
||||
// config.NRD.bit.PORT2_NR = 0; // MCU is non-removable
|
||||
config.MAXPB.reg = 20; // 0mA
|
||||
config.HCMCB.reg = 20; // 0mA
|
||||
config.MFRSL.reg = sizeof(USB2422_MANUFACTURER);
|
||||
config.PRDSL.reg = sizeof(USB2422_PRODUCT);
|
||||
config.SERSL.reg = sizeof(SERNAME);
|
||||
USB2422_strcpy(USB2422_MANUFACTURER, config.MFRSTR, sizeof(USB2422_MANUFACTURER));
|
||||
USB2422_strcpy(USB2422_PRODUCT, config.PRDSTR, sizeof(USB2422_PRODUCT));
|
||||
USB2422_strcpy(SERNAME, config.SERSTR, sizeof(SERNAME));
|
||||
// config.BOOSTUP.bit.BOOST=3; //upstream port
|
||||
// config.BOOSTDOWN.bit.BOOST1=0; // extra port
|
||||
// config.BOOSTDOWN.bit.BOOST2=2; //MCU is close
|
||||
config.STCD.bit.USB_ATTACH = 1;
|
||||
|
||||
extern uint8_t usb_host_port;
|
||||
extern uint8_t usb_extra_state;
|
||||
extern uint8_t usb_extra_manual;
|
||||
extern uint8_t usb_gcr_auto;
|
||||
USB2422_write_block();
|
||||
}
|
||||
|
||||
void USB2422_init(void);
|
||||
void USB_reset(void);
|
||||
void USB_configure(void);
|
||||
uint16_t USB_active(void);
|
||||
void USB_set_host_by_voltage(void);
|
||||
uint16_t adc_get(uint8_t muxpos);
|
||||
uint8_t USB2422_Port_Detect_Init(void);
|
||||
void USB_HandleExtraDevice(void);
|
||||
void USB_ExtraSetState(uint8_t state);
|
||||
void USB2422_reset() {
|
||||
#ifdef USB2422_RESET_PIN
|
||||
writePinLow(USB2422_RESET_PIN);
|
||||
wait_us(2);
|
||||
writePinHigh(USB2422_RESET_PIN);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif //_USB2422_H_
|
||||
bool USB2422_active() {
|
||||
#ifdef USB2422_ACTIVE_PIN
|
||||
return readPin(USB2422_ACTIVE_PIN);
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
59
drivers/usb2422.h
Normal file
59
drivers/usb2422.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* Copyright 2021 QMK
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef USB2422_ADDRESS
|
||||
# define USB2422_ADDRESS 0x58
|
||||
#endif
|
||||
|
||||
#ifndef USB2422_VENDOR_ID
|
||||
# define USB2422_VENDOR_ID 0xFEED
|
||||
#endif
|
||||
#ifndef USB2422_PRODUCT_ID
|
||||
# define USB2422_PRODUCT_ID 0x0001
|
||||
#endif
|
||||
#ifndef USB2422_DEVICE_VER
|
||||
# define USB2422_DEVICE_VER 0x0001
|
||||
#endif
|
||||
|
||||
#ifndef USB2422_MANUFACTURER
|
||||
# define USB2422_MANUFACTURER "QMK"
|
||||
#endif
|
||||
#ifndef USB2422_PRODUCT
|
||||
# define USB2422_PRODUCT "QMK Hub"
|
||||
#endif
|
||||
|
||||
/** \brief Initialises the dependent subsystems */
|
||||
void USB2422_init(void);
|
||||
|
||||
/** \brief Push configuration to the USB2422 device */
|
||||
void USB2422_configure(void);
|
||||
|
||||
/** \brief Reset the chip (RESET_N)
|
||||
*
|
||||
* NOTE:
|
||||
* Depends on a valid USB2422_RESET_PIN configuration
|
||||
*/
|
||||
void USB2422_reset(void);
|
||||
|
||||
/** \brief Indicates the USB state of the hub (SUSP_IND)
|
||||
*
|
||||
* NOTE:
|
||||
* Depends on a valid USB2422_ACTIVE_PIN configuration
|
||||
*/
|
||||
bool USB2422_active(void);
|
||||
@@ -17,11 +17,41 @@
|
||||
|
||||
#include "quantum/color.h"
|
||||
|
||||
/*
|
||||
* The WS2812 datasheets define T1H 900ns, T0H 350ns, T1L 350ns, T0L 900ns. Hence, by default, these
|
||||
* are chosen to be conservative and avoid problems rather than for maximum throughput; in the code,
|
||||
* this is done by default using a WS2812_TIMING parameter that accounts for the whole window (1250ns)
|
||||
* and defining T1H and T0H; T1L and T0L are obtained by subtracting their low counterparts from the window.
|
||||
*
|
||||
* However, there are certain "WS2812"-like LEDs, like the SK6812s, which work in a similar
|
||||
* communication topology but use different timings for the window and the T1L, T1H, T0L and T0H.
|
||||
* This means that, albeit the same driver being applicable, the timings must be adapted.
|
||||
*/
|
||||
|
||||
#ifndef WS2812_TIMING
|
||||
# define WS2812_TIMING 1250
|
||||
#endif
|
||||
|
||||
#ifndef WS2812_T1H
|
||||
# define WS2812_T1H 900 // Width of a 1 bit in ns
|
||||
#endif
|
||||
|
||||
#ifndef WS2812_T1L
|
||||
# define WS2812_T1L (WS2812_TIMING - WS2812_T1H) // Width of a 1 bit in ns
|
||||
#endif
|
||||
|
||||
#ifndef WS2812_T0H
|
||||
# define WS2812_T0H 350 // Width of a 0 bit in ns
|
||||
#endif
|
||||
|
||||
#ifndef WS2812_T0L
|
||||
# define WS2812_T0L (WS2812_TIMING - WS2812_T0H) // Width of a 0 bit in ns
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Older WS2812s can handle a reset time (TRST) of 50us, but recent
|
||||
* component revisions require a minimum of 280us.
|
||||
*/
|
||||
|
||||
#if !defined(WS2812_TRST_US)
|
||||
# define WS2812_TRST_US 280
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user