Compare commits
66 Commits
0.6.46
...
keymap_fol
Author | SHA1 | Date | |
---|---|---|---|
|
1b7efbc03b | ||
|
e54159d9e8 | ||
|
d01f40edbf | ||
|
13f49ad8d9 | ||
|
0f89d7efed | ||
|
2fccc1a064 | ||
|
53c518f7d4 | ||
|
bcbc64aed8 | ||
|
459dfa510e | ||
|
5bb1e7869c | ||
|
58c4ba096a | ||
|
c8cc9c6aab | ||
|
e1e4a51472 | ||
|
c53a8ead93 | ||
|
a6afb16c90 | ||
|
21665df8eb | ||
|
ff4a1ae5d2 | ||
|
018a0142d2 | ||
|
c1f6f1308b | ||
|
274283420d | ||
|
874f5a5c07 | ||
|
161c68b48a | ||
|
5fad8d774d | ||
|
4fdc9badd3 | ||
|
af6107bee8 | ||
|
d233737c95 | ||
|
3e282ab203 | ||
|
1c0d85c143 | ||
|
7c19e9fa04 | ||
|
9fccfc8dd5 | ||
|
1cb72a9c59 | ||
|
82146ecfc0 | ||
|
4a1984d33e | ||
|
676080372c | ||
|
0af7415981 | ||
|
df371458b3 | ||
|
e0e5efbead | ||
|
edb4460e64 | ||
|
fe72bfa070 | ||
|
25642c8840 | ||
|
03b1904b2e | ||
|
bb71a988c2 | ||
|
ddee61c9ba | ||
|
91efe74365 | ||
|
12a64ff24b | ||
|
b034896cd3 | ||
|
2bd625b754 | ||
|
da32068f48 | ||
|
b308d6709e | ||
|
123ad0de95 | ||
|
00fc38435f | ||
|
8b5b41bb47 | ||
|
4bdde668e1 | ||
|
3c0d86eb47 | ||
|
f60166c1a1 | ||
|
7d59f83b2e | ||
|
be81cd8c98 | ||
|
b075df1c87 | ||
|
8a91aa5e6c | ||
|
fae437cfad | ||
|
fc91bf4a65 | ||
|
78ea99d154 | ||
|
2165f9d654 | ||
|
31df12c84f | ||
|
d09d9f32bd | ||
|
690a08cbbb |
1
.gitmodules
vendored
1
.gitmodules
vendored
@@ -1,6 +1,7 @@
|
||||
[submodule "lib/chibios"]
|
||||
path = lib/chibios
|
||||
url = https://github.com/qmk/ChibiOS
|
||||
branch = handwire
|
||||
[submodule "lib/chibios-contrib"]
|
||||
path = lib/chibios-contrib
|
||||
url = https://github.com/qmk/ChibiOS-Contrib
|
||||
|
17
Makefile
17
Makefile
@@ -67,7 +67,7 @@ $(eval $(call NEXT_PATH_ELEMENT))
|
||||
# It's really a very simple if else chain, if you squint enough,
|
||||
# but the makefile syntax makes it very verbose.
|
||||
# If we are in a subfolder of keyboards
|
||||
#
|
||||
#
|
||||
# *** No longer needed **
|
||||
#
|
||||
# ifeq ($(CURRENT_PATH_ELEMENT),keyboards)
|
||||
@@ -320,6 +320,14 @@ define PARSE_KEYBOARD
|
||||
KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_3)/keymaps/*/.)))
|
||||
KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_4)/keymaps/*/.)))
|
||||
KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_5)/keymaps/*/.)))
|
||||
|
||||
# get subkeymaps too
|
||||
KEYMAPS += $$(patsubst $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_1)/keymaps/%,%,$$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_1)/keymaps/*/*/.)))
|
||||
KEYMAPS += $$(patsubst $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_2)/keymaps/%,%,$$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_2)/keymaps/*/*/.)))
|
||||
KEYMAPS += $$(patsubst $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_3)/keymaps/%,%,$$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_3)/keymaps/*/*/.)))
|
||||
KEYMAPS += $$(patsubst $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_4)/keymaps/%,%,$$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_4)/keymaps/*/*/.)))
|
||||
KEYMAPS += $$(patsubst $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_5)/keymaps/%,%,$$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_5)/keymaps/*/*/.)))
|
||||
|
||||
# this might be needed, but in a different form
|
||||
#KEYMAPS := $$(sort $$(filter-out $$(KEYBOARD_FOLDER_1) $$(KEYBOARD_FOLDER_2) \
|
||||
$$(KEYBOARD_FOLDER_3) $$(KEYBOARD_FOLDER_4) $$(KEYBOARD_FOLDER_5), $$(KEYMAPS)))
|
||||
@@ -353,9 +361,11 @@ define PARSE_KEYBOARD
|
||||
|
||||
LAYOUT_KEYMAPS :=
|
||||
$$(foreach LAYOUT,$$(KEYBOARD_LAYOUTS),$$(eval LAYOUT_KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/layouts/*/$$(LAYOUT)/*/.)))))
|
||||
|
||||
|
||||
KEYMAPS := $$(sort $$(KEYMAPS) $$(LAYOUT_KEYMAPS))
|
||||
|
||||
# $$(eval $$(info $$(KEYMAPS)))
|
||||
|
||||
# if the rule after removing the start of it is empty (we haven't specified a kemap or target)
|
||||
# compile all the keymaps
|
||||
ifeq ($$(RULE),)
|
||||
@@ -411,7 +421,8 @@ define PARSE_KEYMAP
|
||||
MAKE_TARGET := $$(patsubst :%,%,$$(RULE))
|
||||
# We need to generate an unique indentifer to append to the COMMANDS list
|
||||
CURRENT_KB_UNDER := $$(subst /,_,$$(CURRENT_KB))
|
||||
COMMAND := COMMAND_KEYBOARD_$$(CURRENT_KB_UNDER)_KEYMAP_$$(CURRENT_KM)
|
||||
CURRENT_KM_UNDER := $$(subst /,_,$$(CURRENT_KM))
|
||||
COMMAND := COMMAND_KEYBOARD_$$(CURRENT_KB_UNDER)_KEYMAP_$$(CURRENT_KM_UNDER)
|
||||
# If we are compiling a keyboard without a subproject, we want to display just the name
|
||||
# of the keyboard, otherwise keyboard/subproject
|
||||
KB_SP := $$(CURRENT_KB)
|
||||
|
@@ -19,8 +19,9 @@ KEYBOARD_FOLDER_4 := $(notdir $(KEYBOARD_FOLDER_PATH_4))
|
||||
KEYBOARD_FOLDER_5 := $(notdir $(KEYBOARD_FOLDER_PATH_5))
|
||||
|
||||
KEYBOARD_FILESAFE := $(subst /,_,$(KEYBOARD))
|
||||
KEYMAP_FILESAFE := $(subst /,_,$(KEYMAP))
|
||||
|
||||
TARGET ?= $(KEYBOARD_FILESAFE)_$(KEYMAP)
|
||||
TARGET ?= $(KEYBOARD_FILESAFE)_$(KEYMAP_FILESAFE)
|
||||
KEYBOARD_OUTPUT := $(BUILD_DIR)/obj_$(KEYBOARD_FILESAFE)
|
||||
|
||||
# Force expansion
|
||||
@@ -176,26 +177,44 @@ MAIN_KEYMAP_PATH_3 := $(KEYBOARD_PATH_3)/keymaps/$(KEYMAP)
|
||||
MAIN_KEYMAP_PATH_4 := $(KEYBOARD_PATH_4)/keymaps/$(KEYMAP)
|
||||
MAIN_KEYMAP_PATH_5 := $(KEYBOARD_PATH_5)/keymaps/$(KEYMAP)
|
||||
|
||||
PARENT_MAIN_KEYMAP_PATH_1 := $(patsubst %/,%,$(dir $(MAIN_KEYMAP_PATH_1)))
|
||||
PARENT_MAIN_KEYMAP_PATH_2 := $(patsubst %/,%,$(dir $(MAIN_KEYMAP_PATH_2)))
|
||||
PARENT_MAIN_KEYMAP_PATH_3 := $(patsubst %/,%,$(dir $(MAIN_KEYMAP_PATH_3)))
|
||||
PARENT_MAIN_KEYMAP_PATH_4 := $(patsubst %/,%,$(dir $(MAIN_KEYMAP_PATH_4)))
|
||||
PARENT_MAIN_KEYMAP_PATH_5 := $(patsubst %/,%,$(dir $(MAIN_KEYMAP_PATH_5)))
|
||||
|
||||
# $(info $(PARENT_MAIN_KEYMAP_PATH_1))
|
||||
|
||||
ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_5)/keymap.c)","")
|
||||
-include $(MAIN_KEYMAP_PATH_5)/rules.mk
|
||||
KEYMAP_C := $(MAIN_KEYMAP_PATH_5)/keymap.c
|
||||
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_5)
|
||||
else ifneq ("$(wildcard $(PARENT_MAIN_KEYMAP_PATH_5)/keymap.c)","")
|
||||
KEYMAP_C := $(PARENT_MAIN_KEYMAP_PATH_5)/keymap.c
|
||||
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_5)
|
||||
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_4)/keymap.c)","")
|
||||
-include $(MAIN_KEYMAP_PATH_4)/rules.mk
|
||||
KEYMAP_C := $(MAIN_KEYMAP_PATH_4)/keymap.c
|
||||
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_4)
|
||||
else ifneq ("$(wildcard $(PARENT_MAIN_KEYMAP_PATH_4)/keymap.c)","")
|
||||
KEYMAP_C := $(PARENT_MAIN_KEYMAP_PATH_4)/keymap.c
|
||||
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_4)
|
||||
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_3)/keymap.c)","")
|
||||
-include $(MAIN_KEYMAP_PATH_3)/rules.mk
|
||||
KEYMAP_C := $(MAIN_KEYMAP_PATH_3)/keymap.c
|
||||
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_3)
|
||||
else ifneq ("$(wildcard $(PARENT_MAIN_KEYMAP_PATH_3)/keymap.c)","")
|
||||
KEYMAP_C := $(PARENT_MAIN_KEYMAP_PATH_3)/keymap.c
|
||||
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_3)
|
||||
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_2)/keymap.c)","")
|
||||
-include $(MAIN_KEYMAP_PATH_2)/rules.mk
|
||||
KEYMAP_C := $(MAIN_KEYMAP_PATH_2)/keymap.c
|
||||
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_2)
|
||||
else ifneq ("$(wildcard $(PARENT_MAIN_KEYMAP_PATH_2)/keymap.c)","")
|
||||
KEYMAP_C := $(PARENT_MAIN_KEYMAP_PATH_2)/keymap.c
|
||||
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_2)
|
||||
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_1)/keymap.c)","")
|
||||
-include $(MAIN_KEYMAP_PATH_1)/rules.mk
|
||||
KEYMAP_C := $(MAIN_KEYMAP_PATH_1)/keymap.c
|
||||
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_1)
|
||||
else ifneq ("$(wildcard $(PARENT_MAIN_KEYMAP_PATH_1)/keymap.c)","")
|
||||
KEYMAP_C := $(PARENT_MAIN_KEYMAP_PATH_1)/keymap.c
|
||||
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_1)
|
||||
else ifneq ($(LAYOUTS),)
|
||||
include build_layout.mk
|
||||
else
|
||||
@@ -203,26 +222,34 @@ else
|
||||
# this state should never be reached
|
||||
endif
|
||||
|
||||
|
||||
PARENT_KEYMAP_PATH := $(patsubst %/,%,$(dir $(KEYMAP_PATH)))
|
||||
|
||||
# User space stuff
|
||||
ifeq ("$(USER_NAME)","")
|
||||
USER_NAME := $(KEYMAP)
|
||||
endif
|
||||
USER_PATH := users/$(USER_NAME)
|
||||
|
||||
-include $(USER_PATH)/rules.mk
|
||||
ifneq ("$(wildcard $(USER_PATH)/config.h)","")
|
||||
CONFIG_H += $(USER_PATH)/config.h
|
||||
endif
|
||||
|
||||
|
||||
# Object files directory
|
||||
# To put object files in current directory, use a dot (.), do NOT make
|
||||
# this an empty or blank macro!
|
||||
KEYMAP_OUTPUT := $(BUILD_DIR)/obj_$(TARGET)
|
||||
|
||||
-include $(PARENT_KEYMAP_PATH)/rules.mk
|
||||
-include $(KEYMAP_PATH)/rules.mk
|
||||
-include $(USER_PATH)/rules.mk
|
||||
|
||||
ifneq ("$(wildcard $(PARENT_KEYMAP_PATH)/config.h)","")
|
||||
CONFIG_H += $(PARENT_KEYMAP_PATH)/config.h
|
||||
endif
|
||||
ifneq ("$(wildcard $(KEYMAP_PATH)/config.h)","")
|
||||
CONFIG_H += $(KEYMAP_PATH)/config.h
|
||||
endif
|
||||
ifneq ("$(wildcard $(USER_PATH)/config.h)","")
|
||||
CONFIG_H += $(USER_PATH)/config.h
|
||||
endif
|
||||
|
||||
# # project specific files
|
||||
SRC += $(KEYBOARD_SRC) \
|
||||
@@ -233,6 +260,7 @@ SRC += $(KEYBOARD_SRC) \
|
||||
#EXTRALDFLAGS = -Wl,--relax
|
||||
|
||||
# Search Path
|
||||
VPATH += $(PARENT_KEYMAP_PATH)
|
||||
VPATH += $(KEYMAP_PATH)
|
||||
VPATH += $(KEYBOARD_PATHS)
|
||||
VPATH += $(COMMON_VPATH)
|
||||
|
@@ -3,11 +3,15 @@ LAYOUTS_REPOS := $(patsubst %/,%,$(sort $(dir $(wildcard $(LAYOUTS_PATH)/*/))))
|
||||
|
||||
define SEARCH_LAYOUTS_REPO
|
||||
LAYOUT_KEYMAP_PATH := $$(LAYOUTS_REPO)/$$(LAYOUT)/$$(KEYMAP)
|
||||
PARENT_LAYOUT_KEYMAP_PATH := $(patsubst %/,%,$(dir $(LAYOUT_KEYMAP_PATH)))
|
||||
LAYOUT_KEYMAP_C := $$(LAYOUT_KEYMAP_PATH)/keymap.c
|
||||
PARENT_LAYOUT_KEYMAP_C := $$(PARENT_LAYOUT_KEYMAP_PATH)/keymap.c
|
||||
ifneq ("$$(wildcard $$(LAYOUT_KEYMAP_C))","")
|
||||
-include $$(LAYOUT_KEYMAP_PATH)/rules.mk
|
||||
KEYMAP_C := $$(LAYOUT_KEYMAP_C)
|
||||
KEYMAP_PATH := $$(LAYOUT_KEYMAP_PATH)
|
||||
else ifneq ("$$(wildcard $$(PARENT_LAYOUT_KEYMAP_C))","")
|
||||
KEYMAP_C := $$(PARENT_LAYOUT_KEYMAP_C)
|
||||
KEYMAP_PATH := $$(LAYOUT_KEYMAP_PATH)
|
||||
endif
|
||||
endef
|
||||
|
||||
@@ -15,4 +19,4 @@ define SEARCH_LAYOUTS
|
||||
$$(foreach LAYOUTS_REPO,$$(LAYOUTS_REPOS),$$(eval $$(call SEARCH_LAYOUTS_REPO)))
|
||||
endef
|
||||
|
||||
$(foreach LAYOUT,$(LAYOUTS),$(eval $(call SEARCH_LAYOUTS)))
|
||||
$(foreach LAYOUT,$(LAYOUTS),$(eval $(call SEARCH_LAYOUTS)))
|
||||
|
12
common.mk
12
common.mk
@@ -3,16 +3,16 @@ include message.mk
|
||||
# Directory common source files exist
|
||||
TOP_DIR = .
|
||||
TMK_DIR = tmk_core
|
||||
TMK_PATH = $(TOP_DIR)/$(TMK_DIR)
|
||||
LIB_PATH = $(TOP_DIR)/lib
|
||||
TMK_PATH = $(TMK_DIR)
|
||||
LIB_PATH = lib
|
||||
|
||||
QUANTUM_DIR = quantum
|
||||
QUANTUM_PATH = $(TOP_DIR)/$(QUANTUM_DIR)
|
||||
QUANTUM_PATH = $(QUANTUM_DIR)
|
||||
|
||||
DRIVER_DIR = drivers
|
||||
DRIVER_PATH = $(TOP_DIR)/$(DRIVER_DIR)
|
||||
DRIVER_PATH = $(DRIVER_DIR)
|
||||
|
||||
BUILD_DIR := $(TOP_DIR)/.build
|
||||
BUILD_DIR := .build
|
||||
|
||||
COMMON_VPATH := $(TOP_DIR)
|
||||
COMMON_VPATH += $(TMK_PATH)
|
||||
@@ -21,4 +21,4 @@ COMMON_VPATH += $(QUANTUM_PATH)/keymap_extras
|
||||
COMMON_VPATH += $(QUANTUM_PATH)/audio
|
||||
COMMON_VPATH += $(QUANTUM_PATH)/process_keycode
|
||||
COMMON_VPATH += $(QUANTUM_PATH)/api
|
||||
COMMON_VPATH += $(DRIVER_PATH)
|
||||
COMMON_VPATH += $(DRIVER_PATH)
|
||||
|
@@ -20,6 +20,13 @@ SERIAL_SRC += $(wildcard $(SERIAL_PATH)/system/*.c)
|
||||
SERIAL_DEFS += -DSERIAL_LINK_ENABLE
|
||||
COMMON_VPATH += $(SERIAL_PATH)
|
||||
|
||||
COMMON_VPATH += $(DRIVER_PATH)
|
||||
ifeq ($(PLATFORM),AVR)
|
||||
COMMON_VPATH += $(DRIVER_PATH)/avr
|
||||
else
|
||||
COMMON_VPATH += $(DRIVER_PATH)/arm
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(API_SYSEX_ENABLE)), yes)
|
||||
OPT_DEFS += -DAPI_SYSEX_ENABLE
|
||||
SRC += $(QUANTUM_DIR)/api/api_sysex.c
|
||||
@@ -117,7 +124,7 @@ endif
|
||||
ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
|
||||
OPT_DEFS += -DRGB_MATRIX_ENABLE
|
||||
SRC += is31fl3731.c
|
||||
SRC += i2c_master.c
|
||||
I2C_ENABLE = yes
|
||||
SRC += $(QUANTUM_DIR)/color.c
|
||||
SRC += $(QUANTUM_DIR)/rgb_matrix.c
|
||||
CIE1931_CURVE = yes
|
||||
@@ -197,6 +204,25 @@ ifeq ($(strip $(USB_HID_ENABLE)), yes)
|
||||
include $(TMK_DIR)/protocol/usb_hid.mk
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(I2C_SLAVE_ENABLE)), yes)
|
||||
I2C_ENABLE = yes
|
||||
OPT_DEFS += -DI2C_SLAVE_ENABLE
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(ENCODER_ENABLE)), yes)
|
||||
OPT_DEFS += -DENCODER_ENABLE
|
||||
SRC += $(QUANTUM_DIR)/encoder.c
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(QWIIC_KEYBOARD_ENABLE)), yes)
|
||||
SRC += qwiic/qwiic_keyboard.c
|
||||
OPT_DEFS += -DQWIIC_KEYBOARD_ENABLE
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(I2C_ENABLE)), yes)
|
||||
SRC += twi2c.c
|
||||
endif
|
||||
|
||||
QUANTUM_SRC:= \
|
||||
$(QUANTUM_DIR)/quantum.c \
|
||||
$(QUANTUM_DIR)/keymap_common.c \
|
||||
|
@@ -34,6 +34,7 @@
|
||||
* [Bootmagic](feature_bootmagic.md)
|
||||
* [Command](feature_command.md)
|
||||
* [Dynamic Macros](feature_dynamic_macros.md)
|
||||
* [Encoders](feature_encoders.md)
|
||||
* [Grave Escape](feature_grave_esc.md)
|
||||
* [Key Lock](feature_key_lock.md)
|
||||
* [Layouts](feature_layouts.md)
|
||||
|
@@ -135,11 +135,9 @@ void led_set_user(uint8_t usb_led) {
|
||||
* Keyboard/Revision: `void led_set_kb(uint8_t usb_led)`
|
||||
* Keymap: `void led_set_user(uint8_t usb_led)`
|
||||
|
||||
|
||||
# Matrix Initialization Code
|
||||
|
||||
Before a keyboard can be used the hardware must be initialized. QMK handles initialization of the keyboard matrix itself, but if you have other hardware like LED's or i²c controllers you will need to set up that hardware before it can be used.
|
||||
|
||||
Before a keyboard can be used the hardware must be initialized. QMK handles initialization of the keyboard matrix itself, but if you have other hardware like LED's or i²c controllers you will need to set up that hardware before it can be used.
|
||||
|
||||
### Example `matrix_init_user()` Implementation
|
||||
|
||||
@@ -179,38 +177,9 @@ This function gets called at every matrix scan, which is basically as often as t
|
||||
You should use this function if you need custom matrix scanning code. It can also be used for custom status output (such as LED's or a display) or other functionality that you want to trigger regularly even when the user isn't typing.
|
||||
|
||||
|
||||
# Keyboard Idling/Wake Code
|
||||
|
||||
If the board supports it, it can be "idled", by stopping a number of functions. A good example of this is RGB lights or backlights. This can save on power consumption, or may be better behavior for your keyboard.
|
||||
|
||||
This is controlled by two functions: `suspend_power_down_*` and `suspend_wakeup_init_*`, which are called when the system is board is idled and when it wakes up, respectively.
|
||||
|
||||
|
||||
### Example suspend_power_down_user() and suspend_wakeup_init_user() Implementation
|
||||
|
||||
This example, at the keyboard level, sets up B1, B2, and B3 as LED pins.
|
||||
|
||||
```
|
||||
void suspend_power_down_user(void)
|
||||
{
|
||||
rgb_matrix_set_suspend_state(true);
|
||||
}
|
||||
|
||||
void suspend_wakeup_init_user(void)
|
||||
{
|
||||
rgb_matrix_set_suspend_state(false);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### `keyboard_init_*` Function Documentation
|
||||
|
||||
* Keyboard/Revision: `void suspend_power_down_kb(void)` and `void suspend_wakeup_init_user(void)`
|
||||
* Keymap: `void suspend_power_down_kb(void)` and `void suspend_wakeup_init_user(void)`
|
||||
|
||||
# Layer Change Code
|
||||
|
||||
This runs code every time that the layers get changed. This can be useful for layer indication, or custom layer handling.
|
||||
Thir runs code every time that the layers get changed. This can be useful for layer indication, or custom layer handling.
|
||||
|
||||
### Example `layer_state_set_*` Implementation
|
||||
|
||||
|
41
docs/feature_encoders.md
Normal file
41
docs/feature_encoders.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Encoders
|
||||
|
||||
Basic encoders are supported by adding this to your `rules.mk`:
|
||||
|
||||
ENCODER_ENABLE = yes
|
||||
|
||||
and this to your `config.h`:
|
||||
|
||||
#define NUMBER_OF_ENCODERS 1
|
||||
#define ENCODERS_PAD_A { B12 }
|
||||
#define ENCODERS_PAD_B { B13 }
|
||||
|
||||
Each PAD_A/B variable defines an array so multiple encoders can be defined, e.g.:
|
||||
|
||||
#define ENCODERS_PAD_A { encoder1a, encoder2a }
|
||||
#define ENCODERS_PAD_B { encoder1a, encoder2b }
|
||||
|
||||
If your encoder's clockwise directions are incorrect, you can swap the A & B pad definitions.
|
||||
|
||||
Additionally, the resolution can be specified in the same file (the default & suggested is 4):
|
||||
|
||||
#define ENCODER_RESOLUTION 4
|
||||
|
||||
## Callbacks
|
||||
|
||||
The callback functions can be inserted into your `<keyboard>.c`:
|
||||
|
||||
void encoder_update_kb(uint8_t index, bool clockwise) {
|
||||
encoder_update_user(index, clockwise);
|
||||
}
|
||||
|
||||
or `keymap.c`:
|
||||
|
||||
void encoder_update_user(uint8_t index, bool clockwise) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
## Hardware
|
||||
|
||||
The A an B lines of the encoders should be wired directly to the MCU, and the C/common lines should be wired to ground.
|
@@ -47,6 +47,16 @@ The `info.json` file is a JSON formatted dictionary with the following keys avai
|
||||
* Example: `Clueboard 66%`
|
||||
* `url`
|
||||
* A URL to the keyboard's product page, [QMK.fm/keyboards](https://qmk.fm/keyboards) page, or other page describing information about the keyboard.
|
||||
* `bootloader`
|
||||
* What bootloader this keyboard uses. Available options:
|
||||
* `atmel-dfu`
|
||||
* `kiibohd-dfu-util`
|
||||
* `lufa-dfu`
|
||||
* `qmk-dfu`
|
||||
* `stm32-dfu-util`
|
||||
* `caterina`
|
||||
* `halfkay`
|
||||
* `bootloadHID`
|
||||
* `maintainer`
|
||||
* GitHub username of the maintainer, or `qmk` for community maintained boards
|
||||
* `width`
|
||||
|
168
drivers/arm/twi2c.c
Normal file
168
drivers/arm/twi2c.c
Normal file
@@ -0,0 +1,168 @@
|
||||
/* 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 "twi2c.h"
|
||||
#include <string.h>
|
||||
#include <hal.h>
|
||||
#include "chprintf.h"
|
||||
#include "memstreams.h"
|
||||
#include "printf.h"
|
||||
#include "hal_i2cslave.h"
|
||||
|
||||
/**
|
||||
* I2C slave test routine.
|
||||
*
|
||||
* To use: Add file to a project, call startComms() with the address of a serial stream
|
||||
*
|
||||
* There are two different responses:
|
||||
* a) A read-only transaction - returns the "Initial Reply" message
|
||||
* b) A write then read transaction - calls a message processor and returns the generated reply.
|
||||
* Stretches clock until reply available.
|
||||
*/
|
||||
// static const I2CConfig masterI2CConfig = {
|
||||
// 400000
|
||||
// };
|
||||
|
||||
I2CSlaveMsgCB twi2c_incoming_message_process, twi2c_catch_error, twi2c_clear_after_send;
|
||||
twi2c_message_received twi2c_message_received_callback;
|
||||
|
||||
static uint8_t twi2c_address;
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
/**
|
||||
* Track I2C errors
|
||||
*/
|
||||
uint8_t gotI2cError = 0;
|
||||
uint32_t lastI2cErrorFlags = 0;
|
||||
|
||||
// Called from ISR to log error
|
||||
void noteI2cError(uint32_t flags)
|
||||
{
|
||||
lastI2cErrorFlags = flags;
|
||||
gotI2cError = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic error handler
|
||||
*
|
||||
* Called in interrupt context, so need to watch what we do
|
||||
*/
|
||||
void twi2c_catch_error(I2CDriver *i2cp)
|
||||
{
|
||||
noteI2cError(i2cp->errors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback after sending of response complete - restores default reply in case polled
|
||||
*/
|
||||
void twi2c_clear_after_send(I2CDriver *i2cp)
|
||||
{
|
||||
// echoReply.size = 0; // Clear receive message
|
||||
// i2cSlaveReplyI(i2cp, &initialReply);
|
||||
}
|
||||
|
||||
uint8_t twi2c_start(void) {
|
||||
i2cStart(&I2C_DRIVER, &i2cconfig);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void twi2c_init(void) {
|
||||
palSetGroupMode(GPIOB,6,7, 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);
|
||||
|
||||
// try high drive (from kiibohd)
|
||||
// I2C_DRIVER.i2c->C2 |= I2Cx_C2_HDRS;
|
||||
// try glitch fixing (from kiibohd)
|
||||
// I2C_DRIVER.i2c->FLT = 4;
|
||||
}
|
||||
|
||||
uint8_t twi2c_write(uint8_t data) {
|
||||
return i2cMasterTransmitTimeout(&I2C_DRIVER, twi2c_address/2, &data, 1, 0, 0, MS2ST(100));
|
||||
}
|
||||
|
||||
uint8_t twi2c_transmit(uint8_t address, uint8_t * data, uint16_t length) {
|
||||
return i2cMasterTransmitTimeout(&I2C_DRIVER, address/2, data, length, 0, 0, MS2ST(100));
|
||||
}
|
||||
|
||||
uint8_t twi2c_receive(uint8_t address, uint8_t * data, uint16_t length) {
|
||||
return i2cMasterReceiveTimeout(&I2C_DRIVER, address/2, data, length, MS2ST(100));
|
||||
}
|
||||
|
||||
|
||||
uint8_t twi2c_incoming_body[50];
|
||||
uint8_t twi2c_outgoing_body[1024];
|
||||
|
||||
// Response to received messages
|
||||
I2CSlaveMsg twi2c_incoming_message = {
|
||||
sizeof(twi2c_incoming_body),
|
||||
twi2c_incoming_body,
|
||||
NULL,
|
||||
twi2c_incoming_message_process,
|
||||
twi2c_catch_error /* Error hook */
|
||||
};
|
||||
|
||||
void twi2c_incoming_message_process(I2CDriver * i2cp) {
|
||||
size_t len = i2cSlaveBytes(i2cp);
|
||||
(*twi2c_message_received_callback)(i2cp, twi2c_incoming_body, len);
|
||||
}
|
||||
|
||||
// Response to received messages
|
||||
I2CSlaveMsg twi2c_outgoing_message = {
|
||||
sizeof(twi2c_outgoing_body),
|
||||
twi2c_outgoing_body,
|
||||
NULL,
|
||||
twi2c_clear_after_send,
|
||||
twi2c_catch_error
|
||||
};
|
||||
|
||||
uint8_t twi2c_reply(I2CDriver * i2cp, uint8_t * data, uint16_t length) {
|
||||
memcpy(twi2c_outgoing_body, data, length);
|
||||
twi2c_outgoing_message.size = length;
|
||||
i2cSlaveReplyI(i2cp, &twi2c_outgoing_message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t twi2c_transmit_receive(uint8_t address, uint8_t * tx_body, uint16_t tx_length, uint8_t * rx_body, uint16_t rx_length) {
|
||||
return i2cMasterTransmitTimeout(&I2C_DRIVER, address/2, tx_body, tx_length, rx_body, rx_length, MS2ST(100));
|
||||
}
|
||||
|
||||
uint8_t twi2c_start_listening(uint8_t address, twi2c_message_received callback) {
|
||||
twi2c_message_received_callback = callback;
|
||||
I2C_DRIVER.slaveTimeout = MS2ST(100);
|
||||
i2cSlaveConfigure(&I2C_DRIVER, &twi2c_incoming_message, &twi2c_outgoing_message);
|
||||
i2cMatchAddress(&I2C_DRIVER, address/2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t twi2c_restart_listening(uint8_t address) {
|
||||
i2cMatchAddress(&I2C_DRIVER, address/2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void twi2c_stop(void) {
|
||||
i2cUnmatchAll(&I2C_DRIVER);
|
||||
i2cStop(&I2C_DRIVER);
|
||||
}
|
48
drivers/arm/twi2c.h
Normal file
48
drivers/arm/twi2c.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef TWI2C_H
|
||||
#define TWI2C_H
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#ifndef I2C_DRIVER
|
||||
#define I2C_DRIVER I2CD1
|
||||
#endif
|
||||
|
||||
#define slaveI2Caddress 0x30 /* Address in our terms - halved by later code */
|
||||
//#define myOtherI2Caddress 0x19
|
||||
I2CSlaveMsgCB twi2c_incoming_message_process, twi2c_catch_error, twi2c_clear_after_send;
|
||||
typedef void (*twi2c_message_received)(I2CDriver *, uint8_t *, uint16_t);
|
||||
|
||||
void twi2c_init(void);
|
||||
uint8_t twi2c_start(void);
|
||||
uint8_t twi2c_write(uint8_t data);
|
||||
uint8_t twi2c_read_ack(void);
|
||||
uint8_t twi2c_read_nack(void);
|
||||
uint8_t twi2c_transmit(uint8_t address, uint8_t* data, uint16_t length);
|
||||
uint8_t twi2c_receive(uint8_t address, uint8_t* data, uint16_t length);
|
||||
uint8_t twi2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length);
|
||||
uint8_t twi2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length);
|
||||
void twi2c_stop(void);
|
||||
|
||||
uint8_t twi2c_reply(I2CDriver * i2cp, uint8_t * data, uint16_t length);
|
||||
uint8_t twi2c_transmit_receive(uint8_t address, uint8_t * tx_body, uint16_t tx_length, uint8_t * rx_body, uint16_t rx_length);
|
||||
uint8_t twi2c_start_listening(uint8_t address, twi2c_message_received callback);
|
||||
uint8_t twi2c_restart_listening(uint8_t address);
|
||||
|
||||
#endif
|
159
drivers/arm/ws2812.c
Normal file
159
drivers/arm/ws2812.c
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* LEDDriver.c
|
||||
*
|
||||
* Created on: Aug 26, 2013
|
||||
* Author: Omri Iluz
|
||||
*/
|
||||
|
||||
#include "ws2812.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
static uint8_t *fb;
|
||||
static int sLeds;
|
||||
static stm32_gpio_t *sPort;
|
||||
static uint32_t sMask;
|
||||
uint8_t* dma_source;
|
||||
|
||||
void setColor(uint8_t color, uint8_t *buf,uint32_t mask){
|
||||
int i;
|
||||
for (i=0;i<8;i++){
|
||||
buf[i]=((color<<i)&0b10000000?0x0:mask);
|
||||
}
|
||||
}
|
||||
|
||||
void setColorRGB(Color c, uint8_t *buf, uint32_t mask){
|
||||
setColor(c.G,buf, mask);
|
||||
setColor(c.R,buf+8, mask);
|
||||
setColor(c.B,buf+16, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize Led Driver
|
||||
* @details Initialize the Led Driver based on parameters.
|
||||
* Following initialization, the frame buffer would automatically be
|
||||
* exported to the supplied port and pins in the right timing to drive
|
||||
* a chain of WS2812B controllers
|
||||
* @note The function assumes the controller is running at 72Mhz
|
||||
* @note Timing is critical for WS2812. While all timing is done in hardware
|
||||
* need to verify memory bandwidth is not exhausted to avoid DMA delays
|
||||
*
|
||||
* @param[in] leds length of the LED chain controlled by each pin
|
||||
* @param[in] port which port would be used for output
|
||||
* @param[in] mask Which pins would be used for output, each pin is a full chain
|
||||
* @param[out] o_fb initialized frame buffer
|
||||
*
|
||||
*/
|
||||
void ledDriverInit(int leds, stm32_gpio_t *port, uint32_t mask, uint8_t **o_fb) {
|
||||
sLeds=leds;
|
||||
sPort=port;
|
||||
sMask=mask;
|
||||
palSetGroupMode(port, sMask, 0, PAL_MODE_OUTPUT_PUSHPULL|PAL_STM32_OSPEED_HIGHEST|PAL_STM32_PUPDR_FLOATING);
|
||||
|
||||
// configure pwm timers -
|
||||
// timer 2 as master, active for data transmission and inactive to disable transmission during reset period (50uS)
|
||||
// timer 3 as slave, during active time creates a 1.25 uS signal, with duty cycle controlled by frame buffer values
|
||||
static PWMConfig pwmc2 = {72000000 / 90, /* 800Khz PWM clock frequency. 1/90 of PWMC3 */
|
||||
(72000000 / 90) * 0.05, /*Total period is 50ms (20FPS), including sLeds cycles + reset length for ws2812b and FB writes */
|
||||
NULL,
|
||||
{ {PWM_OUTPUT_ACTIVE_HIGH, NULL},
|
||||
{PWM_OUTPUT_DISABLED, NULL},
|
||||
{PWM_OUTPUT_DISABLED, NULL},
|
||||
{PWM_OUTPUT_DISABLED, NULL}},
|
||||
TIM_CR2_MMS_2, /* master mode selection */
|
||||
0, };
|
||||
/* master mode selection */
|
||||
static PWMConfig pwmc3 = {72000000,/* 72Mhz PWM clock frequency. */
|
||||
90, /* 90 cycles period (1.25 uS per period @72Mhz */
|
||||
NULL,
|
||||
{ {PWM_OUTPUT_ACTIVE_HIGH, NULL},
|
||||
{PWM_OUTPUT_ACTIVE_HIGH, NULL},
|
||||
{PWM_OUTPUT_ACTIVE_HIGH, NULL},
|
||||
{PWM_OUTPUT_ACTIVE_HIGH, NULL}},
|
||||
0,
|
||||
0,
|
||||
};
|
||||
dma_source = chHeapAlloc(NULL, 1);
|
||||
fb = chHeapAlloc(NULL, ((sLeds) * 24)+10);
|
||||
*o_fb=fb;
|
||||
int j;
|
||||
for (j = 0; j < (sLeds) * 24; j++) fb[j] = 0;
|
||||
dma_source[0] = sMask;
|
||||
// DMA stream 2, triggered by channel3 pwm signal. if FB indicates, reset output value early to indicate "0" bit to ws2812
|
||||
dmaStreamAllocate(STM32_DMA1_STREAM2, 10, NULL, NULL);
|
||||
dmaStreamSetPeripheral(STM32_DMA1_STREAM2, &(sPort->BSRR.H.clear));
|
||||
dmaStreamSetMemory0(STM32_DMA1_STREAM2, fb);
|
||||
dmaStreamSetTransactionSize(STM32_DMA1_STREAM2, (sLeds) * 24);
|
||||
dmaStreamSetMode(
|
||||
STM32_DMA1_STREAM2,
|
||||
STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_MINC | STM32_DMA_CR_PSIZE_BYTE
|
||||
| STM32_DMA_CR_MSIZE_BYTE | STM32_DMA_CR_CIRC | STM32_DMA_CR_PL(2));
|
||||
// DMA stream 3, triggered by pwm update event. output high at beginning of signal
|
||||
dmaStreamAllocate(STM32_DMA1_STREAM3, 10, NULL, NULL);
|
||||
dmaStreamSetPeripheral(STM32_DMA1_STREAM3, &(sPort->BSRR.H.set));
|
||||
dmaStreamSetMemory0(STM32_DMA1_STREAM3, dma_source);
|
||||
dmaStreamSetTransactionSize(STM32_DMA1_STREAM3, 1);
|
||||
dmaStreamSetMode(
|
||||
STM32_DMA1_STREAM3, STM32_DMA_CR_TEIE |
|
||||
STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE
|
||||
| STM32_DMA_CR_CIRC | STM32_DMA_CR_PL(3));
|
||||
// DMA stream 6, triggered by channel1 update event. reset output value late to indicate "1" bit to ws2812.
|
||||
// always triggers but no affect if dma stream 2 already change output value to 0
|
||||
dmaStreamAllocate(STM32_DMA1_STREAM6, 10, NULL, NULL);
|
||||
dmaStreamSetPeripheral(STM32_DMA1_STREAM6, &(sPort->BSRR.H.clear));
|
||||
dmaStreamSetMemory0(STM32_DMA1_STREAM6, dma_source);
|
||||
dmaStreamSetTransactionSize(STM32_DMA1_STREAM6, 1);
|
||||
dmaStreamSetMode(
|
||||
STM32_DMA1_STREAM6,
|
||||
STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE
|
||||
| STM32_DMA_CR_CIRC | STM32_DMA_CR_PL(3));
|
||||
pwmStart(&PWMD2, &pwmc2);
|
||||
pwmStart(&PWMD3, &pwmc3);
|
||||
// set pwm3 as slave, triggerd by pwm2 oc1 event. disables pwmd2 for synchronization.
|
||||
PWMD3.tim->SMCR |= TIM_SMCR_SMS_0 | TIM_SMCR_SMS_2 | TIM_SMCR_TS_0;
|
||||
PWMD2.tim->CR1 &= ~TIM_CR1_CEN;
|
||||
// set pwm values.
|
||||
// 28 (duty in ticks) / 90 (period in ticks) * 1.25uS (period in S) = 0.39 uS
|
||||
pwmEnableChannel(&PWMD3, 2, 28);
|
||||
// 58 (duty in ticks) / 90 (period in ticks) * 1.25uS (period in S) = 0.806 uS
|
||||
pwmEnableChannel(&PWMD3, 0, 58);
|
||||
// active during transfer of 90 cycles * sLeds * 24 bytes * 1/90 multiplier
|
||||
pwmEnableChannel(&PWMD2, 0, 90 * sLeds * 24 / 90);
|
||||
// stop and reset counters for synchronization
|
||||
PWMD2.tim->CNT = 0;
|
||||
// Slave (TIM3) needs to "update" immediately after master (TIM2) start in order to start in sync.
|
||||
// this initial sync is crucial for the stability of the run
|
||||
PWMD3.tim->CNT = 89;
|
||||
PWMD3.tim->DIER |= TIM_DIER_CC3DE | TIM_DIER_CC1DE | TIM_DIER_UDE;
|
||||
dmaStreamEnable(STM32_DMA1_STREAM3);
|
||||
dmaStreamEnable(STM32_DMA1_STREAM6);
|
||||
dmaStreamEnable(STM32_DMA1_STREAM2);
|
||||
// all systems go! both timers and all channels are configured to resonate
|
||||
// in complete sync without any need for CPU cycles (only DMA and timers)
|
||||
// start pwm2 for system to start resonating
|
||||
PWMD2.tim->CR1 |= TIM_CR1_CEN;
|
||||
}
|
||||
|
||||
void ledDriverWaitCycle(void){
|
||||
while (PWMD2.tim->CNT < 90 * sLeds * 24 / 90){chThdSleepMicroseconds(1);};
|
||||
}
|
||||
|
||||
void testPatternFB(uint8_t *fb){
|
||||
int i;
|
||||
Color tmpC = {rand()%256, rand()%256, rand()%256};
|
||||
for (i=0;i<sLeds;i++){
|
||||
setColorRGB(tmpC,fb+24*i, sMask);
|
||||
}
|
||||
}
|
||||
|
||||
void ws2812_setleds(LED_TYPE *ledarray, uint16_t number_of_leds) {
|
||||
// uint8_t i = 0;
|
||||
// while (i < number_of_leds) {
|
||||
// ws2812_write_led(i, ledarray[i].r, ledarray[i].g, ledarray[i].b);
|
||||
// i++;
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
void ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t number_of_leds) {
|
||||
|
||||
}
|
31
drivers/arm/ws2812.h
Normal file
31
drivers/arm/ws2812.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* LEDDriver.h
|
||||
*
|
||||
* Created on: Aug 26, 2013
|
||||
* Author: Omri Iluz
|
||||
*/
|
||||
|
||||
#ifndef WS2812_H_
|
||||
#define WS2812_H_
|
||||
|
||||
#include "hal.h"
|
||||
#include "rgblight_types.h"
|
||||
|
||||
#define sign(x) (( x > 0 ) - ( x < 0 ))
|
||||
|
||||
typedef struct Color Color;
|
||||
struct Color {
|
||||
uint8_t R;
|
||||
uint8_t G;
|
||||
uint8_t B;
|
||||
};
|
||||
|
||||
void ledDriverInit(int leds, stm32_gpio_t *port, uint32_t mask, uint8_t **o_fb);
|
||||
void setColorRGB(Color c, uint8_t *buf, uint32_t mask);
|
||||
void testPatternFB(uint8_t *fb);
|
||||
void ledDriverWaitCycle(void);
|
||||
|
||||
void ws2812_setleds(LED_TYPE *ledarray, uint16_t number_of_leds);
|
||||
void ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t number_of_leds);
|
||||
|
||||
#endif /* LEDDRIVER_H_ */
|
@@ -1,22 +0,0 @@
|
||||
/* Library made by: g4lvanix
|
||||
* Github repository: https://github.com/g4lvanix/I2C-master-lib
|
||||
*/
|
||||
|
||||
#ifndef I2C_MASTER_H
|
||||
#define I2C_MASTER_H
|
||||
|
||||
#define I2C_READ 0x01
|
||||
#define I2C_WRITE 0x00
|
||||
|
||||
void i2c_init(void);
|
||||
uint8_t i2c_start(uint8_t address);
|
||||
uint8_t i2c_write(uint8_t data);
|
||||
uint8_t i2c_read_ack(void);
|
||||
uint8_t i2c_read_nack(void);
|
||||
uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length);
|
||||
uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length);
|
||||
uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length);
|
||||
uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length);
|
||||
void i2c_stop(void);
|
||||
|
||||
#endif // I2C_MASTER_H
|
@@ -1,244 +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'
|
||||
|
||||
// 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;
|
||||
|
||||
//Transmit data until succesful
|
||||
while(i2c_transmit(addr << 1, g_twi_transfer_buffer,2) != 0);
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
//Transmit buffer until succesful
|
||||
while(i2c_transmit(addr << 1, g_twi_transfer_buffer,17) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
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] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
122
drivers/avr/i2c_master.c → drivers/avr/twi2c.c
Executable file → Normal file
122
drivers/avr/i2c_master.c → drivers/avr/twi2c.c
Executable file → Normal file
@@ -5,44 +5,44 @@
|
||||
#include <avr/io.h>
|
||||
#include <util/twi.h>
|
||||
|
||||
#include "i2c_master.h"
|
||||
#include "twi2c.h"
|
||||
|
||||
#define F_SCL 400000UL // SCL frequency
|
||||
#define Prescaler 1
|
||||
#define TWBR_val ((((F_CPU / F_SCL) / Prescaler) - 16 ) / 2)
|
||||
|
||||
void i2c_init(void)
|
||||
void twi2c_init(void)
|
||||
{
|
||||
TWBR = (uint8_t)TWBR_val;
|
||||
}
|
||||
|
||||
uint8_t i2c_start(uint8_t address)
|
||||
uint8_t twi2c_start(uint8_t address)
|
||||
{
|
||||
// reset TWI control register
|
||||
TWCR = 0;
|
||||
// transmit START condition
|
||||
// transmit START condition
|
||||
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
|
||||
// wait for end of transmission
|
||||
while( !(TWCR & (1<<TWINT)) );
|
||||
|
||||
|
||||
// check if the start condition was successfully transmitted
|
||||
if((TWSR & 0xF8) != TW_START){ return 1; }
|
||||
|
||||
|
||||
// load slave address into data register
|
||||
TWDR = address;
|
||||
// start transmission of address
|
||||
TWCR = (1<<TWINT) | (1<<TWEN);
|
||||
// wait for end of transmission
|
||||
while( !(TWCR & (1<<TWINT)) );
|
||||
|
||||
|
||||
// check if the device has acknowledged the READ / WRITE mode
|
||||
uint8_t twst = TW_STATUS & 0xF8;
|
||||
if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t i2c_write(uint8_t data)
|
||||
uint8_t twi2c_write(uint8_t data)
|
||||
{
|
||||
// load data into data register
|
||||
TWDR = data;
|
||||
@@ -50,26 +50,26 @@ uint8_t i2c_write(uint8_t data)
|
||||
TWCR = (1<<TWINT) | (1<<TWEN);
|
||||
// wait for end of transmission
|
||||
while( !(TWCR & (1<<TWINT)) );
|
||||
|
||||
|
||||
if( (TWSR & 0xF8) != TW_MT_DATA_ACK ){ return 1; }
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t i2c_read_ack(void)
|
||||
uint8_t twi2c_read_ack(void)
|
||||
{
|
||||
|
||||
|
||||
// start TWI module and acknowledge data after reception
|
||||
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
|
||||
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
|
||||
// wait for end of transmission
|
||||
while( !(TWCR & (1<<TWINT)) );
|
||||
// return received data from TWDR
|
||||
return TWDR;
|
||||
}
|
||||
|
||||
uint8_t i2c_read_nack(void)
|
||||
uint8_t twi2c_read_nack(void)
|
||||
{
|
||||
|
||||
|
||||
// start receiving without acknowledging reception
|
||||
TWCR = (1<<TWINT) | (1<<TWEN);
|
||||
// wait for end of transmission
|
||||
@@ -78,71 +78,71 @@ uint8_t i2c_read_nack(void)
|
||||
return TWDR;
|
||||
}
|
||||
|
||||
uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length)
|
||||
uint8_t twi2c_transmit(uint8_t address, uint8_t* data, uint16_t length)
|
||||
{
|
||||
if (i2c_start(address | I2C_WRITE)) return 1;
|
||||
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
if (i2c_write(data[i])) return 1;
|
||||
}
|
||||
|
||||
i2c_stop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length)
|
||||
{
|
||||
if (i2c_start(address | I2C_READ)) return 1;
|
||||
|
||||
for (uint16_t i = 0; i < (length-1); i++)
|
||||
{
|
||||
data[i] = i2c_read_ack();
|
||||
}
|
||||
data[(length-1)] = i2c_read_nack();
|
||||
|
||||
i2c_stop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length)
|
||||
{
|
||||
if (i2c_start(devaddr | 0x00)) return 1;
|
||||
|
||||
i2c_write(regaddr);
|
||||
if (twi2c_start(address | I2C_WRITE)) return 1;
|
||||
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
if (i2c_write(data[i])) return 1;
|
||||
if (twi2c_write(data[i])) return 1;
|
||||
}
|
||||
|
||||
i2c_stop();
|
||||
twi2c_stop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length)
|
||||
uint8_t twi2c_receive(uint8_t address, uint8_t* data, uint16_t length)
|
||||
{
|
||||
if (i2c_start(devaddr)) return 1;
|
||||
|
||||
i2c_write(regaddr);
|
||||
|
||||
if (i2c_start(devaddr | 0x01)) return 1;
|
||||
if (twi2c_start(address | I2C_READ)) return 1;
|
||||
|
||||
for (uint16_t i = 0; i < (length-1); i++)
|
||||
{
|
||||
data[i] = i2c_read_ack();
|
||||
data[i] = twi2c_read_ack();
|
||||
}
|
||||
data[(length-1)] = i2c_read_nack();
|
||||
data[(length-1)] = twi2c_read_nack();
|
||||
|
||||
i2c_stop();
|
||||
twi2c_stop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void i2c_stop(void)
|
||||
uint8_t twi2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length)
|
||||
{
|
||||
if (twi2c_start(devaddr | 0x00)) return 1;
|
||||
|
||||
twi2c_write(regaddr);
|
||||
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
if (twi2c_write(data[i])) return 1;
|
||||
}
|
||||
|
||||
twi2c_stop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t twi2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length)
|
||||
{
|
||||
if (twi2c_start(devaddr)) return 1;
|
||||
|
||||
twi2c_write(regaddr);
|
||||
|
||||
if (twi2c_start(devaddr | 0x01)) return 1;
|
||||
|
||||
for (uint16_t i = 0; i < (length-1); i++)
|
||||
{
|
||||
data[i] = twi2c_read_ack();
|
||||
}
|
||||
data[(length-1)] = twi2c_read_nack();
|
||||
|
||||
twi2c_stop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void twi2c_stop(void)
|
||||
{
|
||||
// transmit STOP condition
|
||||
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
|
22
drivers/avr/twi2c.h
Normal file
22
drivers/avr/twi2c.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/* Library made by: g4lvanix
|
||||
* Github repository: https://github.com/g4lvanix/I2C-master-lib
|
||||
*/
|
||||
|
||||
#ifndef TWI2C_H
|
||||
#define TWI2C_H
|
||||
|
||||
#define I2C_READ 0x01
|
||||
#define I2C_WRITE 0x00
|
||||
|
||||
void twi2c_init(void);
|
||||
uint8_t twi2c_start(uint8_t address);
|
||||
uint8_t twi2c_write(uint8_t data);
|
||||
uint8_t twi2c_read_ack(void);
|
||||
uint8_t twi2c_read_nack(void);
|
||||
uint8_t twi2c_transmit(uint8_t address, uint8_t* data, uint16_t length);
|
||||
uint8_t twi2c_receive(uint8_t address, uint8_t* data, uint16_t length);
|
||||
uint8_t twi2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length);
|
||||
uint8_t twi2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length);
|
||||
void twi2c_stop(void);
|
||||
|
||||
#endif // I2C_MASTER_H
|
244
drivers/is31fl3731.c
Normal file
244
drivers/is31fl3731.c
Normal file
@@ -0,0 +1,244 @@
|
||||
/* 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 "wait.h"
|
||||
#include <string.h>
|
||||
#include "twi2c.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'
|
||||
|
||||
// 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;
|
||||
|
||||
//Transmit data until succesful
|
||||
//while(twi2c_transmit(addr << 1, g_twi_transfer_buffer,2) != 0);
|
||||
twi2c_transmit(addr << 1, g_twi_transfer_buffer,2);
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
//Transmit buffer until succesful
|
||||
//while(twi2c_transmit(addr << 1, g_twi_transfer_buffer,17) != 0);
|
||||
twi2c_transmit(addr << 1, g_twi_transfer_buffer,17);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
wait_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] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
202
drivers/qwiic/qwiic_keyboard.c
Normal file
202
drivers/qwiic/qwiic_keyboard.c
Normal file
@@ -0,0 +1,202 @@
|
||||
/* 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 "qwiic_keyboard.h"
|
||||
#include "keymap.h"
|
||||
#include "matrix.h"
|
||||
#include "keyboard.h"
|
||||
#include "twi2c.h"
|
||||
#include <string.h>
|
||||
#include "usb_main.h"
|
||||
#include "usb_driver.h"
|
||||
|
||||
#define QWIIC_KEYBOARD_LAYERS 16
|
||||
#define QWIIC_KEYBOARD_ROWS 8
|
||||
#define QWIIC_KEYBOARD_COLS 8
|
||||
|
||||
#define qwiic_matrix_t uint8_t
|
||||
|
||||
#define QWIIC_KEYBOARD_HANDSHAKE_ADDRESS 0b01010100
|
||||
#define QWIIC_KEYBOARD_LISTENING_ADDRESS_START 0b01010110
|
||||
#define QWIIC_KEYBOARD_HANDSHAKE_MESSAGE_SIZE (QWIIC_KEYBOARD_LAYERS * QWIIC_KEYBOARD_ROWS * QWIIC_KEYBOARD_COLS)
|
||||
#define QWIIC_KEYBOARD_MATRIX_MESSAGE_SIZE MATRIX_ROWS
|
||||
|
||||
void qwiic_keyboard_write_keymap(uint8_t * pointer);
|
||||
void qwiic_keyboard_read_keymap(uint8_t * pointer);
|
||||
|
||||
bool qwiic_keyboard_master = false;
|
||||
bool qwiic_keyboard_connected = false;
|
||||
uint8_t qwiic_keyboard_handshake_message[QWIIC_KEYBOARD_HANDSHAKE_MESSAGE_SIZE] = {0};
|
||||
uint8_t qwiic_keyboard_matrix_message[QWIIC_KEYBOARD_ROWS] = {0};
|
||||
twi2c_message_received qwiic_keyboard_message_received_ptr = qwiic_keyboard_message_received;
|
||||
|
||||
uint16_t qwiic_keyboard_keymap[QWIIC_KEYBOARD_LAYERS][QWIIC_KEYBOARD_ROWS][QWIIC_KEYBOARD_COLS] = {0};
|
||||
uint8_t qwiic_keyboard_listening_address = QWIIC_KEYBOARD_LISTENING_ADDRESS_START;
|
||||
uint8_t qwiic_keyboard_processing_slave = false;
|
||||
|
||||
void qwiic_keyboard_init(void) {
|
||||
twi2c_init();
|
||||
twi2c_start();
|
||||
twi2c_start_listening(QWIIC_KEYBOARD_HANDSHAKE_ADDRESS, qwiic_keyboard_message_received_ptr);
|
||||
}
|
||||
|
||||
void qwiic_keyboard_set_master(void) {
|
||||
twi2c_stop();
|
||||
twi2c_start();
|
||||
qwiic_keyboard_master = true;
|
||||
}
|
||||
|
||||
uint8_t command[1] = { 0x00 };
|
||||
|
||||
void qwiic_keyboard_task(void) {
|
||||
if (USB_DRIVER.state == USB_ACTIVE)
|
||||
qwiic_keyboard_master = true;
|
||||
else
|
||||
qwiic_keyboard_master = false;
|
||||
if (qwiic_keyboard_master) {
|
||||
if (qwiic_keyboard_connected) {
|
||||
// send empty message, expecting matrix info
|
||||
if (MSG_OK == twi2c_transmit_receive(qwiic_keyboard_listening_address,
|
||||
command, 1,
|
||||
qwiic_keyboard_matrix_message, QWIIC_KEYBOARD_MATRIX_MESSAGE_SIZE
|
||||
)) {
|
||||
// majority of this is pulled from keyboard.c:keyboard_task()
|
||||
static qwiic_matrix_t matrix_prev[QWIIC_KEYBOARD_ROWS];
|
||||
qwiic_matrix_t matrix_row = 0;
|
||||
qwiic_matrix_t matrix_change = 0;
|
||||
#ifdef QMK_KEYS_PER_SCAN
|
||||
uint8_t keys_processed = 0;
|
||||
#endif
|
||||
qwiic_keyboard_processing_slave = true;
|
||||
for (uint8_t r = 0; r < QWIIC_KEYBOARD_ROWS; r++) {
|
||||
matrix_row = qwiic_keyboard_matrix_message[r];
|
||||
matrix_change = matrix_row ^ matrix_prev[r];
|
||||
if (matrix_change) {
|
||||
for (uint8_t c = 0; c < QWIIC_KEYBOARD_COLS; c++) {
|
||||
if (matrix_change & ((qwiic_matrix_t)1<<c)) {
|
||||
action_exec((keyevent_t){
|
||||
.key = (keypos_t){ .row = r, .col = c },
|
||||
.pressed = (matrix_row & ((qwiic_matrix_t)1<<c)),
|
||||
.time = (timer_read() | 1) /* time should not be 0 */
|
||||
});
|
||||
// record a processed key
|
||||
matrix_prev[r] ^= ((qwiic_matrix_t)1<<c);
|
||||
#ifdef QMK_KEYS_PER_SCAN
|
||||
// only jump out if we have processed "enough" keys.
|
||||
if (++keys_processed >= QMK_KEYS_PER_SCAN)
|
||||
#endif
|
||||
// process a key per task call
|
||||
goto QWIIC_MATRIX_LOOP_END;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// call with pseudo tick event when no real key event.
|
||||
#ifdef QMK_KEYS_PER_SCAN
|
||||
// we can get here with some keys processed now.
|
||||
if (!keys_processed)
|
||||
#endif
|
||||
action_exec(TICK);
|
||||
QWIIC_MATRIX_LOOP_END:
|
||||
qwiic_keyboard_processing_slave = false;
|
||||
} else {
|
||||
// disconnect
|
||||
// qwiic_keyboard_connected = false;
|
||||
}
|
||||
} else { // if not connected
|
||||
// send new address to listen on, expect back keymap
|
||||
if (MSG_OK == twi2c_transmit_receive(QWIIC_KEYBOARD_HANDSHAKE_ADDRESS,
|
||||
&qwiic_keyboard_listening_address, 1,
|
||||
qwiic_keyboard_handshake_message, QWIIC_KEYBOARD_HANDSHAKE_MESSAGE_SIZE
|
||||
)) {
|
||||
qwiic_keyboard_connected = true;
|
||||
// load keymap into memory
|
||||
qwiic_keyboard_read_keymap(qwiic_keyboard_handshake_message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float song_one_up[][2] = SONG(ONE_UP_SOUND);
|
||||
bool first_message = true;
|
||||
|
||||
void qwiic_keyboard_message_received(I2CDriver *i2cp, uint8_t * body, uint16_t size) {
|
||||
if (qwiic_keyboard_connected) {
|
||||
for (uint8_t row = 0; row < QWIIC_KEYBOARD_ROWS; row++) {
|
||||
if (row < MATRIX_ROWS) {
|
||||
qwiic_keyboard_matrix_message[row] = matrix_get_row(row);
|
||||
} else {
|
||||
qwiic_keyboard_matrix_message[row] = 0;
|
||||
}
|
||||
}
|
||||
twi2c_reply(i2cp, qwiic_keyboard_matrix_message, QWIIC_KEYBOARD_MATRIX_MESSAGE_SIZE);
|
||||
if (first_message) {
|
||||
PLAY_SONG(song_one_up);
|
||||
first_message = false;
|
||||
}
|
||||
} else {
|
||||
qwiic_keyboard_connected = true;
|
||||
qwiic_keyboard_master = false;
|
||||
qwiic_keyboard_listening_address = body[0];
|
||||
twi2c_restart_listening(qwiic_keyboard_listening_address);
|
||||
qwiic_keyboard_write_keymap(qwiic_keyboard_handshake_message);
|
||||
twi2c_reply(i2cp, qwiic_keyboard_handshake_message, QWIIC_KEYBOARD_HANDSHAKE_MESSAGE_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
// qwiic_keyboard_message_received_ptr = qwiic_keyboard_message_received;
|
||||
|
||||
__attribute__((optimize("O0")))
|
||||
void qwiic_keyboard_write_keymap(uint8_t * pointer) {
|
||||
for (uint8_t layer = 0; layer < QWIIC_KEYBOARD_LAYERS; layer++) {
|
||||
for (uint8_t row = 0; row < QWIIC_KEYBOARD_ROWS; row++) {
|
||||
for (uint8_t col = 0; col < QWIIC_KEYBOARD_COLS; col++) {
|
||||
uint16_t keycode = pgm_read_word(&keymaps[layer][row][col]);
|
||||
*pointer++ = (keycode >> 8);
|
||||
*pointer++ = (keycode & 0xFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void qwiic_keyboard_read_keymap(uint8_t * pointer) {
|
||||
for (uint8_t layer = 0; layer < QWIIC_KEYBOARD_LAYERS; layer++) {
|
||||
for (uint8_t row = 0; row < QWIIC_KEYBOARD_ROWS; row++) {
|
||||
for (uint8_t col = 0; col < QWIIC_KEYBOARD_COLS; col++) {
|
||||
uint16_t keycode = ((*pointer++) << 8);
|
||||
keycode |= (*pointer++);
|
||||
qwiic_keyboard_keymap[layer][row][col] = keycode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// overwrite the built-in function - slaves don't need to process keycodes
|
||||
bool is_keyboard_master(void) {
|
||||
return qwiic_keyboard_master;
|
||||
}
|
||||
|
||||
// overwrite the built-in function
|
||||
uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) {
|
||||
if (qwiic_keyboard_processing_slave) {
|
||||
// trick the built-in handling to accept our replacement keymap
|
||||
return qwiic_keyboard_keymap[(layer)][(key.row)][(key.col)];
|
||||
//return KC_A;
|
||||
} else {
|
||||
// Read entire word (16bits)
|
||||
return pgm_read_word(&keymaps[(layer)][(key.row)][(key.col)]);
|
||||
}
|
||||
}
|
26
drivers/qwiic/qwiic_keyboard.h
Normal file
26
drivers/qwiic/qwiic_keyboard.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef QWIIC_KEYBOARD_H
|
||||
#define QWIIC_KEYBOARD_H
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
void qwiic_keyboard_init(void);
|
||||
void qwiic_keyboard_task(void);
|
||||
void qwiic_keyboard_message_received(I2CDriver *i2cp, uint8_t * body, uint16_t size);
|
||||
|
||||
#endif
|
@@ -1,5 +1,5 @@
|
||||
#ifndef CA66_H
|
||||
#define CA66_H
|
||||
#ifndef KB_H
|
||||
#define KB_H
|
||||
|
||||
#include "quantum.h"
|
||||
|
@@ -25,8 +25,9 @@
|
||||
|
||||
/* number of backlight levels */
|
||||
|
||||
#define BACKLIGHT_PIN F0
|
||||
#ifdef BACKLIGHT_PIN
|
||||
#define BACKLIGHT_LEVELS 3
|
||||
#endif
|
||||
|
||||
/* Set 0 if debouncing isn't needed */
|
||||
#define DEBOUNCING_DELAY 5
|
@@ -3,13 +3,11 @@ CA66
|
||||
|
||||
Custom 65%
|
||||
|
||||
Keyboard Maintainer: QMK Community
|
||||
Hardware Supported: CA66
|
||||
Hardware Availability: [Play Keyboard](http://playkeyboard.qdm.com.tw/)
|
||||
|
||||
Keyboard Maintainer: QMK Community
|
||||
Hardware Supported: CA66
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
||||
make playkbtw/ca66:default
|
||||
make ca66:default
|
||||
|
||||
See [build environment setup](https://docs.qmk.fm/build_environment_setup.html) then the [make instructions](https://docs.qmk.fm/make_instructions.html) for more information.
|
@@ -51,6 +51,6 @@ CONSOLE_ENABLE ?= no # Console for debug(+400)
|
||||
COMMAND_ENABLE ?= no # Commands for debug and configuration
|
||||
SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
|
||||
NKRO_ENABLE ?= yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
|
||||
BACKLIGHT_ENABLE ?= yes # Enable keyboard backlight functionality
|
||||
BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality
|
||||
AUDIO_ENABLE ?= no
|
||||
RGBLIGHT_ENABLE ?= yes
|
@@ -42,55 +42,24 @@ void backlight_init_ports(void) {
|
||||
|
||||
#endif
|
||||
|
||||
// for keyboard subdirectory level init functions
|
||||
// @Override
|
||||
void matrix_init_kb(void) {
|
||||
// call user level keymaps, if any
|
||||
matrix_init_user();
|
||||
}
|
||||
|
||||
#ifdef RGBLIGHT_ENABLE
|
||||
extern rgblight_config_t rgblight_config;
|
||||
|
||||
// custom RGB driver
|
||||
void rgblight_set(void) {
|
||||
if (!rgblight_config.enable) {
|
||||
for (uint8_t i=0; i<RGBLED_NUM; i++) {
|
||||
led[i].r = 0;
|
||||
led[i].g = 0;
|
||||
led[i].b = 0;
|
||||
if (!rgblight_config.enable) {
|
||||
for (uint8_t i = 0; i < RGBLED_NUM; i++) {
|
||||
led[i].r = 0;
|
||||
led[i].g = 0;
|
||||
led[i].b = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i2c_init();
|
||||
i2c_send(0xb0, (uint8_t*)led, 3 * RGBLED_NUM);
|
||||
}
|
||||
|
||||
bool rgb_init = false;
|
||||
|
||||
void matrix_scan_kb(void) {
|
||||
// if LEDs were previously on before poweroff, turn them back on
|
||||
if (rgb_init == false && rgblight_config.enable) {
|
||||
i2c_init();
|
||||
i2c_send(0xb0, (uint8_t*)led, 3 * RGBLED_NUM);
|
||||
rgb_init = true;
|
||||
}
|
||||
|
||||
rgblight_task();
|
||||
#else
|
||||
void matrix_scan_kb(void) {
|
||||
#endif
|
||||
matrix_scan_user();
|
||||
/* Nothing else for now. */
|
||||
}
|
||||
|
||||
__attribute__((weak)) // overridable
|
||||
void matrix_init_user(void) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
__attribute__((weak)) // overridable
|
||||
__attribute__ ((weak))
|
||||
void matrix_scan_user(void) {
|
||||
|
||||
rgblight_task();
|
||||
}
|
||||
#endif
|
||||
|
@@ -1,62 +0,0 @@
|
||||
#include QMK_KEYBOARD_H
|
||||
#include "dhertz.h"
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
/* Layer 0: Default Layer
|
||||
* ,---------------------------------------------------------------.
|
||||
* |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| Backsp|Del|
|
||||
* |---------------------------------------------------------------|
|
||||
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]|Enter|Hom|
|
||||
* |------------------------------------------------------` |---|
|
||||
* |SrCtl | A| S| D| F| G| H| J| K| L| ;| '| \| |End|
|
||||
* |---------------------------------------------------------------|
|
||||
* |Shif| #| Z| X| C| V| B| N| M| ,| .| /|Shift |Up |PgD|
|
||||
* |---------------------------------------------------------------|
|
||||
* |NcCtl| Alt| CTab| LyrSpc | CGv| Alt|Lef|Dow|Rig|
|
||||
* `---------------------------------------------------------------'
|
||||
*/
|
||||
[0] = LAYOUT_iso(
|
||||
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_DEL,
|
||||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_HOME,
|
||||
SRCH_CTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NUHS, KC_ENT, KC_END,
|
||||
KC_LSFT, HSH_TLD, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_PGDN,
|
||||
NC_CTL, KC_LALT, CMD_TAB_CMD, LYR_SPC, CMD_GRV_CMD, KC_RALT, KC_LEFT, KC_DOWN, KC_RIGHT
|
||||
),
|
||||
/* Layer 1: Special
|
||||
* ,---------------------------------------------------------------.
|
||||
* | §| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12| |Iso|
|
||||
* |---------------------------------------------------------------|
|
||||
* | | | | | | | | | | | | | | | |
|
||||
* |------------------------------------------------------` |---|
|
||||
* | | | | | | | | | |CSL| | | `| | |
|
||||
* |---------------------------------------------------------------|
|
||||
* | | `| | |CAC| | | | | | | | |PgU| |
|
||||
* |---------------------------------------------------------------|
|
||||
* | | | | | | |Hom|PgD|End|
|
||||
* `---------------------------------------------------------------'
|
||||
*/
|
||||
[1] = LAYOUT_iso(
|
||||
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F10, KC_F11, KC_TRNS, ISO_COUNTRY_CODE,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, CMD_SFT_L, KC_TRNS, KC_TRNS, KC_NUBS, KC_TRNS, KC_TRNS,
|
||||
KC_TRNS, KC_NUBS, KC_TRNS, KC_TRNS, CMD_ALT_C, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PGUP, KC_TRNS,
|
||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, KC_PGDOWN, KC_END
|
||||
),
|
||||
};
|
||||
|
||||
void matrix_init_keymap(void) {
|
||||
rgblight_enable_noeeprom();
|
||||
rgblight_sethsv_teal();
|
||||
}
|
||||
|
||||
uint32_t layer_state_set_keymap(uint32_t state) {
|
||||
switch (biton32(state)) {
|
||||
case 1:
|
||||
rgblight_sethsv_noeeprom_magenta();
|
||||
break;
|
||||
default: // for any other layers, or the default layer
|
||||
rgblight_sethsv_noeeprom_cyan();
|
||||
break;
|
||||
}
|
||||
return state;
|
||||
}
|
@@ -21,7 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "matrix.h"
|
||||
|
||||
#ifndef DEBOUNCE
|
||||
# define DEBOUNCE 5
|
||||
#define DEBOUNCE 5
|
||||
#endif
|
||||
|
||||
static uint8_t debouncing = DEBOUNCE;
|
||||
@@ -29,9 +29,6 @@ static uint8_t debouncing = DEBOUNCE;
|
||||
static matrix_row_t matrix[MATRIX_ROWS];
|
||||
static matrix_row_t matrix_debouncing[MATRIX_ROWS];
|
||||
|
||||
void matrix_set_row_status(uint8_t row);
|
||||
uint8_t bit_reverse(uint8_t x);
|
||||
|
||||
void matrix_init(void) {
|
||||
// all outputs for rows high
|
||||
DDRB = 0xFF;
|
||||
@@ -50,8 +47,18 @@ void matrix_init(void) {
|
||||
matrix[row] = 0x00;
|
||||
matrix_debouncing[row] = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
matrix_init_quantum();
|
||||
void matrix_set_row_status(uint8_t row) {
|
||||
DDRB = (1 << row);
|
||||
PORTB = ~(1 << row);
|
||||
}
|
||||
|
||||
uint8_t bit_reverse(uint8_t x) {
|
||||
x = ((x >> 1) & 0x55) | ((x << 1) & 0xaa);
|
||||
x = ((x >> 2) & 0x33) | ((x << 2) & 0xcc);
|
||||
x = ((x >> 4) & 0x0f) | ((x << 4) & 0xf0);
|
||||
return x;
|
||||
}
|
||||
|
||||
uint8_t matrix_scan(void) {
|
||||
@@ -86,24 +93,11 @@ uint8_t matrix_scan(void) {
|
||||
}
|
||||
}
|
||||
|
||||
matrix_scan_quantum();
|
||||
matrix_scan_user();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// declarations
|
||||
void matrix_set_row_status(uint8_t row) {
|
||||
DDRB = (1 << row);
|
||||
PORTB = ~(1 << row);
|
||||
}
|
||||
|
||||
uint8_t bit_reverse(uint8_t x) {
|
||||
x = ((x >> 1) & 0x55) | ((x << 1) & 0xaa);
|
||||
x = ((x >> 2) & 0x33) | ((x << 2) & 0xcc);
|
||||
x = ((x >> 4) & 0x0f) | ((x << 4) & 0xf0);
|
||||
return x;
|
||||
}
|
||||
|
||||
inline matrix_row_t matrix_get_row(uint8_t row) {
|
||||
return matrix[row];
|
||||
}
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
#define LAYOUT_ortho_4x4( \
|
||||
#define KEYMAP( \
|
||||
A1, A2, A3, A4, \
|
||||
B1, B2, B3, B4, \
|
||||
C1, C2, C3, C4, \
|
||||
@@ -16,13 +16,13 @@
|
||||
}
|
||||
|
||||
// Used to create a keymap using only KC_ prefixed keys
|
||||
#define LAYOUT_kc( \
|
||||
#define KC_KEYMAP( \
|
||||
A1, A2, A3, A4, \
|
||||
B1, B2, B3, B4, \
|
||||
C1, C2, C3, C4, \
|
||||
D1, D2, D3, D4 \
|
||||
) \
|
||||
LAYOUT_ortho_4x4( \
|
||||
KEYMAP( \
|
||||
KC_##A1, KC_##A2, KC_##A3, KC_##A4, \
|
||||
KC_##B1, KC_##B2, KC_##B3, KC_##B4, \
|
||||
KC_##C1, KC_##C2, KC_##C3, KC_##C4, \
|
||||
|
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"keyboard_name": "Chocopad",
|
||||
"url": "",
|
||||
"maintainer": "qmk",
|
||||
"width": 4,
|
||||
"height": 4,
|
||||
"layouts": {
|
||||
"LAYOUT_ortho_4x4": {
|
||||
"layout": [{"x":0, "y":0}, {"x":1, "y":0}, {"x":2, "y":0}, {"x":3, "y":0}, {"x":0, "y":1}, {"x":1, "y":1}, {"x":2, "y":1}, {"x":3, "y":1}, {"x":0, "y":2}, {"x":1, "y":2}, {"x":2, "y":2}, {"x":3, "y":2}, {"x":0, "y":3}, {"x":1, "y":3}, {"x":2, "y":3}, {"x":3, "y":3}]
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,30 +1,61 @@
|
||||
#include QMK_KEYBOARD_H
|
||||
#include "chocopad.h"
|
||||
|
||||
#define _BASE 0
|
||||
#define _FN1 1
|
||||
#define _FN2 2
|
||||
|
||||
#define KC_ KC_TRNS
|
||||
#define _______ KC_TRNS
|
||||
|
||||
#define KC_X1 MO(_FN1)
|
||||
#define KC_X2 MO(_FN2)
|
||||
#define KC_RST RESET
|
||||
#define KC_BSTP BL_STEP
|
||||
#define KC_RTOG RGB_TOG
|
||||
#define KC_RMOD RGB_MOD
|
||||
#define KC_RHUI RGB_HUI
|
||||
#define KC_RHUD RGB_HUD
|
||||
#define KC_RSAI RGB_SAI
|
||||
#define KC_RSAD RGB_SAD
|
||||
#define KC_RVAI RGB_VAI
|
||||
#define KC_RVAD RGB_VAD
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
|
||||
[_BASE] = LAYOUT_ortho_4x4(
|
||||
KC_PGUP, KC_HOME, KC_UP, KC_END , \
|
||||
KC_PGDN, KC_LEFT, KC_DOWN, KC_RGHT, \
|
||||
MO(_FN2), KC_VOLU, KC_MPLY, KC_MPRV, \
|
||||
MO(_FN1), KC_VOLD, KC_MUTE, KC_MNXT \
|
||||
[_BASE] = KC_KEYMAP(
|
||||
//,----+----+----+----.
|
||||
PGUP,HOME, UP ,END ,
|
||||
//|----+----+----+----|
|
||||
PGDN,LEFT,DOWN,RGHT,
|
||||
//|----+----+----+----|
|
||||
X2 ,VOLU,MPLY,MPRV,
|
||||
//|----+----+----+----|
|
||||
X1 ,VOLD,MUTE,MNXT
|
||||
//`----+----+----+----'
|
||||
),
|
||||
[_FN1] = LAYOUT_ortho_4x4(
|
||||
KC_ESC, KC_P7, KC_P8, KC_P9, \
|
||||
KC_TAB, KC_P4, KC_P5, KC_P6, \
|
||||
KC_ENT, KC_P1, KC_P2, KC_P3, \
|
||||
_______, KC_P0, KC_P0, KC_DOT \
|
||||
|
||||
[_FN1] = KC_KEYMAP(
|
||||
//,----+----+----+----.
|
||||
ESC , P7 , P8 , P9 ,
|
||||
//|----+----+----+----|
|
||||
TAB , P4 , P5 , P6 ,
|
||||
//|----+----+----+----|
|
||||
ENT , P1 , P2 , P3 ,
|
||||
//|----+----+----+----|
|
||||
, P0 , P0 ,DOT
|
||||
//`----+----+----+----'
|
||||
),
|
||||
[_FN2] = LAYOUT_ortho_4x4(
|
||||
RGB_TOG, RGB_HUI, RGB_SAI, RGB_VAI, \
|
||||
RGB_MOD, RGB_HUD, RGB_SAD, RGB_VAD, \
|
||||
_______, _______, _______, RESET, \
|
||||
BL_STEP, _______, _______, _______ \
|
||||
|
||||
[_FN2] = KC_KEYMAP(
|
||||
//,----+----+----+----.
|
||||
RTOG,RHUI,RSAI,RVAI,
|
||||
//|----+----+----+----|
|
||||
RMOD,RHUD,RSAD,RVAD,
|
||||
//|----+----+----+----|
|
||||
, , ,RST ,
|
||||
//|----+----+----+----|
|
||||
BSTP, , ,
|
||||
//`----+----+----+----'
|
||||
)
|
||||
|
||||
};
|
||||
|
@@ -54,5 +54,3 @@ NKRO_ENABLE = yes # USB Nkey Rollover - if this doesn't work, see here: https:/
|
||||
BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
|
||||
AUDIO_ENABLE = no
|
||||
RGBLIGHT_ENABLE = yes
|
||||
|
||||
LAYOUTS = ortho_4x4
|
||||
|
@@ -3,7 +3,7 @@
|
||||
#include "quantum.h"
|
||||
|
||||
|
||||
#define LAYOUT( \
|
||||
#define KEYMAP( \
|
||||
k00, k01, k02, k03, k04, k05 \
|
||||
) \
|
||||
{ \
|
||||
|
@@ -1,14 +1,13 @@
|
||||
{
|
||||
"keyboard_name": "Christmas Tree",
|
||||
"keyboard_folder": "christmas_tree",
|
||||
"url": "https://www.reddit.com/r/MechanicalKeyboards/comments/7cqxpf/gb_christmas_tree_pcb_gb_now_live/",
|
||||
"maintainer": "That-Canadian",
|
||||
"width": 3,
|
||||
"height": 3,
|
||||
"layouts": {
|
||||
"2017": {
|
||||
"key_count": 6,
|
||||
"layout": [{"x":1, "y":0}, {"x":0.5, "y":1}, {"x":1.5, "y":1}, {"x":0, "y":2}, {"x":1, "y":2}, {"x":2, "y":2}]
|
||||
"keyboard_name": "Christmas Tree",
|
||||
"keyboard_folder": "christmas_tree",
|
||||
"url": "https://www.reddit.com/r/MechanicalKeyboards/comments/7cqxpf/gb_christmas_tree_pcb_gb_now_live/",
|
||||
"maintainer": "That-Canadian",
|
||||
"width": 3,
|
||||
"height": 3,
|
||||
"layouts": {
|
||||
"2017": {
|
||||
"key_count": 6
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -14,7 +14,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include QMK_KEYBOARD_H
|
||||
#include "christmas_tree.h"
|
||||
|
||||
extern keymap_config_t keymap_config;
|
||||
|
||||
@@ -32,35 +32,27 @@ enum custom_keycodes {
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
|
||||
/* Base
|
||||
* ,------.
|
||||
* | 1 |
|
||||
* ,------+------.
|
||||
* | 2 | 3 |
|
||||
* ,------+------+------.
|
||||
* | 4 | FUNC | 6 |
|
||||
* `--------------------'
|
||||
*/
|
||||
[_BASE] = LAYOUT(
|
||||
KC_1,
|
||||
KC_2, KC_3,
|
||||
KC_4, MO(_FUNC), KC_6
|
||||
),
|
||||
/* Base
|
||||
* ,------.
|
||||
* | 1 |
|
||||
* ,------+------.
|
||||
* | 2 | 3 |
|
||||
* ,------+------+------.
|
||||
* | 4 | FUNC | 6 |
|
||||
* `--------------------'
|
||||
*/
|
||||
[_BASE] = KEYMAP(KC_1, KC_2, KC_3, KC_4, MO(_FUNC), KC_6),
|
||||
|
||||
/* Func
|
||||
* ,------.
|
||||
* |BCKLIT|
|
||||
* ,------+------.
|
||||
* | 8 | 9 |
|
||||
* ,------+------+------.
|
||||
* | 0 | FUNC | RESET|
|
||||
* `--------------------'
|
||||
*/
|
||||
[_FUNC] = LAYOUT(
|
||||
BACKLIT,
|
||||
KC_8, KC_9,
|
||||
KC_0, _______, RESET
|
||||
)
|
||||
/* Func
|
||||
* ,------.
|
||||
* |BCKLIT|
|
||||
* ,------+------.
|
||||
* | 8 | 9 |
|
||||
* ,------+------+------.
|
||||
* | 0 | FUNC | RESET|
|
||||
* `--------------------'
|
||||
*/
|
||||
[_FUNC] = KEYMAP(BACKLIT, KC_8, KC_9, KC_0, _______, RESET)
|
||||
|
||||
|
||||
};
|
||||
|
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 Danny Nguyen <danny@hexwire.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#include "config_common.h"
|
||||
|
||||
#endif // CONFIG_H
|
@@ -1 +0,0 @@
|
||||
#include "fortitude60.h"
|
@@ -1,26 +0,0 @@
|
||||
#ifndef FORTITUDE60_H
|
||||
#define FORTITUDE60_H
|
||||
|
||||
#ifdef KEYBOARD_fortitude60_rev1
|
||||
#include "rev1.h"
|
||||
#endif
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
// Used to create a keymap using only KC_ prefixed keys
|
||||
#define LAYOUT_kc( \
|
||||
L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \
|
||||
L10, L11, L12, L13, L14, L15, R10, R11, R12, R13, R14, R15, \
|
||||
L20, L21, L22, L23, L24, L25, R20, R21, R22, R23, R24, R25, \
|
||||
L30, L31, L32, L33, L34, L35, LT5, RT5, R30, R31, R32, R33, R34, R35, \
|
||||
LT0, LT1, LT2, LT3, LT4, RT4, RT3, RT2, RT1, RT0 \
|
||||
) \
|
||||
LAYOUT( \
|
||||
KC_##L00, KC_##L01, KC_##L02, KC_##L03, KC_##L04, KC_##L05, KC_##R00, KC_##R01, KC_##R02, KC_##R03, KC_##R04, KC_##R05, \
|
||||
KC_##L10, KC_##L11, KC_##L12, KC_##L13, KC_##L14, KC_##L15, KC_##R10, KC_##R11, KC_##R12, KC_##R13, KC_##R14, KC_##R15, \
|
||||
KC_##L20, KC_##L21, KC_##L22, KC_##L23, KC_##L24, KC_##L25, KC_##R20, KC_##R21, KC_##R22, KC_##R23, KC_##R24, KC_##R25, \
|
||||
KC_##L30, KC_##L31, KC_##L32, KC_##L33, KC_##L34, KC_##L35, KC_##LT5, KC_##RT5, KC_##R30, KC_##R31, KC_##R32, KC_##R33, KC_##R34, KC_##R35, \
|
||||
KC_##LT0, KC_##LT1, KC_##LT2, KC_##LT3, KC_##LT4, KC_##RT4, KC_##RT3, KC_##RT2, KC_##RT1, KC_##RT0 \
|
||||
)
|
||||
|
||||
#endif
|
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 Danny Nguyen <danny@hexwire.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_USER_H
|
||||
#define CONFIG_USER_H
|
||||
|
||||
#include "config_common.h"
|
||||
|
||||
#define USE_SERIAL
|
||||
|
||||
/* Select hand configuration */
|
||||
|
||||
// #define MASTER_LEFT
|
||||
// #define MASTER_RIGHT
|
||||
#define EE_HANDS
|
||||
|
||||
#define USE_SERIAL_PD2
|
||||
/* #undef RGBLED_NUM */
|
||||
/* #define RGBLIGHT_ANIMATIONS */
|
||||
/* #define RGBLED_NUM 12 */
|
||||
/* #define RGBLIGHT_HUE_STEP 8 */
|
||||
/* #define RGBLIGHT_SAT_STEP 8 */
|
||||
/* #define RGBLIGHT_VAL_STEP 8 */
|
||||
|
||||
#endif
|
@@ -1,189 +0,0 @@
|
||||
#include QMK_KEYBOARD_H
|
||||
#include "eeconfig.h"
|
||||
|
||||
extern keymap_config_t keymap_config;
|
||||
|
||||
// Each layer gets a name for readability, which is then used in the keymap matrix below.
|
||||
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
|
||||
// Layer names don't all need to be of the same length, obviously, and you can also skip them
|
||||
// entirely and just use numbers.
|
||||
#define _QWERTY 0
|
||||
#define _COLEMAK 1
|
||||
#define _DVORAK 2
|
||||
#define _LOWER 3
|
||||
#define _RAISE 4
|
||||
#define _ADJUST 16
|
||||
|
||||
enum custom_keycodes {
|
||||
QWERTY = SAFE_RANGE,
|
||||
COLEMAK,
|
||||
DVORAK,
|
||||
LOWER,
|
||||
RAISE,
|
||||
ADJUST,
|
||||
};
|
||||
|
||||
// Fillers to make layering more clear
|
||||
#define _______ KC_TRNS
|
||||
#define XXXXXXX KC_NO
|
||||
#define LOWER MO(_LOWER)
|
||||
#define RAISE MO(_RAISE)
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
|
||||
/* Qwerty
|
||||
* ,-----------------------------------------. ,-----------------------------------------.
|
||||
* | ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Del |
|
||||
* |------+------+------+------+------+------| |------+------+------+------+------+------|
|
||||
* | Tab | Q | W | E | R | T | | Y | U | I | O | P | Bksp |
|
||||
* |------+------+------+------+------+------| |------+------+------+------+------+------|
|
||||
* | Esc | A | S | D | F | G | | H | J | K | L | ; | " |
|
||||
* |------+------+------+------+------+------+-------------+------+------+------+------+------+------|
|
||||
* | Shift| Z | X | C | V | B | [ | ] | N | M | , | . | / |Enter |
|
||||
* `-------------+------+------+------+------+------+------+------+------+------+------+-------------'
|
||||
* | GUI | Ctrl |Lower |Space | Ctrl |Enter |Space |Raise | Alt | GUI |
|
||||
* `---------------------------------------------------------------------'
|
||||
*/
|
||||
[_QWERTY] = LAYOUT( \
|
||||
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL, \
|
||||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, \
|
||||
KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, \
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_LBRC, KC_RBRC, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT , \
|
||||
KC_LGUI, KC_LALT, LOWER, KC_SPC, KC_LCTL, KC_ENT, KC_SPC, RAISE, KC_RALT, KC_RGUI\
|
||||
),
|
||||
|
||||
/* Colemak
|
||||
* ,-----------------------------------------. ,-----------------------------------------.
|
||||
* | ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Del |
|
||||
* |------+------+------+------+------+------| |------+------+------+------+------+------|
|
||||
* | Tab | Q | W | F | P | G | | J | L | U | Y | ; | Bksp |
|
||||
* |------+------+------+------+------+------| |------+------+------+------+------+------|
|
||||
* | Esc | A | R | S | T | D | | H | N | E | I | O | " |
|
||||
* |------+------+------+------+------+------+-------------+------+------+------+------+------+------|
|
||||
* | Shift| Z | X | C | V | B | [ | ] | K | M | , | . | / |Enter |
|
||||
* `-------------+------+------+------+------+------+------+------+------+------+------+-------------'
|
||||
* | GUI | Ctrl |Lower |Space | Ctrl |Enter |Space |Raise | Alt | GUI |
|
||||
* `---------------------------------------------------------------------'
|
||||
*/
|
||||
[_COLEMAK] = LAYOUT( \
|
||||
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL, \
|
||||
KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC, \
|
||||
KC_ESC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT, \
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_LBRC, KC_RBRC, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT , \
|
||||
KC_LGUI, KC_LALT, LOWER, KC_SPC, KC_LCTL, KC_ENT, KC_SPC, RAISE, KC_RALT, KC_RGUI\
|
||||
),
|
||||
|
||||
/* Dvorak
|
||||
* ,-----------------------------------------. ,-----------------------------------------.
|
||||
* | ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Del |
|
||||
* |------+------+------+------+------+------| |------+------+------+------+------+------|
|
||||
* | Tab | " | , | . | P | Y | | F | G | C | R | L | Bksp |
|
||||
* |------+------+------+------+------+------| |------+------+------+------+------+------|
|
||||
* | Esc | A | O | E | U | I | | D | H | T | N | S | / |
|
||||
* |------+------+------+------+------+------+-------------+------+------+------+------+------+------|
|
||||
* | Shift| ; | Q | J | K | X | [ | ] | B | M | W | V | Z |Enter |
|
||||
* `-------------+------+------+------+------+------+------+------+------+------+------+-------------'
|
||||
* | GUI | Ctrl |Lower |Space | Ctrl |Enter |Space |Raise | Alt | GUI |
|
||||
* `---------------------------------------------------------------------'
|
||||
*/
|
||||
[_DVORAK] = LAYOUT( \
|
||||
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL, \
|
||||
KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC, \
|
||||
KC_ESC, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_SLSH, \
|
||||
KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_LBRC, KC_RBRC, KC_B, KC_M, KC_W, KC_V, KC_Z, KC_ENT , \
|
||||
KC_LGUI, KC_LALT, LOWER, KC_SPC, KC_LCTL, KC_ENT, KC_SPC, RAISE, KC_RALT, KC_RGUI\
|
||||
),
|
||||
|
||||
/* Lower
|
||||
* ,-----------------------------------------. ,-----------------------------------------.
|
||||
* | ~ | ! | @ | # | $ | % | | ^ | & | * | ( | ) | |
|
||||
* |------+------+------+------+------+------| |------+------+------+------+------+------|
|
||||
* | ~ | ! | @ | # | $ | % | | ^ | & | * | ( | ) | Del |
|
||||
* |------+------+------+------+------+------| |------+------+------+------+------+------|
|
||||
* | Del | F1 | F2 | F3 | F4 | F5 | | F6 | _ | + | | \ | | |
|
||||
* |------+------+------+------+------+------+-------------+------+------+------+------+------+------|
|
||||
* | | F7 | F8 | F9 | F10 | F11 | | | F12 |ISO ~ |ISO | | | | |
|
||||
* `-------------+------+------+------+------+------+------+------+------+------+------+-------------'
|
||||
* | | | | | | | | | | |
|
||||
* `---------------------------------------------------------------------'
|
||||
*/
|
||||
[_LOWER] = LAYOUT( \
|
||||
KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, _______, \
|
||||
KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_DEL, \
|
||||
KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, \
|
||||
_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, _______, _______, KC_F12,S(KC_NUHS),S(KC_NUBS),_______, _______, _______,\
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______\
|
||||
),
|
||||
|
||||
/* Raise
|
||||
* ,-----------------------------------------. ,-----------------------------------------.
|
||||
* | ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Del |
|
||||
* |------+------+------+------+------+------. ,------+------+------+------+------+------|
|
||||
* | ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Bksp |
|
||||
* |------+------+------+------+------+------. ,------+------+------+------+------+------|
|
||||
* | Del | F1 | F2 | F3 | F4 | F5 | | F6 | - | = | [ | ] | | |
|
||||
* |------+------+------+------+------+------+-------------+------+------+------+------+------+------|
|
||||
* | | F7 | F8 | F9 | F10 | F11 | | | F12 |ISO # |ISO / | | | |
|
||||
* `-------------+------+------+------+------+------+------+------+------+------+------+-------------'
|
||||
* | | | | | | | | | | |
|
||||
* `---------------------------------------------------------------------'
|
||||
*/
|
||||
[_RAISE] = LAYOUT( \
|
||||
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL, \
|
||||
KC_GRV, KC_1, KC_UP, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, \
|
||||
KC_DEL, KC_LEFT, KC_DOWN, KC_RGHT, KC_F4, KC_F5, KC_F6,KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, \
|
||||
_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, _______, _______, KC_F12, KC_NUHS, KC_NUBS, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______\
|
||||
),
|
||||
|
||||
/* Adjust (Lower + Raise)
|
||||
* ,-----------------------------------------. ,-----------------------------------------.
|
||||
* | F1 | F2 | F3 | F4 | F5 | F6 | | F7 | F8 | F9 | F10 | F11 | F12 |
|
||||
* |------+------+------+------+------+------. ,------+------+------+------+------+------|
|
||||
* | | Reset|RGB Tg|RGB Md|Hue Up|Hue Dn| |Sat Up|Sat Dn|Val Up|Val Dn| | Bksp |
|
||||
* |------+------+------+------+------+------. ,------+------+------+------+------+------|
|
||||
* | | | |Aud on|Audoff|AGnorm| |AGswap| |BL TOG|BL STP| | |
|
||||
* |------+------+------+------+------+------+-------------+------+------+------+------+------+------|
|
||||
* |Qwerty|Colemk|Dvorak| | | | | | | | | | | |
|
||||
* `-------------+------+------+------+------+------+------+------+------+------+------+-------------'
|
||||
* | | | | | | | | | | |
|
||||
* `---------------------------------------------------------------------'
|
||||
*/
|
||||
[_ADJUST] = LAYOUT( \
|
||||
KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, \
|
||||
_______, RESET , RGB_TOG, RGB_MOD, RGB_HUD, RGB_HUI, RGB_SAD, RGB_SAI, RGB_VAD, RGB_VAI, _______, KC_BSPC, \
|
||||
_______, _______, _______, AU_ON, AU_OFF, AG_NORM, AG_SWAP, _______, BL_TOGG, BL_STEP, _______, _______, \
|
||||
QWERTY, COLEMAK, DVORAK, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______\
|
||||
)
|
||||
|
||||
|
||||
};
|
||||
|
||||
uint32_t layer_state_set_user(uint32_t state) {
|
||||
return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
|
||||
}
|
||||
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
switch (keycode) {
|
||||
case QWERTY:
|
||||
if (record->event.pressed) {
|
||||
set_single_persistent_default_layer(_QWERTY);
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case COLEMAK:
|
||||
if (record->event.pressed) {
|
||||
set_single_persistent_default_layer(_COLEMAK);
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case DVORAK:
|
||||
if (record->event.pressed) {
|
||||
set_single_persistent_default_layer(_DVORAK);
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
@@ -1 +0,0 @@
|
||||
RGBLIGHT_ENABLE = no
|
@@ -1,423 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 Danny Nguyen <danny@keeb.io>
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* scan matrix
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <avr/io.h>
|
||||
#include "wait.h"
|
||||
#include "print.h"
|
||||
#include "debug.h"
|
||||
#include "util.h"
|
||||
#include "matrix.h"
|
||||
#include "split_util.h"
|
||||
#include "pro_micro.h"
|
||||
#include "config.h"
|
||||
#include "timer.h"
|
||||
|
||||
#ifdef BACKLIGHT_ENABLE
|
||||
#include "backlight.h"
|
||||
extern backlight_config_t backlight_config;
|
||||
#endif
|
||||
|
||||
#include "serial.h"
|
||||
|
||||
#ifndef DEBOUNCING_DELAY
|
||||
# define DEBOUNCING_DELAY 5
|
||||
#endif
|
||||
|
||||
#if (DEBOUNCING_DELAY > 0)
|
||||
static uint16_t debouncing_time;
|
||||
static bool debouncing = false;
|
||||
#endif
|
||||
|
||||
#if (MATRIX_COLS <= 8)
|
||||
# define print_matrix_header() print("\nr/c 01234567\n")
|
||||
# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
|
||||
# define matrix_bitpop(i) bitpop(matrix[i])
|
||||
# define ROW_SHIFTER ((uint8_t)1)
|
||||
#else
|
||||
# error "Currently only supports 8 COLS"
|
||||
#endif
|
||||
static matrix_row_t matrix_debouncing[MATRIX_ROWS];
|
||||
|
||||
#define ERROR_DISCONNECT_COUNT 5
|
||||
|
||||
#define SERIAL_LED_ADDR 0x00
|
||||
|
||||
#define ROWS_PER_HAND (MATRIX_ROWS/2)
|
||||
|
||||
static uint8_t error_count = 0;
|
||||
|
||||
static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
|
||||
static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
|
||||
|
||||
/* matrix state(1:on, 0:off) */
|
||||
static matrix_row_t matrix[MATRIX_ROWS];
|
||||
static matrix_row_t matrix_debouncing[MATRIX_ROWS];
|
||||
|
||||
#if (DIODE_DIRECTION == COL2ROW)
|
||||
static void init_cols(void);
|
||||
static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row);
|
||||
static void unselect_rows(void);
|
||||
static void select_row(uint8_t row);
|
||||
static void unselect_row(uint8_t row);
|
||||
#elif (DIODE_DIRECTION == ROW2COL)
|
||||
static void init_rows(void);
|
||||
static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col);
|
||||
static void unselect_cols(void);
|
||||
static void unselect_col(uint8_t col);
|
||||
static void select_col(uint8_t col);
|
||||
#endif
|
||||
|
||||
|
||||
__attribute__ ((weak))
|
||||
void matrix_init_kb(void) {
|
||||
matrix_init_user();
|
||||
}
|
||||
|
||||
__attribute__ ((weak))
|
||||
void matrix_scan_kb(void) {
|
||||
matrix_scan_user();
|
||||
}
|
||||
|
||||
__attribute__ ((weak))
|
||||
void matrix_init_user(void) {
|
||||
}
|
||||
|
||||
__attribute__ ((weak))
|
||||
void matrix_scan_user(void) {
|
||||
}
|
||||
|
||||
inline
|
||||
uint8_t matrix_rows(void)
|
||||
{
|
||||
return MATRIX_ROWS;
|
||||
}
|
||||
|
||||
inline
|
||||
uint8_t matrix_cols(void)
|
||||
{
|
||||
return MATRIX_COLS;
|
||||
}
|
||||
|
||||
void matrix_init(void)
|
||||
{
|
||||
debug_enable = true;
|
||||
debug_matrix = true;
|
||||
debug_mouse = true;
|
||||
// initialize row and col
|
||||
unselect_rows();
|
||||
init_cols();
|
||||
|
||||
TX_RX_LED_INIT;
|
||||
|
||||
// initialize matrix state: all keys off
|
||||
for (uint8_t i=0; i < MATRIX_ROWS; i++) {
|
||||
matrix[i] = 0;
|
||||
matrix_debouncing[i] = 0;
|
||||
}
|
||||
|
||||
matrix_init_quantum();
|
||||
|
||||
}
|
||||
|
||||
uint8_t _matrix_scan(void)
|
||||
{
|
||||
int offset = isLeftHand ? 0 : (ROWS_PER_HAND);
|
||||
#if (DIODE_DIRECTION == COL2ROW)
|
||||
// Set row, read cols
|
||||
for (uint8_t current_row = 0; current_row < ROWS_PER_HAND; current_row++) {
|
||||
# if (DEBOUNCING_DELAY > 0)
|
||||
bool matrix_changed = read_cols_on_row(matrix_debouncing+offset, current_row);
|
||||
|
||||
if (matrix_changed) {
|
||||
debouncing = true;
|
||||
debouncing_time = timer_read();
|
||||
}
|
||||
|
||||
# else
|
||||
read_cols_on_row(matrix+offset, current_row);
|
||||
# endif
|
||||
|
||||
}
|
||||
|
||||
#elif (DIODE_DIRECTION == ROW2COL)
|
||||
// Set col, read rows
|
||||
for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
|
||||
# if (DEBOUNCING_DELAY > 0)
|
||||
bool matrix_changed = read_rows_on_col(matrix_debouncing+offset, current_col);
|
||||
if (matrix_changed) {
|
||||
debouncing = true;
|
||||
debouncing_time = timer_read();
|
||||
}
|
||||
# else
|
||||
read_rows_on_col(matrix+offset, current_col);
|
||||
# endif
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
# if (DEBOUNCING_DELAY > 0)
|
||||
if (debouncing && (timer_elapsed(debouncing_time) > DEBOUNCING_DELAY)) {
|
||||
for (uint8_t i = 0; i < ROWS_PER_HAND; i++) {
|
||||
matrix[i+offset] = matrix_debouncing[i+offset];
|
||||
}
|
||||
debouncing = false;
|
||||
}
|
||||
# endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int serial_transaction(void) {
|
||||
int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;
|
||||
|
||||
if (serial_update_buffers()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ROWS_PER_HAND; ++i) {
|
||||
matrix[slaveOffset+i] = serial_slave_buffer[i];
|
||||
}
|
||||
|
||||
#ifdef BACKLIGHT_ENABLE
|
||||
// Write backlight level for slave to read
|
||||
serial_master_buffer[SERIAL_LED_ADDR] = backlight_config.enable ? backlight_config.level : 0;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint8_t matrix_scan(void)
|
||||
{
|
||||
uint8_t ret = _matrix_scan();
|
||||
|
||||
if( serial_transaction() ) {
|
||||
// turn on the indicator led when halves are disconnected
|
||||
TXLED1;
|
||||
|
||||
error_count++;
|
||||
|
||||
if (error_count > ERROR_DISCONNECT_COUNT) {
|
||||
// reset other half if disconnected
|
||||
int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;
|
||||
for (int i = 0; i < ROWS_PER_HAND; ++i) {
|
||||
matrix[slaveOffset+i] = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// turn off the indicator led on no error
|
||||
TXLED0;
|
||||
error_count = 0;
|
||||
}
|
||||
matrix_scan_quantum();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void matrix_slave_scan(void) {
|
||||
_matrix_scan();
|
||||
|
||||
int offset = (isLeftHand) ? 0 : ROWS_PER_HAND;
|
||||
|
||||
for (int i = 0; i < ROWS_PER_HAND; ++i) {
|
||||
serial_slave_buffer[i] = matrix[offset+i];
|
||||
}
|
||||
|
||||
#ifdef BACKLIGHT_ENABLE
|
||||
// Read backlight level sent from master and update level on slave
|
||||
backlight_set(serial_master_buffer[SERIAL_LED_ADDR]);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool matrix_is_modified(void)
|
||||
{
|
||||
if (debouncing) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline
|
||||
bool matrix_is_on(uint8_t row, uint8_t col)
|
||||
{
|
||||
return (matrix[row] & ((matrix_row_t)1<<col));
|
||||
}
|
||||
|
||||
inline
|
||||
matrix_row_t matrix_get_row(uint8_t row)
|
||||
{
|
||||
return matrix[row];
|
||||
}
|
||||
|
||||
void matrix_print(void)
|
||||
{
|
||||
print("\nr/c 0123456789ABCDEF\n");
|
||||
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
|
||||
phex(row); print(": ");
|
||||
pbin_reverse16(matrix_get_row(row));
|
||||
print("\n");
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t matrix_key_count(void)
|
||||
{
|
||||
uint8_t count = 0;
|
||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||
count += bitpop16(matrix[i]);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
#if (DIODE_DIRECTION == COL2ROW)
|
||||
|
||||
static void init_cols(void)
|
||||
{
|
||||
for(uint8_t x = 0; x < MATRIX_COLS; x++) {
|
||||
uint8_t pin = col_pins[x];
|
||||
_SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
|
||||
_SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
|
||||
}
|
||||
}
|
||||
|
||||
static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
|
||||
{
|
||||
// Store last value of row prior to reading
|
||||
matrix_row_t last_row_value = current_matrix[current_row];
|
||||
|
||||
// Clear data in matrix row
|
||||
current_matrix[current_row] = 0;
|
||||
|
||||
// Select row and wait for row selecton to stabilize
|
||||
select_row(current_row);
|
||||
wait_us(30);
|
||||
|
||||
// For each col...
|
||||
for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
|
||||
|
||||
// Select the col pin to read (active low)
|
||||
uint8_t pin = col_pins[col_index];
|
||||
uint8_t pin_state = (_SFR_IO8(pin >> 4) & _BV(pin & 0xF));
|
||||
|
||||
// Populate the matrix row with the state of the col pin
|
||||
current_matrix[current_row] |= pin_state ? 0 : (ROW_SHIFTER << col_index);
|
||||
}
|
||||
|
||||
// Unselect row
|
||||
unselect_row(current_row);
|
||||
|
||||
return (last_row_value != current_matrix[current_row]);
|
||||
}
|
||||
|
||||
static void select_row(uint8_t row)
|
||||
{
|
||||
uint8_t pin = row_pins[row];
|
||||
_SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT
|
||||
_SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW
|
||||
}
|
||||
|
||||
static void unselect_row(uint8_t row)
|
||||
{
|
||||
uint8_t pin = row_pins[row];
|
||||
_SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
|
||||
_SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
|
||||
}
|
||||
|
||||
static void unselect_rows(void)
|
||||
{
|
||||
for(uint8_t x = 0; x < ROWS_PER_HAND; x++) {
|
||||
uint8_t pin = row_pins[x];
|
||||
_SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
|
||||
_SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
|
||||
}
|
||||
}
|
||||
|
||||
#elif (DIODE_DIRECTION == ROW2COL)
|
||||
|
||||
static void init_rows(void)
|
||||
{
|
||||
for(uint8_t x = 0; x < ROWS_PER_HAND; x++) {
|
||||
uint8_t pin = row_pins[x];
|
||||
_SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
|
||||
_SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
|
||||
}
|
||||
}
|
||||
|
||||
static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
|
||||
{
|
||||
bool matrix_changed = false;
|
||||
|
||||
// Select col and wait for col selecton to stabilize
|
||||
select_col(current_col);
|
||||
wait_us(30);
|
||||
|
||||
// For each row...
|
||||
for(uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++)
|
||||
{
|
||||
|
||||
// Store last value of row prior to reading
|
||||
matrix_row_t last_row_value = current_matrix[row_index];
|
||||
|
||||
// Check row pin state
|
||||
if ((_SFR_IO8(row_pins[row_index] >> 4) & _BV(row_pins[row_index] & 0xF)) == 0)
|
||||
{
|
||||
// Pin LO, set col bit
|
||||
current_matrix[row_index] |= (ROW_SHIFTER << current_col);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pin HI, clear col bit
|
||||
current_matrix[row_index] &= ~(ROW_SHIFTER << current_col);
|
||||
}
|
||||
|
||||
// Determine if the matrix changed state
|
||||
if ((last_row_value != current_matrix[row_index]) && !(matrix_changed))
|
||||
{
|
||||
matrix_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Unselect col
|
||||
unselect_col(current_col);
|
||||
|
||||
return matrix_changed;
|
||||
}
|
||||
|
||||
static void select_col(uint8_t col)
|
||||
{
|
||||
uint8_t pin = col_pins[col];
|
||||
_SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT
|
||||
_SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW
|
||||
}
|
||||
|
||||
static void unselect_col(uint8_t col)
|
||||
{
|
||||
uint8_t pin = col_pins[col];
|
||||
_SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
|
||||
_SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
|
||||
}
|
||||
|
||||
static void unselect_cols(void)
|
||||
{
|
||||
for(uint8_t x = 0; x < MATRIX_COLS; x++) {
|
||||
uint8_t pin = col_pins[x];
|
||||
_SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
|
||||
_SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,15 +0,0 @@
|
||||
# Fortitude60
|
||||
|
||||

|
||||
|
||||
👊A 60% (12x5) split keyboard with staggerd column layout.👊
|
||||
|
||||
Keyboard Maintainer: [Pekaso](https://github.com/Pekaso) [@Pekaso](https://twitter.com/Pekaso)
|
||||
Hardware Supported: Fortitude60 PCB, Beetle 32u4
|
||||
Hardware Availability: [plustk2s.com](http://plustk2s.com)
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
||||
make fortitude60/rev1:default:avrdude
|
||||
|
||||
See [build environment setup](https://docs.qmk.fm/build_environment_setup.html) then the [make instructions](https://docs.qmk.fm/make_instructions.html) for more information.
|
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 Danny Nguyen <danny@keeb.io>
|
||||
|
||||
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 REV1_CONFIG_H
|
||||
#define REV1_CONFIG_H
|
||||
|
||||
#include QMK_KEYBOARD_CONFIG_H
|
||||
|
||||
/* USB Device descriptor parameter */
|
||||
#define VENDOR_ID 0xCB10
|
||||
#define PRODUCT_ID 0x1156
|
||||
#define DEVICE_VER 0x0100
|
||||
#define MANUFACTURER Pekaso
|
||||
#define PRODUCT The Fortitude60 Keyboard
|
||||
#define DESCRIPTION Split 60 keyboard.
|
||||
|
||||
/* key matrix size */
|
||||
// Rows are doubled-up
|
||||
#define MATRIX_ROWS 10
|
||||
#define MATRIX_COLS 6
|
||||
|
||||
// wiring of each half
|
||||
#define MATRIX_ROW_PINS { D1, D0, D3, B7, B6 }
|
||||
#define MATRIX_COL_PINS { F7, F6, F5, B3, B2, B1 }
|
||||
|
||||
/* COL2ROW or ROW2COL */
|
||||
#define DIODE_DIRECTION COL2ROW
|
||||
|
||||
/* define if matrix has ghost */
|
||||
//#define MATRIX_HAS_GHOST
|
||||
|
||||
/* number of backlight levels */
|
||||
#ifdef BACKLIGHT_ENABLE
|
||||
#define BACKLIGHT_PIN B5
|
||||
#define BACKLIGHT_LEVELS 9
|
||||
// #define BACKLIGHT_BREATHING
|
||||
#endif
|
||||
|
||||
/* Set 0 if debouncing isn't needed */
|
||||
#define DEBOUNCING_DELAY 5
|
||||
|
||||
/* 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
|
||||
|
||||
/* key combination for command */
|
||||
#define IS_COMMAND() ( \
|
||||
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
|
||||
)
|
||||
|
||||
/* ws2812 RGB LED */
|
||||
/* #define RGB_DI_PIN D3 */
|
||||
/* #define RGBLIGHT_TIMER */
|
||||
/* #define RGBLED_NUM 16 // Number of LEDs */
|
||||
/* #define ws2812_PORTREG PORTD */
|
||||
/* #define ws2812_DDRREG DDRD */
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
#endif
|
@@ -1,22 +0,0 @@
|
||||
#include "rev1.h"
|
||||
|
||||
#ifdef SSD1306OLED
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
void matrix_init_kb(void) {
|
||||
|
||||
// // green led on
|
||||
// DDRD |= (1<<5);
|
||||
// PORTD &= ~(1<<5);
|
||||
|
||||
// // orange led on
|
||||
// DDRB |= (1<<0);
|
||||
// PORTB &= ~(1<<0);
|
||||
|
||||
matrix_init_user();
|
||||
};
|
||||
|
@@ -1,44 +0,0 @@
|
||||
#ifndef REV1_H
|
||||
#define REV1_H
|
||||
|
||||
#include "fortitude60.h"
|
||||
|
||||
//void promicro_bootloader_jmp(bool program);
|
||||
#include "quantum.h"
|
||||
|
||||
|
||||
#ifdef USE_I2C
|
||||
#include <stddef.h>
|
||||
#ifdef __AVR__
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//void promicro_bootloader_jmp(bool program);
|
||||
|
||||
// Standard Keymap
|
||||
// (TRRS jack on the left half is to the right, TRRS jack on the right half is to the left)
|
||||
#define LAYOUT( \
|
||||
L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \
|
||||
L10, L11, L12, L13, L14, L15, R10, R11, R12, R13, R14, R15, \
|
||||
L20, L21, L22, L23, L24, L25, R20, R21, R22, R23, R24, R25, \
|
||||
L30, L31, L32, L33, L34, L35, LT5, RT5, R30, R31, R32, R33, R34, R35, \
|
||||
LT0, LT1, LT2, LT3, LT4, RT4, RT3, RT2, RT1, RT0 \
|
||||
) \
|
||||
{ \
|
||||
{ L00, L01, L02, L03, L04, L05 }, \
|
||||
{ L10, L11, L12, L13, L14, L15 }, \
|
||||
{ L20, L21, L22, L23, L24, L25 }, \
|
||||
{ L30, L31, L32, L33, L34, L35 }, \
|
||||
{ LT0, LT1, LT2, LT3, LT4, LT5 }, \
|
||||
{ R05, R04, R03, R02, R01, R00 }, \
|
||||
{ R15, R14, R13, R12, R11, R10 }, \
|
||||
{ R25, R24, R23, R22, R21, R20 }, \
|
||||
{ R35, R34, R33, R32, R31, R30 }, \
|
||||
{ RT0, RT1, RT2, RT3, RT4, RT5 } \
|
||||
}
|
||||
|
||||
#define LAYOUT_ortho_5x12 LAYOUT
|
||||
|
||||
#endif
|
@@ -1 +0,0 @@
|
||||
BACKLIGHT_ENABLE = yes
|
@@ -1,72 +0,0 @@
|
||||
SRC += matrix.c \
|
||||
split_util.c \
|
||||
serial.c
|
||||
|
||||
# MCU name
|
||||
#MCU = at90usb1287
|
||||
MCU = atmega32u4
|
||||
|
||||
# Processor frequency.
|
||||
# This will define a symbol, F_CPU, in all source code files equal to the
|
||||
# processor frequency in Hz. You can then use this symbol in your source code to
|
||||
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
|
||||
# automatically to create a 32-bit value in your source code.
|
||||
#
|
||||
# This will be an integer division of F_USB below, as it is sourced by
|
||||
# F_USB after it has run through any CPU prescalers. Note that this value
|
||||
# does not *change* the processor frequency - it should merely be updated to
|
||||
# reflect the processor speed set externally so that the code can use accurate
|
||||
# software delays.
|
||||
F_CPU = 16000000
|
||||
|
||||
#
|
||||
# LUFA specific
|
||||
#
|
||||
# Target architecture (see library "Board Types" documentation).
|
||||
ARCH = AVR8
|
||||
|
||||
# Input clock frequency.
|
||||
# This will define a symbol, F_USB, in all source code files equal to the
|
||||
# input clock frequency (before any prescaling is performed) in Hz. This value may
|
||||
# differ from F_CPU if prescaling is used on the latter, and is required as the
|
||||
# raw input clock is fed directly to the PLL sections of the AVR for high speed
|
||||
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
|
||||
# at the end, this will be done automatically to create a 32-bit value in your
|
||||
# source code.
|
||||
#
|
||||
# If no clock division is performed on the input clock inside the AVR (via the
|
||||
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
|
||||
F_USB = $(F_CPU)
|
||||
|
||||
# Bootloader
|
||||
# This definition is optional, and if your keyboard supports multiple bootloaders of
|
||||
# different sizes, comment this out, and the correct address will be loaded
|
||||
# automatically (+60). See bootloader.mk for all options.
|
||||
BOOTLOADER = caterina
|
||||
|
||||
# Interrupt driven control endpoint task(+60)
|
||||
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
|
||||
|
||||
# Build Options
|
||||
# change to "no" to disable the options, or define them in the Makefile in
|
||||
# the appropriate keymap folder that will get included automatically
|
||||
#
|
||||
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
|
||||
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
|
||||
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
|
||||
CONSOLE_ENABLE = no # Console for debug(+400)
|
||||
COMMAND_ENABLE = yes # Commands for debug and configuration
|
||||
NKRO_ENABLE = no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
|
||||
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
|
||||
MIDI_ENABLE = no # MIDI controls
|
||||
AUDIO_ENABLE = no # Audio output on port C6
|
||||
UNICODE_ENABLE = no # Unicode
|
||||
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
|
||||
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
|
||||
USE_SERIAL = yes # Serial support only on fortitude60
|
||||
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
|
||||
SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
|
||||
|
||||
CUSTOM_MATRIX = yes
|
||||
|
||||
DEFAULT_FOLDER = fortitude60/rev1
|
@@ -1,235 +0,0 @@
|
||||
/*
|
||||
* WARNING: be careful changing this code, it is very timing dependent
|
||||
*/
|
||||
|
||||
#ifndef F_CPU
|
||||
#define F_CPU 16000000
|
||||
#endif
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include <stdbool.h>
|
||||
#include "serial.h"
|
||||
|
||||
#ifndef USE_I2C
|
||||
|
||||
// Serial pulse period in microseconds. Its probably a bad idea to lower this
|
||||
// value.
|
||||
#define SERIAL_DELAY 24
|
||||
|
||||
uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0};
|
||||
uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0};
|
||||
|
||||
#define SLAVE_DATA_CORRUPT (1<<0)
|
||||
volatile uint8_t status = 0;
|
||||
|
||||
inline static
|
||||
void serial_delay(void) {
|
||||
_delay_us(SERIAL_DELAY);
|
||||
}
|
||||
|
||||
inline static
|
||||
void serial_output(void) {
|
||||
SERIAL_PIN_DDR |= SERIAL_PIN_MASK;
|
||||
}
|
||||
|
||||
// make the serial pin an input with pull-up resistor
|
||||
inline static
|
||||
void serial_input(void) {
|
||||
SERIAL_PIN_DDR &= ~SERIAL_PIN_MASK;
|
||||
SERIAL_PIN_PORT |= SERIAL_PIN_MASK;
|
||||
}
|
||||
|
||||
inline static
|
||||
uint8_t serial_read_pin(void) {
|
||||
return !!(SERIAL_PIN_INPUT & SERIAL_PIN_MASK);
|
||||
}
|
||||
|
||||
inline static
|
||||
void serial_low(void) {
|
||||
SERIAL_PIN_PORT &= ~SERIAL_PIN_MASK;
|
||||
}
|
||||
|
||||
inline static
|
||||
void serial_high(void) {
|
||||
SERIAL_PIN_PORT |= SERIAL_PIN_MASK;
|
||||
}
|
||||
|
||||
void serial_master_init(void) {
|
||||
serial_output();
|
||||
serial_high();
|
||||
}
|
||||
|
||||
void serial_slave_init(void) {
|
||||
serial_input();
|
||||
|
||||
#ifndef USE_SERIAL_PD2
|
||||
// Enable INT0
|
||||
EIMSK |= _BV(INT0);
|
||||
// Trigger on falling edge of INT0
|
||||
EICRA &= ~(_BV(ISC00) | _BV(ISC01));
|
||||
#else
|
||||
// Enable INT2
|
||||
EIMSK |= _BV(INT2);
|
||||
// Trigger on falling edge of INT2
|
||||
EICRA &= ~(_BV(ISC20) | _BV(ISC21));
|
||||
#endif
|
||||
}
|
||||
|
||||
// Used by the master to synchronize timing with the slave.
|
||||
static
|
||||
void sync_recv(void) {
|
||||
serial_input();
|
||||
// This shouldn't hang if the slave disconnects because the
|
||||
// serial line will float to high if the slave does disconnect.
|
||||
while (!serial_read_pin());
|
||||
serial_delay();
|
||||
}
|
||||
|
||||
// Used by the slave to send a synchronization signal to the master.
|
||||
static
|
||||
void sync_send(void) {
|
||||
serial_output();
|
||||
|
||||
serial_low();
|
||||
serial_delay();
|
||||
|
||||
serial_high();
|
||||
}
|
||||
|
||||
// Reads a byte from the serial line
|
||||
static
|
||||
uint8_t serial_read_byte(void) {
|
||||
uint8_t byte = 0;
|
||||
serial_input();
|
||||
for ( uint8_t i = 0; i < 8; ++i) {
|
||||
byte = (byte << 1) | serial_read_pin();
|
||||
serial_delay();
|
||||
_delay_us(1);
|
||||
}
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
// Sends a byte with MSB ordering
|
||||
static
|
||||
void serial_write_byte(uint8_t data) {
|
||||
uint8_t b = 8;
|
||||
serial_output();
|
||||
while( b-- ) {
|
||||
if(data & (1 << b)) {
|
||||
serial_high();
|
||||
} else {
|
||||
serial_low();
|
||||
}
|
||||
serial_delay();
|
||||
}
|
||||
}
|
||||
|
||||
// interrupt handle to be used by the slave device
|
||||
ISR(SERIAL_PIN_INTERRUPT) {
|
||||
sync_send();
|
||||
|
||||
uint8_t checksum = 0;
|
||||
for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) {
|
||||
serial_write_byte(serial_slave_buffer[i]);
|
||||
sync_send();
|
||||
checksum += serial_slave_buffer[i];
|
||||
}
|
||||
serial_write_byte(checksum);
|
||||
sync_send();
|
||||
|
||||
// wait for the sync to finish sending
|
||||
serial_delay();
|
||||
|
||||
// read the middle of pulses
|
||||
_delay_us(SERIAL_DELAY/2);
|
||||
|
||||
uint8_t checksum_computed = 0;
|
||||
for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) {
|
||||
serial_master_buffer[i] = serial_read_byte();
|
||||
sync_send();
|
||||
checksum_computed += serial_master_buffer[i];
|
||||
}
|
||||
uint8_t checksum_received = serial_read_byte();
|
||||
sync_send();
|
||||
|
||||
serial_input(); // end transaction
|
||||
|
||||
if ( checksum_computed != checksum_received ) {
|
||||
status |= SLAVE_DATA_CORRUPT;
|
||||
} else {
|
||||
status &= ~SLAVE_DATA_CORRUPT;
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
bool serial_slave_DATA_CORRUPT(void) {
|
||||
return status & SLAVE_DATA_CORRUPT;
|
||||
}
|
||||
|
||||
// Copies the serial_slave_buffer to the master and sends the
|
||||
// serial_master_buffer to the slave.
|
||||
//
|
||||
// Returns:
|
||||
// 0 => no error
|
||||
// 1 => slave did not respond
|
||||
int serial_update_buffers(void) {
|
||||
// this code is very time dependent, so we need to disable interrupts
|
||||
cli();
|
||||
|
||||
// signal to the slave that we want to start a transaction
|
||||
serial_output();
|
||||
serial_low();
|
||||
_delay_us(1);
|
||||
|
||||
// wait for the slaves response
|
||||
serial_input();
|
||||
serial_high();
|
||||
_delay_us(SERIAL_DELAY);
|
||||
|
||||
// check if the slave is present
|
||||
if (serial_read_pin()) {
|
||||
// slave failed to pull the line low, assume not present
|
||||
sei();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// if the slave is present syncronize with it
|
||||
sync_recv();
|
||||
|
||||
uint8_t checksum_computed = 0;
|
||||
// receive data from the slave
|
||||
for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) {
|
||||
serial_slave_buffer[i] = serial_read_byte();
|
||||
sync_recv();
|
||||
checksum_computed += serial_slave_buffer[i];
|
||||
}
|
||||
uint8_t checksum_received = serial_read_byte();
|
||||
sync_recv();
|
||||
|
||||
if (checksum_computed != checksum_received) {
|
||||
sei();
|
||||
return 2;
|
||||
}
|
||||
|
||||
uint8_t checksum = 0;
|
||||
// send data to the slave
|
||||
for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) {
|
||||
serial_write_byte(serial_master_buffer[i]);
|
||||
sync_recv();
|
||||
checksum += serial_master_buffer[i];
|
||||
}
|
||||
serial_write_byte(checksum);
|
||||
sync_recv();
|
||||
|
||||
// always, release the line when not in use
|
||||
serial_output();
|
||||
serial_high();
|
||||
|
||||
sei();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,32 +0,0 @@
|
||||
#ifndef MY_SERIAL_H
|
||||
#define MY_SERIAL_H
|
||||
|
||||
#include "config.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
/* TODO: some defines for interrupt setup */
|
||||
#define SERIAL_PIN_DDR DDRD
|
||||
#define SERIAL_PIN_PORT PORTD
|
||||
#define SERIAL_PIN_INPUT PIND
|
||||
|
||||
#ifndef USE_SERIAL_PD2
|
||||
#define SERIAL_PIN_MASK _BV(PD0)
|
||||
#define SERIAL_PIN_INTERRUPT INT0_vect
|
||||
#else
|
||||
#define SERIAL_PIN_MASK _BV(PD2)
|
||||
#define SERIAL_PIN_INTERRUPT INT2_vect
|
||||
#endif
|
||||
|
||||
#define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2
|
||||
#define SERIAL_MASTER_BUFFER_LENGTH 1
|
||||
|
||||
// Buffers for master - slave communication
|
||||
extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH];
|
||||
extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH];
|
||||
|
||||
void serial_master_init(void);
|
||||
void serial_slave_init(void);
|
||||
int serial_update_buffers(void);
|
||||
bool serial_slave_data_corrupt(void);
|
||||
|
||||
#endif
|
@@ -1,85 +0,0 @@
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include <avr/eeprom.h>
|
||||
#include "split_util.h"
|
||||
#include "matrix.h"
|
||||
#include "keyboard.h"
|
||||
#include "config.h"
|
||||
#include "timer.h"
|
||||
|
||||
#include "serial.h"
|
||||
|
||||
volatile bool isLeftHand = true;
|
||||
|
||||
static void setup_handedness(void) {
|
||||
#ifdef EE_HANDS
|
||||
isLeftHand = eeprom_read_byte(EECONFIG_HANDEDNESS);
|
||||
#else
|
||||
// I2C_MASTER_RIGHT is deprecated, use MASTER_RIGHT instead, since this works for both serial and i2c
|
||||
#if defined(I2C_MASTER_RIGHT) || defined(MASTER_RIGHT)
|
||||
isLeftHand = !has_usb();
|
||||
#else
|
||||
isLeftHand = has_usb();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
static void keyboard_master_setup(void) {
|
||||
#ifdef USE_I2C
|
||||
i2c_master_init();
|
||||
#ifdef SSD1306OLED
|
||||
matrix_master_OLED_init ();
|
||||
#endif
|
||||
#else
|
||||
serial_master_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void keyboard_slave_setup(void) {
|
||||
timer_init();
|
||||
#ifdef USE_I2C
|
||||
i2c_slave_init(SLAVE_I2C_ADDRESS);
|
||||
#else
|
||||
serial_slave_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool has_usb(void) {
|
||||
/* return (UDADDR & _BV(ADDEN)); */
|
||||
USBCON |= (1 << OTGPADE); //enables VBUS pad
|
||||
_delay_us(5);
|
||||
return (USBSTA & (1<<VBUS)); //checks state of VBUS
|
||||
}
|
||||
|
||||
void split_keyboard_setup(void) {
|
||||
setup_handedness();
|
||||
|
||||
if (isLeftHand) {
|
||||
/* if (has_usb()) { */
|
||||
keyboard_master_setup();
|
||||
} else {
|
||||
keyboard_slave_setup();
|
||||
}
|
||||
sei();
|
||||
}
|
||||
|
||||
void keyboard_slave_loop(void) {
|
||||
matrix_init();
|
||||
|
||||
while (1) {
|
||||
matrix_slave_scan();
|
||||
}
|
||||
}
|
||||
|
||||
// this code runs before the usb and keyboard is initialized
|
||||
void matrix_setup(void) {
|
||||
split_keyboard_setup();
|
||||
|
||||
if (!isLeftHand) {
|
||||
/* if (!has_usb()) { */
|
||||
keyboard_slave_loop();
|
||||
}
|
||||
}
|
@@ -1,18 +0,0 @@
|
||||
#ifndef SPLIT_KEYBOARD_UTIL_H
|
||||
#define SPLIT_KEYBOARD_UTIL_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "eeconfig.h"
|
||||
|
||||
extern volatile bool isLeftHand;
|
||||
|
||||
// slave version of matix scan, defined in matrix.c
|
||||
void matrix_slave_scan(void);
|
||||
|
||||
void split_keyboard_setup(void);
|
||||
bool has_usb(void);
|
||||
void keyboard_slave_loop(void);
|
||||
|
||||
void matrix_master_OLED_init (void);
|
||||
|
||||
#endif
|
@@ -1,11 +0,0 @@
|
||||
# Gherkin Layout
|
||||
This is my gherkin layout.
|
||||
It is used as a game pad, and key layout is inspired by spare keys I had lying around.
|
||||
The firmware is very simple, and only includes one layer keymap, and RGB effects.
|
||||
|
||||
# Flashing
|
||||
The following command should be used from the main qmk directory.
|
||||
```
|
||||
make gherkin:bbaserdem
|
||||
sudo avrdude -p atmgea34u4 -P `ls /dev/ttyACM*` -c avr109 -U flash:.build/gherkin_bbaserdem.hex
|
||||
```
|
@@ -1,13 +0,0 @@
|
||||
#ifndef CONFIG_USER_H
|
||||
#define CONFIG_USER_H
|
||||
|
||||
#include "../../config.h"
|
||||
#define RGB_DI_PIN F6
|
||||
#define RGBLED_NUM 10
|
||||
#define RGBLIGHT_ANIMATIONS
|
||||
#ifdef BACKLIGHT_LEVELS
|
||||
#undef BACKLIGHT_LEVELS
|
||||
#endif
|
||||
#define BACKLIGHT_LEVELS 3
|
||||
|
||||
#endif
|
@@ -1,36 +0,0 @@
|
||||
// This is a game-pad gherkin layout with RGB and LED lights
|
||||
|
||||
#include "gherkin.h"
|
||||
|
||||
backlight_config_t backlight_config;
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
/* Game pad
|
||||
* ,-----------------------------------------------------------.
|
||||
* | Esc | 1 | 2 | 3 | 4 | 5 | 6 | Ctl | Alt | ~ |
|
||||
* |-----+-----+-----+-----+-----+-----+-----+-----+-----+-----|
|
||||
* | Tab | Q | W | E | R | T | |^| | ; | ' | / |
|
||||
* |-----+-----+-----+-----+-----+-----+-----+-----+-----+-----|
|
||||
* | Shf | A | S | D | F | <-- | |v| | --> | , | . |
|
||||
* `-----------------------------------------------------------'
|
||||
*/
|
||||
KEYMAP(
|
||||
KC_ESCAPE, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_LCTRL, KC_LALT, KC_GRAVE,
|
||||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_UP, KC_SCLN, KC_QUOTE, KC_SLASH,
|
||||
KC_LSHIFT, KC_A, KC_S, KC_D, KC_F, KC_LEFT, KC_DOWN, KC_RIGHT, KC_COMMA, KC_DOT
|
||||
)
|
||||
};
|
||||
|
||||
void matrix_init_user(void) {
|
||||
// Set LED's to max
|
||||
_delay_us(300);
|
||||
backlight_config.level = 2;
|
||||
backlight_config.enable = 1;
|
||||
eeconfig_update_backlight(backlight_config.raw);
|
||||
backlight_set(backlight_config.level);
|
||||
// Set RGB to rainbow mood light
|
||||
rgblight_enable();
|
||||
rgblight_mode(1);
|
||||
rgblight_sethsv(120,255,255);
|
||||
rgblight_mode(6);
|
||||
}
|
@@ -1,14 +0,0 @@
|
||||
ifndef QUANTUM_DIR
|
||||
include ../../../../Makefile
|
||||
endif
|
||||
|
||||
STENO_ENABLE = no # Additional protocols for Stenography(+1700), requires VIRTSER
|
||||
MOUSEKEY_ENABLE = no # Mouse keys(+4700)
|
||||
EXTRAKEY_ENABLE = no # Audio control and System control(+450)
|
||||
CONSOLE_ENABLE = no # Console for debug(+400)
|
||||
COMMAND_ENABLE = no # Commands for debug and configuration
|
||||
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
|
||||
NKRO_ENABLE = yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
|
||||
AUDIO_ENABLE = no # Enable audio output from keyboard
|
||||
RGBLIGHT_ENABLE = yes # Enable RBG light strips
|
||||
BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
|
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#include "config_common.h"
|
||||
|
||||
/* USB Device descriptor parameter */
|
||||
#define VENDOR_ID 0xFEED
|
||||
#define PRODUCT_ID 0x3060
|
||||
#define DEVICE_VER 0x0001
|
||||
#define MANUFACTURER mtdjr
|
||||
#define PRODUCT Not So MiniDox
|
||||
#define DESCRIPTION A larger version of the MiniDox
|
||||
|
||||
/* key matrix size */
|
||||
// Rows are doubled-up
|
||||
#define MATRIX_ROWS 8
|
||||
#define MATRIX_COLS 6
|
||||
|
||||
/* COL2ROW or ROW2COL */
|
||||
#define DIODE_DIRECTION COL2ROW
|
||||
|
||||
// wiring of each half
|
||||
#define MATRIX_ROW_PINS { D7, E6, B4, B5 }
|
||||
#define MATRIX_COL_PINS { B6, B2, B3, B1, F7, D4 }
|
||||
|
||||
#define USE_SERIAL
|
||||
|
||||
//#define EE_HANDS
|
||||
|
||||
#define MASTER_LEFT
|
||||
//#define MASTER_RIGHT
|
||||
|
||||
/* define if matrix has ghost */
|
||||
//#define MATRIX_HAS_GHOST
|
||||
|
||||
/* number of backlight levels */
|
||||
// #define BACKLIGHT_LEVELS 3
|
||||
|
||||
/* Set 0 if debouncing isn't needed */
|
||||
#define DEBOUNCING_DELAY 5
|
||||
|
||||
/* 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
|
||||
|
||||
/* key combination for command */
|
||||
#define IS_COMMAND() ( \
|
||||
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
|
||||
)
|
||||
|
||||
/* 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
|
||||
|
||||
|
||||
|
||||
#endif
|
@@ -1,162 +0,0 @@
|
||||
#include <util/twi.h>
|
||||
#include <avr/io.h>
|
||||
#include <stdlib.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/twi.h>
|
||||
#include <stdbool.h>
|
||||
#include "i2c.h"
|
||||
|
||||
#ifdef USE_I2C
|
||||
|
||||
// Limits the amount of we wait for any one i2c transaction.
|
||||
// Since were running SCL line 100kHz (=> 10μs/bit), and each transactions is
|
||||
// 9 bits, a single transaction will take around 90μs to complete.
|
||||
//
|
||||
// (F_CPU/SCL_CLOCK) => # of μC cycles to transfer a bit
|
||||
// poll loop takes at least 8 clock cycles to execute
|
||||
#define I2C_LOOP_TIMEOUT (9+1)*(F_CPU/SCL_CLOCK)/8
|
||||
|
||||
#define BUFFER_POS_INC() (slave_buffer_pos = (slave_buffer_pos+1)%SLAVE_BUFFER_SIZE)
|
||||
|
||||
volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE];
|
||||
|
||||
static volatile uint8_t slave_buffer_pos;
|
||||
static volatile bool slave_has_register_set = false;
|
||||
|
||||
// Wait for an i2c operation to finish
|
||||
inline static
|
||||
void i2c_delay(void) {
|
||||
uint16_t lim = 0;
|
||||
while(!(TWCR & (1<<TWINT)) && lim < I2C_LOOP_TIMEOUT)
|
||||
lim++;
|
||||
|
||||
// easier way, but will wait slightly longer
|
||||
// _delay_us(100);
|
||||
}
|
||||
|
||||
// Setup twi to run at 100kHz
|
||||
void i2c_master_init(void) {
|
||||
// no prescaler
|
||||
TWSR = 0;
|
||||
// Set TWI clock frequency to SCL_CLOCK. Need TWBR>10.
|
||||
// Check datasheets for more info.
|
||||
TWBR = ((F_CPU/SCL_CLOCK)-16)/2;
|
||||
}
|
||||
|
||||
// Start a transaction with the given i2c slave address. The direction of the
|
||||
// transfer is set with I2C_READ and I2C_WRITE.
|
||||
// returns: 0 => success
|
||||
// 1 => error
|
||||
uint8_t i2c_master_start(uint8_t address) {
|
||||
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTA);
|
||||
|
||||
i2c_delay();
|
||||
|
||||
// check that we started successfully
|
||||
if ( (TW_STATUS != TW_START) && (TW_STATUS != TW_REP_START))
|
||||
return 1;
|
||||
|
||||
TWDR = address;
|
||||
TWCR = (1<<TWINT) | (1<<TWEN);
|
||||
|
||||
i2c_delay();
|
||||
|
||||
if ( (TW_STATUS != TW_MT_SLA_ACK) && (TW_STATUS != TW_MR_SLA_ACK) )
|
||||
return 1; // slave did not acknowledge
|
||||
else
|
||||
return 0; // success
|
||||
}
|
||||
|
||||
|
||||
// Finish the i2c transaction.
|
||||
void i2c_master_stop(void) {
|
||||
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
|
||||
|
||||
uint16_t lim = 0;
|
||||
while(!(TWCR & (1<<TWSTO)) && lim < I2C_LOOP_TIMEOUT)
|
||||
lim++;
|
||||
}
|
||||
|
||||
// Write one byte to the i2c slave.
|
||||
// returns 0 => slave ACK
|
||||
// 1 => slave NACK
|
||||
uint8_t i2c_master_write(uint8_t data) {
|
||||
TWDR = data;
|
||||
TWCR = (1<<TWINT) | (1<<TWEN);
|
||||
|
||||
i2c_delay();
|
||||
|
||||
// check if the slave acknowledged us
|
||||
return (TW_STATUS == TW_MT_DATA_ACK) ? 0 : 1;
|
||||
}
|
||||
|
||||
// Read one byte from the i2c slave. If ack=1 the slave is acknowledged,
|
||||
// if ack=0 the acknowledge bit is not set.
|
||||
// returns: byte read from i2c device
|
||||
uint8_t i2c_master_read(int ack) {
|
||||
TWCR = (1<<TWINT) | (1<<TWEN) | (ack<<TWEA);
|
||||
|
||||
i2c_delay();
|
||||
return TWDR;
|
||||
}
|
||||
|
||||
void i2c_reset_state(void) {
|
||||
TWCR = 0;
|
||||
}
|
||||
|
||||
void i2c_slave_init(uint8_t address) {
|
||||
TWAR = address << 0; // slave i2c address
|
||||
// TWEN - twi enable
|
||||
// TWEA - enable address acknowledgement
|
||||
// TWINT - twi interrupt flag
|
||||
// TWIE - enable the twi interrupt
|
||||
TWCR = (1<<TWIE) | (1<<TWEA) | (1<<TWINT) | (1<<TWEN);
|
||||
}
|
||||
|
||||
ISR(TWI_vect);
|
||||
|
||||
ISR(TWI_vect) {
|
||||
uint8_t ack = 1;
|
||||
switch(TW_STATUS) {
|
||||
case TW_SR_SLA_ACK:
|
||||
// this device has been addressed as a slave receiver
|
||||
slave_has_register_set = false;
|
||||
break;
|
||||
|
||||
case TW_SR_DATA_ACK:
|
||||
// this device has received data as a slave receiver
|
||||
// The first byte that we receive in this transaction sets the location
|
||||
// of the read/write location of the slaves memory that it exposes over
|
||||
// i2c. After that, bytes will be written at slave_buffer_pos, incrementing
|
||||
// slave_buffer_pos after each write.
|
||||
if(!slave_has_register_set) {
|
||||
slave_buffer_pos = TWDR;
|
||||
// don't acknowledge the master if this memory loctaion is out of bounds
|
||||
if ( slave_buffer_pos >= SLAVE_BUFFER_SIZE ) {
|
||||
ack = 0;
|
||||
slave_buffer_pos = 0;
|
||||
}
|
||||
slave_has_register_set = true;
|
||||
} else {
|
||||
i2c_slave_buffer[slave_buffer_pos] = TWDR;
|
||||
BUFFER_POS_INC();
|
||||
}
|
||||
break;
|
||||
|
||||
case TW_ST_SLA_ACK:
|
||||
case TW_ST_DATA_ACK:
|
||||
// master has addressed this device as a slave transmitter and is
|
||||
// requesting data.
|
||||
TWDR = i2c_slave_buffer[slave_buffer_pos];
|
||||
BUFFER_POS_INC();
|
||||
break;
|
||||
|
||||
case TW_BUS_ERROR: // something went wrong, reset twi state
|
||||
TWCR = 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Reset everything, so we are ready for the next TWI interrupt
|
||||
TWCR |= (1<<TWIE) | (1<<TWINT) | (ack<<TWEA) | (1<<TWEN);
|
||||
}
|
||||
#endif
|
@@ -1,49 +0,0 @@
|
||||
#ifndef I2C_H
|
||||
#define I2C_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef F_CPU
|
||||
#define F_CPU 16000000UL
|
||||
#endif
|
||||
|
||||
#define I2C_READ 1
|
||||
#define I2C_WRITE 0
|
||||
|
||||
#define I2C_ACK 1
|
||||
#define I2C_NACK 0
|
||||
|
||||
#define SLAVE_BUFFER_SIZE 0x10
|
||||
|
||||
// i2c SCL clock frequency
|
||||
#define SCL_CLOCK 400000L
|
||||
|
||||
extern volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE];
|
||||
|
||||
void i2c_master_init(void);
|
||||
uint8_t i2c_master_start(uint8_t address);
|
||||
void i2c_master_stop(void);
|
||||
uint8_t i2c_master_write(uint8_t data);
|
||||
uint8_t i2c_master_read(int);
|
||||
void i2c_reset_state(void);
|
||||
void i2c_slave_init(uint8_t address);
|
||||
|
||||
|
||||
static inline unsigned char i2c_start_read(unsigned char addr) {
|
||||
return i2c_master_start((addr << 1) | I2C_READ);
|
||||
}
|
||||
|
||||
static inline unsigned char i2c_start_write(unsigned char addr) {
|
||||
return i2c_master_start((addr << 1) | I2C_WRITE);
|
||||
}
|
||||
|
||||
// from SSD1306 scrips
|
||||
extern unsigned char i2c_rep_start(unsigned char addr);
|
||||
extern void i2c_start_wait(unsigned char addr);
|
||||
extern unsigned char i2c_readAck(void);
|
||||
extern unsigned char i2c_readNak(void);
|
||||
extern unsigned char i2c_read(unsigned char ack);
|
||||
|
||||
#define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak();
|
||||
|
||||
#endif
|
@@ -1,121 +0,0 @@
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
extern keymap_config_t keymap_config;
|
||||
|
||||
// Each layer gets a name for readability, which is then used in the keymap matrix below.
|
||||
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
|
||||
// Layer names don't all need to be of the same length, obviously, and you can also skip them
|
||||
// entirely and just use numbers.
|
||||
#define _QWERTY 0
|
||||
#define _LOWER 1
|
||||
#define _RAISE 2
|
||||
#define _ADJUST 16
|
||||
|
||||
enum custom_keycodes {
|
||||
QWERTY = SAFE_RANGE,
|
||||
LOWER,
|
||||
RAISE,
|
||||
ADJUST,
|
||||
};
|
||||
|
||||
// Fillers to make layering more clear
|
||||
#define _______ KC_TRNS
|
||||
#define XXXXXXX KC_NO
|
||||
|
||||
#define KC_LOWR LOWER
|
||||
#define KC_RASE RAISE
|
||||
#define KC_RST RESET
|
||||
#define KC_CAD LCTL(LALT(KC_DEL))
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
|
||||
[_QWERTY] = LAYOUT(
|
||||
// ,-------+-------+-------+-------+-------+-------. ,-------+-------+-------+-------+-------+-------.
|
||||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P,KC_BSPC,
|
||||
// |-------+-------+-------+-------+-------+-------. ,-------+-------+-------+-------+-------+-------|
|
||||
KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L,KC_SCLN,KC_QUOT,
|
||||
// |-------+-------+-------+-------+-------+-------. ,-------+-------+-------+-------+-------+-------|
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M,KC_COMM, KC_DOT,KC_SLSH, KC_ENT,
|
||||
// '-------+-------+-------+-------+-------+-------. ,-------+-------+-------+-------+-------+-------'
|
||||
KC_LGUI,KC_LOWR, KC_SPC, KC_SPC,KC_RASE,KC_RALT
|
||||
// `-------+-------+-------` `-------+-------+-------`
|
||||
),
|
||||
|
||||
[_LOWER] = LAYOUT(
|
||||
// ,-------+-------+-------+-------+-------+-------. ,-------+-------+-------+-------+-------+-------.
|
||||
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL,
|
||||
// |-------+-------+-------+-------+-------+-------. ,-------+-------+-------+-------+-------+-------|
|
||||
_______,_______,_______,_______,_______,_______, _______,_______,_______,KC_LCBR,KC_RCBR,KC_BSLS,
|
||||
// |-------+-------+-------+-------+-------+-------. ,-------+-------+-------+-------+-------+-------|
|
||||
_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______,
|
||||
// '-------+-------+-------+-------+-------+-------. ,-------+-------+-------+-------+-------+-------'
|
||||
_______,_______,_______, _______,_______,_______
|
||||
// `-------+-------+-------` `-------+-------+-------`
|
||||
),
|
||||
|
||||
[_RAISE] = LAYOUT(
|
||||
// ,-------+-------+-------+-------+-------+-------. ,-------+-------+-------+-------+-------+-------.
|
||||
KC_GRV,KC_EXLM, KC_AT,KC_HASH, KC_DLR,KC_PERC, KC_CIRC,KC_AMPR,KC_ASTR,KC_LPRN,KC_RPRN, KC_DEL,
|
||||
// |-------+-------+-------+-------+-------+-------. ,-------+-------+-------+-------+-------+-------|
|
||||
_______,_______,_______,_______,KC_MINS, KC_EQL, _______, KC_UP,_______,KC_LBRC,KC_RBRC,KC_PIPE,
|
||||
// |-------+-------+-------+-------+-------+-------. ,-------+-------+-------+-------+-------+-------|
|
||||
_______,_______,_______,_______,_______,_______, KC_LEFT,KC_DOWN,KC_RGHT,_______,_______,_______,
|
||||
// '-------+-------+-------+-------+-------+-------. ,-------+-------+-------+-------+-------+-------'
|
||||
_______,_______,_______, _______,_______,_______
|
||||
// `-------+-------+-------` `-------+-------+-------`
|
||||
),
|
||||
[_ADJUST] = LAYOUT(
|
||||
// ,-------+-------+-------+-------+-------+-------. ,-------+-------+-------+-------+-------+-------.
|
||||
_______,_______,_______,_______, KC_RST,_______, _______,_______,_______,_______,_______, KC_CAD,
|
||||
// |-------+-------+-------+-------+-------+-------. ,-------+-------+-------+-------+-------+-------|
|
||||
_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______,
|
||||
// |-------+-------+-------+-------+-------+-------. ,-------+-------+-------+-------+-------+-------|
|
||||
_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______,
|
||||
// '-------+-------+-------+-------+-------+-------. ,-------+-------+-------+-------+-------+-------'
|
||||
_______,_______,_______, _______,_______,_______
|
||||
// `-------+-------+-------` `-------+-------+-------`
|
||||
)
|
||||
};
|
||||
|
||||
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
switch (keycode) {
|
||||
case QWERTY:
|
||||
if (record->event.pressed) {
|
||||
set_single_persistent_default_layer(_QWERTY);
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case LOWER:
|
||||
if (record->event.pressed) {
|
||||
layer_on(_LOWER);
|
||||
update_tri_layer(_LOWER, _RAISE, _ADJUST);
|
||||
} else {
|
||||
layer_off(_LOWER);
|
||||
update_tri_layer(_LOWER, _RAISE, _ADJUST);
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case RAISE:
|
||||
if (record->event.pressed) {
|
||||
layer_on(_RAISE);
|
||||
update_tri_layer(_LOWER, _RAISE, _ADJUST);
|
||||
} else {
|
||||
layer_off(_RAISE);
|
||||
update_tri_layer(_LOWER, _RAISE, _ADJUST);
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case ADJUST:
|
||||
if (record->event.pressed) {
|
||||
layer_on(_ADJUST);
|
||||
update_tri_layer(_LOWER, _RAISE, _ADJUST);
|
||||
} else {
|
||||
layer_off(_ADJUST);
|
||||
update_tri_layer(_LOWER, _RAISE, _ADJUST);
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
#ifndef CONFIG_USER_H
|
||||
#define CONFIG_USER_H
|
||||
|
||||
#include QMK_KEYBOARD_CONFIG_H
|
||||
|
||||
#define SOLENOID_ENABLE
|
||||
#define SOLENOID_PIN F6
|
||||
#undef SOLENOID_ACTIVE
|
||||
#define SOLENOID_ACTIVE true
|
||||
|
||||
#endif
|
@@ -1,56 +0,0 @@
|
||||
#include QMK_KEYBOARD_H
|
||||
#include "mtdjr.h"
|
||||
|
||||
extern keymap_config_t keymap_config;
|
||||
|
||||
#define KC_LOCK TD(TD_ALTLOCK)
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
|
||||
[_QWERTY] = LAYOUT_kc(
|
||||
// ,----+-----+-----+-----+-----+-----, ,----+-----+-----+-----+-----+-----,
|
||||
TAB, Q, W, E, R, T, Y, U, I, O, P, BSPC,
|
||||
// |----+-----+-----+-----+-----+-----| |----+-----+-----+-----+-----+-----|
|
||||
LCTL, A, S, D, F, G, H, J, K, L, SCLN, QUOT,
|
||||
// |----+-----+-----+-----+-----+-----| |----+-----+-----+-----+-----+-----|
|
||||
LSFT, Z, X, C, V, B, N, M, COMM, DOT, SLSH, ENT,
|
||||
// |----+-----+-----+-----+-----+-----|-, ,-|----+-----+-----+-----+-----+-----|
|
||||
LGUI, LOWR, SPC, SPC, RASE, LOCK
|
||||
// `----+-----+-----` `----+-----+-----`
|
||||
),
|
||||
|
||||
[_LOWER] = LAYOUT_kc(
|
||||
// ,----+-----+-----+-----+-----+-----, ,----+-----+-----+-----+-----+-----,
|
||||
ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, DEL,
|
||||
// |----+-----+-----+-----+-----+-----| |----+-----+-----+-----+-----+-----|
|
||||
, , , , , , , , , LCBR, RCBR, BSLS,
|
||||
// |----+-----+-----+-----+-----+-----| |----+-----+-----+-----+-----+-----|
|
||||
, , , XCPY, XINS, , , , , , , ,
|
||||
// |----+-----+-----+-----+-----+-----|-, ,-|----+-----+-----+-----+-----+-----|
|
||||
, , , , ,
|
||||
// `----+-----+-----` `----+-----+-----`
|
||||
),
|
||||
|
||||
[_RAISE] = LAYOUT_kc(
|
||||
// ,----+-----+-----+-----+-----+-----, ,----+-----+-----+-----+-----+-----,
|
||||
GRV, EXLM, AT, HASH, DLR, PERC, CIRC, AMPR, ASTR, LPRN, RPRN, DEL,
|
||||
// |----+-----+-----+-----+-----+-----| |----+-----+-----+-----+-----+-----|
|
||||
, , , , MINS, EQL, , , UP, LBRC, RBRC, PIPE,
|
||||
// |----+-----+-----+-----+-----+-----| |----+-----+-----+-----+-----+-----|
|
||||
, , , , , , , LEFT, DOWN, RGHT, , ,
|
||||
// |----+-----+-----+-----+-----+-----|-, ,-|----+-----+-----+-----+-----+-----|
|
||||
, , , , ,
|
||||
// `----+-----+-----` `----+-----+-----`
|
||||
),
|
||||
[_ADJUST] = LAYOUT_kc(
|
||||
// ,----+-----+-----+-----+-----+-----, ,----+-----+-----+-----+-----+-----,
|
||||
STOG, xxxx, xxxx, xxxx, RST, xxxx, ROOT, PPLY, PSEF, xxxx, xxxx, CAD,
|
||||
// |----+-----+-----+-----+-----+-----| |----+-----+-----+-----+-----+-----|
|
||||
SDM, SDP, SBOF, SBON, xxxx, xxxx, xxxx, xxxx, xxxx, xxxx, xxxx, xxxx,
|
||||
// |----+-----+-----+-----+-----+-----| |----+-----+-----+-----+-----+-----|
|
||||
xxxx, xxxx, xxxx, xxxx, xxxx, xxxx, xxxx, xxxx, xxxx, xxxx, xxxx, xxxx,
|
||||
// |----+-----+-----+-----+-----+-----|-, ,-|----+-----+-----+-----+-----+-----|
|
||||
xxxx, , xxxx, xxxx, , xxxx
|
||||
// `----+-----+-----` `----+-----+-----`
|
||||
)
|
||||
};
|
@@ -1 +0,0 @@
|
||||
TAP_DANCE_ENABLE = yes
|
@@ -1,307 +0,0 @@
|
||||
/*
|
||||
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* scan matrix
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include "print.h"
|
||||
#include "debug.h"
|
||||
#include "util.h"
|
||||
#include "matrix.h"
|
||||
#include "split_util.h"
|
||||
#include "pro_micro.h"
|
||||
#include "config.h"
|
||||
|
||||
#ifdef USE_I2C
|
||||
# include "i2c.h"
|
||||
#else // USE_SERIAL
|
||||
# include "serial.h"
|
||||
#endif
|
||||
|
||||
#ifndef DEBOUNCE
|
||||
# define DEBOUNCE 5
|
||||
#endif
|
||||
|
||||
#define ERROR_DISCONNECT_COUNT 5
|
||||
|
||||
static uint8_t debouncing = DEBOUNCE;
|
||||
static const int ROWS_PER_HAND = MATRIX_ROWS/2;
|
||||
static uint8_t error_count = 0;
|
||||
|
||||
static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
|
||||
static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
|
||||
|
||||
/* matrix state(1:on, 0:off) */
|
||||
static matrix_row_t matrix[MATRIX_ROWS];
|
||||
static matrix_row_t matrix_debouncing[MATRIX_ROWS];
|
||||
|
||||
static matrix_row_t read_cols(void);
|
||||
static void init_cols(void);
|
||||
static void unselect_rows(void);
|
||||
static void select_row(uint8_t row);
|
||||
|
||||
|
||||
__attribute__ ((weak))
|
||||
void matrix_init_kb(void) {
|
||||
matrix_init_user();
|
||||
}
|
||||
|
||||
__attribute__ ((weak))
|
||||
void matrix_scan_kb(void) {
|
||||
matrix_scan_user();
|
||||
}
|
||||
|
||||
__attribute__ ((weak))
|
||||
void matrix_init_user(void) {
|
||||
}
|
||||
|
||||
__attribute__ ((weak))
|
||||
void matrix_scan_user(void) {
|
||||
}
|
||||
|
||||
inline
|
||||
uint8_t matrix_rows(void)
|
||||
{
|
||||
return MATRIX_ROWS;
|
||||
}
|
||||
|
||||
inline
|
||||
uint8_t matrix_cols(void)
|
||||
{
|
||||
return MATRIX_COLS;
|
||||
}
|
||||
|
||||
void matrix_init(void)
|
||||
{
|
||||
debug_enable = true;
|
||||
debug_matrix = true;
|
||||
debug_mouse = true;
|
||||
// initialize row and col
|
||||
unselect_rows();
|
||||
init_cols();
|
||||
|
||||
TX_RX_LED_INIT;
|
||||
|
||||
// initialize matrix state: all keys off
|
||||
for (uint8_t i=0; i < MATRIX_ROWS; i++) {
|
||||
matrix[i] = 0;
|
||||
matrix_debouncing[i] = 0;
|
||||
}
|
||||
|
||||
matrix_init_quantum();
|
||||
}
|
||||
|
||||
uint8_t _matrix_scan(void)
|
||||
{
|
||||
// Right hand is stored after the left in the matirx so, we need to offset it
|
||||
int offset = isLeftHand ? 0 : (ROWS_PER_HAND);
|
||||
|
||||
for (uint8_t i = 0; i < ROWS_PER_HAND; i++) {
|
||||
select_row(i);
|
||||
_delay_us(30); // without this wait read unstable value.
|
||||
matrix_row_t cols = read_cols();
|
||||
if (matrix_debouncing[i+offset] != cols) {
|
||||
matrix_debouncing[i+offset] = cols;
|
||||
debouncing = DEBOUNCE;
|
||||
}
|
||||
unselect_rows();
|
||||
}
|
||||
|
||||
if (debouncing) {
|
||||
if (--debouncing) {
|
||||
_delay_ms(1);
|
||||
} else {
|
||||
for (uint8_t i = 0; i < ROWS_PER_HAND; i++) {
|
||||
matrix[i+offset] = matrix_debouncing[i+offset];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef USE_I2C
|
||||
|
||||
// Get rows from other half over i2c
|
||||
int i2c_transaction(void) {
|
||||
int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;
|
||||
|
||||
int err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE);
|
||||
if (err) goto i2c_error;
|
||||
|
||||
// start of matrix stored at 0x00
|
||||
err = i2c_master_write(0x00);
|
||||
if (err) goto i2c_error;
|
||||
|
||||
// Start read
|
||||
err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_READ);
|
||||
if (err) goto i2c_error;
|
||||
|
||||
if (!err) {
|
||||
int i;
|
||||
for (i = 0; i < ROWS_PER_HAND-1; ++i) {
|
||||
matrix[slaveOffset+i] = i2c_master_read(I2C_ACK);
|
||||
}
|
||||
matrix[slaveOffset+i] = i2c_master_read(I2C_NACK);
|
||||
i2c_master_stop();
|
||||
} else {
|
||||
i2c_error: // the cable is disconnceted, or something else went wrong
|
||||
i2c_reset_state();
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else // USE_SERIAL
|
||||
|
||||
int serial_transaction(void) {
|
||||
int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;
|
||||
|
||||
if (serial_update_buffers()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ROWS_PER_HAND; ++i) {
|
||||
matrix[slaveOffset+i] = serial_slave_buffer[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t matrix_scan(void)
|
||||
{
|
||||
int ret = _matrix_scan();
|
||||
|
||||
|
||||
|
||||
#ifdef USE_I2C
|
||||
if( i2c_transaction() ) {
|
||||
#else // USE_SERIAL
|
||||
if( serial_transaction() ) {
|
||||
#endif
|
||||
// turn on the indicator led when halves are disconnected
|
||||
TXLED1;
|
||||
|
||||
error_count++;
|
||||
|
||||
if (error_count > ERROR_DISCONNECT_COUNT) {
|
||||
// reset other half if disconnected
|
||||
int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;
|
||||
for (int i = 0; i < ROWS_PER_HAND; ++i) {
|
||||
matrix[slaveOffset+i] = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// turn off the indicator led on no error
|
||||
TXLED0;
|
||||
error_count = 0;
|
||||
}
|
||||
matrix_scan_quantum();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void matrix_slave_scan(void) {
|
||||
_matrix_scan();
|
||||
|
||||
int offset = (isLeftHand) ? 0 : (MATRIX_ROWS / 2);
|
||||
|
||||
#ifdef USE_I2C
|
||||
for (int i = 0; i < ROWS_PER_HAND; ++i) {
|
||||
/* i2c_slave_buffer[i] = matrix[offset+i]; */
|
||||
i2c_slave_buffer[i] = matrix[offset+i];
|
||||
}
|
||||
#else // USE_SERIAL
|
||||
for (int i = 0; i < ROWS_PER_HAND; ++i) {
|
||||
serial_slave_buffer[i] = matrix[offset+i];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool matrix_is_modified(void)
|
||||
{
|
||||
if (debouncing) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline
|
||||
bool matrix_is_on(uint8_t row, uint8_t col)
|
||||
{
|
||||
return (matrix[row] & ((matrix_row_t)1<<col));
|
||||
}
|
||||
|
||||
inline
|
||||
matrix_row_t matrix_get_row(uint8_t row)
|
||||
{
|
||||
return matrix[row];
|
||||
}
|
||||
|
||||
void matrix_print(void)
|
||||
{
|
||||
print("\nr/c 0123456789ABCDEF\n");
|
||||
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
|
||||
phex(row); print(": ");
|
||||
pbin_reverse16(matrix_get_row(row));
|
||||
print("\n");
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t matrix_key_count(void)
|
||||
{
|
||||
uint8_t count = 0;
|
||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||
count += bitpop16(matrix[i]);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static void init_cols(void)
|
||||
{
|
||||
for(int x = 0; x < MATRIX_COLS; x++) {
|
||||
_SFR_IO8((col_pins[x] >> 4) + 1) &= ~_BV(col_pins[x] & 0xF);
|
||||
_SFR_IO8((col_pins[x] >> 4) + 2) |= _BV(col_pins[x] & 0xF);
|
||||
}
|
||||
}
|
||||
|
||||
static matrix_row_t read_cols(void)
|
||||
{
|
||||
matrix_row_t result = 0;
|
||||
for(int x = 0; x < MATRIX_COLS; x++) {
|
||||
result |= (_SFR_IO8(col_pins[x] >> 4) & _BV(col_pins[x] & 0xF)) ? 0 : (1 << x);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void unselect_rows(void)
|
||||
{
|
||||
for(int x = 0; x < ROWS_PER_HAND; x++) {
|
||||
_SFR_IO8((row_pins[x] >> 4) + 1) &= ~_BV(row_pins[x] & 0xF);
|
||||
_SFR_IO8((row_pins[x] >> 4) + 2) |= _BV(row_pins[x] & 0xF);
|
||||
}
|
||||
}
|
||||
|
||||
static void select_row(uint8_t row)
|
||||
{
|
||||
_SFR_IO8((row_pins[row] >> 4) + 1) |= _BV(row_pins[row] & 0xF);
|
||||
_SFR_IO8((row_pins[row] >> 4) + 2) &= ~_BV(row_pins[row] & 0xF);
|
||||
}
|
@@ -1 +0,0 @@
|
||||
#include "not_so_minidox.h"
|
@@ -1,42 +0,0 @@
|
||||
#ifndef NOSOTMINIDOX_H
|
||||
#define NOSOTMINIDOX_H
|
||||
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
#define LAYOUT( \
|
||||
L00, L01, L02, L03, L04, L05, R05, R04, R03, R02, R01, R00, \
|
||||
L10, L11, L12, L13, L14, L15, R15, R14, R13, R12, R11, R10, \
|
||||
L20, L21, L22, L23, L24, L25, R25, R24, R23, R22, R21, R20, \
|
||||
LT1, LT2, LT3, RT3, RT2, RT1 \
|
||||
) \
|
||||
{ \
|
||||
{ L00, L01, L02, L03, L04, L05 }, \
|
||||
{ L10, L11, L12, L13, L14, L15 }, \
|
||||
{ L20, L21, L22, L23, L24, L25 }, \
|
||||
{ KC_NO, KC_NO, KC_NO, LT1, LT2, LT3 }, \
|
||||
{ R00, R01, R02, R03, R04, R05 }, \
|
||||
{ R10, R11, R12, R13, R14, R15 }, \
|
||||
{ R20, R21, R22, R23, R24, R25 }, \
|
||||
{ KC_NO, KC_NO, KC_NO, RT1, RT2, RT3 }, \
|
||||
}
|
||||
|
||||
// Used to create a keymap using only KC_ prefixed keys
|
||||
#define LAYOUT_kc( \
|
||||
L00, L01, L02, L03, L04, L05, R05, R04, R03, R02, R01, R00, \
|
||||
L10, L11, L12, L13, L14, L15, R15, R14, R13, R12, R11, R10, \
|
||||
L20, L21, L22, L23, L24, L25, R25, R24, R23, R22, R21, R20, \
|
||||
LT1, LT2, LT3, RT3, RT2, RT1 \
|
||||
) \
|
||||
{ \
|
||||
{ KC_##L00, KC_##L01, KC_##L02, KC_##L03, KC_##L04, KC_##L05 }, \
|
||||
{ KC_##L10, KC_##L11, KC_##L12, KC_##L13, KC_##L14, KC_##L15 }, \
|
||||
{ KC_##L20, KC_##L21, KC_##L22, KC_##L23, KC_##L24, KC_##L25 }, \
|
||||
{ KC_NO, KC_NO, KC_NO, KC_##LT1, KC_##LT2, KC_##LT3 }, \
|
||||
{ KC_##R00, KC_##R01, KC_##R02, KC_##R03, KC_##R04, KC_##R05 }, \
|
||||
{ KC_##R10, KC_##R11, KC_##R12, KC_##R13, KC_##R14, KC_##R15 }, \
|
||||
{ KC_##R20, KC_##R21, KC_##R22, KC_##R23, KC_##R24, KC_##R25 }, \
|
||||
{ KC_NO, KC_NO, KC_NO, KC_##RT1, KC_##RT2, KC_##RT3 }, \
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,71 +0,0 @@
|
||||
not_so_minidox
|
||||
=====
|
||||
|
||||
![not_so_minidox]()
|
||||
|
||||
A slightly larger version of the MiniDox
|
||||
|
||||
Keyboard Maintainer: mtdjr
|
||||
Hardware Supported: None yet/ProMicro
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
||||
make not_so_minidox/rev1:default
|
||||
|
||||
See [build environment setup](https://docs.qmk.fm/build_environment_setup.html) then the [make instructions](https://docs.qmk.fm/make_instructions.html) for more information.
|
||||
|
||||
Flashing
|
||||
-------
|
||||
Note: Most of this is copied from the Let's Split readme, because it is awesome
|
||||
|
||||
From the root directory run `make PROJECT:KEYMAP:avrdude` for automatic serial port resolution and flashing.
|
||||
Example: `make not_so_minidox/rev1:default:avrdude`
|
||||
|
||||
Choosing which board to plug the USB cable into (choosing Master)
|
||||
--------
|
||||
Because the two boards are identical, the firmware has logic to differentiate the left and right board.
|
||||
|
||||
It uses two strategies to figure things out: look at the EEPROM (memory on the chip) or looks if the current board has the usb cable.
|
||||
|
||||
The EEPROM approach requires additional setup (flashing the eeeprom) but allows you to swap the usb cable to either side.
|
||||
|
||||
The USB cable approach is easier to setup and if you just want the usb cable on the left board, you do not need to do anything extra.
|
||||
|
||||
### Setting the left hand as master
|
||||
If you always plug the usb cable into the left board, nothing extra is needed as this is the default. Comment out `EE_HANDS` and comment out `I2C_MASTER_RIGHT` or `MASTER_RIGHT` if for some reason it was set.
|
||||
|
||||
### Setting the right hand as master
|
||||
If you always plug the usb cable into the right board, add an extra flag to your `config.h`
|
||||
```
|
||||
#define MASTER_RIGHT
|
||||
```
|
||||
|
||||
### Setting EE_hands to use either hands as master
|
||||
If you define `EE_HANDS` in your `config.h`, you will need to set the
|
||||
EEPROM for the left and right halves.
|
||||
|
||||
The EEPROM is used to store whether the
|
||||
half is left handed or right handed. This makes it so that the same firmware
|
||||
file will run on both hands instead of having to flash left and right handed
|
||||
versions of the firmware to each half. To flash the EEPROM file for the left
|
||||
half run:
|
||||
```
|
||||
avrdude -p atmega32u4 -P $(COM_PORT) -c avr109 -U eeprom:w:eeprom-lefthand.eep
|
||||
// or the equivalent in dfu-programmer
|
||||
|
||||
```
|
||||
and similarly for right half
|
||||
```
|
||||
avrdude -p atmega32u4 -P $(COM_PORT) -c avr109 -U eeprom:w:eeprom-righhand.eep
|
||||
// or the equivalent in dfu-programmer
|
||||
```
|
||||
|
||||
NOTE: replace `$(COM_PORT)` with the port of your device (e.g. `/dev/ttyACM0`)
|
||||
|
||||
After you have flashed the EEPROM, you then need to set `EE_HANDS` in your config.h, rebuild the hex files and reflash.
|
||||
|
||||
Note that you need to program both halves, but you have the option of using
|
||||
different keymaps for each half. You could program the left half with a QWERTY
|
||||
layout and the right half with a Colemak layout using bootmagic's default layout option.
|
||||
Then if you connect the left half to a computer by USB the keyboard will use QWERTY and Colemak when the
|
||||
right half is connected.
|
@@ -1,71 +0,0 @@
|
||||
SRC += matrix.c \
|
||||
i2c.c \
|
||||
split_util.c \
|
||||
serial.c
|
||||
|
||||
# MCU name
|
||||
#MCU = at90usb1287
|
||||
MCU = atmega32u4
|
||||
|
||||
# Processor frequency.
|
||||
# This will define a symbol, F_CPU, in all source code files equal to the
|
||||
# processor frequency in Hz. You can then use this symbol in your source code to
|
||||
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
|
||||
# automatically to create a 32-bit value in your source code.
|
||||
#
|
||||
# This will be an integer division of F_USB below, as it is sourced by
|
||||
# F_USB after it has run through any CPU prescalers. Note that this value
|
||||
# does not *change* the processor frequency - it should merely be updated to
|
||||
# reflect the processor speed set externally so that the code can use accurate
|
||||
# software delays.
|
||||
F_CPU = 16000000
|
||||
|
||||
#
|
||||
# LUFA specific
|
||||
#
|
||||
# Target architecture (see library "Board Types" documentation).
|
||||
ARCH = AVR8
|
||||
|
||||
# Input clock frequency.
|
||||
# This will define a symbol, F_USB, in all source code files equal to the
|
||||
# input clock frequency (before any prescaling is performed) in Hz. This value may
|
||||
# differ from F_CPU if prescaling is used on the latter, and is required as the
|
||||
# raw input clock is fed directly to the PLL sections of the AVR for high speed
|
||||
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
|
||||
# at the end, this will be done automatically to create a 32-bit value in your
|
||||
# source code.
|
||||
#
|
||||
# If no clock division is performed on the input clock inside the AVR (via the
|
||||
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
|
||||
F_USB = $(F_CPU)
|
||||
|
||||
# Bootloader
|
||||
# This definition is optional, and if your keyboard supports multiple bootloaders of
|
||||
# different sizes, comment this out, and the correct address will be loaded
|
||||
# automatically (+60). See bootloader.mk for all options.
|
||||
BOOTLOADER = caterina
|
||||
|
||||
# Interrupt driven control endpoint task(+60)
|
||||
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
|
||||
|
||||
# Build Options
|
||||
# change to "no" to disable the options, or define them in the Makefile in
|
||||
# the appropriate keymap folder that will get included automatically
|
||||
#
|
||||
BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000)
|
||||
MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
|
||||
EXTRAKEY_ENABLE ?= no # Audio control and System control(+450)
|
||||
CONSOLE_ENABLE ?= no # Console for debug(+400)
|
||||
COMMAND_ENABLE ?= yes # Commands for debug and configuration
|
||||
NKRO_ENABLE ?= no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
|
||||
BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality
|
||||
MIDI_ENABLE ?= no # MIDI controls
|
||||
AUDIO_ENABLE ?= no # Audio output on port C6
|
||||
UNICODE_ENABLE ?= no # Unicode
|
||||
BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
|
||||
RGBLIGHT_ENABLE ?= no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
|
||||
USE_I2C ?= no
|
||||
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
|
||||
SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
|
||||
|
||||
CUSTOM_MATRIX = yes
|
@@ -1,228 +0,0 @@
|
||||
/*
|
||||
* WARNING: be careful changing this code, it is very timing dependent
|
||||
*/
|
||||
|
||||
#ifndef F_CPU
|
||||
#define F_CPU 16000000
|
||||
#endif
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include <stdbool.h>
|
||||
#include "serial.h"
|
||||
|
||||
#ifndef USE_I2C
|
||||
|
||||
// Serial pulse period in microseconds. Its probably a bad idea to lower this
|
||||
// value.
|
||||
#define SERIAL_DELAY 24
|
||||
|
||||
uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0};
|
||||
uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0};
|
||||
|
||||
#define SLAVE_DATA_CORRUPT (1<<0)
|
||||
volatile uint8_t status = 0;
|
||||
|
||||
inline static
|
||||
void serial_delay(void) {
|
||||
_delay_us(SERIAL_DELAY);
|
||||
}
|
||||
|
||||
inline static
|
||||
void serial_output(void) {
|
||||
SERIAL_PIN_DDR |= SERIAL_PIN_MASK;
|
||||
}
|
||||
|
||||
// make the serial pin an input with pull-up resistor
|
||||
inline static
|
||||
void serial_input(void) {
|
||||
SERIAL_PIN_DDR &= ~SERIAL_PIN_MASK;
|
||||
SERIAL_PIN_PORT |= SERIAL_PIN_MASK;
|
||||
}
|
||||
|
||||
inline static
|
||||
uint8_t serial_read_pin(void) {
|
||||
return !!(SERIAL_PIN_INPUT & SERIAL_PIN_MASK);
|
||||
}
|
||||
|
||||
inline static
|
||||
void serial_low(void) {
|
||||
SERIAL_PIN_PORT &= ~SERIAL_PIN_MASK;
|
||||
}
|
||||
|
||||
inline static
|
||||
void serial_high(void) {
|
||||
SERIAL_PIN_PORT |= SERIAL_PIN_MASK;
|
||||
}
|
||||
|
||||
void serial_master_init(void) {
|
||||
serial_output();
|
||||
serial_high();
|
||||
}
|
||||
|
||||
void serial_slave_init(void) {
|
||||
serial_input();
|
||||
|
||||
// Enable INT0
|
||||
EIMSK |= _BV(INT0);
|
||||
// Trigger on falling edge of INT0
|
||||
EICRA &= ~(_BV(ISC00) | _BV(ISC01));
|
||||
}
|
||||
|
||||
// Used by the master to synchronize timing with the slave.
|
||||
static
|
||||
void sync_recv(void) {
|
||||
serial_input();
|
||||
// This shouldn't hang if the slave disconnects because the
|
||||
// serial line will float to high if the slave does disconnect.
|
||||
while (!serial_read_pin());
|
||||
serial_delay();
|
||||
}
|
||||
|
||||
// Used by the slave to send a synchronization signal to the master.
|
||||
static
|
||||
void sync_send(void) {
|
||||
serial_output();
|
||||
|
||||
serial_low();
|
||||
serial_delay();
|
||||
|
||||
serial_high();
|
||||
}
|
||||
|
||||
// Reads a byte from the serial line
|
||||
static
|
||||
uint8_t serial_read_byte(void) {
|
||||
uint8_t byte = 0;
|
||||
serial_input();
|
||||
for ( uint8_t i = 0; i < 8; ++i) {
|
||||
byte = (byte << 1) | serial_read_pin();
|
||||
serial_delay();
|
||||
_delay_us(1);
|
||||
}
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
// Sends a byte with MSB ordering
|
||||
static
|
||||
void serial_write_byte(uint8_t data) {
|
||||
uint8_t b = 8;
|
||||
serial_output();
|
||||
while( b-- ) {
|
||||
if(data & (1 << b)) {
|
||||
serial_high();
|
||||
} else {
|
||||
serial_low();
|
||||
}
|
||||
serial_delay();
|
||||
}
|
||||
}
|
||||
|
||||
// interrupt handle to be used by the slave device
|
||||
ISR(SERIAL_PIN_INTERRUPT) {
|
||||
sync_send();
|
||||
|
||||
uint8_t checksum = 0;
|
||||
for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) {
|
||||
serial_write_byte(serial_slave_buffer[i]);
|
||||
sync_send();
|
||||
checksum += serial_slave_buffer[i];
|
||||
}
|
||||
serial_write_byte(checksum);
|
||||
sync_send();
|
||||
|
||||
// wait for the sync to finish sending
|
||||
serial_delay();
|
||||
|
||||
// read the middle of pulses
|
||||
_delay_us(SERIAL_DELAY/2);
|
||||
|
||||
uint8_t checksum_computed = 0;
|
||||
for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) {
|
||||
serial_master_buffer[i] = serial_read_byte();
|
||||
sync_send();
|
||||
checksum_computed += serial_master_buffer[i];
|
||||
}
|
||||
uint8_t checksum_received = serial_read_byte();
|
||||
sync_send();
|
||||
|
||||
serial_input(); // end transaction
|
||||
|
||||
if ( checksum_computed != checksum_received ) {
|
||||
status |= SLAVE_DATA_CORRUPT;
|
||||
} else {
|
||||
status &= ~SLAVE_DATA_CORRUPT;
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
bool serial_slave_DATA_CORRUPT(void) {
|
||||
return status & SLAVE_DATA_CORRUPT;
|
||||
}
|
||||
|
||||
// Copies the serial_slave_buffer to the master and sends the
|
||||
// serial_master_buffer to the slave.
|
||||
//
|
||||
// Returns:
|
||||
// 0 => no error
|
||||
// 1 => slave did not respond
|
||||
int serial_update_buffers(void) {
|
||||
// this code is very time dependent, so we need to disable interrupts
|
||||
cli();
|
||||
|
||||
// signal to the slave that we want to start a transaction
|
||||
serial_output();
|
||||
serial_low();
|
||||
_delay_us(1);
|
||||
|
||||
// wait for the slaves response
|
||||
serial_input();
|
||||
serial_high();
|
||||
_delay_us(SERIAL_DELAY);
|
||||
|
||||
// check if the slave is present
|
||||
if (serial_read_pin()) {
|
||||
// slave failed to pull the line low, assume not present
|
||||
sei();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// if the slave is present syncronize with it
|
||||
sync_recv();
|
||||
|
||||
uint8_t checksum_computed = 0;
|
||||
// receive data from the slave
|
||||
for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) {
|
||||
serial_slave_buffer[i] = serial_read_byte();
|
||||
sync_recv();
|
||||
checksum_computed += serial_slave_buffer[i];
|
||||
}
|
||||
uint8_t checksum_received = serial_read_byte();
|
||||
sync_recv();
|
||||
|
||||
if (checksum_computed != checksum_received) {
|
||||
sei();
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t checksum = 0;
|
||||
// send data to the slave
|
||||
for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) {
|
||||
serial_write_byte(serial_master_buffer[i]);
|
||||
sync_recv();
|
||||
checksum += serial_master_buffer[i];
|
||||
}
|
||||
serial_write_byte(checksum);
|
||||
sync_recv();
|
||||
|
||||
// always, release the line when not in use
|
||||
serial_output();
|
||||
serial_high();
|
||||
|
||||
sei();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,26 +0,0 @@
|
||||
#ifndef MY_SERIAL_H
|
||||
#define MY_SERIAL_H
|
||||
|
||||
#include "config.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
/* TODO: some defines for interrupt setup */
|
||||
#define SERIAL_PIN_DDR DDRD
|
||||
#define SERIAL_PIN_PORT PORTD
|
||||
#define SERIAL_PIN_INPUT PIND
|
||||
#define SERIAL_PIN_MASK _BV(PD0)
|
||||
#define SERIAL_PIN_INTERRUPT INT0_vect
|
||||
|
||||
#define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2
|
||||
#define SERIAL_MASTER_BUFFER_LENGTH 1
|
||||
|
||||
// Buffers for master - slave communication
|
||||
extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH];
|
||||
extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH];
|
||||
|
||||
void serial_master_init(void);
|
||||
void serial_slave_init(void);
|
||||
int serial_update_buffers(void);
|
||||
bool serial_slave_data_corrupt(void);
|
||||
|
||||
#endif
|
@@ -1,84 +0,0 @@
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include <avr/eeprom.h>
|
||||
#include "split_util.h"
|
||||
#include "matrix.h"
|
||||
#include "keyboard.h"
|
||||
#include "config.h"
|
||||
|
||||
#ifdef USE_I2C
|
||||
# include "i2c.h"
|
||||
#else
|
||||
# include "serial.h"
|
||||
#endif
|
||||
|
||||
volatile bool isLeftHand = true;
|
||||
|
||||
static void setup_handedness(void) {
|
||||
#ifdef EE_HANDS
|
||||
isLeftHand = eeprom_read_byte(EECONFIG_HANDEDNESS);
|
||||
#else
|
||||
// I2C_MASTER_RIGHT is deprecated, use MASTER_RIGHT instead, since this works for both serial and i2c
|
||||
#if defined(I2C_MASTER_RIGHT) || defined(MASTER_RIGHT)
|
||||
isLeftHand = !has_usb();
|
||||
#else
|
||||
isLeftHand = has_usb();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
static void keyboard_master_setup(void) {
|
||||
#ifdef USE_I2C
|
||||
i2c_master_init();
|
||||
#ifdef SSD1306OLED
|
||||
matrix_master_OLED_init ();
|
||||
#endif
|
||||
#else
|
||||
serial_master_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void keyboard_slave_setup(void) {
|
||||
#ifdef USE_I2C
|
||||
i2c_slave_init(SLAVE_I2C_ADDRESS);
|
||||
#else
|
||||
serial_slave_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool has_usb(void) {
|
||||
USBCON |= (1 << OTGPADE); //enables VBUS pad
|
||||
_delay_us(5);
|
||||
return (USBSTA & (1<<VBUS)); //checks state of VBUS
|
||||
}
|
||||
|
||||
void split_keyboard_setup(void) {
|
||||
setup_handedness();
|
||||
|
||||
if (has_usb()) {
|
||||
keyboard_master_setup();
|
||||
} else {
|
||||
keyboard_slave_setup();
|
||||
}
|
||||
sei();
|
||||
}
|
||||
|
||||
void keyboard_slave_loop(void) {
|
||||
matrix_init();
|
||||
|
||||
while (1) {
|
||||
matrix_slave_scan();
|
||||
}
|
||||
}
|
||||
|
||||
// this code runs before the usb and keyboard is initialized
|
||||
void matrix_setup(void) {
|
||||
split_keyboard_setup();
|
||||
|
||||
if (!has_usb()) {
|
||||
keyboard_slave_loop();
|
||||
}
|
||||
}
|
@@ -1,20 +0,0 @@
|
||||
#ifndef SPLIT_KEYBOARD_UTIL_H
|
||||
#define SPLIT_KEYBOARD_UTIL_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "eeconfig.h"
|
||||
|
||||
#define SLAVE_I2C_ADDRESS 0x32
|
||||
|
||||
extern volatile bool isLeftHand;
|
||||
|
||||
// slave version of matix scan, defined in matrix.c
|
||||
void matrix_slave_scan(void);
|
||||
|
||||
void split_keyboard_setup(void);
|
||||
bool has_usb(void);
|
||||
void keyboard_slave_loop(void);
|
||||
|
||||
void matrix_master_OLED_init (void);
|
||||
|
||||
#endif
|
@@ -32,7 +32,7 @@ extern uint8_t is_master;
|
||||
#define _DVORAK 2
|
||||
#define _LOWER 3
|
||||
#define _RAISE 4
|
||||
#define _ADJUST 6
|
||||
#define _ADJUST 16
|
||||
|
||||
enum custom_keycodes {
|
||||
QWERTY = SAFE_RANGE,
|
||||
@@ -513,12 +513,6 @@ void music_scale_user(void)
|
||||
#ifdef SSD1306OLED
|
||||
|
||||
void matrix_scan_user(void) {
|
||||
static int scan_count = 0;
|
||||
if( scan_count == 2 ) {
|
||||
rgblight_enable();
|
||||
rgblight_mode(35);
|
||||
}
|
||||
if( scan_count < 3 ) scan_count ++;
|
||||
iota_gfx_task(); // this is what updates the display continuously
|
||||
}
|
||||
|
||||
|
@@ -23,15 +23,8 @@
|
||||
#include "debug.h"
|
||||
#include "led_tables.h"
|
||||
|
||||
#ifndef RGBLIGHT_LIMIT_VAL
|
||||
#define RGBLIGHT_LIMIT_VAL 255
|
||||
#endif
|
||||
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||
|
||||
__attribute__ ((weak))
|
||||
const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5};
|
||||
const uint16_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {1024, 20, 10, 5}; //modify for led_test
|
||||
__attribute__ ((weak))
|
||||
const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[] PROGMEM = {120, 60, 30};
|
||||
__attribute__ ((weak))
|
||||
@@ -42,10 +35,9 @@ __attribute__ ((weak))
|
||||
const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {127, 63, 31};
|
||||
__attribute__ ((weak))
|
||||
const uint16_t RGBLED_GRADIENT_RANGES[] PROGMEM = {360, 240, 180, 120, 90};
|
||||
__attribute__ ((weak))
|
||||
const uint16_t RGBLED_RGBCYCLIC_INTERVALS[] PROGMEM = {1024};
|
||||
|
||||
rgblight_config_t rgblight_config;
|
||||
rgblight_config_t inmem_config;
|
||||
|
||||
LED_TYPE led[RGBLED_NUM];
|
||||
uint8_t rgblight_inited = 0;
|
||||
@@ -54,9 +46,11 @@ bool rgblight_timer_enabled = false;
|
||||
void sethsv(uint16_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1) {
|
||||
uint8_t r = 0, g = 0, b = 0, base, color;
|
||||
|
||||
if (val > RGBLIGHT_LIMIT_VAL) {
|
||||
#ifdef RGBLIGHT_LIMIT_VAL
|
||||
if (val > RGBLIGHT_LIMIT_VAL) {
|
||||
val=RGBLIGHT_LIMIT_VAL; // limit the val
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sat == 0) { // Acromatic color (gray). Hue doesn't mind.
|
||||
r = val;
|
||||
@@ -125,8 +119,7 @@ void eeconfig_update_rgblight_default(void) {
|
||||
rgblight_config.mode = 1;
|
||||
rgblight_config.hue = 0;
|
||||
rgblight_config.sat = 255;
|
||||
rgblight_config.val = RGBLIGHT_LIMIT_VAL;
|
||||
rgblight_config.speed = 0;
|
||||
rgblight_config.val = 255;
|
||||
eeconfig_update_rgblight(rgblight_config.raw);
|
||||
}
|
||||
void eeconfig_debug_rgblight(void) {
|
||||
@@ -136,7 +129,6 @@ void eeconfig_debug_rgblight(void) {
|
||||
dprintf("rgblight_config.hue = %d\n", rgblight_config.hue);
|
||||
dprintf("rgblight_config.sat = %d\n", rgblight_config.sat);
|
||||
dprintf("rgblight_config.val = %d\n", rgblight_config.val);
|
||||
dprintf("rgblight_config.speed = %d\n", rgblight_config.speed);
|
||||
}
|
||||
|
||||
void rgblight_init(void) {
|
||||
@@ -162,7 +154,7 @@ void rgblight_init(void) {
|
||||
#endif
|
||||
|
||||
if (rgblight_config.enable) {
|
||||
rgblight_mode_noeeprom(rgblight_config.mode);
|
||||
rgblight_mode(rgblight_config.mode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,7 +211,7 @@ uint32_t rgblight_get_mode(void) {
|
||||
return rgblight_config.mode;
|
||||
}
|
||||
|
||||
void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {
|
||||
void rgblight_mode(uint8_t mode) {
|
||||
if (!rgblight_config.enable) {
|
||||
return;
|
||||
}
|
||||
@@ -230,18 +222,13 @@ void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {
|
||||
} else {
|
||||
rgblight_config.mode = mode;
|
||||
}
|
||||
if (write_to_eeprom) {
|
||||
eeconfig_update_rgblight(rgblight_config.raw);
|
||||
xprintf("rgblight mode [EEPROM]: %u\n", rgblight_config.mode);
|
||||
} else {
|
||||
xprintf("rgblight mode [NOEEPROM]: %u\n", rgblight_config.mode);
|
||||
}
|
||||
eeconfig_update_rgblight(rgblight_config.raw);
|
||||
xprintf("rgblight mode: %u\n", rgblight_config.mode);
|
||||
if (rgblight_config.mode == 1) {
|
||||
#ifdef RGBLIGHT_ANIMATIONS
|
||||
rgblight_timer_disable();
|
||||
#endif
|
||||
} else if ((rgblight_config.mode >= 2 && rgblight_config.mode <= 24) ||
|
||||
rgblight_config.mode == 35 ) {
|
||||
} else if (rgblight_config.mode >= 2 && rgblight_config.mode <= 24) {
|
||||
// MODE 2-5, breathing
|
||||
// MODE 6-8, rainbow mood
|
||||
// MODE 9-14, rainbow swirl
|
||||
@@ -249,7 +236,6 @@ void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {
|
||||
// MODE 21-23, knight
|
||||
// MODE 24, xmas
|
||||
// MODE 25-34, static rainbow
|
||||
// MODE 35 RGB cyclic
|
||||
|
||||
#ifdef RGBLIGHT_ANIMATIONS
|
||||
rgblight_timer_enable();
|
||||
@@ -261,20 +247,11 @@ void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {
|
||||
rgblight_timer_disable();
|
||||
#endif
|
||||
}
|
||||
rgblight_sethsv_noeeprom(rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
|
||||
rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
|
||||
}
|
||||
|
||||
void rgblight_mode(uint8_t mode) {
|
||||
rgblight_mode_eeprom_helper(mode, true);
|
||||
}
|
||||
|
||||
void rgblight_mode_noeeprom(uint8_t mode) {
|
||||
rgblight_mode_eeprom_helper(mode, false);
|
||||
}
|
||||
|
||||
|
||||
void rgblight_toggle(void) {
|
||||
xprintf("rgblight toggle [EEPROM]: rgblight_config.enable = %u\n", !rgblight_config.enable);
|
||||
xprintf("rgblight toggle: rgblight_config.enable = %u\n", !rgblight_config.enable);
|
||||
if (rgblight_config.enable) {
|
||||
rgblight_disable();
|
||||
}
|
||||
@@ -283,34 +260,17 @@ void rgblight_toggle(void) {
|
||||
}
|
||||
}
|
||||
|
||||
void rgblight_toggle_noeeprom(void) {
|
||||
xprintf("rgblight toggle [NOEEPROM]: rgblight_config.enable = %u\n", !rgblight_config.enable);
|
||||
if (rgblight_config.enable) {
|
||||
rgblight_disable_noeeprom();
|
||||
}
|
||||
else {
|
||||
rgblight_enable_noeeprom();
|
||||
}
|
||||
}
|
||||
|
||||
void rgblight_enable(void) {
|
||||
rgblight_config.enable = 1;
|
||||
// No need to update EEPROM here. rgblight_mode() will do that, actually
|
||||
//eeconfig_update_rgblight(rgblight_config.raw);
|
||||
xprintf("rgblight enable [EEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable);
|
||||
eeconfig_update_rgblight(rgblight_config.raw);
|
||||
xprintf("rgblight enable: rgblight_config.enable = %u\n", rgblight_config.enable);
|
||||
rgblight_mode(rgblight_config.mode);
|
||||
}
|
||||
|
||||
void rgblight_enable_noeeprom(void) {
|
||||
rgblight_config.enable = 1;
|
||||
xprintf("rgblight enable [NOEEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable);
|
||||
rgblight_mode_noeeprom(rgblight_config.mode);
|
||||
}
|
||||
|
||||
void rgblight_disable(void) {
|
||||
rgblight_config.enable = 0;
|
||||
eeconfig_update_rgblight(rgblight_config.raw);
|
||||
xprintf("rgblight disable [EEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable);
|
||||
xprintf("rgblight disable: rgblight_config.enable = %u\n", rgblight_config.enable);
|
||||
#ifdef RGBLIGHT_ANIMATIONS
|
||||
rgblight_timer_disable();
|
||||
#endif
|
||||
@@ -318,29 +278,6 @@ void rgblight_disable(void) {
|
||||
rgblight_set();
|
||||
}
|
||||
|
||||
void rgblight_disable_noeeprom(void) {
|
||||
rgblight_config.enable = 0;
|
||||
xprintf("rgblight disable [noEEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable);
|
||||
#ifdef RGBLIGHT_ANIMATIONS
|
||||
rgblight_timer_disable();
|
||||
#endif
|
||||
_delay_ms(50);
|
||||
rgblight_set();
|
||||
}
|
||||
|
||||
|
||||
// Deals with the messy details of incrementing an integer
|
||||
uint8_t increment( uint8_t value, uint8_t step, uint8_t min, uint8_t max ) {
|
||||
int16_t new_value = value;
|
||||
new_value += step;
|
||||
return MIN( MAX( new_value, min ), max );
|
||||
}
|
||||
|
||||
uint8_t decrement( uint8_t value, uint8_t step, uint8_t min, uint8_t max ) {
|
||||
int16_t new_value = value;
|
||||
new_value -= step;
|
||||
return MIN( MAX( new_value, min ), max );
|
||||
}
|
||||
|
||||
void rgblight_increase_hue(void) {
|
||||
uint16_t hue;
|
||||
@@ -376,8 +313,8 @@ void rgblight_decrease_sat(void) {
|
||||
}
|
||||
void rgblight_increase_val(void) {
|
||||
uint8_t val;
|
||||
if (rgblight_config.val + RGBLIGHT_VAL_STEP > RGBLIGHT_LIMIT_VAL) {
|
||||
val = RGBLIGHT_LIMIT_VAL;
|
||||
if (rgblight_config.val + RGBLIGHT_VAL_STEP > 255) {
|
||||
val = 255;
|
||||
} else {
|
||||
val = rgblight_config.val + RGBLIGHT_VAL_STEP;
|
||||
}
|
||||
@@ -392,32 +329,24 @@ void rgblight_decrease_val(void) {
|
||||
}
|
||||
rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, val);
|
||||
}
|
||||
void rgblight_increase_speed(void) {
|
||||
rgblight_config.speed = increment( rgblight_config.speed, 1, 0, 3 );
|
||||
eeconfig_update_rgblight(rgblight_config.raw);//EECONFIG needs to be increased to support this
|
||||
}
|
||||
|
||||
void rgblight_decrease_speed(void) {
|
||||
rgblight_config.speed = decrement( rgblight_config.speed, 1, 0, 3 );
|
||||
eeconfig_update_rgblight(rgblight_config.raw);//EECONFIG needs to be increased to support this
|
||||
}
|
||||
|
||||
void rgblight_sethsv_noeeprom_old(uint16_t hue, uint8_t sat, uint8_t val) {
|
||||
void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val) {
|
||||
inmem_config.raw = rgblight_config.raw;
|
||||
if (rgblight_config.enable) {
|
||||
LED_TYPE tmp_led;
|
||||
sethsv(hue, sat, val, &tmp_led);
|
||||
inmem_config.hue = hue;
|
||||
inmem_config.sat = sat;
|
||||
inmem_config.val = val;
|
||||
// dprintf("rgblight set hue [MEMORY]: %u,%u,%u\n", inmem_config.hue, inmem_config.sat, inmem_config.val);
|
||||
rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b);
|
||||
}
|
||||
}
|
||||
|
||||
void rgblight_sethsv_eeprom_helper(uint16_t hue, uint8_t sat, uint8_t val, bool write_to_eeprom) {
|
||||
void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val) {
|
||||
if (rgblight_config.enable) {
|
||||
if (rgblight_config.mode == 1) {
|
||||
// same static color
|
||||
LED_TYPE tmp_led;
|
||||
sethsv(hue, sat, val, &tmp_led);
|
||||
rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b);
|
||||
rgblight_sethsv_noeeprom(hue, sat, val);
|
||||
} else {
|
||||
// all LEDs in same color
|
||||
if (rgblight_config.mode >= 2 && rgblight_config.mode <= 5) {
|
||||
@@ -442,23 +371,11 @@ void rgblight_sethsv_eeprom_helper(uint16_t hue, uint8_t sat, uint8_t val, bool
|
||||
rgblight_config.hue = hue;
|
||||
rgblight_config.sat = sat;
|
||||
rgblight_config.val = val;
|
||||
if (write_to_eeprom) {
|
||||
eeconfig_update_rgblight(rgblight_config.raw);
|
||||
xprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
|
||||
} else {
|
||||
xprintf("rgblight set hsv [NOEEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
|
||||
}
|
||||
eeconfig_update_rgblight(rgblight_config.raw);
|
||||
xprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
|
||||
}
|
||||
}
|
||||
|
||||
void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val) {
|
||||
rgblight_sethsv_eeprom_helper(hue, sat, val, true);
|
||||
}
|
||||
|
||||
void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val) {
|
||||
rgblight_sethsv_eeprom_helper(hue, sat, val, false);
|
||||
}
|
||||
|
||||
uint16_t rgblight_get_hue(void) {
|
||||
return rgblight_config.hue;
|
||||
}
|
||||
@@ -563,11 +480,18 @@ void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b) {
|
||||
}
|
||||
|
||||
void rgblight_task(void) {
|
||||
if (rgblight_inited == 1) { //modify for led_test
|
||||
/* first call */
|
||||
rgblight_inited = 2;
|
||||
rgblight_enable();
|
||||
rgblight_mode(2);
|
||||
}
|
||||
if (rgblight_timer_enabled) {
|
||||
// mode = 1, static light, do nothing here
|
||||
if (rgblight_config.mode >= 2 && rgblight_config.mode <= 5) {
|
||||
// mode = 2 to 5, breathing mode
|
||||
rgblight_effect_breathing(rgblight_config.mode - 2);
|
||||
#if 0
|
||||
} else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 8) {
|
||||
// mode = 6 to 8, rainbow mood mod
|
||||
rgblight_effect_rainbow_mood(rgblight_config.mode - 6);
|
||||
@@ -583,9 +507,7 @@ void rgblight_task(void) {
|
||||
} else if (rgblight_config.mode == 24) {
|
||||
// mode = 24, christmas mode
|
||||
rgblight_effect_christmas();
|
||||
} else if (rgblight_config.mode == 35) {
|
||||
// mode = 35, RGB cyclic
|
||||
rgblight_effect_rgbcyclic();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -594,19 +516,19 @@ void rgblight_task(void) {
|
||||
void rgblight_effect_breathing(uint8_t interval) {
|
||||
static uint8_t pos = 0;
|
||||
static uint16_t last_timer = 0;
|
||||
float val;
|
||||
|
||||
if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_BREATHING_INTERVALS[interval])) {
|
||||
if (timer_elapsed(last_timer) < pgm_read_word(&RGBLED_BREATHING_INTERVALS[interval])) {//modify for led_test
|
||||
return;
|
||||
}
|
||||
last_timer = timer_read();
|
||||
|
||||
|
||||
// http://sean.voisen.org/blog/2011/10/breathing-led-with-arduino/
|
||||
val = (exp(sin((pos/255.0)*M_PI)) - RGBLIGHT_EFFECT_BREATHE_CENTER/M_E)*(RGBLIGHT_EFFECT_BREATHE_MAX/(M_E-1/M_E));
|
||||
rgblight_sethsv_noeeprom_old(rgblight_config.hue, rgblight_config.sat, val);
|
||||
pos = (pos + 1) % 256;
|
||||
//modify for led_test
|
||||
rgblight_config.hue = (pos*120)%360;
|
||||
rgblight_sethsv_noeeprom(rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
|
||||
pos = (pos + 1) % 3;
|
||||
}
|
||||
#if 0
|
||||
void rgblight_effect_rainbow_mood(uint8_t interval) {
|
||||
static uint16_t current_hue = 0;
|
||||
static uint16_t last_timer = 0;
|
||||
@@ -615,7 +537,7 @@ void rgblight_effect_rainbow_mood(uint8_t interval) {
|
||||
return;
|
||||
}
|
||||
last_timer = timer_read();
|
||||
rgblight_sethsv_noeeprom_old(current_hue, rgblight_config.sat, rgblight_config.val);
|
||||
rgblight_sethsv_noeeprom(current_hue, rgblight_config.sat, rgblight_config.val);
|
||||
current_hue = (current_hue + 1) % 360;
|
||||
}
|
||||
void rgblight_effect_rainbow_swirl(uint8_t interval) {
|
||||
@@ -740,24 +662,5 @@ void rgblight_effect_christmas(void) {
|
||||
}
|
||||
rgblight_set();
|
||||
}
|
||||
|
||||
void rgblight_effect_rgbcyclic(void) {
|
||||
static uint8_t pos = 0;
|
||||
static uint16_t last_timer = 0;
|
||||
uint8_t g; uint8_t r; uint8_t b;
|
||||
|
||||
if (timer_elapsed(last_timer) < pgm_read_word(&RGBLED_RGBCYCLIC_INTERVALS[0])) {
|
||||
return;
|
||||
}
|
||||
last_timer = timer_read();
|
||||
g = r = b = 0;
|
||||
switch( pos ) {
|
||||
case 0: r = RGBLIGHT_LIMIT_VAL; break;
|
||||
case 1: g = RGBLIGHT_LIMIT_VAL; break;
|
||||
case 2: b = RGBLIGHT_LIMIT_VAL; break;
|
||||
}
|
||||
rgblight_setrgb(r, g, b);
|
||||
pos = (pos + 1) % 3;
|
||||
}
|
||||
|
||||
#endif /* 0 */
|
||||
#endif /* RGBLIGHT_ANIMATIONS */
|
||||
|
@@ -17,7 +17,7 @@
|
||||
#define RGBLIGHT_H
|
||||
|
||||
#ifdef RGBLIGHT_ANIMATIONS
|
||||
#define RGBLIGHT_MODES 35
|
||||
#define RGBLIGHT_MODES 5
|
||||
#else
|
||||
#define RGBLIGHT_MODES 1
|
||||
#endif
|
||||
@@ -74,16 +74,14 @@
|
||||
#include "ws2812.h"
|
||||
#endif
|
||||
#include "rgblight_types.h"
|
||||
#include "rgblight_list.h"
|
||||
|
||||
extern LED_TYPE led[RGBLED_NUM];
|
||||
|
||||
extern const uint8_t RGBLED_BREATHING_INTERVALS[4] PROGMEM;
|
||||
extern const uint16_t RGBLED_BREATHING_INTERVALS[4] PROGMEM; //modify for led_test
|
||||
extern const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[3] PROGMEM;
|
||||
extern const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[3] PROGMEM;
|
||||
extern const uint8_t RGBLED_SNAKE_INTERVALS[3] PROGMEM;
|
||||
extern const uint8_t RGBLED_KNIGHT_INTERVALS[3] PROGMEM;
|
||||
extern const uint16_t RGBLED_RGBCYCLIC_INTERVALS[1] PROGMEM;
|
||||
|
||||
typedef union {
|
||||
uint32_t raw;
|
||||
@@ -93,7 +91,6 @@ typedef union {
|
||||
uint16_t hue :9;
|
||||
uint8_t sat :8;
|
||||
uint8_t val :8;
|
||||
uint8_t speed :8;//EECONFIG needs to be increased to support this
|
||||
};
|
||||
} rgblight_config_t;
|
||||
|
||||
@@ -115,8 +112,6 @@ void rgblight_increase_sat(void);
|
||||
void rgblight_decrease_sat(void);
|
||||
void rgblight_increase_val(void);
|
||||
void rgblight_decrease_val(void);
|
||||
void rgblight_increase_speed(void);
|
||||
void rgblight_decrease_speed(void);
|
||||
void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val);
|
||||
uint16_t rgblight_get_hue(void);
|
||||
uint8_t rgblight_get_sat(void);
|
||||
@@ -130,21 +125,9 @@ void eeconfig_update_rgblight(uint32_t val);
|
||||
void eeconfig_update_rgblight_default(void);
|
||||
void eeconfig_debug_rgblight(void);
|
||||
|
||||
void rgb_matrix_increase(void);
|
||||
void rgb_matrix_decrease(void);
|
||||
|
||||
void sethsv(uint16_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1);
|
||||
void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1);
|
||||
|
||||
void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val);
|
||||
void rgblight_mode_noeeprom(uint8_t mode);
|
||||
void rgblight_toggle_noeeprom(void);
|
||||
void rgblight_enable_noeeprom(void);
|
||||
void rgblight_disable_noeeprom(void);
|
||||
|
||||
void rgblight_sethsv_eeprom_helper(uint16_t hue, uint8_t sat, uint8_t val, bool write_to_eeprom);
|
||||
void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom);
|
||||
|
||||
|
||||
#define EZ_RGB(val) rgblight_show_solid_color((val >> 16) & 0xFF, (val >> 8) & 0xFF, val & 0xFF)
|
||||
void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b);
|
||||
@@ -161,6 +144,5 @@ void rgblight_effect_rainbow_swirl(uint8_t interval);
|
||||
void rgblight_effect_snake(uint8_t interval);
|
||||
void rgblight_effect_knight(uint8_t interval);
|
||||
void rgblight_effect_christmas(void);
|
||||
void rgblight_effect_rgbcyclic(void);
|
||||
|
||||
#endif
|
||||
|
@@ -1 +0,0 @@
|
||||
#define USB_MAX_POWER_CONSUMPTION 100
|
@@ -1,84 +0,0 @@
|
||||
#include QMK_KEYBOARD_H
|
||||
#include "keymap.h"
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
/* Layer 0: Default Layer
|
||||
* ,-----------------------------------------------------------.
|
||||
* |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Del|Bsp|
|
||||
* |-----------------------------------------------------------|
|
||||
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]|Enter |
|
||||
* |------------------------------------------------------` |
|
||||
* |SrCtl | A| S| D| F| G| H| J| K| L| ;| '| \| |
|
||||
* |-----------------------------------------------------------|
|
||||
* |Shift | Z| X| C| V| B| N| M| ,| .| /| `|Up |Shi|
|
||||
* |-----------------------------------------------------------|
|
||||
* |NCt|| #|Alt|CmT|CmT| LyrSpc |CGv|Iso|Gui|CSL||Rig|Dow|Lef|
|
||||
* `-----------------------------------------------------------'
|
||||
*/
|
||||
[0] = LAYOUT_JP(
|
||||
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0,KC_MINS, KC_EQL, KC_DEL,KC_BSPC,
|
||||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC,KC_RBRC,
|
||||
SRCH_CTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN,KC_QUOT,KC_NUHS, KC_ENT,
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M,KC_COMM, KC_DOT, KC_SLSH,KC_NUBS, KC_UP, KC_RSFT,
|
||||
NC_CTL, HSH_TLD,KC_LALT,CMD_TAB_CMD,CMD_TAB_CMD, LT(2, KC_SPC) , CMD_GRV_CMD, ISO_COUNTRY_CODE,KC_RGUI, CMD_SFT_L, KC_LEFT,KC_DOWN,KC_RGHT
|
||||
),
|
||||
|
||||
/* Layer 1: iPad mode (Fixed)
|
||||
* ,-----------------------------------------------------------.
|
||||
* | | | | | | | | | | | | | | | |
|
||||
* |-----------------------------------------------------------|
|
||||
* | | | | | | | | | | | | | | |
|
||||
* |------------------------------------------------------` |
|
||||
* |CmdSpc| | | | | | | | | | | | | |
|
||||
* |-----------------------------------------------------------|
|
||||
* | | | | | | | | | | | | | | |
|
||||
* |-----------------------------------------------------------|
|
||||
* | || ~| |CAD| | |CmH| | | || | | |
|
||||
* `-----------------------------------------------------------'
|
||||
*/
|
||||
[1] = LAYOUT_JP(
|
||||
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
|
||||
KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS,
|
||||
CMD_SPC,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
|
||||
KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
|
||||
KC_TRNS, KC_TRNS,KC_TRNS,CMD_ALT_D,KC_TRNS, KC_TRNS ,CMD_H,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS, KC_TRNS
|
||||
),
|
||||
|
||||
/* Layer 2: HHKB mode (Space)
|
||||
* ,-----------------------------------------------------------.
|
||||
* |Pwr| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Ins|Del|
|
||||
* |-----------------------------------------------------------|
|
||||
* |Caps |DL0|DL1| | | | | |Psc|Slk|Pus|Up | | |
|
||||
* |------------------------------------------------------` |
|
||||
* | |VoD|VoU|Mut| | | |Bsp|Del|CSL|Lef|Rig| | |
|
||||
* |-----------------------------------------------------------|
|
||||
* | | | |CAC| | | | | | |Dow| |PgU| |
|
||||
* |-----------------------------------------------------------|
|
||||
* | || ~| | | | | | | | ||Hom|PgD|End|
|
||||
* `-----------------------------------------------------------'
|
||||
*/
|
||||
[2] = LAYOUT_JP(
|
||||
KC_PWR, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_INS,KC_DEL,
|
||||
KC_CAPS, DF(0), DF(1),KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_PSCR,KC_SLCK,KC_PAUS, KC_UP,KC_TRNS,
|
||||
KC_TRNS, KC_VOLD,KC_VOLU,KC_MUTE,KC_TRNS,KC_TRNS,KC_TRNS,KC_BSPC, KC_DEL,CMD_SFT_L,KC_LEFT,KC_RGHT,KC_TRNS,KC_PENT,
|
||||
KC_TRNS, KC_TRNS,KC_TRNS,CMD_ALT_C,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_DOWN,KC_TRNS,KC_PGUP,KC_TRNS,
|
||||
KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS ,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_HOME,KC_PGDN, KC_END
|
||||
),
|
||||
};
|
||||
|
||||
bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
|
||||
switch(keycode) {
|
||||
case CMD_SPC:
|
||||
mod_or_mod_with_macro(record, KC_LGUI, " ");
|
||||
break;
|
||||
case CMD_H:
|
||||
mod_or_mod_with_macro(record, KC_RGUI, "H");
|
||||
break;
|
||||
case CMD_ALT_D:
|
||||
mod_or_mod_with_macro(record, KC_LGUI, SS_LALT("D"));
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
@@ -1,7 +0,0 @@
|
||||
#include "dhertz.h"
|
||||
|
||||
enum dhertz_keycodes {
|
||||
CMD_SPC = NEW_SAFE_RANGE,
|
||||
CMD_H,
|
||||
CMD_ALT_D,
|
||||
};
|
@@ -1,2 +0,0 @@
|
||||
OPT_DEFS += -DHHKB_JP
|
||||
|
@@ -33,7 +33,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifdef RGBLIGHT_ENABLE
|
||||
#undef RGBLED_NUM
|
||||
#define RGBLED_NUM 18 // Number of LEDs
|
||||
#define RGBLED_NUM 16 // Number of LEDs
|
||||
#define RGBLIGHT_ANIMATIONS
|
||||
#define RGBLIGHT_HUE_STEP 12
|
||||
#define RGBLIGHT_SAT_STEP 12
|
||||
@@ -58,13 +58,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define PRODUCT Drashna Hacked Iris Rev.2
|
||||
#endif
|
||||
|
||||
#define SHFT_LED1 6
|
||||
#define SHFT_LED2 11
|
||||
|
||||
#define CTRL_LED1 7
|
||||
#define CTRL_LED2 10
|
||||
|
||||
#define GUI_LED1 8
|
||||
#define GUI_LED2 9
|
||||
|
||||
#endif
|
||||
|
@@ -2,6 +2,15 @@
|
||||
#include QMK_KEYBOARD_H
|
||||
#include "drashna.h"
|
||||
|
||||
#ifdef INDICATOR_LIGHTS
|
||||
extern userspace_config_t userspace_config;
|
||||
|
||||
uint8_t last_mod;
|
||||
uint8_t last_led;
|
||||
uint8_t last_osm;
|
||||
bool has_mods_changed = false;
|
||||
#endif
|
||||
|
||||
#define KC_ALAP ALT_T(KC_APP)
|
||||
#define KC_OSLG OSM(MOD_LGUI)
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
@@ -46,7 +55,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
|
||||
[_LOWER] = LAYOUT_wrapper(
|
||||
_______, _________________FUNC_LEFT_________________, _________________FUNC_RIGHT________________, _______,
|
||||
KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, _______,
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
|
||||
_______, _______, _______, _______, _______, _______, _______, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE,
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, _______,
|
||||
_______, _______, _______, _______, _______, _______
|
||||
@@ -54,7 +63,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
|
||||
[_RAISE] = LAYOUT_wrapper(
|
||||
_______, _________________FUNC_LEFT_________________, _________________FUNC_RIGHT________________, _______,
|
||||
KC_GRV, ________________NUMBER_LEFT________________, ________________NUMBER_RIGHT_______________, _______,
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
|
||||
_______, _______, _______, _______, _______, _______, _______, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS,
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_PGUP, KC_END, _______,
|
||||
_______, _______, _______, _______, _______, _______
|
||||
@@ -62,28 +71,93 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
|
||||
[_ADJUST] = LAYOUT_wrapper(
|
||||
KC_MAKE, _______, _______, _______, _______, _______, KC_SEC1, KC_SEC2, KC_SEC3, KC_SEC4, KC_SEC5, KC_RST,
|
||||
VRSN, RGB_MOD, RGB_HUI, RGB_SAI, RGB_VAI, RGB_TOG, KC_NUKE, _______, _______, _______, _______, EPRM,
|
||||
_______, _______, CK_TOGG, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, WORKMAN, TG(_MODS),
|
||||
_______, RGB_SMOD,RGB_HUD, RGB_SAD, RGB_VAD, KC_RGB_T,_______, _______, MG_NKRO, KC_MUTE, KC_VOLD, KC_VOLU, KC_MNXT, KC_MPLY,
|
||||
VRSN, RGB_MOD, RGB_HUI, RGB_SAI, RGB_VAI, RGB_TOG, _______, _______, _______, _______, _______, EPRM,
|
||||
_______, _______, CK_TOGG, AU_ON, AU_OFF, AG_NORM, AG_SWAP, KC_QWERTY, KC_COLEMAK, KC_DVORAK, KC_WORKMAN, _______,
|
||||
TG(_MODS),RGB_SMOD,RGB_HUD,RGB_SAD, RGB_VAD, KC_RGB_T,_______, _______, MG_NKRO, KC_MUTE, KC_VOLD, KC_VOLU, KC_MNXT, KC_MPLY,
|
||||
_______, _______, _______, _______, _______, _______
|
||||
)
|
||||
|
||||
};
|
||||
|
||||
|
||||
bool indicator_is_this_led_used(uint8_t index) {
|
||||
switch (index) {
|
||||
void matrix_init_keymap(void) {
|
||||
#ifdef INDICATOR_LIGHTS
|
||||
case SHFT_LED1:
|
||||
case SHFT_LED2:
|
||||
case CTRL_LED1:
|
||||
case CTRL_LED2:
|
||||
case GUI_LED1:
|
||||
case GUI_LED2:
|
||||
return true;
|
||||
break;
|
||||
last_mod = get_mods();
|
||||
last_led = host_keyboard_leds();
|
||||
last_osm =get_oneshot_mods();
|
||||
#endif
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t layer_state_set_keymap (uint32_t state) {
|
||||
#ifdef INDICATOR_LIGHTS
|
||||
uint8_t modifiders = get_mods();
|
||||
uint8_t led_usb_state = host_keyboard_leds();
|
||||
uint8_t one_shot = get_oneshot_mods();
|
||||
|
||||
|
||||
if (modifiders & MODS_SHIFT_MASK || led_usb_state & (1<<USB_LED_CAPS_LOCK) || one_shot & MODS_SHIFT_MASK) {
|
||||
rgblight_sethsv_at(0, 255, 255, 5);
|
||||
rgblight_sethsv_at(0, 255, 255, 10);
|
||||
}
|
||||
if (modifiders & MODS_CTRL_MASK || one_shot & MODS_CTRL_MASK) {
|
||||
rgblight_sethsv_at(51, 255, 255, 6);
|
||||
rgblight_sethsv_at(51, 255, 255, 9);
|
||||
}
|
||||
if (modifiders & MODS_ALT_MASK || one_shot & MODS_ALT_MASK) {
|
||||
rgblight_sethsv_at(120, 255, 255, 7);
|
||||
rgblight_sethsv_at(120, 255, 255, 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
void matrix_scan_keymap (void) {
|
||||
|
||||
#ifdef INDICATOR_LIGHTS
|
||||
uint8_t current_mod = get_mods();
|
||||
uint8_t current_led = host_keyboard_leds();
|
||||
uint8_t current_osm =get_oneshot_mods();
|
||||
|
||||
if (last_mod == current_mod) {
|
||||
last_mod = current_mod;
|
||||
has_mods_changed = true;
|
||||
}
|
||||
if (last_led == current_led) {
|
||||
last_led = current_led;
|
||||
has_mods_changed = true;
|
||||
}
|
||||
if (last_osm == current_osm) {
|
||||
last_osm = current_osm;
|
||||
has_mods_changed = true;
|
||||
}
|
||||
|
||||
|
||||
if (userspace_config.rgb_layer_change && has_mods_changed && biton32(layer_state) == 0) {
|
||||
if (current_mod & MODS_SHIFT_MASK || current_led & (1<<USB_LED_CAPS_LOCK) || current_osm & MODS_SHIFT_MASK) {
|
||||
rgblight_sethsv_at(0, 255, 255, 5);
|
||||
rgblight_sethsv_at(0, 255, 255, 10);
|
||||
} else {
|
||||
rgblight_sethsv_default_helper(5);
|
||||
rgblight_sethsv_default_helper(10);
|
||||
}
|
||||
if (current_mod & MODS_CTRL_MASK || current_osm & MODS_CTRL_MASK) {
|
||||
rgblight_sethsv_at(51, 255, 255, 6);
|
||||
rgblight_sethsv_at(51, 255, 255, 9);
|
||||
} else {
|
||||
rgblight_sethsv_default_helper(6);
|
||||
rgblight_sethsv_default_helper(9);
|
||||
}
|
||||
if (current_mod & MODS_GUI_MASK || current_osm & MODS_GUI_MASK) {
|
||||
rgblight_sethsv_at(120, 255, 255, 7);
|
||||
rgblight_sethsv_at(120, 255, 255, 8);
|
||||
} else {
|
||||
rgblight_sethsv_default_helper(7);
|
||||
rgblight_sethsv_default_helper(8);
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@@ -7,9 +7,6 @@ TAP_DANCE_ENABLE = no
|
||||
RGBLIGHT_ENABLE = yes
|
||||
AUDIO_ENABLE = yes
|
||||
NKRO_ENABLE = yes
|
||||
BACKLIGHT_ENABLE = no
|
||||
SWAP_HANDS_ENABLE = no
|
||||
|
||||
BACKLIGHT_ENABLE = no
|
||||
SWAP_HANDS_ENABLE = yes
|
||||
INDICATOR_LIGHTS = yes
|
||||
MACROS_ENABLED = no
|
||||
RGBLIGHT_TWINKLE = yes
|
||||
|
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 Danny Nguyen <danny@keeb.io>
|
||||
|
||||
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 CONFIG_USER_H
|
||||
#define CONFIG_USER_H
|
||||
|
||||
#include "config_common.h"
|
||||
|
||||
/* Use I2C or Serial, not both */
|
||||
|
||||
#define USE_SERIAL
|
||||
#undef USE_I2C
|
||||
|
||||
/* Select hand configuration */
|
||||
|
||||
// #define MASTER_LEFT
|
||||
// #define MASTER_RIGHT
|
||||
#define EE_HANDS
|
||||
|
||||
#ifdef RGBLIGHT_ENABLE
|
||||
#undef RGBLED_NUM
|
||||
#define RGBLED_NUM 16 // Number of LEDs
|
||||
#define RGBLIGHT_ANIMATIONS
|
||||
#define RGBLIGHT_HUE_STEP 12
|
||||
#define RGBLIGHT_SAT_STEP 12
|
||||
#define RGBLIGHT_VAL_STEP 12
|
||||
#define RGBLIGHT_EFFECT_KNIGHT_LENGTH 2
|
||||
#define RGBLIGHT_EFFECT_SNAKE_LENGTH 2
|
||||
#define RGBLIGHT_EFFECT_BREATHE_CENTER 1
|
||||
|
||||
#define RGBLIGHT_LIMIT_VAL 225
|
||||
#endif // RGBLIGHT_ENABLE
|
||||
|
||||
#ifdef AUDIO_ENABLE
|
||||
#define C6_AUDIO
|
||||
#ifdef RGBLIGHT_ENABLE
|
||||
#define NO_MUSIC_MODE
|
||||
#endif //RGBLIGHT_ENABLE
|
||||
#endif //AUDIO_ENABLE
|
||||
|
||||
|
||||
#undef PRODUCT
|
||||
#ifdef KEYBOARD_iris_rev2
|
||||
#define PRODUCT Drashna Hacked Iris Rev.2
|
||||
#endif
|
||||
|
||||
#define SHFT_LED1 5
|
||||
#define SHFT_LED2 10
|
||||
|
||||
#define CTRL_LED1 6
|
||||
#define CTRL_LED2 9
|
||||
|
||||
#define GUI_LED1 7
|
||||
#define GUI_LED2 8
|
||||
|
||||
#endif
|
@@ -1,89 +0,0 @@
|
||||
|
||||
#include QMK_KEYBOARD_H
|
||||
#include "drashna.h"
|
||||
|
||||
#define KC_ALAP ALT_T(KC_APP)
|
||||
#define KC_OSLG OSM(MOD_LGUI)
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
|
||||
[_QWERTY] = LAYOUT_wrapper(
|
||||
KC_ESC, ________________NUMBER_LEFT________________, ________________NUMBER_RIGHT_______________, KC_MINS,
|
||||
KC_TAB , _________________QWERTY_L1_________________, _________________QWERTY_R1_________________, KC_BSLS,
|
||||
KC_CCCV, _________________QWERTY_L2_________________, _________________QWERTY_R2_________________, KC_QUOT,
|
||||
KC_MLSF, _________________QWERTY_L3_________________, KC_ALAP, KC_OSLG, _________________QWERTY_R3_________________, KC_MRSF,
|
||||
LT(_LOWER,KC_GRV), KC_SPC, KC_BSPC, KC_DEL, KC_ENT, RAISE
|
||||
),
|
||||
[_COLEMAK] = LAYOUT_wrapper(
|
||||
KC_ESC , ________________NUMBER_LEFT________________, ________________NUMBER_RIGHT_______________, KC_MINS,
|
||||
KC_TAB , _________________COLEMAK_L1________________, _________________COLEMAK_R1________________, KC_BSLS,
|
||||
KC_CCCV, _________________COLEMAK_L2________________, _________________COLEMAK_R2________________, KC_QUOT,
|
||||
KC_MLSF, _________________COLEMAK_L3________________, KC_ALAP, KC_OSLG, _________________COLEMAK_R3________________, KC_MRSF,
|
||||
LT(_LOWER,KC_GRV), KC_SPC, KC_BSPC, KC_DEL, KC_ENT, RAISE
|
||||
),
|
||||
[_DVORAK] = LAYOUT_wrapper(
|
||||
KC_ESC, ________________NUMBER_LEFT________________, ________________NUMBER_RIGHT_______________, KC_MINS,
|
||||
KC_TAB , _________________DVORAK_L1_________________, _________________DVORAK_R1_________________, KC_BSLS,
|
||||
KC_CCCV, _________________DVORAK_L2_________________, _________________DVORAK_R2_________________, KC_QUOT,
|
||||
KC_MLSF, _________________DVORAK_L3_________________, KC_ALAP, KC_OSLG, _________________DVORAK_R3_________________, KC_MRSF,
|
||||
LT(_LOWER,KC_GRV), KC_SPC, KC_BSPC, KC_DEL, KC_ENT, RAISE
|
||||
),
|
||||
[_WORKMAN] = LAYOUT_wrapper(
|
||||
KC_ESC, ________________NUMBER_LEFT________________, ________________NUMBER_RIGHT_______________, KC_MINS,
|
||||
KC_TAB , _________________WORKMAN_L1________________, _________________WORKMAN_R1________________, KC_BSLS,
|
||||
KC_CCCV, _________________WORKMAN_L2________________, _________________WORKMAN_R2________________, KC_QUOT,
|
||||
KC_MLSF, _________________WORKMAN_L3________________, KC_ALAP, KC_OSLG, _________________WORKMAN_R3________________, KC_MRSF,
|
||||
LT(_LOWER,KC_GRV), KC_SPC, KC_BSPC, KC_DEL, KC_ENT, RAISE
|
||||
),
|
||||
|
||||
[_MODS] = LAYOUT_wrapper(
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
|
||||
KC_LSFT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_RSFT,
|
||||
_______, _______, _______, _______, _______, _______
|
||||
),
|
||||
|
||||
|
||||
[_LOWER] = LAYOUT_wrapper(
|
||||
_______, _________________FUNC_LEFT_________________, _________________FUNC_RIGHT________________, _______,
|
||||
KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, _______,
|
||||
_______, _______, _______, _______, _______, _______, _______, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE,
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, _______,
|
||||
_______, _______, _______, _______, _______, _______
|
||||
),
|
||||
|
||||
[_RAISE] = LAYOUT_wrapper(
|
||||
_______, _________________FUNC_LEFT_________________, _________________FUNC_RIGHT________________, _______,
|
||||
KC_GRV, ________________NUMBER_LEFT________________, ________________NUMBER_RIGHT_______________, _______,
|
||||
_______, _______, _______, _______, _______, _______, _______, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS,
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_PGUP, KC_END, _______,
|
||||
_______, _______, _______, _______, _______, _______
|
||||
),
|
||||
|
||||
[_ADJUST] = LAYOUT_wrapper(
|
||||
KC_MAKE, _______, _______, _______, _______, _______, KC_SEC1, KC_SEC2, KC_SEC3, KC_SEC4, KC_SEC5, KC_RST,
|
||||
VRSN, RGB_MOD, RGB_HUI, RGB_SAI, RGB_VAI, RGB_TOG, KC_NUKE, _______, _______, _______, _______, EPRM,
|
||||
_______, _______, CK_TOGG, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, WORKMAN, TG(_MODS),
|
||||
_______, RGB_SMOD,RGB_HUD, RGB_SAD, RGB_VAD, KC_RGB_T,_______, _______, MG_NKRO, KC_MUTE, KC_VOLD, KC_VOLU, KC_MNXT, KC_MPLY,
|
||||
_______, _______, _______, _______, _______, _______
|
||||
)
|
||||
|
||||
};
|
||||
|
||||
|
||||
bool indicator_is_this_led_used(uint8_t index) {
|
||||
switch (index) {
|
||||
#ifdef INDICATOR_LIGHTS
|
||||
case SHFT_LED1:
|
||||
case SHFT_LED2:
|
||||
case CTRL_LED1:
|
||||
case CTRL_LED2:
|
||||
case GUI_LED1:
|
||||
case GUI_LED2:
|
||||
return true;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -1,17 +0,0 @@
|
||||
USER_NAME := drashna
|
||||
|
||||
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
|
||||
MOUSEKEY_ENABLE = no # Mouse keys(+4700)
|
||||
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
|
||||
CONSOLE_ENABLE = no # Console for debug(+400)
|
||||
COMMAND_ENABLE = no # Commands for debug and configuration
|
||||
TAP_DANCE_ENABLE = no
|
||||
RGBLIGHT_ENABLE = yes
|
||||
AUDIO_ENABLE = yes
|
||||
NKRO_ENABLE = yes
|
||||
BACKLIGHT_ENABLE = no
|
||||
SWAP_HANDS_ENABLE = no
|
||||
|
||||
INDICATOR_LIGHTS = yes
|
||||
MACROS_ENABLED = no
|
||||
RGBLIGHT_TWINKLE = yes
|
@@ -1,2 +0,0 @@
|
||||
# krusli's Iris keymap
|
||||
Based off the default and Planck keymaps.
|
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 Danny Nguyen <danny@keeb.io>
|
||||
|
||||
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 CONFIG_USER_H
|
||||
#define CONFIG_USER_H
|
||||
|
||||
#include "config_common.h"
|
||||
|
||||
// #define PREVENT_STUCK_MODIFIERS
|
||||
|
||||
/* Use I2C or Serial, not both */
|
||||
|
||||
#define USE_SERIAL
|
||||
// #define USE_I2C
|
||||
|
||||
/* Select hand configuration */
|
||||
|
||||
#define MASTER_LEFT
|
||||
// #define MASTER_RIGHT
|
||||
// #define EE_HANDS
|
||||
|
||||
#undef RGBLED_NUM
|
||||
#define RGBLIGHT_ANIMATIONS
|
||||
#define RGBLED_NUM 12
|
||||
#define RGBLIGHT_HUE_STEP 8
|
||||
#define RGBLIGHT_SAT_STEP 8
|
||||
#define RGBLIGHT_VAL_STEP 8
|
||||
|
||||
#endif
|
@@ -1,98 +0,0 @@
|
||||
#include "iris.h"
|
||||
#include "action_layer.h"
|
||||
#include "eeconfig.h"
|
||||
|
||||
extern keymap_config_t keymap_config;
|
||||
|
||||
#define _QWERTY 0
|
||||
#define _LOWER 1
|
||||
#define _RAISE 2
|
||||
#define _ADJUST 16
|
||||
|
||||
enum custom_keycodes {
|
||||
QWERTY = SAFE_RANGE,
|
||||
LOWER,
|
||||
RAISE,
|
||||
ADJUST,
|
||||
};
|
||||
|
||||
#define _______ KC_TRNS
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
[_QWERTY] = LAYOUT(
|
||||
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSLS,
|
||||
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC,
|
||||
KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT,
|
||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_HOME, KC_END, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT,
|
||||
KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LALT
|
||||
),
|
||||
|
||||
[_LOWER] = LAYOUT(
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_PSCR,
|
||||
KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC,
|
||||
_______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE,
|
||||
_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, _______, _______, KC_F12, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT,
|
||||
_______, _______, _______, _______, _______, _______
|
||||
),
|
||||
|
||||
[_RAISE] = LAYOUT(
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_PSCR,
|
||||
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC,
|
||||
_______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS,
|
||||
_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, _______, _______, KC_F12, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT,
|
||||
_______, _______, _______, _______, _______, _______
|
||||
),
|
||||
|
||||
[_ADJUST] = LAYOUT(
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
|
||||
RGB_TOG, RGB_MOD, RGB_HUI, RGB_SAI, RGB_VAI, _______, _______, _______, _______, _______, _______, _______,
|
||||
_______, _______, RGB_HUD, RGB_SAD, RGB_SAD, RGB_VAD, _______, _______, _______, _______, _______, _______,
|
||||
BL_STEP, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
|
||||
_______, _______, _______, _______, _______, _______
|
||||
),
|
||||
};
|
||||
|
||||
void persistent_default_layer_set(uint16_t default_layer) {
|
||||
eeconfig_update_default_layer(default_layer);
|
||||
default_layer_set(default_layer);
|
||||
}
|
||||
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
switch (keycode) {
|
||||
case QWERTY:
|
||||
if (record->event.pressed) {
|
||||
persistent_default_layer_set(1UL<<_QWERTY);
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case LOWER:
|
||||
if (record->event.pressed) {
|
||||
layer_on(_LOWER);
|
||||
update_tri_layer(_LOWER, _RAISE, _ADJUST);
|
||||
} else {
|
||||
layer_off(_LOWER);
|
||||
update_tri_layer(_LOWER, _RAISE, _ADJUST);
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case RAISE:
|
||||
if (record->event.pressed) {
|
||||
layer_on(_RAISE);
|
||||
update_tri_layer(_LOWER, _RAISE, _ADJUST);
|
||||
} else {
|
||||
layer_off(_RAISE);
|
||||
update_tri_layer(_LOWER, _RAISE, _ADJUST);
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case ADJUST:
|
||||
if (record->event.pressed) {
|
||||
layer_on(_ADJUST);
|
||||
} else {
|
||||
layer_off(_ADJUST);
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
@@ -1,6 +0,0 @@
|
||||
RGBLIGHT_ENABLE = no
|
||||
BACKLIGHT_ENABLE = no
|
||||
|
||||
ifndef QUANTUM_DIR
|
||||
include ../../../../Makefile
|
||||
endif
|
@@ -20,9 +20,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "config_common.h"
|
||||
|
||||
#define SOLENOID_ENABLE
|
||||
#define SOLENOID_PIN C6
|
||||
|
||||
/* Use I2C or Serial, not both */
|
||||
|
||||
#define USE_SERIAL
|
||||
@@ -31,7 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
/* Select hand configuration */
|
||||
|
||||
#define MASTER_LEFT
|
||||
|
||||
#define TAPPING_TERM 250
|
||||
// #define MASTER_RIGHT
|
||||
// #define EE_HANDS
|
||||
|
||||
|
@@ -1,8 +1,145 @@
|
||||
#include QMK_KEYBOARD_H
|
||||
#include "mtdjr.h"
|
||||
#include "iris.h"
|
||||
#include "action_layer.h"
|
||||
#include "eeconfig.h"
|
||||
#include "action_macro.h"
|
||||
#include <timer.h>
|
||||
#include "pincontrol.h"
|
||||
|
||||
extern keymap_config_t keymap_config;
|
||||
|
||||
#define _QWERTY 0
|
||||
#define _LOWER 1
|
||||
#define _RAISE 2
|
||||
#define _SUPER 3
|
||||
#define _ADJUST 16
|
||||
#define SOLENOID_DEFAULT_DWELL 12
|
||||
#define SOLENOID_MAX_DWELL 100
|
||||
#define SOLENOID_MIN_DWELL 4
|
||||
#define SOLENOID_PIN C6
|
||||
|
||||
|
||||
bool solenoid_enabled = false;
|
||||
bool solenoid_on = false;
|
||||
bool solenoid_buzz = false;
|
||||
bool solenoid_buzzing = false;
|
||||
uint16_t solenoid_start = 0;
|
||||
uint8_t solenoid_dwell = SOLENOID_DEFAULT_DWELL;
|
||||
|
||||
|
||||
void solenoid_buzz_on(void) {
|
||||
solenoid_buzz = true;
|
||||
}
|
||||
|
||||
void solenoid_buzz_off(void) {
|
||||
solenoid_buzz = false;
|
||||
}
|
||||
|
||||
void solenoid_dwell_minus(void) {
|
||||
if (solenoid_dwell > 0) solenoid_dwell--;
|
||||
}
|
||||
|
||||
void solenoid_dwell_plus(void) {
|
||||
if (solenoid_dwell < SOLENOID_MAX_DWELL) solenoid_dwell++;
|
||||
}
|
||||
|
||||
void solenoid_toggle(void) {
|
||||
solenoid_enabled = !solenoid_enabled;
|
||||
}
|
||||
|
||||
void solenoid_stop(void) {
|
||||
digitalWrite(SOLENOID_PIN, PinLevelLow);
|
||||
solenoid_on = false;
|
||||
solenoid_buzzing = false;
|
||||
}
|
||||
|
||||
void solenoid_fire(void) {
|
||||
if (!solenoid_enabled) return;
|
||||
|
||||
if (!solenoid_buzz && solenoid_on) return;
|
||||
if (solenoid_buzz && solenoid_buzzing) return;
|
||||
|
||||
solenoid_on = true;
|
||||
solenoid_buzzing = true;
|
||||
solenoid_start = timer_read();
|
||||
digitalWrite(SOLENOID_PIN, PinLevelHigh);
|
||||
}
|
||||
|
||||
void solenoid_check(void) {
|
||||
uint16_t elapsed = 0;
|
||||
|
||||
if (!solenoid_on) return;
|
||||
|
||||
elapsed = timer_elapsed(solenoid_start);
|
||||
|
||||
//Check if it's time to finish this solenoid click cycle
|
||||
if (elapsed > solenoid_dwell) {
|
||||
solenoid_stop();
|
||||
return;
|
||||
}
|
||||
|
||||
//Check whether to buzz the solenoid on and off
|
||||
if (solenoid_buzz) {
|
||||
if (elapsed / SOLENOID_MIN_DWELL % 2 == 0){
|
||||
if (!solenoid_buzzing) {
|
||||
solenoid_buzzing = true;
|
||||
digitalWrite(SOLENOID_PIN, PinLevelHigh);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (solenoid_buzzing) {
|
||||
solenoid_buzzing = false;
|
||||
digitalWrite(SOLENOID_PIN, PinLevelLow);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void solenoid_setup(void) {
|
||||
pinMode(SOLENOID_PIN, PinDirectionOutput);
|
||||
}
|
||||
|
||||
void matrix_init_user(void) {
|
||||
solenoid_setup();
|
||||
}
|
||||
|
||||
void matrix_scan_user(void) {
|
||||
solenoid_check();
|
||||
}
|
||||
|
||||
|
||||
enum custom_keycodes {
|
||||
QWERTY = SAFE_RANGE,
|
||||
LOWER,
|
||||
RAISE,
|
||||
SUPER,
|
||||
ADJUST,
|
||||
SOL_TOG,
|
||||
SOLENOID_DWELL_MINUS,
|
||||
SOLENOID_DWELL_PLUS,
|
||||
SOLENOID_BUZZ_ON,
|
||||
SOLENOID_BUZZ_OFF,
|
||||
TD_ESC = 0,
|
||||
};
|
||||
|
||||
#define KC_ KC_TRNS
|
||||
#define _______ KC_TRNS
|
||||
|
||||
#define KC_LOWR LOWER
|
||||
#define KC_RASE RAISE
|
||||
#define KC_SUPR SUPER
|
||||
#define KC_RST RESET
|
||||
#define KC_BL_S BL_STEP
|
||||
#define KC_EXC TD(TD_ESC)
|
||||
#define SOLTOG SOLENOID_TOG
|
||||
|
||||
// Macro Declarations
|
||||
#define UM_ROOT M(0)
|
||||
#define UM_PPLY M(1)
|
||||
#define UM_PSEF M(2)
|
||||
#define KC_XCPY M(3)
|
||||
#define KC_XINS M(4)
|
||||
#define UM_CAD M(5)
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
|
||||
[_QWERTY] = LAYOUT_kc(
|
||||
@@ -15,7 +152,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
//|----+----+----+----+----+----+----. ,----|----+----+----+----+----+----|
|
||||
EQL, Z , X , C , V , B ,LGUI, LALT, N , M ,COMM,DOT ,SLSH,MINS,
|
||||
//`----+----+----+--+-+----+----+----/ \----+----+----+----+----+----+----'
|
||||
LCTL,RASE,SPC , SPC ,LOWR,xxxx
|
||||
LCTL,RASE,SPC , SPC ,LOWR,SUPR
|
||||
// `----+----+----' `----+----+----'
|
||||
),
|
||||
|
||||
@@ -41,23 +178,130 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
//|----+----+----+----+----+----| |----+----+----+----+----+----|
|
||||
, F9 ,F10 ,F11 ,F12 , , , , , , , ,
|
||||
//|----+----+----+----+----+----+----. ,----|----+----+----+----+----+----|
|
||||
, , ,XCPY,XINS, , , , , , , , , ,
|
||||
, , ,XCPY,XINS, , , , , , , , ,PLUS,
|
||||
//`----+----+----+--+-+----+----+----/ \----+----+----+----+----+----+----'
|
||||
, , , , ,
|
||||
// `----+----+----' `----+----+----'
|
||||
),
|
||||
|
||||
[_ADJUST] = LAYOUT_kc(
|
||||
//,----+----+----+----+----+----. ,----+----+----+----+----+----.
|
||||
STOG,ROOT,PPLY,PSEF,xxxx,xxxx, xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,
|
||||
//|----+----+----+----+----+----| |----+----+----+----+----+----|
|
||||
xxxx,xxxx,xxxx,xxxx,xxxx,xxxx, xxxx,xxxx,xxxx,xxxx,xxxx,BSLS,
|
||||
//|----+----+----+----+----+----| |----+----+----+----+----+----|
|
||||
xxxx,xxxx,xxxx,xxxx,xxxx,xxxx, xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,
|
||||
//|----+----+----+----+----+----+----. ,----|----+----+----+----+----+----|
|
||||
xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx, xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,
|
||||
//`----+----+----+--+-+----+----+----/ \----+----+----+----+----+----+----'
|
||||
xxxx, ,xxxx, xxxx, ,
|
||||
// `----+----+----' `----+----+----'
|
||||
)
|
||||
[_SUPER] = LAYOUT(
|
||||
//,--------+--------+--------+--------+--------+--------. ,--------+--------+--------+--------+--------+--------.
|
||||
SOL_TOG, UM_ROOT, UM_PPLY, UM_PSEF, _______, _______, _______, _______, _______, _______, _______, _______,
|
||||
//|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
|
||||
_______, _______, _______, _______, _______, _______, _______, KC_LBRC, _______, _______, _______, _______,
|
||||
//|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, UM_CAD ,
|
||||
//|--------+--------+--------+--------+--------+--------+--------. ,--------|--------+--------+--------+--------+--------+--------|
|
||||
_______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MUTE, KC_VOLD, KC_VOLU, KC_MNXT, KC_MPLY,
|
||||
//`--------+--------+--------+----+---+--------+--------+--------/ \--------+--------+--------+---+----+--------+--------+--------'
|
||||
_______, _______, _______, _______, _______, _______
|
||||
// `--------+--------+--------' `--------+--------+--------'
|
||||
)
|
||||
|
||||
};
|
||||
|
||||
void persistent_default_layer_set(uint16_t default_layer) {
|
||||
eeconfig_update_default_layer(default_layer);
|
||||
default_layer_set(default_layer);
|
||||
}
|
||||
|
||||
qk_tap_dance_action_t tap_dance_actions[] = {
|
||||
//Tap once for grave accent, twice for ESC
|
||||
[TD_ESC] = ACTION_TAP_DANCE_DOUBLE(KC_GRV, KC_ESC)
|
||||
};
|
||||
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
if (record->event.pressed) {
|
||||
solenoid_fire();
|
||||
}
|
||||
switch (keycode) {
|
||||
case QWERTY:
|
||||
if (record->event.pressed) {
|
||||
persistent_default_layer_set(1UL<<_QWERTY);
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case LOWER:
|
||||
if (record->event.pressed) {
|
||||
layer_on(_LOWER);
|
||||
update_tri_layer(_LOWER, _RAISE, _ADJUST);
|
||||
} else {
|
||||
layer_off(_LOWER);
|
||||
update_tri_layer(_LOWER, _RAISE, _ADJUST);
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case RAISE:
|
||||
if (record->event.pressed) {
|
||||
layer_on(_RAISE);
|
||||
update_tri_layer(_LOWER, _RAISE, _ADJUST);
|
||||
} else {
|
||||
layer_off(_RAISE);
|
||||
update_tri_layer(_LOWER, _RAISE, _ADJUST);
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case SUPER:
|
||||
if (record->event.pressed) {
|
||||
layer_on(_SUPER);
|
||||
update_tri_layer(_LOWER, _RAISE, _ADJUST);
|
||||
} else {
|
||||
layer_off(_SUPER);
|
||||
update_tri_layer(_LOWER, _RAISE, _ADJUST);
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case SOLTOG:
|
||||
if (record->event.pressed) {
|
||||
solenoid_toggle();
|
||||
}
|
||||
break;
|
||||
case SOLENOID_DWELL_MINUS:
|
||||
if (record->event.pressed) {
|
||||
solenoid_dwell_minus();
|
||||
}
|
||||
break;
|
||||
case SOLENOID_DWELL_PLUS:
|
||||
if (record->event.pressed) {
|
||||
solenoid_dwell_plus();
|
||||
}
|
||||
break;
|
||||
case SOLENOID_BUZZ_ON:
|
||||
if (record->event.pressed) {
|
||||
solenoid_buzz_on();
|
||||
}
|
||||
break;
|
||||
case SOLENOID_BUZZ_OFF:
|
||||
if (record->event.pressed) {
|
||||
solenoid_buzz_off();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
|
||||
if (record->event.pressed) {
|
||||
switch(id) {
|
||||
case 0:
|
||||
SEND_STRING("sudo su -\n");
|
||||
return false; break;
|
||||
case 1:
|
||||
SEND_STRING("puppet apply /etc/puppetlabs/code/environments/production/manifests/site.pp\n");
|
||||
return false; break;
|
||||
case 2:
|
||||
SEND_STRING("ps -ef | grep ");
|
||||
return false; break;
|
||||
case 3:
|
||||
return MACRO(D(LCTL), T(INS), U(LCTL), END);
|
||||
break;
|
||||
case 4:
|
||||
return MACRO(D(LSFT), T(INS), U(LSFT), END);
|
||||
break;
|
||||
case 5:
|
||||
return MACRO(D(LCTL), D(RALT), T(DEL), END);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return MACRO_NONE;
|
||||
};
|
||||
|
@@ -1,5 +1,6 @@
|
||||
RGBLIGHT_ENABLE = no
|
||||
BACKLIGHT_ENABLE = no
|
||||
TAP_DANCE_ENABLE = no
|
||||
|
||||
ifndef QUANTUM_DIR
|
||||
include ../../../../Makefile
|
||||
|
@@ -51,7 +51,7 @@ void matrix_init(void) {
|
||||
matrix_debouncing[row] = 0x00;
|
||||
}
|
||||
|
||||
matrix_init_quantum();
|
||||
matrix_init_quantum(); // missing from original port by Luiz
|
||||
}
|
||||
|
||||
uint8_t matrix_scan(void) {
|
||||
@@ -86,7 +86,7 @@ uint8_t matrix_scan(void) {
|
||||
}
|
||||
}
|
||||
|
||||
matrix_scan_quantum();
|
||||
matrix_scan_quantum(); // also missing in original PS2AVRGB implementation
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@@ -62,7 +62,6 @@ SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
|
||||
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
|
||||
NKRO_ENABLE = no # USB Nkey Rollover
|
||||
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality on B7 by default
|
||||
RGBLIGHT_ENABLE ?= yes # Enable keyboard RGB underglow
|
||||
MIDI_ENABLE = no # MIDI support (+2400 to 4200, depending on config)
|
||||
UNICODE_ENABLE = no # Unicode
|
||||
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
|
||||
|
@@ -1,27 +0,0 @@
|
||||
# Lets Split Layout
|
||||
|
||||
Check out [user readme](../../../../users/bbaserdem/README.md) for more info.
|
||||
|
||||
# Usage
|
||||
|
||||
**These commands depend on there being no other arduino connected!**
|
||||
Also udev rules can be set instead of using sudo.
|
||||
Please unplug all other usb devices.
|
||||
|
||||
To make the hex files;
|
||||
```
|
||||
make lets_split/rev2:bbaserdem
|
||||
make lets_split/rev2:bbaserdem_right
|
||||
```
|
||||
|
||||
For the left half, after plugging in and resetting; (from repo main directory)
|
||||
```
|
||||
sudo avrdude -p atmega32u4 -P "$(ls /dev/ttyACM*)" -c avr109 -D -U flash:w:.build/lets_split_rev2_bbaserdem.hex
|
||||
sudo avrdude -p atmega32u4 -P "$(ls /dev/ttyACM*)" -c avr109 -U eeprom:w:keyboards/lets_split/eeprom-lefthand.eep
|
||||
```
|
||||
|
||||
For the right half;
|
||||
```
|
||||
sudo avrdude -p atmgea34u4 -P "$(ls /dev/ttyACM*)" -c avr109 -D -U flash:w:.build/lets_split_rev2_bbaserdem_right.hex
|
||||
sudo avrdude -p atmega32u4 -P "$(ls /dev/ttyACM*)" -c avr109 -U eeprom:w:keyboards/lets_split/eeprom-righhand.eep
|
||||
```
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user