Compare commits
154 Commits
Author | SHA1 | Date | |
---|---|---|---|
fdd0f91527 | |||
2410f02359 | |||
c63d9ee0d5 | |||
95e9ef27be | |||
0680bfe03d | |||
a63d4774f5 | |||
1ee545014a | |||
eb19fb5b57 | |||
91cf4b00c5 | |||
e16b39f0c2 | |||
a68057852b | |||
f6bd5d793a | |||
0e17a44b46 | |||
1e7d08d2e3 | |||
b806cc9eea | |||
26dacd51fc | |||
7e8c0a368b | |||
028a4feeed | |||
a9b6ebcd89 | |||
34d01f0a7f | |||
80edd8a9d8 | |||
b6d8524794 | |||
4de9ed7eb0 | |||
067091d9c2 | |||
37d3055264 | |||
c6eccb39e0 | |||
6d1536db1d | |||
9064b424e9 | |||
5d8d350976 | |||
6076ed85be | |||
9d27d55443 | |||
4951fc52be | |||
356fe590e6 | |||
c8cd1ebc45 | |||
a4294a153b | |||
343dc1be7f | |||
cffaf0acf4 | |||
3f8654c85d | |||
8720c6628a | |||
e1be79d7c9 | |||
d0b55b59f9 | |||
9d99fd8418 | |||
220ea4c9b7 | |||
dbef2ad6b9 | |||
e2755c11b3 | |||
2091280bbb | |||
4a3eb3bdd4 | |||
10c636a1ee | |||
99da48c72b | |||
4cc1edbb67 | |||
d87ef88de0 | |||
8bc771a842 | |||
ee238f1219 | |||
c55313509f | |||
78a01068a4 | |||
10b4591d88 | |||
fe687af54d | |||
a18cd1b2b6 | |||
19fdfccca2 | |||
9175eebc87 | |||
8007d9f3a7 | |||
da24a34efb | |||
700aa8fe1c | |||
97df0fc072 | |||
fe0683938a | |||
15a73f4f64 | |||
4044c746d0 | |||
9b237f5de3 | |||
303ca46e77 | |||
a828d49f8c | |||
9eab1667b0 | |||
c19d949b72 | |||
632287535c | |||
789619eeb9 | |||
3549415116 | |||
4cfdd2cff5 | |||
1eaf9c8b9b | |||
bfc9aa66f9 | |||
23867894c0 | |||
b3d80d4af0 | |||
77b7e2cd59 | |||
89838d0939 | |||
ad2bb529c7 | |||
feec8ad469 | |||
61b6116147 | |||
e12151f15e | |||
6cdc6e8397 | |||
08963796d8 | |||
05b7383703 | |||
39256c2449 | |||
e510491bbc | |||
09759c20ae | |||
3be4d2417c | |||
f0e0ca402c | |||
2a49832db3 | |||
d263b27c9a | |||
1cdef7cd2f | |||
acd2767631 | |||
7ad0f24efa | |||
5d723ab158 | |||
a1568b9972 | |||
317c624761 | |||
e5f201edb4 | |||
8e50a472ab | |||
c909c4ea50 | |||
bd4ba8d180 | |||
bcdd7735c8 | |||
99cb107b71 | |||
9c8f8bd3bc | |||
98b16b3294 | |||
85659ae5e1 | |||
2a89134d8e | |||
3eabd7946e | |||
fd0bd29a0a | |||
feb5e4aaeb | |||
90d8ed6c44 | |||
243764b83d | |||
489a922f34 | |||
1ac2dd9b63 | |||
98afb45a27 | |||
83da38c5e4 | |||
ccfe60eb57 | |||
435e9b7bdb | |||
925b65b7d0 | |||
619b5d1e6d | |||
69fef83b0e | |||
fd085837e1 | |||
d8e6ada5d7 | |||
16d6fd6e8e | |||
2b0f5d3bea | |||
0c4e0a2097 | |||
f6ec2ce201 | |||
0346bc2c5b | |||
e818b29879 | |||
9a4db7a860 | |||
a6e1cb08c6 | |||
a2b4178245 | |||
ef5b161bb5 | |||
23d68d0ba1 | |||
435a1202e7 | |||
3e8f272873 | |||
f8a915a2db | |||
ec26684491 | |||
ac46378ac6 | |||
bb4af7deee | |||
d8db4ab202 | |||
329b574831 | |||
20e5798e63 | |||
9aee5e6427 | |||
dfef321bdf | |||
b29799f887 | |||
0a00583462 | |||
a057f1ca9e | |||
62a8603122 |
@ -1,3 +1,9 @@
|
||||
# Determine what keyboard we are building and setup the build environment.
|
||||
#
|
||||
# We support folders up to 5 levels deep below `keyboards/`. This file is
|
||||
# responsible for determining which folder is being used and doing the
|
||||
# corresponding environment setup.
|
||||
|
||||
ifndef VERBOSE
|
||||
.SILENT:
|
||||
endif
|
||||
@ -6,26 +12,15 @@ endif
|
||||
|
||||
include common.mk
|
||||
|
||||
# 5/4/3/2/1
|
||||
KEYBOARD_FOLDER_PATH_1 := $(KEYBOARD)
|
||||
KEYBOARD_FOLDER_PATH_2 := $(patsubst %/,%,$(dir $(KEYBOARD_FOLDER_PATH_1)))
|
||||
KEYBOARD_FOLDER_PATH_3 := $(patsubst %/,%,$(dir $(KEYBOARD_FOLDER_PATH_2)))
|
||||
KEYBOARD_FOLDER_PATH_4 := $(patsubst %/,%,$(dir $(KEYBOARD_FOLDER_PATH_3)))
|
||||
KEYBOARD_FOLDER_PATH_5 := $(patsubst %/,%,$(dir $(KEYBOARD_FOLDER_PATH_4)))
|
||||
KEYBOARD_FOLDER_1 := $(notdir $(KEYBOARD_FOLDER_PATH_1))
|
||||
KEYBOARD_FOLDER_2 := $(notdir $(KEYBOARD_FOLDER_PATH_2))
|
||||
KEYBOARD_FOLDER_3 := $(notdir $(KEYBOARD_FOLDER_PATH_3))
|
||||
KEYBOARD_FOLDER_4 := $(notdir $(KEYBOARD_FOLDER_PATH_4))
|
||||
KEYBOARD_FOLDER_5 := $(notdir $(KEYBOARD_FOLDER_PATH_5))
|
||||
|
||||
# Set the filename for the final firmware binary
|
||||
KEYBOARD_FILESAFE := $(subst /,_,$(KEYBOARD))
|
||||
|
||||
TARGET ?= $(KEYBOARD_FILESAFE)_$(KEYMAP)
|
||||
KEYBOARD_OUTPUT := $(BUILD_DIR)/obj_$(KEYBOARD_FILESAFE)
|
||||
|
||||
# Force expansion
|
||||
TARGET := $(TARGET)
|
||||
|
||||
# For split boards we need to set a master half.
|
||||
MASTER ?= left
|
||||
ifdef master
|
||||
MASTER = $(master)
|
||||
@ -39,35 +34,58 @@ $(error MASTER does not have a valid value(left/right))
|
||||
endif
|
||||
endif
|
||||
|
||||
# Determine which subfolders exist.
|
||||
KEYBOARD_FOLDER_PATH_1 := $(KEYBOARD)
|
||||
KEYBOARD_FOLDER_PATH_2 := $(patsubst %/,%,$(dir $(KEYBOARD_FOLDER_PATH_1)))
|
||||
KEYBOARD_FOLDER_PATH_3 := $(patsubst %/,%,$(dir $(KEYBOARD_FOLDER_PATH_2)))
|
||||
KEYBOARD_FOLDER_PATH_4 := $(patsubst %/,%,$(dir $(KEYBOARD_FOLDER_PATH_3)))
|
||||
KEYBOARD_FOLDER_PATH_5 := $(patsubst %/,%,$(dir $(KEYBOARD_FOLDER_PATH_4)))
|
||||
KEYBOARD_FOLDER_1 := $(notdir $(KEYBOARD_FOLDER_PATH_1))
|
||||
KEYBOARD_FOLDER_2 := $(notdir $(KEYBOARD_FOLDER_PATH_2))
|
||||
KEYBOARD_FOLDER_3 := $(notdir $(KEYBOARD_FOLDER_PATH_3))
|
||||
KEYBOARD_FOLDER_4 := $(notdir $(KEYBOARD_FOLDER_PATH_4))
|
||||
KEYBOARD_FOLDER_5 := $(notdir $(KEYBOARD_FOLDER_PATH_5))
|
||||
KEYBOARD_PATHS :=
|
||||
|
||||
KEYBOARD_PATH_1 := keyboards/$(KEYBOARD_FOLDER_PATH_1)
|
||||
KEYBOARD_PATH_2 := keyboards/$(KEYBOARD_FOLDER_PATH_2)
|
||||
KEYBOARD_PATH_3 := keyboards/$(KEYBOARD_FOLDER_PATH_3)
|
||||
KEYBOARD_PATH_4 := keyboards/$(KEYBOARD_FOLDER_PATH_4)
|
||||
KEYBOARD_PATH_5 := keyboards/$(KEYBOARD_FOLDER_PATH_5)
|
||||
|
||||
ifneq ("$(wildcard $(KEYBOARD_PATH_5)/rules.mk)","")
|
||||
ifneq ("$(wildcard $(KEYBOARD_PATH_5)/)","")
|
||||
KEYBOARD_PATHS += $(KEYBOARD_PATH_5)
|
||||
endif
|
||||
ifneq ("$(wildcard $(KEYBOARD_PATH_4)/)","")
|
||||
KEYBOARD_PATHS += $(KEYBOARD_PATH_4)
|
||||
endif
|
||||
ifneq ("$(wildcard $(KEYBOARD_PATH_3)/)","")
|
||||
KEYBOARD_PATHS += $(KEYBOARD_PATH_3)
|
||||
endif
|
||||
ifneq ("$(wildcard $(KEYBOARD_PATH_2)/)","")
|
||||
KEYBOARD_PATHS += $(KEYBOARD_PATH_2)
|
||||
endif
|
||||
ifneq ("$(wildcard $(KEYBOARD_PATH_1)/)","")
|
||||
KEYBOARD_PATHS += $(KEYBOARD_PATH_1)
|
||||
endif
|
||||
|
||||
# Pull in rules.mk files from all our subfolders
|
||||
ifneq ("$(wildcard $(KEYBOARD_PATH_5)/rules.mk)","")
|
||||
include $(KEYBOARD_PATH_5)/rules.mk
|
||||
endif
|
||||
ifneq ("$(wildcard $(KEYBOARD_PATH_4)/rules.mk)","")
|
||||
KEYBOARD_PATHS += $(KEYBOARD_PATH_4)
|
||||
include $(KEYBOARD_PATH_4)/rules.mk
|
||||
endif
|
||||
ifneq ("$(wildcard $(KEYBOARD_PATH_3)/rules.mk)","")
|
||||
KEYBOARD_PATHS += $(KEYBOARD_PATH_3)
|
||||
include $(KEYBOARD_PATH_3)/rules.mk
|
||||
endif
|
||||
ifneq ("$(wildcard $(KEYBOARD_PATH_2)/rules.mk)","")
|
||||
KEYBOARD_PATHS += $(KEYBOARD_PATH_2)
|
||||
include $(KEYBOARD_PATH_2)/rules.mk
|
||||
endif
|
||||
ifneq ("$(wildcard $(KEYBOARD_PATH_1)/rules.mk)","")
|
||||
KEYBOARD_PATHS += $(KEYBOARD_PATH_1)
|
||||
include $(KEYBOARD_PATH_1)/rules.mk
|
||||
endif
|
||||
|
||||
# Find all the C source files to be compiled in subfolders.
|
||||
KEYBOARD_SRC :=
|
||||
|
||||
KEYBOARD_C_1 := $(KEYBOARD_PATH_1)/$(KEYBOARD_FOLDER_1).c
|
||||
@ -95,6 +113,15 @@ endif
|
||||
OPT_DEFS += -DKEYBOARD_$(KEYBOARD_FILESAFE)
|
||||
|
||||
|
||||
# Setup the define for QMK_KEYBOARD_H. This is used inside of keymaps so
|
||||
# that the same keymap may be used on multiple keyboards.
|
||||
#
|
||||
# We grab the most top-level include file that we can. That file should
|
||||
# use #ifdef statements to include all the neccesary subfolder includes,
|
||||
# as described here:
|
||||
#
|
||||
# https://docs.qmk.fm/#/feature_layouts?id=tips-for-making-layouts-keyboard-agnostic
|
||||
#
|
||||
ifneq ("$(wildcard $(KEYBOARD_PATH_1)/$(KEYBOARD_FOLDER_1).h)","")
|
||||
QMK_KEYBOARD_H = $(KEYBOARD_FOLDER_1).h
|
||||
endif
|
||||
@ -111,13 +138,15 @@ ifneq ("$(wildcard $(KEYBOARD_PATH_5)/$(KEYBOARD_FOLDER_5).h)","")
|
||||
QMK_KEYBOARD_H = $(KEYBOARD_FOLDER_5).h
|
||||
endif
|
||||
|
||||
# We can assume a ChibiOS target When MCU_FAMILY is defined , since it's not used for LUFA
|
||||
# Determine and set parameters based on the keyboard's processor family.
|
||||
# We can assume a ChibiOS target When MCU_FAMILY is defined since it's
|
||||
# not used for LUFA
|
||||
ifdef MCU_FAMILY
|
||||
FIRMWARE_FORMAT=bin
|
||||
FIRMWARE_FORMAT?=bin
|
||||
PLATFORM=CHIBIOS
|
||||
else
|
||||
PLATFORM=AVR
|
||||
FIRMWARE_FORMAT=hex
|
||||
FIRMWARE_FORMAT?=hex
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),CHIBIOS)
|
||||
@ -148,6 +177,7 @@ ifeq ($(PLATFORM),CHIBIOS)
|
||||
endif
|
||||
endif
|
||||
|
||||
# Find all of the config.h files and add them to our CONFIG_H define.
|
||||
CONFIG_H :=
|
||||
ifneq ("$(wildcard $(KEYBOARD_PATH_5)/config.h)","")
|
||||
CONFIG_H += $(KEYBOARD_PATH_5)/config.h
|
||||
@ -203,7 +233,7 @@ else
|
||||
# this state should never be reached
|
||||
endif
|
||||
|
||||
# User space stuff
|
||||
# Userspace setup and definitions
|
||||
ifeq ("$(USER_NAME)","")
|
||||
USER_NAME := $(KEYMAP)
|
||||
endif
|
||||
@ -283,11 +313,6 @@ $(KEYBOARD_OUTPUT)_CONFIG := $(PROJECT_CONFIG)
|
||||
|
||||
# Default target.
|
||||
all: build check-size
|
||||
|
||||
# Change the build target to build a HEX file or a library.
|
||||
build: elf cpfirmware
|
||||
#build: elf hex eep lss sym
|
||||
#build: lib
|
||||
|
||||
|
||||
include $(TMK_PATH)/rules.mk
|
||||
|
@ -61,8 +61,8 @@ endif
|
||||
|
||||
ifeq ($(strip $(STENO_ENABLE)), yes)
|
||||
OPT_DEFS += -DSTENO_ENABLE
|
||||
VIRTSER_ENABLE := yes
|
||||
SRC += $(QUANTUM_DIR)/process_keycode/process_steno.c
|
||||
VIRTSER_ENABLE := yes
|
||||
SRC += $(QUANTUM_DIR)/process_keycode/process_steno.c
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(VIRTSER_ENABLE)), yes)
|
||||
@ -75,9 +75,9 @@ ifeq ($(strip $(FAUXCLICKY_ENABLE)), yes)
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(POINTING_DEVICE_ENABLE)), yes)
|
||||
OPT_DEFS += -DPOINTING_DEVICE_ENABLE
|
||||
OPT_DEFS += -DMOUSE_ENABLE
|
||||
SRC += $(QUANTUM_DIR)/pointing_device.c
|
||||
OPT_DEFS += -DPOINTING_DEVICE_ENABLE
|
||||
OPT_DEFS += -DMOUSE_ENABLE
|
||||
SRC += $(QUANTUM_DIR)/pointing_device.c
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(UCIS_ENABLE)), yes)
|
||||
@ -110,12 +110,14 @@ ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
|
||||
ifeq ($(strip $(RGBLIGHT_CUSTOM_DRIVER)), yes)
|
||||
OPT_DEFS += -DRGBLIGHT_CUSTOM_DRIVER
|
||||
else
|
||||
SRC += ws2812.c
|
||||
SRC += ws2812.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
|
||||
OPT_DEFS += -DRGB_MATRIX_ENABLE
|
||||
OPT_DEFS += -DIS31FL3731
|
||||
COMMON_VPATH += $(DRIVER_PATH)/issi
|
||||
SRC += is31fl3731.c
|
||||
SRC += i2c_master.c
|
||||
SRC += $(QUANTUM_DIR)/color.c
|
||||
@ -123,6 +125,28 @@ ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
|
||||
CIE1931_CURVE = yes
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(RGB_MATRIX_ENABLE)), IS31FL3731)
|
||||
OPT_DEFS += -DRGB_MATRIX_ENABLE
|
||||
OPT_DEFS += -DIS31FL3731
|
||||
COMMON_VPATH += $(DRIVER_PATH)/issi
|
||||
SRC += is31fl3731.c
|
||||
SRC += i2c_master.c
|
||||
SRC += $(QUANTUM_DIR)/color.c
|
||||
SRC += $(QUANTUM_DIR)/rgb_matrix.c
|
||||
CIE1931_CURVE = yes
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(RGB_MATRIX_ENABLE)), IS31FL3733)
|
||||
OPT_DEFS += -DRGB_MATRIX_ENABLE
|
||||
OPT_DEFS += -DIS31FL3733
|
||||
COMMON_VPATH += $(DRIVER_PATH)/issi
|
||||
SRC += is31fl3733.c
|
||||
SRC += i2c_master.c
|
||||
SRC += $(QUANTUM_DIR)/color.c
|
||||
SRC += $(QUANTUM_DIR)/rgb_matrix.c
|
||||
CIE1931_CURVE = yes
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(TAP_DANCE_ENABLE)), yes)
|
||||
OPT_DEFS += -DTAP_DANCE_ENABLE
|
||||
SRC += $(QUANTUM_DIR)/process_keycode/process_tap_dance.c
|
||||
@ -169,7 +193,7 @@ ifeq ($(strip $(BACKLIGHT_ENABLE)), yes)
|
||||
ifeq ($(strip $(VISUALIZER_ENABLE)), yes)
|
||||
CIE1931_CURVE = yes
|
||||
endif
|
||||
ifeq ($(strip $(BACKLIGHT_CUSTOM_DRIVER)), yes)
|
||||
ifeq ($(strip $(BACKLIGHT_CUSTOM_DRIVER)), yes)
|
||||
OPT_DEFS += -DBACKLIGHT_CUSTOM_DRIVER
|
||||
endif
|
||||
endif
|
||||
@ -200,7 +224,7 @@ endif
|
||||
|
||||
ifeq ($(strip $(HD44780_ENABLE)), yes)
|
||||
SRC += drivers/avr/hd44780.c
|
||||
OPT_DEFS += -DHD44780_ENABLE
|
||||
OPT_DEFS += -DHD44780_ENABLE
|
||||
endif
|
||||
|
||||
QUANTUM_SRC:= \
|
||||
|
@ -1,36 +1,51 @@
|
||||
* [Getting Started](README.md)
|
||||
* [QMK Introduction](getting_started_introduction.md)
|
||||
* [Install Build Tools](getting_started_build_tools.md)
|
||||
* Alternative: [Vagrant Guide](getting_started_vagrant.md)
|
||||
* [Build/Compile Instructions](getting_started_make_guide.md)
|
||||
* [Flashing Firmware](flashing.md)
|
||||
* [Contributing to QMK](contributing.md)
|
||||
* [How to Use Github](getting_started_github.md)
|
||||
* [Getting Help](getting_started_getting_help.md)
|
||||
|
||||
* [Complete Newbs Guide](newbs.md)
|
||||
* [Getting Started](newbs_getting_started.md)
|
||||
* [Building Your First Firmware](newbs_building_firmware.md)
|
||||
* [Flashing Firmware](newbs_flashing.md)
|
||||
* [Testing and Debugging](newbs_testing_debugging.md)
|
||||
|
||||
* [QMK Basics](README.md)
|
||||
* [QMK Introduction](getting_started_introduction.md)
|
||||
* [Contributing to QMK](contributing.md)
|
||||
* [How to Use Github](getting_started_github.md)
|
||||
* [Getting Help](getting_started_getting_help.md)
|
||||
|
||||
* [FAQ](faq.md)
|
||||
* [General FAQ](faq_general.md)
|
||||
* [Build/Compile QMK](faq_build.md)
|
||||
* [Debugging/Troubleshooting QMK](faq_debug.md)
|
||||
* [Keymap](faq_keymap.md)
|
||||
|
||||
* Detailed Guides
|
||||
* [Install Build Tools](getting_started_build_tools.md)
|
||||
* [Vagrant Guide](getting_started_vagrant.md)
|
||||
* [Build/Compile Instructions](getting_started_make_guide.md)
|
||||
* [Flashing Firmware](flashing.md)
|
||||
* [Customizing Functionality](custom_quantum_functions.md)
|
||||
* [Keymap Overview](keymap.md)
|
||||
|
||||
* [Hardware](hardware.md)
|
||||
* [Keyboard Guidelines](hardware_keyboard_guidelines.md)
|
||||
* [AVR Processors](hardware_avr.md)
|
||||
* ARM Processors (TBD)
|
||||
* [Drivers](hardware_drivers.md)
|
||||
|
||||
* Reference
|
||||
* [Keyboard Guidelines](hardware_keyboard_guidelines.md)
|
||||
* [Config Options](config_options.md)
|
||||
* [Keycodes](keycodes.md)
|
||||
* [Documentation Best Practices](documentation_best_practices.md)
|
||||
* [Documentation Templates](documentation_templates.md)
|
||||
* [Glossary](reference_glossary.md)
|
||||
* [Unit Testing](unit_testing.md)
|
||||
* [Useful Functions](ref_functions.md)
|
||||
|
||||
* [Features](features.md)
|
||||
* [Basic Keycodes](keycodes_basic.md)
|
||||
* [Quantum Keycodes](quantum_keycodes.md)
|
||||
* [Advanced Keycodes](feature_advanced_keycodes.md)
|
||||
* [Audio](feature_audio.md)
|
||||
* [Auto Shift](feature_auto_shift.md)
|
||||
* [Backlight](feature_backlight.md)
|
||||
* [Bluetooth](feature_bluetooth.md)
|
||||
* [Bootmagic](feature_bootmagic.md)
|
||||
* [Command](feature_command.md)
|
||||
* [Dynamic Macros](feature_dynamic_macros.md)
|
||||
@ -40,6 +55,7 @@
|
||||
* [Leader Key](feature_leader_key.md)
|
||||
* [Macros](feature_macros.md)
|
||||
* [Mouse Keys](feature_mouse_keys.md)
|
||||
* [One Shot Keys](feature_advanced_keycodes.md#one-shot-keys)
|
||||
* [Pointing Device](feature_pointing_device.md)
|
||||
* [PS/2 Mouse](feature_ps2_mouse.md)
|
||||
* [RGB Lighting](feature_rgblight.md)
|
||||
@ -53,36 +69,8 @@
|
||||
* [Thermal Printer](feature_thermal_printer.md)
|
||||
* [Unicode](feature_unicode.md)
|
||||
* [Userspace](feature_userspace.md)
|
||||
|
||||
* [Keycodes](keycodes.md)
|
||||
* [Basic](keycodes_basic.md)
|
||||
* [Quantum](quantum_keycodes.md)
|
||||
* [Audio](feature_audio.md#audio-keycodes)
|
||||
* [Backlight](feature_backlight.md#backlight-keycodes)
|
||||
* [Bluetooth](feature_bluetooth.md#bluetooth-keycodes)
|
||||
* [Bootmagic](feature_bootmagic.md#bootmagic-keycodes)
|
||||
* [Layer Switching](feature_advanced_keycodes.md#switching-and-toggling-layers)
|
||||
* [Mod+Key](feature_advanced_keycodes.md#modifier-keys)
|
||||
* [Mod Tap](feature_advanced_keycodes.md#mod-tap)
|
||||
* [Mouse Keys](feature_mouse_keys.md#mapping-mouse-actions-to-keyboard-keys)
|
||||
* [One Shot Keys](feature_advanced_keycodes.md#one-shot-keys)
|
||||
* [RGB Light](feature_rgblight.md#rgblight-keycodes)
|
||||
* [RGB Matrix](feature_rgb_matrix.md#keycodes)
|
||||
* [Shifted Keys](feature_advanced_keycodes.md#shifted-keycodes)
|
||||
* [Stenography](feature_stenography.md#keycode-reference)
|
||||
* [Swap Hands](feature_swap_hands.md#swap-keycodes)
|
||||
* [Thermal Printer](feature_thermal_printer.md#thermal-printer-keycodes)
|
||||
* [US ANSI Shifted Keys](keycodes_us_ansi_shifted.md)
|
||||
|
||||
* Reference
|
||||
* [Config Options](config_options.md)
|
||||
* [Customizing Functionality](custom_quantum_functions.md)
|
||||
* [Documentation Best Practices](documentation_best_practices.md)
|
||||
* [Documentation Templates](documentation_templates.md)
|
||||
* [Glossary](reference_glossary.md)
|
||||
* [Keymap Overview](keymap.md)
|
||||
* [Unit Testing](unit_testing.md)
|
||||
|
||||
* For Makers and Modders
|
||||
* [Hand Wiring Guide](hand_wire.md)
|
||||
* [ISP Flashing Guide](isp_flashing_guide.md)
|
||||
|
@ -1,36 +1,51 @@
|
||||
* [Getting Started](README.md)
|
||||
* [QMK Introduction](getting_started_introduction.md)
|
||||
* [Install Build Tools](getting_started_build_tools.md)
|
||||
* Alternative: [Vagrant Guide](getting_started_vagrant.md)
|
||||
* [Build/Compile Instructions](getting_started_make_guide.md)
|
||||
* [Flashing Firmware](flashing.md)
|
||||
* [Contributing to QMK](contributing.md)
|
||||
* [How to Use Github](getting_started_github.md)
|
||||
* [Getting Help](getting_started_getting_help.md)
|
||||
|
||||
* [Complete Newbs Guide](newbs.md)
|
||||
* [Getting Started](newbs_getting_started.md)
|
||||
* [Building Your First Firmware](newbs_building_firmware.md)
|
||||
* [Flashing Firmware](newbs_flashing.md)
|
||||
* [Testing and Debugging](newbs_testing_debugging.md)
|
||||
|
||||
* [QMK Basics](README.md)
|
||||
* [QMK Introduction](getting_started_introduction.md)
|
||||
* [Contributing to QMK](contributing.md)
|
||||
* [How to Use Github](getting_started_github.md)
|
||||
* [Getting Help](getting_started_getting_help.md)
|
||||
|
||||
* [FAQ](faq.md)
|
||||
* [General FAQ](faq_general.md)
|
||||
* [Build/Compile QMK](faq_build.md)
|
||||
* [Debugging/Troubleshooting QMK](faq_debug.md)
|
||||
* [Keymap](faq_keymap.md)
|
||||
|
||||
* Detailed Guides
|
||||
* [Install Build Tools](getting_started_build_tools.md)
|
||||
* [Vagrant Guide](getting_started_vagrant.md)
|
||||
* [Build/Compile Instructions](getting_started_make_guide.md)
|
||||
* [Flashing Firmware](flashing.md)
|
||||
* [Customizing Functionality](custom_quantum_functions.md)
|
||||
* [Keymap Overview](keymap.md)
|
||||
|
||||
* [Hardware](hardware.md)
|
||||
* [Keyboard Guidelines](hardware_keyboard_guidelines.md)
|
||||
* [AVR Processors](hardware_avr.md)
|
||||
* ARM Processors (TBD)
|
||||
* [Drivers](hardware_drivers.md)
|
||||
|
||||
* Reference
|
||||
* [Keyboard Guidelines](hardware_keyboard_guidelines.md)
|
||||
* [Config Options](config_options.md)
|
||||
* [Keycodes](keycodes.md)
|
||||
* [Documentation Best Practices](documentation_best_practices.md)
|
||||
* [Documentation Templates](documentation_templates.md)
|
||||
* [Glossary](reference_glossary.md)
|
||||
* [Unit Testing](unit_testing.md)
|
||||
* [Useful Functions](ref_functions.md)
|
||||
|
||||
* [Features](features.md)
|
||||
* [Basic Keycodes](keycodes_basic.md)
|
||||
* [Quantum Keycodes](quantum_keycodes.md)
|
||||
* [Advanced Keycodes](feature_advanced_keycodes.md)
|
||||
* [Audio](feature_audio.md)
|
||||
* [Auto Shift](feature_auto_shift.md)
|
||||
* [Backlight](feature_backlight.md)
|
||||
* [Bluetooth](feature_bluetooth.md)
|
||||
* [Bootmagic](feature_bootmagic.md)
|
||||
* [Command](feature_command.md)
|
||||
* [Dynamic Macros](feature_dynamic_macros.md)
|
||||
@ -40,6 +55,7 @@
|
||||
* [Leader Key](feature_leader_key.md)
|
||||
* [Macros](feature_macros.md)
|
||||
* [Mouse Keys](feature_mouse_keys.md)
|
||||
* [One Shot Keys](feature_advanced_keycodes.md#one-shot-keys)
|
||||
* [Pointing Device](feature_pointing_device.md)
|
||||
* [PS/2 Mouse](feature_ps2_mouse.md)
|
||||
* [RGB Lighting](feature_rgblight.md)
|
||||
@ -53,36 +69,8 @@
|
||||
* [Thermal Printer](feature_thermal_printer.md)
|
||||
* [Unicode](feature_unicode.md)
|
||||
* [Userspace](feature_userspace.md)
|
||||
|
||||
* [Keycodes](keycodes.md)
|
||||
* [Basic](keycodes_basic.md)
|
||||
* [Quantum](quantum_keycodes.md)
|
||||
* [Audio](feature_audio.md#audio-keycodes)
|
||||
* [Backlight](feature_backlight.md#backlight-keycodes)
|
||||
* [Bluetooth](feature_bluetooth.md#bluetooth-keycodes)
|
||||
* [Bootmagic](feature_bootmagic.md#bootmagic-keycodes)
|
||||
* [Layer Switching](feature_advanced_keycodes.md#switching-and-toggling-layers)
|
||||
* [Mod+Key](feature_advanced_keycodes.md#modifier-keys)
|
||||
* [Mod Tap](feature_advanced_keycodes.md#mod-tap)
|
||||
* [Mouse Keys](feature_mouse_keys.md#mapping-mouse-actions-to-keyboard-keys)
|
||||
* [One Shot Keys](feature_advanced_keycodes.md#one-shot-keys)
|
||||
* [RGB Light](feature_rgblight.md#rgblight-keycodes)
|
||||
* [RGB Matrix](feature_rgb_matrix.md#keycodes)
|
||||
* [Shifted Keys](feature_advanced_keycodes.md#shifted-keycodes)
|
||||
* [Stenography](feature_stenography.md#keycode-reference)
|
||||
* [Swap Hands](feature_swap_hands.md#swap-keycodes)
|
||||
* [Thermal Printer](feature_thermal_printer.md#thermal-printer-keycodes)
|
||||
* [US ANSI Shifted Keys](keycodes_us_ansi_shifted.md)
|
||||
|
||||
* Reference
|
||||
* [Config Options](config_options.md)
|
||||
* [Customizing Functionality](custom_quantum_functions.md)
|
||||
* [Documentation Best Practices](documentation_best_practices.md)
|
||||
* [Documentation Templates](documentation_templates.md)
|
||||
* [Glossary](reference_glossary.md)
|
||||
* [Keymap Overview](keymap.md)
|
||||
* [Unit Testing](unit_testing.md)
|
||||
|
||||
* For Makers and Modders
|
||||
* [Hand Wiring Guide](hand_wire.md)
|
||||
* [ISP Flashing Guide](isp_flashing_guide.md)
|
||||
|
@ -199,6 +199,8 @@ This is a [make](https://www.gnu.org/software/make/manual/make.html) file that i
|
||||
|
||||
* `DEFAULT_FOLDER`
|
||||
* Used to specify a default folder when a keyboard has more than one sub-folder.
|
||||
* `FIRMWARE_FORMAT`
|
||||
* Defines which format (bin, hex) is copied to the root `qmk_firmware` folder after building.
|
||||
* `SRC`
|
||||
* Used to add files to the compilation/linking list.
|
||||
* `LAYOUTS`
|
||||
|
@ -11,8 +11,8 @@ Keycodes are actually defined in [common/keycode.h](https://github.com/qmk/qmk_f
|
||||
|
||||
There are 3 standard keyboard layouts in use around the world- ANSI, ISO, and JIS. North America primarily uses ANSI, Europe and Africa primarily use ISO, and Japan uses JIS. Regions not mentioned typically use either ANSI or ISO. The keycodes corresponding to these layouts are shown here:
|
||||
|
||||
<!-- Source for this image: http://www.keyboard-layout-editor.com/#/gists/9ce023dc6caadc0cf11c88c782350a8c -->
|
||||

|
||||
<!-- Source for this image: http://www.keyboard-layout-editor.com/#/gists/070a530eedaed36a2d77f3f6fd455677 -->
|
||||

|
||||
|
||||
## Some Of My Keys Are Swapped Or Not Working
|
||||
|
||||
@ -34,12 +34,11 @@ See [issue #168](https://github.com/tmk/tmk_keyboard/issues/168) and
|
||||
* http://en.wikipedia.org/wiki/Magic_SysRq_key
|
||||
* http://en.wikipedia.org/wiki/System_request
|
||||
|
||||
## Power Key Doesn't Work
|
||||
Use `KC_PWR` instead of `KC_POWER` or vice versa.
|
||||
* `KC_PWR` works with Windows and Linux, not with OSX.
|
||||
* `KC_POWER` works with OSX and Linux, not with Windows.
|
||||
## Power Keys Aren't Working
|
||||
|
||||
More info: http://geekhack.org/index.php?topic=14290.msg1327264#msg1327264
|
||||
Somewhat confusingly, there are two "Power" keycodes in QMK: `KC_POWER` in the Keyboard/Keypad HID usage page, and `KC_SYSTEM_POWER` (or `KC_PWR`) in the Consumer page.
|
||||
|
||||
The former is only recognized on macOS, while the latter, `KC_SLEP` and `KC_WAKE` are supported by all three major operating systems, so it is recommended to use those instead. Under Windows, these keys take effect immediately, however on macOS they must be held down until a dialog appears.
|
||||
|
||||
## One Shot Modifier
|
||||
Solves my personal 'the' problem. I often got 'the' or 'THe' wrongly instead of 'The'. One Shot Shift mitigates this for me.
|
||||
@ -87,14 +86,14 @@ On **Xorg** you can use `compose` key, instead.
|
||||
And see this for **Unicode** input.
|
||||
* http://en.wikipedia.org/wiki/Unicode_input
|
||||
|
||||
## `Fn` Key on macOS
|
||||
|
||||
## Apple/Mac Keyboard `Fn`
|
||||
Not supported.
|
||||
Unlike most Fn keys, the one on Apple keyboards actually has its own keycode... sort of. It takes the place of the sixth keycode in a basic 6KRO HID report -- so an Apple keyboard is in fact only 5KRO.
|
||||
|
||||
Apple/Mac keyboard sends keycode for Fn unlike most of other keyboards.
|
||||
I think you can send Apple Fn key using Apple venter specific Page 0xff01 and usage 0x0003. But you have to change HID Report Descriptor for this, of course.
|
||||
It is technically possible to get QMK to send this key. However, doing so requires modification of the report format to add the state of the Fn key.
|
||||
Even worse, it is not recognized unless the keyboard's VID and PID match that of a real Apple keyboard. The legal issues that official QMK support for this feature may create mean it is unlikely to happen.
|
||||
|
||||
https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-606.1.7/IOHIDFamily/AppleHIDUsageTables.h
|
||||
See [this issue](https://github.com/qmk/qmk_firmware/issues/2179) for detailed information.
|
||||
|
||||
|
||||
## Media Control Keys in Mac OSX
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Advanced Keycodes
|
||||
|
||||
Your keymap can include keycodes that are more advanced than normal, for example shifted keys. This page documents the functions that are available to you.
|
||||
Your keymap can include keycodes that are more advanced than normal, for example keys that switch layers or send modifiers when held, but send regular keycodes when tapped. This page documents the functions that are available to you.
|
||||
|
||||
### Assigning Custom Names
|
||||
|
||||
@ -73,34 +73,6 @@ You can also chain these, like this:
|
||||
|
||||
LALT(LCTL(KC_DEL)) -- this makes a key that sends Alt, Control, and Delete in a single keypress.
|
||||
|
||||
# Shifted Keycodes
|
||||
|
||||
The following shortcuts automatically add `LSFT()` to keycodes to get commonly used symbols.
|
||||
|
||||
|Key |Aliases |Description |
|
||||
|------------------------|------------------|-------------------|
|
||||
|`KC_TILDE` |`KC_TILD` |`~` |
|
||||
|`KC_EXCLAIM` |`KC_EXLM` |`!` |
|
||||
|`KC_AT` | |`@` |
|
||||
|`KC_HASH` | |`#` |
|
||||
|`KC_DOLLAR` |`KC_DLR` |`$` |
|
||||
|`KC_PERCENT` |`KC_PERC` |`%` |
|
||||
|`KC_CIRCUMFLEX` |`KC_CIRC` |`^` |
|
||||
|`KC_AMPERSAND` |`KC_AMPR` |`&` |
|
||||
|`KC_ASTERISK` |`KC_ASTR` |`*` |
|
||||
|`KC_LEFT_PAREN` |`KC_LPRN` |`(` |
|
||||
|`KC_RIGHT_PAREN` |`KC_RPRN` |`)` |
|
||||
|`KC_UNDERSCORE` |`KC_UNDS` |`_` |
|
||||
|`KC_PLUS` | |`+` |
|
||||
|`KC_LEFT_CURLY_BRACE` |`KC_LCBR` |`{` |
|
||||
|`KC_RIGHT_CURLY_BRACE` |`KC_RCBR` |`}` |
|
||||
|`KC_PIPE` | |<code>|</code>|
|
||||
|`KC_COLON` |`KC_COLN` |`:` |
|
||||
|`KC_DOUBLE_QUOTE` |`KC_DQT`/`KC_DQUO`|`"` |
|
||||
|`KC_LEFT_ANGLE_BRACKET` |`KC_LT`/`KC_LABK` |`<` |
|
||||
|`KC_RIGHT_ANGLE_BRACKET`|`KC_GT`/`KC_RABK` |`>` |
|
||||
|`KC_QUESTION` |`KC_QUES` |`?` |
|
||||
|
||||
# Mod Tap
|
||||
|
||||
`MT(mod, kc)` - is *mod* (modifier key - MOD_LCTL, MOD_LSFT) when held, and *kc* when tapped. In other words, you can have a key that sends Esc (or the letter O or whatever) when you tap it, but works as a Control key or a Shift key when you hold it down.
|
||||
|
@ -51,3 +51,22 @@ In this way `OCRxx` essentially controls the duty cycle of the LEDs, and thus th
|
||||
|
||||
The breathing effect is achieved by registering an interrupt handler for `TIMER1_OVF_vect` that is called whenever the counter resets, roughly 244 times per second.
|
||||
In this handler, the value of an incrementing counter is mapped onto a precomputed brightness curve. To turn off breathing, the interrupt handler is simply disabled, and the brightness reset to the level stored in EEPROM.
|
||||
|
||||
## Backlight Functions
|
||||
|
||||
|Function |Description |
|
||||
|----------|----------------------------------------------------------|
|
||||
|`backlight_toggle()` |Turn the backlight on or off |
|
||||
|`backlight_step()` |Cycle through backlight levels |
|
||||
|`backlight_increase()` |Increase the backlight level |
|
||||
|`backlight_decrease()` |Decrease the backlight level |
|
||||
|`backlight_level(x)` |Sets the backlight level to specified level |
|
||||
|`get_backlight_level()`|Toggle backlight breathing |
|
||||
|
||||
### Backlight Breathing Functions
|
||||
|
||||
|Function |Description |
|
||||
|----------|----------------------------------------------------------|
|
||||
|`breathing_toggle()` |Turn the backlight breathing on or off |
|
||||
|`breathing_enable()` |Turns on backlight breathing |
|
||||
|`breathing_disable()` |Turns off backlight breathing |
|
||||
|
@ -1,8 +1,12 @@
|
||||
# RGB Matrix Lighting
|
||||
|
||||
## Driver configuration
|
||||
|
||||
### IS31FL3731
|
||||
|
||||
There is basic support for addressable RGB matrix lighting with the I2C IS31FL3731 RGB controller. To enable it, add this to your `rules.mk`:
|
||||
|
||||
RGB_MATRIX_ENABLE = yes
|
||||
RGB_MATRIX_ENABLE = IS31FL3731
|
||||
|
||||
Configure the hardware via your `config.h`:
|
||||
|
||||
@ -36,7 +40,51 @@ Define these arrays listing all the LEDs in your `<keyboard>.c`:
|
||||
....
|
||||
}
|
||||
|
||||
Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](http://www.issi.com/WW/pdf/31FL3731.pdf). The `driver` is the index of the driver you defined in your `config.h` (`0` or `1` right now).
|
||||
Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](http://www.issi.com/WW/pdf/31FL3731.pdf) and the header file `drivers/issi/is31fl3731.h`. The `driver` is the index of the driver you defined in your `config.h` (`0` or `1` right now).
|
||||
|
||||
### IS31FL3733
|
||||
|
||||
There is basic support for addressable RGB matrix lighting with the I2C IS31FL3733 RGB controller. To enable it, add this to your `rules.mk`:
|
||||
|
||||
RGB_MATRIX_ENABLE = IS31FL3733
|
||||
|
||||
Configure the hardware via your `config.h`:
|
||||
|
||||
// This is a 7-bit address, that gets left-shifted and bit 0
|
||||
// set to 0 for write, 1 for read (as per I2C protocol)
|
||||
// The address will vary depending on your wiring:
|
||||
// 00 <-> GND
|
||||
// 01 <-> SCL
|
||||
// 10 <-> SDA
|
||||
// 11 <-> VCC
|
||||
// ADDR1 represents A1:A0 of the 7-bit address.
|
||||
// ADDR2 represents A3:A2 of the 7-bit address.
|
||||
// The result is: 0b101(ADDR2)(ADDR1)
|
||||
#define DRIVER_ADDR_1 0b1010000
|
||||
#define DRIVER_ADDR_2 0b1010000 // this is here for compliancy reasons.
|
||||
|
||||
#define DRIVER_COUNT 1
|
||||
#define DRIVER_1_LED_TOTAL 64
|
||||
#define DRIVER_LED_TOTAL DRIVER_1_LED_TOTAL
|
||||
|
||||
Currently only a single drivers is supported, but it would be trivial to support all 4 combinations. For now define `DRIVER_ADDR_2` as `DRIVER_ADDR_1`
|
||||
|
||||
Define these arrays listing all the LEDs in your `<keyboard>.c`:
|
||||
|
||||
const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
|
||||
/* Refer to IS31 manual for these locations
|
||||
* driver
|
||||
* | R location
|
||||
* | | G location
|
||||
* | | | B location
|
||||
* | | | | */
|
||||
{0, B_1, A_1, C_1},
|
||||
....
|
||||
}
|
||||
|
||||
Where `X_Y` is the location of the LED in the matrix defined by [the datasheet](http://www.issi.com/WW/pdf/31FL3733.pdf) and the header file `drivers/issi/is31fl3733.h`. The `driver` is the index of the driver you defined in your `config.h` (Only `0` right now).
|
||||
|
||||
From this point forward the configuration is the same for all the drivers.
|
||||
|
||||
const rgb_led g_rgb_leds[DRIVER_LED_TOTAL] = {
|
||||
/* {row | col << 4}
|
||||
@ -80,7 +128,7 @@ All RGB keycodes are currently shared with the RGBLIGHT system:
|
||||
These are the effects that are currently available:
|
||||
|
||||
enum rgb_matrix_effects {
|
||||
RGB_MATRIX_SOLID_COLOR = 1,
|
||||
RGB_MATRIX_SOLID_COLOR = 1,
|
||||
RGB_MATRIX_ALPHAS_MODS,
|
||||
RGB_MATRIX_DUAL_BEACON,
|
||||
RGB_MATRIX_GRADIENT_UP_DOWN,
|
||||
@ -93,7 +141,7 @@ These are the effects that are currently available:
|
||||
RGB_MATRIX_RAINBOW_MOVING_CHEVRON,
|
||||
RGB_MATRIX_JELLYBEAN_RAINDROPS,
|
||||
#ifdef RGB_MATRIX_KEYPRESSES
|
||||
RGB_MATRIX_SOLID_REACTIVE,
|
||||
RGB_MATRIX_SOLID_REACTIVE,
|
||||
RGB_MATRIX_SPLASH,
|
||||
RGB_MATRIX_MULTISPLASH,
|
||||
RGB_MATRIX_SOLID_SPLASH,
|
||||
@ -107,7 +155,7 @@ These are the effects that are currently available:
|
||||
Custom layer effects can be done by defining this in your `<keyboard>.c`:
|
||||
|
||||
void rgb_matrix_indicators_kb(void) {
|
||||
// rgb_matrix_set_color(index, red, green, blue);
|
||||
rgb_matrix_set_color(index, red, green, blue);
|
||||
}
|
||||
|
||||
A similar function works in the keymap as `rgb_matrix_indicators_user`.
|
||||
|
@ -1,131 +1,46 @@
|
||||
# RGB Lighting
|
||||
|
||||
If you've installed addressable RGB lights on your keyboard you can control them with QMK. Currently we support the following addressable LEDs on Atmel AVR processors:
|
||||
QMK has the ability to control RGB LEDs attached to your keyboard. This is commonly called *underglow*, due to the LEDs often being mounted on the bottom of the keyboard, producing a nice diffused effect when combined with a translucent case.
|
||||
|
||||
* WS2811 and variants (WS2812, WS2812B, WS2812C, etc)
|
||||
* SK6812RGBW
|
||||

|
||||
|
||||
Some keyboards come with RGB LEDs pre-installed. Others have to have LEDs installed after the fact. See below for information on modifying your keyboard.
|
||||
Some keyboards come with RGB LEDs preinstalled. Others must have them installed after the fact. See the [Hardware Modification](#hardware-modification) section for information on adding RGB lighting to your keyboard.
|
||||
|
||||
## Selecting Colors
|
||||
Currently QMK supports the following addressable LEDs on AVR microcontrollers (however, the white LED in RGBW variants is not supported):
|
||||
|
||||
QMK uses Hue, Saturation, and Value to set color rather than using RGB. You can use the color wheel below to see how this works. Changing the Hue will cycle around the circle. Saturation will affect the intensity of the color, which you can see as you move from the inner part to the outer part of the wheel. Value sets the overall brightness.
|
||||
* WS2811, WS2812, WS2812B, WS2812C, etc.
|
||||
* SK6812, SK6812MINI, SK6805
|
||||
|
||||
<img src="gitbook/images/color-wheel.svg" alt="HSV Color Wheel" width="250">
|
||||
These LEDs are called "addressable" because instead of using a wire per color, each LED contains a small microchip that understands a special protocol sent over a single wire. The chip passes on the remaining data to the next LED, allowing them to be chained together. In this way, you can easily control the color of the individual LEDs.
|
||||
|
||||
If you would like to learn more about HSV you can start with the [Wikipedia article](https://en.wikipedia.org/wiki/HSL_and_HSV).
|
||||
## Usage
|
||||
|
||||
## Configuration
|
||||
On keyboards with onboard RGB LEDs, it is usually enabled by default. If it is not working for you, check that your `rules.mk` includes the following:
|
||||
|
||||
Before RGB Lighting can be used you have to enable it in `rules.mk`:
|
||||
|
||||
RGBLIGHT_ENABLE = yes
|
||||
|
||||
You can configure the behavior of the RGB lighting by defining values inside `config.h`.
|
||||
|
||||
### Required Configuration
|
||||
|
||||
At minimum you have to define the pin your LED strip is connected to and the number of LEDs connected.
|
||||
|
||||
```c
|
||||
#define RGB_DI_PIN D7 // The pin the LED strip is connected to
|
||||
#define RGBLED_NUM 14 // Number of LEDs in your strip
|
||||
```make
|
||||
RGBLIGHT_ENABLE = yes
|
||||
```
|
||||
|
||||
### Optional Configuration
|
||||
At minimum you must define the data pin your LED strip is connected to, and the number of LEDs in the strip, in your `config.h`. If your keyboard has onboard RGB LEDs, and you are simply creating a keymap, you usually won't need to modify these.
|
||||
|
||||
You can change the behavior of the RGB Lighting by setting these configuration values. Use `#define <Option> <Value>` in a `config.h` at the keyboard, revision, or keymap level.
|
||||
|Define |Description |
|
||||
|------------|---------------------------------------------|
|
||||
|`RGB_DI_PIN`|The pin connected to the data pin of the LEDs|
|
||||
|`RGBLED_NUM`|The number of LEDs connected |
|
||||
|
||||
| Option | Default Value | Description |
|
||||
|--------|---------------|-------------|
|
||||
| `RGBLIGHT_HUE_STEP` | 10 | How many hues you want to have available. |
|
||||
| `RGBLIGHT_SAT_STEP` | 17 | How many steps of saturation you'd like. |
|
||||
| `RGBLIGHT_VAL_STEP` | 17 | The number of levels of brightness you want. |
|
||||
| `RGBLIGHT_LIMIT_VAL` | 255 | Limit the val of HSV to limit the maximum brightness simply. |
|
||||
| `RGBLIGHT_SLEEP` | | `#define` this will shut off the lights when the host goes to sleep |
|
||||
Then you should be able to use the keycodes below to change the RGB lighting to your liking.
|
||||
|
||||
### Color Selection
|
||||
|
||||
### Animations
|
||||
QMK uses [Hue, Saturation, and Value](https://en.wikipedia.org/wiki/HSL_and_HSV) to select colors rather than RGB. The color wheel below demonstrates how this works.
|
||||
|
||||
If you have `#define RGBLIGHT_ANIMATIONS` in your `config.h` you will have a number of animation modes you can cycle through using the `RGB_MOD` key. You can also `#define` other options to tweak certain animations.
|
||||
<img src="gitbook/images/color-wheel.svg" alt="HSV Color Wheel" width="250"/>
|
||||
|
||||
| Option | Default Value | Description |
|
||||
|--------|---------------|-------------|
|
||||
| `RGBLIGHT_ANIMATIONS` | | `#define` this to enable animation modes. |
|
||||
| `RGBLIGHT_EFFECT_BREATHE_CENTER` | 1.85 | Used to calculate the curve for the breathing animation. Valid values 1.0-2.7. |
|
||||
| `RGBLIGHT_EFFECT_BREATHE_MAX` | 255 | The maximum brightness for the breathing mode. Valid values 1-255. |
|
||||
| `RGBLIGHT_EFFECT_SNAKE_LENGTH` | 4 | The number of LEDs to light up for the "snake" animation. |
|
||||
| `RGBLIGHT_EFFECT_KNIGHT_LENGTH` | 3 | The number of LEDs to light up for the "knight" animation. |
|
||||
| `RGBLIGHT_EFFECT_KNIGHT_OFFSET` | 0 | Start the knight animation this many LEDs from the start of the strip. |
|
||||
| `RGBLIGHT_EFFECT_KNIGHT_LED_NUM` | RGBLED_NUM | The number of LEDs to have the "knight" animation travel. |
|
||||
| `RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL` | 1000 | How long to wait between light changes for the "christmas" animation. Specified in ms. |
|
||||
| `RGBLIGHT_EFFECT_CHRISTMAS_STEP` | 2 | How many LED's to group the red/green colors by for the christmas mode. |
|
||||
Changing the **Hue** cycles around the circle.
|
||||
Changing the **Saturation** moves between the inner and outer sections of the wheel, affecting the intensity of the color.
|
||||
Changing the **Value** sets the overall brightness.
|
||||
|
||||
You can also tweak the behavior of the animations by defining these consts in your `keymap.c`. These mostly affect the speed different modes animate at.
|
||||
|
||||
```c
|
||||
// How long (in ms) to wait between animation steps for the breathing mode
|
||||
const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5};
|
||||
|
||||
// How long (in ms) to wait between animation steps for the rainbow mode
|
||||
const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[] PROGMEM = {120, 60, 30};
|
||||
|
||||
// How long (in ms) to wait between animation steps for the swirl mode
|
||||
const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {100, 50, 20};
|
||||
|
||||
// How long (in ms) to wait between animation steps for the snake mode
|
||||
const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20};
|
||||
|
||||
// How long (in ms) to wait between animation steps for the knight modes
|
||||
const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {127, 63, 31};
|
||||
|
||||
// These control which colors are selected for the gradient mode
|
||||
const uint16_t RGBLED_GRADIENT_RANGES[] PROGMEM = {360, 240, 180, 120, 90};
|
||||
```
|
||||
|
||||
### LED Control
|
||||
|
||||
Look in `rgblights.h` for all available functions, but if you want to control all or some LEDs your goto functions are:
|
||||
|
||||
```c
|
||||
// turn all lights off (stored in EEPROM)
|
||||
rgblight_disable();
|
||||
// turn lights on, based on their previous state (stored in EEPROM)
|
||||
rgblight_enable();
|
||||
|
||||
// turn all lights off (not stored in EEPROM)
|
||||
rgblight_disable_noeeprom();
|
||||
// turn lights on, based on their previous state (not stored in EEPROM)
|
||||
rgblight_enable_noeeprom();
|
||||
|
||||
// where r/g/b is a number from 0..255. Turns all the LEDs to this color (ignores mode, not stored in EEPROM).
|
||||
rgblight_setrgb(r, g, b);
|
||||
// HSV color control - h is a value from 0..360 and s/v is a value from 0..255 (stored in EEPROM)
|
||||
rgblight_sethsv(h, s, v);
|
||||
// HSV color control - h is a value from 0..360 and s/v is a value from 0..255 (not stored in EEPROM)
|
||||
rgblight_sethsv_noeeprom(h, s, v);
|
||||
|
||||
// Sets the mode, if rgb animations are enabled (stored in eeprom)
|
||||
rgblight_mode(x);
|
||||
// Sets the mode, if rgb animations are enabled (not stored in eeprom)
|
||||
rgblight_mode_noeeprom(x);
|
||||
// MODE 1, solid color
|
||||
// MODE 2-5, breathing
|
||||
// MODE 6-8, rainbow mood
|
||||
// MODE 9-14, rainbow swirl
|
||||
// MODE 15-20, snake
|
||||
// MODE 21-23, knight
|
||||
// MODE 24, xmas
|
||||
// MODE 25-34, static rainbow
|
||||
|
||||
rgblight_setrgb_at(r,g,b, LED); // control a single LED. 0 <= LED < RGBLED_NUM
|
||||
rgblight_sethsv_at(h,s,v, LED); // control a single LED. 0 <= LED < RGBLED_NUM
|
||||
```
|
||||
You can find a list of predefined colors at [`quantum/rgblight_list.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/rgblight_list.h). Free to add to this list!
|
||||
|
||||
## RGB Lighting Keycodes
|
||||
|
||||
These control the RGB Lighting functionality.
|
||||
## Keycodes
|
||||
|
||||
|Key |Aliases |Description |
|
||||
|-------------------|----------|--------------------------------------------------------------------|
|
||||
@ -146,25 +61,97 @@ These control the RGB Lighting functionality.
|
||||
|`RGB_MODE_KNIGHT` |`RGB_M_K` |"Knight Rider" animation mode |
|
||||
|`RGB_MODE_XMAS` |`RGB_M_X` |Christmas animation mode |
|
||||
|`RGB_MODE_GRADIENT`|`RGB_M_G` |Static gradient animation mode |
|
||||
|`RGB_MODE_RGBTEST `|`RGB_M_T` |Red,Green,Blue test animation mode |
|
||||
|`RGB_MODE_RGBTEST` |`RGB_M_T` |Red, Green, Blue test animation mode |
|
||||
|
||||
note: for backwards compatibility, `RGB_SMOD` is an alias for `RGB_MOD`.
|
||||
?> For backwards compatibility, `RGB_SMOD` is another alias of `RGB_MOD`.
|
||||
|
||||
## Configuration
|
||||
|
||||
Your RGB lighting can be configured by placing these `#define`s in your `config.h`:
|
||||
|
||||
|Define |Default |Description |
|
||||
|---------------------|-------------|-----------------------------------------------------------------------------|
|
||||
|`RGBLIGHT_HUE_STEP` |`10` |The number of steps to cycle through the hue by |
|
||||
|`RGBLIGHT_SAT_STEP` |`17` |The number of steps to increment the saturation by |
|
||||
|`RGBLIGHT_VAL_STEP` |`17` |The number of steps to increment the brightness by |
|
||||
|`RGBLIGHT_LIMIT_VAL` |`255` |The maximum brightness level |
|
||||
|`RGBLIGHT_SLEEP` |*Not defined*|If defined, the RGB lighting will be switched off when the host goes to sleep|
|
||||
|
||||
## Animations
|
||||
|
||||
Not only can this lighting be whatever color you want, if `RGBLIGHT_ANIMATIONS` is defined, you also have a number of animation modes at your disposal:
|
||||
|
||||
|Mode |Description |
|
||||
|-----|---------------------|
|
||||
|1 |Solid color |
|
||||
|2-5 |Solid color breathing|
|
||||
|6-8 |Cycling rainbow |
|
||||
|9-14 |Swirling rainbow |
|
||||
|15-20|Snake |
|
||||
|21-23|Knight |
|
||||
|24 |Christmas |
|
||||
|25-34|Static gradient |
|
||||
|35 |RGB Test |
|
||||
|36 |Alternating |
|
||||
|
||||
Check out [this video](https://youtube.com/watch?v=VKrpPAHlisY) for a demonstration.
|
||||
|
||||
The following options can be used to tweak the various animations:
|
||||
|
||||
|Define |Default |Description |
|
||||
|------------------------------------|-------------|-------------------------------------------------------------------------------------|
|
||||
|`RGBLIGHT_ANIMATIONS` |*Not defined*|If defined, enables additional animation modes |
|
||||
|`RGBLIGHT_EFFECT_BREATHE_CENTER` |`1.85` |Used to calculate the curve for the breathing animation. Valid values are 1.0 to 2.7 |
|
||||
|`RGBLIGHT_EFFECT_BREATHE_MAX` |`255` |The maximum brightness for the breathing mode. Valid values are 1 to 255 |
|
||||
|`RGBLIGHT_EFFECT_SNAKE_LENGTH` |`4` |The number of LEDs to light up for the "Snake" animation |
|
||||
|`RGBLIGHT_EFFECT_KNIGHT_LENGTH` |`3` |The number of LEDs to light up for the "Knight" animation |
|
||||
|`RGBLIGHT_EFFECT_KNIGHT_OFFSET` |`0` |The number of LEDs to start the "Knight" animation from the start of the strip by |
|
||||
|`RGBLIGHT_EFFECT_KNIGHT_LED_NUM` |`RGBLED_NUM` |The number of LEDs to have the "Knight" animation travel |
|
||||
|`RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL`|`1000` |How long to wait between light changes for the "Christmas" animation, in milliseconds|
|
||||
|`RGBLIGHT_EFFECT_CHRISTMAS_STEP` |`2` |The number of LEDs to group the red/green colors by for the "Christmas" animation |
|
||||
|
||||
You can also modify the speeds that the different modes animate at:
|
||||
|
||||
```c
|
||||
// How long (in milliseconds) to wait between animation steps for each of the "Solid color breathing" animations
|
||||
const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5};
|
||||
|
||||
// How long (in milliseconds) to wait between animation steps for each of the "Cycling rainbow" animations
|
||||
const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[] PROGMEM = {120, 60, 30};
|
||||
|
||||
// How long (in milliseconds) to wait between animation steps for each of the "Swirling rainbow" animations
|
||||
const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {100, 50, 20};
|
||||
|
||||
// How long (in milliseconds) to wait between animation steps for each of the "Snake" animations
|
||||
const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20};
|
||||
|
||||
// How long (in milliseconds) to wait between animation steps for each of the "Knight" animations
|
||||
const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {127, 63, 31};
|
||||
|
||||
// These control which hues are selected for each of the "Static gradient" modes
|
||||
const uint16_t RGBLED_GRADIENT_RANGES[] PROGMEM = {360, 240, 180, 120, 90};
|
||||
```
|
||||
|
||||
## Functions
|
||||
|
||||
If you need to change your RGB lighting in code, for example in a macro to change the color whenever you switch layers, QMK provides a set of functions to assist you. See [`rgblight.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/rgblight.h) for the full list, but the most commonly used functions include:
|
||||
|
||||
|Function |Description |
|
||||
|-----------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
|`rgblight_enable()` |Turn LEDs on, based on their previous state |
|
||||
|`rgblight_enable_noeeprom()` |Turn LEDs on, based on their previous state (not written to EEPROM) |
|
||||
|`rgblight_disable()` |Turn LEDs off |
|
||||
|`rgblight_disable_noeeprom()` |Turn LEDs off (not written to EEPROM) |
|
||||
|`rgblight_mode(x)` |Set the mode, if RGB animations are enabled |
|
||||
|`rgblight_mode_noeeprom(x)` |Set the mode, if RGB animations are enabled (not written to EEPROM) |
|
||||
|`rgblight_setrgb(r, g, b)` |Set all LEDs to the given RGB value where `r`/`g`/`b` are between 0 and 255 (not written to EEPROM) |
|
||||
|`rgblight_setrgb_at(r, g, b, led)` |Set a single LED to the given RGB value, where `r`/`g`/`b` are between 0 and 255 and `led` is between 0 and `RGBLED_NUM` (not written to EEPROM) |
|
||||
|`rgblight_sethsv(h, s, v)` |Set all LEDs to the given HSV value where `h` is between 0 and 360 and `s`/`v` are between 0 and 255 |
|
||||
|`rgblight_sethsv_noeeprom(h, s, v)`|Set all LEDs to the given HSV value where `h` is between 0 and 360 and `s`/`v` are between 0 and 255 (not written to EEPROM) |
|
||||
|`rgblight_sethsv_at(h, s, v, led)` |Set a single LED to the given HSV value, where `h` is between 0 and 360, `s`/`v` are between 0 and 255, and `led` is between 0 and `RGBLED_NUM` (not written to EEPROM)|
|
||||
|
||||
Additionally, [`rgblight_list.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/rgblight_list.h) defines several predefined shortcuts for various colors. Feel free to add to this list!
|
||||
|
||||
## Hardware Modification
|
||||
|
||||

|
||||
|
||||
Here is a quick demo on Youtube (with NPKC KC60) (https://www.youtube.com/watch?v=VKrpPAHlisY).
|
||||
|
||||
For this mod, you need an unused pin wiring to DI of WS2812 strip. After wiring the VCC, GND, and DI, you can enable the underglow in your Makefile.
|
||||
|
||||
RGBLIGHT_ENABLE = yes
|
||||
|
||||
In order to use the underglow animation functions, you need to have `#define RGBLIGHT_ANIMATIONS` in your `config.h`.
|
||||
|
||||
Please add the following options into your config.h, and set them up according your hardware configuration. These settings are for the `F4` pin by default:
|
||||
|
||||
#define RGB_DI_PIN F4 // The pin your RGB strip is wired to
|
||||
#define RGBLED_NUM 14 // Number of LEDs
|
||||
|
||||
You'll need to edit `RGB_DI_PIN` to the pin you have your `DI` on your RGB strip wired to.
|
||||
If your keyboard lacks onboard underglow LEDs, you may often be able to solder on an RGB LED strip yourself. You will need to find an unused pin to wire to the data pin of your LED strip. Some keyboards may break out unused pins from the MCU to make soldering easier. The other two pins, VCC and GND, must also be connected to the appropriate power pins.
|
||||
|
@ -22,9 +22,9 @@ Note that the array indices are reversed same as the matrix and the values are o
|
||||
|Key |Description |
|
||||
|-----------|-------------------------------------------------------------------------|
|
||||
|`SH_T(key)`|Sends `key` with a tap; momentary swap when held. |
|
||||
|`SW_ON` |Turns on swapping and leaves it on. |
|
||||
|`SW_OFF` |Turn off swapping and leaves it off. Good for returning to a known state.|
|
||||
|`SW_MON` |Swaps hands when pressed, returns to normal when released (momentary). |
|
||||
|`SW_MOFF` |Momentarily turns off swap. |
|
||||
|`SH_ON` |Turns on swapping and leaves it on. |
|
||||
|`SH_OFF` |Turn off swapping and leaves it off. Good for returning to a known state.|
|
||||
|`SH_MON` |Swaps hands when pressed, returns to normal when released (momentary). |
|
||||
|`SH_MOFF` |Momentarily turns off swap. |
|
||||
|`SH_TG` |Toggles swap on and off with every key press. |
|
||||
|`SH_TT` |Toggles with a tap; momentary when held. |
|
||||
|
@ -3,7 +3,7 @@
|
||||
QMK has a staggering number of features for building your keyboard. It can take some time to understand all of them and determine which one will achieve your goal.
|
||||
|
||||
|
||||
* [Advanced Keycodes](feature_advanced_keycodes.md) - Change layers, type shifted keys, and more. Go beyond typing simple characters.
|
||||
* [Advanced Keycodes](feature_advanced_keycodes.md) - Change layers, dual-action keys, and more. Go beyond typing simple characters.
|
||||
* [Audio](feature_audio.md) - Connect a speaker to your keyboard for audio feedback, midi support, and music mode.
|
||||
* [Auto Shift](feature_auto_shift.md) - Tap for the normal key, hold slightly longer for its shifted state.
|
||||
* [Backlight](feature_backlight.md) - LED lighting support for your keyboard.
|
||||
|
@ -25,3 +25,11 @@ You can make use of uGFX within QMK to drive character and graphic LCD's, LED ar
|
||||
## WS2812 (AVR Only)
|
||||
|
||||
Support for WS2811/WS2812{a,b,c} LED's. For more information see the [RGB Light](feature_rgblight.md) page.
|
||||
|
||||
## IS31FL3731
|
||||
|
||||
Support for up to 2 drivers. Each driver impliments 2 charlieplex matrices to individually address LEDs using I2C. This allows up to 144 same color LEDs or 32 RGB LEDs. For more information on how to setup the driver see the [RGB Matrix](feature_rgb_matrix.md) page.
|
||||
|
||||
## IS31FL3733
|
||||
|
||||
Support for up to a single driver with room for expansion. Each driver can control 192 individual LEDs or 64 RGB LEDs. For more information on how to setup the driver see the [RGB Matrix](feature_rgb_matrix.md) page.
|
@ -19,58 +19,79 @@ If you're having trouble flashing/erasing your board, and running into cryptic e
|
||||
Memory write error, use debug for more info.
|
||||
commands.c:360: Error writing memory data. (err -4)
|
||||
|
||||
You're likely going to need to ISP flash your board/device to get it working again. Luckily, this process is pretty straight-forward, provided you have any extra programmable keyboard, Arduino, or Teensy 2.0/Teensy 2.0++. There are also dedicated ISP flashers available for this, but most cost >$15, and it's assumed that if you are googling this error, this is the first you've heard about ISP flashing, and don't have one readily available (whereas you might have some other AVR board). __We'll be using a Teensy 2.0 with Windows 10 in this guide__ - if you are comfortable doing this on another system, please consider editing this guide and contributing those instructions!
|
||||
You're likely going to need to ISP flash your board/device to get it working again. Luckily, this process is pretty straight-forward, provided you have any extra programmable keyboard, Pro Micro, or Teensy 2.0/Teensy 2.0++. There are also dedicated ISP flashers available for this, but most cost >$15, and it's assumed that if you are googling this error, this is the first you've heard about ISP flashing, and don't have one readily available (whereas you might have some other AVR board). __We'll be using a Teensy 2.0 or Pro Micro with Windows 10 in this guide__ - if you are comfortable doing this on another system, please consider editing this guide and contributing those instructions!
|
||||
|
||||
## Software Needed
|
||||
|
||||
* [The Arduino IDE](https://www.arduino.cc/en/Main/Software)
|
||||
* [Teensyduino](https://www.pjrc.com/teensy/td_download.html) (if you're using a Teensy)
|
||||
* [WinAVR](http://www.ladyada.net/learn/avr/setup-win.html) (Windows)
|
||||
* [Teensy Loader](https://www.pjrc.com/teensy/loader.html) (if using a Teensy)
|
||||
* QMK Toolbox (flash as usual - be sure to select the correct MCU) or `avrdude` via [WinAVR](http://www.ladyada.net/learn/avr/setup-win.html) (for Teensy & Pro Micro)
|
||||
|
||||
## Wiring
|
||||
|
||||
This is pretty straight-forward - we'll be connecting like-things to like-things in the following manner:
|
||||
|
||||
Flasher B0 <-> Keyboard RESET
|
||||
Flasher B1 <-> Keyboard B1 (SCLK)
|
||||
Flasher B2 <-> Keyboard B2 (MOSI)
|
||||
Flasher B3 <-> Keyboard B3 (MISO)
|
||||
Flasher VCC <-> Keyboard VCC
|
||||
Flasher GND <-> Keyboard GND
|
||||
### Teensy 2.0
|
||||
|
||||
## The ISP Firmware
|
||||
Teensy B0 <-> Keyboard RESET
|
||||
Teensy B1 <-> Keyboard B1 (SCLK)
|
||||
Teensy B2 <-> Keyboard B2 (MOSI)
|
||||
Teensy B3 <-> Keyboard B3 (MISO)
|
||||
Teensy VCC <-> Keyboard VCC
|
||||
Teensy GND <-> Keyboard GND
|
||||
|
||||
### Pro Micro
|
||||
|
||||
Pro Micro 10 (B6) <-> Keyboard RESET
|
||||
Pro Micro 15 (B1) <-> Keyboard B1 (SCLK)
|
||||
Pro Micro 16 (B2) <-> Keyboard B2 (MOSI)
|
||||
Pro Micro 14 (B3) <-> Keyboard B3 (MISO)
|
||||
Pro Micro VCC <-> Keyboard VCC
|
||||
Pro Micro GND <-> Keyboard GND
|
||||
|
||||
## The ISP Firmware (now pre-compiled)
|
||||
|
||||
The only difference between the .hex files below is which pin is connected to RESET. You can use them on other boards as well, as long as you're aware of the pins being used. If for some reason neither of these pins are available, [create an issue](https://github.com/qmk/qmk_firmware/issues/new), and we can generate one for you!
|
||||
|
||||
* Teensy 2.0: [`util/teensy_2.0_ISP_B0.hex`](https://github.com/qmk/qmk_firmware/blob/master/util/teensy_2.0_ISP_B0.hex) (`B0`)
|
||||
* Pro Micro: [`util/pro_micro_ISP_B6_10.hex`](https://github.com/qmk/qmk_firmware/blob/master/util/pro_mico_ISP_B6_10.hex) (`B6/10`)
|
||||
|
||||
**Flash your Teenys/Pro Micro with one of these and continue - you won't need the file after flashing your ISP device.**
|
||||
|
||||
## Just the Bootloader File
|
||||
|
||||
If you just want to get things back to normal, you can flash only a bootloader from [`util/` folder](https://github.com/qmk/qmk_firmware/tree/master/util), and use your normal process to flash the firmware afterwards. Be sure to flash the correct bootloader for your chip:
|
||||
|
||||
* [`atmega32u4`](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_atmega32u4_1_0_0.hex) - Most keyboards, Planck Rev 1-5, Preonic Rev 1-2
|
||||
* [`at90usb1286`](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_at90usb128x_1_0_1.hex) - Planck Light Rev 1
|
||||
|
||||
If you're not sure what your board uses, look in the `rules.mk` file for the keyboard in QMK. The `MCU =` line will have the value you need. It may differ between different versions of the board.
|
||||
|
||||
### Advanced/Production Techniques
|
||||
|
||||
If you'd like to flash both the bootloader **and** the regular firmware at the same time, you need to combine the files.
|
||||
|
||||
1. Open the original firmware .hex file in a text editor
|
||||
2. Remove the last line (which should be `:00000001FF` - this is an EOF message)
|
||||
3. Copy the entire bootloader's contents onto a new line (with no empty lines between) and paste it at the end of the original file
|
||||
4. Save it as a new file by naming it `<keyboard>_<keymap>_production.hex`
|
||||
|
||||
It's possible to use other bootloaders here in the same way, but __you need a bootloader__, otherwise you'll have to use ISP again to write new firmware to your keyboard.
|
||||
|
||||
## Flashing Your Bootloader/Production File
|
||||
|
||||
Make sure your keyboard is unplugged from any device, and plug in your Teensy.
|
||||
|
||||
1. Run Arduino after you have everything installed
|
||||
2. Select `Tools > Board * > Teensy 2.0`
|
||||
3. Click `File > Examples > 11.ArduinoISP > ArduinoISP`
|
||||
### QMK Toolbox
|
||||
|
||||
Then scroll down until you see something that looks like this block of code:
|
||||
1. `AVRISP device connected` will show up in yellow
|
||||
2. Select the correct bootloader/production .hex file with the `Open` dialog (spaces can't be in the path)
|
||||
3. Be sure the correct `Microcontroller` option is selected
|
||||
4. Hit `Flash`
|
||||
5. Wait, as nothing will output for a while, especially with production files
|
||||
|
||||
// Configure which pins to use:
|
||||
If the verification and fuse checks are ok, you're done! Your board may restart automatically, otherwise, unplug your Teensy and plug in your keyboard - you can leave your Teensy wired to your keyboard while testing things, but it's recommended that you desolder it/remove the wiring once you're sure everything works.
|
||||
|
||||
// The standard pin configuration.
|
||||
#ifndef ARDUINO_HOODLOADER2
|
||||
|
||||
#define RESET 0 // Use 0 (B0) instead of 10
|
||||
#define LED_HB 11 // Use 11 (LED on the Teensy 2.0)
|
||||
#define LED_ERR 8 // This won't be used unless you have an LED hooked-up to 8 (D3)
|
||||
#define LED_PMODE 7 // This won't be used unless you have an LED hooked-up to 7 (D2)
|
||||
|
||||
And make the changes in the last four lines. If you're using something besides the Teensy 2.0, you'll want to choose something else that makes sense for `LED_HB`. We define `RESET` as `0`/`B0` because that's what's close - if you want to use another pin for some reason, [you can use the pinouts to choose something else](https://www.pjrc.com/teensy/pinout.html).
|
||||
|
||||
Once you've made your changes, you can click the Upload button (right arrow), which will open up the Teensy flasher app - you'll need to press the reset button on the Teensy the first time, but after that, it's automatic (you shouldn't be flashing this more than once, though). Once flashed, the orange LED on the Teensy will flash on and off, indicating it's ready for some action.
|
||||
|
||||
## The `.hex` File
|
||||
|
||||
Before flashing your firmware, you're going to need to and do a little preparation. We'll be appending [this bootloader (also a .hex file)](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_atmega32u4_1_0_0.hex) to the end of our firmware by opening the original .hex file in a text editor, and removing the last line, which should be `:00000001FF` (this is an EOF message). After that's been removed, copy the entire bootloader's contents and paste it at the end of the original file, and save it.
|
||||
|
||||
It's possible to use other bootloaders here in the same way, but __you need a bootloader__, otherwise you'll have to ISP to write new firmware to your keyboard.
|
||||
|
||||
## Flashing Your Firmware
|
||||
|
||||
Make sure your keyboard is unplugged from any device, and plug in your Teensy.
|
||||
### Command Line
|
||||
|
||||
Open `cmd` and navigate to your where your modified .hex file is. We'll pretend this file is called `main.hex`, and that your Teensy 2.0 is on the `COM3` port - if you're unsure, you can open your Device Manager, and look for `Ports > USB Serial Device`. Use that COM port here. You can confirm it's the right port with:
|
||||
|
||||
|
277
docs/keycodes.md
277
docs/keycodes.md
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,31 +1,33 @@
|
||||
# US ANSI Shifted Symbols
|
||||
|
||||
These keycodes correspond to characters that are "shifted" on a standard US ANSI keyboards. They do not have dedicated keycodes but are instead typed by holding down shift and then sending a keycode.
|
||||
These keycodes correspond to characters that are "shifted" on a standard US ANSI keyboard. They do not have keycodes of their own but are simply shortcuts for `LSFT(kc)`, and as such send a Left Shift with the unshifted keycode, not the symbol itself.
|
||||
|
||||
It's important to remember that all of these keycodes send a left shift - this may cause unintended actions if unaccounted for. The short code is preferred in most situations.
|
||||
## Caveats
|
||||
|
||||
## US ANSI Shifted Keycodes
|
||||
Unfortunately, these keycodes cannot be used in Mod-Taps or Layer-Taps, since any modifiers specified in the keycode are ignored.
|
||||
|
||||
|Key |Aliases |Description |
|
||||
|------------------------|------------------|-------------------|
|
||||
|`KC_TILDE` |`KC_TILD` |`~` |
|
||||
|`KC_EXCLAIM` |`KC_EXLM` |`!` |
|
||||
|`KC_AT` | |`@` |
|
||||
|`KC_HASH` | |`#` |
|
||||
|`KC_DOLLAR` |`KC_DLR` |`$` |
|
||||
|`KC_PERCENT` |`KC_PERC` |`%` |
|
||||
|`KC_CIRCUMFLEX` |`KC_CIRC` |`^` |
|
||||
|`KC_AMPERSAND` |`KC_AMPR` |`&` |
|
||||
|`KC_ASTERISK` |`KC_ASTR` |`*` |
|
||||
|`KC_LEFT_PAREN` |`KC_LPRN` |`(` |
|
||||
|`KC_RIGHT_PAREN` |`KC_RPRN` |`)` |
|
||||
|`KC_UNDERSCORE` |`KC_UNDS` |`_` |
|
||||
|`KC_PLUS` | |`+` |
|
||||
|`KC_LEFT_CURLY_BRACE` |`KC_LCBR` |`{` |
|
||||
|`KC_RIGHT_CURLY_BRACE` |`KC_RCBR` |`}` |
|
||||
|`KC_PIPE` | |<code>|</code>|
|
||||
|`KC_COLON` |`KC_COLN` |`:` |
|
||||
|`KC_DOUBLE_QUOTE` |`KC_DQT`/`KC_DQUO`|`"` |
|
||||
|`KC_LEFT_ANGLE_BRACKET` |`KC_LT`/`KC_LABK` |`<` |
|
||||
|`KC_RIGHT_ANGLE_BRACKET`|`KC_GT`/`KC_RABK` |`>` |
|
||||
|`KC_QUESTION` |`KC_QUES` |`?` |
|
||||
## Keycodes
|
||||
|
||||
|Key |Aliases |Description |
|
||||
|------------------------|-------------------|-------------------|
|
||||
|`KC_TILDE` |`KC_TILD` |`~` |
|
||||
|`KC_EXCLAIM` |`KC_EXLM` |`!` |
|
||||
|`KC_AT` | |`@` |
|
||||
|`KC_HASH` | |`#` |
|
||||
|`KC_DOLLAR` |`KC_DLR` |`$` |
|
||||
|`KC_PERCENT` |`KC_PERC` |`%` |
|
||||
|`KC_CIRCUMFLEX` |`KC_CIRC` |`^` |
|
||||
|`KC_AMPERSAND` |`KC_AMPR` |`&` |
|
||||
|`KC_ASTERISK` |`KC_ASTR` |`*` |
|
||||
|`KC_LEFT_PAREN` |`KC_LPRN` |`(` |
|
||||
|`KC_RIGHT_PAREN` |`KC_RPRN` |`)` |
|
||||
|`KC_UNDERSCORE` |`KC_UNDS` |`_` |
|
||||
|`KC_PLUS` | |`+` |
|
||||
|`KC_LEFT_CURLY_BRACE` |`KC_LCBR` |`{` |
|
||||
|`KC_RIGHT_CURLY_BRACE` |`KC_RCBR` |`}` |
|
||||
|`KC_PIPE` | |<code>|</code>|
|
||||
|`KC_COLON` |`KC_COLN` |`:` |
|
||||
|`KC_DOUBLE_QUOTE` |`KC_DQUO`, `KC_DQT`|`"` |
|
||||
|`KC_LEFT_ANGLE_BRACKET` |`KC_LABK`, `KC_LT` |`<` |
|
||||
|`KC_RIGHT_ANGLE_BRACKET`|`KC_RABK`, `KC_GT` |`>` |
|
||||
|`KC_QUESTION` |`KC_QUES` |`?` |
|
||||
|
48
docs/ref_functions.md
Normal file
48
docs/ref_functions.md
Normal file
@ -0,0 +1,48 @@
|
||||
# List of Useful Core Functions To Make Your Keyboard Better
|
||||
|
||||
There are a lot of hidden functions in QMK that are incredible useful, or may add a bit of functionality that you've been wanting. Functions that are specific to certain features are not included here, as those will be on their respective feature page.
|
||||
|
||||
## (OLKB) Tri Layers
|
||||
|
||||
There are actually separate functions that you can use there, depending on what you're after.
|
||||
|
||||
The first is the `update_tri_layer(x, y, z)` function. This function check to see if layers `x` and `y` are both on. If they are both on, then it runs on layer `z`. Otherwise, if both `x` and `y` are not both on (either only one is, or neither is), then it runs off layer `z`.
|
||||
|
||||
This function is useful if you want to create specific keys that have this functionality, but other layer keycodes won't do this.
|
||||
|
||||
The other function is `update_tri_layer_state(state, x, y, z)`. This function is meant to be called from they [`layer_state_set_*` functions](custom_quantum_functions.md#layer-change-code). This means that any time that you use a keycode to change the layer, this will be checked. So you could use `LT(layer, kc)` to change the layer and it will trigger the same layer check.
|
||||
|
||||
The caveat to this method is that you cannot access the `z` layer without having `x` and `y` layers on, since if you try to activate just layer `z`, it will run this code and turn off layer `z` before you could use it.
|
||||
|
||||
## Setting the Persistent Default Layer
|
||||
|
||||
Do you want to set the default layer, so that it's retained even after you unplug the board? If so, this is the function for you.
|
||||
|
||||
To use this, you would use `set_single_persistent_default_layer(layer)`. If you have a name defined for your layer, you can use that instead (such as _QWERTY, _DVORAK or _COLEMAK).
|
||||
|
||||
This will set the default layer, update the persistent settings, and play a tune if you have [Audio](feature_audio.md) enabled on your board, and the default layer sounds set.
|
||||
|
||||
To configure the default layer sounds, you would want to define this in your `config.h` file, like this:
|
||||
|
||||
```c
|
||||
#define DEFAULT_LAYER_SONGS { SONG(QWERTY_SOUND), \
|
||||
SONG(COLEMAK_SOUND), \
|
||||
SONG(DVORAK_SOUND) \
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
?> There are a large number of predefined songs in [quantum/audio/song_list.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/audio/song_list.h) that you can use.
|
||||
|
||||
## Reseting the keyboard
|
||||
|
||||
There is the `RESET` quantum keycode that you can use. But if you want to reset the board as part of a macro, rather than hitting a key separately, you can do that.
|
||||
|
||||
And to do so, add `reset_keyboard()` to your function or macro, and this will reset to bootloader.
|
||||
|
||||
## Wiping the EEPROM (Persistent Storage)
|
||||
|
||||
If you're having issues with Audio, RGB Underglow, backlighting or keys acting weird, then you can reset the EEPROM (persistent setting storage). Bootmagic is one way to do this, but if that isn't enabled, then you can use a custom macro to do so.
|
||||
|
||||
To wipe the EEPROM, run `eeconfig_init()` from your function or macro to reset most of the settings to default.
|
||||
|
104
drivers/arm/i2c_master.c
Normal file
104
drivers/arm/i2c_master.c
Normal file
@ -0,0 +1,104 @@
|
||||
/* Copyright 2018 Jack Humbert
|
||||
* Copyright 2018 Yiancar
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/* This library is only valid for STM32 processors.
|
||||
* This library follows the convention of the AVR i2c_master library.
|
||||
* As a result addresses are expected to be already shifted (addr << 1).
|
||||
* I2CD1 is the default driver which corresponds to pins B6 and B7. This
|
||||
* can be changed.
|
||||
* Please ensure that HAL_USE_I2C is TRUE in the halconf.h file and that
|
||||
* STM32_I2C_USE_I2C1 is TRUE in the mcuconf.h file. Pins B6 and B7 are used
|
||||
* but using any other I2C pins should be trivial.
|
||||
*/
|
||||
|
||||
#include "i2c_master.h"
|
||||
#include <string.h>
|
||||
#include <hal.h>
|
||||
|
||||
static uint8_t i2c_address;
|
||||
|
||||
// This configures the I2C clock to 400Mhz assuming a 72Mhz clock
|
||||
// For more info : https://www.st.com/en/embedded-software/stsw-stm32126.html
|
||||
static const I2CConfig i2cconfig = {
|
||||
STM32_TIMINGR_PRESC(15U) |
|
||||
STM32_TIMINGR_SCLDEL(4U) | STM32_TIMINGR_SDADEL(2U) |
|
||||
STM32_TIMINGR_SCLH(15U) | STM32_TIMINGR_SCLL(21U),
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
void i2c_init(void)
|
||||
{
|
||||
palSetGroupMode(GPIOB, GPIOB_PIN6 | GPIOB_PIN7, 0, PAL_MODE_INPUT); // Try releasing special pins for a short time
|
||||
chThdSleepMilliseconds(10);
|
||||
|
||||
palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP);
|
||||
palSetPadMode(GPIOB, 7, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP);
|
||||
|
||||
//i2cInit(); //This is invoked by halInit() so no need to redo it.
|
||||
}
|
||||
|
||||
// This is usually not needed
|
||||
uint8_t i2c_start(uint8_t address)
|
||||
{
|
||||
i2c_address = address;
|
||||
i2cStart(&I2C_DRIVER, &i2cconfig);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout)
|
||||
{
|
||||
i2c_address = address;
|
||||
i2cStart(&I2C_DRIVER, &i2cconfig);
|
||||
return i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), data, length, 0, 0, MS2ST(timeout));
|
||||
}
|
||||
|
||||
uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout)
|
||||
{
|
||||
i2c_address = address;
|
||||
i2cStart(&I2C_DRIVER, &i2cconfig);
|
||||
return i2cMasterReceiveTimeout(&I2C_DRIVER, (i2c_address >> 1), data, length, MS2ST(timeout));
|
||||
}
|
||||
|
||||
uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout)
|
||||
{
|
||||
i2c_address = devaddr;
|
||||
i2cStart(&I2C_DRIVER, &i2cconfig);
|
||||
|
||||
uint8_t complete_packet[length + 1];
|
||||
for(uint8_t i = 0; i < length; i++)
|
||||
{
|
||||
complete_packet[i+1] = data[i];
|
||||
}
|
||||
complete_packet[0] = regaddr;
|
||||
|
||||
return i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), complete_packet, length + 1, 0, 0, MS2ST(timeout));
|
||||
}
|
||||
|
||||
uint8_t i2c_readReg(uint8_t devaddr, uint8_t* regaddr, uint8_t* data, uint16_t length, uint16_t timeout)
|
||||
{
|
||||
i2c_address = devaddr;
|
||||
i2cStart(&I2C_DRIVER, &i2cconfig);
|
||||
return i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), regaddr, 1, data, length, MS2ST(timeout));
|
||||
}
|
||||
|
||||
// This is usually not needed. It releases the driver to allow pins to become GPIO again.
|
||||
uint8_t i2c_stop(uint16_t timeout)
|
||||
{
|
||||
i2cStop(&I2C_DRIVER);
|
||||
return 0;
|
||||
}
|
39
drivers/arm/i2c_master.h
Normal file
39
drivers/arm/i2c_master.h
Normal file
@ -0,0 +1,39 @@
|
||||
/* Copyright 2018 Jack Humbert
|
||||
* Copyright 2018 Yiancar
|
||||
*
|
||||
* This program is free sofare: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Sofare 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/>.
|
||||
*/
|
||||
|
||||
/* This library follows the convention of the AVR i2c_master library.
|
||||
* As a result addresses are expected to be already shifted (addr << 1).
|
||||
* I2CD1 is the default driver which corresponds to pins B6 and B7. This
|
||||
* can be changed.
|
||||
* Please ensure that HAL_USE_I2C is TRUE in the halconf.h file and that
|
||||
* STM32_I2C_USE_I2C1 is TRUE in the mcuconf.h file.
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include <hal.h>
|
||||
|
||||
#ifndef I2C_DRIVER
|
||||
#define I2C_DRIVER I2CD1
|
||||
#endif
|
||||
|
||||
void i2c_init(void);
|
||||
uint8_t i2c_start(uint8_t address);
|
||||
uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);
|
||||
uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);
|
||||
uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
|
||||
uint8_t i2c_readReg(uint8_t devaddr, uint8_t* regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
|
||||
uint8_t i2c_stop(uint16_t timeout);
|
@ -1,262 +0,0 @@
|
||||
/* Copyright 2017 Jason Williams
|
||||
* Copyright 2018 Jack Humbert
|
||||
*
|
||||
* 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 "is31fl3731.h"
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
#include <string.h>
|
||||
#include "i2c_master.h"
|
||||
#include "progmem.h"
|
||||
|
||||
// This is a 7-bit address, that gets left-shifted and bit 0
|
||||
// set to 0 for write, 1 for read (as per I2C protocol)
|
||||
// The address will vary depending on your wiring:
|
||||
// 0b1110100 AD <-> GND
|
||||
// 0b1110111 AD <-> VCC
|
||||
// 0b1110101 AD <-> SCL
|
||||
// 0b1110110 AD <-> SDA
|
||||
#define ISSI_ADDR_DEFAULT 0x74
|
||||
|
||||
#define ISSI_REG_CONFIG 0x00
|
||||
#define ISSI_REG_CONFIG_PICTUREMODE 0x00
|
||||
#define ISSI_REG_CONFIG_AUTOPLAYMODE 0x08
|
||||
#define ISSI_REG_CONFIG_AUDIOPLAYMODE 0x18
|
||||
|
||||
#define ISSI_CONF_PICTUREMODE 0x00
|
||||
#define ISSI_CONF_AUTOFRAMEMODE 0x04
|
||||
#define ISSI_CONF_AUDIOMODE 0x08
|
||||
|
||||
#define ISSI_REG_PICTUREFRAME 0x01
|
||||
|
||||
#define ISSI_REG_SHUTDOWN 0x0A
|
||||
#define ISSI_REG_AUDIOSYNC 0x06
|
||||
|
||||
#define ISSI_COMMANDREGISTER 0xFD
|
||||
#define ISSI_BANK_FUNCTIONREG 0x0B // helpfully called 'page nine'
|
||||
|
||||
#ifndef ISSI_TIMEOUT
|
||||
#define ISSI_TIMEOUT 100
|
||||
#endif
|
||||
|
||||
#ifndef ISSI_PERSISTENCE
|
||||
#define ISSI_PERSISTENCE 0
|
||||
#endif
|
||||
|
||||
// Transfer buffer for TWITransmitData()
|
||||
uint8_t g_twi_transfer_buffer[20];
|
||||
|
||||
// These buffers match the IS31FL3731 PWM registers 0x24-0xB3.
|
||||
// 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 IS31FL3731_write_pwm_buffer() but it's
|
||||
// probably not worth the extra complexity.
|
||||
uint8_t g_pwm_buffer[DRIVER_COUNT][144];
|
||||
bool g_pwm_buffer_update_required = false;
|
||||
|
||||
uint8_t g_led_control_registers[DRIVER_COUNT][18] = { { 0 }, { 0 } };
|
||||
bool g_led_control_registers_update_required = false;
|
||||
|
||||
// This is the bit pattern in the LED control registers
|
||||
// (for matrix A, add one to register for matrix B)
|
||||
//
|
||||
// reg - b7 b6 b5 b4 b3 b2 b1 b0
|
||||
// 0x00 - R08,R07,R06,R05,R04,R03,R02,R01
|
||||
// 0x02 - G08,G07,G06,G05,G04,G03,G02,R00
|
||||
// 0x04 - B08,B07,B06,B05,B04,B03,G01,G00
|
||||
// 0x06 - - , - , - , - , - ,B02,B01,B00
|
||||
// 0x08 - - , - , - , - , - , - , - , -
|
||||
// 0x0A - B17,B16,B15, - , - , - , - , -
|
||||
// 0x0C - G17,G16,B14,B13,B12,B11,B10,B09
|
||||
// 0x0E - R17,G15,G14,G13,G12,G11,G10,G09
|
||||
// 0x10 - R16,R15,R14,R13,R12,R11,R10,R09
|
||||
|
||||
|
||||
void IS31FL3731_write_register( uint8_t addr, uint8_t reg, uint8_t data )
|
||||
{
|
||||
g_twi_transfer_buffer[0] = reg;
|
||||
g_twi_transfer_buffer[1] = data;
|
||||
|
||||
#if ISSI_PERSISTENCE > 0
|
||||
for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) {
|
||||
if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0)
|
||||
break;
|
||||
}
|
||||
#else
|
||||
i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT);
|
||||
#endif
|
||||
}
|
||||
|
||||
void IS31FL3731_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer )
|
||||
{
|
||||
// assumes bank is already selected
|
||||
|
||||
// transmit PWM registers in 9 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 < 144; i += 16 ) {
|
||||
// set the first register, e.g. 0x24, 0x34, 0x44, etc.
|
||||
g_twi_transfer_buffer[0] = 0x24 + i;
|
||||
// copy the data from i to i+15
|
||||
// device will auto-increment register for data after the first byte
|
||||
// thus this sets registers 0x24-0x33, 0x34-0x43, etc. in one transfer
|
||||
for ( int j = 0; j < 16; j++ ) {
|
||||
g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j];
|
||||
}
|
||||
|
||||
#if ISSI_PERSISTENCE > 0
|
||||
for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) {
|
||||
if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) == 0)
|
||||
break;
|
||||
}
|
||||
#else
|
||||
i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void IS31FL3731_init( uint8_t addr )
|
||||
{
|
||||
// In order to avoid the LEDs being driven with garbage data
|
||||
// in the LED driver's PWM registers, first enable software shutdown,
|
||||
// then set up the mode and other settings, clear the PWM registers,
|
||||
// then disable software shutdown.
|
||||
|
||||
// select "function register" bank
|
||||
IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG );
|
||||
|
||||
// enable software shutdown
|
||||
IS31FL3731_write_register( addr, ISSI_REG_SHUTDOWN, 0x00 );
|
||||
// this delay was copied from other drivers, might not be needed
|
||||
_delay_ms( 10 );
|
||||
|
||||
// picture mode
|
||||
IS31FL3731_write_register( addr, ISSI_REG_CONFIG, ISSI_REG_CONFIG_PICTUREMODE );
|
||||
// display frame 0
|
||||
IS31FL3731_write_register( addr, ISSI_REG_PICTUREFRAME, 0x00 );
|
||||
// audio sync off
|
||||
IS31FL3731_write_register( addr, ISSI_REG_AUDIOSYNC, 0x00 );
|
||||
|
||||
// select bank 0
|
||||
IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, 0 );
|
||||
|
||||
// turn off all LEDs in the LED control register
|
||||
for ( int i = 0x00; i <= 0x11; i++ )
|
||||
{
|
||||
IS31FL3731_write_register( addr, i, 0x00 );
|
||||
}
|
||||
|
||||
// turn off all LEDs in the blink control register (not really needed)
|
||||
for ( int i = 0x12; i <= 0x23; i++ )
|
||||
{
|
||||
IS31FL3731_write_register( addr, i, 0x00 );
|
||||
}
|
||||
|
||||
// set PWM on all LEDs to 0
|
||||
for ( int i = 0x24; i <= 0xB3; i++ )
|
||||
{
|
||||
IS31FL3731_write_register( addr, i, 0x00 );
|
||||
}
|
||||
|
||||
// select "function register" bank
|
||||
IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG );
|
||||
|
||||
// disable software shutdown
|
||||
IS31FL3731_write_register( addr, ISSI_REG_SHUTDOWN, 0x01 );
|
||||
|
||||
// select bank 0 and leave it selected.
|
||||
// most usage after initialization is just writing PWM buffers in bank 0
|
||||
// as there's not much point in double-buffering
|
||||
IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, 0 );
|
||||
|
||||
}
|
||||
|
||||
void IS31FL3731_set_color( int index, uint8_t red, uint8_t green, uint8_t blue )
|
||||
{
|
||||
if ( index >= 0 && index < DRIVER_LED_TOTAL ) {
|
||||
is31_led led = g_is31_leds[index];
|
||||
|
||||
// Subtract 0x24 to get the second index of g_pwm_buffer
|
||||
g_pwm_buffer[led.driver][led.r - 0x24] = red;
|
||||
g_pwm_buffer[led.driver][led.g - 0x24] = green;
|
||||
g_pwm_buffer[led.driver][led.b - 0x24] = blue;
|
||||
g_pwm_buffer_update_required = true;
|
||||
}
|
||||
}
|
||||
|
||||
void IS31FL3731_set_color_all( uint8_t red, uint8_t green, uint8_t blue )
|
||||
{
|
||||
for ( int i = 0; i < DRIVER_LED_TOTAL; i++ )
|
||||
{
|
||||
IS31FL3731_set_color( i, red, green, blue );
|
||||
}
|
||||
}
|
||||
|
||||
void IS31FL3731_set_led_control_register( uint8_t index, bool red, bool green, bool blue )
|
||||
{
|
||||
is31_led led = g_is31_leds[index];
|
||||
|
||||
uint8_t control_register_r = (led.r - 0x24) / 8;
|
||||
uint8_t control_register_g = (led.g - 0x24) / 8;
|
||||
uint8_t control_register_b = (led.b - 0x24) / 8;
|
||||
uint8_t bit_r = (led.r - 0x24) % 8;
|
||||
uint8_t bit_g = (led.g - 0x24) % 8;
|
||||
uint8_t bit_b = (led.b - 0x24) % 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 = true;
|
||||
|
||||
}
|
||||
|
||||
void IS31FL3731_update_pwm_buffers( uint8_t addr1, uint8_t addr2 )
|
||||
{
|
||||
if ( g_pwm_buffer_update_required )
|
||||
{
|
||||
IS31FL3731_write_pwm_buffer( addr1, g_pwm_buffer[0] );
|
||||
IS31FL3731_write_pwm_buffer( addr2, g_pwm_buffer[1] );
|
||||
}
|
||||
g_pwm_buffer_update_required = false;
|
||||
}
|
||||
|
||||
void IS31FL3731_update_led_control_registers( uint8_t addr1, uint8_t addr2 )
|
||||
{
|
||||
if ( g_led_control_registers_update_required )
|
||||
{
|
||||
for ( int i=0; i<18; i++ )
|
||||
{
|
||||
IS31FL3731_write_register(addr1, i, g_led_control_registers[0][i] );
|
||||
IS31FL3731_write_register(addr2, i, g_led_control_registers[1][i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
271
drivers/issi/is31fl3731.c
Normal file
271
drivers/issi/is31fl3731.c
Normal file
@ -0,0 +1,271 @@
|
||||
/* Copyright 2017 Jason Williams
|
||||
* Copyright 2018 Jack Humbert
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifdef __AVR__
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
#else
|
||||
#include "wait.h"
|
||||
#endif
|
||||
|
||||
#include "is31fl3731.h"
|
||||
#include <string.h>
|
||||
#include "i2c_master.h"
|
||||
#include "progmem.h"
|
||||
|
||||
// This is a 7-bit address, that gets left-shifted and bit 0
|
||||
// set to 0 for write, 1 for read (as per I2C protocol)
|
||||
// The address will vary depending on your wiring:
|
||||
// 0b1110100 AD <-> GND
|
||||
// 0b1110111 AD <-> VCC
|
||||
// 0b1110101 AD <-> SCL
|
||||
// 0b1110110 AD <-> SDA
|
||||
#define ISSI_ADDR_DEFAULT 0x74
|
||||
|
||||
#define ISSI_REG_CONFIG 0x00
|
||||
#define ISSI_REG_CONFIG_PICTUREMODE 0x00
|
||||
#define ISSI_REG_CONFIG_AUTOPLAYMODE 0x08
|
||||
#define ISSI_REG_CONFIG_AUDIOPLAYMODE 0x18
|
||||
|
||||
#define ISSI_CONF_PICTUREMODE 0x00
|
||||
#define ISSI_CONF_AUTOFRAMEMODE 0x04
|
||||
#define ISSI_CONF_AUDIOMODE 0x08
|
||||
|
||||
#define ISSI_REG_PICTUREFRAME 0x01
|
||||
|
||||
#define ISSI_REG_SHUTDOWN 0x0A
|
||||
#define ISSI_REG_AUDIOSYNC 0x06
|
||||
|
||||
#define ISSI_COMMANDREGISTER 0xFD
|
||||
#define ISSI_BANK_FUNCTIONREG 0x0B // helpfully called 'page nine'
|
||||
|
||||
#ifndef ISSI_TIMEOUT
|
||||
#define ISSI_TIMEOUT 100
|
||||
#endif
|
||||
|
||||
#ifndef ISSI_PERSISTENCE
|
||||
#define ISSI_PERSISTENCE 0
|
||||
#endif
|
||||
|
||||
// Transfer buffer for TWITransmitData()
|
||||
uint8_t g_twi_transfer_buffer[20];
|
||||
|
||||
// These buffers match the IS31FL3731 PWM registers 0x24-0xB3.
|
||||
// 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 IS31FL3731_write_pwm_buffer() but it's
|
||||
// probably not worth the extra complexity.
|
||||
uint8_t g_pwm_buffer[DRIVER_COUNT][144];
|
||||
bool g_pwm_buffer_update_required = false;
|
||||
|
||||
uint8_t g_led_control_registers[DRIVER_COUNT][18] = { { 0 }, { 0 } };
|
||||
bool g_led_control_registers_update_required = false;
|
||||
|
||||
// This is the bit pattern in the LED control registers
|
||||
// (for matrix A, add one to register for matrix B)
|
||||
//
|
||||
// reg - b7 b6 b5 b4 b3 b2 b1 b0
|
||||
// 0x00 - R08,R07,R06,R05,R04,R03,R02,R01
|
||||
// 0x02 - G08,G07,G06,G05,G04,G03,G02,R00
|
||||
// 0x04 - B08,B07,B06,B05,B04,B03,G01,G00
|
||||
// 0x06 - - , - , - , - , - ,B02,B01,B00
|
||||
// 0x08 - - , - , - , - , - , - , - , -
|
||||
// 0x0A - B17,B16,B15, - , - , - , - , -
|
||||
// 0x0C - G17,G16,B14,B13,B12,B11,B10,B09
|
||||
// 0x0E - R17,G15,G14,G13,G12,G11,G10,G09
|
||||
// 0x10 - R16,R15,R14,R13,R12,R11,R10,R09
|
||||
|
||||
|
||||
void IS31FL3731_write_register( uint8_t addr, uint8_t reg, uint8_t data )
|
||||
{
|
||||
g_twi_transfer_buffer[0] = reg;
|
||||
g_twi_transfer_buffer[1] = data;
|
||||
|
||||
#if ISSI_PERSISTENCE > 0
|
||||
for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) {
|
||||
if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0)
|
||||
break;
|
||||
}
|
||||
#else
|
||||
i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT);
|
||||
#endif
|
||||
}
|
||||
|
||||
void IS31FL3731_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer )
|
||||
{
|
||||
// assumes bank is already selected
|
||||
|
||||
// transmit PWM registers in 9 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 < 144; i += 16 ) {
|
||||
// set the first register, e.g. 0x24, 0x34, 0x44, etc.
|
||||
g_twi_transfer_buffer[0] = 0x24 + i;
|
||||
// copy the data from i to i+15
|
||||
// device will auto-increment register for data after the first byte
|
||||
// thus this sets registers 0x24-0x33, 0x34-0x43, etc. in one transfer
|
||||
for ( int j = 0; j < 16; j++ ) {
|
||||
g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j];
|
||||
}
|
||||
|
||||
#if ISSI_PERSISTENCE > 0
|
||||
for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) {
|
||||
if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) == 0)
|
||||
break;
|
||||
}
|
||||
#else
|
||||
i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void IS31FL3731_init( uint8_t addr )
|
||||
{
|
||||
// In order to avoid the LEDs being driven with garbage data
|
||||
// in the LED driver's PWM registers, first enable software shutdown,
|
||||
// then set up the mode and other settings, clear the PWM registers,
|
||||
// then disable software shutdown.
|
||||
|
||||
// select "function register" bank
|
||||
IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG );
|
||||
|
||||
// enable software shutdown
|
||||
IS31FL3731_write_register( addr, ISSI_REG_SHUTDOWN, 0x00 );
|
||||
// this delay was copied from other drivers, might not be needed
|
||||
#ifdef __AVR__
|
||||
_delay_ms( 10 );
|
||||
#else
|
||||
wait_ms(10);
|
||||
#endif
|
||||
|
||||
// picture mode
|
||||
IS31FL3731_write_register( addr, ISSI_REG_CONFIG, ISSI_REG_CONFIG_PICTUREMODE );
|
||||
// display frame 0
|
||||
IS31FL3731_write_register( addr, ISSI_REG_PICTUREFRAME, 0x00 );
|
||||
// audio sync off
|
||||
IS31FL3731_write_register( addr, ISSI_REG_AUDIOSYNC, 0x00 );
|
||||
|
||||
// select bank 0
|
||||
IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, 0 );
|
||||
|
||||
// turn off all LEDs in the LED control register
|
||||
for ( int i = 0x00; i <= 0x11; i++ )
|
||||
{
|
||||
IS31FL3731_write_register( addr, i, 0x00 );
|
||||
}
|
||||
|
||||
// turn off all LEDs in the blink control register (not really needed)
|
||||
for ( int i = 0x12; i <= 0x23; i++ )
|
||||
{
|
||||
IS31FL3731_write_register( addr, i, 0x00 );
|
||||
}
|
||||
|
||||
// set PWM on all LEDs to 0
|
||||
for ( int i = 0x24; i <= 0xB3; i++ )
|
||||
{
|
||||
IS31FL3731_write_register( addr, i, 0x00 );
|
||||
}
|
||||
|
||||
// select "function register" bank
|
||||
IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG );
|
||||
|
||||
// disable software shutdown
|
||||
IS31FL3731_write_register( addr, ISSI_REG_SHUTDOWN, 0x01 );
|
||||
|
||||
// select bank 0 and leave it selected.
|
||||
// most usage after initialization is just writing PWM buffers in bank 0
|
||||
// as there's not much point in double-buffering
|
||||
IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, 0 );
|
||||
|
||||
}
|
||||
|
||||
void IS31FL3731_set_color( int index, uint8_t red, uint8_t green, uint8_t blue )
|
||||
{
|
||||
if ( index >= 0 && index < DRIVER_LED_TOTAL ) {
|
||||
is31_led led = g_is31_leds[index];
|
||||
|
||||
// Subtract 0x24 to get the second index of g_pwm_buffer
|
||||
g_pwm_buffer[led.driver][led.r - 0x24] = red;
|
||||
g_pwm_buffer[led.driver][led.g - 0x24] = green;
|
||||
g_pwm_buffer[led.driver][led.b - 0x24] = blue;
|
||||
g_pwm_buffer_update_required = true;
|
||||
}
|
||||
}
|
||||
|
||||
void IS31FL3731_set_color_all( uint8_t red, uint8_t green, uint8_t blue )
|
||||
{
|
||||
for ( int i = 0; i < DRIVER_LED_TOTAL; i++ )
|
||||
{
|
||||
IS31FL3731_set_color( i, red, green, blue );
|
||||
}
|
||||
}
|
||||
|
||||
void IS31FL3731_set_led_control_register( uint8_t index, bool red, bool green, bool blue )
|
||||
{
|
||||
is31_led led = g_is31_leds[index];
|
||||
|
||||
uint8_t control_register_r = (led.r - 0x24) / 8;
|
||||
uint8_t control_register_g = (led.g - 0x24) / 8;
|
||||
uint8_t control_register_b = (led.b - 0x24) / 8;
|
||||
uint8_t bit_r = (led.r - 0x24) % 8;
|
||||
uint8_t bit_g = (led.g - 0x24) % 8;
|
||||
uint8_t bit_b = (led.b - 0x24) % 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 = true;
|
||||
|
||||
}
|
||||
|
||||
void IS31FL3731_update_pwm_buffers( uint8_t addr1, uint8_t addr2 )
|
||||
{
|
||||
if ( g_pwm_buffer_update_required )
|
||||
{
|
||||
IS31FL3731_write_pwm_buffer( addr1, g_pwm_buffer[0] );
|
||||
IS31FL3731_write_pwm_buffer( addr2, g_pwm_buffer[1] );
|
||||
}
|
||||
g_pwm_buffer_update_required = false;
|
||||
}
|
||||
|
||||
void IS31FL3731_update_led_control_registers( uint8_t addr1, uint8_t addr2 )
|
||||
{
|
||||
if ( g_led_control_registers_update_required )
|
||||
{
|
||||
for ( int i=0; i<18; i++ )
|
||||
{
|
||||
IS31FL3731_write_register(addr1, i, g_led_control_registers[0][i] );
|
||||
IS31FL3731_write_register(addr2, i, g_led_control_registers[1][i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct is31_led {
|
||||
uint8_t driver:2;
|
||||
uint8_t driver:2;
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
253
drivers/issi/is31fl3733.c
Normal file
253
drivers/issi/is31fl3733.c
Normal file
@ -0,0 +1,253 @@
|
||||
/* Copyright 2017 Jason Williams
|
||||
* Copyright 2018 Jack Humbert
|
||||
* Copyright 2018 Yiancar
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifdef __AVR__
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
#else
|
||||
#include "wait.h"
|
||||
#endif
|
||||
|
||||
#include "is31fl3733.h"
|
||||
#include <string.h>
|
||||
#include "i2c_master.h"
|
||||
#include "progmem.h"
|
||||
|
||||
// This is a 7-bit address, that gets left-shifted and bit 0
|
||||
// set to 0 for write, 1 for read (as per I2C protocol)
|
||||
// The address will vary depending on your wiring:
|
||||
// 00 <-> GND
|
||||
// 01 <-> SCL
|
||||
// 10 <-> SDA
|
||||
// 11 <-> VCC
|
||||
// ADDR1 represents A1:A0 of the 7-bit address.
|
||||
// ADDR2 represents A3:A2 of the 7-bit address.
|
||||
// The result is: 0b101(ADDR2)(ADDR1)
|
||||
#define ISSI_ADDR_DEFAULT 0x50
|
||||
|
||||
#define ISSI_COMMANDREGISTER 0xFD
|
||||
#define ISSI_COMMANDREGISTER_WRITELOCK 0xFE
|
||||
#define ISSI_INTERRUPTMASKREGISTER 0xF0
|
||||
#define ISSI_INTERRUPTSTATUSREGISTER 0xF1
|
||||
|
||||
#define ISSI_PAGE_LEDCONTROL 0x00 //PG0
|
||||
#define ISSI_PAGE_PWM 0x01 //PG1
|
||||
#define ISSI_PAGE_AUTOBREATH 0x02 //PG2
|
||||
#define ISSI_PAGE_FUNCTION 0x03 //PG3
|
||||
|
||||
#define ISSI_REG_CONFIGURATION 0x00 //PG3
|
||||
#define ISSI_REG_GLOBALCURRENT 0x01 //PG3
|
||||
#define ISSI_REG_RESET 0x11// PG3
|
||||
#define ISSI_REG_SWPULLUP 0x0F //PG3
|
||||
#define ISSI_REG_CSPULLUP 0x10 //PG3
|
||||
|
||||
#ifndef ISSI_TIMEOUT
|
||||
#define ISSI_TIMEOUT 100
|
||||
#endif
|
||||
|
||||
#ifndef ISSI_PERSISTENCE
|
||||
#define ISSI_PERSISTENCE 0
|
||||
#endif
|
||||
|
||||
// Transfer buffer for TWITransmitData()
|
||||
uint8_t g_twi_transfer_buffer[20];
|
||||
|
||||
// These buffers match the IS31FL3733 PWM registers.
|
||||
// The control buffers match the PG0 LED On/Off registers.
|
||||
// Storing them like this is optimal for I2C transfers to the registers.
|
||||
// We could optimize this and take out the unused registers from these
|
||||
// buffers and the transfers in IS31FL3733_write_pwm_buffer() but it's
|
||||
// probably not worth the extra complexity.
|
||||
uint8_t g_pwm_buffer[DRIVER_COUNT][192];
|
||||
bool g_pwm_buffer_update_required = false;
|
||||
|
||||
uint8_t g_led_control_registers[DRIVER_COUNT][24] = { { 0 }, { 0 } };
|
||||
bool g_led_control_registers_update_required = false;
|
||||
|
||||
void IS31FL3733_write_register( uint8_t addr, uint8_t reg, uint8_t data )
|
||||
{
|
||||
g_twi_transfer_buffer[0] = reg;
|
||||
g_twi_transfer_buffer[1] = data;
|
||||
|
||||
#if ISSI_PERSISTENCE > 0
|
||||
for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) {
|
||||
if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0)
|
||||
break;
|
||||
}
|
||||
#else
|
||||
i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT);
|
||||
#endif
|
||||
}
|
||||
|
||||
void IS31FL3733_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer )
|
||||
{
|
||||
// assumes PG1 is already selected
|
||||
|
||||
// transmit PWM registers in 12 transfers of 16 bytes
|
||||
// g_twi_transfer_buffer[] is 20 bytes
|
||||
|
||||
// iterate over the pwm_buffer contents at 16 byte intervals
|
||||
for ( int i = 0; i < 192; i += 16 ) {
|
||||
g_twi_transfer_buffer[0] = i;
|
||||
// copy the data from i to i+15
|
||||
// device will auto-increment register for data after the first byte
|
||||
// thus this sets registers 0x00-0x0F, 0x10-0x1F, etc. in one transfer
|
||||
for ( int j = 0; j < 16; j++ ) {
|
||||
g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j];
|
||||
}
|
||||
|
||||
#if ISSI_PERSISTENCE > 0
|
||||
for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) {
|
||||
if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) == 0)
|
||||
break;
|
||||
}
|
||||
#else
|
||||
i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void IS31FL3733_init( uint8_t addr )
|
||||
{
|
||||
// In order to avoid the LEDs being driven with garbage data
|
||||
// in the LED driver's PWM registers, shutdown is enabled last.
|
||||
// Set up the mode and other settings, clear the PWM registers,
|
||||
// then disable software shutdown.
|
||||
|
||||
// Unlock the command register.
|
||||
IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 );
|
||||
|
||||
// Select PG0
|
||||
IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL );
|
||||
// Turn off all LEDs.
|
||||
for ( int i = 0x00; i <= 0x17; i++ )
|
||||
{
|
||||
IS31FL3733_write_register( addr, i, 0x00 );
|
||||
}
|
||||
|
||||
// Unlock the command register.
|
||||
IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 );
|
||||
|
||||
// Select PG1
|
||||
IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM );
|
||||
// Set PWM on all LEDs to 0
|
||||
// No need to setup Breath registers to PWM as that is the default.
|
||||
for ( int i = 0x00; i <= 0xBF; i++ )
|
||||
{
|
||||
IS31FL3733_write_register( addr, i, 0x00 );
|
||||
}
|
||||
|
||||
// Unlock the command register.
|
||||
IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 );
|
||||
|
||||
// Select PG3
|
||||
IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_FUNCTION );
|
||||
// Set global current to maximum.
|
||||
IS31FL3733_write_register( addr, ISSI_REG_GLOBALCURRENT, 0xFF );
|
||||
// Disable software shutdown.
|
||||
IS31FL3733_write_register( addr, ISSI_REG_CONFIGURATION, 0x01 );
|
||||
|
||||
// Wait 10ms to ensure the device has woken up.
|
||||
#ifdef __AVR__
|
||||
_delay_ms( 10 );
|
||||
#else
|
||||
wait_ms(10);
|
||||
#endif
|
||||
}
|
||||
|
||||
void IS31FL3733_set_color( int index, uint8_t red, uint8_t green, uint8_t blue )
|
||||
{
|
||||
if ( index >= 0 && index < DRIVER_LED_TOTAL ) {
|
||||
is31_led led = g_is31_leds[index];
|
||||
|
||||
g_pwm_buffer[led.driver][led.r] = red;
|
||||
g_pwm_buffer[led.driver][led.g] = green;
|
||||
g_pwm_buffer[led.driver][led.b] = blue;
|
||||
g_pwm_buffer_update_required = true;
|
||||
}
|
||||
}
|
||||
|
||||
void IS31FL3733_set_color_all( uint8_t red, uint8_t green, uint8_t blue )
|
||||
{
|
||||
for ( int i = 0; i < DRIVER_LED_TOTAL; i++ )
|
||||
{
|
||||
IS31FL3733_set_color( i, red, green, blue );
|
||||
}
|
||||
}
|
||||
|
||||
void IS31FL3733_set_led_control_register( uint8_t index, bool red, bool green, bool blue )
|
||||
{
|
||||
is31_led led = g_is31_leds[index];
|
||||
|
||||
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 = true;
|
||||
|
||||
}
|
||||
|
||||
void IS31FL3733_update_pwm_buffers( uint8_t addr1, uint8_t addr2 )
|
||||
{
|
||||
if ( g_pwm_buffer_update_required )
|
||||
{
|
||||
// Firstly we need to unlock the command register and select PG1
|
||||
IS31FL3733_write_register( addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 );
|
||||
IS31FL3733_write_register( addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM );
|
||||
|
||||
IS31FL3733_write_pwm_buffer( addr1, g_pwm_buffer[0] );
|
||||
//IS31FL3733_write_pwm_buffer( addr2, g_pwm_buffer[1] );
|
||||
}
|
||||
g_pwm_buffer_update_required = false;
|
||||
}
|
||||
|
||||
void IS31FL3733_update_led_control_registers( uint8_t addr1, uint8_t addr2 )
|
||||
{
|
||||
if ( g_led_control_registers_update_required )
|
||||
{
|
||||
// Firstly we need to unlock the command register and select PG0
|
||||
IS31FL3733_write_register( addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 );
|
||||
IS31FL3733_write_register( addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL );
|
||||
for ( int i=0; i<24; i++ )
|
||||
{
|
||||
IS31FL3733_write_register(addr1, i, g_led_control_registers[0][i] );
|
||||
//IS31FL3733_write_register(addr2, i, g_led_control_registers[1][i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
255
drivers/issi/is31fl3733.h
Normal file
255
drivers/issi/is31fl3733.h
Normal file
@ -0,0 +1,255 @@
|
||||
/* Copyright 2017 Jason Williams
|
||||
* Copyright 2018 Jack Humbert
|
||||
* Copyright 2018 Yiancar
|
||||
*
|
||||
* 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 IS31FL3733_DRIVER_H
|
||||
#define IS31FL3733_DRIVER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct is31_led {
|
||||
uint8_t driver:2;
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
} __attribute__((packed)) is31_led;
|
||||
|
||||
extern const is31_led g_is31_leds[DRIVER_LED_TOTAL];
|
||||
|
||||
void IS31FL3733_init( uint8_t addr );
|
||||
void IS31FL3733_write_register( uint8_t addr, uint8_t reg, uint8_t data );
|
||||
void IS31FL3733_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer );
|
||||
|
||||
void IS31FL3733_set_color( int index, uint8_t red, uint8_t green, uint8_t blue );
|
||||
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 );
|
||||
|
||||
// This should not be called from an interrupt
|
||||
// (eg. from a timer interrupt).
|
||||
// Call this while idle (in between matrix scans).
|
||||
// If the buffer is dirty, it will update the driver with the buffer.
|
||||
void IS31FL3733_update_pwm_buffers( uint8_t addr1, uint8_t addr2 );
|
||||
void IS31FL3733_update_led_control_registers( uint8_t addr1, uint8_t addr2 );
|
||||
|
||||
#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
|
||||
|
||||
#endif // IS31FL3733_DRIVER_H
|
43
keyboards/1upkeyboards/1up60hse/1up60hse.c
Normal file
43
keyboards/1upkeyboards/1up60hse/1up60hse.c
Normal file
@ -0,0 +1,43 @@
|
||||
/* Copyright 2018 MechMerlin
|
||||
*
|
||||
* 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 "1up60hse.h"
|
||||
|
||||
void matrix_init_kb(void) {
|
||||
// put your keyboard start-up code here
|
||||
// runs once when the firmware starts up
|
||||
|
||||
matrix_init_user();
|
||||
}
|
||||
|
||||
void matrix_scan_kb(void) {
|
||||
// put your looping keyboard code here
|
||||
// runs every cycle (a lot)
|
||||
|
||||
matrix_scan_user();
|
||||
}
|
||||
|
||||
bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
|
||||
// put your per-action keyboard code here
|
||||
// runs for every action, just before processing by the firmware
|
||||
|
||||
return process_record_user(keycode, record);
|
||||
}
|
||||
|
||||
void led_set_kb(uint8_t usb_led) {
|
||||
// put your keyboard LED indicator (ex: Caps Lock LED) toggling code here
|
||||
|
||||
led_set_user(usb_led);
|
||||
}
|
39
keyboards/1upkeyboards/1up60hse/1up60hse.h
Normal file
39
keyboards/1upkeyboards/1up60hse/1up60hse.h
Normal file
@ -0,0 +1,39 @@
|
||||
/* Copyright 2018 MechMerlin
|
||||
*
|
||||
* 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 KB_H
|
||||
#define KB_H
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
// This 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_60_ansi( \
|
||||
K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, \
|
||||
K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \
|
||||
K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2D, \
|
||||
K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3D, \
|
||||
K40, K41, K42, K45, K49, K4A, K4B, K4D \
|
||||
) { \
|
||||
{ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D }, \
|
||||
{ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D }, \
|
||||
{ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, KC_NO, K2D }, \
|
||||
{ K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, KC_NO, KC_NO, K3D }, \
|
||||
{ K40, K41, K42, KC_NO, KC_NO, K45, KC_NO, KC_NO, KC_NO, K49, K4A, K4B, KC_NO, K4D } \
|
||||
}
|
||||
#endif
|
224
keyboards/1upkeyboards/1up60hse/config.h
Normal file
224
keyboards/1upkeyboards/1up60hse/config.h
Normal file
@ -0,0 +1,224 @@
|
||||
/*
|
||||
Copyright 2018 MechMerlin
|
||||
|
||||
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 "config_common.h"
|
||||
|
||||
/* USB Device descriptor parameter */
|
||||
#define VENDOR_ID 0xFEED
|
||||
#define PRODUCT_ID 0x0000
|
||||
#define DEVICE_VER 0x0001
|
||||
#define MANUFACTURER 1upkeyboards
|
||||
#define PRODUCT 1up60hse
|
||||
#define DESCRIPTION A custom 60% keyboard
|
||||
|
||||
/* key matrix size */
|
||||
#define MATRIX_ROWS 5
|
||||
#define MATRIX_COLS 14
|
||||
|
||||
/*
|
||||
* Keyboard Matrix Assignments
|
||||
*
|
||||
* Change this to how you wired your keyboard
|
||||
* COLS: AVR pins used for columns, left to right
|
||||
* ROWS: AVR pins used for rows, top to bottom
|
||||
* DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
|
||||
* ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
|
||||
*
|
||||
*/
|
||||
#define MATRIX_ROW_PINS { B3, B2, B1, B0, D4 }
|
||||
#define MATRIX_COL_PINS { C7, F7, F6, F5, F4, F1, E6, D1, D0, D2, D3, D5, D6, D7 }
|
||||
#define UNUSED_PINS
|
||||
|
||||
/* COL2ROW, ROW2COL, or CUSTOM_MATRIX */
|
||||
#define DIODE_DIRECTION COL2ROW
|
||||
|
||||
#define BACKLIGHT_PIN B7
|
||||
#define BACKLIGHT_BREATHING
|
||||
#define BACKLIGHT_LEVELS 5
|
||||
|
||||
#define RGB_DI_PIN F0
|
||||
#ifdef RGB_DI_PIN
|
||||
#define RGBLIGHT_ANIMATIONS
|
||||
#define RGBLED_NUM 14
|
||||
#define RGBLIGHT_HUE_STEP 8
|
||||
#define RGBLIGHT_SAT_STEP 8
|
||||
#define RGBLIGHT_VAL_STEP 8
|
||||
#endif
|
||||
|
||||
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
|
||||
#define DEBOUNCING_DELAY 5
|
||||
|
||||
/* define if matrix has ghost (lacks anti-ghosting diodes) */
|
||||
//#define MATRIX_HAS_GHOST
|
||||
|
||||
/* number of backlight levels */
|
||||
|
||||
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
|
||||
#define LOCKING_SUPPORT_ENABLE
|
||||
/* Locking resynchronize hack */
|
||||
#define LOCKING_RESYNC_ENABLE
|
||||
|
||||
/* If defined, GRAVE_ESC will always act as ESC when CTRL is held.
|
||||
* This is userful for the Windows task manager shortcut (ctrl+shift+esc).
|
||||
*/
|
||||
// #define GRAVE_ESC_CTRL_OVERRIDE
|
||||
|
||||
/*
|
||||
* Force NKRO
|
||||
*
|
||||
* Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
|
||||
* state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
|
||||
* makefile for this to work.)
|
||||
*
|
||||
* If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
|
||||
* until the next keyboard reset.
|
||||
*
|
||||
* NKRO may prevent your keystrokes from being detected in the BIOS, but it is
|
||||
* fully operational during normal computer usage.
|
||||
*
|
||||
* For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
|
||||
* or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
|
||||
* bootmagic, NKRO mode will always be enabled until it is toggled again during a
|
||||
* power-up.
|
||||
*
|
||||
*/
|
||||
//#define FORCE_NKRO
|
||||
|
||||
/*
|
||||
* Magic Key Options
|
||||
*
|
||||
* Magic keys are hotkey commands that allow control over firmware functions of
|
||||
* the keyboard. They are best used in combination with the HID Listen program,
|
||||
* found here: https://www.pjrc.com/teensy/hid_listen.html
|
||||
*
|
||||
* The options below allow the magic key functionality to be changed. This is
|
||||
* useful if your keyboard/keypad is missing keys and you want magic key support.
|
||||
*
|
||||
*/
|
||||
|
||||
/* key combination for magic key command */
|
||||
#define IS_COMMAND() ( \
|
||||
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
|
||||
)
|
||||
|
||||
/* control how magic key switches layers */
|
||||
//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true
|
||||
//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true
|
||||
//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false
|
||||
|
||||
/* override magic key keymap */
|
||||
//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
|
||||
//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
|
||||
//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
|
||||
//#define MAGIC_KEY_HELP1 H
|
||||
//#define MAGIC_KEY_HELP2 SLASH
|
||||
//#define MAGIC_KEY_DEBUG D
|
||||
//#define MAGIC_KEY_DEBUG_MATRIX X
|
||||
//#define MAGIC_KEY_DEBUG_KBD K
|
||||
//#define MAGIC_KEY_DEBUG_MOUSE M
|
||||
//#define MAGIC_KEY_VERSION V
|
||||
//#define MAGIC_KEY_STATUS S
|
||||
//#define MAGIC_KEY_CONSOLE C
|
||||
//#define MAGIC_KEY_LAYER0_ALT1 ESC
|
||||
//#define MAGIC_KEY_LAYER0_ALT2 GRAVE
|
||||
//#define MAGIC_KEY_LAYER0 0
|
||||
//#define MAGIC_KEY_LAYER1 1
|
||||
//#define MAGIC_KEY_LAYER2 2
|
||||
//#define MAGIC_KEY_LAYER3 3
|
||||
//#define MAGIC_KEY_LAYER4 4
|
||||
//#define MAGIC_KEY_LAYER5 5
|
||||
//#define MAGIC_KEY_LAYER6 6
|
||||
//#define MAGIC_KEY_LAYER7 7
|
||||
//#define MAGIC_KEY_LAYER8 8
|
||||
//#define MAGIC_KEY_LAYER9 9
|
||||
//#define MAGIC_KEY_BOOTLOADER PAUSE
|
||||
//#define MAGIC_KEY_LOCK CAPS
|
||||
//#define MAGIC_KEY_EEPROM E
|
||||
//#define MAGIC_KEY_NKRO N
|
||||
//#define MAGIC_KEY_SLEEP_LED Z
|
||||
|
||||
/*
|
||||
* Feature disable options
|
||||
* These options are also useful to firmware size reduction.
|
||||
*/
|
||||
|
||||
/* disable debug print */
|
||||
//#define NO_DEBUG
|
||||
|
||||
/* disable print */
|
||||
//#define NO_PRINT
|
||||
|
||||
/* disable action features */
|
||||
//#define NO_ACTION_LAYER
|
||||
//#define NO_ACTION_TAPPING
|
||||
//#define NO_ACTION_ONESHOT
|
||||
//#define NO_ACTION_MACRO
|
||||
//#define NO_ACTION_FUNCTION
|
||||
|
||||
/*
|
||||
* MIDI options
|
||||
*/
|
||||
|
||||
/* Prevent use of disabled MIDI features in the keymap */
|
||||
//#define MIDI_ENABLE_STRICT 1
|
||||
|
||||
/* enable basic MIDI features:
|
||||
- MIDI notes can be sent when in Music mode is on
|
||||
*/
|
||||
//#define MIDI_BASIC
|
||||
|
||||
/* enable advanced MIDI features:
|
||||
- MIDI notes can be added to the keymap
|
||||
- Octave shift and transpose
|
||||
- Virtual sustain, portamento, and modulation wheel
|
||||
- etc.
|
||||
*/
|
||||
//#define MIDI_ADVANCED
|
||||
|
||||
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
|
||||
//#define MIDI_TONE_KEYCODE_OCTAVES 1
|
||||
|
||||
/*
|
||||
* HD44780 LCD Display Configuration
|
||||
*/
|
||||
/*
|
||||
#define LCD_LINES 2 //< number of visible lines of the display
|
||||
#define LCD_DISP_LENGTH 16 //< visibles characters per line of the display
|
||||
|
||||
#define LCD_IO_MODE 1 //< 0: memory mapped mode, 1: IO port mode
|
||||
|
||||
#if LCD_IO_MODE
|
||||
#define LCD_PORT PORTB //< port for the LCD lines
|
||||
#define LCD_DATA0_PORT LCD_PORT //< port for 4bit data bit 0
|
||||
#define LCD_DATA1_PORT LCD_PORT //< port for 4bit data bit 1
|
||||
#define LCD_DATA2_PORT LCD_PORT //< port for 4bit data bit 2
|
||||
#define LCD_DATA3_PORT LCD_PORT //< port for 4bit data bit 3
|
||||
#define LCD_DATA0_PIN 4 //< pin for 4bit data bit 0
|
||||
#define LCD_DATA1_PIN 5 //< pin for 4bit data bit 1
|
||||
#define LCD_DATA2_PIN 6 //< pin for 4bit data bit 2
|
||||
#define LCD_DATA3_PIN 7 //< pin for 4bit data bit 3
|
||||
#define LCD_RS_PORT LCD_PORT //< port for RS line
|
||||
#define LCD_RS_PIN 3 //< pin for RS line
|
||||
#define LCD_RW_PORT LCD_PORT //< port for RW line
|
||||
#define LCD_RW_PIN 2 //< pin for RW line
|
||||
#define LCD_E_PORT LCD_PORT //< port for Enable line
|
||||
#define LCD_E_PIN 1 //< pin for Enable line
|
||||
#endif
|
||||
*/
|
||||
|
12
keyboards/1upkeyboards/1up60hse/info.json
Normal file
12
keyboards/1upkeyboards/1up60hse/info.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"keyboard_name": "1up60hse",
|
||||
"url": "",
|
||||
"maintainer": "qmk",
|
||||
"width": 15,
|
||||
"height": 5,
|
||||
"layouts": {
|
||||
"LAYOUT_60_ansi": {
|
||||
"layout": [{"label":"~", "x":0, "y":0}, {"label":"!", "x":1, "y":0}, {"label":"@", "x":2, "y":0}, {"label":"#", "x":3, "y":0}, {"label":"$", "x":4, "y":0}, {"label":"%", "x":5, "y":0}, {"label":"^", "x":6, "y":0}, {"label":"&", "x":7, "y":0}, {"label":"*", "x":8, "y":0}, {"label":"(", "x":9, "y":0}, {"label":")", "x":10, "y":0}, {"label":"_", "x":11, "y":0}, {"label":"+", "x":12, "y":0}, {"label":"Backspace", "x":13, "y":0, "w":2}, {"label":"Tab", "x":0, "y":1, "w":1.5}, {"label":"Q", "x":1.5, "y":1}, {"label":"W", "x":2.5, "y":1}, {"label":"E", "x":3.5, "y":1}, {"label":"R", "x":4.5, "y":1}, {"label":"T", "x":5.5, "y":1}, {"label":"Y", "x":6.5, "y":1}, {"label":"U", "x":7.5, "y":1}, {"label":"I", "x":8.5, "y":1}, {"label":"O", "x":9.5, "y":1}, {"label":"P", "x":10.5, "y":1}, {"label":"{", "x":11.5, "y":1}, {"label":"}", "x":12.5, "y":1}, {"label":"|", "x":13.5, "y":1, "w":1.5}, {"label":"Caps Lock", "x":0, "y":2, "w":1.75}, {"label":"A", "x":1.75, "y":2}, {"label":"S", "x":2.75, "y":2}, {"label":"D", "x":3.75, "y":2}, {"label":"F", "x":4.75, "y":2}, {"label":"G", "x":5.75, "y":2}, {"label":"H", "x":6.75, "y":2}, {"label":"J", "x":7.75, "y":2}, {"label":"K", "x":8.75, "y":2}, {"label":"L", "x":9.75, "y":2}, {"label":":", "x":10.75, "y":2}, {"label":"\"", "x":11.75, "y":2}, {"label":"Enter", "x":12.75, "y":2, "w":2.25}, {"label":"Shift", "x":0, "y":3, "w":2.25}, {"label":"Z", "x":2.25, "y":3}, {"label":"X", "x":3.25, "y":3}, {"label":"C", "x":4.25, "y":3}, {"label":"V", "x":5.25, "y":3}, {"label":"B", "x":6.25, "y":3}, {"label":"N", "x":7.25, "y":3}, {"label":"M", "x":8.25, "y":3}, {"label":"<", "x":9.25, "y":3}, {"label":">", "x":10.25, "y":3}, {"label":"?", "x":11.25, "y":3}, {"label":"Shift", "x":12.25, "y":3, "w":2.75}, {"label":"Ctrl", "x":0, "y":4, "w":1.25}, {"label":"Win", "x":1.25, "y":4, "w":1.25}, {"label":"Alt", "x":2.5, "y":4, "w":1.25}, {"x":3.75, "y":4, "w":6.25}, {"label":"Alt", "x":10, "y":4, "w":1.25}, {"label":"Win", "x":11.25, "y":4, "w":1.25}, {"label":"Menu", "x":12.5, "y":4, "w":1.25}, {"label":"Ctrl", "x":13.75, "y":4, "w":1.25}]
|
||||
}
|
||||
}
|
||||
}
|
19
keyboards/1upkeyboards/1up60hse/keymaps/default/config.h
Normal file
19
keyboards/1upkeyboards/1up60hse/keymaps/default/config.h
Normal file
@ -0,0 +1,19 @@
|
||||
/* Copyright 2018 MechMerlin
|
||||
*
|
||||
* 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
|
||||
|
||||
// place overrides here
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user