aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build_keyboard.mk182
-rw-r--r--keyboards/ergodox/config.h2
-rw-r--r--keyboards/ergodox/ez/rules.mk4
-rw-r--r--keyboards/ergodox/infinity/Makefile2
-rw-r--r--keyboards/ergodox/infinity/animations.c107
-rw-r--r--keyboards/ergodox/infinity/animations.h30
-rw-r--r--keyboards/ergodox/infinity/config.h4
-rw-r--r--keyboards/ergodox/infinity/drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c37
-rw-r--r--keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/board_ST7565.h80
-rw-r--r--keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c411
-rw-r--r--keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_config.h11
-rw-r--r--keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/st7565.h2
-rw-r--r--keyboards/ergodox/infinity/gfxconf.h2
-rw-r--r--keyboards/ergodox/infinity/infinity.c51
-rw-r--r--keyboards/ergodox/infinity/infinity.h71
-rw-r--r--keyboards/ergodox/infinity/rules.mk13
-rw-r--r--keyboards/ergodox/infinity/simple_visualizer.h123
-rw-r--r--keyboards/ergodox/infinity/visualizer.c329
-rw-r--r--keyboards/ergodox/keymaps/default/visualizer.c42
-rw-r--r--keyboards/ergodox/keymaps/familiar/README.md69
-rw-r--r--keyboards/ergodox/keymaps/familiar/familiar.pngbin0 -> 149846 bytes
-rw-r--r--keyboards/ergodox/keymaps/familiar/keymap.c267
-rw-r--r--keyboards/planck/keymaps/khord/config.h1
-rw-r--r--keyboards/planck/keymaps/khord/keymap.c42
-rw-r--r--keyboards/xd60/keymaps/default/keymap.c4
-rw-r--r--quantum/led_tables.c71
-rw-r--r--quantum/led_tables.h30
-rw-r--r--quantum/rgblight.c58
-rw-r--r--quantum/serial_link/system/serial_link.c2
-rw-r--r--quantum/visualizer/example_integration/callbacks.c36
-rw-r--r--quantum/visualizer/example_integration/gfxconf.h325
-rw-r--r--quantum/visualizer/example_integration/lcd_backlight_hal.c91
-rw-r--r--quantum/visualizer/example_integration/visualizer_user.c121
-rw-r--r--quantum/visualizer/lcd_backlight.c8
-rw-r--r--quantum/visualizer/lcd_backlight.h4
-rw-r--r--quantum/visualizer/lcd_backlight_keyframes.c77
-rw-r--r--quantum/visualizer/lcd_backlight_keyframes.h30
-rw-r--r--quantum/visualizer/lcd_keyframes.c188
-rw-r--r--quantum/visualizer/lcd_keyframes.h39
-rw-r--r--quantum/visualizer/led_keyframes.c (renamed from quantum/visualizer/led_test.c)57
-rw-r--r--quantum/visualizer/led_keyframes.h (renamed from quantum/visualizer/led_test.h)20
-rw-r--r--quantum/visualizer/resources/lcd_logo.c61
-rw-r--r--quantum/visualizer/resources/lcd_logo.pngbin0 -> 490 bytes
-rw-r--r--quantum/visualizer/resources/resources.h27
-rw-r--r--quantum/visualizer/visualizer.c226
-rw-r--r--quantum/visualizer/visualizer.h41
-rw-r--r--quantum/visualizer/visualizer.mk21
-rw-r--r--quantum/visualizer/visualizer_keyframes.c23
-rw-r--r--quantum/visualizer/visualizer_keyframes.h26
-rw-r--r--tmk_core/common/action_util.c6
50 files changed, 2165 insertions, 1309 deletions
diff --git a/build_keyboard.mk b/build_keyboard.mk
index 82464d583..9da8277db 100644
--- a/build_keyboard.mk
+++ b/build_keyboard.mk
@@ -7,11 +7,11 @@ endif
7include common.mk 7include common.mk
8 8
9ifneq ($(SUBPROJECT),) 9ifneq ($(SUBPROJECT),)
10 TARGET ?= $(KEYBOARD)_$(SUBPROJECT)_$(KEYMAP) 10 TARGET ?= $(KEYBOARD)_$(SUBPROJECT)_$(KEYMAP)
11 KEYBOARD_OUTPUT := $(BUILD_DIR)/obj_$(KEYBOARD)_$(SUBPROJECT) 11 KEYBOARD_OUTPUT := $(BUILD_DIR)/obj_$(KEYBOARD)_$(SUBPROJECT)
12else 12else
13 TARGET ?= $(KEYBOARD)_$(KEYMAP) 13 TARGET ?= $(KEYBOARD)_$(KEYMAP)
14 KEYBOARD_OUTPUT := $(BUILD_DIR)/obj_$(KEYBOARD) 14 KEYBOARD_OUTPUT := $(BUILD_DIR)/obj_$(KEYBOARD)
15endif 15endif
16 16
17# Force expansion 17# Force expansion
@@ -20,15 +20,15 @@ TARGET := $(TARGET)
20 20
21MASTER ?= left 21MASTER ?= left
22ifdef master 22ifdef master
23 MASTER = $(master) 23 MASTER = $(master)
24endif 24endif
25 25
26ifeq ($(MASTER),right) 26ifeq ($(MASTER),right)
27 OPT_DEFS += -DMASTER_IS_ON_RIGHT 27 OPT_DEFS += -DMASTER_IS_ON_RIGHT
28else 28else
29 ifneq ($(MASTER),left) 29 ifneq ($(MASTER),left)
30$(error MASTER does not have a valid value(left/right)) 30$(error MASTER does not have a valid value(left/right))
31 endif 31 endif
32endif 32endif
33 33
34 34
@@ -56,31 +56,31 @@ endif
56 56
57# We can assume a ChibiOS target When MCU_FAMILY is defined, since it's not used for LUFA 57# We can assume a ChibiOS target When MCU_FAMILY is defined, since it's not used for LUFA
58ifdef MCU_FAMILY 58ifdef MCU_FAMILY
59 PLATFORM=CHIBIOS 59 PLATFORM=CHIBIOS
60else 60else
61 PLATFORM=AVR 61 PLATFORM=AVR
62endif 62endif
63 63
64ifeq ($(PLATFORM),CHIBIOS) 64ifeq ($(PLATFORM),CHIBIOS)
65 include $(TMK_PATH)/protocol/chibios.mk 65 include $(TMK_PATH)/protocol/chibios.mk
66 include $(TMK_PATH)/chibios.mk 66 include $(TMK_PATH)/chibios.mk
67 OPT_OS = chibios 67 OPT_OS = chibios
68 ifneq ("$(wildcard $(SUBPROJECT_PATH)/bootloader_defs.h)","") 68 ifneq ("$(wildcard $(SUBPROJECT_PATH)/bootloader_defs.h)","")
69 OPT_DEFS += -include $(SUBPROJECT_PATH)/bootloader_defs.h 69 OPT_DEFS += -include $(SUBPROJECT_PATH)/bootloader_defs.h
70 else ifneq ("$(wildcard $(SUBPROJECT_PATH)/boards/$(BOARD)/bootloader_defs.h)","") 70 else ifneq ("$(wildcard $(SUBPROJECT_PATH)/boards/$(BOARD)/bootloader_defs.h)","")
71 OPT_DEFS += -include $(SUBPROJECT_PATH)/boards/$(BOARD)/bootloader_defs.h 71 OPT_DEFS += -include $(SUBPROJECT_PATH)/boards/$(BOARD)/bootloader_defs.h
72 else ifneq ("$(wildcard $(KEYBOARD_PATH)/bootloader_defs.h)","") 72 else ifneq ("$(wildcard $(KEYBOARD_PATH)/bootloader_defs.h)","")
73 OPT_DEFS += -include $(KEYBOARD_PATH)/bootloader_defs.h 73 OPT_DEFS += -include $(KEYBOARD_PATH)/bootloader_defs.h
74 else ifneq ("$(wildcard $(KEYBOARD_PATH)/boards/$(BOARD)/bootloader_defs.h)","") 74 else ifneq ("$(wildcard $(KEYBOARD_PATH)/boards/$(BOARD)/bootloader_defs.h)","")
75 OPT_DEFS += -include $(KEYBOARD_PATH)/boards/$(BOARD)/bootloader_defs.h 75 OPT_DEFS += -include $(KEYBOARD_PATH)/boards/$(BOARD)/bootloader_defs.h
76 endif 76 endif
77endif 77endif
78 78
79CONFIG_H = $(KEYBOARD_PATH)/config.h 79CONFIG_H = $(KEYBOARD_PATH)/config.h
80ifneq ($(SUBPROJECT),) 80ifneq ($(SUBPROJECT),)
81 ifneq ("$(wildcard $(SUBPROJECT_C))","") 81 ifneq ("$(wildcard $(SUBPROJECT_C))","")
82 CONFIG_H = $(SUBPROJECT_PATH)/config.h 82 CONFIG_H = $(SUBPROJECT_PATH)/config.h
83 endif 83 endif
84endif 84endif
85 85
86# Save the defines and includes here, so we don't include any keymap specific ones 86# Save the defines and includes here, so we don't include any keymap specific ones
@@ -112,30 +112,30 @@ KEYMAP_OUTPUT := $(BUILD_DIR)/obj_$(TARGET)
112 112
113 113
114ifneq ("$(wildcard $(KEYMAP_PATH)/config.h)","") 114ifneq ("$(wildcard $(KEYMAP_PATH)/config.h)","")
115 CONFIG_H = $(KEYMAP_PATH)/config.h 115 CONFIG_H = $(KEYMAP_PATH)/config.h
116endif 116endif
117 117
118# # project specific files 118# # project specific files
119SRC += $(KEYBOARD_C) \ 119SRC += $(KEYBOARD_C) \
120 $(KEYMAP_C) \ 120 $(KEYMAP_C) \
121 $(QUANTUM_DIR)/quantum.c \ 121 $(QUANTUM_DIR)/quantum.c \
122 $(QUANTUM_DIR)/keymap_common.c \ 122 $(QUANTUM_DIR)/keymap_common.c \
123 $(QUANTUM_DIR)/keycode_config.c \ 123 $(QUANTUM_DIR)/keycode_config.c \
124 $(QUANTUM_DIR)/process_keycode/process_leader.c 124 $(QUANTUM_DIR)/process_keycode/process_leader.c
125 125
126ifneq ($(SUBPROJECT),) 126ifneq ($(SUBPROJECT),)
127 SRC += $(SUBPROJECT_C) 127 SRC += $(SUBPROJECT_C)
128endif 128endif
129 129
130ifndef CUSTOM_MATRIX 130ifndef CUSTOM_MATRIX
131 SRC += $(QUANTUM_DIR)/matrix.c 131 SRC += $(QUANTUM_DIR)/matrix.c
132endif 132endif
133 133
134ifeq ($(strip $(API_SYSEX_ENABLE)), yes) 134ifeq ($(strip $(API_SYSEX_ENABLE)), yes)
135 OPT_DEFS += -DAPI_SYSEX_ENABLE 135 OPT_DEFS += -DAPI_SYSEX_ENABLE
136 SRC += $(QUANTUM_DIR)/api/api_sysex.c 136 SRC += $(QUANTUM_DIR)/api/api_sysex.c
137 OPT_DEFS += -DAPI_ENABLE 137 OPT_DEFS += -DAPI_ENABLE
138 SRC += $(QUANTUM_DIR)/api.c 138 SRC += $(QUANTUM_DIR)/api.c
139 MIDI_ENABLE=yes 139 MIDI_ENABLE=yes
140endif 140endif
141 141
@@ -144,25 +144,25 @@ MUSIC_ENABLE := 0
144ifeq ($(strip $(AUDIO_ENABLE)), yes) 144ifeq ($(strip $(AUDIO_ENABLE)), yes)
145 OPT_DEFS += -DAUDIO_ENABLE 145 OPT_DEFS += -DAUDIO_ENABLE
146 MUSIC_ENABLE := 1 146 MUSIC_ENABLE := 1
147 SRC += $(QUANTUM_DIR)/process_keycode/process_audio.c 147 SRC += $(QUANTUM_DIR)/process_keycode/process_audio.c
148 SRC += $(QUANTUM_DIR)/audio/audio.c 148 SRC += $(QUANTUM_DIR)/audio/audio.c
149 SRC += $(QUANTUM_DIR)/audio/voices.c 149 SRC += $(QUANTUM_DIR)/audio/voices.c
150 SRC += $(QUANTUM_DIR)/audio/luts.c 150 SRC += $(QUANTUM_DIR)/audio/luts.c
151endif 151endif
152 152
153ifeq ($(strip $(MIDI_ENABLE)), yes) 153ifeq ($(strip $(MIDI_ENABLE)), yes)
154 OPT_DEFS += -DMIDI_ENABLE 154 OPT_DEFS += -DMIDI_ENABLE
155 MUSIC_ENABLE := 1 155 MUSIC_ENABLE := 1
156 SRC += $(QUANTUM_DIR)/process_keycode/process_midi.c 156 SRC += $(QUANTUM_DIR)/process_keycode/process_midi.c
157endif 157endif
158 158
159ifeq ($(MUSIC_ENABLE), 1) 159ifeq ($(MUSIC_ENABLE), 1)
160 SRC += $(QUANTUM_DIR)/process_keycode/process_music.c 160 SRC += $(QUANTUM_DIR)/process_keycode/process_music.c
161endif 161endif
162 162
163ifeq ($(strip $(COMBO_ENABLE)), yes) 163ifeq ($(strip $(COMBO_ENABLE)), yes)
164 OPT_DEFS += -DCOMBO_ENABLE 164 OPT_DEFS += -DCOMBO_ENABLE
165 SRC += $(QUANTUM_DIR)/process_keycode/process_combo.c 165 SRC += $(QUANTUM_DIR)/process_keycode/process_combo.c
166endif 166endif
167 167
168ifeq ($(strip $(VIRTSER_ENABLE)), yes) 168ifeq ($(strip $(VIRTSER_ENABLE)), yes)
@@ -171,56 +171,80 @@ endif
171 171
172ifeq ($(strip $(FAUXCLICKY_ENABLE)), yes) 172ifeq ($(strip $(FAUXCLICKY_ENABLE)), yes)
173 OPT_DEFS += -DFAUXCLICKY_ENABLE 173 OPT_DEFS += -DFAUXCLICKY_ENABLE
174 SRC += $(QUANTUM_DIR)/fauxclicky.c 174 SRC += $(QUANTUM_DIR)/fauxclicky.c
175endif 175endif
176 176
177ifeq ($(strip $(UCIS_ENABLE)), yes) 177ifeq ($(strip $(UCIS_ENABLE)), yes)
178 OPT_DEFS += -DUCIS_ENABLE 178 OPT_DEFS += -DUCIS_ENABLE
179 SRC += $(QUANTUM_DIR)/process_keycode/process_unicode_common.c 179 SRC += $(QUANTUM_DIR)/process_keycode/process_unicode_common.c
180 SRC += $(QUANTUM_DIR)/process_keycode/process_ucis.c 180 SRC += $(QUANTUM_DIR)/process_keycode/process_ucis.c
181endif 181endif
182 182
183ifeq ($(strip $(UNICODEMAP_ENABLE)), yes) 183ifeq ($(strip $(UNICODEMAP_ENABLE)), yes)
184 OPT_DEFS += -DUNICODEMAP_ENABLE 184 OPT_DEFS += -DUNICODEMAP_ENABLE
185 SRC += $(QUANTUM_DIR)/process_keycode/process_unicode_common.c 185 SRC += $(QUANTUM_DIR)/process_keycode/process_unicode_common.c
186 SRC += $(QUANTUM_DIR)/process_keycode/process_unicodemap.c 186 SRC += $(QUANTUM_DIR)/process_keycode/process_unicodemap.c
187endif 187endif
188 188
189ifeq ($(strip $(UNICODE_ENABLE)), yes) 189ifeq ($(strip $(UNICODE_ENABLE)), yes)
190 OPT_DEFS += -DUNICODE_ENABLE 190 OPT_DEFS += -DUNICODE_ENABLE
191 SRC += $(QUANTUM_DIR)/process_keycode/process_unicode_common.c 191 SRC += $(QUANTUM_DIR)/process_keycode/process_unicode_common.c
192 SRC += $(QUANTUM_DIR)/process_keycode/process_unicode.c 192 SRC += $(QUANTUM_DIR)/process_keycode/process_unicode.c
193endif 193endif
194 194
195ifeq ($(strip $(RGBLIGHT_ENABLE)), yes) 195ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
196 OPT_DEFS += -DRGBLIGHT_ENABLE 196 OPT_DEFS += -DRGBLIGHT_ENABLE
197 SRC += $(QUANTUM_DIR)/light_ws2812.c 197 SRC += $(QUANTUM_DIR)/light_ws2812.c
198 SRC += $(QUANTUM_DIR)/rgblight.c 198 SRC += $(QUANTUM_DIR)/rgblight.c
199 CIE1931_CURVE = yes
200 LED_BREATHING_TABLE = yes
199endif 201endif
200 202
201ifeq ($(strip $(TAP_DANCE_ENABLE)), yes) 203ifeq ($(strip $(TAP_DANCE_ENABLE)), yes)
202 OPT_DEFS += -DTAP_DANCE_ENABLE 204 OPT_DEFS += -DTAP_DANCE_ENABLE
203 SRC += $(QUANTUM_DIR)/process_keycode/process_tap_dance.c 205 SRC += $(QUANTUM_DIR)/process_keycode/process_tap_dance.c
204endif 206endif
205 207
206ifeq ($(strip $(PRINTING_ENABLE)), yes) 208ifeq ($(strip $(PRINTING_ENABLE)), yes)
207 OPT_DEFS += -DPRINTING_ENABLE 209 OPT_DEFS += -DPRINTING_ENABLE
208 SRC += $(QUANTUM_DIR)/process_keycode/process_printer.c 210 SRC += $(QUANTUM_DIR)/process_keycode/process_printer.c
209 SRC += $(TMK_DIR)/protocol/serial_uart.c 211 SRC += $(TMK_DIR)/protocol/serial_uart.c
210endif 212endif
211 213
212ifeq ($(strip $(SERIAL_LINK_ENABLE)), yes) 214ifeq ($(strip $(SERIAL_LINK_ENABLE)), yes)
213 SRC += $(patsubst $(QUANTUM_PATH)/%,%,$(SERIAL_SRC)) 215 SRC += $(patsubst $(QUANTUM_PATH)/%,%,$(SERIAL_SRC))
214 OPT_DEFS += $(SERIAL_DEFS) 216 OPT_DEFS += $(SERIAL_DEFS)
215 VAPTH += $(SERIAL_PATH) 217 VAPTH += $(SERIAL_PATH)
216endif 218endif
217 219
218ifneq ($(strip $(VARIABLE_TRACE)),) 220ifneq ($(strip $(VARIABLE_TRACE)),)
219 SRC += $(QUANTUM_DIR)/variable_trace.c 221 SRC += $(QUANTUM_DIR)/variable_trace.c
220 OPT_DEFS += -DNUM_TRACED_VARIABLES=$(strip $(VARIABLE_TRACE)) 222 OPT_DEFS += -DNUM_TRACED_VARIABLES=$(strip $(VARIABLE_TRACE))
221ifneq ($(strip $(MAX_VARIABLE_TRACE_SIZE)),) 223ifneq ($(strip $(MAX_VARIABLE_TRACE_SIZE)),)
222 OPT_DEFS += -DMAX_VARIABLE_TRACE_SIZE=$(strip $(MAX_VARIABLE_TRACE_SIZE)) 224 OPT_DEFS += -DMAX_VARIABLE_TRACE_SIZE=$(strip $(MAX_VARIABLE_TRACE_SIZE))
225endif
226endif
227
228ifeq ($(strip $(LCD_ENABLE)), yes)
229 CIE1931_CURVE = yes
223endif 230endif
231
232ifeq ($(strip $(LED_ENABLE)), yes)
233 CIE1931_CURVE = yes
234endif
235
236ifeq ($(strip $(CIE1931_CURVE)), yes)
237 OPT_DEFS += -DUSE_CIE1931_CURVE
238 LED_TABLES = yes
239endif
240
241ifeq ($(strip $(LED_BREATHING_TABLE)), yes)
242 OPT_DEFS += -DUSE_LED_BREATHING_TABLE
243 LED_TABLES = yes
244endif
245
246ifeq ($(strip $(LED_TABLES)), yes)
247 SRC += $(QUANTUM_DIR)/led_tables.c
224endif 248endif
225 249
226# Optimize size but this may cause error "relocation truncated to fit" 250# Optimize size but this may cause error "relocation truncated to fit"
@@ -229,7 +253,7 @@ endif
229# Search Path 253# Search Path
230VPATH += $(KEYMAP_PATH) 254VPATH += $(KEYMAP_PATH)
231ifneq ($(SUBPROJECT),) 255ifneq ($(SUBPROJECT),)
232 VPATH += $(SUBPROJECT_PATH) 256 VPATH += $(SUBPROJECT_PATH)
233endif 257endif
234VPATH += $(KEYBOARD_PATH) 258VPATH += $(KEYBOARD_PATH)
235VPATH += $(COMMON_VPATH) 259VPATH += $(COMMON_VPATH)
@@ -243,27 +267,27 @@ EXTRALDFLAGS += $(TMK_COMMON_LDFLAGS)
243 267
244ifeq ($(PLATFORM),AVR) 268ifeq ($(PLATFORM),AVR)
245ifeq ($(strip $(PROTOCOL)), VUSB) 269ifeq ($(strip $(PROTOCOL)), VUSB)
246 include $(TMK_PATH)/protocol/vusb.mk 270 include $(TMK_PATH)/protocol/vusb.mk
247else 271else
248 include $(TMK_PATH)/protocol/lufa.mk 272 include $(TMK_PATH)/protocol/lufa.mk
249endif 273endif
250 include $(TMK_PATH)/avr.mk 274 include $(TMK_PATH)/avr.mk
251endif 275endif
252 276
253ifeq ($(strip $(VISUALIZER_ENABLE)), yes) 277ifeq ($(strip $(VISUALIZER_ENABLE)), yes)
254 VISUALIZER_DIR = $(QUANTUM_DIR)/visualizer 278 VISUALIZER_DIR = $(QUANTUM_DIR)/visualizer
255 VISUALIZER_PATH = $(QUANTUM_PATH)/visualizer 279 VISUALIZER_PATH = $(QUANTUM_PATH)/visualizer
256 include $(VISUALIZER_PATH)/visualizer.mk 280 include $(VISUALIZER_PATH)/visualizer.mk
257endif 281endif
258 282
259OUTPUTS := $(KEYMAP_OUTPUT) $(KEYBOARD_OUTPUT) 283OUTPUTS := $(KEYMAP_OUTPUT) $(KEYBOARD_OUTPUT)
260$(KEYMAP_OUTPUT)_SRC := $(SRC) 284$(KEYMAP_OUTPUT)_SRC := $(SRC)
261$(KEYMAP_OUTPUT)_DEFS := $(OPT_DEFS) -DQMK_KEYBOARD=\"$(KEYBOARD)\" -DQMK_KEYMAP=\"$(KEYMAP)\" 285$(KEYMAP_OUTPUT)_DEFS := $(OPT_DEFS) $(GFXDEFS) -DQMK_KEYBOARD=\"$(KEYBOARD)\" -DQMK_KEYMAP=\"$(KEYMAP)\"
262$(KEYMAP_OUTPUT)_INC := $(VPATH) $(EXTRAINCDIRS) 286$(KEYMAP_OUTPUT)_INC := $(VPATH) $(EXTRAINCDIRS)
263$(KEYMAP_OUTPUT)_CONFIG := $(CONFIG_H) 287$(KEYMAP_OUTPUT)_CONFIG := $(CONFIG_H)
264$(KEYBOARD_OUTPUT)_SRC := $(CHIBISRC) 288$(KEYBOARD_OUTPUT)_SRC := $(CHIBISRC) $(GFXSRC)
265$(KEYBOARD_OUTPUT)_DEFS := $(PROJECT_DEFS) 289$(KEYBOARD_OUTPUT)_DEFS := $(PROJECT_DEFS) $(GFXDEFS)
266$(KEYBOARD_OUTPUT)_INC := $(PROJECT_INC) 290$(KEYBOARD_OUTPUT)_INC := $(PROJECT_INC) $(GFXINC)
267$(KEYBOARD_OUTPUT)_CONFIG := $(PROJECT_CONFIG) 291$(KEYBOARD_OUTPUT)_CONFIG := $(PROJECT_CONFIG)
268 292
269# Default target. 293# Default target.
diff --git a/keyboards/ergodox/config.h b/keyboards/ergodox/config.h
index 361859832..994a8c643 100644
--- a/keyboards/ergodox/config.h
+++ b/keyboards/ergodox/config.h
@@ -34,4 +34,4 @@
34#endif 34#endif
35 35
36 36
37#endif /* KEYBOARDS_ERGODOX_CONFIG_H_ */ \ No newline at end of file 37#endif /* KEYBOARDS_ERGODOX_CONFIG_H_ */
diff --git a/keyboards/ergodox/ez/rules.mk b/keyboards/ergodox/ez/rules.mk
index 64b2db815..6cd1c0c4f 100644
--- a/keyboards/ergodox/ez/rules.mk
+++ b/keyboards/ergodox/ez/rules.mk
@@ -74,7 +74,3 @@ OPT_DEFS += -DBOOTLOADER_SIZE=512
74SLEEP_LED_ENABLE = no 74SLEEP_LED_ENABLE = no
75API_SYSEX_ENABLE ?= no 75API_SYSEX_ENABLE ?= no
76RGBLIGHT_ENABLE ?= yes 76RGBLIGHT_ENABLE ?= yes
77
78ifndef QUANTUM_DIR
79 include ../../../Makefile
80endif
diff --git a/keyboards/ergodox/infinity/Makefile b/keyboards/ergodox/infinity/Makefile
index 191c6bb66..bd09e5885 100644
--- a/keyboards/ergodox/infinity/Makefile
+++ b/keyboards/ergodox/infinity/Makefile
@@ -1,3 +1,3 @@
1ifndef MAKEFILE_INCLUDED 1ifndef MAKEFILE_INCLUDED
2 include ../../../Makefile 2 include ../../../Makefile
3endif \ No newline at end of file 3endif
diff --git a/keyboards/ergodox/infinity/animations.c b/keyboards/ergodox/infinity/animations.c
new file mode 100644
index 000000000..4c9f6d9c8
--- /dev/null
+++ b/keyboards/ergodox/infinity/animations.c
@@ -0,0 +1,107 @@
1/* Copyright 2017 Fred Sundvik
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#if defined(VISUALIZER_ENABLE)
18
19#include "animations.h"
20#include "visualizer.h"
21#ifdef LCD_ENABLE
22#include "lcd_keyframes.h"
23#endif
24#ifdef LCD_BACKLIGHT_ENABLE
25#include "lcd_backlight_keyframes.h"
26#endif
27
28#ifdef LED_ENABLE
29#include "led_keyframes.h"
30#endif
31
32#include "visualizer_keyframes.h"
33
34
35#if defined(LCD_ENABLE) && defined(LCD_BACKLIGHT_ENABLE)
36
37// Don't worry, if the startup animation is long, you can use the keyboard like normal
38// during that time
39keyframe_animation_t default_startup_animation = {
40 .num_frames = 4,
41 .loop = false,
42 .frame_lengths = {0, 0, 0, gfxMillisecondsToTicks(5000), 0},
43 .frame_functions = {
44 lcd_keyframe_enable,
45 backlight_keyframe_enable,
46 lcd_keyframe_draw_logo,
47 backlight_keyframe_animate_color,
48 },
49};
50
51keyframe_animation_t default_suspend_animation = {
52 .num_frames = 4,
53 .loop = false,
54 .frame_lengths = {0, gfxMillisecondsToTicks(1000), 0, 0},
55 .frame_functions = {
56 lcd_keyframe_display_layer_text,
57 backlight_keyframe_animate_color,
58 lcd_keyframe_disable,
59 backlight_keyframe_disable,
60 },
61};
62#endif
63
64#if defined(LED_ENABLE)
65#define CROSSFADE_TIME 1000
66#define GRADIENT_TIME 3000
67
68keyframe_animation_t led_test_animation = {
69 .num_frames = 14,
70 .loop = true,
71 .frame_lengths = {
72 gfxMillisecondsToTicks(1000), // fade in
73 gfxMillisecondsToTicks(1000), // no op (leds on)
74 gfxMillisecondsToTicks(1000), // fade out
75 gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade
76 gfxMillisecondsToTicks(GRADIENT_TIME), // left to rigt (outside in)
77 gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade
78 gfxMillisecondsToTicks(GRADIENT_TIME), // top_to_bottom
79 0, // mirror leds
80 gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade
81 gfxMillisecondsToTicks(GRADIENT_TIME), // left_to_right (mirrored, so inside out)
82 gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade
83 gfxMillisecondsToTicks(GRADIENT_TIME), // top_to_bottom
84 0, // normal leds
85 gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade
86
87 },
88 .frame_functions = {
89 led_keyframe_fade_in_all,
90 keyframe_no_operation,
91 led_keyframe_fade_out_all,
92 led_keyframe_crossfade,
93 led_keyframe_left_to_right_gradient,
94 led_keyframe_crossfade,
95 led_keyframe_top_to_bottom_gradient,
96 led_keyframe_mirror_orientation,
97 led_keyframe_crossfade,
98 led_keyframe_left_to_right_gradient,
99 led_keyframe_crossfade,
100 led_keyframe_top_to_bottom_gradient,
101 led_keyframe_normal_orientation,
102 led_keyframe_crossfade,
103 },
104};
105#endif
106
107#endif
diff --git a/keyboards/ergodox/infinity/animations.h b/keyboards/ergodox/infinity/animations.h
new file mode 100644
index 000000000..6d8b9830d
--- /dev/null
+++ b/keyboards/ergodox/infinity/animations.h
@@ -0,0 +1,30 @@
1/* Copyright 2017 Fred Sundvik
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef KEYBOARDS_ERGODOX_INFINITY_ANIMATIONS_H_
18#define KEYBOARDS_ERGODOX_INFINITY_ANIMATIONS_H_
19
20#include "visualizer.h"
21
22// You can use these default animations, but of course you can also write your own custom ones instead
23extern keyframe_animation_t default_startup_animation;
24extern keyframe_animation_t default_suspend_animation;
25
26// An animation for testing and demonstrating the led support, should probably not be used for real world
27// cases
28extern keyframe_animation_t led_test_animation;
29
30#endif /* KEYBOARDS_ERGODOX_INFINITY_ANIMATIONS_H_ */
diff --git a/keyboards/ergodox/infinity/config.h b/keyboards/ergodox/infinity/config.h
index 9e264083b..95f713819 100644
--- a/keyboards/ergodox/infinity/config.h
+++ b/keyboards/ergodox/infinity/config.h
@@ -40,7 +40,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
40/* number of backlight levels */ 40/* number of backlight levels */
41#define BACKLIGHT_LEVELS 3 41#define BACKLIGHT_LEVELS 3
42 42
43#define LED_BRIGHTNESS_LO 15 43#define LED_BRIGHTNESS_LO 100
44#define LED_BRIGHTNESS_HI 255 44#define LED_BRIGHTNESS_HI 255
45 45
46/* define if matrix has ghost */ 46/* define if matrix has ghost */
@@ -54,6 +54,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
54// The visualizer needs gfx thread priorities 54// The visualizer needs gfx thread priorities
55#define VISUALIZER_THREAD_PRIORITY (NORMAL_PRIORITY - 2) 55#define VISUALIZER_THREAD_PRIORITY (NORMAL_PRIORITY - 2)
56 56
57#define VISUALIZER_USER_DATA_SIZE 16
58
57/* 59/*
58 * Feature disable options 60 * Feature disable options
59 * These options are also useful to firmware size reduction. 61 * These options are also useful to firmware size reduction.
diff --git a/keyboards/ergodox/infinity/drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c b/keyboards/ergodox/infinity/drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c
index 1d21f0c49..ea09c4bb0 100644
--- a/keyboards/ergodox/infinity/drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c
+++ b/keyboards/ergodox/infinity/drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c
@@ -25,6 +25,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
25 25
26#include "board_IS31FL3731C.h" 26#include "board_IS31FL3731C.h"
27 27
28
29// Can't include led_tables from here
30extern const uint8_t CIE1931_CURVE[];
31
28/*===========================================================================*/ 32/*===========================================================================*/
29/* Driver local definitions. */ 33/* Driver local definitions. */
30/*===========================================================================*/ 34/*===========================================================================*/
@@ -100,37 +104,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
100 104
101#define IS31 105#define IS31
102 106
103//Generated by http://jared.geek.nz/2013/feb/linear-led-pwm
104const unsigned char cie[256] = {
105 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
106 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
107 2, 2, 2, 3, 3, 3, 3, 3, 3, 3,
108 3, 4, 4, 4, 4, 4, 4, 5, 5, 5,
109 5, 5, 6, 6, 6, 6, 6, 7, 7, 7,
110 7, 8, 8, 8, 8, 9, 9, 9, 10, 10,
111 10, 10, 11, 11, 11, 12, 12, 12, 13, 13,
112 13, 14, 14, 15, 15, 15, 16, 16, 17, 17,
113 17, 18, 18, 19, 19, 20, 20, 21, 21, 22,
114 22, 23, 23, 24, 24, 25, 25, 26, 26, 27,
115 28, 28, 29, 29, 30, 31, 31, 32, 32, 33,
116 34, 34, 35, 36, 37, 37, 38, 39, 39, 40,
117 41, 42, 43, 43, 44, 45, 46, 47, 47, 48,
118 49, 50, 51, 52, 53, 54, 54, 55, 56, 57,
119 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
120 68, 70, 71, 72, 73, 74, 75, 76, 77, 79,
121 80, 81, 82, 83, 85, 86, 87, 88, 90, 91,
122 92, 94, 95, 96, 98, 99, 100, 102, 103, 105,
123 106, 108, 109, 110, 112, 113, 115, 116, 118, 120,
124 121, 123, 124, 126, 128, 129, 131, 132, 134, 136,
125 138, 139, 141, 143, 145, 146, 148, 150, 152, 154,
126 155, 157, 159, 161, 163, 165, 167, 169, 171, 173,
127 175, 177, 179, 181, 183, 185, 187, 189, 191, 193,
128 196, 198, 200, 202, 204, 207, 209, 211, 214, 216,
129 218, 220, 223, 225, 228, 230, 232, 235, 237, 240,
130 242, 245, 247, 250, 252, 255,
131};
132
133
134/*===========================================================================*/ 107/*===========================================================================*/
135/* Driver local functions. */ 108/* Driver local functions. */
136/*===========================================================================*/ 109/*===========================================================================*/
@@ -231,7 +204,7 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
231 uint8_t* src = PRIV(g)->frame_buffer; 204 uint8_t* src = PRIV(g)->frame_buffer;
232 for (int y=0;y<GDISP_SCREEN_HEIGHT;y++) { 205 for (int y=0;y<GDISP_SCREEN_HEIGHT;y++) {
233 for (int x=0;x<GDISP_SCREEN_WIDTH;x++) { 206 for (int x=0;x<GDISP_SCREEN_WIDTH;x++) {
234 PRIV(g)->write_buffer[get_led_address(g, x, y)]=cie[*src]; 207 PRIV(g)->write_buffer[get_led_address(g, x, y)]=CIE1931_CURVE[*src];
235 ++src; 208 ++src;
236 } 209 }
237 } 210 }
diff --git a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/board_ST7565.h b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/board_ST7565.h
index 290571ce5..e8c17e6e3 100644
--- a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/board_ST7565.h
+++ b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/board_ST7565.h
@@ -8,8 +8,6 @@
8#ifndef _GDISP_LLD_BOARD_H 8#ifndef _GDISP_LLD_BOARD_H
9#define _GDISP_LLD_BOARD_H 9#define _GDISP_LLD_BOARD_H
10 10
11#include "print.h"
12
13#define ST7565_LCD_BIAS ST7565_LCD_BIAS_9 // actually 6 11#define ST7565_LCD_BIAS ST7565_LCD_BIAS_9 // actually 6
14#define ST7565_ADC ST7565_ADC_NORMAL 12#define ST7565_ADC ST7565_ADC_NORMAL
15#define ST7565_COM_SCAN ST7565_COM_SCAN_DEC 13#define ST7565_COM_SCAN ST7565_COM_SCAN_DEC
@@ -39,35 +37,49 @@
39// MSB First 37// MSB First
40// CLK Low by default 38// CLK Low by default
41static const SPIConfig spi1config = { 39static const SPIConfig spi1config = {
42 NULL, 40 // Operation complete callback or @p NULL.
43 /* HW dependent part.*/ 41 .end_cb = NULL,
44 ST7565_GPIOPORT, 42 //The chip select line port - when not using pcs.
45 ST7565_SS_PIN, 43 .ssport = ST7565_GPIOPORT,
46 SPIx_CTARn_FMSZ(7) 44 // brief The chip select line pad number - when not using pcs.
47 | SPIx_CTARn_ASC(7) 45 .sspad=ST7565_SS_PIN,
48 | SPIx_CTARn_DT(7) 46 // SPI initialization data.
49 | SPIx_CTARn_CSSCK(7) 47 .tar0 =
50 | SPIx_CTARn_PBR(0) 48 SPIx_CTARn_FMSZ(7) // Frame size = 8 bytes
51 | SPIx_CTARn_BR(7) 49 | SPIx_CTARn_ASC(1) // After SCK Delay Scaler (min 50 ns) = 55.56ns
52 //SPI_CR1_BR_0 50 | SPIx_CTARn_DT(0) // Delay After Transfer Scaler (no minimum)= 27.78ns
51 | SPIx_CTARn_CSSCK(0) // PCS to SCK Delay Scaler (min 20 ns) = 27.78ns
52 | SPIx_CTARn_PBR(0) // Baud Rate Prescaler = 2
53 | SPIx_CTARn_BR(0) // Baud rate (min 50ns) = 55.56ns
53}; 54};
54 55
55static bool_t st7565_is_data_mode = 1; 56static GFXINLINE void acquire_bus(GDisplay *g) {
57 (void) g;
58 // Only the LCD is using the SPI bus, so no need to acquire
59 // spiAcquireBus(&SPID1);
60 spiSelect(&SPID1);
61}
62
63static GFXINLINE void release_bus(GDisplay *g) {
64 (void) g;
65 // Only the LCD is using the SPI bus, so no need to release
66 //spiReleaseBus(&SPID1);
67 spiUnselect(&SPID1);
68}
56 69
57static GFXINLINE void init_board(GDisplay *g) { 70static GFXINLINE void init_board(GDisplay *g) {
58 (void) g; 71 (void) g;
59 palSetPadModeNamed(A0, PAL_MODE_OUTPUT_PUSHPULL); 72 palSetPadModeNamed(A0, PAL_MODE_OUTPUT_PUSHPULL);
60 palSetPad(ST7565_GPIOPORT, ST7565_A0_PIN); 73 palSetPad(ST7565_GPIOPORT, ST7565_A0_PIN);
61 st7565_is_data_mode = 1;
62 palSetPadModeNamed(RST, PAL_MODE_OUTPUT_PUSHPULL); 74 palSetPadModeNamed(RST, PAL_MODE_OUTPUT_PUSHPULL);
63 palSetPad(ST7565_GPIOPORT, ST7565_RST_PIN); 75 palSetPad(ST7565_GPIOPORT, ST7565_RST_PIN);
64 palSetPadModeRaw(MOSI, ST7565_SPI_MODE); 76 palSetPadModeRaw(MOSI, ST7565_SPI_MODE);
65 palSetPadModeRaw(SLCK, ST7565_SPI_MODE); 77 palSetPadModeRaw(SLCK, ST7565_SPI_MODE);
66 palSetPadModeRaw(SS, ST7565_SPI_MODE); 78 palSetPadModeRaw(SS, PAL_MODE_OUTPUT_PUSHPULL);
67 79
68 spiInit(); 80 spiInit();
69 spiStart(&SPID1, &spi1config); 81 spiStart(&SPID1, &spi1config);
70 spiSelect(&SPID1); 82 release_bus(g);
71} 83}
72 84
73static GFXINLINE void post_init_board(GDisplay *g) { 85static GFXINLINE void post_init_board(GDisplay *g) {
@@ -84,43 +96,17 @@ static GFXINLINE void setpin_reset(GDisplay *g, bool_t state) {
84 } 96 }
85} 97}
86 98
87static GFXINLINE void acquire_bus(GDisplay *g) { 99static GFXINLINE void enter_data_mode(GDisplay *g) {
88 (void) g; 100 palSetPad(ST7565_GPIOPORT, ST7565_A0_PIN);
89 // Only the LCD is using the SPI bus, so no need to acquire
90 // spiAcquireBus(&SPID1);
91} 101}
92 102
93static GFXINLINE void release_bus(GDisplay *g) { 103static GFXINLINE void enter_cmd_mode(GDisplay *g) {
94 (void) g; 104 palClearPad(ST7565_GPIOPORT, ST7565_A0_PIN);
95 // Only the LCD is using the SPI bus, so no need to release
96 //spiReleaseBus(&SPID1);
97} 105}
98 106
99static GFXINLINE void write_cmd(GDisplay *g, uint8_t cmd) {
100 (void) g;
101 if (st7565_is_data_mode) {
102 // The sleeps need to be at lest 10 vs 25 ns respectively
103 // So let's sleep two ticks, one tick might not be enough
104 // if we are at the end of the tick
105 chThdSleep(2);
106 palClearPad(ST7565_GPIOPORT, ST7565_A0_PIN);
107 chThdSleep(2);
108 st7565_is_data_mode = 0;
109 }
110 spiSend(&SPID1, 1, &cmd);
111}
112 107
113static GFXINLINE void write_data(GDisplay *g, uint8_t* data, uint16_t length) { 108static GFXINLINE void write_data(GDisplay *g, uint8_t* data, uint16_t length) {
114 (void) g; 109 (void) g;
115 if (!st7565_is_data_mode) {
116 // The sleeps need to be at lest 10 vs 25 ns respectively
117 // So let's sleep two ticks, one tick might not be enough
118 // if we are at the end of the tick
119 chThdSleep(2);
120 palSetPad(ST7565_GPIOPORT, ST7565_A0_PIN);
121 chThdSleep(2);
122 st7565_is_data_mode = 1;
123 }
124 spiSend(&SPID1, length, data); 110 spiSend(&SPID1, length, data);
125} 111}
126 112
diff --git a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c
index c33aea81a..b04ad0293 100644
--- a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c
+++ b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c
@@ -20,16 +20,16 @@
20/*===========================================================================*/ 20/*===========================================================================*/
21 21
22#ifndef GDISP_SCREEN_HEIGHT 22#ifndef GDISP_SCREEN_HEIGHT
23 #define GDISP_SCREEN_HEIGHT 32 23#define GDISP_SCREEN_HEIGHT 32
24#endif 24#endif
25#ifndef GDISP_SCREEN_WIDTH 25#ifndef GDISP_SCREEN_WIDTH
26 #define GDISP_SCREEN_WIDTH 128 26#define GDISP_SCREEN_WIDTH 128
27#endif 27#endif
28#ifndef GDISP_INITIAL_CONTRAST 28#ifndef GDISP_INITIAL_CONTRAST
29 #define GDISP_INITIAL_CONTRAST 0 29#define GDISP_INITIAL_CONTRAST 35
30#endif 30#endif
31#ifndef GDISP_INITIAL_BACKLIGHT 31#ifndef GDISP_INITIAL_BACKLIGHT
32 #define GDISP_INITIAL_BACKLIGHT 100 32#define GDISP_INITIAL_BACKLIGHT 100
33#endif 33#endif
34 34
35#define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER<<0) 35#define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER<<0)
@@ -40,16 +40,16 @@
40/* Driver config defaults for backward compatibility. */ 40/* Driver config defaults for backward compatibility. */
41/*===========================================================================*/ 41/*===========================================================================*/
42#ifndef ST7565_LCD_BIAS 42#ifndef ST7565_LCD_BIAS
43 #define ST7565_LCD_BIAS ST7565_LCD_BIAS_7 43#define ST7565_LCD_BIAS ST7565_LCD_BIAS_7
44#endif 44#endif
45#ifndef ST7565_ADC 45#ifndef ST7565_ADC
46 #define ST7565_ADC ST7565_ADC_NORMAL 46#define ST7565_ADC ST7565_ADC_NORMAL
47#endif 47#endif
48#ifndef ST7565_COM_SCAN 48#ifndef ST7565_COM_SCAN
49 #define ST7565_COM_SCAN ST7565_COM_SCAN_INC 49#define ST7565_COM_SCAN ST7565_COM_SCAN_INC
50#endif 50#endif
51#ifndef ST7565_PAGE_ORDER 51#ifndef ST7565_PAGE_ORDER
52 #define ST7565_PAGE_ORDER 0,1,2,3 52#define ST7565_PAGE_ORDER 0,1,2,3
53#endif 53#endif
54 54
55/*===========================================================================*/ 55/*===========================================================================*/
@@ -58,12 +58,24 @@
58 58
59typedef struct{ 59typedef struct{
60 bool_t buffer2; 60 bool_t buffer2;
61 uint8_t data_pos;
62 uint8_t data[16];
61 uint8_t ram[GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH / 8]; 63 uint8_t ram[GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH / 8];
62}PrivData; 64}PrivData;
63 65
64// Some common routines and macros 66// Some common routines and macros
65#define PRIV(g) ((PrivData*)g->priv) 67#define PRIV(g) ((PrivData*)g->priv)
66#define RAM(g) (PRIV(g)->ram) 68#define RAM(g) (PRIV(g)->ram)
69
70static GFXINLINE void write_cmd(GDisplay* g, uint8_t cmd) {
71 PRIV(g)->data[PRIV(g)->data_pos++] = cmd;
72}
73
74static GFXINLINE void flush_cmd(GDisplay* g) {
75 write_data(g, PRIV(g)->data, PRIV(g)->data_pos);
76 PRIV(g)->data_pos = 0;
77}
78
67#define write_cmd2(g, cmd1, cmd2) { write_cmd(g, cmd1); write_cmd(g, cmd2); } 79#define write_cmd2(g, cmd1, cmd2) { write_cmd(g, cmd1); write_cmd(g, cmd2); }
68#define write_cmd3(g, cmd1, cmd2, cmd3) { write_cmd(g, cmd1); write_cmd(g, cmd2); write_cmd(g, cmd3); } 80#define write_cmd3(g, cmd1, cmd2, cmd3) { write_cmd(g, cmd1); write_cmd(g, cmd2); write_cmd(g, cmd3); }
69 81
@@ -86,207 +98,232 @@ typedef struct{
86 */ 98 */
87 99
88LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { 100LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
89 // The private area is the display surface. 101 // The private area is the display surface.
90 g->priv = gfxAlloc(sizeof(PrivData)); 102 g->priv = gfxAlloc(sizeof(PrivData));
91 PRIV(g)->buffer2 = false; 103 PRIV(g)->buffer2 = false;
92 104 PRIV(g)->data_pos = 0;
93 // Initialise the board interface 105
94 init_board(g); 106 // Initialise the board interface
95 107 init_board(g);
96 // Hardware reset 108
97 setpin_reset(g, TRUE); 109 // Hardware reset
98 gfxSleepMilliseconds(20); 110 setpin_reset(g, TRUE);
99 setpin_reset(g, FALSE); 111 gfxSleepMilliseconds(20);
100 gfxSleepMilliseconds(20); 112 setpin_reset(g, FALSE);
101 113 gfxSleepMilliseconds(20);
102 acquire_bus(g); 114 acquire_bus(g);
103 write_cmd(g, ST7565_DISPLAY_OFF); 115 enter_cmd_mode(g);
104 write_cmd(g, ST7565_LCD_BIAS); 116
117 write_cmd(g, ST7565_RESET);
118 write_cmd(g, ST7565_LCD_BIAS);
105 write_cmd(g, ST7565_ADC); 119 write_cmd(g, ST7565_ADC);
106 write_cmd(g, ST7565_COM_SCAN); 120 write_cmd(g, ST7565_COM_SCAN);
107
108 write_cmd(g, ST7565_START_LINE | 0);
109
110 write_cmd(g, ST7565_RESISTOR_RATIO | 0x6);
111
112 // turn on voltage converter (VC=1, VR=0, VF=0)
113 write_cmd(g, ST7565_POWER_CONTROL | 0x04);
114 delay_ms(50);
115 121
116 // turn on voltage regulator (VC=1, VR=1, VF=0) 122 write_cmd(g, ST7565_RESISTOR_RATIO | 0x1);
117 write_cmd(g, ST7565_POWER_CONTROL | 0x06); 123 write_cmd2(g, ST7565_CONTRAST, GDISP_INITIAL_CONTRAST);
118 delay_ms(50);
119 124
120 // turn on voltage follower (VC=1, VR=1, VF=1) 125 // turn on internal power supply (VC=1, VR=1, VF=1)
121 write_cmd(g, ST7565_POWER_CONTROL | 0x07); 126 write_cmd(g, ST7565_POWER_CONTROL | 0x07);
122 delay_ms(50);
123 127
124 write_cmd(g, 0xE2); 128 write_cmd(g, ST7565_INVERT_DISPLAY);
125 write_cmd(g, ST7565_COM_SCAN); 129 write_cmd(g, ST7565_ALLON_NORMAL);
126 write_cmd2(g, ST7565_CONTRAST, GDISP_INITIAL_CONTRAST*64/101);
127 //write_cmd2(g, ST7565_CONTRAST, 0);
128 write_cmd(g, ST7565_DISPLAY_ON);
129 write_cmd(g, ST7565_ALLON_NORMAL);
130 write_cmd(g, ST7565_INVERT_DISPLAY);
131 130
132 write_cmd(g, ST7565_RMW); 131 write_cmd(g, ST7565_START_LINE | 0);
132 write_cmd(g, ST7565_RMW);
133 flush_cmd(g);
133 134
134 // Finish Init 135 // Finish Init
135 post_init_board(g); 136 post_init_board(g);
136 137
137 // Release the bus 138 // Release the bus
138 release_bus(g); 139 release_bus(g);
139 140
140 /* Initialise the GDISP structure */ 141 /* Initialise the GDISP structure */
141 g->g.Width = GDISP_SCREEN_WIDTH; 142 g->g.Width = GDISP_SCREEN_WIDTH;
142 g->g.Height = GDISP_SCREEN_HEIGHT; 143 g->g.Height = GDISP_SCREEN_HEIGHT;
143 g->g.Orientation = GDISP_ROTATE_0; 144 g->g.Orientation = GDISP_ROTATE_0;
144 g->g.Powermode = powerOn; 145 g->g.Powermode = powerOff;
145 g->g.Backlight = GDISP_INITIAL_BACKLIGHT; 146 g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
146 g->g.Contrast = GDISP_INITIAL_CONTRAST; 147 g->g.Contrast = GDISP_INITIAL_CONTRAST;
147 return TRUE; 148 return TRUE;
148} 149}
149 150
150#if GDISP_HARDWARE_FLUSH 151#if GDISP_HARDWARE_FLUSH
151 LLDSPEC void gdisp_lld_flush(GDisplay *g) { 152LLDSPEC void gdisp_lld_flush(GDisplay *g) {
152 unsigned p; 153 unsigned p;
153 154
154 // Don't flush if we don't need it. 155 // Don't flush if we don't need it.
155 if (!(g->flags & GDISP_FLG_NEEDFLUSH)) 156 if (!(g->flags & GDISP_FLG_NEEDFLUSH))
156 return; 157 return;
157 158
158 acquire_bus(g); 159 acquire_bus(g);
159 unsigned dstOffset = (PRIV(g)->buffer2 ? 4 : 0); 160 enter_cmd_mode(g);
160 for (p = 0; p < 4; p++) { 161 unsigned dstOffset = (PRIV(g)->buffer2 ? 4 : 0);
161 write_cmd(g, ST7565_PAGE | (p + dstOffset)); 162 for (p = 0; p < 4; p++) {
162 write_cmd(g, ST7565_COLUMN_MSB | 0); 163 write_cmd(g, ST7565_PAGE | (p + dstOffset));
163 write_cmd(g, ST7565_COLUMN_LSB | 0); 164 write_cmd(g, ST7565_COLUMN_MSB | 0);
164 write_cmd(g, ST7565_RMW); 165 write_cmd(g, ST7565_COLUMN_LSB | 0);
165 write_data(g, RAM(g) + (p*GDISP_SCREEN_WIDTH), GDISP_SCREEN_WIDTH); 166 write_cmd(g, ST7565_RMW);
166 } 167 flush_cmd(g);
167 unsigned line = (PRIV(g)->buffer2 ? 32 : 0); 168 enter_data_mode(g);
168 write_cmd(g, ST7565_START_LINE | line); 169 write_data(g, RAM(g) + (p*GDISP_SCREEN_WIDTH), GDISP_SCREEN_WIDTH);
169 PRIV(g)->buffer2 = !PRIV(g)->buffer2; 170 enter_cmd_mode(g);
170 release_bus(g); 171 }
171 172 unsigned line = (PRIV(g)->buffer2 ? 32 : 0);
172 g->flags &= ~GDISP_FLG_NEEDFLUSH; 173 write_cmd(g, ST7565_START_LINE | line);
173 } 174 flush_cmd(g);
175 PRIV(g)->buffer2 = !PRIV(g)->buffer2;
176 release_bus(g);
177
178 g->flags &= ~GDISP_FLG_NEEDFLUSH;
179}
174#endif 180#endif
175 181
176#if GDISP_HARDWARE_DRAWPIXEL 182#if GDISP_HARDWARE_DRAWPIXEL
177 LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { 183LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
178 coord_t x, y; 184 coord_t x, y;
179 185
180 switch(g->g.Orientation) { 186 switch(g->g.Orientation) {
181 default: 187 default:
182 case GDISP_ROTATE_0: 188 case GDISP_ROTATE_0:
183 x = g->p.x; 189 x = g->p.x;
184 y = g->p.y; 190 y = g->p.y;
185 break; 191 break;
186 case GDISP_ROTATE_90: 192 case GDISP_ROTATE_90:
187 x = g->p.y; 193 x = g->p.y;
188 y = GDISP_SCREEN_HEIGHT-1 - g->p.x; 194 y = GDISP_SCREEN_HEIGHT-1 - g->p.x;
189 break; 195 break;
190 case GDISP_ROTATE_180: 196 case GDISP_ROTATE_180:
191 x = GDISP_SCREEN_WIDTH-1 - g->p.x; 197 x = GDISP_SCREEN_WIDTH-1 - g->p.x;
192 y = GDISP_SCREEN_HEIGHT-1 - g->p.y; 198 y = GDISP_SCREEN_HEIGHT-1 - g->p.y;
193 break; 199 break;
194 case GDISP_ROTATE_270: 200 case GDISP_ROTATE_270:
195 x = GDISP_SCREEN_HEIGHT-1 - g->p.y; 201 x = GDISP_SCREEN_HEIGHT-1 - g->p.y;
196 y = g->p.x; 202 y = g->p.x;
197 break; 203 break;
198 } 204 }
199 if (gdispColor2Native(g->p.color) != Black) 205 if (gdispColor2Native(g->p.color) != Black)
200 RAM(g)[xyaddr(x, y)] |= xybit(y); 206 RAM(g)[xyaddr(x, y)] |= xybit(y);
201 else 207 else
202 RAM(g)[xyaddr(x, y)] &= ~xybit(y); 208 RAM(g)[xyaddr(x, y)] &= ~xybit(y);
203 g->flags |= GDISP_FLG_NEEDFLUSH; 209 g->flags |= GDISP_FLG_NEEDFLUSH;
204 } 210}
205#endif 211#endif
206 212
207#if GDISP_HARDWARE_PIXELREAD 213#if GDISP_HARDWARE_PIXELREAD
208 LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) { 214LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) {
209 coord_t x, y; 215 coord_t x, y;
210 216
211 switch(g->g.Orientation) { 217 switch(g->g.Orientation) {
212 default: 218 default:
213 case GDISP_ROTATE_0: 219 case GDISP_ROTATE_0:
214 x = g->p.x; 220 x = g->p.x;
215 y = g->p.y; 221 y = g->p.y;
216 break; 222 break;
217 case GDISP_ROTATE_90: 223 case GDISP_ROTATE_90:
218 x = g->p.y; 224 x = g->p.y;
219 y = GDISP_SCREEN_HEIGHT-1 - g->p.x; 225 y = GDISP_SCREEN_HEIGHT-1 - g->p.x;
220 break; 226 break;
221 case GDISP_ROTATE_180: 227 case GDISP_ROTATE_180:
222 x = GDISP_SCREEN_WIDTH-1 - g->p.x; 228 x = GDISP_SCREEN_WIDTH-1 - g->p.x;
223 y = GDISP_SCREEN_HEIGHT-1 - g->p.y; 229 y = GDISP_SCREEN_HEIGHT-1 - g->p.y;
224 break; 230 break;
225 case GDISP_ROTATE_270: 231 case GDISP_ROTATE_270:
226 x = GDISP_SCREEN_HEIGHT-1 - g->p.y; 232 x = GDISP_SCREEN_HEIGHT-1 - g->p.y;
227 y = g->p.x; 233 y = g->p.x;
228 break; 234 break;
229 } 235 }
230 return (RAM(g)[xyaddr(x, y)] & xybit(y)) ? White : Black; 236 return (RAM(g)[xyaddr(x, y)] & xybit(y)) ? White : Black;
231 } 237}
232#endif 238#endif
233 239
240LLDSPEC void gdisp_lld_blit_area(GDisplay *g) {
241 uint8_t* buffer = (uint8_t*)g->p.ptr;
242 int linelength = g->p.cx;
243 for (int i = 0; i < g->p.cy; i++) {
244 unsigned dstx = g->p.x;
245 unsigned dsty = g->p.y + i;
246 unsigned srcx = g->p.x1;
247 unsigned srcy = g->p.y1 + i;
248 unsigned srcbit = srcy * g->p.x2 + srcx;
249 for(int j=0; j < linelength; j++) {
250 uint8_t src = buffer[srcbit / 8];
251 uint8_t bit = 7-(srcbit % 8);
252 uint8_t bitset = (src >> bit) & 1;
253 uint8_t* dst = &(RAM(g)[xyaddr(dstx, dsty)]);
254 if (bitset) {
255 *dst |= xybit(dsty);
256 }
257 else {
258 *dst &= ~xybit(dsty);
259 }
260 dstx++;
261 srcbit++;
262 }
263 }
264 g->flags |= GDISP_FLG_NEEDFLUSH;
265}
266
234#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL 267#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
235 LLDSPEC void gdisp_lld_control(GDisplay *g) { 268LLDSPEC void gdisp_lld_control(GDisplay *g) {
236 switch(g->p.x) { 269 switch(g->p.x) {
237 case GDISP_CONTROL_POWER: 270 case GDISP_CONTROL_POWER:
238 if (g->g.Powermode == (powermode_t)g->p.ptr) 271 if (g->g.Powermode == (powermode_t)g->p.ptr)
239 return; 272 return;
240 switch((powermode_t)g->p.ptr) { 273 switch((powermode_t)g->p.ptr) {
241 case powerOff: 274 case powerOff:
242 case powerSleep: 275 case powerSleep:
243 case powerDeepSleep: 276 case powerDeepSleep:
244 acquire_bus(g); 277 acquire_bus(g);
245 write_cmd(g, ST7565_DISPLAY_OFF); 278 enter_cmd_mode(g);
246 release_bus(g); 279 write_cmd(g, ST7565_DISPLAY_OFF);
247 break; 280 flush_cmd(g);
248 case powerOn: 281 release_bus(g);
249 acquire_bus(g); 282 break;
250 write_cmd(g, ST7565_DISPLAY_ON); 283 case powerOn:
251 release_bus(g); 284 acquire_bus(g);
252 break; 285 enter_cmd_mode(g);
253 default: 286 write_cmd(g, ST7565_DISPLAY_ON);
254 return; 287 flush_cmd(g);
255 } 288 release_bus(g);
256 g->g.Powermode = (powermode_t)g->p.ptr; 289 break;
257 return; 290 default:
258 291 return;
259 case GDISP_CONTROL_ORIENTATION: 292 }
260 if (g->g.Orientation == (orientation_t)g->p.ptr) 293 g->g.Powermode = (powermode_t)g->p.ptr;
261 return; 294 return;
262 switch((orientation_t)g->p.ptr) { 295
263 /* Rotation is handled by the drawing routines */ 296 case GDISP_CONTROL_ORIENTATION:
264 case GDISP_ROTATE_0: 297 if (g->g.Orientation == (orientation_t)g->p.ptr)
265 case GDISP_ROTATE_180: 298 return;
266 g->g.Height = GDISP_SCREEN_HEIGHT; 299 switch((orientation_t)g->p.ptr) {
267 g->g.Width = GDISP_SCREEN_WIDTH; 300 /* Rotation is handled by the drawing routines */
268 break; 301 case GDISP_ROTATE_0:
269 case GDISP_ROTATE_90: 302 case GDISP_ROTATE_180:
270 case GDISP_ROTATE_270: 303 g->g.Height = GDISP_SCREEN_HEIGHT;
271 g->g.Height = GDISP_SCREEN_WIDTH; 304 g->g.Width = GDISP_SCREEN_WIDTH;
272 g->g.Width = GDISP_SCREEN_HEIGHT; 305 break;
273 break; 306 case GDISP_ROTATE_90:
274 default: 307 case GDISP_ROTATE_270:
275 return; 308 g->g.Height = GDISP_SCREEN_WIDTH;
276 } 309 g->g.Width = GDISP_SCREEN_HEIGHT;
277 g->g.Orientation = (orientation_t)g->p.ptr; 310 break;
278 return; 311 default:
279 312 return;
280 case GDISP_CONTROL_CONTRAST: 313 }
281 if ((unsigned)g->p.ptr > 100) 314 g->g.Orientation = (orientation_t)g->p.ptr;
282 g->p.ptr = (void *)100; 315 return;
283 acquire_bus(g); 316
284 write_cmd2(g, ST7565_CONTRAST, ((((unsigned)g->p.ptr)<<6)/101) & 0x3F); 317 case GDISP_CONTROL_CONTRAST:
285 release_bus(g); 318 g->g.Contrast = (unsigned)g->p.ptr & 63;
286 g->g.Contrast = (unsigned)g->p.ptr; 319 acquire_bus(g);
287 return; 320 enter_cmd_mode(g);
288 } 321 write_cmd2(g, ST7565_CONTRAST, g->g.Contrast);
289 } 322 flush_cmd(g);
323 release_bus(g);
324 return;
325 }
326}
290#endif // GDISP_NEED_CONTROL 327#endif // GDISP_NEED_CONTROL
291 328
292#endif // GFX_USE_GDISP 329#endif // GFX_USE_GDISP
diff --git a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_config.h b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_config.h
index 48587b9e1..2b66a877c 100644
--- a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_config.h
+++ b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_config.h
@@ -14,12 +14,13 @@
14/* Driver hardware support. */ 14/* Driver hardware support. */
15/*===========================================================================*/ 15/*===========================================================================*/
16 16
17#define GDISP_HARDWARE_FLUSH TRUE // This controller requires flushing 17#define GDISP_HARDWARE_FLUSH TRUE // This controller requires flushing
18#define GDISP_HARDWARE_DRAWPIXEL TRUE 18#define GDISP_HARDWARE_DRAWPIXEL TRUE
19#define GDISP_HARDWARE_PIXELREAD TRUE 19#define GDISP_HARDWARE_PIXELREAD TRUE
20#define GDISP_HARDWARE_CONTROL TRUE 20#define GDISP_HARDWARE_CONTROL TRUE
21#define GDISP_HARDWARE_BITFILLS TRUE
21 22
22#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_MONO 23#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_MONO
23 24
24#endif /* GFX_USE_GDISP */ 25#endif /* GFX_USE_GDISP */
25 26
diff --git a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/st7565.h b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/st7565.h
index 48636b33d..24924ff05 100644
--- a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/st7565.h
+++ b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/st7565.h
@@ -34,4 +34,6 @@
34#define ST7565_RESISTOR_RATIO 0x20 34#define ST7565_RESISTOR_RATIO 0x20
35#define ST7565_POWER_CONTROL 0x28 35#define ST7565_POWER_CONTROL 0x28
36 36
37#define ST7565_RESET 0xE2
38
37#endif /* _ST7565_H */ 39#endif /* _ST7565_H */
diff --git a/keyboards/ergodox/infinity/gfxconf.h b/keyboards/ergodox/infinity/gfxconf.h
index 8caa577b7..45b9f5858 100644
--- a/keyboards/ergodox/infinity/gfxconf.h
+++ b/keyboards/ergodox/infinity/gfxconf.h
@@ -143,7 +143,7 @@
143 #define GDISP_HARDWARE_DRAWPIXEL TRUE 143 #define GDISP_HARDWARE_DRAWPIXEL TRUE
144 #define GDISP_HARDWARE_CLEARS FALSE 144 #define GDISP_HARDWARE_CLEARS FALSE
145 #define GDISP_HARDWARE_FILLS FALSE 145 #define GDISP_HARDWARE_FILLS FALSE
146 #define GDISP_HARDWARE_BITFILLS FALSE 146 //#define GDISP_HARDWARE_BITFILLS FALSE
147 #define GDISP_HARDWARE_SCROLL FALSE 147 #define GDISP_HARDWARE_SCROLL FALSE
148 #define GDISP_HARDWARE_PIXELREAD TRUE 148 #define GDISP_HARDWARE_PIXELREAD TRUE
149 #define GDISP_HARDWARE_CONTROL TRUE 149 #define GDISP_HARDWARE_CONTROL TRUE
diff --git a/keyboards/ergodox/infinity/infinity.c b/keyboards/ergodox/infinity/infinity.c
index 02db67eaf..62259ed3f 100644
--- a/keyboards/ergodox/infinity/infinity.c
+++ b/keyboards/ergodox/infinity/infinity.c
@@ -70,10 +70,33 @@ void lcd_backlight_hal_init(void) {
70 RGB_PORT->PCR[BLUE_PIN] = RGB_MODE; 70 RGB_PORT->PCR[BLUE_PIN] = RGB_MODE;
71} 71}
72 72
73static uint16_t cie_lightness(uint16_t v) {
74 // The CIE 1931 formula for lightness
75 // Y = luminance (output) 0-1
76 // L = lightness input 0 - 100
77
78 // Y = (L* / 902.3) if L* <= 8
79 // Y = ((L* + 16) / 116)^3 if L* > 8
80
81 float l = 100.0f * (v / 65535.0f);
82 float y = 0.0f;
83 if (l <= 8.0f) {
84 y = l / 902.3;
85 }
86 else {
87 y = ((l + 16.0f) / 116.0f);
88 y = y * y * y;
89 if (y > 1.0f) {
90 y = 1.0f;
91 }
92 }
93 return y * 65535.0f;
94}
95
73void lcd_backlight_hal_color(uint16_t r, uint16_t g, uint16_t b) { 96void lcd_backlight_hal_color(uint16_t r, uint16_t g, uint16_t b) {
74 CHANNEL_RED.CnV = r; 97 CHANNEL_RED.CnV = cie_lightness(r);
75 CHANNEL_GREEN.CnV = g; 98 CHANNEL_GREEN.CnV = cie_lightness(g);
76 CHANNEL_BLUE.CnV = b; 99 CHANNEL_BLUE.CnV = cie_lightness(b);
77} 100}
78 101
79__attribute__ ((weak)) 102__attribute__ ((weak))
@@ -103,34 +126,48 @@ void matrix_scan_kb(void) {
103 matrix_scan_user(); 126 matrix_scan_user();
104} 127}
105 128
129__attribute__ ((weak))
106void ergodox_board_led_on(void){ 130void ergodox_board_led_on(void){
107} 131}
108 132
133__attribute__ ((weak))
109void ergodox_right_led_1_on(void){ 134void ergodox_right_led_1_on(void){
110} 135}
111 136
137__attribute__ ((weak))
112void ergodox_right_led_2_on(void){ 138void ergodox_right_led_2_on(void){
113} 139}
114 140
141__attribute__ ((weak))
115void ergodox_right_led_3_on(void){ 142void ergodox_right_led_3_on(void){
116} 143}
117 144
118void ergodox_right_led_on(uint8_t led){ 145__attribute__ ((weak))
119}
120
121void ergodox_board_led_off(void){ 146void ergodox_board_led_off(void){
122} 147}
123 148
149__attribute__ ((weak))
124void ergodox_right_led_1_off(void){ 150void ergodox_right_led_1_off(void){
125} 151}
126 152
153__attribute__ ((weak))
127void ergodox_right_led_2_off(void){ 154void ergodox_right_led_2_off(void){
128} 155}
129 156
157__attribute__ ((weak))
130void ergodox_right_led_3_off(void){ 158void ergodox_right_led_3_off(void){
131} 159}
132 160
133void ergodox_right_led_off(uint8_t led){ 161__attribute__ ((weak))
162void ergodox_right_led_1_set(uint8_t n) {
163}
164
165__attribute__ ((weak))
166void ergodox_right_led_2_set(uint8_t n) {
167}
168
169__attribute__ ((weak))
170void ergodox_right_led_3_set(uint8_t n) {
134} 171}
135 172
136#ifdef ONEHAND_ENABLE 173#ifdef ONEHAND_ENABLE
diff --git a/keyboards/ergodox/infinity/infinity.h b/keyboards/ergodox/infinity/infinity.h
index fec9e565c..73a0f4bf7 100644
--- a/keyboards/ergodox/infinity/infinity.h
+++ b/keyboards/ergodox/infinity/infinity.h
@@ -7,13 +7,38 @@ void ergodox_board_led_on(void);
7void ergodox_right_led_1_on(void); 7void ergodox_right_led_1_on(void);
8void ergodox_right_led_2_on(void); 8void ergodox_right_led_2_on(void);
9void ergodox_right_led_3_on(void); 9void ergodox_right_led_3_on(void);
10void ergodox_right_led_on(uint8_t led); 10
11inline void ergodox_right_led_on(uint8_t led) {
12 switch (led) {
13 case 0:
14 ergodox_right_led_1_on();
15 break;
16 case 1:
17 ergodox_right_led_2_on();
18 break;
19 case 2:
20 ergodox_right_led_3_on();
21 break;
22 }
23}
11 24
12void ergodox_board_led_off(void); 25void ergodox_board_led_off(void);
13void ergodox_right_led_1_off(void); 26void ergodox_right_led_1_off(void);
14void ergodox_right_led_2_off(void); 27void ergodox_right_led_2_off(void);
15void ergodox_right_led_3_off(void); 28void ergodox_right_led_3_off(void);
16void ergodox_right_led_off(uint8_t led); 29inline void ergodox_right_led_off(uint8_t led) {
30 switch (led) {
31 case 0:
32 ergodox_right_led_1_off();
33 break;
34 case 1:
35 ergodox_right_led_2_off();
36 break;
37 case 2:
38 ergodox_right_led_3_off();
39 break;
40 }
41}
17 42
18inline void ergodox_led_all_on(void) 43inline void ergodox_led_all_on(void)
19{ 44{
@@ -31,36 +56,22 @@ inline void ergodox_led_all_off(void)
31 ergodox_right_led_3_off(); 56 ergodox_right_led_3_off();
32} 57}
33 58
34inline void ergodox_right_led_1_set(uint8_t n){ 59void ergodox_right_led_1_set(uint8_t n);
35 if (n) { 60void ergodox_right_led_2_set(uint8_t n);
36 ergodox_right_led_1_on(); 61void ergodox_right_led_3_set(uint8_t n);
37 } else {
38 ergodox_right_led_1_off();
39 }
40}
41
42inline void ergodox_right_led_2_set(uint8_t n){
43 if (n) {
44 ergodox_right_led_2_on();
45 } else {
46 ergodox_right_led_2_off();
47 }
48}
49
50inline void ergodox_right_led_3_set(uint8_t n){
51 if (n) {
52 ergodox_right_led_3_on();
53 } else {
54 ergodox_right_led_3_off();
55 }
56}
57 62
58inline void ergodox_right_led_set(uint8_t led, uint8_t n){ 63inline void ergodox_right_led_set(uint8_t led, uint8_t n){
59 if (n) { 64 switch (led) {
60 ergodox_right_led_on(led); 65 case 0:
61 } else { 66 ergodox_right_led_1_set(n);
62 ergodox_right_led_off(led); 67 break;
63 } 68 case 1:
69 ergodox_right_led_2_set(n);
70 break;
71 case 2:
72 ergodox_right_led_3_set(n);
73 break;
74 }
64} 75}
65 76
66inline void ergodox_led_all_set(uint8_t n) { 77inline void ergodox_led_all_set(uint8_t n) {
diff --git a/keyboards/ergodox/infinity/rules.mk b/keyboards/ergodox/infinity/rules.mk
index 473a6dfec..9e6170d89 100644
--- a/keyboards/ergodox/infinity/rules.mk
+++ b/keyboards/ergodox/infinity/rules.mk
@@ -1,6 +1,7 @@
1# project specific files 1# project specific files
2SRC = matrix.c \ 2SRC = matrix.c \
3 led.c 3 led.c \
4 animations.c
4 5
5## chip/board settings 6## chip/board settings
6# - the next two should match the directories in 7# - the next two should match the directories in
@@ -59,21 +60,17 @@ OPT_DEFS += -DCORTEX_VTOR_INIT=0x00002000
59# 60#
60CUSTOM_MATRIX ?= yes # Custom matrix file 61CUSTOM_MATRIX ?= yes # Custom matrix file
61SERIAL_LINK_ENABLE = yes 62SERIAL_LINK_ENABLE = yes
62VISUALIZER_ENABLE ?= no #temporarily disabled to make everything compile 63VISUALIZER_ENABLE ?= yes
63LCD_ENABLE ?= yes 64LCD_ENABLE ?= yes
64LED_ENABLE ?= yes 65LED_ENABLE ?= no
65LCD_BACKLIGHT_ENABLE ?= yes 66LCD_BACKLIGHT_ENABLE ?= yes
66MIDI_ENABLE = no 67MIDI_ENABLE = no
67RGBLIGHT_ENABLE = no 68RGBLIGHT_ENABLE = no
68 69
69ifndef QUANTUM_DIR
70 include ../../../Makefile
71endif
72
73ifdef LCD_ENABLE 70ifdef LCD_ENABLE
74include $(SUBPROJECT_PATH)/drivers/gdisp/st7565ergodox/driver.mk 71include $(SUBPROJECT_PATH)/drivers/gdisp/st7565ergodox/driver.mk
75endif 72endif
76 73
77ifdef LED_ENABLE 74ifdef LED_ENABLE
78include $(SUBPROJECT_PATH)/drivers/gdisp/IS31FL3731C/driver.mk 75include $(SUBPROJECT_PATH)/drivers/gdisp/IS31FL3731C/driver.mk
79endif 76endif \ No newline at end of file
diff --git a/keyboards/ergodox/infinity/simple_visualizer.h b/keyboards/ergodox/infinity/simple_visualizer.h
new file mode 100644
index 000000000..ded8a3222
--- /dev/null
+++ b/keyboards/ergodox/infinity/simple_visualizer.h
@@ -0,0 +1,123 @@
1/* Copyright 2017 Fred Sundvik
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef KEYBOARDS_ERGODOX_INFINITY_SIMPLE_VISUALIZER_H_
18#define KEYBOARDS_ERGODOX_INFINITY_SIMPLE_VISUALIZER_H_
19
20// Currently we are assuming that both the backlight and LCD are enabled
21// But it's entirely possible to write a custom visualizer that use only
22// one of them
23#ifndef LCD_BACKLIGHT_ENABLE
24#error This visualizer needs that LCD backlight is enabled
25#endif
26
27#ifndef LCD_ENABLE
28#error This visualizer needs that LCD is enabled
29#endif
30
31#include "visualizer.h"
32#include "visualizer_keyframes.h"
33#include "lcd_keyframes.h"
34#include "lcd_backlight_keyframes.h"
35#include "system/serial_link.h"
36#include "led.h"
37#include "animations.h"
38
39static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0xFF);
40static const uint32_t initial_color = LCD_COLOR(0, 0, 0);
41
42static bool initial_update = true;
43
44// Feel free to modify the animations below, or even add new ones if needed
45
46static keyframe_animation_t lcd_layer_display = {
47 .num_frames = 1,
48 .loop = false,
49 .frame_lengths = {gfxMillisecondsToTicks(0)},
50 .frame_functions = {lcd_keyframe_display_layer_and_led_states}
51};
52
53// The color animation animates the LCD color when you change layers
54static keyframe_animation_t color_animation = {
55 .num_frames = 2,
56 .loop = false,
57 // Note that there's a 200 ms no-operation frame,
58 // this prevents the color from changing when activating the layer
59 // momentarily
60 .frame_lengths = {gfxMillisecondsToTicks(200), gfxMillisecondsToTicks(500)},
61 .frame_functions = {keyframe_no_operation, backlight_keyframe_animate_color},
62};
63
64void initialize_user_visualizer(visualizer_state_t* state) {
65 // The brightness will be dynamically adjustable in the future
66 // But for now, change it here.
67 lcd_backlight_brightness(130);
68 state->current_lcd_color = initial_color;
69 state->target_lcd_color = logo_background_color;
70 initial_update = true;
71 start_keyframe_animation(&default_startup_animation);
72}
73
74
75// This function should be implemented by the keymap visualizer
76// Don't change anything else than state->target_lcd_color and state->layer_text as that's the only thing
77// that the simple_visualizer assumes that you are updating
78// Also make sure that the buffer passed to state->layer_text remains valid until the previous animation is
79// stopped. This can be done by either double buffering it or by using constant strings
80static void get_visualizer_layer_and_color(visualizer_state_t* state);
81
82void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) {
83 // Add more tests, change the colors and layer texts here
84 // Usually you want to check the high bits (higher layers first)
85 // because that's the order layers are processed for keypresses
86 // You can for check for example:
87 // state->status.layer
88 // state->status.default_layer
89 // state->status.leds (see led.h for available statuses)
90
91 uint32_t prev_color = state->target_lcd_color;
92 const char* prev_layer_text = state->layer_text;
93
94 get_visualizer_layer_and_color(state);
95
96 if (initial_update || prev_color != state->target_lcd_color) {
97 start_keyframe_animation(&color_animation);
98 }
99
100 if (initial_update || prev_layer_text != state->layer_text) {
101 start_keyframe_animation(&lcd_layer_display);
102 }
103 // You can also stop existing animations, and start your custom ones here
104 // remember that you should normally have only one animation for the LCD
105 // and one for the background. But you can also combine them if you want.
106}
107
108void user_visualizer_suspend(visualizer_state_t* state) {
109 state->layer_text = "Suspending...";
110 uint8_t hue = LCD_HUE(state->current_lcd_color);
111 uint8_t sat = LCD_SAT(state->current_lcd_color);
112 state->target_lcd_color = LCD_COLOR(hue, sat, 0);
113 start_keyframe_animation(&default_suspend_animation);
114}
115
116void user_visualizer_resume(visualizer_state_t* state) {
117 state->current_lcd_color = initial_color;
118 state->target_lcd_color = logo_background_color;
119 initial_update = true;
120 start_keyframe_animation(&default_startup_animation);
121}
122
123#endif /* KEYBOARDS_ERGODOX_INFINITY_SIMPLE_VISUALIZER_H_ */
diff --git a/keyboards/ergodox/infinity/visualizer.c b/keyboards/ergodox/infinity/visualizer.c
new file mode 100644
index 000000000..a4b09a34d
--- /dev/null
+++ b/keyboards/ergodox/infinity/visualizer.c
@@ -0,0 +1,329 @@
1/*
2Copyright 2016 Fred Sundvik <fsundvik@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18// Currently we are assuming that both the backlight and LCD are enabled
19// But it's entirely possible to write a custom visualizer that use only
20// one of them
21#ifndef LCD_BACKLIGHT_ENABLE
22#error This visualizer needs that LCD backlight is enabled
23#endif
24
25#ifndef LCD_ENABLE
26#error This visualizer needs that LCD is enabled
27#endif
28
29#include "visualizer.h"
30#include "visualizer_keyframes.h"
31#include "lcd_keyframes.h"
32#include "lcd_backlight_keyframes.h"
33#include "system/serial_link.h"
34#include "animations.h"
35
36static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0xFF);
37static const uint32_t initial_color = LCD_COLOR(0, 0, 0);
38
39static const uint32_t led_emulation_colors[4] = {
40 LCD_COLOR(0, 0, 0),
41 LCD_COLOR(255, 255, 255),
42 LCD_COLOR(84, 255, 255),
43 LCD_COLOR(168, 255, 255),
44};
45
46static uint32_t next_led_target_color = 0;
47
48typedef enum {
49 LCD_STATE_INITIAL,
50 LCD_STATE_LAYER_BITMAP,
51 LCD_STATE_BITMAP_AND_LEDS,
52} lcd_state_t;
53
54static lcd_state_t lcd_state = LCD_STATE_INITIAL;
55
56typedef struct {
57 uint8_t led_on;
58 uint8_t led1;
59 uint8_t led2;
60 uint8_t led3;
61} visualizer_user_data_t;
62
63// Don't access from visualization function, use the visualizer state instead
64static visualizer_user_data_t user_data_keyboard = {
65 .led_on = 0,
66 .led1 = LED_BRIGHTNESS_HI,
67 .led2 = LED_BRIGHTNESS_HI,
68 .led3 = LED_BRIGHTNESS_HI,
69};
70
71_Static_assert(sizeof(visualizer_user_data_t) <= VISUALIZER_USER_DATA_SIZE,
72 "Please increase the VISUALIZER_USER_DATA_SIZE");
73
74// Feel free to modify the animations below, or even add new ones if needed
75
76
77// The color animation animates the LCD color when you change layers
78static keyframe_animation_t one_led_color = {
79 .num_frames = 1,
80 .loop = false,
81 .frame_lengths = {gfxMillisecondsToTicks(0)},
82 .frame_functions = {backlight_keyframe_set_color},
83};
84
85bool swap_led_target_color(keyframe_animation_t* animation, visualizer_state_t* state) {
86 uint32_t temp = next_led_target_color;
87 next_led_target_color = state->target_lcd_color;
88 state->target_lcd_color = temp;
89 return false;
90}
91
92// The color animation animates the LCD color when you change layers
93static keyframe_animation_t two_led_colors = {
94 .num_frames = 2,
95 .loop = true,
96 .frame_lengths = {gfxMillisecondsToTicks(1000), gfxMillisecondsToTicks(0)},
97 .frame_functions = {backlight_keyframe_set_color, swap_led_target_color},
98};
99
100// The LCD animation alternates between the layer name display and a
101// bitmap that displays all active layers
102static keyframe_animation_t lcd_bitmap_animation = {
103 .num_frames = 1,
104 .loop = false,
105 .frame_lengths = {gfxMillisecondsToTicks(0)},
106 .frame_functions = {lcd_keyframe_display_layer_bitmap},
107};
108
109static keyframe_animation_t lcd_bitmap_leds_animation = {
110 .num_frames = 2,
111 .loop = true,
112 .frame_lengths = {gfxMillisecondsToTicks(2000), gfxMillisecondsToTicks(2000)},
113 .frame_functions = {lcd_keyframe_display_layer_bitmap, lcd_keyframe_display_led_states},
114};
115
116void initialize_user_visualizer(visualizer_state_t* state) {
117 // The brightness will be dynamically adjustable in the future
118 // But for now, change it here.
119 lcd_backlight_brightness(130);
120 state->current_lcd_color = initial_color;
121 state->target_lcd_color = logo_background_color;
122 lcd_state = LCD_STATE_INITIAL;
123 start_keyframe_animation(&default_startup_animation);
124}
125
126inline bool is_led_on(visualizer_user_data_t* user_data, uint8_t num) {
127 return user_data->led_on & (1u << num);
128}
129
130static uint8_t get_led_index_master(visualizer_user_data_t* user_data) {
131 for (int i=0; i < 3; i++) {
132 if (is_led_on(user_data, i)) {
133 return i + 1;
134 }
135 }
136 return 0;
137}
138
139static uint8_t get_led_index_slave(visualizer_user_data_t* user_data) {
140 uint8_t master_index = get_led_index_master(user_data);
141 if (master_index!=0) {
142 for (int i=master_index; i < 3; i++) {
143 if (is_led_on(user_data, i)) {
144 return i + 1;
145 }
146 }
147 }
148
149 return 0;
150}
151
152static uint8_t get_secondary_led_index(visualizer_user_data_t* user_data) {
153 if (is_led_on(user_data, 0) &&
154 is_led_on(user_data, 1) &&
155 is_led_on(user_data, 2)) {
156 return 3;
157 }
158 return 0;
159}
160
161static uint8_t get_brightness(visualizer_user_data_t* user_data, uint8_t index) {
162 switch (index) {
163 case 1:
164 return user_data->led1;
165 case 2:
166 return user_data->led2;
167 case 3:
168 return user_data->led3;
169 }
170 return 0;
171}
172
173static void update_emulated_leds(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) {
174 visualizer_user_data_t* user_data_new = (visualizer_user_data_t*)state->status.user_data;
175 visualizer_user_data_t* user_data_old = (visualizer_user_data_t*)prev_status->user_data;
176
177 uint8_t new_index;
178 uint8_t old_index;
179
180 if (is_serial_link_master()) {
181 new_index = get_led_index_master(user_data_new);
182 old_index = get_led_index_master(user_data_old);
183 }
184 else {
185 new_index = get_led_index_slave(user_data_new);
186 old_index = get_led_index_slave(user_data_old);
187 }
188 uint8_t new_secondary_index = get_secondary_led_index(user_data_new);
189 uint8_t old_secondary_index = get_secondary_led_index(user_data_old);
190
191 uint8_t old_brightness = get_brightness(user_data_old, old_index);
192 uint8_t new_brightness = get_brightness(user_data_new, new_index);
193
194 uint8_t old_secondary_brightness = get_brightness(user_data_old, old_secondary_index);
195 uint8_t new_secondary_brightness = get_brightness(user_data_new, new_secondary_index);
196
197 if (lcd_state == LCD_STATE_INITIAL ||
198 new_index != old_index ||
199 new_secondary_index != old_secondary_index ||
200 new_brightness != old_brightness ||
201 new_secondary_brightness != old_secondary_brightness) {
202
203 if (new_secondary_index != 0) {
204 state->target_lcd_color = change_lcd_color_intensity(
205 led_emulation_colors[new_index], new_brightness);
206 next_led_target_color = change_lcd_color_intensity(
207 led_emulation_colors[new_secondary_index], new_secondary_brightness);
208
209 stop_keyframe_animation(&one_led_color);
210 start_keyframe_animation(&two_led_colors);
211 } else {
212 state->target_lcd_color = change_lcd_color_intensity(
213 led_emulation_colors[new_index], new_brightness);
214 stop_keyframe_animation(&two_led_colors);
215 start_keyframe_animation(&one_led_color);
216 }
217 }
218}
219
220static void update_lcd_text(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) {
221 if (state->status.leds) {
222 if (lcd_state != LCD_STATE_BITMAP_AND_LEDS ||
223 state->status.leds != prev_status->leds ||
224 state->status.layer != prev_status->layer ||
225 state->status.default_layer != prev_status->default_layer) {
226
227 // NOTE: that it doesn't matter if the animation isn't playing, stop will do nothing in that case
228 stop_keyframe_animation(&lcd_bitmap_animation);
229
230 lcd_state = LCD_STATE_BITMAP_AND_LEDS;
231 // For information:
232 // The logic in this function makes sure that this doesn't happen, but if you call start on an
233 // animation that is already playing it will be restarted.
234 start_keyframe_animation(&lcd_bitmap_leds_animation);
235 }
236 } else {
237 if (lcd_state != LCD_STATE_LAYER_BITMAP ||
238 state->status.layer != prev_status->layer ||
239 state->status.default_layer != prev_status->default_layer) {
240
241 stop_keyframe_animation(&lcd_bitmap_leds_animation);
242
243 lcd_state = LCD_STATE_LAYER_BITMAP;
244 start_keyframe_animation(&lcd_bitmap_animation);
245 }
246 }
247}
248
249void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) {
250 // Check the status here to start and stop animations
251 // You might have to save some state, like the current animation here so that you can start the right
252 // This function is called every time the status changes
253
254 // NOTE that this is called from the visualizer thread, so don't access anything else outside the status
255 // This is also important because the slave won't have access to the active layer for example outside the
256 // status.
257
258 update_emulated_leds(state, prev_status);
259 update_lcd_text(state, prev_status);
260
261}
262
263void user_visualizer_suspend(visualizer_state_t* state) {
264 state->layer_text = "Suspending...";
265 uint8_t hue = LCD_HUE(state->current_lcd_color);
266 uint8_t sat = LCD_SAT(state->current_lcd_color);
267 state->target_lcd_color = LCD_COLOR(hue, sat, 0);
268 start_keyframe_animation(&default_suspend_animation);
269}
270
271void user_visualizer_resume(visualizer_state_t* state) {
272 state->current_lcd_color = initial_color;
273 state->target_lcd_color = logo_background_color;
274 lcd_state = LCD_STATE_INITIAL;
275 start_keyframe_animation(&default_startup_animation);
276}
277
278void ergodox_board_led_on(void){
279 // No board led support
280}
281
282void ergodox_right_led_1_on(void){
283 user_data_keyboard.led_on |= (1u << 0);
284 visualizer_set_user_data(&user_data_keyboard);
285}
286
287void ergodox_right_led_2_on(void){
288 user_data_keyboard.led_on |= (1u << 1);
289 visualizer_set_user_data(&user_data_keyboard);
290}
291
292void ergodox_right_led_3_on(void){
293 user_data_keyboard.led_on |= (1u << 2);
294 visualizer_set_user_data(&user_data_keyboard);
295}
296
297void ergodox_board_led_off(void){
298 // No board led support
299}
300
301void ergodox_right_led_1_off(void){
302 user_data_keyboard.led_on &= ~(1u << 0);
303 visualizer_set_user_data(&user_data_keyboard);
304}
305
306void ergodox_right_led_2_off(void){
307 user_data_keyboard.led_on &= ~(1u << 1);
308 visualizer_set_user_data(&user_data_keyboard);
309}
310
311void ergodox_right_led_3_off(void){
312 user_data_keyboard.led_on &= ~(1u << 2);
313 visualizer_set_user_data(&user_data_keyboard);
314}
315
316void ergodox_right_led_1_set(uint8_t n) {
317 user_data_keyboard.led1 = n;
318 visualizer_set_user_data(&user_data_keyboard);
319}
320
321void ergodox_right_led_2_set(uint8_t n) {
322 user_data_keyboard.led2 = n;
323 visualizer_set_user_data(&user_data_keyboard);
324}
325
326void ergodox_right_led_3_set(uint8_t n) {
327 user_data_keyboard.led3 = n;
328 visualizer_set_user_data(&user_data_keyboard);
329}
diff --git a/keyboards/ergodox/keymaps/default/visualizer.c b/keyboards/ergodox/keymaps/default/visualizer.c
new file mode 100644
index 000000000..502e53f3d
--- /dev/null
+++ b/keyboards/ergodox/keymaps/default/visualizer.c
@@ -0,0 +1,42 @@
1/*
2Copyright 2017 Fred Sundvik
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#include "simple_visualizer.h"
19
20// This function should be implemented by the keymap visualizer
21// Don't change anything else than state->target_lcd_color and state->layer_text as that's the only thing
22// that the simple_visualizer assumes that you are updating
23// Also make sure that the buffer passed to state->layer_text remains valid until the previous animation is
24// stopped. This can be done by either double buffering it or by using constant strings
25static void get_visualizer_layer_and_color(visualizer_state_t* state) {
26 uint8_t saturation = 60;
27 if (state->status.leds & (1u << USB_LED_CAPS_LOCK)) {
28 saturation = 255;
29 }
30 if (state->status.layer & 0x4) {
31 state->target_lcd_color = LCD_COLOR(0, saturation, 0xFF);
32 state->layer_text = "Media & Mouse";
33 }
34 else if (state->status.layer & 0x2) {
35 state->target_lcd_color = LCD_COLOR(168, saturation, 0xFF);
36 state->layer_text = "Symbol";
37 }
38 else {
39 state->target_lcd_color = LCD_COLOR(84, saturation, 0xFF);
40 state->layer_text = "Default";
41 }
42}
diff --git a/keyboards/ergodox/keymaps/familiar/README.md b/keyboards/ergodox/keymaps/familiar/README.md
new file mode 100644
index 000000000..e4336d9b5
--- /dev/null
+++ b/keyboards/ergodox/keymaps/familiar/README.md
@@ -0,0 +1,69 @@
1# ErgoDox Familiar Layout
2Familiar layout for those who regularly switch back and forth from ErgoDox to regular QWERTY.
3
4[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](../../../../license_GPLv3.md../../../../license_GPLv3.md) [![standard-readme compliant](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg)](https://github.com/RichardLitt/standard-readme)
5
6## Table of Contents
7
8- [Background](#background)
9- [Install](#install)
10- [Usage](#usage)
11 - [Layers](#layers)
12- [Contribute](#contribute)
13 - [Issues](#issues)
14- [License](#license)
15
16## Background
17
18This layout is built to be as familiar as possible for users coming directly from a default (QWERTY US) keyboard, while gaining as much advantage as possible from the ErgoDox and QMK featureset. I use an ErgoDoxEZ at home, but I don't have a regular office (CS grad student) so I regularly use either my laptop or a default-setup lab computer; I context switch daily so this layout is meant to reduce the mental overhead as much as possible.
19
20The default ErgoDoxEZ layout is probably more optimized as a solo daily driver - as are a lot of the others available keymaps. The focus of this layout is to get as much from the 'Dox as possible without overly disrupting long-established muscle memory.
21
22Key features of the familiar layout:
231. QWERTY default layout.
241. International symbols layer, mapped in the US-International layout default positions, through [UCIS](https://github.com/qmk/qmk_firmware/wiki/Unicode-and-additional-language-support#ucis_enable).
251. Numpad layer on right hand.
261. Thumb cluster holds spacebar, ALT, and access to secondary layers.
271. Function-layer arrow keys in both the first-person-shooter (actually ESDF instead of WASD) and vim (HJKL) locations.
28
29## Install
30
31If you are on Windows or Mac, choose the proper line in [`keymap.c`](keymap.c) for [unicode/international character support](https://github.com/qmk/qmk_firmware/wiki/Unicode-and-additional-language-support#ucis_enable) (starts at line 235).
32```c
33void matrix_init_user(void) {
34 set_unicode_input_mode(UC_LNX); // Linux
35 //set_unicode_input_mode(UC_OSX); // Mac OSX
36 //set_unicode_input_mode(UC_WIN); // Windows (with registry key, see wiki)
37 //set_unicode_input_mode(UC_WINC); // Windows (with WinCompose, see wiki)
38};
39```
40
41For instructions on building and installing this keymap, [go to the wiki](https://github.com/qmk/qmk_firmware/tree/master/keyboards/ergodox#build-dependencies). Below is the command for me; it may be different for you.
42```sh
43$ make ergodox-ez-familiar-teensy
44```
45
46## Usage
47
48[![Familiar Layout](familiar.png)](http://www.keyboard-layout-editor.com/#/gists/13508a9f99cff381d58b7be6f7dcc644)
49
50### Layers
511. Base Layer: QWERTY, with arrow keys at bottom right.
521. UCIS Layer: US-International symbols layer, plus —. Accessed by toggling the `INTL` layer using the UCIS key (bottom of left thumb cluster).
531. UCIS-Shifted Layer: Making shift work for UCIS characters. An ugly workaround. Any ideas? Accessed through holding shift while the UCIS layer is active (toggles the `INSF` layer).
541. Numpad Layer: Right hand number pad. Accessed by toggling the `NUMP` layer using the NPAD key (bottom of right thumb cluster).
551. Function Layer: F1-F12, arrows on ESDF and HJKL, media player controls. Accessed by holding either FN key (center key of each thumb cluster), which toggles the `ARRW` layer. I know, I need to work on my naming conventions.
56
57## Contribute
58
59[Contributor Covenant](http://contributor-covenant.org/)
60
61I'm terrible at this; I have no background in human-computer interaction, kinesiology, or keyboard-ology. Please send comments/issues/pull requests/angry tweets/etc. If you think there is a better way to take advantage of the ErgoDox/QMK comination without straying far from 84/101-key QWERTY, I want to know it.
62
63### Issues
641. The top two keys of the right thumb cluster are currently unused. I wanted them for screen brightness, but I haven't found a solution I like.
651. The `'`, `"`, `[`, and `]` keys are terrible to access; I want to put them somewhere else but I haven't figured out where.
661. The `INSF` layer is an ugly workaround. I should write a function for doing different things in the `INTL` layer depending on whether SHIFT is being held. Or something. Ideas?
67
68## License
69QMK is licensed ([mostly](https://github.com/qmk/qmk_firmware/issues/1038)) under the [GPLv2](blob/master/license_GPLv2.md). Accordingly, to whatever extent applicable, this keymap is licensed under the [GPLv3](../../../../license_GPLv3.md).
diff --git a/keyboards/ergodox/keymaps/familiar/familiar.png b/keyboards/ergodox/keymaps/familiar/familiar.png
new file mode 100644
index 000000000..f8b50e75e
--- /dev/null
+++ b/keyboards/ergodox/keymaps/familiar/familiar.png
Binary files differ
diff --git a/keyboards/ergodox/keymaps/familiar/keymap.c b/keyboards/ergodox/keymaps/familiar/keymap.c
new file mode 100644
index 000000000..c5f94afda
--- /dev/null
+++ b/keyboards/ergodox/keymaps/familiar/keymap.c
@@ -0,0 +1,267 @@
1#include "ergodox.h"
2#include "debug.h"
3#include "action_layer.h"
4#include "version.h"
5
6// Layers
7#define BASE 0 // default layer
8#define INTL 1 // international symbols
9#define INSF 2 // international symbols shifted
10#define NUMP 3 // numpad
11#define ARRW 4 // function, media, arrow keys
12
13// Fillers to make layering more clear
14#define _______ KC_TRNS
15#define XXXXXXX KC_NO
16
17const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
18// If it accepts an argument (i.e, is a function), it doesn't need KC_.
19// Otherwise, it needs KC_*
20/* layer 0 : default
21 *
22 * ,--------------------------------------------------. ,--------------------------------------------------.
23 * | ESC | 1 | 2 | 3 | 4 | 5 | 6 | | 7 | 8 | 9 | 0 | - | = | BCKSPC |
24 * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
25 * | TAB | Q | W | E | R | T | HOME | | PGUP | Y | U | I | O | P | DELETE |
26 * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
27 * | ` | A | S | D | F | G |------| |------| H | J | K | L | ; | ENTER |
28 * |--------+------+------+------+------+------| END | | PGDN |------+------+------+------+------+--------|
29 * | (/LSFT | Z | X | C | V | B | | | | N | M | , | . | UP | )/RSFT |
30 * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
31 * | LCTRL | LGUI | MENU | ' | " | | [ | ] | LEFT | DOWN | RIGHT |
32 * `------------------------------------' `------------------------------------'
33 * ,-------------. ,-------------.
34 * | VOL- | VOL+ | | | |
35 * ,------|------|------| |------+------+------.
36 * | SPC/ |SLASH/| MUTE | |NUMLCK|WHACK/| SPC/ |
37 * | ALT | MO(1)|------| |------|MO(1) | ALT |
38 * | | | LAY3 | | LAY2 | | |
39 * `--------------------' `--------------------'
40 */
41[BASE] = KEYMAP(
42 // left hand
43 KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6,
44 KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_HOME,
45 KC_GRV, KC_A, KC_S, KC_D, KC_F, KC_G,
46 KC_LSPO, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_END,
47 KC_LCTL, KC_LGUI, KC_MENU, KC_QUOT, S(KC_QUOT),
48 KC_VOLD, KC_VOLU,
49 KC_MUTE,
50 ALT_T(KC_SPC), LT(ARRW,KC_SLSH), TG(INTL),
51 // right hand
52 KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC,
53 KC_PGUP, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_DEL,
54 KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_ENTER,
55 KC_PGDN, KC_N, KC_M, KC_COMM, KC_DOT, KC_UP, KC_RSPC,
56 KC_LBRC, KC_RBRC, KC_LEFT, KC_DOWN, KC_RGHT,
57 _______, _______,
58 KC_NLCK,
59 TG(NUMP), LT(ARRW,KC_BSLS), ALT_T(KC_SPC)
60 ),
61
62/* layer 1: International symbols, etc
63 *
64 * ,--------------------------------------------------. ,--------------------------------------------------.
65 * | ´ | ¡ | ² | ³ | ¤ | € | ¼ | | ½ | ¾ | ‘ | ’ | ¥ | × | |
66 * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
67 * | | ä | å | é | ® | þ | | | | ü | ú | í | ó | ö | |
68 * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
69 * | | á | ß | ð | | |------| |------| | | | ø | ¶ | |
70 * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
71 * |MO(INSF)| æ | | © | | | | | | ñ | µ | ç | | |MO(INSF)|
72 * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
73 * | | | | ¬ | ¿ | | « | » | | | |
74 * `------------------------------------' `------------------------------------'
75 * ,-------------. ,-------------.
76 * | | | | | |
77 * ,------|------|------| |------+------+------.
78 * | | | | | | | |
79 * | | |------| |------| | |
80 * | | | | | | | |
81 * `--------------------' `--------------------'
82 */
83[INTL] = KEYMAP(
84 // left hand
85 UC(0x00B4), UC(0x00A1), UC(0x00B2), UC(0x00B3), UC(0x00A4), UC(0x20AC), UC(0x00BC),
86 _______, UC(0x00E4), UC(0x00E5), UC(0x00E9), UC(0x00AE), UC(0x00FE), _______,
87 _______, UC(0x00E1), UC(0x00DF), UC(0x00F0), _______, _______,
88 MO(INSF), UC(0x00E6), _______, UC(0x00A9), _______, _______, _______,
89 _______, _______, _______, UC(0x00AC), UC(0x00BF),
90 _______, _______,
91 _______,
92 _______, _______, _______,
93 // right hand
94 UC(0x00BD), UC(0x00BE), UC(0x2018), UC(0x2019), UC(0x00A5), UC(0x00D7), _______,
95 _______, UC(0x00FC), UC(0x00FA), UC(0x00ED), UC(0x00F3), UC(0x00F6), _______,
96 _______, _______, _______, UC(0x00F8), UC(0x00B6), _______,
97 _______, UC(0x00F1), UC(0x00B5), UC(0x00E7), _______, _______, MO(INSF),
98 UC(0x00AB), UC(0x00BB), _______, _______, _______,
99 _______, _______,
100 _______,
101 _______, _______, _______
102 ),
103
104/* layer 2 : international symbols, shifted
105 * This layer is an ugly workaround; it pretends that SHIFT still works normally on keys
106 * which don't produce an "upper case" or "shifted" international symobol.
107 *
108 * ,--------------------------------------------------. ,--------------------------------------------------.
109 * | ¨ | ¹ | | | £ | | | | | | | | — | ÷ | |
110 * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
111 * | | Ä | Å | É | | Þ | | | | Ü | Ú | Í | Ó | Ö | |
112 * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
113 * | | Á | § | Ð | | |------| |------| | | | Ø | ° | |
114 * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
115 * | | Æ | | ¢ | | | | | | Ñ | | Ç | | | |
116 * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
117 * | | | | ¦ | | | | | | | |
118 * `------------------------------------' `------------------------------------'
119 * ,-------------. ,-------------.
120 * | | | | | |
121 * ,------|------|------| |------+------+------.
122 * | | | | | | | |
123 * | | |------| |------| | |
124 * | | | | | | | |
125 * `--------------------' `--------------------'
126 */
127[INSF] = KEYMAP(
128 // left hand
129 UC(0x00A8), UC(0x00B9), _______, _______, UC(0x00A3), _______, _______,
130 _______, UC(0x00C4), UC(0x00C5), UC(0x00C9), _______, UC(0x00DE), _______,
131 _______, UC(0x00C1), UC(0x00A7), UC(0x00D0), S(KC_F), S(KC_G),
132 _______, UC(0x00C6), S(KC_X), UC(0x00A2), S(KC_V), S(KC_B), _______,
133 _______, _______, _______, UC(0x00A6), _______,
134 _______, _______,
135 _______,
136 _______, _______, _______,
137 // right hand
138 _______, _______, _______, _______, UC(0x2014), UC(0x00F7), _______,
139 _______, UC(0x00DC), UC(0x00DA), UC(0x00CD), UC(0x00D3), UC(0x00D6), _______,
140 S(KC_H), S(KC_J), S(KC_K), UC(0x00D8), UC(0x00B0), _______,
141 _______, UC(0x00D1), _______, UC(0x00C7), S(KC_DOT), _______, _______,
142 _______, _______, _______, _______, _______,
143 _______, _______,
144 _______,
145 _______, _______, _______
146 ),
147
148/* layer 3: numberpad
149 *
150 * ,--------------------------------------------------. ,--------------------------------------------------.
151 * | | | | | | | | | | | ( | ) | / | * | |
152 * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
153 * | | | | | | | | | | | 7 | 8 | 9 | - | |
154 * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
155 * | | | | | | |------| |------| | 4 | 5 | 6 | + | |
156 * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
157 * | | | | | | | | | | | 1 | 2 | 3 | = | |
158 * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
159 * | | | | | | | 0 | . | , | ENTER| |
160 * `------------------------------------' `------------------------------------'
161 * ,-------------. ,-------------.
162 * | | | | | |
163 * ,------|------|------| |------+------+------.
164 * | | | | | | | |
165 * | | |------| |------| | |
166 * | | | | | | | |
167 * `--------------------' `--------------------'
168 */
169[NUMP] = KEYMAP(
170 // left hand
171 _______, _______, _______, _______, _______, _______, _______,
172 _______, _______, _______, _______, _______, _______, _______,
173 _______, _______, _______, _______, _______, _______,
174 _______, _______, _______, _______, _______, _______, _______,
175 _______, _______, _______, _______, _______,
176 _______, _______,
177 _______,
178 _______, _______, _______,
179 // right hand
180 _______, _______, S(KC_9), S(KC_0), KC_PSLS, KC_PAST, _______,
181 _______, _______, KC_KP_7, KC_KP_8, KC_KP_9, KC_PMNS, _______,
182 _______, KC_KP_4, KC_KP_5, KC_KP_6, KC_PPLS, _______,
183 _______, _______, KC_KP_1, KC_KP_2, KC_KP_3, KC_PEQL, _______,
184 KC_KP_0, KC_KP_DOT, KC_PCMM, KC_PENT, _______,
185 _______, _______,
186 _______,
187 _______, _______, _______
188 ),
189
190/* layer 4 : functions and arrows
191 * This layer is at the top so that the functions still work no matter what layers are active.
192 *
193 * ,--------------------------------------------------. ,--------------------------------------------------.
194 * | ESCAPE | F1 | F2 | F3 | F4 | F5 | F6 | | F7 | F8 | F9 | F10 | F11 | F12 | SYSREQ |
195 * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
196 * | | | | UP | | | | | | | | | | | INSERT |
197 * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
198 * |CAPSLOCK| | LEFT | DOWN |RIGHT | |------| |------| LEFT | DOWN | UP | RIGHT| | |
199 * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
200 * | |M_PREV|M_STOP|M_PLPS|M_NEXT| | | | | | | | | PGUP | |
201 * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
202 * | | | | | | | | | HOME | PGDN | END |
203 * `------------------------------------' `------------------------------------'
204 * ,-------------. ,-------------.
205 * | | PAUSE| | | |
206 * ,------|------|------| |------+------+------.
207 * | | | | |SCRLK | | |
208 * | | |------| |------| | |
209 * | | | | | | | |
210 * `--------------------' `--------------------'
211 */
212[ARRW] = KEYMAP(
213 // left hand
214 KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6,
215 _______, _______, _______, KC_UP, _______, _______, _______,
216 KC_CAPS, _______, KC_LEFT, KC_DOWN, KC_RGHT, _______,
217 _______, _______, _______, _______, _______, _______, _______,
218 _______, _______, _______, _______, _______,
219 _______, KC_PAUSE,
220 _______,
221 _______, _______, _______,
222 // right hand
223 KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_SYSREQ,
224 _______, _______, _______, _______, _______, _______, KC_INS,
225 KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, _______, _______,
226 _______, _______, _______, _______, _______, KC_PGUP, _______,
227 _______, _______, KC_HOME, KC_PGDN, KC_END,
228 _______, _______,
229 KC_SLCK,
230 _______, _______, _______
231 ),
232};
233
234// Runs just one time when the keyboard initializes.
235void matrix_init_user(void) {
236 set_unicode_input_mode(UC_LNX); // Linux
237 //set_unicode_input_mode(UC_OSX); // Mac OSX
238 //set_unicode_input_mode(UC_WIN); // Windows (with registry key, see wiki)
239 //set_unicode_input_mode(UC_WINC); // Windows (with WinCompose, see wiki)
240};
241
242// Runs constantly in the background, in a loop.
243void matrix_scan_user(void) {
244
245 uint8_t layer = biton32(layer_state);
246
247 ergodox_board_led_off();
248 ergodox_right_led_1_off();
249 ergodox_right_led_2_off();
250 ergodox_right_led_3_off();
251 switch (layer) {
252 case INTL:
253 case INSF:
254 ergodox_right_led_1_on();
255 break;
256 case NUMP:
257 ergodox_right_led_2_on();
258 break;
259 case ARRW:
260 ergodox_right_led_3_on();
261 break;
262 default:
263 // none
264 break;
265 }
266
267};
diff --git a/keyboards/planck/keymaps/khord/config.h b/keyboards/planck/keymaps/khord/config.h
index 008f3a5c2..83dece50e 100644
--- a/keyboards/planck/keymaps/khord/config.h
+++ b/keyboards/planck/keymaps/khord/config.h
@@ -48,6 +48,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
48 48
49/* number of backlight levels */ 49/* number of backlight levels */
50#define BACKLIGHT_LEVELS 3 50#define BACKLIGHT_LEVELS 3
51#define BACKLIGHT_BREATHING
51 52
52/* Set 0 if debouncing isn't needed */ 53/* Set 0 if debouncing isn't needed */
53#define DEBOUNCING_DELAY 5 54#define DEBOUNCING_DELAY 5
diff --git a/keyboards/planck/keymaps/khord/keymap.c b/keyboards/planck/keymaps/khord/keymap.c
index 8001a0986..e371e5b70 100644
--- a/keyboards/planck/keymaps/khord/keymap.c
+++ b/keyboards/planck/keymaps/khord/keymap.c
@@ -37,6 +37,14 @@ enum planck_keycodes {
37#define _______ KC_TRNS 37#define _______ KC_TRNS
38#define XXXXXXX KC_NO 38#define XXXXXXX KC_NO
39 39
40#define MACRO_BREATH_TOGGLE 21
41#define MACRO_BREATH_SPEED_INC 23
42#define MACRO_BREATH_SPEED_DEC 24
43#define MACRO_BREATH_DEFAULT 25
44#define M_BRTOG M(MACRO_BREATH_TOGGLE)
45#define M_BRINC M(MACRO_BREATH_SPEED_INC)
46#define M_BRDEC M(MACRO_BREATH_SPEED_DEC)
47#define M_BRDFT M(MACRO_BREATH_DEFAULT)
40// Tap Dance Declarations 48// Tap Dance Declarations
41enum { 49enum {
42 ESC_CAP = 0, 50 ESC_CAP = 0,
@@ -173,10 +181,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
173 * `-----------------------------------------------------------------------------------' 181 * `-----------------------------------------------------------------------------------'
174 */ 182 */
175[_ADJUST] = { 183[_ADJUST] = {
176 {_______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL}, 184 {_______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, M_BRDFT, KC_DEL },
177 {_______, _______, _______, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, PLOVER, _______}, 185 {_______, _______, _______, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, _______, _______, M_BRINC, _______},
178 {_______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______}, 186 {_______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, M_BRDEC, C_A_INS},
179 {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, C_A_INS, C_A_DEL} 187 {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, M_BRTOG, C_A_DEL}
180} 188}
181 189
182 190
@@ -210,6 +218,32 @@ void persistant_default_layer_set(uint16_t default_layer) {
210 default_layer_set(default_layer); 218 default_layer_set(default_layer);
211} 219}
212 220
221const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
222 switch(id) {
223 case MACRO_BREATH_TOGGLE:
224 if (record->event.pressed) {
225 breathing_toggle();
226 }
227 break;
228 case MACRO_BREATH_SPEED_INC:
229 if (record->event.pressed) {
230 breathing_speed_inc(1);
231 }
232 break;
233 case MACRO_BREATH_SPEED_DEC:
234 if (record->event.pressed) {
235 breathing_speed_dec(1);
236 }
237 break;
238 case MACRO_BREATH_DEFAULT:
239 if (record->event.pressed) {
240 breathing_defaults();
241 }
242 break;
243 }
244 return MACRO_NONE;
245}
246
213bool process_record_user(uint16_t keycode, keyrecord_t *record) { 247bool process_record_user(uint16_t keycode, keyrecord_t *record) {
214 switch (keycode) { 248 switch (keycode) {
215 case QWERTY: 249 case QWERTY:
diff --git a/keyboards/xd60/keymaps/default/keymap.c b/keyboards/xd60/keymaps/default/keymap.c
index 11be9afca..784088d53 100644
--- a/keyboards/xd60/keymaps/default/keymap.c
+++ b/keyboards/xd60/keymaps/default/keymap.c
@@ -5,8 +5,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
5 5
6 // 0: Base Layer 6 // 0: Base Layer
7 KEYMAP( 7 KEYMAP(
8 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_BSLS, KC_GRV, \ 8 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_GRV, \
9 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_BSPC, \ 9 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_BSLS, \
10 KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NO, KC_ENT, \ 10 KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NO, KC_ENT, \
11 KC_LSFT, KC_NO, 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_DEL, \ 11 KC_LSFT, KC_NO, 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_DEL, \
12 KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RGUI, F(0), KC_LEFT, KC_DOWN, KC_RIGHT), 12 KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RGUI, F(0), KC_LEFT, KC_DOWN, KC_RIGHT),
diff --git a/quantum/led_tables.c b/quantum/led_tables.c
new file mode 100644
index 000000000..b99f26209
--- /dev/null
+++ b/quantum/led_tables.c
@@ -0,0 +1,71 @@
1/*
2Copyright 2017 Fred Sundvik
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8This program is distributed in the hope that it will be useful,
9but WITHOUT ANY WARRANTY; without even the implied warranty of
10MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11GNU General Public License for more details.
12You should have received a copy of the GNU General Public License
13along with this program. If not, see <http://www.gnu.org/licenses/>.
14*/
15
16#include "led_tables.h"
17
18
19#ifdef USE_CIE1931_CURVE
20// Lightness curve using the CIE 1931 lightness formula
21//Generated by the python script provided in http://jared.geek.nz/2013/feb/linear-led-pwm
22const uint8_t CIE1931_CURVE[] PROGMEM = {
23 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
24 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
25 2, 2, 2, 3, 3, 3, 3, 3, 3, 3,
26 3, 4, 4, 4, 4, 4, 4, 5, 5, 5,
27 5, 5, 6, 6, 6, 6, 6, 7, 7, 7,
28 7, 8, 8, 8, 8, 9, 9, 9, 10, 10,
29 10, 10, 11, 11, 11, 12, 12, 12, 13, 13,
30 13, 14, 14, 15, 15, 15, 16, 16, 17, 17,
31 17, 18, 18, 19, 19, 20, 20, 21, 21, 22,
32 22, 23, 23, 24, 24, 25, 25, 26, 26, 27,
33 28, 28, 29, 29, 30, 31, 31, 32, 32, 33,
34 34, 34, 35, 36, 37, 37, 38, 39, 39, 40,
35 41, 42, 43, 43, 44, 45, 46, 47, 47, 48,
36 49, 50, 51, 52, 53, 54, 54, 55, 56, 57,
37 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
38 68, 70, 71, 72, 73, 74, 75, 76, 77, 79,
39 80, 81, 82, 83, 85, 86, 87, 88, 90, 91,
40 92, 94, 95, 96, 98, 99, 100, 102, 103, 105,
41 106, 108, 109, 110, 112, 113, 115, 116, 118, 120,
42 121, 123, 124, 126, 128, 129, 131, 132, 134, 136,
43 138, 139, 141, 143, 145, 146, 148, 150, 152, 154,
44 155, 157, 159, 161, 163, 165, 167, 169, 171, 173,
45 175, 177, 179, 181, 183, 185, 187, 189, 191, 193,
46 196, 198, 200, 202, 204, 207, 209, 211, 214, 216,
47 218, 220, 223, 225, 228, 230, 232, 235, 237, 240,
48 242, 245, 247, 250, 252, 255,
49 };
50#endif
51
52#ifdef USE_LED_BREATHING_TABLE
53const uint8_t LED_BREATHING_TABLE[] PROGMEM = {
54 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 9,
55 10, 11, 12, 14, 15, 17, 18, 20, 21, 23, 25, 27, 29, 31, 33, 35,
56 37, 40, 42, 44, 47, 49, 52, 54, 57, 59, 62, 65, 67, 70, 73, 76,
57 79, 82, 85, 88, 90, 93, 97, 100, 103, 106, 109, 112, 115, 118, 121, 124,
58 127, 131, 134, 137, 140, 143, 146, 149, 152, 155, 158, 162, 165, 167, 170, 173,
59 176, 179, 182, 185, 188, 190, 193, 196, 198, 201, 203, 206, 208, 211, 213, 215,
60 218, 220, 222, 224, 226, 228, 230, 232, 234, 235, 237, 238, 240, 241, 243, 244,
61 245, 246, 248, 249, 250, 250, 251, 252, 253, 253, 254, 254, 254, 255, 255, 255,
62 255, 255, 255, 255, 254, 254, 254, 253, 253, 252, 251, 250, 250, 249, 248, 246,
63 245, 244, 243, 241, 240, 238, 237, 235, 234, 232, 230, 228, 226, 224, 222, 220,
64 218, 215, 213, 211, 208, 206, 203, 201, 198, 196, 193, 190, 188, 185, 182, 179,
65 176, 173, 170, 167, 165, 162, 158, 155, 152, 149, 146, 143, 140, 137, 134, 131,
66 128, 124, 121, 118, 115, 112, 109, 106, 103, 100, 97, 93, 90, 88, 85, 82,
67 79, 76, 73, 70, 67, 65, 62, 59, 57, 54, 52, 49, 47, 44, 42, 40,
68 37, 35, 33, 31, 29, 27, 25, 23, 21, 20, 18, 17, 15, 14, 12, 11,
69 10, 9, 7, 6, 5, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0
70};
71#endif
diff --git a/quantum/led_tables.h b/quantum/led_tables.h
new file mode 100644
index 000000000..af49bf332
--- /dev/null
+++ b/quantum/led_tables.h
@@ -0,0 +1,30 @@
1/*
2Copyright 2017 Fred Sundvik
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8This program is distributed in the hope that it will be useful,
9but WITHOUT ANY WARRANTY; without even the implied warranty of
10MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11GNU General Public License for more details.
12You should have received a copy of the GNU General Public License
13along with this program. If not, see <http://www.gnu.org/licenses/>.
14*/
15
16#ifndef LED_TABLES_H
17#define LED_TABLES_H
18
19#include "progmem.h"
20#include <stdint.h>
21
22#ifdef USE_CIE1931_CURVE
23extern const uint8_t CIE1931_CURVE[] PROGMEM;
24#endif
25
26#ifdef USE_LED_BREATHING_TABLE
27extern const uint8_t LED_BREATHING_TABLE[] PROGMEM;
28#endif
29
30#endif
diff --git a/quantum/rgblight.c b/quantum/rgblight.c
index eff70aae1..4eec2a776 100644
--- a/quantum/rgblight.c
+++ b/quantum/rgblight.c
@@ -20,56 +20,8 @@
20#include "timer.h" 20#include "timer.h"
21#include "rgblight.h" 21#include "rgblight.h"
22#include "debug.h" 22#include "debug.h"
23#include "led_tables.h"
23 24
24// Lightness curve using the CIE 1931 lightness formula
25//Generated by the python script provided in http://jared.geek.nz/2013/feb/linear-led-pwm
26const uint8_t DIM_CURVE[] PROGMEM = {
27 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
28 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
29 2, 2, 2, 3, 3, 3, 3, 3, 3, 3,
30 3, 4, 4, 4, 4, 4, 4, 5, 5, 5,
31 5, 5, 6, 6, 6, 6, 6, 7, 7, 7,
32 7, 8, 8, 8, 8, 9, 9, 9, 10, 10,
33 10, 10, 11, 11, 11, 12, 12, 12, 13, 13,
34 13, 14, 14, 15, 15, 15, 16, 16, 17, 17,
35 17, 18, 18, 19, 19, 20, 20, 21, 21, 22,
36 22, 23, 23, 24, 24, 25, 25, 26, 26, 27,
37 28, 28, 29, 29, 30, 31, 31, 32, 32, 33,
38 34, 34, 35, 36, 37, 37, 38, 39, 39, 40,
39 41, 42, 43, 43, 44, 45, 46, 47, 47, 48,
40 49, 50, 51, 52, 53, 54, 54, 55, 56, 57,
41 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
42 68, 70, 71, 72, 73, 74, 75, 76, 77, 79,
43 80, 81, 82, 83, 85, 86, 87, 88, 90, 91,
44 92, 94, 95, 96, 98, 99, 100, 102, 103, 105,
45 106, 108, 109, 110, 112, 113, 115, 116, 118, 120,
46 121, 123, 124, 126, 128, 129, 131, 132, 134, 136,
47 138, 139, 141, 143, 145, 146, 148, 150, 152, 154,
48 155, 157, 159, 161, 163, 165, 167, 169, 171, 173,
49 175, 177, 179, 181, 183, 185, 187, 189, 191, 193,
50 196, 198, 200, 202, 204, 207, 209, 211, 214, 216,
51 218, 220, 223, 225, 228, 230, 232, 235, 237, 240,
52 242, 245, 247, 250, 252, 255,
53 };
54
55const uint8_t RGBLED_BREATHING_TABLE[] PROGMEM = {
56 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 9,
57 10, 11, 12, 14, 15, 17, 18, 20, 21, 23, 25, 27, 29, 31, 33, 35,
58 37, 40, 42, 44, 47, 49, 52, 54, 57, 59, 62, 65, 67, 70, 73, 76,
59 79, 82, 85, 88, 90, 93, 97, 100, 103, 106, 109, 112, 115, 118, 121, 124,
60 127, 131, 134, 137, 140, 143, 146, 149, 152, 155, 158, 162, 165, 167, 170, 173,
61 176, 179, 182, 185, 188, 190, 193, 196, 198, 201, 203, 206, 208, 211, 213, 215,
62 218, 220, 222, 224, 226, 228, 230, 232, 234, 235, 237, 238, 240, 241, 243, 244,
63 245, 246, 248, 249, 250, 250, 251, 252, 253, 253, 254, 254, 254, 255, 255, 255,
64 255, 255, 255, 255, 254, 254, 254, 253, 253, 252, 251, 250, 250, 249, 248, 246,
65 245, 244, 243, 241, 240, 238, 237, 235, 234, 232, 230, 228, 226, 224, 222, 220,
66 218, 215, 213, 211, 208, 206, 203, 201, 198, 196, 193, 190, 188, 185, 182, 179,
67 176, 173, 170, 167, 165, 162, 158, 155, 152, 149, 146, 143, 140, 137, 134, 131,
68 128, 124, 121, 118, 115, 112, 109, 106, 103, 100, 97, 93, 90, 88, 85, 82,
69 79, 76, 73, 70, 67, 65, 62, 59, 57, 54, 52, 49, 47, 44, 42, 40,
70 37, 35, 33, 31, 29, 27, 25, 23, 21, 20, 18, 17, 15, 14, 12, 11,
71 10, 9, 7, 6, 5, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0
72};
73 25
74__attribute__ ((weak)) 26__attribute__ ((weak))
75const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5}; 27const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5};
@@ -135,9 +87,9 @@ void sethsv(uint16_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1) {
135 break; 87 break;
136 } 88 }
137 } 89 }
138 r = pgm_read_byte(&DIM_CURVE[r]); 90 r = pgm_read_byte(&CIE1931_CURVE[r]);
139 g = pgm_read_byte(&DIM_CURVE[g]); 91 g = pgm_read_byte(&CIE1931_CURVE[g]);
140 b = pgm_read_byte(&DIM_CURVE[b]); 92 b = pgm_read_byte(&CIE1931_CURVE[b]);
141 93
142 setrgb(r, g, b, led1); 94 setrgb(r, g, b, led1);
143} 95}
@@ -509,7 +461,7 @@ void rgblight_effect_breathing(uint8_t interval) {
509 } 461 }
510 last_timer = timer_read(); 462 last_timer = timer_read();
511 463
512 rgblight_sethsv_noeeprom(rgblight_config.hue, rgblight_config.sat, pgm_read_byte(&RGBLED_BREATHING_TABLE[pos])); 464 rgblight_sethsv_noeeprom(rgblight_config.hue, rgblight_config.sat, pgm_read_byte(&LED_BREATHING_TABLE[pos]));
513 pos = (pos + 1) % 256; 465 pos = (pos + 1) % 256;
514} 466}
515void rgblight_effect_rainbow_mood(uint8_t interval) { 467void rgblight_effect_rainbow_mood(uint8_t interval) {
diff --git a/quantum/serial_link/system/serial_link.c b/quantum/serial_link/system/serial_link.c
index 75c7e77a7..b3bee62a1 100644
--- a/quantum/serial_link/system/serial_link.c
+++ b/quantum/serial_link/system/serial_link.c
@@ -212,7 +212,7 @@ void serial_link_update(void) {
212 212
213 systime_t current_time = chVTGetSystemTimeX(); 213 systime_t current_time = chVTGetSystemTimeX();
214 systime_t delta = current_time - last_update; 214 systime_t delta = current_time - last_update;
215 if (changed || delta > US2ST(1000)) { 215 if (changed || delta > US2ST(5000)) {
216 last_update = current_time; 216 last_update = current_time;
217 last_matrix = matrix; 217 last_matrix = matrix;
218 matrix_object_t* m = begin_write_keyboard_matrix(); 218 matrix_object_t* m = begin_write_keyboard_matrix();
diff --git a/quantum/visualizer/example_integration/callbacks.c b/quantum/visualizer/example_integration/callbacks.c
deleted file mode 100644
index 2539615d6..000000000
--- a/quantum/visualizer/example_integration/callbacks.c
+++ /dev/null
@@ -1,36 +0,0 @@
1/*
2The MIT License (MIT)
3
4Copyright (c) 2016 Fred Sundvik
5
6Permission is hereby granted, free of charge, to any person obtaining a copy
7of this software and associated documentation files (the "Software"), to deal
8in the Software without restriction, including without limitation the rights
9to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10copies of the Software, and to permit persons to whom the Software is
11furnished to do so, subject to the following conditions:
12
13The above copyright notice and this permission notice shall be included in all
14copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22SOFTWARE.
23*/
24
25#include "keyboard.h"
26#include "action_layer.h"
27#include "visualizer.h"
28#include "host.h"
29
30void post_keyboard_init(void) {
31 visualizer_init();
32}
33
34void post_keyboard_task() {
35 visualizer_set_state(default_layer_state, layer_state, host_keyboard_leds());
36}
diff --git a/quantum/visualizer/example_integration/gfxconf.h b/quantum/visualizer/example_integration/gfxconf.h
deleted file mode 100644
index 304c5d187..000000000
--- a/quantum/visualizer/example_integration/gfxconf.h
+++ /dev/null
@@ -1,325 +0,0 @@
1/**
2 * This file has a different license to the rest of the uGFX system.
3 * You can copy, modify and distribute this file as you see fit.
4 * You do not need to publish your source modifications to this file.
5 * The only thing you are not permitted to do is to relicense it
6 * under a different license.
7 */
8
9/**
10 * Copy this file into your project directory and rename it as gfxconf.h
11 * Edit your copy to turn on the uGFX features you want to use.
12 * The values below are the defaults.
13 *
14 * Only remove the comments from lines where you want to change the
15 * default value. This allows definitions to be included from
16 * driver makefiles when required and provides the best future
17 * compatibility for your project.
18 *
19 * Please use spaces instead of tabs in this file.
20 */
21
22#ifndef _GFXCONF_H
23#define _GFXCONF_H
24
25
26///////////////////////////////////////////////////////////////////////////
27// GOS - One of these must be defined, preferably in your Makefile //
28///////////////////////////////////////////////////////////////////////////
29#define GFX_USE_OS_CHIBIOS TRUE
30//#define GFX_USE_OS_FREERTOS FALSE
31// #define GFX_FREERTOS_USE_TRACE FALSE
32//#define GFX_USE_OS_WIN32 FALSE
33//#define GFX_USE_OS_LINUX FALSE
34//#define GFX_USE_OS_OSX FALSE
35//#define GFX_USE_OS_ECOS FALSE
36//#define GFX_USE_OS_RAWRTOS FALSE
37//#define GFX_USE_OS_ARDUINO FALSE
38//#define GFX_USE_OS_KEIL FALSE
39//#define GFX_USE_OS_CMSIS FALSE
40//#define GFX_USE_OS_RAW32 FALSE
41// #define INTERRUPTS_OFF() optional_code
42// #define INTERRUPTS_ON() optional_code
43// These are not defined by default for some reason
44#define GOS_NEED_X_THREADS FALSE
45#define GOS_NEED_X_HEAP FALSE
46
47// Options that (should where relevant) apply to all operating systems
48 #define GFX_NO_INLINE FALSE
49// #define GFX_COMPILER GFX_COMPILER_UNKNOWN
50// #define GFX_CPU GFX_CPU_UNKNOWN
51// #define GFX_OS_HEAP_SIZE 0
52// #define GFX_OS_NO_INIT FALSE
53// #define GFX_OS_INIT_NO_WARNING FALSE
54// #define GFX_OS_PRE_INIT_FUNCTION myHardwareInitRoutine
55// #define GFX_OS_EXTRA_INIT_FUNCTION myOSInitRoutine
56// #define GFX_OS_EXTRA_DEINIT_FUNCTION myOSDeInitRoutine
57
58
59///////////////////////////////////////////////////////////////////////////
60// GDISP //
61///////////////////////////////////////////////////////////////////////////
62#define GFX_USE_GDISP TRUE
63
64//#define GDISP_NEED_AUTOFLUSH FALSE
65//#define GDISP_NEED_TIMERFLUSH FALSE
66//#define GDISP_NEED_VALIDATION TRUE
67//#define GDISP_NEED_CLIP TRUE
68//#define GDISP_NEED_CIRCLE FALSE
69//#define GDISP_NEED_ELLIPSE FALSE
70//#define GDISP_NEED_ARC FALSE
71//#define GDISP_NEED_ARCSECTORS FALSE
72//#define GDISP_NEED_CONVEX_POLYGON FALSE
73//#define GDISP_NEED_SCROLL FALSE
74//#define GDISP_NEED_PIXELREAD FALSE
75//#define GDISP_NEED_CONTROL FALSE
76//#define GDISP_NEED_QUERY FALSE
77//#define GDISP_NEED_MULTITHREAD FALSE
78//#define GDISP_NEED_STREAMING FALSE
79#define GDISP_NEED_TEXT TRUE
80// #define GDISP_NEED_TEXT_WORDWRAP FALSE
81// #define GDISP_NEED_ANTIALIAS FALSE
82// #define GDISP_NEED_UTF8 FALSE
83 #define GDISP_NEED_TEXT_KERNING TRUE
84// #define GDISP_INCLUDE_FONT_UI1 FALSE
85// #define GDISP_INCLUDE_FONT_UI2 FALSE // The smallest preferred font.
86// #define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE
87// #define GDISP_INCLUDE_FONT_DEJAVUSANS10 FALSE
88// #define GDISP_INCLUDE_FONT_DEJAVUSANS12 FALSE
89// #define GDISP_INCLUDE_FONT_DEJAVUSANS16 FALSE
90// #define GDISP_INCLUDE_FONT_DEJAVUSANS20 FALSE
91// #define GDISP_INCLUDE_FONT_DEJAVUSANS24 FALSE
92// #define GDISP_INCLUDE_FONT_DEJAVUSANS32 FALSE
93 #define GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12 TRUE
94// #define GDISP_INCLUDE_FONT_FIXED_10X20 FALSE
95// #define GDISP_INCLUDE_FONT_FIXED_7X14 FALSE
96 #define GDISP_INCLUDE_FONT_FIXED_5X8 TRUE
97// #define GDISP_INCLUDE_FONT_DEJAVUSANS12_AA FALSE
98// #define GDISP_INCLUDE_FONT_DEJAVUSANS16_AA FALSE
99// #define GDISP_INCLUDE_FONT_DEJAVUSANS20_AA FALSE
100// #define GDISP_INCLUDE_FONT_DEJAVUSANS24_AA FALSE
101// #define GDISP_INCLUDE_FONT_DEJAVUSANS32_AA FALSE
102// #define GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12_AA FALSE
103// #define GDISP_INCLUDE_USER_FONTS FALSE
104
105//#define GDISP_NEED_IMAGE FALSE
106// #define GDISP_NEED_IMAGE_NATIVE FALSE
107// #define GDISP_NEED_IMAGE_GIF FALSE
108// #define GDISP_NEED_IMAGE_BMP FALSE
109// #define GDISP_NEED_IMAGE_BMP_1 FALSE
110// #define GDISP_NEED_IMAGE_BMP_4 FALSE
111// #define GDISP_NEED_IMAGE_BMP_4_RLE FALSE
112// #define GDISP_NEED_IMAGE_BMP_8 FALSE
113// #define GDISP_NEED_IMAGE_BMP_8_RLE FALSE
114// #define GDISP_NEED_IMAGE_BMP_16 FALSE
115// #define GDISP_NEED_IMAGE_BMP_24 FALSE
116// #define GDISP_NEED_IMAGE_BMP_32 FALSE
117// #define GDISP_NEED_IMAGE_JPG FALSE
118// #define GDISP_NEED_IMAGE_PNG FALSE
119// #define GDISP_NEED_IMAGE_ACCOUNTING FALSE
120
121//#define GDISP_NEED_PIXMAP FALSE
122// #define GDISP_NEED_PIXMAP_IMAGE FALSE
123
124//#define GDISP_DEFAULT_ORIENTATION GDISP_ROTATE_LANDSCAPE // If not defined the native hardware orientation is used.
125//#define GDISP_LINEBUF_SIZE 128
126//#define GDISP_STARTUP_COLOR Black
127#define GDISP_NEED_STARTUP_LOGO FALSE
128
129//#define GDISP_TOTAL_DISPLAYS 1
130
131//#define GDISP_DRIVER_LIST GDISPVMT_Win32, GDISPVMT_Win32
132// #ifdef GDISP_DRIVER_LIST
133// // For code and speed optimization define as TRUE or FALSE if all controllers have the same capability
134// #define GDISP_HARDWARE_STREAM_WRITE FALSE
135// #define GDISP_HARDWARE_STREAM_READ FALSE
136// #define GDISP_HARDWARE_STREAM_POS FALSE
137// #define GDISP_HARDWARE_DRAWPIXEL FALSE
138// #define GDISP_HARDWARE_CLEARS FALSE
139// #define GDISP_HARDWARE_FILLS FALSE
140// #define GDISP_HARDWARE_BITFILLS FALSE
141// #define GDISP_HARDWARE_SCROLL FALSE
142// #define GDISP_HARDWARE_PIXELREAD FALSE
143// #define GDISP_HARDWARE_CONTROL FALSE
144// #define GDISP_HARDWARE_QUERY FALSE
145// #define GDISP_HARDWARE_CLIP FALSE
146
147 #define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB888
148// #endif
149
150// The custom format is not defined for some reason, so define it as error
151// so we don't get compiler warnings
152#define GDISP_PIXELFORMAT_CUSTOM GDISP_PIXELFORMAT_ERROR
153
154#define GDISP_USE_GFXNET FALSE
155// #define GDISP_GFXNET_PORT 13001
156// #define GDISP_GFXNET_CUSTOM_LWIP_STARTUP FALSE
157// #define GDISP_DONT_WAIT_FOR_NET_DISPLAY FALSE
158// #define GDISP_GFXNET_UNSAFE_SOCKETS FALSE
159
160
161///////////////////////////////////////////////////////////////////////////
162// GWIN //
163///////////////////////////////////////////////////////////////////////////
164#define GFX_USE_GWIN FALSE
165
166//#define GWIN_NEED_WINDOWMANAGER FALSE
167// #define GWIN_REDRAW_IMMEDIATE FALSE
168// #define GWIN_REDRAW_SINGLEOP FALSE
169// #define GWIN_NEED_FLASHING FALSE
170// #define GWIN_FLASHING_PERIOD 250
171
172//#define GWIN_NEED_CONSOLE FALSE
173// #define GWIN_CONSOLE_USE_HISTORY FALSE
174// #define GWIN_CONSOLE_HISTORY_AVERAGING FALSE
175// #define GWIN_CONSOLE_HISTORY_ATCREATE FALSE
176// #define GWIN_CONSOLE_ESCSEQ FALSE
177// #define GWIN_CONSOLE_USE_BASESTREAM FALSE
178// #define GWIN_CONSOLE_USE_FLOAT FALSE
179//#define GWIN_NEED_GRAPH FALSE
180//#define GWIN_NEED_GL3D FALSE
181
182//#define GWIN_NEED_WIDGET FALSE
183//#define GWIN_FOCUS_HIGHLIGHT_WIDTH 1
184// #define GWIN_NEED_LABEL FALSE
185// #define GWIN_LABEL_ATTRIBUTE FALSE
186// #define GWIN_NEED_BUTTON FALSE
187// #define GWIN_BUTTON_LAZY_RELEASE FALSE
188// #define GWIN_NEED_SLIDER FALSE
189// #define GWIN_SLIDER_NOSNAP FALSE
190// #define GWIN_SLIDER_DEAD_BAND 5
191// #define GWIN_SLIDER_TOGGLE_INC 20
192// #define GWIN_NEED_CHECKBOX FALSE
193// #define GWIN_NEED_IMAGE FALSE
194// #define GWIN_NEED_IMAGE_ANIMATION FALSE
195// #define GWIN_NEED_RADIO FALSE
196// #define GWIN_NEED_LIST FALSE
197// #define GWIN_NEED_LIST_IMAGES FALSE
198// #define GWIN_NEED_PROGRESSBAR FALSE
199// #define GWIN_PROGRESSBAR_AUTO FALSE
200// #define GWIN_NEED_KEYBOARD FALSE
201// #define GWIN_KEYBOARD_DEFAULT_LAYOUT VirtualKeyboard_English1
202// #define GWIN_NEED_KEYBOARD_ENGLISH1 TRUE
203// #define GWIN_NEED_TEXTEDIT FALSE
204// #define GWIN_FLAT_STYLING FALSE
205// #define GWIN_WIDGET_TAGS FALSE
206
207//#define GWIN_NEED_CONTAINERS FALSE
208// #define GWIN_NEED_CONTAINER FALSE
209// #define GWIN_NEED_FRAME FALSE
210// #define GWIN_NEED_TABSET FALSE
211// #define GWIN_TABSET_TABHEIGHT 18
212
213
214///////////////////////////////////////////////////////////////////////////
215// GEVENT //
216///////////////////////////////////////////////////////////////////////////
217#define GFX_USE_GEVENT FALSE
218
219//#define GEVENT_ASSERT_NO_RESOURCE FALSE
220//#define GEVENT_MAXIMUM_SIZE 32
221//#define GEVENT_MAX_SOURCE_LISTENERS 32
222
223
224///////////////////////////////////////////////////////////////////////////
225// GTIMER //
226///////////////////////////////////////////////////////////////////////////
227#define GFX_USE_GTIMER FALSE
228
229//#define GTIMER_THREAD_PRIORITY HIGH_PRIORITY
230//#define GTIMER_THREAD_WORKAREA_SIZE 2048
231
232
233///////////////////////////////////////////////////////////////////////////
234// GQUEUE //
235///////////////////////////////////////////////////////////////////////////
236#define GFX_USE_GQUEUE FALSE
237
238//#define GQUEUE_NEED_ASYNC FALSE
239//#define GQUEUE_NEED_GSYNC FALSE
240//#define GQUEUE_NEED_FSYNC FALSE
241//#define GQUEUE_NEED_BUFFERS FALSE
242
243///////////////////////////////////////////////////////////////////////////
244// GINPUT //
245///////////////////////////////////////////////////////////////////////////
246#define GFX_USE_GINPUT FALSE
247
248//#define GINPUT_NEED_MOUSE FALSE
249// #define GINPUT_TOUCH_STARTRAW FALSE
250// #define GINPUT_TOUCH_NOTOUCH FALSE
251// #define GINPUT_TOUCH_NOCALIBRATE FALSE
252// #define GINPUT_TOUCH_NOCALIBRATE_GUI FALSE
253// #define GINPUT_MOUSE_POLL_PERIOD 25
254// #define GINPUT_MOUSE_CLICK_TIME 300
255// #define GINPUT_TOUCH_CXTCLICK_TIME 700
256// #define GINPUT_TOUCH_USER_CALIBRATION_LOAD FALSE
257// #define GINPUT_TOUCH_USER_CALIBRATION_SAVE FALSE
258// #define GMOUSE_DRIVER_LIST GMOUSEVMT_Win32, GMOUSEVMT_Win32
259//#define GINPUT_NEED_KEYBOARD FALSE
260// #define GINPUT_KEYBOARD_POLL_PERIOD 200
261// #define GKEYBOARD_DRIVER_LIST GKEYBOARDVMT_Win32, GKEYBOARDVMT_Win32
262// #define GKEYBOARD_LAYOUT_OFF FALSE
263// #define GKEYBOARD_LAYOUT_SCANCODE2_US FALSE
264//#define GINPUT_NEED_TOGGLE FALSE
265//#define GINPUT_NEED_DIAL FALSE
266
267
268///////////////////////////////////////////////////////////////////////////
269// GFILE //
270///////////////////////////////////////////////////////////////////////////
271#define GFX_USE_GFILE FALSE
272
273//#define GFILE_NEED_PRINTG FALSE
274//#define GFILE_NEED_SCANG FALSE
275//#define GFILE_NEED_STRINGS FALSE
276//#define GFILE_NEED_FILELISTS FALSE
277//#define GFILE_NEED_STDIO FALSE
278//#define GFILE_NEED_NOAUTOMOUNT FALSE
279//#define GFILE_NEED_NOAUTOSYNC FALSE
280
281//#define GFILE_NEED_MEMFS FALSE
282//#define GFILE_NEED_ROMFS FALSE
283//#define GFILE_NEED_RAMFS FALSE
284//#define GFILE_NEED_FATFS FALSE
285//#define GFILE_NEED_NATIVEFS FALSE
286//#define GFILE_NEED_CHBIOSFS FALSE
287
288//#define GFILE_ALLOW_FLOATS FALSE
289//#define GFILE_ALLOW_DEVICESPECIFIC FALSE
290//#define GFILE_MAX_GFILES 3
291
292///////////////////////////////////////////////////////////////////////////
293// GADC //
294///////////////////////////////////////////////////////////////////////////
295#define GFX_USE_GADC FALSE
296
297//#define GADC_MAX_LOWSPEED_DEVICES 4
298
299
300///////////////////////////////////////////////////////////////////////////
301// GAUDIO //
302///////////////////////////////////////////////////////////////////////////
303#define GFX_USE_GAUDIO FALSE
304// There seems to be a bug in the ugfx code, the wrong define is used
305// So define it in order to avoid warnings
306#define GFX_USE_GAUDIN GFX_USE_GAUDIO
307// #define GAUDIO_NEED_PLAY FALSE
308// #define GAUDIO_NEED_RECORD FALSE
309
310
311///////////////////////////////////////////////////////////////////////////
312// GMISC //
313///////////////////////////////////////////////////////////////////////////
314#define GFX_USE_GMISC FALSE
315
316//#define GMISC_NEED_ARRAYOPS FALSE
317//#define GMISC_NEED_FASTTRIG FALSE
318//#define GMISC_NEED_FIXEDTRIG FALSE
319//#define GMISC_NEED_INVSQRT FALSE
320// #define GMISC_INVSQRT_MIXED_ENDIAN FALSE
321// #define GMISC_INVSQRT_REAL_SLOW FALSE
322//#define GMISC_NEED_MATRIXFLOAT2D FALSE
323//#define GMISC_NEED_MATRIXFIXED2D FALSE
324
325#endif /* _GFXCONF_H */
diff --git a/quantum/visualizer/example_integration/lcd_backlight_hal.c b/quantum/visualizer/example_integration/lcd_backlight_hal.c
deleted file mode 100644
index 913131b16..000000000
--- a/quantum/visualizer/example_integration/lcd_backlight_hal.c
+++ /dev/null
@@ -1,91 +0,0 @@
1/*
2The MIT License (MIT)
3
4Copyright (c) 2016 Fred Sundvik
5
6Permission is hereby granted, free of charge, to any person obtaining a copy
7of this software and associated documentation files (the "Software"), to deal
8in the Software without restriction, including without limitation the rights
9to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10copies of the Software, and to permit persons to whom the Software is
11furnished to do so, subject to the following conditions:
12
13The above copyright notice and this permission notice shall be included in all
14copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22SOFTWARE.
23*/
24
25#include "lcd_backlight.h"
26#include "hal.h"
27
28#define RED_PIN 1
29#define GREEN_PIN 2
30#define BLUE_PIN 3
31#define CHANNEL_RED FTM0->CHANNEL[0]
32#define CHANNEL_GREEN FTM0->CHANNEL[1]
33#define CHANNEL_BLUE FTM0->CHANNEL[2]
34
35#define RGB_PORT PORTC
36#define RGB_PORT_GPIO GPIOC
37
38// Base FTM clock selection (72 MHz system clock)
39// @ 0xFFFF period, 72 MHz / (0xFFFF * 2) = Actual period
40// Higher pre-scalar will use the most power (also look the best)
41// Pre-scalar calculations
42// 0 - 72 MHz -> 549 Hz
43// 1 - 36 MHz -> 275 Hz
44// 2 - 18 MHz -> 137 Hz
45// 3 - 9 MHz -> 69 Hz (Slightly visible flicker)
46// 4 - 4 500 kHz -> 34 Hz (Visible flickering)
47// 5 - 2 250 kHz -> 17 Hz
48// 6 - 1 125 kHz -> 9 Hz
49// 7 - 562 500 Hz -> 4 Hz
50// Using a higher pre-scalar without flicker is possible but FTM0_MOD will need to be reduced
51// Which will reduce the brightness range
52#define PRESCALAR_DEFINE 0
53
54void lcd_backlight_hal_init(void) {
55 // Setup Backlight
56 SIM->SCGC6 |= SIM_SCGC6_FTM0;
57 FTM0->CNT = 0; // Reset counter
58
59 // PWM Period
60 // 16-bit maximum
61 FTM0->MOD = 0xFFFF;
62
63 // Set FTM to PWM output - Edge Aligned, Low-true pulses
64#define CNSC_MODE FTM_SC_CPWMS | FTM_SC_PS(4) | FTM_SC_CLKS(0)
65 CHANNEL_RED.CnSC = CNSC_MODE;
66 CHANNEL_GREEN.CnSC = CNSC_MODE;
67 CHANNEL_BLUE.CnSC = CNSC_MODE;
68
69 // System clock, /w prescalar setting
70 FTM0->SC = FTM_SC_CLKS(1) | FTM_SC_PS(PRESCALAR_DEFINE);
71
72 CHANNEL_RED.CnV = 0;
73 CHANNEL_GREEN.CnV = 0;
74 CHANNEL_BLUE.CnV = 0;
75
76 RGB_PORT_GPIO->PDDR |= (1 << RED_PIN);
77 RGB_PORT_GPIO->PDDR |= (1 << GREEN_PIN);
78 RGB_PORT_GPIO->PDDR |= (1 << BLUE_PIN);
79
80#define RGB_MODE PORTx_PCRn_SRE | PORTx_PCRn_DSE | PORTx_PCRn_MUX(4)
81 RGB_PORT->PCR[RED_PIN] = RGB_MODE;
82 RGB_PORT->PCR[GREEN_PIN] = RGB_MODE;
83 RGB_PORT->PCR[BLUE_PIN] = RGB_MODE;
84}
85
86void lcd_backlight_hal_color(uint16_t r, uint16_t g, uint16_t b) {
87 CHANNEL_RED.CnV = r;
88 CHANNEL_GREEN.CnV = g;
89 CHANNEL_BLUE.CnV = b;
90}
91
diff --git a/quantum/visualizer/example_integration/visualizer_user.c b/quantum/visualizer/example_integration/visualizer_user.c
deleted file mode 100644
index fc09fe2ea..000000000
--- a/quantum/visualizer/example_integration/visualizer_user.c
+++ /dev/null
@@ -1,121 +0,0 @@
1/*
2The MIT License (MIT)
3
4Copyright (c) 2016 Fred Sundvik
5
6Permission is hereby granted, free of charge, to any person obtaining a copy
7of this software and associated documentation files (the "Software"), to deal
8in the Software without restriction, including without limitation the rights
9to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10copies of the Software, and to permit persons to whom the Software is
11furnished to do so, subject to the following conditions:
12
13The above copyright notice and this permission notice shall be included in all
14copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22SOFTWARE.
23*/
24
25// Currently we are assuming that both the backlight and LCD are enabled
26// But it's entirely possible to write a custom visualizer that use only
27// one of them
28#ifndef LCD_BACKLIGHT_ENABLE
29#error This visualizer needs that LCD backlight is enabled
30#endif
31
32#ifndef LCD_ENABLE
33#error This visualizer needs that LCD is enabled
34#endif
35
36#include "visualizer.h"
37
38static const char* welcome_text[] = {"TMK", "Infinity Ergodox"};
39
40// Just an example how to write custom keyframe functions, we could have moved
41// all this into the init function
42bool display_welcome(keyframe_animation_t* animation, visualizer_state_t* state) {
43 (void)animation;
44 // Read the uGFX documentation for information how to use the displays
45 // http://wiki.ugfx.org/index.php/Main_Page
46 gdispClear(White);
47 // You can use static variables for things that can't be found in the animation
48 // or state structs
49 gdispDrawString(0, 3, welcome_text[0], state->font_dejavusansbold12, Black);
50 gdispDrawString(0, 15, welcome_text[1], state->font_dejavusansbold12, Black);
51 // Always remember to flush the display
52 gdispFlush();
53 // you could set the backlight color as well, but we won't do it here, since
54 // it's part of the following animation
55 // lcd_backlight_color(hue, saturation, intensity);
56 // We don't need constant updates, just drawing the screen once is enough
57 return false;
58}
59
60// Feel free to modify the animations below, or even add new ones if needed
61
62// Don't worry, if the startup animation is long, you can use the keyboard like normal
63// during that time
64static keyframe_animation_t startup_animation = {
65 .num_frames = 4,
66 .loop = false,
67 .frame_lengths = {0, MS2ST(1000), MS2ST(5000), 0},
68 .frame_functions = {display_welcome, keyframe_animate_backlight_color, keyframe_no_operation, enable_visualization},
69};
70
71// The color animation animates the LCD color when you change layers
72static keyframe_animation_t color_animation = {
73 .num_frames = 2,
74 .loop = false,
75 // Note that there's a 200 ms no-operation frame,
76 // this prevents the color from changing when activating the layer
77 // momentarily
78 .frame_lengths = {MS2ST(200), MS2ST(500)},
79 .frame_functions = {keyframe_no_operation, keyframe_animate_backlight_color},
80};
81
82// The LCD animation alternates between the layer name display and a
83// bitmap that displays all active layers
84static keyframe_animation_t lcd_animation = {
85 .num_frames = 2,
86 .loop = true,
87 .frame_lengths = {MS2ST(2000), MS2ST(2000)},
88 .frame_functions = {keyframe_display_layer_text, keyframe_display_layer_bitmap},
89};
90
91void initialize_user_visualizer(visualizer_state_t* state) {
92 // The brightness will be dynamically adjustable in the future
93 // But for now, change it here.
94 lcd_backlight_brightness(0x50);
95 state->current_lcd_color = LCD_COLOR(0x00, 0x00, 0xFF);
96 state->target_lcd_color = LCD_COLOR(0x10, 0xFF, 0xFF);
97 start_keyframe_animation(&startup_animation);
98}
99
100void update_user_visualizer_state(visualizer_state_t* state) {
101 // Add more tests, change the colors and layer texts here
102 // Usually you want to check the high bits (higher layers first)
103 // because that's the order layers are processed for keypresses
104 // You can for check for example:
105 // state->status.layer
106 // state->status.default_layer
107 // state->status.leds (see led.h for available statuses)
108 if (state->status.layer & 0x2) {
109 state->target_lcd_color = LCD_COLOR(0xA0, 0xB0, 0xFF);
110 state->layer_text = "Layer 2";
111 }
112 else {
113 state->target_lcd_color = LCD_COLOR(0x50, 0xB0, 0xFF);
114 state->layer_text = "Layer 1";
115 }
116 // You can also stop existing animations, and start your custom ones here
117 // remember that you should normally have only one animation for the LCD
118 // and one for the background. But you can also combine them if you want.
119 start_keyframe_animation(&lcd_animation);
120 start_keyframe_animation(&color_animation);
121}
diff --git a/quantum/visualizer/lcd_backlight.c b/quantum/visualizer/lcd_backlight.c
index 70187d1e0..00de3fab5 100644
--- a/quantum/visualizer/lcd_backlight.c
+++ b/quantum/visualizer/lcd_backlight.c
@@ -25,10 +25,10 @@ SOFTWARE.
25#include "lcd_backlight.h" 25#include "lcd_backlight.h"
26#include <math.h> 26#include <math.h>
27 27
28static uint8_t current_hue = 0x00; 28static uint8_t current_hue = 0;
29static uint8_t current_saturation = 0x00; 29static uint8_t current_saturation = 0;
30static uint8_t current_intensity = 0xFF; 30static uint8_t current_intensity = 0;
31static uint8_t current_brightness = 0x7F; 31static uint8_t current_brightness = 0;
32 32
33void lcd_backlight_init(void) { 33void lcd_backlight_init(void) {
34 lcd_backlight_hal_init(); 34 lcd_backlight_hal_init();
diff --git a/quantum/visualizer/lcd_backlight.h b/quantum/visualizer/lcd_backlight.h
index dd3e37a06..14dde64a1 100644
--- a/quantum/visualizer/lcd_backlight.h
+++ b/quantum/visualizer/lcd_backlight.h
@@ -32,6 +32,10 @@ SOFTWARE.
32#define LCD_SAT(color) ((color >> 8) & 0xFF) 32#define LCD_SAT(color) ((color >> 8) & 0xFF)
33#define LCD_INT(color) (color & 0xFF) 33#define LCD_INT(color) (color & 0xFF)
34 34
35inline uint32_t change_lcd_color_intensity(uint32_t color, uint8_t new_intensity) {
36 return (color & 0xFFFFFF00) | new_intensity;
37}
38
35void lcd_backlight_init(void); 39void lcd_backlight_init(void);
36void lcd_backlight_color(uint8_t hue, uint8_t saturation, uint8_t intensity); 40void lcd_backlight_color(uint8_t hue, uint8_t saturation, uint8_t intensity);
37void lcd_backlight_brightness(uint8_t b); 41void lcd_backlight_brightness(uint8_t b);
diff --git a/quantum/visualizer/lcd_backlight_keyframes.c b/quantum/visualizer/lcd_backlight_keyframes.c
new file mode 100644
index 000000000..8436d4e3d
--- /dev/null
+++ b/quantum/visualizer/lcd_backlight_keyframes.c
@@ -0,0 +1,77 @@
1/* Copyright 2017 Fred Sundvik
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "lcd_backlight_keyframes.h"
18
19bool backlight_keyframe_animate_color(keyframe_animation_t* animation, visualizer_state_t* state) {
20 int frame_length = animation->frame_lengths[animation->current_frame];
21 int current_pos = frame_length - animation->time_left_in_frame;
22 uint8_t t_h = LCD_HUE(state->target_lcd_color);
23 uint8_t t_s = LCD_SAT(state->target_lcd_color);
24 uint8_t t_i = LCD_INT(state->target_lcd_color);
25 uint8_t p_h = LCD_HUE(state->prev_lcd_color);
26 uint8_t p_s = LCD_SAT(state->prev_lcd_color);
27 uint8_t p_i = LCD_INT(state->prev_lcd_color);
28
29 uint8_t d_h1 = t_h - p_h; //Modulo arithmetic since we want to wrap around
30 int d_h2 = t_h - p_h;
31 // Chose the shortest way around
32 int d_h = abs(d_h2) < d_h1 ? d_h2 : d_h1;
33 int d_s = t_s - p_s;
34 int d_i = t_i - p_i;
35
36 int hue = (d_h * current_pos) / frame_length;
37 int sat = (d_s * current_pos) / frame_length;
38 int intensity = (d_i * current_pos) / frame_length;
39 //dprintf("%X -> %X = %X\n", p_h, t_h, hue);
40 hue += p_h;
41 sat += p_s;
42 intensity += p_i;
43 state->current_lcd_color = LCD_COLOR(hue, sat, intensity);
44 lcd_backlight_color(
45 LCD_HUE(state->current_lcd_color),
46 LCD_SAT(state->current_lcd_color),
47 LCD_INT(state->current_lcd_color));
48
49 return true;
50}
51
52bool backlight_keyframe_set_color(keyframe_animation_t* animation, visualizer_state_t* state) {
53 (void)animation;
54 state->prev_lcd_color = state->target_lcd_color;
55 state->current_lcd_color = state->target_lcd_color;
56 lcd_backlight_color(
57 LCD_HUE(state->current_lcd_color),
58 LCD_SAT(state->current_lcd_color),
59 LCD_INT(state->current_lcd_color));
60 return false;
61}
62
63bool backlight_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) {
64 (void)animation;
65 (void)state;
66 lcd_backlight_hal_color(0, 0, 0);
67 return false;
68}
69
70bool backlight_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) {
71 (void)animation;
72 (void)state;
73 lcd_backlight_color(LCD_HUE(state->current_lcd_color),
74 LCD_SAT(state->current_lcd_color),
75 LCD_INT(state->current_lcd_color));
76 return false;
77}
diff --git a/quantum/visualizer/lcd_backlight_keyframes.h b/quantum/visualizer/lcd_backlight_keyframes.h
new file mode 100644
index 000000000..e1c125cf9
--- /dev/null
+++ b/quantum/visualizer/lcd_backlight_keyframes.h
@@ -0,0 +1,30 @@
1/* Copyright 2017 Fred Sundvik
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef QUANTUM_VISUALIZER_LCD_BACKLIGHT_KEYFRAMES_H_
18#define QUANTUM_VISUALIZER_LCD_BACKLIGHT_KEYFRAMES_H_
19
20#include "visualizer.h"
21
22// Animates the LCD backlight color between the current color and the target color (of the state)
23bool backlight_keyframe_animate_color(keyframe_animation_t* animation, visualizer_state_t* state);
24// Sets the backlight color to the target color
25bool backlight_keyframe_set_color(keyframe_animation_t* animation, visualizer_state_t* state);
26
27bool backlight_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state);
28bool backlight_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state);
29
30#endif /* QUANTUM_VISUALIZER_LCD_BACKLIGHT_KEYFRAMES_H_ */
diff --git a/quantum/visualizer/lcd_keyframes.c b/quantum/visualizer/lcd_keyframes.c
new file mode 100644
index 000000000..df11861dd
--- /dev/null
+++ b/quantum/visualizer/lcd_keyframes.c
@@ -0,0 +1,188 @@
1/* Copyright 2017 Fred Sundvik
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "lcd_keyframes.h"
18#include <string.h>
19#include "action_util.h"
20#include "led.h"
21#include "resources/resources.h"
22
23bool lcd_keyframe_display_layer_text(keyframe_animation_t* animation, visualizer_state_t* state) {
24 (void)animation;
25 gdispClear(White);
26 gdispDrawString(0, 10, state->layer_text, state->font_dejavusansbold12, Black);
27 return false;
28}
29
30static void format_layer_bitmap_string(uint16_t default_layer, uint16_t layer, char* buffer) {
31 for (int i=0; i<16;i++)
32 {
33 uint32_t mask = (1u << i);
34 if (default_layer & mask) {
35 if (layer & mask) {
36 *buffer = 'B';
37 } else {
38 *buffer = 'D';
39 }
40 } else if (layer & mask) {
41 *buffer = '1';
42 } else {
43 *buffer = '0';
44 }
45 ++buffer;
46
47 if (i==3 || i==7 || i==11) {
48 *buffer = ' ';
49 ++buffer;
50 }
51 }
52 *buffer = 0;
53}
54
55bool lcd_keyframe_display_layer_bitmap(keyframe_animation_t* animation, visualizer_state_t* state) {
56 (void)animation;
57 const char* layer_help = "1=On D=Default B=Both";
58 char layer_buffer[16 + 4]; // 3 spaces and one null terminator
59 gdispClear(White);
60 gdispDrawString(0, 0, layer_help, state->font_fixed5x8, Black);
61 format_layer_bitmap_string(state->status.default_layer, state->status.layer, layer_buffer);
62 gdispDrawString(0, 10, layer_buffer, state->font_fixed5x8, Black);
63 format_layer_bitmap_string(state->status.default_layer >> 16, state->status.layer >> 16, layer_buffer);
64 gdispDrawString(0, 20, layer_buffer, state->font_fixed5x8, Black);
65 return false;
66}
67
68static void format_mods_bitmap_string(uint8_t mods, char* buffer) {
69 *buffer = ' ';
70 ++buffer;
71
72 for (int i = 0; i<8; i++)
73 {
74 uint32_t mask = (1u << i);
75 if (mods & mask) {
76 *buffer = '1';
77 } else {
78 *buffer = '0';
79 }
80 ++buffer;
81
82 if (i==3) {
83 *buffer = ' ';
84 ++buffer;
85 }
86 }
87 *buffer = 0;
88}
89
90bool lcd_keyframe_display_mods_bitmap(keyframe_animation_t* animation, visualizer_state_t* state) {
91 (void)animation;
92
93 const char* title = "Modifier states";
94 const char* mods_header = " CSAG CSAG ";
95 char status_buffer[12];
96
97 gdispClear(White);
98 gdispDrawString(0, 0, title, state->font_fixed5x8, Black);
99 gdispDrawString(0, 10, mods_header, state->font_fixed5x8, Black);
100 format_mods_bitmap_string(state->status.mods, status_buffer);
101 gdispDrawString(0, 20, status_buffer, state->font_fixed5x8, Black);
102
103 return false;
104}
105
106#define LED_STATE_STRING_SIZE sizeof("NUM CAPS SCRL COMP KANA")
107
108static void get_led_state_string(char* output, visualizer_state_t* state) {
109 uint8_t pos = 0;
110
111 if (state->status.leds & (1u << USB_LED_NUM_LOCK)) {
112 memcpy(output + pos, "NUM ", 4);
113 pos += 4;
114 }
115 if (state->status.leds & (1u << USB_LED_CAPS_LOCK)) {
116 memcpy(output + pos, "CAPS ", 5);
117 pos += 5;
118 }
119 if (state->status.leds & (1u << USB_LED_SCROLL_LOCK)) {
120 memcpy(output + pos, "SCRL ", 5);
121 pos += 5;
122 }
123 if (state->status.leds & (1u << USB_LED_COMPOSE)) {
124 memcpy(output + pos, "COMP ", 5);
125 pos += 5;
126 }
127 if (state->status.leds & (1u << USB_LED_KANA)) {
128 memcpy(output + pos, "KANA ", 5);
129 pos += 5;
130 }
131 output[pos] = 0;
132}
133
134bool lcd_keyframe_display_led_states(keyframe_animation_t* animation, visualizer_state_t* state)
135{
136 (void)animation;
137 char output[LED_STATE_STRING_SIZE];
138 get_led_state_string(output, state);
139 gdispClear(White);
140 gdispDrawString(0, 10, output, state->font_dejavusansbold12, Black);
141 return false;
142}
143
144bool lcd_keyframe_display_layer_and_led_states(keyframe_animation_t* animation, visualizer_state_t* state) {
145 (void)animation;
146 gdispClear(White);
147 uint8_t y = 10;
148 if (state->status.leds) {
149 char output[LED_STATE_STRING_SIZE];
150 get_led_state_string(output, state);
151 gdispDrawString(0, 1, output, state->font_dejavusansbold12, Black);
152 y = 17;
153 }
154 gdispDrawString(0, y, state->layer_text, state->font_dejavusansbold12, Black);
155 return false;
156}
157
158bool lcd_keyframe_draw_logo(keyframe_animation_t* animation, visualizer_state_t* state) {
159 (void)state;
160 (void)animation;
161 // Read the uGFX documentation for information how to use the displays
162 // http://wiki.ugfx.org/index.php/Main_Page
163 gdispClear(White);
164
165 // You can use static variables for things that can't be found in the animation
166 // or state structs, here we use the image
167
168 //gdispGBlitArea is a tricky function to use since it supports blitting part of the image
169 // if you have full screen image, then just use 128 and 32 for both source and target dimensions
170 gdispGBlitArea(GDISP, 0, 0, 128, 32, 0, 0, 128, (pixel_t*)resource_lcd_logo);
171
172 return false;
173}
174
175
176bool lcd_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) {
177 (void)animation;
178 (void)state;
179 gdispSetPowerMode(powerOff);
180 return false;
181}
182
183bool lcd_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) {
184 (void)animation;
185 (void)state;
186 gdispSetPowerMode(powerOn);
187 return false;
188}
diff --git a/quantum/visualizer/lcd_keyframes.h b/quantum/visualizer/lcd_keyframes.h
new file mode 100644
index 000000000..2e912b4c7
--- /dev/null
+++ b/quantum/visualizer/lcd_keyframes.h
@@ -0,0 +1,39 @@
1/* Copyright 2017 Fred Sundvik
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef QUANTUM_VISUALIZER_LCD_KEYFRAMES_H_
18#define QUANTUM_VISUALIZER_LCD_KEYFRAMES_H_
19
20#include "visualizer.h"
21
22// Displays the layer text centered vertically on the screen
23bool lcd_keyframe_display_layer_text(keyframe_animation_t* animation, visualizer_state_t* state);
24// Displays a bitmap (0/1) of all the currently active layers
25bool lcd_keyframe_display_layer_bitmap(keyframe_animation_t* animation, visualizer_state_t* state);
26// Displays a bitmap (0/1) of all the currently active mods
27bool lcd_keyframe_display_mods_bitmap(keyframe_animation_t* animation, visualizer_state_t* state);
28// Displays the keyboard led states (CAPS (Caps lock), NUM (Num lock), SCRL (Scroll lock), COMP (Compose), KANA)
29bool lcd_keyframe_display_led_states(keyframe_animation_t* animation, visualizer_state_t* state);
30// Displays both the layer text and the led states
31bool lcd_keyframe_display_layer_and_led_states(keyframe_animation_t* animation, visualizer_state_t* state);
32// Displays the QMK logo on the LCD screen
33bool lcd_keyframe_draw_logo(keyframe_animation_t* animation, visualizer_state_t* state);
34
35bool lcd_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state);
36bool lcd_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state);
37
38
39#endif /* QUANTUM_VISUALIZER_LCD_KEYFRAMES_H_ */
diff --git a/quantum/visualizer/led_test.c b/quantum/visualizer/led_keyframes.c
index a9abace8d..2dacd990d 100644
--- a/quantum/visualizer/led_test.c
+++ b/quantum/visualizer/led_keyframes.c
@@ -21,50 +21,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22SOFTWARE. 22SOFTWARE.
23*/ 23*/
24#include "led_test.h"
25#include "gfx.h" 24#include "gfx.h"
26#include "math.h" 25#include "math.h"
27 26#include "led_keyframes.h"
28#define CROSSFADE_TIME 1000
29#define GRADIENT_TIME 3000
30
31keyframe_animation_t led_test_animation = {
32 .num_frames = 14,
33 .loop = true,
34 .frame_lengths = {
35 gfxMillisecondsToTicks(1000), // fade in
36 gfxMillisecondsToTicks(1000), // no op (leds on)
37 gfxMillisecondsToTicks(1000), // fade out
38 gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade
39 gfxMillisecondsToTicks(GRADIENT_TIME), // left to rigt (outside in)
40 gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade
41 gfxMillisecondsToTicks(GRADIENT_TIME), // top_to_bottom
42 0, // mirror leds
43 gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade
44 gfxMillisecondsToTicks(GRADIENT_TIME), // left_to_right (mirrored, so inside out)
45 gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade
46 gfxMillisecondsToTicks(GRADIENT_TIME), // top_to_bottom
47 0, // normal leds
48 gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade
49
50 },
51 .frame_functions = {
52 keyframe_fade_in_all_leds,
53 keyframe_no_operation,
54 keyframe_fade_out_all_leds,
55 keyframe_led_crossfade,
56 keyframe_led_left_to_right_gradient,
57 keyframe_led_crossfade,
58 keyframe_led_top_to_bottom_gradient,
59 keyframe_mirror_led_orientation,
60 keyframe_led_crossfade,
61 keyframe_led_left_to_right_gradient,
62 keyframe_led_crossfade,
63 keyframe_led_top_to_bottom_gradient,
64 keyframe_normal_led_orientation,
65 keyframe_led_crossfade,
66 },
67};
68 27
69static uint8_t fade_led_color(keyframe_animation_t* animation, int from, int to) { 28static uint8_t fade_led_color(keyframe_animation_t* animation, int from, int to) {
70 int frame_length = animation->frame_lengths[animation->current_frame]; 29 int frame_length = animation->frame_lengths[animation->current_frame];
@@ -96,19 +55,19 @@ static uint8_t compute_gradient_color(float t, float index, float num) {
96 return (uint8_t)(255.0f * v); 55 return (uint8_t)(255.0f * v);
97} 56}
98 57
99bool keyframe_fade_in_all_leds(keyframe_animation_t* animation, visualizer_state_t* state) { 58bool led_keyframe_fade_in_all(keyframe_animation_t* animation, visualizer_state_t* state) {
100 (void)state; 59 (void)state;
101 keyframe_fade_all_leds_from_to(animation, 0, 255); 60 keyframe_fade_all_leds_from_to(animation, 0, 255);
102 return true; 61 return true;
103} 62}
104 63
105bool keyframe_fade_out_all_leds(keyframe_animation_t* animation, visualizer_state_t* state) { 64bool led_keyframe_fade_out_all(keyframe_animation_t* animation, visualizer_state_t* state) {
106 (void)state; 65 (void)state;
107 keyframe_fade_all_leds_from_to(animation, 255, 0); 66 keyframe_fade_all_leds_from_to(animation, 255, 0);
108 return true; 67 return true;
109} 68}
110 69
111bool keyframe_led_left_to_right_gradient(keyframe_animation_t* animation, visualizer_state_t* state) { 70bool led_keyframe_left_to_right_gradient(keyframe_animation_t* animation, visualizer_state_t* state) {
112 (void)state; 71 (void)state;
113 float frame_length = animation->frame_lengths[animation->current_frame]; 72 float frame_length = animation->frame_lengths[animation->current_frame];
114 float current_pos = frame_length - animation->time_left_in_frame; 73 float current_pos = frame_length - animation->time_left_in_frame;
@@ -120,7 +79,7 @@ bool keyframe_led_left_to_right_gradient(keyframe_animation_t* animation, visual
120 return true; 79 return true;
121} 80}
122 81
123bool keyframe_led_top_to_bottom_gradient(keyframe_animation_t* animation, visualizer_state_t* state) { 82bool led_keyframe_top_to_bottom_gradient(keyframe_animation_t* animation, visualizer_state_t* state) {
124 (void)state; 83 (void)state;
125 float frame_length = animation->frame_lengths[animation->current_frame]; 84 float frame_length = animation->frame_lengths[animation->current_frame];
126 float current_pos = frame_length - animation->time_left_in_frame; 85 float current_pos = frame_length - animation->time_left_in_frame;
@@ -139,7 +98,7 @@ static void copy_current_led_state(uint8_t* dest) {
139 } 98 }
140 } 99 }
141} 100}
142bool keyframe_led_crossfade(keyframe_animation_t* animation, visualizer_state_t* state) { 101bool led_keyframe_crossfade(keyframe_animation_t* animation, visualizer_state_t* state) {
143 (void)state; 102 (void)state;
144 if (animation->first_update_of_frame) { 103 if (animation->first_update_of_frame) {
145 copy_current_led_state(&crossfade_start_frame[0][0]); 104 copy_current_led_state(&crossfade_start_frame[0][0]);
@@ -155,14 +114,14 @@ bool keyframe_led_crossfade(keyframe_animation_t* animation, visualizer_state_t*
155 return true; 114 return true;
156} 115}
157 116
158bool keyframe_mirror_led_orientation(keyframe_animation_t* animation, visualizer_state_t* state) { 117bool led_keyframe_mirror_orientation(keyframe_animation_t* animation, visualizer_state_t* state) {
159 (void)state; 118 (void)state;
160 (void)animation; 119 (void)animation;
161 gdispGSetOrientation(LED_DISPLAY, GDISP_ROTATE_180); 120 gdispGSetOrientation(LED_DISPLAY, GDISP_ROTATE_180);
162 return false; 121 return false;
163} 122}
164 123
165bool keyframe_normal_led_orientation(keyframe_animation_t* animation, visualizer_state_t* state) { 124bool led_keyframe_normal_orientation(keyframe_animation_t* animation, visualizer_state_t* state) {
166 (void)state; 125 (void)state;
167 (void)animation; 126 (void)animation;
168 gdispGSetOrientation(LED_DISPLAY, GDISP_ROTATE_0); 127 gdispGSetOrientation(LED_DISPLAY, GDISP_ROTATE_0);
diff --git a/quantum/visualizer/led_test.h b/quantum/visualizer/led_keyframes.h
index 5e2325753..a68943041 100644
--- a/quantum/visualizer/led_test.h
+++ b/quantum/visualizer/led_keyframes.h
@@ -22,20 +22,20 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22SOFTWARE. 22SOFTWARE.
23*/ 23*/
24 24
25#ifndef TMK_VISUALIZER_LED_TEST_H_ 25#ifndef LED_KEYFRAMES_H
26#define TMK_VISUALIZER_LED_TEST_H_ 26#define LED_KEYFRAMES_H
27 27
28#include "visualizer.h" 28#include "visualizer.h"
29 29
30bool keyframe_fade_in_all_leds(keyframe_animation_t* animation, visualizer_state_t* state); 30bool led_keyframe_fade_in_all(keyframe_animation_t* animation, visualizer_state_t* state);
31bool keyframe_fade_out_all_leds(keyframe_animation_t* animation, visualizer_state_t* state); 31bool led_keyframe_fade_out_all(keyframe_animation_t* animation, visualizer_state_t* state);
32bool keyframe_led_left_to_right_gradient(keyframe_animation_t* animation, visualizer_state_t* state); 32bool led_keyframe_left_to_right_gradient(keyframe_animation_t* animation, visualizer_state_t* state);
33bool keyframe_led_top_to_bottom_gradient(keyframe_animation_t* animation, visualizer_state_t* state); 33bool led_keyframe_top_to_bottom_gradient(keyframe_animation_t* animation, visualizer_state_t* state);
34bool keyframe_led_crossfade(keyframe_animation_t* animation, visualizer_state_t* state); 34bool led_keyframe_crossfade(keyframe_animation_t* animation, visualizer_state_t* state);
35bool keyframe_mirror_led_orientation(keyframe_animation_t* animation, visualizer_state_t* state); 35bool led_keyframe_mirror_orientation(keyframe_animation_t* animation, visualizer_state_t* state);
36bool keyframe_normal_led_orientation(keyframe_animation_t* animation, visualizer_state_t* state); 36bool led_keyframe_normal_orientation(keyframe_animation_t* animation, visualizer_state_t* state);
37 37
38extern keyframe_animation_t led_test_animation; 38extern keyframe_animation_t led_test_animation;
39 39
40 40
41#endif /* TMK_VISUALIZER_LED_TEST_H_ */ 41#endif /* LED_KEYFRAMES_H */
diff --git a/quantum/visualizer/resources/lcd_logo.c b/quantum/visualizer/resources/lcd_logo.c
new file mode 100644
index 000000000..d1a0ffa7f
--- /dev/null
+++ b/quantum/visualizer/resources/lcd_logo.c
@@ -0,0 +1,61 @@
1/* Copyright 2017 Fred Sundvik
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "resources.h"
18
19
20// To generate an image array like this
21// Ensure the image is 128 x 32 or smaller
22// Convert the bitmap to a C array using a program like http://www.riuson.com/lcd-image-converter/
23// Ensure the the conversion process produces a monochrome format array - 1 bit/pixel, left to right, top to bottom
24// Update array in the source code with the C array produced by the conversion program
25
26// The image below is generated from lcd_logo.png
27const uint8_t resource_lcd_logo[512] = {
28 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
29 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
30 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
31 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
32 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34 0x00, 0xf8, 0xfe, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
35 0x00, 0x38, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36 0x00, 0x38, 0x38, 0x38, 0x06, 0x29, 0x41, 0x24, 0x52, 0x24, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00,
37 0x00, 0x38, 0x38, 0x38, 0x09, 0x55, 0x42, 0xaa, 0xaa, 0xaa, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00,
38 0x00, 0x38, 0x38, 0x38, 0x09, 0x55, 0x82, 0x28, 0xaa, 0xae, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00,
39 0x00, 0x38, 0x38, 0x38, 0x09, 0x55, 0x43, 0x28, 0xaa, 0xaa, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00,
40 0x00, 0x38, 0x38, 0x38, 0x0a, 0x55, 0x42, 0x28, 0xaa, 0xaa, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00,
41 0x00, 0x38, 0x38, 0x38, 0x05, 0x45, 0x42, 0x28, 0x89, 0x4a, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00,
42 0x00, 0x18, 0x38, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43 0x00, 0x1c, 0x38, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44 0x00, 0x0e, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45 0x00, 0x03, 0xff, 0x80, 0x04, 0x45, 0x14, 0xa4, 0x92, 0x83, 0x52, 0x22, 0x22, 0x36, 0x00, 0x00,
46 0x00, 0x00, 0x38, 0x00, 0x0a, 0xaa, 0xaa, 0xaa, 0xba, 0x84, 0x55, 0x55, 0x57, 0x45, 0x00, 0x00,
47 0x00, 0x00, 0x38, 0x00, 0x08, 0xaa, 0xaa, 0xaa, 0x92, 0xb2, 0x55, 0x55, 0x42, 0x65, 0x00, 0x00,
48 0x00, 0x00, 0x38, 0x00, 0x08, 0xaa, 0xaa, 0xaa, 0x92, 0x81, 0x56, 0x65, 0x42, 0x45, 0x00, 0x00,
49 0x00, 0x00, 0x38, 0x00, 0x0a, 0xaa, 0xaa, 0xaa, 0x92, 0x81, 0x54, 0x45, 0x42, 0x45, 0x00, 0x00,
50 0x00, 0x00, 0x38, 0x00, 0x04, 0x48, 0xa2, 0x4a, 0x89, 0x06, 0x24, 0x42, 0x41, 0x36, 0x00, 0x00,
51 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
56 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
60};
61
diff --git a/quantum/visualizer/resources/lcd_logo.png b/quantum/visualizer/resources/lcd_logo.png
new file mode 100644
index 000000000..6cf26fc67
--- /dev/null
+++ b/quantum/visualizer/resources/lcd_logo.png
Binary files differ
diff --git a/quantum/visualizer/resources/resources.h b/quantum/visualizer/resources/resources.h
new file mode 100644
index 000000000..1ea27a536
--- /dev/null
+++ b/quantum/visualizer/resources/resources.h
@@ -0,0 +1,27 @@
1/* Copyright 2017 Fred Sundvik
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef QUANTUM_VISUALIZER_RESOURCES_RESOURCES_H_
18#define QUANTUM_VISUALIZER_RESOURCES_RESOURCES_H_
19
20#include <stdint.h>
21
22#ifdef LCD_ENABLE
23extern const uint8_t resource_lcd_logo[];
24#endif
25
26
27#endif /* QUANTUM_VISUALIZER_RESOURCES_RESOURCES_H_ */
diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c
index 5826d909e..6f134097f 100644
--- a/quantum/visualizer/visualizer.c
+++ b/quantum/visualizer/visualizer.c
@@ -48,20 +48,22 @@ SOFTWARE.
48#include "serial_link/system/serial_link.h" 48#include "serial_link/system/serial_link.h"
49#endif 49#endif
50 50
51#include "action_util.h"
52
51// Define this in config.h 53// Define this in config.h
52#ifndef VISUALIZER_THREAD_PRIORITY 54#ifndef VISUALIZER_THREAD_PRIORITY
53#define "Visualizer thread priority not defined" 55#define "Visualizer thread priority not defined"
54#endif 56#endif
55 57
56// mods status
57#include "action_util.h"
58
59static visualizer_keyboard_status_t current_status = { 58static visualizer_keyboard_status_t current_status = {
60 .layer = 0xFFFFFFFF, 59 .layer = 0xFFFFFFFF,
61 .default_layer = 0xFFFFFFFF, 60 .default_layer = 0xFFFFFFFF,
62 .mods = 0xFF, 61 .mods = 0xFF,
63 .leds = 0xFFFFFFFF, 62 .leds = 0xFFFFFFFF,
64 .suspended = false, 63 .suspended = false,
64#ifdef VISUALIZER_USER_DATA_SIZE
65 .user_data = {0}
66#endif
65}; 67};
66 68
67static bool same_status(visualizer_keyboard_status_t* status1, visualizer_keyboard_status_t* status2) { 69static bool same_status(visualizer_keyboard_status_t* status1, visualizer_keyboard_status_t* status2) {
@@ -69,11 +71,19 @@ static bool same_status(visualizer_keyboard_status_t* status1, visualizer_keyboa
69 status1->default_layer == status2->default_layer && 71 status1->default_layer == status2->default_layer &&
70 status1->mods == status2->mods && 72 status1->mods == status2->mods &&
71 status1->leds == status2->leds && 73 status1->leds == status2->leds &&
72 status1->suspended == status2->suspended; 74 status1->suspended == status2->suspended
75#ifdef VISUALIZER_USER_DATA_SIZE
76 && memcmp(status1->user_data, status2->user_data, VISUALIZER_USER_DATA_SIZE) == 0
77#endif
78 ;
73} 79}
74 80
75static bool visualizer_enabled = false; 81static bool visualizer_enabled = false;
76 82
83#ifdef VISUALIZER_USER_DATA_SIZE
84static uint8_t user_data[VISUALIZER_USER_DATA_SIZE];
85#endif
86
77#define MAX_SIMULTANEOUS_ANIMATIONS 4 87#define MAX_SIMULTANEOUS_ANIMATIONS 4
78static keyframe_animation_t* animations[MAX_SIMULTANEOUS_ANIMATIONS] = {}; 88static keyframe_animation_t* animations[MAX_SIMULTANEOUS_ANIMATIONS] = {};
79 89
@@ -144,6 +154,14 @@ void stop_all_keyframe_animations(void) {
144 } 154 }
145} 155}
146 156
157static uint8_t get_num_running_animations(void) {
158 uint8_t count = 0;
159 for (int i=0;i<MAX_SIMULTANEOUS_ANIMATIONS;i++) {
160 count += animations[i] ? 1 : 0;
161 }
162 return count;
163}
164
147static bool update_keyframe_animation(keyframe_animation_t* animation, visualizer_state_t* state, systemticks_t delta, systemticks_t* sleep_time) { 165static bool update_keyframe_animation(keyframe_animation_t* animation, visualizer_state_t* state, systemticks_t delta, systemticks_t* sleep_time) {
148 // TODO: Clean up this messy code 166 // TODO: Clean up this messy code
149 dprintf("Animation frame%d, left %d, delta %d\n", animation->current_frame, 167 dprintf("Animation frame%d, left %d, delta %d\n", animation->current_frame,
@@ -212,175 +230,6 @@ void run_next_keyframe(keyframe_animation_t* animation, visualizer_state_t* stat
212 (*temp_animation.frame_functions[next_frame])(&temp_animation, &temp_state); 230 (*temp_animation.frame_functions[next_frame])(&temp_animation, &temp_state);
213} 231}
214 232
215bool keyframe_no_operation(keyframe_animation_t* animation, visualizer_state_t* state) {
216 (void)animation;
217 (void)state;
218 return false;
219}
220
221#ifdef LCD_BACKLIGHT_ENABLE
222bool keyframe_animate_backlight_color(keyframe_animation_t* animation, visualizer_state_t* state) {
223 int frame_length = animation->frame_lengths[animation->current_frame];
224 int current_pos = frame_length - animation->time_left_in_frame;
225 uint8_t t_h = LCD_HUE(state->target_lcd_color);
226 uint8_t t_s = LCD_SAT(state->target_lcd_color);
227 uint8_t t_i = LCD_INT(state->target_lcd_color);
228 uint8_t p_h = LCD_HUE(state->prev_lcd_color);
229 uint8_t p_s = LCD_SAT(state->prev_lcd_color);
230 uint8_t p_i = LCD_INT(state->prev_lcd_color);
231
232 uint8_t d_h1 = t_h - p_h; //Modulo arithmetic since we want to wrap around
233 int d_h2 = t_h - p_h;
234 // Chose the shortest way around
235 int d_h = abs(d_h2) < d_h1 ? d_h2 : d_h1;
236 int d_s = t_s - p_s;
237 int d_i = t_i - p_i;
238
239 int hue = (d_h * current_pos) / frame_length;
240 int sat = (d_s * current_pos) / frame_length;
241 int intensity = (d_i * current_pos) / frame_length;
242 //dprintf("%X -> %X = %X\n", p_h, t_h, hue);
243 hue += p_h;
244 sat += p_s;
245 intensity += p_i;
246 state->current_lcd_color = LCD_COLOR(hue, sat, intensity);
247 lcd_backlight_color(
248 LCD_HUE(state->current_lcd_color),
249 LCD_SAT(state->current_lcd_color),
250 LCD_INT(state->current_lcd_color));
251
252 return true;
253}
254
255bool keyframe_set_backlight_color(keyframe_animation_t* animation, visualizer_state_t* state) {
256 (void)animation;
257 state->prev_lcd_color = state->target_lcd_color;
258 state->current_lcd_color = state->target_lcd_color;
259 lcd_backlight_color(
260 LCD_HUE(state->current_lcd_color),
261 LCD_SAT(state->current_lcd_color),
262 LCD_INT(state->current_lcd_color));
263 return false;
264}
265#endif // LCD_BACKLIGHT_ENABLE
266
267#ifdef LCD_ENABLE
268bool keyframe_display_layer_text(keyframe_animation_t* animation, visualizer_state_t* state) {
269 (void)animation;
270 gdispClear(White);
271 gdispDrawString(0, 10, state->layer_text, state->font_dejavusansbold12, Black);
272 gdispFlush();
273 return false;
274}
275
276static void format_layer_bitmap_string(uint16_t default_layer, uint16_t layer, char* buffer) {
277 for (int i=0; i<16;i++)
278 {
279 uint32_t mask = (1u << i);
280 if (default_layer & mask) {
281 if (layer & mask) {
282 *buffer = 'B';
283 } else {
284 *buffer = 'D';
285 }
286 } else if (layer & mask) {
287 *buffer = '1';
288 } else {
289 *buffer = '0';
290 }
291 ++buffer;
292
293 if (i==3 || i==7 || i==11) {
294 *buffer = ' ';
295 ++buffer;
296 }
297 }
298 *buffer = 0;
299}
300
301bool keyframe_display_layer_bitmap(keyframe_animation_t* animation, visualizer_state_t* state) {
302 (void)animation;
303 const char* layer_help = "1=On D=Default B=Both";
304 char layer_buffer[16 + 4]; // 3 spaces and one null terminator
305 gdispClear(White);
306 gdispDrawString(0, 0, layer_help, state->font_fixed5x8, Black);
307 format_layer_bitmap_string(state->status.default_layer, state->status.layer, layer_buffer);
308 gdispDrawString(0, 10, layer_buffer, state->font_fixed5x8, Black);
309 format_layer_bitmap_string(state->status.default_layer >> 16, state->status.layer >> 16, layer_buffer);
310 gdispDrawString(0, 20, layer_buffer, state->font_fixed5x8, Black);
311 gdispFlush();
312 return false;
313}
314
315static void format_mods_bitmap_string(uint8_t mods, char* buffer) {
316 *buffer = ' ';
317 ++buffer;
318
319 for (int i = 0; i<8; i++)
320 {
321 uint32_t mask = (1u << i);
322 if (mods & mask) {
323 *buffer = '1';
324 } else {
325 *buffer = '0';
326 }
327 ++buffer;
328
329 if (i==3) {
330 *buffer = ' ';
331 ++buffer;
332 }
333 }
334 *buffer = 0;
335}
336
337bool keyframe_display_mods_bitmap(keyframe_animation_t* animation, visualizer_state_t* state) {
338 (void)animation;
339
340 const char* title = "Modifier states";
341 const char* mods_header = " CSAG CSAG ";
342 char status_buffer[12];
343
344 gdispClear(White);
345 gdispDrawString(0, 0, title, state->font_fixed5x8, Black);
346 gdispDrawString(0, 10, mods_header, state->font_fixed5x8, Black);
347 format_mods_bitmap_string(state->status.mods, status_buffer);
348 gdispDrawString(0, 20, status_buffer, state->font_fixed5x8, Black);
349
350 gdispFlush();
351 return false;
352}
353#endif // LCD_ENABLE
354
355bool keyframe_disable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state) {
356 (void)animation;
357 (void)state;
358#ifdef LCD_ENABLE
359 gdispSetPowerMode(powerOff);
360#endif
361#ifdef LCD_BACKLIGHT_ENABLE
362 lcd_backlight_hal_color(0, 0, 0);
363#endif
364 return false;
365}
366
367bool keyframe_enable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state) {
368 (void)animation;
369 (void)state;
370#ifdef LCD_ENABLE
371 gdispSetPowerMode(powerOn);
372#endif
373 return false;
374}
375
376bool enable_visualization(keyframe_animation_t* animation, visualizer_state_t* state) {
377 (void)animation;
378 (void)state;
379 dprint("User visualizer inited\n");
380 visualizer_enabled = true;
381 return false;
382}
383
384// TODO: Optimize the stack size, this is probably way too big 233// TODO: Optimize the stack size, this is probably way too big
385static DECLARE_THREAD_STACK(visualizerThreadStack, 1024); 234static DECLARE_THREAD_STACK(visualizerThreadStack, 1024);
386static DECLARE_THREAD_FUNCTION(visualizerThread, arg) { 235static DECLARE_THREAD_FUNCTION(visualizerThread, arg) {
@@ -396,6 +245,9 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) {
396 .mods = 0xFF, 245 .mods = 0xFF,
397 .leds = 0xFFFFFFFF, 246 .leds = 0xFFFFFFFF,
398 .suspended = false, 247 .suspended = false,
248#ifdef VISUALIZER_USER_DATA_SIZE
249 .user_data = {0},
250#endif
399 }; 251 };
400 252
401 visualizer_state_t state = { 253 visualizer_state_t state = {
@@ -418,13 +270,15 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) {
418 270
419 systemticks_t sleep_time = TIME_INFINITE; 271 systemticks_t sleep_time = TIME_INFINITE;
420 systemticks_t current_time = gfxSystemTicks(); 272 systemticks_t current_time = gfxSystemTicks();
273 bool force_update = true;
421 274
422 while(true) { 275 while(true) {
423 systemticks_t new_time = gfxSystemTicks(); 276 systemticks_t new_time = gfxSystemTicks();
424 systemticks_t delta = new_time - current_time; 277 systemticks_t delta = new_time - current_time;
425 current_time = new_time; 278 current_time = new_time;
426 bool enabled = visualizer_enabled; 279 bool enabled = visualizer_enabled;
427 if (!same_status(&state.status, &current_status)) { 280 if (force_update || !same_status(&state.status, &current_status)) {
281 force_update = false;
428 if (visualizer_enabled) { 282 if (visualizer_enabled) {
429 if (current_status.suspended) { 283 if (current_status.suspended) {
430 stop_all_keyframe_animations(); 284 stop_all_keyframe_animations();
@@ -433,8 +287,9 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) {
433 user_visualizer_suspend(&state); 287 user_visualizer_suspend(&state);
434 } 288 }
435 else { 289 else {
290 visualizer_keyboard_status_t prev_status = state.status;
436 state.status = current_status; 291 state.status = current_status;
437 update_user_visualizer_state(&state); 292 update_user_visualizer_state(&state, &prev_status);
438 } 293 }
439 state.prev_lcd_color = state.current_lcd_color; 294 state.prev_lcd_color = state.current_lcd_color;
440 } 295 }
@@ -458,13 +313,17 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) {
458 gdispGFlush(LED_DISPLAY); 313 gdispGFlush(LED_DISPLAY);
459#endif 314#endif
460 315
316#ifdef LCD_ENABLE
317 gdispGFlush(LCD_DISPLAY);
318#endif
319
461#ifdef EMULATOR 320#ifdef EMULATOR
462 draw_emulator(); 321 draw_emulator();
463#endif 322#endif
464 // The animation can enable the visualizer 323 // Enable the visualizer when the startup or the suspend animation has finished
465 // And we might need to update the state when that happens 324 if (!visualizer_enabled && state.status.suspended == false && get_num_running_animations() == 0) {
466 // so don't sleep 325 visualizer_enabled = true;
467 if (enabled != visualizer_enabled) { 326 force_update = true;
468 sleep_time = 0; 327 sleep_time = 0;
469 } 328 }
470 329
@@ -554,6 +413,12 @@ uint8_t visualizer_get_mods() {
554 return mods; 413 return mods;
555} 414}
556 415
416#ifdef VISUALIZER_USER_DATA_SIZE
417void visualizer_set_user_data(void* u) {
418 memcpy(user_data, u, VISUALIZER_USER_DATA_SIZE);
419}
420#endif
421
557void visualizer_update(uint32_t default_state, uint32_t state, uint8_t mods, uint32_t leds) { 422void visualizer_update(uint32_t default_state, uint32_t state, uint8_t mods, uint32_t leds) {
558 // Note that there's a small race condition here, the thread could read 423 // Note that there's a small race condition here, the thread could read
559 // a state where one of these are set but not the other. But this should 424 // a state where one of these are set but not the other. But this should
@@ -582,6 +447,9 @@ void visualizer_update(uint32_t default_state, uint32_t state, uint8_t mods, uin
582 .leds = leds, 447 .leds = leds,
583 .suspended = current_status.suspended, 448 .suspended = current_status.suspended,
584 }; 449 };
450#ifdef VISUALIZER_USER_DATA_SIZE
451 memcpy(new_status.user_data, user_data, VISUALIZER_USER_DATA_SIZE);
452#endif
585 if (!same_status(&current_status, &new_status)) { 453 if (!same_status(&current_status, &new_status)) {
586 changed = true; 454 changed = true;
587 current_status = new_status; 455 current_status = new_status;
diff --git a/quantum/visualizer/visualizer.h b/quantum/visualizer/visualizer.h
index 315af5022..d6f279e10 100644
--- a/quantum/visualizer/visualizer.h
+++ b/quantum/visualizer/visualizer.h
@@ -34,7 +34,7 @@ SOFTWARE.
34#include "lcd_backlight.h" 34#include "lcd_backlight.h"
35#endif 35#endif
36 36
37// use this function to merget both real_mods and oneshot_mods in a uint16_t 37// use this function to merge both real_mods and oneshot_mods in a uint16_t
38uint8_t visualizer_get_mods(void); 38uint8_t visualizer_get_mods(void);
39 39
40// This need to be called once at the start 40// This need to be called once at the start
@@ -68,6 +68,9 @@ typedef struct {
68 uint8_t mods; 68 uint8_t mods;
69 uint32_t leds; // See led.h for available statuses 69 uint32_t leds; // See led.h for available statuses
70 bool suspended; 70 bool suspended;
71#ifdef VISUALIZER_USER_DATA_SIZE
72 uint8_t user_data[VISUALIZER_USER_DATA_SIZE];
73#endif
71} visualizer_keyboard_status_t; 74} visualizer_keyboard_status_t;
72 75
73// The state struct is used by the various keyframe functions 76// The state struct is used by the various keyframe functions
@@ -123,32 +126,22 @@ void stop_keyframe_animation(keyframe_animation_t* animation);
123// Useful for crossfades for example 126// Useful for crossfades for example
124void run_next_keyframe(keyframe_animation_t* animation, visualizer_state_t* state); 127void run_next_keyframe(keyframe_animation_t* animation, visualizer_state_t* state);
125 128
126// Some predefined keyframe functions that can be used by the user code 129// The master can set userdata which will be transferred to the slave
127// Does nothing, useful for adding delays 130#ifdef VISUALIZER_USER_DATA_SIZE
128bool keyframe_no_operation(keyframe_animation_t* animation, visualizer_state_t* state); 131void visualizer_set_user_data(void* user_data);
129// Animates the LCD backlight color between the current color and the target color (of the state) 132#endif
130bool keyframe_animate_backlight_color(keyframe_animation_t* animation, visualizer_state_t* state);
131// Sets the backlight color to the target color
132bool keyframe_set_backlight_color(keyframe_animation_t* animation, visualizer_state_t* state);
133// Displays the layer text centered vertically on the screen
134bool keyframe_display_layer_text(keyframe_animation_t* animation, visualizer_state_t* state);
135// Displays a bitmap (0/1) of all the currently active layers
136bool keyframe_display_layer_bitmap(keyframe_animation_t* animation, visualizer_state_t* state);
137// Displays a bitmap (0/1) of all the currently active mods
138bool keyframe_display_mods_bitmap(keyframe_animation_t* animation, visualizer_state_t* state);
139
140bool keyframe_disable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state);
141bool keyframe_enable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state);
142
143// Call this once, when the initial animation has finished, alternatively you can call it
144// directly from the initalize_user_visualizer function (the animation can be null)
145bool enable_visualization(keyframe_animation_t* animation, visualizer_state_t* state);
146 133
147// These functions have to be implemented by the user 134// These functions have to be implemented by the user
148void initialize_user_visualizer(visualizer_state_t* state); 135// Called regularly each time the state has changed (but not every scan loop)
149void update_user_visualizer_state(visualizer_state_t* state); 136void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status);
137// Called when the computer goes to suspend, will also stop calling update_user_visualizer_state
150void user_visualizer_suspend(visualizer_state_t* state); 138void user_visualizer_suspend(visualizer_state_t* state);
139// You have to start at least one animation as a response to the following two functions
140// When the animation has finished the visualizer will resume normal operation and start calling the
141// update_user_visualizer_state again
142// Called when the keyboard boots up
143void initialize_user_visualizer(visualizer_state_t* state);
144// Called when the computer resumes from a suspend
151void user_visualizer_resume(visualizer_state_t* state); 145void user_visualizer_resume(visualizer_state_t* state);
152 146
153
154#endif /* VISUALIZER_H */ 147#endif /* VISUALIZER_H */
diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk
index 2f4a41d66..5f710124b 100644
--- a/quantum/visualizer/visualizer.mk
+++ b/quantum/visualizer/visualizer.mk
@@ -20,7 +20,8 @@
20# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21# SOFTWARE. 21# SOFTWARE.
22 22
23SRC += $(VISUALIZER_DIR)/visualizer.c 23SRC += $(VISUALIZER_DIR)/visualizer.c \
24 $(VISUALIZER_DIR)/visualizer_keyframes.c
24EXTRAINCDIRS += $(GFXINC) $(VISUALIZER_DIR) 25EXTRAINCDIRS += $(GFXINC) $(VISUALIZER_DIR)
25GFXLIB = $(LIB_PATH)/ugfx 26GFXLIB = $(LIB_PATH)/ugfx
26VPATH += $(VISUALIZER_PATH) 27VPATH += $(VISUALIZER_PATH)
@@ -32,25 +33,33 @@ OPT_DEFS += -DLCD_ENABLE
32ULIBS += -lm 33ULIBS += -lm
33endif 34endif
34 35
35ifdef LCD_BACKLIGHT_ENABLE 36ifeq ($(strip $(LCD_ENABLE)), yes)
36SRC += $(VISUALIZER_DIR)/lcd_backlight.c 37SRC += $(VISUALIZER_DIR)/lcd_backlight.c
38SRC += $(VISUALIZER_DIR)/lcd_keyframes.c
39SRC += $(VISUALIZER_DIR)/lcd_backlight_keyframes.c
40# Note, that the linker will strip out any resources that are not actually in use
41SRC += $(VISUALIZER_DIR)/resources/lcd_logo.c
37OPT_DEFS += -DLCD_BACKLIGHT_ENABLE 42OPT_DEFS += -DLCD_BACKLIGHT_ENABLE
38endif 43endif
39 44
40ifdef LED_ENABLE 45ifeq ($(strip $(LED_ENABLE)), yes)
41SRC += $(VISUALIZER_DIR)/led_test.c 46SRC += $(VISUALIZER_DIR)/led_keyframes.c
42OPT_DEFS += -DLED_ENABLE 47OPT_DEFS += -DLED_ENABLE
43endif 48endif
44 49
45include $(GFXLIB)/gfx.mk 50include $(GFXLIB)/gfx.mk
46SRC += $(patsubst $(TOP_DIR)/%,%,$(GFXSRC)) 51GFXSRC := $(patsubst $(TOP_DIR)/%,%,$(GFXSRC))
47OPT_DEFS += $(patsubst %,-D%,$(patsubst -D%,%,$(GFXDEFS))) 52GFXDEFS := $(patsubst %,-D%,$(patsubst -D%,%,$(GFXDEFS)))
48 53
49ifneq ("$(wildcard $(KEYMAP_PATH)/visualizer.c)","") 54ifneq ("$(wildcard $(KEYMAP_PATH)/visualizer.c)","")
50 SRC += keyboards/$(KEYBOARD)/keymaps/$(KEYMAP)/visualizer.c 55 SRC += keyboards/$(KEYBOARD)/keymaps/$(KEYMAP)/visualizer.c
51else 56else
52 ifeq ("$(wildcard $(SUBPROJECT_PATH)/keymaps/$(KEYMAP)/visualizer.c)","") 57 ifeq ("$(wildcard $(SUBPROJECT_PATH)/keymaps/$(KEYMAP)/visualizer.c)","")
58 ifeq ("$(wildcard $(SUBPROJECT_PATH)/visualizer.c)","")
53$(error "$(KEYMAP_PATH)/visualizer.c" does not exist) 59$(error "$(KEYMAP_PATH)/visualizer.c" does not exist)
60 else
61 SRC += keyboards/$(KEYBOARD)/$(SUBPROJECT)/visualizer.c
62 endif
54 else 63 else
55 SRC += keyboards/$(KEYBOARD)/$(SUBPROJECT)/keymaps/$(KEYMAP)/visualizer.c 64 SRC += keyboards/$(KEYBOARD)/$(SUBPROJECT)/keymaps/$(KEYMAP)/visualizer.c
56 endif 65 endif
diff --git a/quantum/visualizer/visualizer_keyframes.c b/quantum/visualizer/visualizer_keyframes.c
new file mode 100644
index 000000000..8f6a7e15a
--- /dev/null
+++ b/quantum/visualizer/visualizer_keyframes.c
@@ -0,0 +1,23 @@
1/* Copyright 2017 Fred Sundvik
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "visualizer_keyframes.h"
18
19bool keyframe_no_operation(keyframe_animation_t* animation, visualizer_state_t* state) {
20 (void)animation;
21 (void)state;
22 return false;
23}
diff --git a/quantum/visualizer/visualizer_keyframes.h b/quantum/visualizer/visualizer_keyframes.h
new file mode 100644
index 000000000..9ef7653c5
--- /dev/null
+++ b/quantum/visualizer/visualizer_keyframes.h
@@ -0,0 +1,26 @@
1/* Copyright 2017 Fred Sundvik
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef QUANTUM_VISUALIZER_VISUALIZER_KEYFRAMES_H_
18#define QUANTUM_VISUALIZER_VISUALIZER_KEYFRAMES_H_
19
20#include "visualizer.h"
21
22// Some predefined keyframe functions that can be used by the user code
23// Does nothing, useful for adding delays
24bool keyframe_no_operation(keyframe_animation_t* animation, visualizer_state_t* state);
25
26#endif /* QUANTUM_VISUALIZER_VISUALIZER_KEYFRAMES_H_ */
diff --git a/tmk_core/common/action_util.c b/tmk_core/common/action_util.c
index cb4b25264..77848c092 100644
--- a/tmk_core/common/action_util.c
+++ b/tmk_core/common/action_util.c
@@ -58,9 +58,13 @@ void set_oneshot_locked_mods(int8_t mods) { oneshot_locked_mods = mods; }
58void clear_oneshot_locked_mods(void) { oneshot_locked_mods = 0; } 58void clear_oneshot_locked_mods(void) { oneshot_locked_mods = 0; }
59#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) 59#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
60static int16_t oneshot_time = 0; 60static int16_t oneshot_time = 0;
61inline bool has_oneshot_mods_timed_out() { 61bool has_oneshot_mods_timed_out(void) {
62 return TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT; 62 return TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT;
63} 63}
64#else
65bool has_oneshot_mods_timed_out(void) {
66 return false;
67}
64#endif 68#endif
65#endif 69#endif
66 70