From aee9b10e92a597984ba9693b2dfcf597ca380a70 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sun, 10 Jul 2016 23:45:39 +0300 Subject: [PATCH 01/34] Add a keyboard specific visualizer --- keyboards/ergodox/infinity/Makefile | 2 +- keyboards/ergodox/infinity/rules.mk | 2 +- keyboards/ergodox/infinity/visualizer.c | 168 ++++++++++++++++++++++++ quantum/visualizer/visualizer.mk | 4 + 4 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 keyboards/ergodox/infinity/visualizer.c diff --git a/keyboards/ergodox/infinity/Makefile b/keyboards/ergodox/infinity/Makefile index 191c6bb664..bd09e5885d 100644 --- a/keyboards/ergodox/infinity/Makefile +++ b/keyboards/ergodox/infinity/Makefile @@ -1,3 +1,3 @@ ifndef MAKEFILE_INCLUDED include ../../../Makefile -endif \ No newline at end of file +endif diff --git a/keyboards/ergodox/infinity/rules.mk b/keyboards/ergodox/infinity/rules.mk index 473a6dfec6..1b011cd589 100644 --- a/keyboards/ergodox/infinity/rules.mk +++ b/keyboards/ergodox/infinity/rules.mk @@ -59,7 +59,7 @@ OPT_DEFS += -DCORTEX_VTOR_INIT=0x00002000 # CUSTOM_MATRIX ?= yes # Custom matrix file SERIAL_LINK_ENABLE = yes -VISUALIZER_ENABLE ?= no #temporarily disabled to make everything compile +VISUALIZER_ENABLE ?= yes LCD_ENABLE ?= yes LED_ENABLE ?= yes LCD_BACKLIGHT_ENABLE ?= yes diff --git a/keyboards/ergodox/infinity/visualizer.c b/keyboards/ergodox/infinity/visualizer.c new file mode 100644 index 0000000000..c0d335ce6a --- /dev/null +++ b/keyboards/ergodox/infinity/visualizer.c @@ -0,0 +1,168 @@ +/* +Copyright 2016 Fred Sundvik + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +// Currently we are assuming that both the backlight and LCD are enabled +// But it's entirely possible to write a custom visualizer that use only +// one of them +#ifndef LCD_BACKLIGHT_ENABLE +#error This visualizer needs that LCD backlight is enabled +#endif + +#ifndef LCD_ENABLE +#error This visualizer needs that LCD is enabled +#endif + +#include "visualizer.h" +#include "led_test.h" + +static const char* welcome_text[] = {"TMK", "Infinity Ergodox"}; + +// Just an example how to write custom keyframe functions, we could have moved +// all this into the init function +bool display_welcome(keyframe_animation_t* animation, visualizer_state_t* state) { + (void)animation; + // Read the uGFX documentation for information how to use the displays + // http://wiki.ugfx.org/index.php/Main_Page + gdispClear(White); + // You can use static variables for things that can't be found in the animation + // or state structs + gdispDrawString(0, 3, welcome_text[0], state->font_dejavusansbold12, Black); + gdispDrawString(0, 15, welcome_text[1], state->font_dejavusansbold12, Black); + // Always remember to flush the display + gdispFlush(); + // you could set the backlight color as well, but we won't do it here, since + // it's part of the following animation + // lcd_backlight_color(hue, saturation, intensity); + // We don't need constant updates, just drawing the screen once is enough + return false; +} + +// Feel free to modify the animations below, or even add new ones if needed + +// Don't worry, if the startup animation is long, you can use the keyboard like normal +// during that time +static keyframe_animation_t startup_animation = { + .num_frames = 4, + .loop = false, + .frame_lengths = {0, gfxMillisecondsToTicks(1000), gfxMillisecondsToTicks(5000), 0}, + .frame_functions = { + display_welcome, + keyframe_animate_backlight_color, + keyframe_no_operation, + enable_visualization + }, +}; + +// The color animation animates the LCD color when you change layers +static keyframe_animation_t color_animation = { + .num_frames = 2, + .loop = false, + // Note that there's a 200 ms no-operation frame, + // this prevents the color from changing when activating the layer + // momentarily + .frame_lengths = {gfxMillisecondsToTicks(200), gfxMillisecondsToTicks(500)}, + .frame_functions = {keyframe_no_operation, keyframe_animate_backlight_color}, +}; + +// The LCD animation alternates between the layer name display and a +// bitmap that displays all active layers +static keyframe_animation_t lcd_animation = { + .num_frames = 2, + .loop = true, + .frame_lengths = {gfxMillisecondsToTicks(2000), gfxMillisecondsToTicks(2000)}, + .frame_functions = {keyframe_display_layer_text, keyframe_display_layer_bitmap}, +}; + +static keyframe_animation_t suspend_animation = { + .num_frames = 3, + .loop = false, + .frame_lengths = {0, gfxMillisecondsToTicks(1000), 0}, + .frame_functions = { + keyframe_display_layer_text, + keyframe_animate_backlight_color, + keyframe_disable_lcd_and_backlight, + }, +}; + +static keyframe_animation_t resume_animation = { + .num_frames = 5, + .loop = false, + .frame_lengths = {0, 0, gfxMillisecondsToTicks(1000), gfxMillisecondsToTicks(5000), 0}, + .frame_functions = { + keyframe_enable_lcd_and_backlight, + display_welcome, + keyframe_animate_backlight_color, + keyframe_no_operation, + enable_visualization, + }, +}; + +void initialize_user_visualizer(visualizer_state_t* state) { + // The brightness will be dynamically adjustable in the future + // But for now, change it here. + lcd_backlight_brightness(0x50); + state->current_lcd_color = LCD_COLOR(0x00, 0x00, 0xFF); + state->target_lcd_color = LCD_COLOR(0x10, 0xFF, 0xFF); + start_keyframe_animation(&startup_animation); + start_keyframe_animation(&led_test_animation); +} + +void update_user_visualizer_state(visualizer_state_t* state) { + // Add more tests, change the colors and layer texts here + // Usually you want to check the high bits (higher layers first) + // because that's the order layers are processed for keypresses + // You can for check for example: + // state->status.layer + // state->status.default_layer + // state->status.leds (see led.h for available statuses) + if (state->status.layer & 0x8) { + state->target_lcd_color = LCD_COLOR(0xC0, 0xB0, 0xFF); + state->layer_text = "Numpad"; + } + else if (state->status.layer & 0x4) { + state->target_lcd_color = LCD_COLOR(0, 0xB0, 0xFF); + state->layer_text = "KBD functions"; + } + else if (state->status.layer & 0x2) { + state->target_lcd_color = LCD_COLOR(0x80, 0xB0, 0xFF); + state->layer_text = "Function keys"; + } + else { + state->target_lcd_color = LCD_COLOR(0x40, 0xB0, 0xFF); + state->layer_text = "Default"; + } + // You can also stop existing animations, and start your custom ones here + // remember that you should normally have only one animation for the LCD + // and one for the background. But you can also combine them if you want. + start_keyframe_animation(&lcd_animation); + start_keyframe_animation(&color_animation); +} + +void user_visualizer_suspend(visualizer_state_t* state) { + state->layer_text = "Suspending..."; + uint8_t hue = LCD_HUE(state->current_lcd_color); + uint8_t sat = LCD_SAT(state->current_lcd_color); + state->target_lcd_color = LCD_COLOR(hue, sat, 0); + start_keyframe_animation(&suspend_animation); +} + +void user_visualizer_resume(visualizer_state_t* state) { + state->current_lcd_color = LCD_COLOR(0x00, 0x00, 0x00); + state->target_lcd_color = LCD_COLOR(0x10, 0xFF, 0xFF); + start_keyframe_animation(&resume_animation); + start_keyframe_animation(&led_test_animation); +} diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk index 2f4a41d66f..ecdeba1eee 100644 --- a/quantum/visualizer/visualizer.mk +++ b/quantum/visualizer/visualizer.mk @@ -50,7 +50,11 @@ ifneq ("$(wildcard $(KEYMAP_PATH)/visualizer.c)","") SRC += keyboards/$(KEYBOARD)/keymaps/$(KEYMAP)/visualizer.c else ifeq ("$(wildcard $(SUBPROJECT_PATH)/keymaps/$(KEYMAP)/visualizer.c)","") + ifeq ("$(wildcard $(SUBPROJECT_PATH)/visualizer.c)","") $(error "$(KEYMAP_PATH)/visualizer.c" does not exist) + else + SRC += keyboards/$(KEYBOARD)/$(SUBPROJECT)/visualizer.c + endif else SRC += keyboards/$(KEYBOARD)/$(SUBPROJECT)/keymaps/$(KEYMAP)/visualizer.c endif From bb86be1f1f3927a7ce339cb9439c97914af24754 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sun, 28 Aug 2016 23:08:34 +0300 Subject: [PATCH 02/34] Remove unneeded makefile include --- keyboards/ergodox/ez/rules.mk | 4 ---- keyboards/ergodox/infinity/rules.mk | 4 ---- 2 files changed, 8 deletions(-) diff --git a/keyboards/ergodox/ez/rules.mk b/keyboards/ergodox/ez/rules.mk index 64b2db8158..6cd1c0c4f7 100644 --- a/keyboards/ergodox/ez/rules.mk +++ b/keyboards/ergodox/ez/rules.mk @@ -74,7 +74,3 @@ OPT_DEFS += -DBOOTLOADER_SIZE=512 SLEEP_LED_ENABLE = no API_SYSEX_ENABLE ?= no RGBLIGHT_ENABLE ?= yes - -ifndef QUANTUM_DIR - include ../../../Makefile -endif diff --git a/keyboards/ergodox/infinity/rules.mk b/keyboards/ergodox/infinity/rules.mk index 1b011cd589..d51574acae 100644 --- a/keyboards/ergodox/infinity/rules.mk +++ b/keyboards/ergodox/infinity/rules.mk @@ -66,10 +66,6 @@ LCD_BACKLIGHT_ENABLE ?= yes MIDI_ENABLE = no RGBLIGHT_ENABLE = no -ifndef QUANTUM_DIR - include ../../../Makefile -endif - ifdef LCD_ENABLE include $(SUBPROJECT_PATH)/drivers/gdisp/st7565ergodox/driver.mk endif From f5c89416527a3ec435ed49137fd2bf4af216024c Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sun, 28 Aug 2016 23:25:39 +0300 Subject: [PATCH 03/34] UGFX is compiled once per keyboard instead of keymap --- build_keyboard.mk | 8 ++++---- .../infinity/drivers/gdisp/st7565ergodox/board_ST7565.h | 2 -- quantum/visualizer/visualizer.mk | 4 ++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/build_keyboard.mk b/build_keyboard.mk index 82464d5830..ad92892e27 100644 --- a/build_keyboard.mk +++ b/build_keyboard.mk @@ -258,12 +258,12 @@ endif OUTPUTS := $(KEYMAP_OUTPUT) $(KEYBOARD_OUTPUT) $(KEYMAP_OUTPUT)_SRC := $(SRC) -$(KEYMAP_OUTPUT)_DEFS := $(OPT_DEFS) -DQMK_KEYBOARD=\"$(KEYBOARD)\" -DQMK_KEYMAP=\"$(KEYMAP)\" +$(KEYMAP_OUTPUT)_DEFS := $(OPT_DEFS) $(GFXDEFS) -DQMK_KEYBOARD=\"$(KEYBOARD)\" -DQMK_KEYMAP=\"$(KEYMAP)\" $(KEYMAP_OUTPUT)_INC := $(VPATH) $(EXTRAINCDIRS) $(KEYMAP_OUTPUT)_CONFIG := $(CONFIG_H) -$(KEYBOARD_OUTPUT)_SRC := $(CHIBISRC) -$(KEYBOARD_OUTPUT)_DEFS := $(PROJECT_DEFS) -$(KEYBOARD_OUTPUT)_INC := $(PROJECT_INC) +$(KEYBOARD_OUTPUT)_SRC := $(CHIBISRC) $(GFXSRC) +$(KEYBOARD_OUTPUT)_DEFS := $(PROJECT_DEFS) $(GFXDEFS) +$(KEYBOARD_OUTPUT)_INC := $(PROJECT_INC) $(GFXINC) $(KEYBOARD_OUTPUT)_CONFIG := $(PROJECT_CONFIG) # Default target. diff --git a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/board_ST7565.h b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/board_ST7565.h index 290571ce5b..abda0bd858 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 @@ #ifndef _GDISP_LLD_BOARD_H #define _GDISP_LLD_BOARD_H -#include "print.h" - #define ST7565_LCD_BIAS ST7565_LCD_BIAS_9 // actually 6 #define ST7565_ADC ST7565_ADC_NORMAL #define ST7565_COM_SCAN ST7565_COM_SCAN_DEC diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk index ecdeba1eee..8f5fb89334 100644 --- a/quantum/visualizer/visualizer.mk +++ b/quantum/visualizer/visualizer.mk @@ -43,8 +43,8 @@ OPT_DEFS += -DLED_ENABLE endif include $(GFXLIB)/gfx.mk -SRC += $(patsubst $(TOP_DIR)/%,%,$(GFXSRC)) -OPT_DEFS += $(patsubst %,-D%,$(patsubst -D%,%,$(GFXDEFS))) +GFXSRC := $(patsubst $(TOP_DIR)/%,%,$(GFXSRC)) +GFXDEFS := $(patsubst %,-D%,$(patsubst -D%,%,$(GFXDEFS))) ifneq ("$(wildcard $(KEYMAP_PATH)/visualizer.c)","") SRC += keyboards/$(KEYBOARD)/keymaps/$(KEYMAP)/visualizer.c From 6039a4f6edefbad7604a9533d445091cd646f240 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Tue, 28 Mar 2017 09:59:29 +0300 Subject: [PATCH 04/34] Empty implementation of has_onshot_mods_timed_out When the timeout is zero or not defined, the function now returns false. Fixes a linker error when the visualizer is enabled --- tmk_core/common/action_util.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tmk_core/common/action_util.c b/tmk_core/common/action_util.c index cb4b252648..77848c0923 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; } void clear_oneshot_locked_mods(void) { oneshot_locked_mods = 0; } #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) static int16_t oneshot_time = 0; -inline bool has_oneshot_mods_timed_out() { +bool has_oneshot_mods_timed_out(void) { return TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT; } +#else +bool has_oneshot_mods_timed_out(void) { + return false; +} #endif #endif From 503565d1742ed458c992192a05f6ffe1db053135 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Fri, 31 Mar 2017 22:51:00 +0300 Subject: [PATCH 05/34] Only re-send matrix every 5ms The previous 1ms value was too often, and wouldn't always leave time for the visualizer --- quantum/serial_link/system/serial_link.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quantum/serial_link/system/serial_link.c b/quantum/serial_link/system/serial_link.c index 75c7e77a76..b3bee62a18 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) { systime_t current_time = chVTGetSystemTimeX(); systime_t delta = current_time - last_update; - if (changed || delta > US2ST(1000)) { + if (changed || delta > US2ST(5000)) { last_update = current_time; last_matrix = matrix; matrix_object_t* m = begin_write_keyboard_matrix(); From 2b24d35846693a3365a35b6ee9bc31b70659cfcf Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Fri, 31 Mar 2017 23:58:10 +0300 Subject: [PATCH 06/34] Hopefully finally fix the corrupt LCD The SPI bus is now selected and deselected before each set of commands. Also speed up things by buffering many commands into a single batch. --- .../gdisp/st7565ergodox/board_ST7565.h | 46 +-- .../gdisp/st7565ergodox/gdisp_lld_ST7565.c | 371 ++++++++++-------- 2 files changed, 217 insertions(+), 200 deletions(-) diff --git a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/board_ST7565.h b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/board_ST7565.h index abda0bd858..c2092b5e8d 100644 --- a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/board_ST7565.h +++ b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/board_ST7565.h @@ -37,10 +37,14 @@ // MSB First // CLK Low by default static const SPIConfig spi1config = { - NULL, - /* HW dependent part.*/ - ST7565_GPIOPORT, - ST7565_SS_PIN, + // Operation complete callback or @p NULL. + .end_cb = NULL, + //The chip select line port - when not using pcs. + .ssport = ST7565_GPIOPORT, + // brief The chip select line pad number - when not using pcs. + .sspad=ST7565_SS_PIN, + // SPI initialization data. + .tar0 = SPIx_CTARn_FMSZ(7) | SPIx_CTARn_ASC(7) | SPIx_CTARn_DT(7) @@ -50,13 +54,10 @@ static const SPIConfig spi1config = { //SPI_CR1_BR_0 }; -static bool_t st7565_is_data_mode = 1; - static GFXINLINE void init_board(GDisplay *g) { (void) g; palSetPadModeNamed(A0, PAL_MODE_OUTPUT_PUSHPULL); palSetPad(ST7565_GPIOPORT, ST7565_A0_PIN); - st7565_is_data_mode = 1; palSetPadModeNamed(RST, PAL_MODE_OUTPUT_PUSHPULL); palSetPad(ST7565_GPIOPORT, ST7565_RST_PIN); palSetPadModeRaw(MOSI, ST7565_SPI_MODE); @@ -65,7 +66,6 @@ static GFXINLINE void init_board(GDisplay *g) { spiInit(); spiStart(&SPID1, &spi1config); - spiSelect(&SPID1); } static GFXINLINE void post_init_board(GDisplay *g) { @@ -86,39 +86,27 @@ static GFXINLINE void acquire_bus(GDisplay *g) { (void) g; // Only the LCD is using the SPI bus, so no need to acquire // spiAcquireBus(&SPID1); + spiSelect(&SPID1); } static GFXINLINE void release_bus(GDisplay *g) { (void) g; // Only the LCD is using the SPI bus, so no need to release //spiReleaseBus(&SPID1); + spiUnselect(&SPID1); } -static GFXINLINE void write_cmd(GDisplay *g, uint8_t cmd) { - (void) g; - if (st7565_is_data_mode) { - // The sleeps need to be at lest 10 vs 25 ns respectively - // So let's sleep two ticks, one tick might not be enough - // if we are at the end of the tick - chThdSleep(2); - palClearPad(ST7565_GPIOPORT, ST7565_A0_PIN); - chThdSleep(2); - st7565_is_data_mode = 0; - } - spiSend(&SPID1, 1, &cmd); +static GFXINLINE void enter_data_mode(GDisplay *g) { + palSetPad(ST7565_GPIOPORT, ST7565_A0_PIN); } +static GFXINLINE void enter_cmd_mode(GDisplay *g) { + palClearPad(ST7565_GPIOPORT, ST7565_A0_PIN); +} + + static GFXINLINE void write_data(GDisplay *g, uint8_t* data, uint16_t length) { (void) g; - if (!st7565_is_data_mode) { - // The sleeps need to be at lest 10 vs 25 ns respectively - // So let's sleep two ticks, one tick might not be enough - // if we are at the end of the tick - chThdSleep(2); - palSetPad(ST7565_GPIOPORT, ST7565_A0_PIN); - chThdSleep(2); - st7565_is_data_mode = 1; - } spiSend(&SPID1, length, data); } 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 c33aea81a8..4547f14193 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 @@ /*===========================================================================*/ #ifndef GDISP_SCREEN_HEIGHT - #define GDISP_SCREEN_HEIGHT 32 +#define GDISP_SCREEN_HEIGHT 32 #endif #ifndef GDISP_SCREEN_WIDTH - #define GDISP_SCREEN_WIDTH 128 +#define GDISP_SCREEN_WIDTH 128 #endif #ifndef GDISP_INITIAL_CONTRAST - #define GDISP_INITIAL_CONTRAST 0 +#define GDISP_INITIAL_CONTRAST 0 #endif #ifndef GDISP_INITIAL_BACKLIGHT - #define GDISP_INITIAL_BACKLIGHT 100 +#define GDISP_INITIAL_BACKLIGHT 100 #endif #define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER<<0) @@ -40,16 +40,16 @@ /* Driver config defaults for backward compatibility. */ /*===========================================================================*/ #ifndef ST7565_LCD_BIAS - #define ST7565_LCD_BIAS ST7565_LCD_BIAS_7 +#define ST7565_LCD_BIAS ST7565_LCD_BIAS_7 #endif #ifndef ST7565_ADC - #define ST7565_ADC ST7565_ADC_NORMAL +#define ST7565_ADC ST7565_ADC_NORMAL #endif #ifndef ST7565_COM_SCAN - #define ST7565_COM_SCAN ST7565_COM_SCAN_INC +#define ST7565_COM_SCAN ST7565_COM_SCAN_INC #endif #ifndef ST7565_PAGE_ORDER - #define ST7565_PAGE_ORDER 0,1,2,3 +#define ST7565_PAGE_ORDER 0,1,2,3 #endif /*===========================================================================*/ @@ -58,12 +58,24 @@ typedef struct{ bool_t buffer2; + uint8_t data_pos; + uint8_t data[16]; uint8_t ram[GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH / 8]; }PrivData; // Some common routines and macros #define PRIV(g) ((PrivData*)g->priv) #define RAM(g) (PRIV(g)->ram) + +static GFXINLINE void write_cmd(GDisplay* g, uint8_t cmd) { + PRIV(g)->data[PRIV(g)->data_pos++] = cmd; +} + +static GFXINLINE void flush_cmd(GDisplay* g) { + write_data(g, PRIV(g)->data, PRIV(g)->data_pos); + PRIV(g)->data_pos = 0; +} + #define write_cmd2(g, cmd1, cmd2) { write_cmd(g, cmd1); write_cmd(g, cmd2); } #define write_cmd3(g, cmd1, cmd2, cmd3) { write_cmd(g, cmd1); write_cmd(g, cmd2); write_cmd(g, cmd3); } @@ -86,207 +98,224 @@ typedef struct{ */ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { - // The private area is the display surface. - g->priv = gfxAlloc(sizeof(PrivData)); - PRIV(g)->buffer2 = false; + // The private area is the display surface. + g->priv = gfxAlloc(sizeof(PrivData)); + PRIV(g)->buffer2 = false; + PRIV(g)->data_pos = 0; - // Initialise the board interface - init_board(g); + // Initialise the board interface + init_board(g); - // Hardware reset - setpin_reset(g, TRUE); - gfxSleepMilliseconds(20); - setpin_reset(g, FALSE); - gfxSleepMilliseconds(20); + // Hardware reset + setpin_reset(g, TRUE); + gfxSleepMilliseconds(20); + setpin_reset(g, FALSE); + gfxSleepMilliseconds(20); - acquire_bus(g); + acquire_bus(g); + enter_cmd_mode(g); write_cmd(g, ST7565_DISPLAY_OFF); - write_cmd(g, ST7565_LCD_BIAS); + write_cmd(g, ST7565_LCD_BIAS); write_cmd(g, ST7565_ADC); write_cmd(g, ST7565_COM_SCAN); - + write_cmd(g, ST7565_START_LINE | 0); - write_cmd(g, ST7565_RESISTOR_RATIO | 0x6); + write_cmd(g, ST7565_RESISTOR_RATIO | 0x6); - // turn on voltage converter (VC=1, VR=0, VF=0) - write_cmd(g, ST7565_POWER_CONTROL | 0x04); - delay_ms(50); + // turn on voltage converter (VC=1, VR=0, VF=0) + write_cmd(g, ST7565_POWER_CONTROL | 0x04); + flush_cmd(g); + delay_ms(50); - // turn on voltage regulator (VC=1, VR=1, VF=0) - write_cmd(g, ST7565_POWER_CONTROL | 0x06); - delay_ms(50); + // turn on voltage regulator (VC=1, VR=1, VF=0) + write_cmd(g, ST7565_POWER_CONTROL | 0x06); + flush_cmd(g); + delay_ms(50); - // turn on voltage follower (VC=1, VR=1, VF=1) - write_cmd(g, ST7565_POWER_CONTROL | 0x07); - delay_ms(50); + // turn on voltage follower (VC=1, VR=1, VF=1) + write_cmd(g, ST7565_POWER_CONTROL | 0x07); + flush_cmd(g); + delay_ms(50); - write_cmd(g, 0xE2); + write_cmd(g, 0xE2); write_cmd(g, ST7565_COM_SCAN); - write_cmd2(g, ST7565_CONTRAST, GDISP_INITIAL_CONTRAST*64/101); - //write_cmd2(g, ST7565_CONTRAST, 0); - write_cmd(g, ST7565_DISPLAY_ON); - write_cmd(g, ST7565_ALLON_NORMAL); - write_cmd(g, ST7565_INVERT_DISPLAY); + write_cmd2(g, ST7565_CONTRAST, GDISP_INITIAL_CONTRAST*64/101); + //write_cmd2(g, ST7565_CONTRAST, 0); + write_cmd(g, ST7565_DISPLAY_ON); + write_cmd(g, ST7565_ALLON_NORMAL); + write_cmd(g, ST7565_INVERT_DISPLAY); - write_cmd(g, ST7565_RMW); + write_cmd(g, ST7565_RMW); + flush_cmd(g); // Finish Init post_init_board(g); - // Release the bus - release_bus(g); + // Release the bus + release_bus(g); - /* Initialise the GDISP structure */ - g->g.Width = GDISP_SCREEN_WIDTH; - g->g.Height = GDISP_SCREEN_HEIGHT; - g->g.Orientation = GDISP_ROTATE_0; - g->g.Powermode = powerOn; - g->g.Backlight = GDISP_INITIAL_BACKLIGHT; - g->g.Contrast = GDISP_INITIAL_CONTRAST; - return TRUE; + /* Initialise the GDISP structure */ + g->g.Width = GDISP_SCREEN_WIDTH; + g->g.Height = GDISP_SCREEN_HEIGHT; + g->g.Orientation = GDISP_ROTATE_0; + g->g.Powermode = powerOn; + g->g.Backlight = GDISP_INITIAL_BACKLIGHT; + g->g.Contrast = GDISP_INITIAL_CONTRAST; + return TRUE; } #if GDISP_HARDWARE_FLUSH - LLDSPEC void gdisp_lld_flush(GDisplay *g) { - unsigned p; +LLDSPEC void gdisp_lld_flush(GDisplay *g) { + unsigned p; - // Don't flush if we don't need it. - if (!(g->flags & GDISP_FLG_NEEDFLUSH)) - return; + // Don't flush if we don't need it. + if (!(g->flags & GDISP_FLG_NEEDFLUSH)) + return; - acquire_bus(g); - unsigned dstOffset = (PRIV(g)->buffer2 ? 4 : 0); - for (p = 0; p < 4; p++) { - write_cmd(g, ST7565_PAGE | (p + dstOffset)); - write_cmd(g, ST7565_COLUMN_MSB | 0); - write_cmd(g, ST7565_COLUMN_LSB | 0); - write_cmd(g, ST7565_RMW); - write_data(g, RAM(g) + (p*GDISP_SCREEN_WIDTH), GDISP_SCREEN_WIDTH); - } - unsigned line = (PRIV(g)->buffer2 ? 32 : 0); - write_cmd(g, ST7565_START_LINE | line); - PRIV(g)->buffer2 = !PRIV(g)->buffer2; - release_bus(g); + acquire_bus(g); + enter_cmd_mode(g); + unsigned dstOffset = (PRIV(g)->buffer2 ? 4 : 0); + for (p = 0; p < 4; p++) { + write_cmd(g, ST7565_PAGE | (p + dstOffset)); + write_cmd(g, ST7565_COLUMN_MSB | 0); + write_cmd(g, ST7565_COLUMN_LSB | 0); + write_cmd(g, ST7565_RMW); + flush_cmd(g); + enter_data_mode(g); + write_data(g, RAM(g) + (p*GDISP_SCREEN_WIDTH), GDISP_SCREEN_WIDTH); + enter_cmd_mode(g); + } + unsigned line = (PRIV(g)->buffer2 ? 32 : 0); + write_cmd(g, ST7565_START_LINE | line); + flush_cmd(g); + PRIV(g)->buffer2 = !PRIV(g)->buffer2; + release_bus(g); - g->flags &= ~GDISP_FLG_NEEDFLUSH; - } + g->flags &= ~GDISP_FLG_NEEDFLUSH; +} #endif #if GDISP_HARDWARE_DRAWPIXEL - LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { - coord_t x, y; +LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { + coord_t x, y; - switch(g->g.Orientation) { - default: - case GDISP_ROTATE_0: - x = g->p.x; - y = g->p.y; - break; - case GDISP_ROTATE_90: - x = g->p.y; - y = GDISP_SCREEN_HEIGHT-1 - g->p.x; - break; - case GDISP_ROTATE_180: - x = GDISP_SCREEN_WIDTH-1 - g->p.x; - y = GDISP_SCREEN_HEIGHT-1 - g->p.y; - break; - case GDISP_ROTATE_270: - x = GDISP_SCREEN_HEIGHT-1 - g->p.y; - y = g->p.x; - break; - } - if (gdispColor2Native(g->p.color) != Black) - RAM(g)[xyaddr(x, y)] |= xybit(y); - else - RAM(g)[xyaddr(x, y)] &= ~xybit(y); - g->flags |= GDISP_FLG_NEEDFLUSH; - } + switch(g->g.Orientation) { + default: + case GDISP_ROTATE_0: + x = g->p.x; + y = g->p.y; + break; + case GDISP_ROTATE_90: + x = g->p.y; + y = GDISP_SCREEN_HEIGHT-1 - g->p.x; + break; + case GDISP_ROTATE_180: + x = GDISP_SCREEN_WIDTH-1 - g->p.x; + y = GDISP_SCREEN_HEIGHT-1 - g->p.y; + break; + case GDISP_ROTATE_270: + x = GDISP_SCREEN_HEIGHT-1 - g->p.y; + y = g->p.x; + break; + } + if (gdispColor2Native(g->p.color) != Black) + RAM(g)[xyaddr(x, y)] |= xybit(y); + else + RAM(g)[xyaddr(x, y)] &= ~xybit(y); + g->flags |= GDISP_FLG_NEEDFLUSH; +} #endif #if GDISP_HARDWARE_PIXELREAD - LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) { - coord_t x, y; +LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) { + coord_t x, y; - switch(g->g.Orientation) { - default: - case GDISP_ROTATE_0: - x = g->p.x; - y = g->p.y; - break; - case GDISP_ROTATE_90: - x = g->p.y; - y = GDISP_SCREEN_HEIGHT-1 - g->p.x; - break; - case GDISP_ROTATE_180: - x = GDISP_SCREEN_WIDTH-1 - g->p.x; - y = GDISP_SCREEN_HEIGHT-1 - g->p.y; - break; - case GDISP_ROTATE_270: - x = GDISP_SCREEN_HEIGHT-1 - g->p.y; - y = g->p.x; - break; - } - return (RAM(g)[xyaddr(x, y)] & xybit(y)) ? White : Black; - } + switch(g->g.Orientation) { + default: + case GDISP_ROTATE_0: + x = g->p.x; + y = g->p.y; + break; + case GDISP_ROTATE_90: + x = g->p.y; + y = GDISP_SCREEN_HEIGHT-1 - g->p.x; + break; + case GDISP_ROTATE_180: + x = GDISP_SCREEN_WIDTH-1 - g->p.x; + y = GDISP_SCREEN_HEIGHT-1 - g->p.y; + break; + case GDISP_ROTATE_270: + x = GDISP_SCREEN_HEIGHT-1 - g->p.y; + y = g->p.x; + break; + } + return (RAM(g)[xyaddr(x, y)] & xybit(y)) ? White : Black; +} #endif #if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL - LLDSPEC void gdisp_lld_control(GDisplay *g) { - switch(g->p.x) { - case GDISP_CONTROL_POWER: - if (g->g.Powermode == (powermode_t)g->p.ptr) - return; - switch((powermode_t)g->p.ptr) { - case powerOff: - case powerSleep: - case powerDeepSleep: - acquire_bus(g); - write_cmd(g, ST7565_DISPLAY_OFF); - release_bus(g); - break; - case powerOn: - acquire_bus(g); - write_cmd(g, ST7565_DISPLAY_ON); - release_bus(g); - break; - default: - return; - } - g->g.Powermode = (powermode_t)g->p.ptr; - return; +LLDSPEC void gdisp_lld_control(GDisplay *g) { + switch(g->p.x) { + case GDISP_CONTROL_POWER: + if (g->g.Powermode == (powermode_t)g->p.ptr) + return; + switch((powermode_t)g->p.ptr) { + case powerOff: + case powerSleep: + case powerDeepSleep: + acquire_bus(g); + enter_cmd_mode(g); + write_cmd(g, ST7565_DISPLAY_OFF); + flush_cmd(g); + release_bus(g); + break; + case powerOn: + acquire_bus(g); + enter_cmd_mode(g); + write_cmd(g, ST7565_DISPLAY_ON); + flush_cmd(g); + release_bus(g); + break; + default: + return; + } + g->g.Powermode = (powermode_t)g->p.ptr; + return; - case GDISP_CONTROL_ORIENTATION: - if (g->g.Orientation == (orientation_t)g->p.ptr) - return; - switch((orientation_t)g->p.ptr) { - /* Rotation is handled by the drawing routines */ - case GDISP_ROTATE_0: - case GDISP_ROTATE_180: - g->g.Height = GDISP_SCREEN_HEIGHT; - g->g.Width = GDISP_SCREEN_WIDTH; - break; - case GDISP_ROTATE_90: - case GDISP_ROTATE_270: - g->g.Height = GDISP_SCREEN_WIDTH; - g->g.Width = GDISP_SCREEN_HEIGHT; - break; - default: - return; - } - g->g.Orientation = (orientation_t)g->p.ptr; - return; + case GDISP_CONTROL_ORIENTATION: + if (g->g.Orientation == (orientation_t)g->p.ptr) + return; + switch((orientation_t)g->p.ptr) { + /* Rotation is handled by the drawing routines */ + case GDISP_ROTATE_0: + case GDISP_ROTATE_180: + g->g.Height = GDISP_SCREEN_HEIGHT; + g->g.Width = GDISP_SCREEN_WIDTH; + break; + case GDISP_ROTATE_90: + case GDISP_ROTATE_270: + g->g.Height = GDISP_SCREEN_WIDTH; + g->g.Width = GDISP_SCREEN_HEIGHT; + break; + default: + return; + } + g->g.Orientation = (orientation_t)g->p.ptr; + return; - case GDISP_CONTROL_CONTRAST: - if ((unsigned)g->p.ptr > 100) - g->p.ptr = (void *)100; - acquire_bus(g); - write_cmd2(g, ST7565_CONTRAST, ((((unsigned)g->p.ptr)<<6)/101) & 0x3F); - release_bus(g); - g->g.Contrast = (unsigned)g->p.ptr; - return; - } - } + case GDISP_CONTROL_CONTRAST: + if ((unsigned)g->p.ptr > 100) + g->p.ptr = (void *)100; + acquire_bus(g); + enter_cmd_mode(g); + write_cmd2(g, ST7565_CONTRAST, ((((unsigned)g->p.ptr)<<6)/101) & 0x3F); + flush_cmd(g); + release_bus(g); + g->g.Contrast = (unsigned)g->p.ptr; + return; + } +} #endif // GDISP_NEED_CONTROL #endif // GFX_USE_GDISP From a8f5897b976ee9f16b1798db38fb0ee4b8981c9e Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sat, 1 Apr 2017 16:36:34 +0300 Subject: [PATCH 07/34] Add support for blitting to the Infinity LCD --- .../gdisp/st7565ergodox/gdisp_lld_ST7565.c | 26 +++++++++++++++++++ .../gdisp/st7565ergodox/gdisp_lld_config.h | 11 ++++---- keyboards/ergodox/infinity/gfxconf.h | 2 +- 3 files changed, 33 insertions(+), 6 deletions(-) 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 4547f14193..2c8a168e76 100644 --- a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c +++ b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c @@ -254,6 +254,32 @@ LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) { } #endif +LLDSPEC void gdisp_lld_blit_area(GDisplay *g) { + uint8_t* buffer = (uint8_t*)g->p.ptr; + int linelength = g->p.cx; + for (int i = 0; i < g->p.cy; i++) { + unsigned dstx = g->p.x; + unsigned dsty = g->p.y + i; + unsigned srcx = g->p.x1; + unsigned srcy = g->p.y1 + i; + unsigned srcbit = srcy * g->p.x2 + srcx; + for(int j=0; j < linelength; j++) { + uint8_t src = buffer[srcbit / 8]; + uint8_t bit = 7-(srcbit % 8); + uint8_t bitset = (src >> bit) & 1; + uint8_t* dst = &(RAM(g)[xyaddr(dstx, dsty)]); + if (bitset) { + *dst |= xybit(dsty); + } + else { + *dst &= ~xybit(dsty); + } + dstx++; + srcbit++; + } + } +} + #if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL LLDSPEC void gdisp_lld_control(GDisplay *g) { switch(g->p.x) { 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 48587b9e14..2b66a877c8 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 @@ /* Driver hardware support. */ /*===========================================================================*/ -#define GDISP_HARDWARE_FLUSH TRUE // This controller requires flushing -#define GDISP_HARDWARE_DRAWPIXEL TRUE -#define GDISP_HARDWARE_PIXELREAD TRUE -#define GDISP_HARDWARE_CONTROL TRUE +#define GDISP_HARDWARE_FLUSH TRUE // This controller requires flushing +#define GDISP_HARDWARE_DRAWPIXEL TRUE +#define GDISP_HARDWARE_PIXELREAD TRUE +#define GDISP_HARDWARE_CONTROL TRUE +#define GDISP_HARDWARE_BITFILLS TRUE -#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_MONO +#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_MONO #endif /* GFX_USE_GDISP */ diff --git a/keyboards/ergodox/infinity/gfxconf.h b/keyboards/ergodox/infinity/gfxconf.h index 8caa577b73..45b9f58580 100644 --- a/keyboards/ergodox/infinity/gfxconf.h +++ b/keyboards/ergodox/infinity/gfxconf.h @@ -143,7 +143,7 @@ #define GDISP_HARDWARE_DRAWPIXEL TRUE #define GDISP_HARDWARE_CLEARS FALSE #define GDISP_HARDWARE_FILLS FALSE - #define GDISP_HARDWARE_BITFILLS FALSE + //#define GDISP_HARDWARE_BITFILLS FALSE #define GDISP_HARDWARE_SCROLL FALSE #define GDISP_HARDWARE_PIXELREAD TRUE #define GDISP_HARDWARE_CONTROL TRUE From e6f7a8a47a82258725683980b83e215c8323aef2 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sat, 1 Apr 2017 16:37:31 +0300 Subject: [PATCH 08/34] Display QMK logo at startup of Infinity Ergodox --- keyboards/ergodox/infinity/lcd_logo.png | Bin 0 -> 490 bytes keyboards/ergodox/infinity/visualizer.c | 89 +++++++++++++++++------- 2 files changed, 65 insertions(+), 24 deletions(-) create mode 100644 keyboards/ergodox/infinity/lcd_logo.png diff --git a/keyboards/ergodox/infinity/lcd_logo.png b/keyboards/ergodox/infinity/lcd_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..6cf26fc6783a5b586eedbc6ff0940e124795e9bf GIT binary patch literal 490 zcmVwbn1gKp4ks>ggHBQn#f%?f(k66Mz*M@DZc5GX^?yF7n3m0^nAJyA1J9 zXB@WzkY=`ql?*WpcLLz{<2wyX>!$tCwhj4L*#2&>7W_UPg`>t&iX0$icIkD+k+w)JLfu z=^qB|3q53BAu5w2h~wX`dshvxcTNj{TdG$bz$nHq<-!#pSrd0>faF. #include "visualizer.h" #include "led_test.h" -static const char* welcome_text[] = {"TMK", "Infinity Ergodox"}; +// To generate an image array like this +// Ensure the image is 128 x 32 or smaller +// Convert the bitmap to a C array using a program like http://www.riuson.com/lcd-image-converter/ +// Ensure the the conversion process produces a monochrome format array - 1 bit/pixel, left to right, top to bottom +// Update array in the source code with the C array produced by the conversion program -// Just an example how to write custom keyframe functions, we could have moved -// all this into the init function -bool display_welcome(keyframe_animation_t* animation, visualizer_state_t* state) { +// The image below is generated from lcd_logo.png +static const uint8_t image_data_lcd_logo[512] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0xfe, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x38, 0x38, 0x06, 0x29, 0x41, 0x24, 0x52, 0x24, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x38, 0x38, 0x09, 0x55, 0x42, 0xaa, 0xaa, 0xaa, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x38, 0x38, 0x09, 0x55, 0x82, 0x28, 0xaa, 0xae, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x38, 0x38, 0x09, 0x55, 0x43, 0x28, 0xaa, 0xaa, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x38, 0x38, 0x0a, 0x55, 0x42, 0x28, 0xaa, 0xaa, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x38, 0x38, 0x05, 0x45, 0x42, 0x28, 0x89, 0x4a, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x38, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1c, 0x38, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0e, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xff, 0x80, 0x04, 0x45, 0x14, 0xa4, 0x92, 0x83, 0x52, 0x22, 0x22, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x00, 0x0a, 0xaa, 0xaa, 0xaa, 0xba, 0x84, 0x55, 0x55, 0x57, 0x45, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x00, 0x08, 0xaa, 0xaa, 0xaa, 0x92, 0xb2, 0x55, 0x55, 0x42, 0x65, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x00, 0x08, 0xaa, 0xaa, 0xaa, 0x92, 0x81, 0x56, 0x65, 0x42, 0x45, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x00, 0x0a, 0xaa, 0xaa, 0xaa, 0x92, 0x81, 0x54, 0x45, 0x42, 0x45, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x00, 0x04, 0x48, 0xa2, 0x4a, 0x89, 0x06, 0x24, 0x42, 0x41, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0x80); +static const uint32_t initial_color = LCD_COLOR(0, 0, 0xFF); + +bool display_logo(keyframe_animation_t* animation, visualizer_state_t* state) { + (void)state; (void)animation; + (void)state; // Read the uGFX documentation for information how to use the displays // http://wiki.ugfx.org/index.php/Main_Page gdispClear(White); + // You can use static variables for things that can't be found in the animation - // or state structs - gdispDrawString(0, 3, welcome_text[0], state->font_dejavusansbold12, Black); - gdispDrawString(0, 15, welcome_text[1], state->font_dejavusansbold12, Black); + // or state structs, here we use the image + + //gdispGBlitArea is a tricky function to use since it supports blitting part of the image + // if you have full screen image, then just use 128 and 32 for both source and target dimensions + gdispGBlitArea(GDISP, 0, 0, 128, 32, 0, 0, 128, (pixel_t*)image_data_lcd_logo); + // Always remember to flush the display gdispFlush(); - // you could set the backlight color as well, but we won't do it here, since - // it's part of the following animation - // lcd_backlight_color(hue, saturation, intensity); - // We don't need constant updates, just drawing the screen once is enough return false; } @@ -56,13 +99,12 @@ bool display_welcome(keyframe_animation_t* animation, visualizer_state_t* state) // Don't worry, if the startup animation is long, you can use the keyboard like normal // during that time static keyframe_animation_t startup_animation = { - .num_frames = 4, + .num_frames = 3, .loop = false, - .frame_lengths = {0, gfxMillisecondsToTicks(1000), gfxMillisecondsToTicks(5000), 0}, + .frame_lengths = {0, gfxMillisecondsToTicks(10000), 0}, .frame_functions = { - display_welcome, + display_logo, keyframe_animate_backlight_color, - keyframe_no_operation, enable_visualization }, }; @@ -78,6 +120,7 @@ static keyframe_animation_t color_animation = { .frame_functions = {keyframe_no_operation, keyframe_animate_backlight_color}, }; + // The LCD animation alternates between the layer name display and a // bitmap that displays all active layers static keyframe_animation_t lcd_animation = { @@ -99,14 +142,13 @@ static keyframe_animation_t suspend_animation = { }; static keyframe_animation_t resume_animation = { - .num_frames = 5, + .num_frames = 4, .loop = false, - .frame_lengths = {0, 0, gfxMillisecondsToTicks(1000), gfxMillisecondsToTicks(5000), 0}, + .frame_lengths = {0, 0, gfxMillisecondsToTicks(10000), 0}, .frame_functions = { keyframe_enable_lcd_and_backlight, - display_welcome, + display_logo, keyframe_animate_backlight_color, - keyframe_no_operation, enable_visualization, }, }; @@ -115,10 +157,9 @@ void initialize_user_visualizer(visualizer_state_t* state) { // The brightness will be dynamically adjustable in the future // But for now, change it here. lcd_backlight_brightness(0x50); - state->current_lcd_color = LCD_COLOR(0x00, 0x00, 0xFF); - state->target_lcd_color = LCD_COLOR(0x10, 0xFF, 0xFF); + state->current_lcd_color = initial_color; + state->target_lcd_color = logo_background_color; start_keyframe_animation(&startup_animation); - start_keyframe_animation(&led_test_animation); } void update_user_visualizer_state(visualizer_state_t* state) { @@ -161,8 +202,8 @@ void user_visualizer_suspend(visualizer_state_t* state) { } void user_visualizer_resume(visualizer_state_t* state) { - state->current_lcd_color = LCD_COLOR(0x00, 0x00, 0x00); - state->target_lcd_color = LCD_COLOR(0x10, 0xFF, 0xFF); + state->current_lcd_color = initial_color; + state->target_lcd_color = logo_background_color; start_keyframe_animation(&resume_animation); start_keyframe_animation(&led_test_animation); } From bc97413bf70b1906b387dea35bb22575ec57eff8 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sat, 1 Apr 2017 16:38:12 +0300 Subject: [PATCH 09/34] Disable LEDs on Infinity Ergodox --- keyboards/ergodox/infinity/rules.mk | 2 +- keyboards/ergodox/infinity/visualizer.c | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/keyboards/ergodox/infinity/rules.mk b/keyboards/ergodox/infinity/rules.mk index d51574acae..aaadfe34b5 100644 --- a/keyboards/ergodox/infinity/rules.mk +++ b/keyboards/ergodox/infinity/rules.mk @@ -61,7 +61,7 @@ CUSTOM_MATRIX ?= yes # Custom matrix file SERIAL_LINK_ENABLE = yes VISUALIZER_ENABLE ?= yes LCD_ENABLE ?= yes -LED_ENABLE ?= yes +LED_ENABLE ?= no LCD_BACKLIGHT_ENABLE ?= yes MIDI_ENABLE = no RGBLIGHT_ENABLE = no diff --git a/keyboards/ergodox/infinity/visualizer.c b/keyboards/ergodox/infinity/visualizer.c index 0ce1d4ae4e..c8fc3d78ef 100644 --- a/keyboards/ergodox/infinity/visualizer.c +++ b/keyboards/ergodox/infinity/visualizer.c @@ -27,7 +27,6 @@ along with this program. If not, see . #endif #include "visualizer.h" -#include "led_test.h" // To generate an image array like this // Ensure the image is 128 x 32 or smaller @@ -205,5 +204,4 @@ void user_visualizer_resume(visualizer_state_t* state) { state->current_lcd_color = initial_color; state->target_lcd_color = logo_background_color; start_keyframe_animation(&resume_animation); - start_keyframe_animation(&led_test_animation); } From f113f95440f8cd7377930868656caf515dbd609c Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sat, 1 Apr 2017 17:43:38 +0300 Subject: [PATCH 10/34] Move CIE1931 and breathing tables to its own file --- build_keyboard.mk | 23 ++++++ .../gdisp/IS31FL3731C/gdisp_IS31FL3731C.c | 37 ++-------- quantum/led_tables.c | 71 +++++++++++++++++++ quantum/led_tables.h | 30 ++++++++ quantum/rgblight.c | 58 ++------------- quantum/visualizer/visualizer.mk | 4 +- 6 files changed, 136 insertions(+), 87 deletions(-) create mode 100644 quantum/led_tables.c create mode 100644 quantum/led_tables.h diff --git a/build_keyboard.mk b/build_keyboard.mk index ad92892e27..79d2b6b0f0 100644 --- a/build_keyboard.mk +++ b/build_keyboard.mk @@ -196,6 +196,8 @@ ifeq ($(strip $(RGBLIGHT_ENABLE)), yes) OPT_DEFS += -DRGBLIGHT_ENABLE SRC += $(QUANTUM_DIR)/light_ws2812.c SRC += $(QUANTUM_DIR)/rgblight.c + CIE1931_CURVE = yes + LED_BREATHING_TABLE = yes endif ifeq ($(strip $(TAP_DANCE_ENABLE)), yes) @@ -223,6 +225,27 @@ ifneq ($(strip $(MAX_VARIABLE_TRACE_SIZE)),) endif endif +ifeq ($(strip $(LCD_ENABLE)), yes) +CIE1931_CURVE = yes +endif + +ifeq ($(strip $(LED_ENABLE)), yes) +CIE1931_CURVE = yes +endif + +ifeq ($(strip $(CIE1931_CURVE)), yes) + OPT_DEFS += -DUSE_CIE1931_CURVE + LED_TABLES = yes +endif +ifeq ($(strip $(LED_BREATHING_TABLE)), yes) + OPT_DEFS += -DUSE_LED_BREATHING_TABLE + LED_TABLES = yes +endif + +ifeq ($(strip $(LED_TABLES)), yes) + SRC += $(QUANTUM_DIR)/led_tables.c +endif + # Optimize size but this may cause error "relocation truncated to fit" #EXTRALDFLAGS = -Wl,--relax diff --git a/keyboards/ergodox/infinity/drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c b/keyboards/ergodox/infinity/drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c index 1d21f0c498..ea09c4bb0c 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 . #include "board_IS31FL3731C.h" + +// Can't include led_tables from here +extern const uint8_t CIE1931_CURVE[]; + /*===========================================================================*/ /* Driver local definitions. */ /*===========================================================================*/ @@ -100,37 +104,6 @@ along with this program. If not, see . #define IS31 -//Generated by http://jared.geek.nz/2013/feb/linear-led-pwm -const unsigned char cie[256] = { - 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, - 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, - 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, - 7, 8, 8, 8, 8, 9, 9, 9, 10, 10, - 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, - 13, 14, 14, 15, 15, 15, 16, 16, 17, 17, - 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, - 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, - 28, 28, 29, 29, 30, 31, 31, 32, 32, 33, - 34, 34, 35, 36, 37, 37, 38, 39, 39, 40, - 41, 42, 43, 43, 44, 45, 46, 47, 47, 48, - 49, 50, 51, 52, 53, 54, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 70, 71, 72, 73, 74, 75, 76, 77, 79, - 80, 81, 82, 83, 85, 86, 87, 88, 90, 91, - 92, 94, 95, 96, 98, 99, 100, 102, 103, 105, - 106, 108, 109, 110, 112, 113, 115, 116, 118, 120, - 121, 123, 124, 126, 128, 129, 131, 132, 134, 136, - 138, 139, 141, 143, 145, 146, 148, 150, 152, 154, - 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, - 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, - 196, 198, 200, 202, 204, 207, 209, 211, 214, 216, - 218, 220, 223, 225, 228, 230, 232, 235, 237, 240, - 242, 245, 247, 250, 252, 255, -}; - - /*===========================================================================*/ /* Driver local functions. */ /*===========================================================================*/ @@ -231,7 +204,7 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { uint8_t* src = PRIV(g)->frame_buffer; for (int y=0;ywrite_buffer[get_led_address(g, x, y)]=cie[*src]; + PRIV(g)->write_buffer[get_led_address(g, x, y)]=CIE1931_CURVE[*src]; ++src; } } diff --git a/quantum/led_tables.c b/quantum/led_tables.c new file mode 100644 index 0000000000..b99f262097 --- /dev/null +++ b/quantum/led_tables.c @@ -0,0 +1,71 @@ +/* +Copyright 2017 Fred Sundvik + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "led_tables.h" + + +#ifdef USE_CIE1931_CURVE +// Lightness curve using the CIE 1931 lightness formula +//Generated by the python script provided in http://jared.geek.nz/2013/feb/linear-led-pwm +const uint8_t CIE1931_CURVE[] PROGMEM = { + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, + 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, + 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, + 7, 8, 8, 8, 8, 9, 9, 9, 10, 10, + 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, + 13, 14, 14, 15, 15, 15, 16, 16, 17, 17, + 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, + 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, + 28, 28, 29, 29, 30, 31, 31, 32, 32, 33, + 34, 34, 35, 36, 37, 37, 38, 39, 39, 40, + 41, 42, 43, 43, 44, 45, 46, 47, 47, 48, + 49, 50, 51, 52, 53, 54, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 70, 71, 72, 73, 74, 75, 76, 77, 79, + 80, 81, 82, 83, 85, 86, 87, 88, 90, 91, + 92, 94, 95, 96, 98, 99, 100, 102, 103, 105, + 106, 108, 109, 110, 112, 113, 115, 116, 118, 120, + 121, 123, 124, 126, 128, 129, 131, 132, 134, 136, + 138, 139, 141, 143, 145, 146, 148, 150, 152, 154, + 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, + 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, + 196, 198, 200, 202, 204, 207, 209, 211, 214, 216, + 218, 220, 223, 225, 228, 230, 232, 235, 237, 240, + 242, 245, 247, 250, 252, 255, + }; +#endif + +#ifdef USE_LED_BREATHING_TABLE +const uint8_t LED_BREATHING_TABLE[] PROGMEM = { + 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 9, + 10, 11, 12, 14, 15, 17, 18, 20, 21, 23, 25, 27, 29, 31, 33, 35, + 37, 40, 42, 44, 47, 49, 52, 54, 57, 59, 62, 65, 67, 70, 73, 76, + 79, 82, 85, 88, 90, 93, 97, 100, 103, 106, 109, 112, 115, 118, 121, 124, + 127, 131, 134, 137, 140, 143, 146, 149, 152, 155, 158, 162, 165, 167, 170, 173, + 176, 179, 182, 185, 188, 190, 193, 196, 198, 201, 203, 206, 208, 211, 213, 215, + 218, 220, 222, 224, 226, 228, 230, 232, 234, 235, 237, 238, 240, 241, 243, 244, + 245, 246, 248, 249, 250, 250, 251, 252, 253, 253, 254, 254, 254, 255, 255, 255, + 255, 255, 255, 255, 254, 254, 254, 253, 253, 252, 251, 250, 250, 249, 248, 246, + 245, 244, 243, 241, 240, 238, 237, 235, 234, 232, 230, 228, 226, 224, 222, 220, + 218, 215, 213, 211, 208, 206, 203, 201, 198, 196, 193, 190, 188, 185, 182, 179, + 176, 173, 170, 167, 165, 162, 158, 155, 152, 149, 146, 143, 140, 137, 134, 131, + 128, 124, 121, 118, 115, 112, 109, 106, 103, 100, 97, 93, 90, 88, 85, 82, + 79, 76, 73, 70, 67, 65, 62, 59, 57, 54, 52, 49, 47, 44, 42, 40, + 37, 35, 33, 31, 29, 27, 25, 23, 21, 20, 18, 17, 15, 14, 12, 11, + 10, 9, 7, 6, 5, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0 +}; +#endif diff --git a/quantum/led_tables.h b/quantum/led_tables.h new file mode 100644 index 0000000000..af49bf3323 --- /dev/null +++ b/quantum/led_tables.h @@ -0,0 +1,30 @@ +/* +Copyright 2017 Fred Sundvik + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#ifndef LED_TABLES_H +#define LED_TABLES_H + +#include "progmem.h" +#include + +#ifdef USE_CIE1931_CURVE +extern const uint8_t CIE1931_CURVE[] PROGMEM; +#endif + +#ifdef USE_LED_BREATHING_TABLE +extern const uint8_t LED_BREATHING_TABLE[] PROGMEM; +#endif + +#endif diff --git a/quantum/rgblight.c b/quantum/rgblight.c index eff70aae1d..4eec2a7762 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -20,56 +20,8 @@ #include "timer.h" #include "rgblight.h" #include "debug.h" +#include "led_tables.h" -// Lightness curve using the CIE 1931 lightness formula -//Generated by the python script provided in http://jared.geek.nz/2013/feb/linear-led-pwm -const uint8_t DIM_CURVE[] PROGMEM = { - 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, - 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, - 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, - 7, 8, 8, 8, 8, 9, 9, 9, 10, 10, - 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, - 13, 14, 14, 15, 15, 15, 16, 16, 17, 17, - 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, - 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, - 28, 28, 29, 29, 30, 31, 31, 32, 32, 33, - 34, 34, 35, 36, 37, 37, 38, 39, 39, 40, - 41, 42, 43, 43, 44, 45, 46, 47, 47, 48, - 49, 50, 51, 52, 53, 54, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 70, 71, 72, 73, 74, 75, 76, 77, 79, - 80, 81, 82, 83, 85, 86, 87, 88, 90, 91, - 92, 94, 95, 96, 98, 99, 100, 102, 103, 105, - 106, 108, 109, 110, 112, 113, 115, 116, 118, 120, - 121, 123, 124, 126, 128, 129, 131, 132, 134, 136, - 138, 139, 141, 143, 145, 146, 148, 150, 152, 154, - 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, - 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, - 196, 198, 200, 202, 204, 207, 209, 211, 214, 216, - 218, 220, 223, 225, 228, 230, 232, 235, 237, 240, - 242, 245, 247, 250, 252, 255, - }; - -const uint8_t RGBLED_BREATHING_TABLE[] PROGMEM = { - 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 9, - 10, 11, 12, 14, 15, 17, 18, 20, 21, 23, 25, 27, 29, 31, 33, 35, - 37, 40, 42, 44, 47, 49, 52, 54, 57, 59, 62, 65, 67, 70, 73, 76, - 79, 82, 85, 88, 90, 93, 97, 100, 103, 106, 109, 112, 115, 118, 121, 124, - 127, 131, 134, 137, 140, 143, 146, 149, 152, 155, 158, 162, 165, 167, 170, 173, - 176, 179, 182, 185, 188, 190, 193, 196, 198, 201, 203, 206, 208, 211, 213, 215, - 218, 220, 222, 224, 226, 228, 230, 232, 234, 235, 237, 238, 240, 241, 243, 244, - 245, 246, 248, 249, 250, 250, 251, 252, 253, 253, 254, 254, 254, 255, 255, 255, - 255, 255, 255, 255, 254, 254, 254, 253, 253, 252, 251, 250, 250, 249, 248, 246, - 245, 244, 243, 241, 240, 238, 237, 235, 234, 232, 230, 228, 226, 224, 222, 220, - 218, 215, 213, 211, 208, 206, 203, 201, 198, 196, 193, 190, 188, 185, 182, 179, - 176, 173, 170, 167, 165, 162, 158, 155, 152, 149, 146, 143, 140, 137, 134, 131, - 128, 124, 121, 118, 115, 112, 109, 106, 103, 100, 97, 93, 90, 88, 85, 82, - 79, 76, 73, 70, 67, 65, 62, 59, 57, 54, 52, 49, 47, 44, 42, 40, - 37, 35, 33, 31, 29, 27, 25, 23, 21, 20, 18, 17, 15, 14, 12, 11, - 10, 9, 7, 6, 5, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0 -}; __attribute__ ((weak)) const 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) { break; } } - r = pgm_read_byte(&DIM_CURVE[r]); - g = pgm_read_byte(&DIM_CURVE[g]); - b = pgm_read_byte(&DIM_CURVE[b]); + r = pgm_read_byte(&CIE1931_CURVE[r]); + g = pgm_read_byte(&CIE1931_CURVE[g]); + b = pgm_read_byte(&CIE1931_CURVE[b]); setrgb(r, g, b, led1); } @@ -509,7 +461,7 @@ void rgblight_effect_breathing(uint8_t interval) { } last_timer = timer_read(); - rgblight_sethsv_noeeprom(rgblight_config.hue, rgblight_config.sat, pgm_read_byte(&RGBLED_BREATHING_TABLE[pos])); + rgblight_sethsv_noeeprom(rgblight_config.hue, rgblight_config.sat, pgm_read_byte(&LED_BREATHING_TABLE[pos])); pos = (pos + 1) % 256; } void rgblight_effect_rainbow_mood(uint8_t interval) { diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk index 8f5fb89334..3861cb1f04 100644 --- a/quantum/visualizer/visualizer.mk +++ b/quantum/visualizer/visualizer.mk @@ -32,12 +32,12 @@ OPT_DEFS += -DLCD_ENABLE ULIBS += -lm endif -ifdef LCD_BACKLIGHT_ENABLE +ifeq ($(strip $(LCD_ENABLE)), yes) SRC += $(VISUALIZER_DIR)/lcd_backlight.c OPT_DEFS += -DLCD_BACKLIGHT_ENABLE endif -ifdef LED_ENABLE +ifeq ($(strip $(LED_ENABLE)), yes) SRC += $(VISUALIZER_DIR)/led_test.c OPT_DEFS += -DLED_ENABLE endif From 951b6f33a0dc479d29831aaa5c73fc526faf0471 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sat, 1 Apr 2017 21:28:27 +0300 Subject: [PATCH 11/34] CIE 1931 for the LCD backlight --- keyboards/ergodox/infinity/infinity.c | 29 ++++++++++++++++++++++--- keyboards/ergodox/infinity/visualizer.c | 6 ++--- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/keyboards/ergodox/infinity/infinity.c b/keyboards/ergodox/infinity/infinity.c index 02db67eaf2..ecc072abbe 100644 --- a/keyboards/ergodox/infinity/infinity.c +++ b/keyboards/ergodox/infinity/infinity.c @@ -70,10 +70,33 @@ void lcd_backlight_hal_init(void) { RGB_PORT->PCR[BLUE_PIN] = RGB_MODE; } +static uint16_t cie_lightness(uint16_t v) { + // The CIE 1931 formula for lightness + // Y = luminance (output) 0-1 + // L = lightness input 0 - 100 + + // Y = (L* / 902.3) if L* <= 8 + // Y = ((L* + 16) / 116)^3 if L* > 8 + + float l = 100.0f * (v / 65535.0f); + float y = 0.0f; + if (l <= 8.0f) { + y = l / 902.3; + } + else { + y = ((l + 16.0f) / 116.0f); + y = y * y * y; + if (y > 1.0f) { + y = 1.0f; + } + } + return y * 65535.0f; +} + void lcd_backlight_hal_color(uint16_t r, uint16_t g, uint16_t b) { - CHANNEL_RED.CnV = r; - CHANNEL_GREEN.CnV = g; - CHANNEL_BLUE.CnV = b; + CHANNEL_RED.CnV = cie_lightness(r); + CHANNEL_GREEN.CnV = cie_lightness(g); + CHANNEL_BLUE.CnV = cie_lightness(b); } __attribute__ ((weak)) diff --git a/keyboards/ergodox/infinity/visualizer.c b/keyboards/ergodox/infinity/visualizer.c index c8fc3d78ef..12336fdc57 100644 --- a/keyboards/ergodox/infinity/visualizer.c +++ b/keyboards/ergodox/infinity/visualizer.c @@ -70,8 +70,8 @@ static const uint8_t image_data_lcd_logo[512] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0x80); -static const uint32_t initial_color = LCD_COLOR(0, 0, 0xFF); +static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0xFF); +static const uint32_t initial_color = LCD_COLOR(0, 0, 0); bool display_logo(keyframe_animation_t* animation, visualizer_state_t* state) { (void)state; @@ -155,7 +155,7 @@ static keyframe_animation_t resume_animation = { void initialize_user_visualizer(visualizer_state_t* state) { // The brightness will be dynamically adjustable in the future // But for now, change it here. - lcd_backlight_brightness(0x50); + lcd_backlight_brightness(130); state->current_lcd_color = initial_color; state->target_lcd_color = logo_background_color; start_keyframe_animation(&startup_animation); From 9a4ce28683b667ab67d48d92196bab7e277d4800 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sat, 1 Apr 2017 22:52:58 +0300 Subject: [PATCH 12/34] Display layer bitmap and keyboard led states on the LCD --- keyboards/ergodox/infinity/visualizer.c | 86 ++++++++++++++++--------- quantum/visualizer/visualizer.c | 38 ++++++++++- quantum/visualizer/visualizer.h | 4 +- 3 files changed, 97 insertions(+), 31 deletions(-) diff --git a/keyboards/ergodox/infinity/visualizer.c b/keyboards/ergodox/infinity/visualizer.c index 12336fdc57..6af3a72ee1 100644 --- a/keyboards/ergodox/infinity/visualizer.c +++ b/keyboards/ergodox/infinity/visualizer.c @@ -73,6 +73,14 @@ static const uint8_t image_data_lcd_logo[512] = { static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0xFF); static const uint32_t initial_color = LCD_COLOR(0, 0, 0); +typedef enum { + LCD_STATE_INITIAL, + LCD_STATE_LAYER_BITMAP, + LCD_STATE_BITMAP_AND_LEDS, +} lcd_state_t; + +static lcd_state_t lcd_state = LCD_STATE_INITIAL; + bool display_logo(keyframe_animation_t* animation, visualizer_state_t* state) { (void)state; (void)animation; @@ -122,11 +130,18 @@ static keyframe_animation_t color_animation = { // The LCD animation alternates between the layer name display and a // bitmap that displays all active layers -static keyframe_animation_t lcd_animation = { +static keyframe_animation_t lcd_bitmap_animation = { + .num_frames = 1, + .loop = false, + .frame_lengths = {gfxMillisecondsToTicks(0)}, + .frame_functions = {keyframe_display_layer_bitmap}, +}; + +static keyframe_animation_t lcd_bitmap_leds_animation = { .num_frames = 2, .loop = true, .frame_lengths = {gfxMillisecondsToTicks(2000), gfxMillisecondsToTicks(2000)}, - .frame_functions = {keyframe_display_layer_text, keyframe_display_layer_bitmap}, + .frame_functions = {keyframe_display_layer_bitmap, keyframe_display_led_states}, }; static keyframe_animation_t suspend_animation = { @@ -158,38 +173,50 @@ void initialize_user_visualizer(visualizer_state_t* state) { lcd_backlight_brightness(130); state->current_lcd_color = initial_color; state->target_lcd_color = logo_background_color; + lcd_state = LCD_STATE_INITIAL; start_keyframe_animation(&startup_animation); } -void update_user_visualizer_state(visualizer_state_t* state) { - // Add more tests, change the colors and layer texts here - // Usually you want to check the high bits (higher layers first) - // because that's the order layers are processed for keypresses - // You can for check for example: - // state->status.layer - // state->status.default_layer - // state->status.leds (see led.h for available statuses) - if (state->status.layer & 0x8) { - state->target_lcd_color = LCD_COLOR(0xC0, 0xB0, 0xFF); - state->layer_text = "Numpad"; - } - else if (state->status.layer & 0x4) { - state->target_lcd_color = LCD_COLOR(0, 0xB0, 0xFF); - state->layer_text = "KBD functions"; - } - else if (state->status.layer & 0x2) { - state->target_lcd_color = LCD_COLOR(0x80, 0xB0, 0xFF); - state->layer_text = "Function keys"; - } - else { +void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t prev_status) { + // Check the status here to start and stop animations + // You might have to save some state, like the current animation here so that you can start the right + // This function is called every time the status changes + + // NOTE that this is called from the visualizer thread, so don't access anything else outside the status + // This is also important because the slave won't have access to the active layer for example outside the + // status. + + if (lcd_state == LCD_STATE_INITIAL) { state->target_lcd_color = LCD_COLOR(0x40, 0xB0, 0xFF); - state->layer_text = "Default"; + start_keyframe_animation(&color_animation); + } + + if (state->status.leds) { + if (lcd_state != LCD_STATE_BITMAP_AND_LEDS || + state->status.leds != prev_status.leds || + state->status.layer != prev_status.layer || + state->status.default_layer != prev_status.default_layer) { + + // NOTE: that it doesn't matter if the animation isn't playing, stop will do nothing in that case + stop_keyframe_animation(&lcd_bitmap_animation); + + lcd_state = LCD_STATE_BITMAP_AND_LEDS; + // For information: + // The logic in this function makes sure that this doesn't happen, but if you call start on an + // animation that is already playing it will be restarted. + start_keyframe_animation(&lcd_bitmap_leds_animation); + } + } else { + if (lcd_state != LCD_STATE_LAYER_BITMAP || + state->status.layer != prev_status.layer || + state->status.default_layer != prev_status.default_layer) { + + stop_keyframe_animation(&lcd_bitmap_leds_animation); + + lcd_state = LCD_STATE_LAYER_BITMAP; + start_keyframe_animation(&lcd_bitmap_animation); + } } - // You can also stop existing animations, and start your custom ones here - // remember that you should normally have only one animation for the LCD - // and one for the background. But you can also combine them if you want. - start_keyframe_animation(&lcd_animation); - start_keyframe_animation(&color_animation); } void user_visualizer_suspend(visualizer_state_t* state) { @@ -203,5 +230,6 @@ void user_visualizer_suspend(visualizer_state_t* state) { void user_visualizer_resume(visualizer_state_t* state) { state->current_lcd_color = initial_color; state->target_lcd_color = logo_background_color; + lcd_state = LCD_STATE_INITIAL; start_keyframe_animation(&resume_animation); } diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c index 5826d909e4..62ebebceed 100644 --- a/quantum/visualizer/visualizer.c +++ b/quantum/visualizer/visualizer.c @@ -56,6 +56,8 @@ SOFTWARE. // mods status #include "action_util.h" +#include "led.h" + static visualizer_keyboard_status_t current_status = { .layer = 0xFFFFFFFF, .default_layer = 0xFFFFFFFF, @@ -350,6 +352,39 @@ bool keyframe_display_mods_bitmap(keyframe_animation_t* animation, visualizer_st gdispFlush(); return false; } + +bool keyframe_display_led_states(keyframe_animation_t* animation, visualizer_state_t* state) +{ + char output[sizeof("NUM CAPS SCRL COMP KANA")]; + uint8_t pos = 0; + + if (state->status.leds & (1u << USB_LED_NUM_LOCK)) { + memcpy(output + pos, "NUM ", 4); + pos += 4; + } + if (state->status.leds & (1u << USB_LED_CAPS_LOCK)) { + memcpy(output + pos, "CAPS ", 5); + pos += 5; + } + if (state->status.leds & (1u << USB_LED_SCROLL_LOCK)) { + memcpy(output + pos, "SCRL ", 5); + pos += 5; + } + if (state->status.leds & (1u << USB_LED_COMPOSE)) { + memcpy(output + pos, "COMP ", 5); + pos += 5; + } + if (state->status.leds & (1u << USB_LED_KANA)) { + memcpy(output + pos, "KANA ", 5); + pos += 5; + } + output[pos] = 0; + gdispClear(White); + gdispDrawString(0, 10, output, state->font_dejavusansbold12, Black); + gdispFlush(); + return false; +} + #endif // LCD_ENABLE bool keyframe_disable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state) { @@ -433,8 +468,9 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) { user_visualizer_suspend(&state); } else { + visualizer_keyboard_status_t prev_status = state.status; state.status = current_status; - update_user_visualizer_state(&state); + update_user_visualizer_state(&state, prev_status); } state.prev_lcd_color = state.current_lcd_color; } diff --git a/quantum/visualizer/visualizer.h b/quantum/visualizer/visualizer.h index 315af50228..2c81cb9f71 100644 --- a/quantum/visualizer/visualizer.h +++ b/quantum/visualizer/visualizer.h @@ -136,6 +136,8 @@ bool keyframe_display_layer_text(keyframe_animation_t* animation, visualizer_sta bool keyframe_display_layer_bitmap(keyframe_animation_t* animation, visualizer_state_t* state); // Displays a bitmap (0/1) of all the currently active mods bool keyframe_display_mods_bitmap(keyframe_animation_t* animation, visualizer_state_t* state); +// Displays the keyboard led states (CAPS (Caps lock), NUM (Num lock), SCRL (Scroll lock), COMP (Compose), KANA) +bool keyframe_display_led_states(keyframe_animation_t* animation, visualizer_state_t* state); bool keyframe_disable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state); bool keyframe_enable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state); @@ -146,7 +148,7 @@ bool enable_visualization(keyframe_animation_t* animation, visualizer_state_t* s // These functions have to be implemented by the user void initialize_user_visualizer(visualizer_state_t* state); -void update_user_visualizer_state(visualizer_state_t* state); +void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t prev_status); void user_visualizer_suspend(visualizer_state_t* state); void user_visualizer_resume(visualizer_state_t* state); From 39385144e7dc3337e623cdc8147b4a441f22fd62 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sun, 2 Apr 2017 01:31:04 +0300 Subject: [PATCH 13/34] Emulate Ergodox EZ leds by LCD colors --- keyboards/ergodox/infinity/config.h | 2 + keyboards/ergodox/infinity/infinity.c | 22 ++- keyboards/ergodox/infinity/infinity.h | 71 ++++++---- keyboards/ergodox/infinity/visualizer.c | 175 ++++++++++++++++++++++-- quantum/visualizer/visualizer.c | 25 +++- quantum/visualizer/visualizer.h | 8 ++ 6 files changed, 258 insertions(+), 45 deletions(-) diff --git a/keyboards/ergodox/infinity/config.h b/keyboards/ergodox/infinity/config.h index 9e264083be..6cde193e13 100644 --- a/keyboards/ergodox/infinity/config.h +++ b/keyboards/ergodox/infinity/config.h @@ -54,6 +54,8 @@ along with this program. If not, see . // The visualizer needs gfx thread priorities #define VISUALIZER_THREAD_PRIORITY (NORMAL_PRIORITY - 2) +#define VISUALIZER_USER_DATA_SIZE 16 + /* * Feature disable options * These options are also useful to firmware size reduction. diff --git a/keyboards/ergodox/infinity/infinity.c b/keyboards/ergodox/infinity/infinity.c index ecc072abbe..62259ed3f6 100644 --- a/keyboards/ergodox/infinity/infinity.c +++ b/keyboards/ergodox/infinity/infinity.c @@ -126,34 +126,48 @@ void matrix_scan_kb(void) { matrix_scan_user(); } +__attribute__ ((weak)) void ergodox_board_led_on(void){ } +__attribute__ ((weak)) void ergodox_right_led_1_on(void){ } +__attribute__ ((weak)) void ergodox_right_led_2_on(void){ } +__attribute__ ((weak)) void ergodox_right_led_3_on(void){ } -void ergodox_right_led_on(uint8_t led){ -} - +__attribute__ ((weak)) void ergodox_board_led_off(void){ } +__attribute__ ((weak)) void ergodox_right_led_1_off(void){ } +__attribute__ ((weak)) void ergodox_right_led_2_off(void){ } +__attribute__ ((weak)) void ergodox_right_led_3_off(void){ } -void ergodox_right_led_off(uint8_t led){ +__attribute__ ((weak)) +void ergodox_right_led_1_set(uint8_t n) { +} + +__attribute__ ((weak)) +void ergodox_right_led_2_set(uint8_t n) { +} + +__attribute__ ((weak)) +void ergodox_right_led_3_set(uint8_t n) { } #ifdef ONEHAND_ENABLE diff --git a/keyboards/ergodox/infinity/infinity.h b/keyboards/ergodox/infinity/infinity.h index fec9e565cd..73a0f4bf70 100644 --- a/keyboards/ergodox/infinity/infinity.h +++ b/keyboards/ergodox/infinity/infinity.h @@ -7,13 +7,38 @@ void ergodox_board_led_on(void); void ergodox_right_led_1_on(void); void ergodox_right_led_2_on(void); void ergodox_right_led_3_on(void); -void ergodox_right_led_on(uint8_t led); + +inline void ergodox_right_led_on(uint8_t led) { + switch (led) { + case 0: + ergodox_right_led_1_on(); + break; + case 1: + ergodox_right_led_2_on(); + break; + case 2: + ergodox_right_led_3_on(); + break; + } +} void ergodox_board_led_off(void); void ergodox_right_led_1_off(void); void ergodox_right_led_2_off(void); void ergodox_right_led_3_off(void); -void ergodox_right_led_off(uint8_t led); +inline void ergodox_right_led_off(uint8_t led) { + switch (led) { + case 0: + ergodox_right_led_1_off(); + break; + case 1: + ergodox_right_led_2_off(); + break; + case 2: + ergodox_right_led_3_off(); + break; + } +} inline void ergodox_led_all_on(void) { @@ -31,36 +56,22 @@ inline void ergodox_led_all_off(void) ergodox_right_led_3_off(); } -inline void ergodox_right_led_1_set(uint8_t n){ - if (n) { - ergodox_right_led_1_on(); - } else { - ergodox_right_led_1_off(); - } -} - -inline void ergodox_right_led_2_set(uint8_t n){ - if (n) { - ergodox_right_led_2_on(); - } else { - ergodox_right_led_2_off(); - } -} - -inline void ergodox_right_led_3_set(uint8_t n){ - if (n) { - ergodox_right_led_3_on(); - } else { - ergodox_right_led_3_off(); - } -} +void ergodox_right_led_1_set(uint8_t n); +void ergodox_right_led_2_set(uint8_t n); +void ergodox_right_led_3_set(uint8_t n); inline void ergodox_right_led_set(uint8_t led, uint8_t n){ - if (n) { - ergodox_right_led_on(led); - } else { - ergodox_right_led_off(led); - } + switch (led) { + case 0: + ergodox_right_led_1_set(n); + break; + case 1: + ergodox_right_led_2_set(n); + break; + case 2: + ergodox_right_led_3_set(n); + break; + } } inline void ergodox_led_all_set(uint8_t n) { diff --git a/keyboards/ergodox/infinity/visualizer.c b/keyboards/ergodox/infinity/visualizer.c index 6af3a72ee1..7bc42fbc70 100644 --- a/keyboards/ergodox/infinity/visualizer.c +++ b/keyboards/ergodox/infinity/visualizer.c @@ -27,6 +27,7 @@ along with this program. If not, see . #endif #include "visualizer.h" +#include "system/serial_link.h" // To generate an image array like this // Ensure the image is 128 x 32 or smaller @@ -73,6 +74,15 @@ static const uint8_t image_data_lcd_logo[512] = { static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0xFF); static const uint32_t initial_color = LCD_COLOR(0, 0, 0); +static const uint32_t led_emulation_colors[4] = { + LCD_COLOR(0, 0, 0), + LCD_COLOR(255, 255, 255), + LCD_COLOR(84, 255, 255), + LCD_COLOR(168, 255, 255), +}; + +static uint32_t next_led_target_color = 0; + typedef enum { LCD_STATE_INITIAL, LCD_STATE_LAYER_BITMAP, @@ -81,6 +91,19 @@ typedef enum { static lcd_state_t lcd_state = LCD_STATE_INITIAL; +typedef struct { + uint8_t led_on; + uint8_t led1; + uint8_t led2; + uint8_t led3; +} visualizer_user_data_t; + +// Don't access from visualization function, use the visualizer state instead +static visualizer_user_data_t user_data_keyboard = {}; + +_Static_assert(sizeof(visualizer_user_data_t) <= VISUALIZER_USER_DATA_SIZE, + "Please increase the VISUALIZER_USER_DATA_SIZE"); + bool display_logo(keyframe_animation_t* animation, visualizer_state_t* state) { (void)state; (void)animation; @@ -117,16 +140,27 @@ static keyframe_animation_t startup_animation = { }; // The color animation animates the LCD color when you change layers -static keyframe_animation_t color_animation = { - .num_frames = 2, +static keyframe_animation_t one_led_color = { + .num_frames = 1, .loop = false, - // Note that there's a 200 ms no-operation frame, - // this prevents the color from changing when activating the layer - // momentarily - .frame_lengths = {gfxMillisecondsToTicks(200), gfxMillisecondsToTicks(500)}, - .frame_functions = {keyframe_no_operation, keyframe_animate_backlight_color}, + .frame_lengths = {gfxMillisecondsToTicks(0)}, + .frame_functions = {keyframe_set_backlight_color}, }; +bool swap_led_target_color(keyframe_animation_t* animation, visualizer_state_t* state) { + uint32_t temp = next_led_target_color; + next_led_target_color = state->target_lcd_color; + state->target_lcd_color = temp; + return false; +} + +// The color animation animates the LCD color when you change layers +static keyframe_animation_t two_led_colors = { + .num_frames = 2, + .loop = true, + .frame_lengths = {gfxMillisecondsToTicks(1000), gfxMillisecondsToTicks(0)}, + .frame_functions = {keyframe_set_backlight_color, swap_led_target_color}, +}; // The LCD animation alternates between the layer name display and a // bitmap that displays all active layers @@ -177,6 +211,45 @@ void initialize_user_visualizer(visualizer_state_t* state) { start_keyframe_animation(&startup_animation); } +static const uint32_t red; +static const uint32_t green; +static const uint32_t blue; + +inline bool is_led_on(visualizer_user_data_t* user_data, uint8_t num) { + return user_data->led_on & (1u << num); +} + +static uint8_t get_led_index_master(visualizer_user_data_t* user_data) { + for (int i=0; i < 3; i++) { + if (is_led_on(user_data, i)) { + return i + 1; + } + } + return 0; +} + +static uint8_t get_led_index_slave(visualizer_user_data_t* user_data) { + uint8_t master_index = get_led_index_master(user_data); + if (master_index!=0) { + for (int i=master_index; i < 3; i++) { + if (is_led_on(user_data, i)) { + return i + 1; + } + } + } + + return 0; +} + +static uint8_t get_secondary_led_index(visualizer_user_data_t* user_data) { + if (is_led_on(user_data, 0) && + is_led_on(user_data, 1) && + is_led_on(user_data, 2)) { + return 3; + } + return 0; +} + void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t prev_status) { // Check the status here to start and stop animations // You might have to save some state, like the current animation here so that you can start the right @@ -186,9 +259,38 @@ void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard // This is also important because the slave won't have access to the active layer for example outside the // status. - if (lcd_state == LCD_STATE_INITIAL) { - state->target_lcd_color = LCD_COLOR(0x40, 0xB0, 0xFF); - start_keyframe_animation(&color_animation); + + visualizer_user_data_t* user_data_new = (visualizer_user_data_t*)state->status.user_data; + visualizer_user_data_t* user_data_old = (visualizer_user_data_t*)prev_status.user_data; + + uint8_t new_index; + uint8_t old_index; + + if (is_serial_link_master()) { + new_index = get_led_index_master(user_data_new); + old_index = get_led_index_master(user_data_old); + } + else { + new_index = get_led_index_slave(user_data_new); + old_index = get_led_index_slave(user_data_old); + } + uint8_t new_secondary_index = get_secondary_led_index(user_data_new); + uint8_t old_secondary_index = get_secondary_led_index(user_data_old); + + if (lcd_state == LCD_STATE_INITIAL || + new_index != old_index || + new_secondary_index != old_secondary_index) { + + if (new_secondary_index != 0) { + state->target_lcd_color = led_emulation_colors[new_index]; + next_led_target_color = led_emulation_colors[new_secondary_index]; + stop_keyframe_animation(&one_led_color); + start_keyframe_animation(&two_led_colors); + } else { + state->target_lcd_color = led_emulation_colors[new_index]; + stop_keyframe_animation(&two_led_colors); + start_keyframe_animation(&one_led_color); + } } if (state->status.leds) { @@ -233,3 +335,56 @@ void user_visualizer_resume(visualizer_state_t* state) { lcd_state = LCD_STATE_INITIAL; start_keyframe_animation(&resume_animation); } + +void ergodox_board_led_on(void){ + // No board led support +} + +void ergodox_right_led_1_on(void){ + user_data_keyboard.led_on |= (1u << 0); + visualizer_set_user_data(&user_data_keyboard); +} + +void ergodox_right_led_2_on(void){ + user_data_keyboard.led_on |= (1u << 1); + visualizer_set_user_data(&user_data_keyboard); +} + +void ergodox_right_led_3_on(void){ + user_data_keyboard.led_on |= (1u << 2); + visualizer_set_user_data(&user_data_keyboard); +} + +void ergodox_board_led_off(void){ + // No board led support +} + +void ergodox_right_led_1_off(void){ + user_data_keyboard.led_on &= ~(1u << 0); + visualizer_set_user_data(&user_data_keyboard); +} + +void ergodox_right_led_2_off(void){ + user_data_keyboard.led_on &= ~(1u << 1); + visualizer_set_user_data(&user_data_keyboard); +} + +void ergodox_right_led_3_off(void){ + user_data_keyboard.led_on &= ~(1u << 2); + visualizer_set_user_data(&user_data_keyboard); +} + +void ergodox_right_led_1_set(uint8_t n) { + user_data_keyboard.led1 = n; + visualizer_set_user_data(&user_data_keyboard); +} + +void ergodox_right_led_2_set(uint8_t n) { + user_data_keyboard.led2 = n; + visualizer_set_user_data(&user_data_keyboard); +} + +void ergodox_right_led_3_set(uint8_t n) { + user_data_keyboard.led3 = n; + visualizer_set_user_data(&user_data_keyboard); +} diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c index 62ebebceed..bff0df4947 100644 --- a/quantum/visualizer/visualizer.c +++ b/quantum/visualizer/visualizer.c @@ -64,6 +64,9 @@ static visualizer_keyboard_status_t current_status = { .mods = 0xFF, .leds = 0xFFFFFFFF, .suspended = false, +#ifdef VISUALIZER_USER_DATA_SIZE + .user_data = {0} +#endif }; static bool same_status(visualizer_keyboard_status_t* status1, visualizer_keyboard_status_t* status2) { @@ -71,11 +74,19 @@ static bool same_status(visualizer_keyboard_status_t* status1, visualizer_keyboa status1->default_layer == status2->default_layer && status1->mods == status2->mods && status1->leds == status2->leds && - status1->suspended == status2->suspended; + status1->suspended == status2->suspended +#ifdef VISUALIZER_USER_DATA_SIZE + && memcmp(status1->user_data, status2->user_data, VISUALIZER_USER_DATA_SIZE) == 0 +#endif + ; } static bool visualizer_enabled = false; +#ifdef VISUALIZER_USER_DATA_SIZE +static uint8_t user_data[VISUALIZER_USER_DATA_SIZE]; +#endif + #define MAX_SIMULTANEOUS_ANIMATIONS 4 static keyframe_animation_t* animations[MAX_SIMULTANEOUS_ANIMATIONS] = {}; @@ -431,6 +442,9 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) { .mods = 0xFF, .leds = 0xFFFFFFFF, .suspended = false, +#ifdef VISUALIZER_USER_DATA_SIZE + .user_data = {0}, +#endif }; visualizer_state_t state = { @@ -590,6 +604,12 @@ uint8_t visualizer_get_mods() { return mods; } +#ifdef VISUALIZER_USER_DATA_SIZE +void visualizer_set_user_data(void* u) { + memcpy(user_data, u, VISUALIZER_USER_DATA_SIZE); +} +#endif + void visualizer_update(uint32_t default_state, uint32_t state, uint8_t mods, uint32_t leds) { // Note that there's a small race condition here, the thread could read // a state where one of these are set but not the other. But this should @@ -618,6 +638,9 @@ void visualizer_update(uint32_t default_state, uint32_t state, uint8_t mods, uin .leds = leds, .suspended = current_status.suspended, }; +#ifdef VISUALIZER_USER_DATA_SIZE + memcpy(new_status.user_data, user_data, VISUALIZER_USER_DATA_SIZE); +#endif if (!same_status(¤t_status, &new_status)) { changed = true; current_status = new_status; diff --git a/quantum/visualizer/visualizer.h b/quantum/visualizer/visualizer.h index 2c81cb9f71..beb8f2ab41 100644 --- a/quantum/visualizer/visualizer.h +++ b/quantum/visualizer/visualizer.h @@ -68,6 +68,9 @@ typedef struct { uint8_t mods; uint32_t leds; // See led.h for available statuses bool suspended; +#ifdef VISUALIZER_USER_DATA_SIZE + uint8_t user_data[VISUALIZER_USER_DATA_SIZE]; +#endif } visualizer_keyboard_status_t; // The state struct is used by the various keyframe functions @@ -146,6 +149,11 @@ bool keyframe_enable_lcd_and_backlight(keyframe_animation_t* animation, visualiz // directly from the initalize_user_visualizer function (the animation can be null) bool enable_visualization(keyframe_animation_t* animation, visualizer_state_t* state); +// The master can set userdata which will be transferred to the slave +#ifdef VISUALIZER_USER_DATA_SIZE +void visualizer_set_user_data(void* user_data); +#endif + // These functions have to be implemented by the user void initialize_user_visualizer(visualizer_state_t* state); void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t prev_status); From 5fbaf31dc26a7bb27eb276ec419255e92b293d60 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sun, 2 Apr 2017 02:29:50 +0300 Subject: [PATCH 14/34] Brightness for Ergodox Infinity emulated LEDs --- keyboards/ergodox/infinity/config.h | 2 +- keyboards/ergodox/infinity/visualizer.c | 76 ++++++++++++++++++------- quantum/visualizer/lcd_backlight.h | 4 ++ quantum/visualizer/visualizer.c | 2 +- quantum/visualizer/visualizer.h | 2 +- 5 files changed, 63 insertions(+), 23 deletions(-) diff --git a/keyboards/ergodox/infinity/config.h b/keyboards/ergodox/infinity/config.h index 6cde193e13..95f713819e 100644 --- a/keyboards/ergodox/infinity/config.h +++ b/keyboards/ergodox/infinity/config.h @@ -40,7 +40,7 @@ along with this program. If not, see . /* number of backlight levels */ #define BACKLIGHT_LEVELS 3 -#define LED_BRIGHTNESS_LO 15 +#define LED_BRIGHTNESS_LO 100 #define LED_BRIGHTNESS_HI 255 /* define if matrix has ghost */ diff --git a/keyboards/ergodox/infinity/visualizer.c b/keyboards/ergodox/infinity/visualizer.c index 7bc42fbc70..c7afd9384c 100644 --- a/keyboards/ergodox/infinity/visualizer.c +++ b/keyboards/ergodox/infinity/visualizer.c @@ -99,7 +99,12 @@ typedef struct { } visualizer_user_data_t; // Don't access from visualization function, use the visualizer state instead -static visualizer_user_data_t user_data_keyboard = {}; +static visualizer_user_data_t user_data_keyboard = { + .led_on = 0, + .led1 = LED_BRIGHTNESS_HI, + .led2 = LED_BRIGHTNESS_HI, + .led3 = LED_BRIGHTNESS_HI, +}; _Static_assert(sizeof(visualizer_user_data_t) <= VISUALIZER_USER_DATA_SIZE, "Please increase the VISUALIZER_USER_DATA_SIZE"); @@ -250,18 +255,21 @@ static uint8_t get_secondary_led_index(visualizer_user_data_t* user_data) { return 0; } -void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t prev_status) { - // Check the status here to start and stop animations - // You might have to save some state, like the current animation here so that you can start the right - // This function is called every time the status changes - - // NOTE that this is called from the visualizer thread, so don't access anything else outside the status - // This is also important because the slave won't have access to the active layer for example outside the - // status. - +static uint8_t get_brightness(visualizer_user_data_t* user_data, uint8_t index) { + switch (index) { + case 1: + return user_data->led1; + case 2: + return user_data->led2; + case 3: + return user_data->led3; + } + return 0; +} +static void update_emulated_leds(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) { visualizer_user_data_t* user_data_new = (visualizer_user_data_t*)state->status.user_data; - visualizer_user_data_t* user_data_old = (visualizer_user_data_t*)prev_status.user_data; + visualizer_user_data_t* user_data_old = (visualizer_user_data_t*)prev_status->user_data; uint8_t new_index; uint8_t old_index; @@ -277,27 +285,41 @@ void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard uint8_t new_secondary_index = get_secondary_led_index(user_data_new); uint8_t old_secondary_index = get_secondary_led_index(user_data_old); + uint8_t old_brightness = get_brightness(user_data_old, old_index); + uint8_t new_brightness = get_brightness(user_data_new, new_index); + + uint8_t old_secondary_brightness = get_brightness(user_data_old, old_secondary_index); + uint8_t new_secondary_brightness = get_brightness(user_data_new, new_secondary_index); + if (lcd_state == LCD_STATE_INITIAL || new_index != old_index || - new_secondary_index != old_secondary_index) { + new_secondary_index != old_secondary_index || + new_brightness != old_brightness || + new_secondary_brightness != old_secondary_brightness) { if (new_secondary_index != 0) { - state->target_lcd_color = led_emulation_colors[new_index]; - next_led_target_color = led_emulation_colors[new_secondary_index]; + state->target_lcd_color = change_lcd_color_intensity( + led_emulation_colors[new_index], new_brightness); + next_led_target_color = change_lcd_color_intensity( + led_emulation_colors[new_secondary_index], new_secondary_brightness); + stop_keyframe_animation(&one_led_color); start_keyframe_animation(&two_led_colors); } else { - state->target_lcd_color = led_emulation_colors[new_index]; + state->target_lcd_color = change_lcd_color_intensity( + led_emulation_colors[new_index], new_brightness); stop_keyframe_animation(&two_led_colors); start_keyframe_animation(&one_led_color); } } +} +static void update_lcd_text(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) { if (state->status.leds) { if (lcd_state != LCD_STATE_BITMAP_AND_LEDS || - state->status.leds != prev_status.leds || - state->status.layer != prev_status.layer || - state->status.default_layer != prev_status.default_layer) { + state->status.leds != prev_status->leds || + state->status.layer != prev_status->layer || + state->status.default_layer != prev_status->default_layer) { // NOTE: that it doesn't matter if the animation isn't playing, stop will do nothing in that case stop_keyframe_animation(&lcd_bitmap_animation); @@ -310,8 +332,8 @@ void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard } } else { if (lcd_state != LCD_STATE_LAYER_BITMAP || - state->status.layer != prev_status.layer || - state->status.default_layer != prev_status.default_layer) { + state->status.layer != prev_status->layer || + state->status.default_layer != prev_status->default_layer) { stop_keyframe_animation(&lcd_bitmap_leds_animation); @@ -321,6 +343,20 @@ void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard } } +void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) { + // Check the status here to start and stop animations + // You might have to save some state, like the current animation here so that you can start the right + // This function is called every time the status changes + + // NOTE that this is called from the visualizer thread, so don't access anything else outside the status + // This is also important because the slave won't have access to the active layer for example outside the + // status. + + update_emulated_leds(state, prev_status); + update_lcd_text(state, prev_status); + +} + void user_visualizer_suspend(visualizer_state_t* state) { state->layer_text = "Suspending..."; uint8_t hue = LCD_HUE(state->current_lcd_color); diff --git a/quantum/visualizer/lcd_backlight.h b/quantum/visualizer/lcd_backlight.h index dd3e37a064..14dde64a1a 100644 --- a/quantum/visualizer/lcd_backlight.h +++ b/quantum/visualizer/lcd_backlight.h @@ -32,6 +32,10 @@ SOFTWARE. #define LCD_SAT(color) ((color >> 8) & 0xFF) #define LCD_INT(color) (color & 0xFF) +inline uint32_t change_lcd_color_intensity(uint32_t color, uint8_t new_intensity) { + return (color & 0xFFFFFF00) | new_intensity; +} + void lcd_backlight_init(void); void lcd_backlight_color(uint8_t hue, uint8_t saturation, uint8_t intensity); void lcd_backlight_brightness(uint8_t b); diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c index bff0df4947..3b3f51b1ff 100644 --- a/quantum/visualizer/visualizer.c +++ b/quantum/visualizer/visualizer.c @@ -484,7 +484,7 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) { else { visualizer_keyboard_status_t prev_status = state.status; state.status = current_status; - update_user_visualizer_state(&state, prev_status); + update_user_visualizer_state(&state, &prev_status); } state.prev_lcd_color = state.current_lcd_color; } diff --git a/quantum/visualizer/visualizer.h b/quantum/visualizer/visualizer.h index beb8f2ab41..e8ace5b37b 100644 --- a/quantum/visualizer/visualizer.h +++ b/quantum/visualizer/visualizer.h @@ -156,7 +156,7 @@ void visualizer_set_user_data(void* user_data); // These functions have to be implemented by the user void initialize_user_visualizer(visualizer_state_t* state); -void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t prev_status); +void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status); void user_visualizer_suspend(visualizer_state_t* state); void user_visualizer_resume(visualizer_state_t* state); From 65e8127c91c6a0fc027a1a482de443302e00d019 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Mon, 3 Apr 2017 22:08:34 +0300 Subject: [PATCH 15/34] Add visualizer for Ergodox default --- .../ergodox/keymaps/default/visualizer.c | 426 ++++++++++++++++++ 1 file changed, 426 insertions(+) create mode 100644 keyboards/ergodox/keymaps/default/visualizer.c diff --git a/keyboards/ergodox/keymaps/default/visualizer.c b/keyboards/ergodox/keymaps/default/visualizer.c new file mode 100644 index 0000000000..c7afd9384c --- /dev/null +++ b/keyboards/ergodox/keymaps/default/visualizer.c @@ -0,0 +1,426 @@ +/* +Copyright 2016 Fred Sundvik + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +// Currently we are assuming that both the backlight and LCD are enabled +// But it's entirely possible to write a custom visualizer that use only +// one of them +#ifndef LCD_BACKLIGHT_ENABLE +#error This visualizer needs that LCD backlight is enabled +#endif + +#ifndef LCD_ENABLE +#error This visualizer needs that LCD is enabled +#endif + +#include "visualizer.h" +#include "system/serial_link.h" + +// To generate an image array like this +// Ensure the image is 128 x 32 or smaller +// Convert the bitmap to a C array using a program like http://www.riuson.com/lcd-image-converter/ +// Ensure the the conversion process produces a monochrome format array - 1 bit/pixel, left to right, top to bottom +// Update array in the source code with the C array produced by the conversion program + +// The image below is generated from lcd_logo.png +static const uint8_t image_data_lcd_logo[512] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0xfe, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x38, 0x38, 0x06, 0x29, 0x41, 0x24, 0x52, 0x24, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x38, 0x38, 0x09, 0x55, 0x42, 0xaa, 0xaa, 0xaa, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x38, 0x38, 0x09, 0x55, 0x82, 0x28, 0xaa, 0xae, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x38, 0x38, 0x09, 0x55, 0x43, 0x28, 0xaa, 0xaa, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x38, 0x38, 0x0a, 0x55, 0x42, 0x28, 0xaa, 0xaa, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x38, 0x38, 0x05, 0x45, 0x42, 0x28, 0x89, 0x4a, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x38, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1c, 0x38, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0e, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xff, 0x80, 0x04, 0x45, 0x14, 0xa4, 0x92, 0x83, 0x52, 0x22, 0x22, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x00, 0x0a, 0xaa, 0xaa, 0xaa, 0xba, 0x84, 0x55, 0x55, 0x57, 0x45, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x00, 0x08, 0xaa, 0xaa, 0xaa, 0x92, 0xb2, 0x55, 0x55, 0x42, 0x65, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x00, 0x08, 0xaa, 0xaa, 0xaa, 0x92, 0x81, 0x56, 0x65, 0x42, 0x45, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x00, 0x0a, 0xaa, 0xaa, 0xaa, 0x92, 0x81, 0x54, 0x45, 0x42, 0x45, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x00, 0x04, 0x48, 0xa2, 0x4a, 0x89, 0x06, 0x24, 0x42, 0x41, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0xFF); +static const uint32_t initial_color = LCD_COLOR(0, 0, 0); + +static const uint32_t led_emulation_colors[4] = { + LCD_COLOR(0, 0, 0), + LCD_COLOR(255, 255, 255), + LCD_COLOR(84, 255, 255), + LCD_COLOR(168, 255, 255), +}; + +static uint32_t next_led_target_color = 0; + +typedef enum { + LCD_STATE_INITIAL, + LCD_STATE_LAYER_BITMAP, + LCD_STATE_BITMAP_AND_LEDS, +} lcd_state_t; + +static lcd_state_t lcd_state = LCD_STATE_INITIAL; + +typedef struct { + uint8_t led_on; + uint8_t led1; + uint8_t led2; + uint8_t led3; +} visualizer_user_data_t; + +// Don't access from visualization function, use the visualizer state instead +static visualizer_user_data_t user_data_keyboard = { + .led_on = 0, + .led1 = LED_BRIGHTNESS_HI, + .led2 = LED_BRIGHTNESS_HI, + .led3 = LED_BRIGHTNESS_HI, +}; + +_Static_assert(sizeof(visualizer_user_data_t) <= VISUALIZER_USER_DATA_SIZE, + "Please increase the VISUALIZER_USER_DATA_SIZE"); + +bool display_logo(keyframe_animation_t* animation, visualizer_state_t* state) { + (void)state; + (void)animation; + (void)state; + // Read the uGFX documentation for information how to use the displays + // http://wiki.ugfx.org/index.php/Main_Page + gdispClear(White); + + // You can use static variables for things that can't be found in the animation + // or state structs, here we use the image + + //gdispGBlitArea is a tricky function to use since it supports blitting part of the image + // if you have full screen image, then just use 128 and 32 for both source and target dimensions + gdispGBlitArea(GDISP, 0, 0, 128, 32, 0, 0, 128, (pixel_t*)image_data_lcd_logo); + + // Always remember to flush the display + gdispFlush(); + return false; +} + +// Feel free to modify the animations below, or even add new ones if needed + +// Don't worry, if the startup animation is long, you can use the keyboard like normal +// during that time +static keyframe_animation_t startup_animation = { + .num_frames = 3, + .loop = false, + .frame_lengths = {0, gfxMillisecondsToTicks(10000), 0}, + .frame_functions = { + display_logo, + keyframe_animate_backlight_color, + enable_visualization + }, +}; + +// The color animation animates the LCD color when you change layers +static keyframe_animation_t one_led_color = { + .num_frames = 1, + .loop = false, + .frame_lengths = {gfxMillisecondsToTicks(0)}, + .frame_functions = {keyframe_set_backlight_color}, +}; + +bool swap_led_target_color(keyframe_animation_t* animation, visualizer_state_t* state) { + uint32_t temp = next_led_target_color; + next_led_target_color = state->target_lcd_color; + state->target_lcd_color = temp; + return false; +} + +// The color animation animates the LCD color when you change layers +static keyframe_animation_t two_led_colors = { + .num_frames = 2, + .loop = true, + .frame_lengths = {gfxMillisecondsToTicks(1000), gfxMillisecondsToTicks(0)}, + .frame_functions = {keyframe_set_backlight_color, swap_led_target_color}, +}; + +// The LCD animation alternates between the layer name display and a +// bitmap that displays all active layers +static keyframe_animation_t lcd_bitmap_animation = { + .num_frames = 1, + .loop = false, + .frame_lengths = {gfxMillisecondsToTicks(0)}, + .frame_functions = {keyframe_display_layer_bitmap}, +}; + +static keyframe_animation_t lcd_bitmap_leds_animation = { + .num_frames = 2, + .loop = true, + .frame_lengths = {gfxMillisecondsToTicks(2000), gfxMillisecondsToTicks(2000)}, + .frame_functions = {keyframe_display_layer_bitmap, keyframe_display_led_states}, +}; + +static keyframe_animation_t suspend_animation = { + .num_frames = 3, + .loop = false, + .frame_lengths = {0, gfxMillisecondsToTicks(1000), 0}, + .frame_functions = { + keyframe_display_layer_text, + keyframe_animate_backlight_color, + keyframe_disable_lcd_and_backlight, + }, +}; + +static keyframe_animation_t resume_animation = { + .num_frames = 4, + .loop = false, + .frame_lengths = {0, 0, gfxMillisecondsToTicks(10000), 0}, + .frame_functions = { + keyframe_enable_lcd_and_backlight, + display_logo, + keyframe_animate_backlight_color, + enable_visualization, + }, +}; + +void initialize_user_visualizer(visualizer_state_t* state) { + // The brightness will be dynamically adjustable in the future + // But for now, change it here. + lcd_backlight_brightness(130); + state->current_lcd_color = initial_color; + state->target_lcd_color = logo_background_color; + lcd_state = LCD_STATE_INITIAL; + start_keyframe_animation(&startup_animation); +} + +static const uint32_t red; +static const uint32_t green; +static const uint32_t blue; + +inline bool is_led_on(visualizer_user_data_t* user_data, uint8_t num) { + return user_data->led_on & (1u << num); +} + +static uint8_t get_led_index_master(visualizer_user_data_t* user_data) { + for (int i=0; i < 3; i++) { + if (is_led_on(user_data, i)) { + return i + 1; + } + } + return 0; +} + +static uint8_t get_led_index_slave(visualizer_user_data_t* user_data) { + uint8_t master_index = get_led_index_master(user_data); + if (master_index!=0) { + for (int i=master_index; i < 3; i++) { + if (is_led_on(user_data, i)) { + return i + 1; + } + } + } + + return 0; +} + +static uint8_t get_secondary_led_index(visualizer_user_data_t* user_data) { + if (is_led_on(user_data, 0) && + is_led_on(user_data, 1) && + is_led_on(user_data, 2)) { + return 3; + } + return 0; +} + +static uint8_t get_brightness(visualizer_user_data_t* user_data, uint8_t index) { + switch (index) { + case 1: + return user_data->led1; + case 2: + return user_data->led2; + case 3: + return user_data->led3; + } + return 0; +} + +static void update_emulated_leds(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) { + visualizer_user_data_t* user_data_new = (visualizer_user_data_t*)state->status.user_data; + visualizer_user_data_t* user_data_old = (visualizer_user_data_t*)prev_status->user_data; + + uint8_t new_index; + uint8_t old_index; + + if (is_serial_link_master()) { + new_index = get_led_index_master(user_data_new); + old_index = get_led_index_master(user_data_old); + } + else { + new_index = get_led_index_slave(user_data_new); + old_index = get_led_index_slave(user_data_old); + } + uint8_t new_secondary_index = get_secondary_led_index(user_data_new); + uint8_t old_secondary_index = get_secondary_led_index(user_data_old); + + uint8_t old_brightness = get_brightness(user_data_old, old_index); + uint8_t new_brightness = get_brightness(user_data_new, new_index); + + uint8_t old_secondary_brightness = get_brightness(user_data_old, old_secondary_index); + uint8_t new_secondary_brightness = get_brightness(user_data_new, new_secondary_index); + + if (lcd_state == LCD_STATE_INITIAL || + new_index != old_index || + new_secondary_index != old_secondary_index || + new_brightness != old_brightness || + new_secondary_brightness != old_secondary_brightness) { + + if (new_secondary_index != 0) { + state->target_lcd_color = change_lcd_color_intensity( + led_emulation_colors[new_index], new_brightness); + next_led_target_color = change_lcd_color_intensity( + led_emulation_colors[new_secondary_index], new_secondary_brightness); + + stop_keyframe_animation(&one_led_color); + start_keyframe_animation(&two_led_colors); + } else { + state->target_lcd_color = change_lcd_color_intensity( + led_emulation_colors[new_index], new_brightness); + stop_keyframe_animation(&two_led_colors); + start_keyframe_animation(&one_led_color); + } + } +} + +static void update_lcd_text(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) { + if (state->status.leds) { + if (lcd_state != LCD_STATE_BITMAP_AND_LEDS || + state->status.leds != prev_status->leds || + state->status.layer != prev_status->layer || + state->status.default_layer != prev_status->default_layer) { + + // NOTE: that it doesn't matter if the animation isn't playing, stop will do nothing in that case + stop_keyframe_animation(&lcd_bitmap_animation); + + lcd_state = LCD_STATE_BITMAP_AND_LEDS; + // For information: + // The logic in this function makes sure that this doesn't happen, but if you call start on an + // animation that is already playing it will be restarted. + start_keyframe_animation(&lcd_bitmap_leds_animation); + } + } else { + if (lcd_state != LCD_STATE_LAYER_BITMAP || + state->status.layer != prev_status->layer || + state->status.default_layer != prev_status->default_layer) { + + stop_keyframe_animation(&lcd_bitmap_leds_animation); + + lcd_state = LCD_STATE_LAYER_BITMAP; + start_keyframe_animation(&lcd_bitmap_animation); + } + } +} + +void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) { + // Check the status here to start and stop animations + // You might have to save some state, like the current animation here so that you can start the right + // This function is called every time the status changes + + // NOTE that this is called from the visualizer thread, so don't access anything else outside the status + // This is also important because the slave won't have access to the active layer for example outside the + // status. + + update_emulated_leds(state, prev_status); + update_lcd_text(state, prev_status); + +} + +void user_visualizer_suspend(visualizer_state_t* state) { + state->layer_text = "Suspending..."; + uint8_t hue = LCD_HUE(state->current_lcd_color); + uint8_t sat = LCD_SAT(state->current_lcd_color); + state->target_lcd_color = LCD_COLOR(hue, sat, 0); + start_keyframe_animation(&suspend_animation); +} + +void user_visualizer_resume(visualizer_state_t* state) { + state->current_lcd_color = initial_color; + state->target_lcd_color = logo_background_color; + lcd_state = LCD_STATE_INITIAL; + start_keyframe_animation(&resume_animation); +} + +void ergodox_board_led_on(void){ + // No board led support +} + +void ergodox_right_led_1_on(void){ + user_data_keyboard.led_on |= (1u << 0); + visualizer_set_user_data(&user_data_keyboard); +} + +void ergodox_right_led_2_on(void){ + user_data_keyboard.led_on |= (1u << 1); + visualizer_set_user_data(&user_data_keyboard); +} + +void ergodox_right_led_3_on(void){ + user_data_keyboard.led_on |= (1u << 2); + visualizer_set_user_data(&user_data_keyboard); +} + +void ergodox_board_led_off(void){ + // No board led support +} + +void ergodox_right_led_1_off(void){ + user_data_keyboard.led_on &= ~(1u << 0); + visualizer_set_user_data(&user_data_keyboard); +} + +void ergodox_right_led_2_off(void){ + user_data_keyboard.led_on &= ~(1u << 1); + visualizer_set_user_data(&user_data_keyboard); +} + +void ergodox_right_led_3_off(void){ + user_data_keyboard.led_on &= ~(1u << 2); + visualizer_set_user_data(&user_data_keyboard); +} + +void ergodox_right_led_1_set(uint8_t n) { + user_data_keyboard.led1 = n; + visualizer_set_user_data(&user_data_keyboard); +} + +void ergodox_right_led_2_set(uint8_t n) { + user_data_keyboard.led2 = n; + visualizer_set_user_data(&user_data_keyboard); +} + +void ergodox_right_led_3_set(uint8_t n) { + user_data_keyboard.led3 = n; + visualizer_set_user_data(&user_data_keyboard); +} From fa6da78ff3c96a71ed65684e276352700843d539 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Mon, 3 Apr 2017 23:00:58 +0300 Subject: [PATCH 16/34] Simple layer display on Infinity Ergodox default layout --- .../ergodox/keymaps/default/visualizer.c | 284 ++++-------------- 1 file changed, 61 insertions(+), 223 deletions(-) diff --git a/keyboards/ergodox/keymaps/default/visualizer.c b/keyboards/ergodox/keymaps/default/visualizer.c index c7afd9384c..d99d5f7026 100644 --- a/keyboards/ergodox/keymaps/default/visualizer.c +++ b/keyboards/ergodox/keymaps/default/visualizer.c @@ -1,5 +1,5 @@ /* -Copyright 2016 Fred Sundvik +Copyright 2017 Fred Sundvik This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -74,15 +74,6 @@ static const uint8_t image_data_lcd_logo[512] = { static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0xFF); static const uint32_t initial_color = LCD_COLOR(0, 0, 0); -static const uint32_t led_emulation_colors[4] = { - LCD_COLOR(0, 0, 0), - LCD_COLOR(255, 255, 255), - LCD_COLOR(84, 255, 255), - LCD_COLOR(168, 255, 255), -}; - -static uint32_t next_led_target_color = 0; - typedef enum { LCD_STATE_INITIAL, LCD_STATE_LAYER_BITMAP, @@ -91,24 +82,6 @@ typedef enum { static lcd_state_t lcd_state = LCD_STATE_INITIAL; -typedef struct { - uint8_t led_on; - uint8_t led1; - uint8_t led2; - uint8_t led3; -} visualizer_user_data_t; - -// Don't access from visualization function, use the visualizer state instead -static visualizer_user_data_t user_data_keyboard = { - .led_on = 0, - .led1 = LED_BRIGHTNESS_HI, - .led2 = LED_BRIGHTNESS_HI, - .led3 = LED_BRIGHTNESS_HI, -}; - -_Static_assert(sizeof(visualizer_user_data_t) <= VISUALIZER_USER_DATA_SIZE, - "Please increase the VISUALIZER_USER_DATA_SIZE"); - bool display_logo(keyframe_animation_t* animation, visualizer_state_t* state) { (void)state; (void)animation; @@ -144,43 +117,34 @@ static keyframe_animation_t startup_animation = { }, }; -// The color animation animates the LCD color when you change layers -static keyframe_animation_t one_led_color = { - .num_frames = 1, - .loop = false, - .frame_lengths = {gfxMillisecondsToTicks(0)}, - .frame_functions = {keyframe_set_backlight_color}, -}; - -bool swap_led_target_color(keyframe_animation_t* animation, visualizer_state_t* state) { - uint32_t temp = next_led_target_color; - next_led_target_color = state->target_lcd_color; - state->target_lcd_color = temp; - return false; -} - -// The color animation animates the LCD color when you change layers -static keyframe_animation_t two_led_colors = { - .num_frames = 2, - .loop = true, - .frame_lengths = {gfxMillisecondsToTicks(1000), gfxMillisecondsToTicks(0)}, - .frame_functions = {keyframe_set_backlight_color, swap_led_target_color}, -}; - // The LCD animation alternates between the layer name display and a // bitmap that displays all active layers -static keyframe_animation_t lcd_bitmap_animation = { - .num_frames = 1, - .loop = false, - .frame_lengths = {gfxMillisecondsToTicks(0)}, - .frame_functions = {keyframe_display_layer_bitmap}, -}; - -static keyframe_animation_t lcd_bitmap_leds_animation = { +static keyframe_animation_t lcd_layer_bitmap_animation = { .num_frames = 2, .loop = true, - .frame_lengths = {gfxMillisecondsToTicks(2000), gfxMillisecondsToTicks(2000)}, - .frame_functions = {keyframe_display_layer_bitmap, keyframe_display_led_states}, + .frame_lengths = { + gfxMillisecondsToTicks(2000), + gfxMillisecondsToTicks(2000) + }, + .frame_functions = { + keyframe_display_layer_text, + keyframe_display_layer_bitmap + }, +}; + +static keyframe_animation_t lcd_layer_bitmap_leds_animation = { + .num_frames = 3, + .loop = true, + .frame_lengths = { + gfxMillisecondsToTicks(2000), + gfxMillisecondsToTicks(2000), + gfxMillisecondsToTicks(2000) + }, + .frame_functions = { + keyframe_display_layer_text, + keyframe_display_led_states, + keyframe_display_layer_bitmap, + }, }; static keyframe_animation_t suspend_animation = { @@ -206,6 +170,17 @@ static keyframe_animation_t resume_animation = { }, }; +// The color animation animates the LCD color when you change layers +static keyframe_animation_t color_animation = { + .num_frames = 2, + .loop = false, + // Note that there's a 200 ms no-operation frame, + // this prevents the color from changing when activating the layer + // momentarily + .frame_lengths = {gfxMillisecondsToTicks(200), gfxMillisecondsToTicks(500)}, + .frame_functions = {keyframe_no_operation, keyframe_animate_backlight_color}, +}; + void initialize_user_visualizer(visualizer_state_t* state) { // The brightness will be dynamically adjustable in the future // But for now, change it here. @@ -216,105 +191,32 @@ void initialize_user_visualizer(visualizer_state_t* state) { start_keyframe_animation(&startup_animation); } -static const uint32_t red; -static const uint32_t green; -static const uint32_t blue; +void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) { + // Add more tests, change the colors and layer texts here + // Usually you want to check the high bits (higher layers first) + // because that's the order layers are processed for keypresses + // You can for check for example: + // state->status.layer + // state->status.default_layer + // state->status.leds (see led.h for available statuses) -inline bool is_led_on(visualizer_user_data_t* user_data, uint8_t num) { - return user_data->led_on & (1u << num); -} - -static uint8_t get_led_index_master(visualizer_user_data_t* user_data) { - for (int i=0; i < 3; i++) { - if (is_led_on(user_data, i)) { - return i + 1; - } + if (state->status.layer & 0x4) { + state->target_lcd_color = LCD_COLOR(0, 0xB0, 0xFF); + state->layer_text = "Media & Mouse"; } - return 0; -} - -static uint8_t get_led_index_slave(visualizer_user_data_t* user_data) { - uint8_t master_index = get_led_index_master(user_data); - if (master_index!=0) { - for (int i=master_index; i < 3; i++) { - if (is_led_on(user_data, i)) { - return i + 1; - } - } - } - - return 0; -} - -static uint8_t get_secondary_led_index(visualizer_user_data_t* user_data) { - if (is_led_on(user_data, 0) && - is_led_on(user_data, 1) && - is_led_on(user_data, 2)) { - return 3; - } - return 0; -} - -static uint8_t get_brightness(visualizer_user_data_t* user_data, uint8_t index) { - switch (index) { - case 1: - return user_data->led1; - case 2: - return user_data->led2; - case 3: - return user_data->led3; - } - return 0; -} - -static void update_emulated_leds(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) { - visualizer_user_data_t* user_data_new = (visualizer_user_data_t*)state->status.user_data; - visualizer_user_data_t* user_data_old = (visualizer_user_data_t*)prev_status->user_data; - - uint8_t new_index; - uint8_t old_index; - - if (is_serial_link_master()) { - new_index = get_led_index_master(user_data_new); - old_index = get_led_index_master(user_data_old); + else if (state->status.layer & 0x2) { + state->target_lcd_color = LCD_COLOR(0x80, 0xB0, 0xFF); + state->layer_text = "Symbol"; } else { - new_index = get_led_index_slave(user_data_new); - old_index = get_led_index_slave(user_data_old); + state->target_lcd_color = LCD_COLOR(0x40, 0xB0, 0xFF); + state->layer_text = "Default"; } - uint8_t new_secondary_index = get_secondary_led_index(user_data_new); - uint8_t old_secondary_index = get_secondary_led_index(user_data_old); - uint8_t old_brightness = get_brightness(user_data_old, old_index); - uint8_t new_brightness = get_brightness(user_data_new, new_index); - - uint8_t old_secondary_brightness = get_brightness(user_data_old, old_secondary_index); - uint8_t new_secondary_brightness = get_brightness(user_data_new, new_secondary_index); - - if (lcd_state == LCD_STATE_INITIAL || - new_index != old_index || - new_secondary_index != old_secondary_index || - new_brightness != old_brightness || - new_secondary_brightness != old_secondary_brightness) { - - if (new_secondary_index != 0) { - state->target_lcd_color = change_lcd_color_intensity( - led_emulation_colors[new_index], new_brightness); - next_led_target_color = change_lcd_color_intensity( - led_emulation_colors[new_secondary_index], new_secondary_brightness); - - stop_keyframe_animation(&one_led_color); - start_keyframe_animation(&two_led_colors); - } else { - state->target_lcd_color = change_lcd_color_intensity( - led_emulation_colors[new_index], new_brightness); - stop_keyframe_animation(&two_led_colors); - start_keyframe_animation(&one_led_color); - } + if (lcd_state == LCD_STATE_INITIAL || state->status.layer != prev_status->layer) { + start_keyframe_animation(&color_animation); } -} -static void update_lcd_text(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) { if (state->status.leds) { if (lcd_state != LCD_STATE_BITMAP_AND_LEDS || state->status.leds != prev_status->leds || @@ -322,39 +224,28 @@ static void update_lcd_text(visualizer_state_t* state, visualizer_keyboard_statu state->status.default_layer != prev_status->default_layer) { // NOTE: that it doesn't matter if the animation isn't playing, stop will do nothing in that case - stop_keyframe_animation(&lcd_bitmap_animation); + stop_keyframe_animation(&lcd_layer_bitmap_animation); lcd_state = LCD_STATE_BITMAP_AND_LEDS; // For information: // The logic in this function makes sure that this doesn't happen, but if you call start on an // animation that is already playing it will be restarted. - start_keyframe_animation(&lcd_bitmap_leds_animation); + start_keyframe_animation(&lcd_layer_bitmap_leds_animation); } } else { if (lcd_state != LCD_STATE_LAYER_BITMAP || state->status.layer != prev_status->layer || state->status.default_layer != prev_status->default_layer) { - stop_keyframe_animation(&lcd_bitmap_leds_animation); + stop_keyframe_animation(&lcd_layer_bitmap_leds_animation); lcd_state = LCD_STATE_LAYER_BITMAP; - start_keyframe_animation(&lcd_bitmap_animation); + start_keyframe_animation(&lcd_layer_bitmap_animation); } } -} - -void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) { - // Check the status here to start and stop animations - // You might have to save some state, like the current animation here so that you can start the right - // This function is called every time the status changes - - // NOTE that this is called from the visualizer thread, so don't access anything else outside the status - // This is also important because the slave won't have access to the active layer for example outside the - // status. - - update_emulated_leds(state, prev_status); - update_lcd_text(state, prev_status); - + // You can also stop existing animations, and start your custom ones here + // remember that you should normally have only one animation for the LCD + // and one for the background. But you can also combine them if you want. } void user_visualizer_suspend(visualizer_state_t* state) { @@ -371,56 +262,3 @@ void user_visualizer_resume(visualizer_state_t* state) { lcd_state = LCD_STATE_INITIAL; start_keyframe_animation(&resume_animation); } - -void ergodox_board_led_on(void){ - // No board led support -} - -void ergodox_right_led_1_on(void){ - user_data_keyboard.led_on |= (1u << 0); - visualizer_set_user_data(&user_data_keyboard); -} - -void ergodox_right_led_2_on(void){ - user_data_keyboard.led_on |= (1u << 1); - visualizer_set_user_data(&user_data_keyboard); -} - -void ergodox_right_led_3_on(void){ - user_data_keyboard.led_on |= (1u << 2); - visualizer_set_user_data(&user_data_keyboard); -} - -void ergodox_board_led_off(void){ - // No board led support -} - -void ergodox_right_led_1_off(void){ - user_data_keyboard.led_on &= ~(1u << 0); - visualizer_set_user_data(&user_data_keyboard); -} - -void ergodox_right_led_2_off(void){ - user_data_keyboard.led_on &= ~(1u << 1); - visualizer_set_user_data(&user_data_keyboard); -} - -void ergodox_right_led_3_off(void){ - user_data_keyboard.led_on &= ~(1u << 2); - visualizer_set_user_data(&user_data_keyboard); -} - -void ergodox_right_led_1_set(uint8_t n) { - user_data_keyboard.led1 = n; - visualizer_set_user_data(&user_data_keyboard); -} - -void ergodox_right_led_2_set(uint8_t n) { - user_data_keyboard.led2 = n; - visualizer_set_user_data(&user_data_keyboard); -} - -void ergodox_right_led_3_set(uint8_t n) { - user_data_keyboard.led3 = n; - visualizer_set_user_data(&user_data_keyboard); -} From 05bc4880ddc9e904cfa1773caff1ae81977d2a76 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Tue, 4 Apr 2017 22:29:40 +0300 Subject: [PATCH 17/34] Tweaks to the Ergodox default visualizer No animation, display led statuses and layer name on the same screen Don't display layer bitmap Fully saturated colors for caps, less saturated ones normally --- .../ergodox/keymaps/default/visualizer.c | 76 +++++-------------- quantum/visualizer/visualizer.c | 28 ++++++- quantum/visualizer/visualizer.h | 1 + 3 files changed, 44 insertions(+), 61 deletions(-) diff --git a/keyboards/ergodox/keymaps/default/visualizer.c b/keyboards/ergodox/keymaps/default/visualizer.c index d99d5f7026..305aaae157 100644 --- a/keyboards/ergodox/keymaps/default/visualizer.c +++ b/keyboards/ergodox/keymaps/default/visualizer.c @@ -28,6 +28,7 @@ along with this program. If not, see . #include "visualizer.h" #include "system/serial_link.h" +#include "led.h" // To generate an image array like this // Ensure the image is 128 x 32 or smaller @@ -117,34 +118,11 @@ static keyframe_animation_t startup_animation = { }, }; -// The LCD animation alternates between the layer name display and a -// bitmap that displays all active layers -static keyframe_animation_t lcd_layer_bitmap_animation = { - .num_frames = 2, - .loop = true, - .frame_lengths = { - gfxMillisecondsToTicks(2000), - gfxMillisecondsToTicks(2000) - }, - .frame_functions = { - keyframe_display_layer_text, - keyframe_display_layer_bitmap - }, -}; - -static keyframe_animation_t lcd_layer_bitmap_leds_animation = { - .num_frames = 3, - .loop = true, - .frame_lengths = { - gfxMillisecondsToTicks(2000), - gfxMillisecondsToTicks(2000), - gfxMillisecondsToTicks(2000) - }, - .frame_functions = { - keyframe_display_layer_text, - keyframe_display_led_states, - keyframe_display_layer_bitmap, - }, +static keyframe_animation_t lcd_layer_display = { + .num_frames = 1, + .loop = false, + .frame_lengths = {gfxMillisecondsToTicks(0)}, + .frame_functions = {keyframe_display_layer_and_led_states} }; static keyframe_animation_t suspend_animation = { @@ -200,49 +178,31 @@ void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard // state->status.default_layer // state->status.leds (see led.h for available statuses) + uint8_t saturation = 60; + if (state->status.leds & (1u << USB_LED_CAPS_LOCK)) { + saturation = 255; + } if (state->status.layer & 0x4) { - state->target_lcd_color = LCD_COLOR(0, 0xB0, 0xFF); + state->target_lcd_color = LCD_COLOR(0, saturation, 0xFF); state->layer_text = "Media & Mouse"; } else if (state->status.layer & 0x2) { - state->target_lcd_color = LCD_COLOR(0x80, 0xB0, 0xFF); + state->target_lcd_color = LCD_COLOR(168, saturation, 0xFF); state->layer_text = "Symbol"; } else { - state->target_lcd_color = LCD_COLOR(0x40, 0xB0, 0xFF); + state->target_lcd_color = LCD_COLOR(84, saturation, 0xFF); state->layer_text = "Default"; } - if (lcd_state == LCD_STATE_INITIAL || state->status.layer != prev_status->layer) { + if (lcd_state == LCD_STATE_INITIAL || + state->status.layer != prev_status->layer || + state->status.default_layer != prev_status->default_layer || + state->status.leds != prev_status->leds) { start_keyframe_animation(&color_animation); + start_keyframe_animation(&lcd_layer_display); } - if (state->status.leds) { - if (lcd_state != LCD_STATE_BITMAP_AND_LEDS || - state->status.leds != prev_status->leds || - state->status.layer != prev_status->layer || - state->status.default_layer != prev_status->default_layer) { - - // NOTE: that it doesn't matter if the animation isn't playing, stop will do nothing in that case - stop_keyframe_animation(&lcd_layer_bitmap_animation); - - lcd_state = LCD_STATE_BITMAP_AND_LEDS; - // For information: - // The logic in this function makes sure that this doesn't happen, but if you call start on an - // animation that is already playing it will be restarted. - start_keyframe_animation(&lcd_layer_bitmap_leds_animation); - } - } else { - if (lcd_state != LCD_STATE_LAYER_BITMAP || - state->status.layer != prev_status->layer || - state->status.default_layer != prev_status->default_layer) { - - stop_keyframe_animation(&lcd_layer_bitmap_leds_animation); - - lcd_state = LCD_STATE_LAYER_BITMAP; - start_keyframe_animation(&lcd_layer_bitmap_animation); - } - } // You can also stop existing animations, and start your custom ones here // remember that you should normally have only one animation for the LCD // and one for the background. But you can also combine them if you want. diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c index 3b3f51b1ff..2533eb7090 100644 --- a/quantum/visualizer/visualizer.c +++ b/quantum/visualizer/visualizer.c @@ -364,9 +364,9 @@ bool keyframe_display_mods_bitmap(keyframe_animation_t* animation, visualizer_st return false; } -bool keyframe_display_led_states(keyframe_animation_t* animation, visualizer_state_t* state) -{ - char output[sizeof("NUM CAPS SCRL COMP KANA")]; +#define LED_STATE_STRING_SIZE sizeof("NUM CAPS SCRL COMP KANA") + +static void get_led_state_string(char* output, visualizer_state_t* state) { uint8_t pos = 0; if (state->status.leds & (1u << USB_LED_NUM_LOCK)) { @@ -390,12 +390,34 @@ bool keyframe_display_led_states(keyframe_animation_t* animation, visualizer_sta pos += 5; } output[pos] = 0; +} + +bool keyframe_display_led_states(keyframe_animation_t* animation, visualizer_state_t* state) +{ + (void)animation; + char output[LED_STATE_STRING_SIZE]; + get_led_state_string(output, state); gdispClear(White); gdispDrawString(0, 10, output, state->font_dejavusansbold12, Black); gdispFlush(); return false; } +bool keyframe_display_layer_and_led_states(keyframe_animation_t* animation, visualizer_state_t* state) { + (void)animation; + gdispClear(White); + uint8_t y = 10; + if (state->status.leds) { + char output[LED_STATE_STRING_SIZE]; + get_led_state_string(output, state); + gdispDrawString(0, 1, output, state->font_dejavusansbold12, Black); + y = 17; + } + gdispDrawString(0, y, state->layer_text, state->font_dejavusansbold12, Black); + gdispFlush(); + return false; +} + #endif // LCD_ENABLE bool keyframe_disable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state) { diff --git a/quantum/visualizer/visualizer.h b/quantum/visualizer/visualizer.h index e8ace5b37b..3b05c305e2 100644 --- a/quantum/visualizer/visualizer.h +++ b/quantum/visualizer/visualizer.h @@ -141,6 +141,7 @@ bool keyframe_display_layer_bitmap(keyframe_animation_t* animation, visualizer_s bool keyframe_display_mods_bitmap(keyframe_animation_t* animation, visualizer_state_t* state); // Displays the keyboard led states (CAPS (Caps lock), NUM (Num lock), SCRL (Scroll lock), COMP (Compose), KANA) bool keyframe_display_led_states(keyframe_animation_t* animation, visualizer_state_t* state); +bool keyframe_display_layer_and_led_states(keyframe_animation_t* animation, visualizer_state_t* state); bool keyframe_disable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state); bool keyframe_enable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state); From 05530b193f4d4476b01c2e7f882619a81194888a Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Wed, 5 Apr 2017 07:48:51 +0300 Subject: [PATCH 18/34] Delete visualizer example integration It's much better to refer to the actual code than to to try to keep some examples up to date. --- .../example_integration/callbacks.c | 36 -- .../visualizer/example_integration/gfxconf.h | 325 ------------------ .../example_integration/lcd_backlight_hal.c | 91 ----- .../example_integration/visualizer_user.c | 121 ------- 4 files changed, 573 deletions(-) delete mode 100644 quantum/visualizer/example_integration/callbacks.c delete mode 100644 quantum/visualizer/example_integration/gfxconf.h delete mode 100644 quantum/visualizer/example_integration/lcd_backlight_hal.c delete mode 100644 quantum/visualizer/example_integration/visualizer_user.c diff --git a/quantum/visualizer/example_integration/callbacks.c b/quantum/visualizer/example_integration/callbacks.c deleted file mode 100644 index 2539615d65..0000000000 --- a/quantum/visualizer/example_integration/callbacks.c +++ /dev/null @@ -1,36 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "keyboard.h" -#include "action_layer.h" -#include "visualizer.h" -#include "host.h" - -void post_keyboard_init(void) { - visualizer_init(); -} - -void post_keyboard_task() { - visualizer_set_state(default_layer_state, layer_state, host_keyboard_leds()); -} diff --git a/quantum/visualizer/example_integration/gfxconf.h b/quantum/visualizer/example_integration/gfxconf.h deleted file mode 100644 index 304c5d187a..0000000000 --- a/quantum/visualizer/example_integration/gfxconf.h +++ /dev/null @@ -1,325 +0,0 @@ -/** - * This file has a different license to the rest of the uGFX system. - * You can copy, modify and distribute this file as you see fit. - * You do not need to publish your source modifications to this file. - * The only thing you are not permitted to do is to relicense it - * under a different license. - */ - -/** - * Copy this file into your project directory and rename it as gfxconf.h - * Edit your copy to turn on the uGFX features you want to use. - * The values below are the defaults. - * - * Only remove the comments from lines where you want to change the - * default value. This allows definitions to be included from - * driver makefiles when required and provides the best future - * compatibility for your project. - * - * Please use spaces instead of tabs in this file. - */ - -#ifndef _GFXCONF_H -#define _GFXCONF_H - - -/////////////////////////////////////////////////////////////////////////// -// GOS - One of these must be defined, preferably in your Makefile // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_OS_CHIBIOS TRUE -//#define GFX_USE_OS_FREERTOS FALSE -// #define GFX_FREERTOS_USE_TRACE FALSE -//#define GFX_USE_OS_WIN32 FALSE -//#define GFX_USE_OS_LINUX FALSE -//#define GFX_USE_OS_OSX FALSE -//#define GFX_USE_OS_ECOS FALSE -//#define GFX_USE_OS_RAWRTOS FALSE -//#define GFX_USE_OS_ARDUINO FALSE -//#define GFX_USE_OS_KEIL FALSE -//#define GFX_USE_OS_CMSIS FALSE -//#define GFX_USE_OS_RAW32 FALSE -// #define INTERRUPTS_OFF() optional_code -// #define INTERRUPTS_ON() optional_code -// These are not defined by default for some reason -#define GOS_NEED_X_THREADS FALSE -#define GOS_NEED_X_HEAP FALSE - -// Options that (should where relevant) apply to all operating systems - #define GFX_NO_INLINE FALSE -// #define GFX_COMPILER GFX_COMPILER_UNKNOWN -// #define GFX_CPU GFX_CPU_UNKNOWN -// #define GFX_OS_HEAP_SIZE 0 -// #define GFX_OS_NO_INIT FALSE -// #define GFX_OS_INIT_NO_WARNING FALSE -// #define GFX_OS_PRE_INIT_FUNCTION myHardwareInitRoutine -// #define GFX_OS_EXTRA_INIT_FUNCTION myOSInitRoutine -// #define GFX_OS_EXTRA_DEINIT_FUNCTION myOSDeInitRoutine - - -/////////////////////////////////////////////////////////////////////////// -// GDISP // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GDISP TRUE - -//#define GDISP_NEED_AUTOFLUSH FALSE -//#define GDISP_NEED_TIMERFLUSH FALSE -//#define GDISP_NEED_VALIDATION TRUE -//#define GDISP_NEED_CLIP TRUE -//#define GDISP_NEED_CIRCLE FALSE -//#define GDISP_NEED_ELLIPSE FALSE -//#define GDISP_NEED_ARC FALSE -//#define GDISP_NEED_ARCSECTORS FALSE -//#define GDISP_NEED_CONVEX_POLYGON FALSE -//#define GDISP_NEED_SCROLL FALSE -//#define GDISP_NEED_PIXELREAD FALSE -//#define GDISP_NEED_CONTROL FALSE -//#define GDISP_NEED_QUERY FALSE -//#define GDISP_NEED_MULTITHREAD FALSE -//#define GDISP_NEED_STREAMING FALSE -#define GDISP_NEED_TEXT TRUE -// #define GDISP_NEED_TEXT_WORDWRAP FALSE -// #define GDISP_NEED_ANTIALIAS FALSE -// #define GDISP_NEED_UTF8 FALSE - #define GDISP_NEED_TEXT_KERNING TRUE -// #define GDISP_INCLUDE_FONT_UI1 FALSE -// #define GDISP_INCLUDE_FONT_UI2 FALSE // The smallest preferred font. -// #define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE -// #define GDISP_INCLUDE_FONT_DEJAVUSANS10 FALSE -// #define GDISP_INCLUDE_FONT_DEJAVUSANS12 FALSE -// #define GDISP_INCLUDE_FONT_DEJAVUSANS16 FALSE -// #define GDISP_INCLUDE_FONT_DEJAVUSANS20 FALSE -// #define GDISP_INCLUDE_FONT_DEJAVUSANS24 FALSE -// #define GDISP_INCLUDE_FONT_DEJAVUSANS32 FALSE - #define GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12 TRUE -// #define GDISP_INCLUDE_FONT_FIXED_10X20 FALSE -// #define GDISP_INCLUDE_FONT_FIXED_7X14 FALSE - #define GDISP_INCLUDE_FONT_FIXED_5X8 TRUE -// #define GDISP_INCLUDE_FONT_DEJAVUSANS12_AA FALSE -// #define GDISP_INCLUDE_FONT_DEJAVUSANS16_AA FALSE -// #define GDISP_INCLUDE_FONT_DEJAVUSANS20_AA FALSE -// #define GDISP_INCLUDE_FONT_DEJAVUSANS24_AA FALSE -// #define GDISP_INCLUDE_FONT_DEJAVUSANS32_AA FALSE -// #define GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12_AA FALSE -// #define GDISP_INCLUDE_USER_FONTS FALSE - -//#define GDISP_NEED_IMAGE FALSE -// #define GDISP_NEED_IMAGE_NATIVE FALSE -// #define GDISP_NEED_IMAGE_GIF FALSE -// #define GDISP_NEED_IMAGE_BMP FALSE -// #define GDISP_NEED_IMAGE_BMP_1 FALSE -// #define GDISP_NEED_IMAGE_BMP_4 FALSE -// #define GDISP_NEED_IMAGE_BMP_4_RLE FALSE -// #define GDISP_NEED_IMAGE_BMP_8 FALSE -// #define GDISP_NEED_IMAGE_BMP_8_RLE FALSE -// #define GDISP_NEED_IMAGE_BMP_16 FALSE -// #define GDISP_NEED_IMAGE_BMP_24 FALSE -// #define GDISP_NEED_IMAGE_BMP_32 FALSE -// #define GDISP_NEED_IMAGE_JPG FALSE -// #define GDISP_NEED_IMAGE_PNG FALSE -// #define GDISP_NEED_IMAGE_ACCOUNTING FALSE - -//#define GDISP_NEED_PIXMAP FALSE -// #define GDISP_NEED_PIXMAP_IMAGE FALSE - -//#define GDISP_DEFAULT_ORIENTATION GDISP_ROTATE_LANDSCAPE // If not defined the native hardware orientation is used. -//#define GDISP_LINEBUF_SIZE 128 -//#define GDISP_STARTUP_COLOR Black -#define GDISP_NEED_STARTUP_LOGO FALSE - -//#define GDISP_TOTAL_DISPLAYS 1 - -//#define GDISP_DRIVER_LIST GDISPVMT_Win32, GDISPVMT_Win32 -// #ifdef GDISP_DRIVER_LIST -// // For code and speed optimization define as TRUE or FALSE if all controllers have the same capability -// #define GDISP_HARDWARE_STREAM_WRITE FALSE -// #define GDISP_HARDWARE_STREAM_READ FALSE -// #define GDISP_HARDWARE_STREAM_POS FALSE -// #define GDISP_HARDWARE_DRAWPIXEL FALSE -// #define GDISP_HARDWARE_CLEARS FALSE -// #define GDISP_HARDWARE_FILLS FALSE -// #define GDISP_HARDWARE_BITFILLS FALSE -// #define GDISP_HARDWARE_SCROLL FALSE -// #define GDISP_HARDWARE_PIXELREAD FALSE -// #define GDISP_HARDWARE_CONTROL FALSE -// #define GDISP_HARDWARE_QUERY FALSE -// #define GDISP_HARDWARE_CLIP FALSE - - #define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB888 -// #endif - -// The custom format is not defined for some reason, so define it as error -// so we don't get compiler warnings -#define GDISP_PIXELFORMAT_CUSTOM GDISP_PIXELFORMAT_ERROR - -#define GDISP_USE_GFXNET FALSE -// #define GDISP_GFXNET_PORT 13001 -// #define GDISP_GFXNET_CUSTOM_LWIP_STARTUP FALSE -// #define GDISP_DONT_WAIT_FOR_NET_DISPLAY FALSE -// #define GDISP_GFXNET_UNSAFE_SOCKETS FALSE - - -/////////////////////////////////////////////////////////////////////////// -// GWIN // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GWIN FALSE - -//#define GWIN_NEED_WINDOWMANAGER FALSE -// #define GWIN_REDRAW_IMMEDIATE FALSE -// #define GWIN_REDRAW_SINGLEOP FALSE -// #define GWIN_NEED_FLASHING FALSE -// #define GWIN_FLASHING_PERIOD 250 - -//#define GWIN_NEED_CONSOLE FALSE -// #define GWIN_CONSOLE_USE_HISTORY FALSE -// #define GWIN_CONSOLE_HISTORY_AVERAGING FALSE -// #define GWIN_CONSOLE_HISTORY_ATCREATE FALSE -// #define GWIN_CONSOLE_ESCSEQ FALSE -// #define GWIN_CONSOLE_USE_BASESTREAM FALSE -// #define GWIN_CONSOLE_USE_FLOAT FALSE -//#define GWIN_NEED_GRAPH FALSE -//#define GWIN_NEED_GL3D FALSE - -//#define GWIN_NEED_WIDGET FALSE -//#define GWIN_FOCUS_HIGHLIGHT_WIDTH 1 -// #define GWIN_NEED_LABEL FALSE -// #define GWIN_LABEL_ATTRIBUTE FALSE -// #define GWIN_NEED_BUTTON FALSE -// #define GWIN_BUTTON_LAZY_RELEASE FALSE -// #define GWIN_NEED_SLIDER FALSE -// #define GWIN_SLIDER_NOSNAP FALSE -// #define GWIN_SLIDER_DEAD_BAND 5 -// #define GWIN_SLIDER_TOGGLE_INC 20 -// #define GWIN_NEED_CHECKBOX FALSE -// #define GWIN_NEED_IMAGE FALSE -// #define GWIN_NEED_IMAGE_ANIMATION FALSE -// #define GWIN_NEED_RADIO FALSE -// #define GWIN_NEED_LIST FALSE -// #define GWIN_NEED_LIST_IMAGES FALSE -// #define GWIN_NEED_PROGRESSBAR FALSE -// #define GWIN_PROGRESSBAR_AUTO FALSE -// #define GWIN_NEED_KEYBOARD FALSE -// #define GWIN_KEYBOARD_DEFAULT_LAYOUT VirtualKeyboard_English1 -// #define GWIN_NEED_KEYBOARD_ENGLISH1 TRUE -// #define GWIN_NEED_TEXTEDIT FALSE -// #define GWIN_FLAT_STYLING FALSE -// #define GWIN_WIDGET_TAGS FALSE - -//#define GWIN_NEED_CONTAINERS FALSE -// #define GWIN_NEED_CONTAINER FALSE -// #define GWIN_NEED_FRAME FALSE -// #define GWIN_NEED_TABSET FALSE -// #define GWIN_TABSET_TABHEIGHT 18 - - -/////////////////////////////////////////////////////////////////////////// -// GEVENT // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GEVENT FALSE - -//#define GEVENT_ASSERT_NO_RESOURCE FALSE -//#define GEVENT_MAXIMUM_SIZE 32 -//#define GEVENT_MAX_SOURCE_LISTENERS 32 - - -/////////////////////////////////////////////////////////////////////////// -// GTIMER // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GTIMER FALSE - -//#define GTIMER_THREAD_PRIORITY HIGH_PRIORITY -//#define GTIMER_THREAD_WORKAREA_SIZE 2048 - - -/////////////////////////////////////////////////////////////////////////// -// GQUEUE // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GQUEUE FALSE - -//#define GQUEUE_NEED_ASYNC FALSE -//#define GQUEUE_NEED_GSYNC FALSE -//#define GQUEUE_NEED_FSYNC FALSE -//#define GQUEUE_NEED_BUFFERS FALSE - -/////////////////////////////////////////////////////////////////////////// -// GINPUT // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GINPUT FALSE - -//#define GINPUT_NEED_MOUSE FALSE -// #define GINPUT_TOUCH_STARTRAW FALSE -// #define GINPUT_TOUCH_NOTOUCH FALSE -// #define GINPUT_TOUCH_NOCALIBRATE FALSE -// #define GINPUT_TOUCH_NOCALIBRATE_GUI FALSE -// #define GINPUT_MOUSE_POLL_PERIOD 25 -// #define GINPUT_MOUSE_CLICK_TIME 300 -// #define GINPUT_TOUCH_CXTCLICK_TIME 700 -// #define GINPUT_TOUCH_USER_CALIBRATION_LOAD FALSE -// #define GINPUT_TOUCH_USER_CALIBRATION_SAVE FALSE -// #define GMOUSE_DRIVER_LIST GMOUSEVMT_Win32, GMOUSEVMT_Win32 -//#define GINPUT_NEED_KEYBOARD FALSE -// #define GINPUT_KEYBOARD_POLL_PERIOD 200 -// #define GKEYBOARD_DRIVER_LIST GKEYBOARDVMT_Win32, GKEYBOARDVMT_Win32 -// #define GKEYBOARD_LAYOUT_OFF FALSE -// #define GKEYBOARD_LAYOUT_SCANCODE2_US FALSE -//#define GINPUT_NEED_TOGGLE FALSE -//#define GINPUT_NEED_DIAL FALSE - - -/////////////////////////////////////////////////////////////////////////// -// GFILE // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GFILE FALSE - -//#define GFILE_NEED_PRINTG FALSE -//#define GFILE_NEED_SCANG FALSE -//#define GFILE_NEED_STRINGS FALSE -//#define GFILE_NEED_FILELISTS FALSE -//#define GFILE_NEED_STDIO FALSE -//#define GFILE_NEED_NOAUTOMOUNT FALSE -//#define GFILE_NEED_NOAUTOSYNC FALSE - -//#define GFILE_NEED_MEMFS FALSE -//#define GFILE_NEED_ROMFS FALSE -//#define GFILE_NEED_RAMFS FALSE -//#define GFILE_NEED_FATFS FALSE -//#define GFILE_NEED_NATIVEFS FALSE -//#define GFILE_NEED_CHBIOSFS FALSE - -//#define GFILE_ALLOW_FLOATS FALSE -//#define GFILE_ALLOW_DEVICESPECIFIC FALSE -//#define GFILE_MAX_GFILES 3 - -/////////////////////////////////////////////////////////////////////////// -// GADC // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GADC FALSE - -//#define GADC_MAX_LOWSPEED_DEVICES 4 - - -/////////////////////////////////////////////////////////////////////////// -// GAUDIO // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GAUDIO FALSE -// There seems to be a bug in the ugfx code, the wrong define is used -// So define it in order to avoid warnings -#define GFX_USE_GAUDIN GFX_USE_GAUDIO -// #define GAUDIO_NEED_PLAY FALSE -// #define GAUDIO_NEED_RECORD FALSE - - -/////////////////////////////////////////////////////////////////////////// -// GMISC // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GMISC FALSE - -//#define GMISC_NEED_ARRAYOPS FALSE -//#define GMISC_NEED_FASTTRIG FALSE -//#define GMISC_NEED_FIXEDTRIG FALSE -//#define GMISC_NEED_INVSQRT FALSE -// #define GMISC_INVSQRT_MIXED_ENDIAN FALSE -// #define GMISC_INVSQRT_REAL_SLOW FALSE -//#define GMISC_NEED_MATRIXFLOAT2D FALSE -//#define GMISC_NEED_MATRIXFIXED2D FALSE - -#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 913131b169..0000000000 --- a/quantum/visualizer/example_integration/lcd_backlight_hal.c +++ /dev/null @@ -1,91 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "lcd_backlight.h" -#include "hal.h" - -#define RED_PIN 1 -#define GREEN_PIN 2 -#define BLUE_PIN 3 -#define CHANNEL_RED FTM0->CHANNEL[0] -#define CHANNEL_GREEN FTM0->CHANNEL[1] -#define CHANNEL_BLUE FTM0->CHANNEL[2] - -#define RGB_PORT PORTC -#define RGB_PORT_GPIO GPIOC - -// Base FTM clock selection (72 MHz system clock) -// @ 0xFFFF period, 72 MHz / (0xFFFF * 2) = Actual period -// Higher pre-scalar will use the most power (also look the best) -// Pre-scalar calculations -// 0 - 72 MHz -> 549 Hz -// 1 - 36 MHz -> 275 Hz -// 2 - 18 MHz -> 137 Hz -// 3 - 9 MHz -> 69 Hz (Slightly visible flicker) -// 4 - 4 500 kHz -> 34 Hz (Visible flickering) -// 5 - 2 250 kHz -> 17 Hz -// 6 - 1 125 kHz -> 9 Hz -// 7 - 562 500 Hz -> 4 Hz -// Using a higher pre-scalar without flicker is possible but FTM0_MOD will need to be reduced -// Which will reduce the brightness range -#define PRESCALAR_DEFINE 0 - -void lcd_backlight_hal_init(void) { - // Setup Backlight - SIM->SCGC6 |= SIM_SCGC6_FTM0; - FTM0->CNT = 0; // Reset counter - - // PWM Period - // 16-bit maximum - FTM0->MOD = 0xFFFF; - - // Set FTM to PWM output - Edge Aligned, Low-true pulses -#define CNSC_MODE FTM_SC_CPWMS | FTM_SC_PS(4) | FTM_SC_CLKS(0) - CHANNEL_RED.CnSC = CNSC_MODE; - CHANNEL_GREEN.CnSC = CNSC_MODE; - CHANNEL_BLUE.CnSC = CNSC_MODE; - - // System clock, /w prescalar setting - FTM0->SC = FTM_SC_CLKS(1) | FTM_SC_PS(PRESCALAR_DEFINE); - - CHANNEL_RED.CnV = 0; - CHANNEL_GREEN.CnV = 0; - CHANNEL_BLUE.CnV = 0; - - RGB_PORT_GPIO->PDDR |= (1 << RED_PIN); - RGB_PORT_GPIO->PDDR |= (1 << GREEN_PIN); - RGB_PORT_GPIO->PDDR |= (1 << BLUE_PIN); - -#define RGB_MODE PORTx_PCRn_SRE | PORTx_PCRn_DSE | PORTx_PCRn_MUX(4) - RGB_PORT->PCR[RED_PIN] = RGB_MODE; - RGB_PORT->PCR[GREEN_PIN] = RGB_MODE; - RGB_PORT->PCR[BLUE_PIN] = RGB_MODE; -} - -void lcd_backlight_hal_color(uint16_t r, uint16_t g, uint16_t b) { - CHANNEL_RED.CnV = r; - CHANNEL_GREEN.CnV = g; - CHANNEL_BLUE.CnV = b; -} - diff --git a/quantum/visualizer/example_integration/visualizer_user.c b/quantum/visualizer/example_integration/visualizer_user.c deleted file mode 100644 index fc09fe2eaf..0000000000 --- a/quantum/visualizer/example_integration/visualizer_user.c +++ /dev/null @@ -1,121 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -// Currently we are assuming that both the backlight and LCD are enabled -// But it's entirely possible to write a custom visualizer that use only -// one of them -#ifndef LCD_BACKLIGHT_ENABLE -#error This visualizer needs that LCD backlight is enabled -#endif - -#ifndef LCD_ENABLE -#error This visualizer needs that LCD is enabled -#endif - -#include "visualizer.h" - -static const char* welcome_text[] = {"TMK", "Infinity Ergodox"}; - -// Just an example how to write custom keyframe functions, we could have moved -// all this into the init function -bool display_welcome(keyframe_animation_t* animation, visualizer_state_t* state) { - (void)animation; - // Read the uGFX documentation for information how to use the displays - // http://wiki.ugfx.org/index.php/Main_Page - gdispClear(White); - // You can use static variables for things that can't be found in the animation - // or state structs - gdispDrawString(0, 3, welcome_text[0], state->font_dejavusansbold12, Black); - gdispDrawString(0, 15, welcome_text[1], state->font_dejavusansbold12, Black); - // Always remember to flush the display - gdispFlush(); - // you could set the backlight color as well, but we won't do it here, since - // it's part of the following animation - // lcd_backlight_color(hue, saturation, intensity); - // We don't need constant updates, just drawing the screen once is enough - return false; -} - -// Feel free to modify the animations below, or even add new ones if needed - -// Don't worry, if the startup animation is long, you can use the keyboard like normal -// during that time -static keyframe_animation_t startup_animation = { - .num_frames = 4, - .loop = false, - .frame_lengths = {0, MS2ST(1000), MS2ST(5000), 0}, - .frame_functions = {display_welcome, keyframe_animate_backlight_color, keyframe_no_operation, enable_visualization}, -}; - -// The color animation animates the LCD color when you change layers -static keyframe_animation_t color_animation = { - .num_frames = 2, - .loop = false, - // Note that there's a 200 ms no-operation frame, - // this prevents the color from changing when activating the layer - // momentarily - .frame_lengths = {MS2ST(200), MS2ST(500)}, - .frame_functions = {keyframe_no_operation, keyframe_animate_backlight_color}, -}; - -// The LCD animation alternates between the layer name display and a -// bitmap that displays all active layers -static keyframe_animation_t lcd_animation = { - .num_frames = 2, - .loop = true, - .frame_lengths = {MS2ST(2000), MS2ST(2000)}, - .frame_functions = {keyframe_display_layer_text, keyframe_display_layer_bitmap}, -}; - -void initialize_user_visualizer(visualizer_state_t* state) { - // The brightness will be dynamically adjustable in the future - // But for now, change it here. - lcd_backlight_brightness(0x50); - state->current_lcd_color = LCD_COLOR(0x00, 0x00, 0xFF); - state->target_lcd_color = LCD_COLOR(0x10, 0xFF, 0xFF); - start_keyframe_animation(&startup_animation); -} - -void update_user_visualizer_state(visualizer_state_t* state) { - // Add more tests, change the colors and layer texts here - // Usually you want to check the high bits (higher layers first) - // because that's the order layers are processed for keypresses - // You can for check for example: - // state->status.layer - // state->status.default_layer - // state->status.leds (see led.h for available statuses) - if (state->status.layer & 0x2) { - state->target_lcd_color = LCD_COLOR(0xA0, 0xB0, 0xFF); - state->layer_text = "Layer 2"; - } - else { - state->target_lcd_color = LCD_COLOR(0x50, 0xB0, 0xFF); - state->layer_text = "Layer 1"; - } - // You can also stop existing animations, and start your custom ones here - // remember that you should normally have only one animation for the LCD - // and one for the background. But you can also combine them if you want. - start_keyframe_animation(&lcd_animation); - start_keyframe_animation(&color_animation); -} From 5815c5d317b02d688990980fdf01848e81247c21 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Wed, 5 Apr 2017 08:40:39 +0300 Subject: [PATCH 19/34] Move LCD keyframes to its own file --- keyboards/ergodox/infinity/visualizer.c | 7 +- .../ergodox/keymaps/default/visualizer.c | 5 +- quantum/visualizer/lcd_keyframes.c | 160 ++++++++++++++++++ quantum/visualizer/lcd_keyframes.h | 33 ++++ quantum/visualizer/visualizer.c | 150 +--------------- quantum/visualizer/visualizer.h | 9 - quantum/visualizer/visualizer.mk | 1 + 7 files changed, 203 insertions(+), 162 deletions(-) create mode 100644 quantum/visualizer/lcd_keyframes.c create mode 100644 quantum/visualizer/lcd_keyframes.h diff --git a/keyboards/ergodox/infinity/visualizer.c b/keyboards/ergodox/infinity/visualizer.c index c7afd9384c..3abed08db0 100644 --- a/keyboards/ergodox/infinity/visualizer.c +++ b/keyboards/ergodox/infinity/visualizer.c @@ -27,6 +27,7 @@ along with this program. If not, see . #endif #include "visualizer.h" +#include "lcd_keyframes.h" #include "system/serial_link.h" // To generate an image array like this @@ -173,14 +174,14 @@ static keyframe_animation_t lcd_bitmap_animation = { .num_frames = 1, .loop = false, .frame_lengths = {gfxMillisecondsToTicks(0)}, - .frame_functions = {keyframe_display_layer_bitmap}, + .frame_functions = {lcd_keyframe_display_layer_bitmap}, }; static keyframe_animation_t lcd_bitmap_leds_animation = { .num_frames = 2, .loop = true, .frame_lengths = {gfxMillisecondsToTicks(2000), gfxMillisecondsToTicks(2000)}, - .frame_functions = {keyframe_display_layer_bitmap, keyframe_display_led_states}, + .frame_functions = {lcd_keyframe_display_layer_bitmap, lcd_keyframe_display_led_states}, }; static keyframe_animation_t suspend_animation = { @@ -188,7 +189,7 @@ static keyframe_animation_t suspend_animation = { .loop = false, .frame_lengths = {0, gfxMillisecondsToTicks(1000), 0}, .frame_functions = { - keyframe_display_layer_text, + lcd_keyframe_display_layer_text, keyframe_animate_backlight_color, keyframe_disable_lcd_and_backlight, }, diff --git a/keyboards/ergodox/keymaps/default/visualizer.c b/keyboards/ergodox/keymaps/default/visualizer.c index 305aaae157..ef87ac4195 100644 --- a/keyboards/ergodox/keymaps/default/visualizer.c +++ b/keyboards/ergodox/keymaps/default/visualizer.c @@ -27,6 +27,7 @@ along with this program. If not, see . #endif #include "visualizer.h" +#include "lcd_keyframes.h" #include "system/serial_link.h" #include "led.h" @@ -122,7 +123,7 @@ static keyframe_animation_t lcd_layer_display = { .num_frames = 1, .loop = false, .frame_lengths = {gfxMillisecondsToTicks(0)}, - .frame_functions = {keyframe_display_layer_and_led_states} + .frame_functions = {lcd_keyframe_display_layer_and_led_states} }; static keyframe_animation_t suspend_animation = { @@ -130,7 +131,7 @@ static keyframe_animation_t suspend_animation = { .loop = false, .frame_lengths = {0, gfxMillisecondsToTicks(1000), 0}, .frame_functions = { - keyframe_display_layer_text, + lcd_keyframe_display_layer_text, keyframe_animate_backlight_color, keyframe_disable_lcd_and_backlight, }, diff --git a/quantum/visualizer/lcd_keyframes.c b/quantum/visualizer/lcd_keyframes.c new file mode 100644 index 0000000000..00d9734e6a --- /dev/null +++ b/quantum/visualizer/lcd_keyframes.c @@ -0,0 +1,160 @@ +/* Copyright 2017 Fred Sundvik + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "lcd_keyframes.h" +#include +#include "action_util.h" +#include "led.h" + +bool lcd_keyframe_display_layer_text(keyframe_animation_t* animation, visualizer_state_t* state) { + (void)animation; + gdispClear(White); + gdispDrawString(0, 10, state->layer_text, state->font_dejavusansbold12, Black); + gdispFlush(); + return false; +} + +static void format_layer_bitmap_string(uint16_t default_layer, uint16_t layer, char* buffer) { + for (int i=0; i<16;i++) + { + uint32_t mask = (1u << i); + if (default_layer & mask) { + if (layer & mask) { + *buffer = 'B'; + } else { + *buffer = 'D'; + } + } else if (layer & mask) { + *buffer = '1'; + } else { + *buffer = '0'; + } + ++buffer; + + if (i==3 || i==7 || i==11) { + *buffer = ' '; + ++buffer; + } + } + *buffer = 0; +} + +bool lcd_keyframe_display_layer_bitmap(keyframe_animation_t* animation, visualizer_state_t* state) { + (void)animation; + const char* layer_help = "1=On D=Default B=Both"; + char layer_buffer[16 + 4]; // 3 spaces and one null terminator + gdispClear(White); + gdispDrawString(0, 0, layer_help, state->font_fixed5x8, Black); + format_layer_bitmap_string(state->status.default_layer, state->status.layer, layer_buffer); + gdispDrawString(0, 10, layer_buffer, state->font_fixed5x8, Black); + format_layer_bitmap_string(state->status.default_layer >> 16, state->status.layer >> 16, layer_buffer); + gdispDrawString(0, 20, layer_buffer, state->font_fixed5x8, Black); + gdispFlush(); + return false; +} + +static void format_mods_bitmap_string(uint8_t mods, char* buffer) { + *buffer = ' '; + ++buffer; + + for (int i = 0; i<8; i++) + { + uint32_t mask = (1u << i); + if (mods & mask) { + *buffer = '1'; + } else { + *buffer = '0'; + } + ++buffer; + + if (i==3) { + *buffer = ' '; + ++buffer; + } + } + *buffer = 0; +} + +bool lcd_keyframe_display_mods_bitmap(keyframe_animation_t* animation, visualizer_state_t* state) { + (void)animation; + + const char* title = "Modifier states"; + const char* mods_header = " CSAG CSAG "; + char status_buffer[12]; + + gdispClear(White); + gdispDrawString(0, 0, title, state->font_fixed5x8, Black); + gdispDrawString(0, 10, mods_header, state->font_fixed5x8, Black); + format_mods_bitmap_string(state->status.mods, status_buffer); + gdispDrawString(0, 20, status_buffer, state->font_fixed5x8, Black); + + gdispFlush(); + return false; +} + +#define LED_STATE_STRING_SIZE sizeof("NUM CAPS SCRL COMP KANA") + +static void get_led_state_string(char* output, visualizer_state_t* state) { + uint8_t pos = 0; + + if (state->status.leds & (1u << USB_LED_NUM_LOCK)) { + memcpy(output + pos, "NUM ", 4); + pos += 4; + } + if (state->status.leds & (1u << USB_LED_CAPS_LOCK)) { + memcpy(output + pos, "CAPS ", 5); + pos += 5; + } + if (state->status.leds & (1u << USB_LED_SCROLL_LOCK)) { + memcpy(output + pos, "SCRL ", 5); + pos += 5; + } + if (state->status.leds & (1u << USB_LED_COMPOSE)) { + memcpy(output + pos, "COMP ", 5); + pos += 5; + } + if (state->status.leds & (1u << USB_LED_KANA)) { + memcpy(output + pos, "KANA ", 5); + pos += 5; + } + output[pos] = 0; +} + +bool lcd_keyframe_display_led_states(keyframe_animation_t* animation, visualizer_state_t* state) +{ + (void)animation; + char output[LED_STATE_STRING_SIZE]; + get_led_state_string(output, state); + gdispClear(White); + gdispDrawString(0, 10, output, state->font_dejavusansbold12, Black); + gdispFlush(); + return false; +} + +bool lcd_keyframe_display_layer_and_led_states(keyframe_animation_t* animation, visualizer_state_t* state) { + (void)animation; + gdispClear(White); + uint8_t y = 10; + if (state->status.leds) { + char output[LED_STATE_STRING_SIZE]; + get_led_state_string(output, state); + gdispDrawString(0, 1, output, state->font_dejavusansbold12, Black); + y = 17; + } + gdispDrawString(0, y, state->layer_text, state->font_dejavusansbold12, Black); + gdispFlush(); + return false; +} diff --git a/quantum/visualizer/lcd_keyframes.h b/quantum/visualizer/lcd_keyframes.h new file mode 100644 index 0000000000..0c9f39ab8c --- /dev/null +++ b/quantum/visualizer/lcd_keyframes.h @@ -0,0 +1,33 @@ +/* Copyright 2017 Fred Sundvik + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef QUANTUM_VISUALIZER_LCD_KEYFRAMES_H_ +#define QUANTUM_VISUALIZER_LCD_KEYFRAMES_H_ + +#include "visualizer.h" + +// Displays the layer text centered vertically on the screen +bool lcd_keyframe_display_layer_text(keyframe_animation_t* animation, visualizer_state_t* state); +// Displays a bitmap (0/1) of all the currently active layers +bool lcd_keyframe_display_layer_bitmap(keyframe_animation_t* animation, visualizer_state_t* state); +// Displays a bitmap (0/1) of all the currently active mods +bool lcd_keyframe_display_mods_bitmap(keyframe_animation_t* animation, visualizer_state_t* state); +// Displays the keyboard led states (CAPS (Caps lock), NUM (Num lock), SCRL (Scroll lock), COMP (Compose), KANA) +bool lcd_keyframe_display_led_states(keyframe_animation_t* animation, visualizer_state_t* state); +// Displays both the layer text and the led states +bool lcd_keyframe_display_layer_and_led_states(keyframe_animation_t* animation, visualizer_state_t* state); + +#endif /* QUANTUM_VISUALIZER_LCD_KEYFRAMES_H_ */ diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c index 2533eb7090..514d7c44e0 100644 --- a/quantum/visualizer/visualizer.c +++ b/quantum/visualizer/visualizer.c @@ -48,16 +48,13 @@ SOFTWARE. #include "serial_link/system/serial_link.h" #endif +#include "action_util.h" + // Define this in config.h #ifndef VISUALIZER_THREAD_PRIORITY #define "Visualizer thread priority not defined" #endif -// mods status -#include "action_util.h" - -#include "led.h" - static visualizer_keyboard_status_t current_status = { .layer = 0xFFFFFFFF, .default_layer = 0xFFFFFFFF, @@ -277,149 +274,6 @@ bool keyframe_set_backlight_color(keyframe_animation_t* animation, visualizer_st } #endif // LCD_BACKLIGHT_ENABLE -#ifdef LCD_ENABLE -bool keyframe_display_layer_text(keyframe_animation_t* animation, visualizer_state_t* state) { - (void)animation; - gdispClear(White); - gdispDrawString(0, 10, state->layer_text, state->font_dejavusansbold12, Black); - gdispFlush(); - return false; -} - -static void format_layer_bitmap_string(uint16_t default_layer, uint16_t layer, char* buffer) { - for (int i=0; i<16;i++) - { - uint32_t mask = (1u << i); - if (default_layer & mask) { - if (layer & mask) { - *buffer = 'B'; - } else { - *buffer = 'D'; - } - } else if (layer & mask) { - *buffer = '1'; - } else { - *buffer = '0'; - } - ++buffer; - - if (i==3 || i==7 || i==11) { - *buffer = ' '; - ++buffer; - } - } - *buffer = 0; -} - -bool keyframe_display_layer_bitmap(keyframe_animation_t* animation, visualizer_state_t* state) { - (void)animation; - const char* layer_help = "1=On D=Default B=Both"; - char layer_buffer[16 + 4]; // 3 spaces and one null terminator - gdispClear(White); - gdispDrawString(0, 0, layer_help, state->font_fixed5x8, Black); - format_layer_bitmap_string(state->status.default_layer, state->status.layer, layer_buffer); - gdispDrawString(0, 10, layer_buffer, state->font_fixed5x8, Black); - format_layer_bitmap_string(state->status.default_layer >> 16, state->status.layer >> 16, layer_buffer); - gdispDrawString(0, 20, layer_buffer, state->font_fixed5x8, Black); - gdispFlush(); - return false; -} - -static void format_mods_bitmap_string(uint8_t mods, char* buffer) { - *buffer = ' '; - ++buffer; - - for (int i = 0; i<8; i++) - { - uint32_t mask = (1u << i); - if (mods & mask) { - *buffer = '1'; - } else { - *buffer = '0'; - } - ++buffer; - - if (i==3) { - *buffer = ' '; - ++buffer; - } - } - *buffer = 0; -} - -bool keyframe_display_mods_bitmap(keyframe_animation_t* animation, visualizer_state_t* state) { - (void)animation; - - const char* title = "Modifier states"; - const char* mods_header = " CSAG CSAG "; - char status_buffer[12]; - - gdispClear(White); - gdispDrawString(0, 0, title, state->font_fixed5x8, Black); - gdispDrawString(0, 10, mods_header, state->font_fixed5x8, Black); - format_mods_bitmap_string(state->status.mods, status_buffer); - gdispDrawString(0, 20, status_buffer, state->font_fixed5x8, Black); - - gdispFlush(); - return false; -} - -#define LED_STATE_STRING_SIZE sizeof("NUM CAPS SCRL COMP KANA") - -static void get_led_state_string(char* output, visualizer_state_t* state) { - uint8_t pos = 0; - - if (state->status.leds & (1u << USB_LED_NUM_LOCK)) { - memcpy(output + pos, "NUM ", 4); - pos += 4; - } - if (state->status.leds & (1u << USB_LED_CAPS_LOCK)) { - memcpy(output + pos, "CAPS ", 5); - pos += 5; - } - if (state->status.leds & (1u << USB_LED_SCROLL_LOCK)) { - memcpy(output + pos, "SCRL ", 5); - pos += 5; - } - if (state->status.leds & (1u << USB_LED_COMPOSE)) { - memcpy(output + pos, "COMP ", 5); - pos += 5; - } - if (state->status.leds & (1u << USB_LED_KANA)) { - memcpy(output + pos, "KANA ", 5); - pos += 5; - } - output[pos] = 0; -} - -bool keyframe_display_led_states(keyframe_animation_t* animation, visualizer_state_t* state) -{ - (void)animation; - char output[LED_STATE_STRING_SIZE]; - get_led_state_string(output, state); - gdispClear(White); - gdispDrawString(0, 10, output, state->font_dejavusansbold12, Black); - gdispFlush(); - return false; -} - -bool keyframe_display_layer_and_led_states(keyframe_animation_t* animation, visualizer_state_t* state) { - (void)animation; - gdispClear(White); - uint8_t y = 10; - if (state->status.leds) { - char output[LED_STATE_STRING_SIZE]; - get_led_state_string(output, state); - gdispDrawString(0, 1, output, state->font_dejavusansbold12, Black); - y = 17; - } - gdispDrawString(0, y, state->layer_text, state->font_dejavusansbold12, Black); - gdispFlush(); - return false; -} - -#endif // LCD_ENABLE - bool keyframe_disable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state) { (void)animation; (void)state; diff --git a/quantum/visualizer/visualizer.h b/quantum/visualizer/visualizer.h index 3b05c305e2..440044fd3d 100644 --- a/quantum/visualizer/visualizer.h +++ b/quantum/visualizer/visualizer.h @@ -133,15 +133,6 @@ bool keyframe_no_operation(keyframe_animation_t* animation, visualizer_state_t* bool keyframe_animate_backlight_color(keyframe_animation_t* animation, visualizer_state_t* state); // Sets the backlight color to the target color bool keyframe_set_backlight_color(keyframe_animation_t* animation, visualizer_state_t* state); -// Displays the layer text centered vertically on the screen -bool keyframe_display_layer_text(keyframe_animation_t* animation, visualizer_state_t* state); -// Displays a bitmap (0/1) of all the currently active layers -bool keyframe_display_layer_bitmap(keyframe_animation_t* animation, visualizer_state_t* state); -// Displays a bitmap (0/1) of all the currently active mods -bool keyframe_display_mods_bitmap(keyframe_animation_t* animation, visualizer_state_t* state); -// Displays the keyboard led states (CAPS (Caps lock), NUM (Num lock), SCRL (Scroll lock), COMP (Compose), KANA) -bool keyframe_display_led_states(keyframe_animation_t* animation, visualizer_state_t* state); -bool keyframe_display_layer_and_led_states(keyframe_animation_t* animation, visualizer_state_t* state); bool keyframe_disable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state); bool keyframe_enable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state); diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk index 3861cb1f04..325cefd6f8 100644 --- a/quantum/visualizer/visualizer.mk +++ b/quantum/visualizer/visualizer.mk @@ -34,6 +34,7 @@ endif ifeq ($(strip $(LCD_ENABLE)), yes) SRC += $(VISUALIZER_DIR)/lcd_backlight.c +SRC += $(VISUALIZER_DIR)/lcd_keyframes.c OPT_DEFS += -DLCD_BACKLIGHT_ENABLE endif From 5ba228b684a32c1099efc6207842a56ff102961a Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Wed, 5 Apr 2017 08:48:30 +0300 Subject: [PATCH 20/34] Move LCD backlight keyframes to its own file --- keyboards/ergodox/infinity/visualizer.c | 11 ++-- .../ergodox/keymaps/default/visualizer.c | 9 +-- quantum/visualizer/lcd_backlight_keyframes.c | 61 +++++++++++++++++++ quantum/visualizer/lcd_backlight_keyframes.h | 27 ++++++++ quantum/visualizer/visualizer.c | 46 -------------- quantum/visualizer/visualizer.h | 4 -- quantum/visualizer/visualizer.mk | 1 + 7 files changed, 100 insertions(+), 59 deletions(-) create mode 100644 quantum/visualizer/lcd_backlight_keyframes.c create mode 100644 quantum/visualizer/lcd_backlight_keyframes.h diff --git a/keyboards/ergodox/infinity/visualizer.c b/keyboards/ergodox/infinity/visualizer.c index 3abed08db0..bbed4e9897 100644 --- a/keyboards/ergodox/infinity/visualizer.c +++ b/keyboards/ergodox/infinity/visualizer.c @@ -28,6 +28,7 @@ along with this program. If not, see . #include "visualizer.h" #include "lcd_keyframes.h" +#include "lcd_backlight_keyframes.h" #include "system/serial_link.h" // To generate an image array like this @@ -140,7 +141,7 @@ static keyframe_animation_t startup_animation = { .frame_lengths = {0, gfxMillisecondsToTicks(10000), 0}, .frame_functions = { display_logo, - keyframe_animate_backlight_color, + backlight_keyframe_animate_color, enable_visualization }, }; @@ -150,7 +151,7 @@ static keyframe_animation_t one_led_color = { .num_frames = 1, .loop = false, .frame_lengths = {gfxMillisecondsToTicks(0)}, - .frame_functions = {keyframe_set_backlight_color}, + .frame_functions = {backlight_keyframe_set_color}, }; bool swap_led_target_color(keyframe_animation_t* animation, visualizer_state_t* state) { @@ -165,7 +166,7 @@ static keyframe_animation_t two_led_colors = { .num_frames = 2, .loop = true, .frame_lengths = {gfxMillisecondsToTicks(1000), gfxMillisecondsToTicks(0)}, - .frame_functions = {keyframe_set_backlight_color, swap_led_target_color}, + .frame_functions = {backlight_keyframe_set_color, swap_led_target_color}, }; // The LCD animation alternates between the layer name display and a @@ -190,7 +191,7 @@ static keyframe_animation_t suspend_animation = { .frame_lengths = {0, gfxMillisecondsToTicks(1000), 0}, .frame_functions = { lcd_keyframe_display_layer_text, - keyframe_animate_backlight_color, + backlight_keyframe_animate_color, keyframe_disable_lcd_and_backlight, }, }; @@ -202,7 +203,7 @@ static keyframe_animation_t resume_animation = { .frame_functions = { keyframe_enable_lcd_and_backlight, display_logo, - keyframe_animate_backlight_color, + backlight_keyframe_animate_color, enable_visualization, }, }; diff --git a/keyboards/ergodox/keymaps/default/visualizer.c b/keyboards/ergodox/keymaps/default/visualizer.c index ef87ac4195..07f5a44ab3 100644 --- a/keyboards/ergodox/keymaps/default/visualizer.c +++ b/keyboards/ergodox/keymaps/default/visualizer.c @@ -28,6 +28,7 @@ along with this program. If not, see . #include "visualizer.h" #include "lcd_keyframes.h" +#include "lcd_backlight_keyframes.h" #include "system/serial_link.h" #include "led.h" @@ -114,7 +115,7 @@ static keyframe_animation_t startup_animation = { .frame_lengths = {0, gfxMillisecondsToTicks(10000), 0}, .frame_functions = { display_logo, - keyframe_animate_backlight_color, + backlight_keyframe_animate_color, enable_visualization }, }; @@ -132,7 +133,7 @@ static keyframe_animation_t suspend_animation = { .frame_lengths = {0, gfxMillisecondsToTicks(1000), 0}, .frame_functions = { lcd_keyframe_display_layer_text, - keyframe_animate_backlight_color, + backlight_keyframe_animate_color, keyframe_disable_lcd_and_backlight, }, }; @@ -144,7 +145,7 @@ static keyframe_animation_t resume_animation = { .frame_functions = { keyframe_enable_lcd_and_backlight, display_logo, - keyframe_animate_backlight_color, + backlight_keyframe_animate_color, enable_visualization, }, }; @@ -157,7 +158,7 @@ static keyframe_animation_t color_animation = { // this prevents the color from changing when activating the layer // momentarily .frame_lengths = {gfxMillisecondsToTicks(200), gfxMillisecondsToTicks(500)}, - .frame_functions = {keyframe_no_operation, keyframe_animate_backlight_color}, + .frame_functions = {keyframe_no_operation, backlight_keyframe_animate_color}, }; void initialize_user_visualizer(visualizer_state_t* state) { diff --git a/quantum/visualizer/lcd_backlight_keyframes.c b/quantum/visualizer/lcd_backlight_keyframes.c new file mode 100644 index 0000000000..0964737087 --- /dev/null +++ b/quantum/visualizer/lcd_backlight_keyframes.c @@ -0,0 +1,61 @@ +/* Copyright 2017 Fred Sundvik + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "lcd_backlight_keyframes.h" + +bool backlight_keyframe_animate_color(keyframe_animation_t* animation, visualizer_state_t* state) { + int frame_length = animation->frame_lengths[animation->current_frame]; + int current_pos = frame_length - animation->time_left_in_frame; + uint8_t t_h = LCD_HUE(state->target_lcd_color); + uint8_t t_s = LCD_SAT(state->target_lcd_color); + uint8_t t_i = LCD_INT(state->target_lcd_color); + uint8_t p_h = LCD_HUE(state->prev_lcd_color); + uint8_t p_s = LCD_SAT(state->prev_lcd_color); + uint8_t p_i = LCD_INT(state->prev_lcd_color); + + uint8_t d_h1 = t_h - p_h; //Modulo arithmetic since we want to wrap around + int d_h2 = t_h - p_h; + // Chose the shortest way around + int d_h = abs(d_h2) < d_h1 ? d_h2 : d_h1; + int d_s = t_s - p_s; + int d_i = t_i - p_i; + + int hue = (d_h * current_pos) / frame_length; + int sat = (d_s * current_pos) / frame_length; + int intensity = (d_i * current_pos) / frame_length; + //dprintf("%X -> %X = %X\n", p_h, t_h, hue); + hue += p_h; + sat += p_s; + intensity += p_i; + state->current_lcd_color = LCD_COLOR(hue, sat, intensity); + lcd_backlight_color( + LCD_HUE(state->current_lcd_color), + LCD_SAT(state->current_lcd_color), + LCD_INT(state->current_lcd_color)); + + return true; +} + +bool backlight_keyframe_set_color(keyframe_animation_t* animation, visualizer_state_t* state) { + (void)animation; + state->prev_lcd_color = state->target_lcd_color; + state->current_lcd_color = state->target_lcd_color; + lcd_backlight_color( + LCD_HUE(state->current_lcd_color), + LCD_SAT(state->current_lcd_color), + LCD_INT(state->current_lcd_color)); + return false; +} diff --git a/quantum/visualizer/lcd_backlight_keyframes.h b/quantum/visualizer/lcd_backlight_keyframes.h new file mode 100644 index 0000000000..8cd5a46c6a --- /dev/null +++ b/quantum/visualizer/lcd_backlight_keyframes.h @@ -0,0 +1,27 @@ +/* Copyright 2017 Fred Sundvik + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef QUANTUM_VISUALIZER_LCD_BACKLIGHT_KEYFRAMES_H_ +#define QUANTUM_VISUALIZER_LCD_BACKLIGHT_KEYFRAMES_H_ + +#include "visualizer.h" + +// Animates the LCD backlight color between the current color and the target color (of the state) +bool backlight_keyframe_animate_color(keyframe_animation_t* animation, visualizer_state_t* state); +// Sets the backlight color to the target color +bool backlight_keyframe_set_color(keyframe_animation_t* animation, visualizer_state_t* state); + +#endif /* QUANTUM_VISUALIZER_LCD_BACKLIGHT_KEYFRAMES_H_ */ diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c index 514d7c44e0..6ebd806e40 100644 --- a/quantum/visualizer/visualizer.c +++ b/quantum/visualizer/visualizer.c @@ -228,52 +228,6 @@ bool keyframe_no_operation(keyframe_animation_t* animation, visualizer_state_t* return false; } -#ifdef LCD_BACKLIGHT_ENABLE -bool keyframe_animate_backlight_color(keyframe_animation_t* animation, visualizer_state_t* state) { - int frame_length = animation->frame_lengths[animation->current_frame]; - int current_pos = frame_length - animation->time_left_in_frame; - uint8_t t_h = LCD_HUE(state->target_lcd_color); - uint8_t t_s = LCD_SAT(state->target_lcd_color); - uint8_t t_i = LCD_INT(state->target_lcd_color); - uint8_t p_h = LCD_HUE(state->prev_lcd_color); - uint8_t p_s = LCD_SAT(state->prev_lcd_color); - uint8_t p_i = LCD_INT(state->prev_lcd_color); - - uint8_t d_h1 = t_h - p_h; //Modulo arithmetic since we want to wrap around - int d_h2 = t_h - p_h; - // Chose the shortest way around - int d_h = abs(d_h2) < d_h1 ? d_h2 : d_h1; - int d_s = t_s - p_s; - int d_i = t_i - p_i; - - int hue = (d_h * current_pos) / frame_length; - int sat = (d_s * current_pos) / frame_length; - int intensity = (d_i * current_pos) / frame_length; - //dprintf("%X -> %X = %X\n", p_h, t_h, hue); - hue += p_h; - sat += p_s; - intensity += p_i; - state->current_lcd_color = LCD_COLOR(hue, sat, intensity); - lcd_backlight_color( - LCD_HUE(state->current_lcd_color), - LCD_SAT(state->current_lcd_color), - LCD_INT(state->current_lcd_color)); - - return true; -} - -bool keyframe_set_backlight_color(keyframe_animation_t* animation, visualizer_state_t* state) { - (void)animation; - state->prev_lcd_color = state->target_lcd_color; - state->current_lcd_color = state->target_lcd_color; - lcd_backlight_color( - LCD_HUE(state->current_lcd_color), - LCD_SAT(state->current_lcd_color), - LCD_INT(state->current_lcd_color)); - return false; -} -#endif // LCD_BACKLIGHT_ENABLE - bool keyframe_disable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state) { (void)animation; (void)state; diff --git a/quantum/visualizer/visualizer.h b/quantum/visualizer/visualizer.h index 440044fd3d..5c870dbfe9 100644 --- a/quantum/visualizer/visualizer.h +++ b/quantum/visualizer/visualizer.h @@ -129,10 +129,6 @@ void run_next_keyframe(keyframe_animation_t* animation, visualizer_state_t* stat // Some predefined keyframe functions that can be used by the user code // Does nothing, useful for adding delays bool keyframe_no_operation(keyframe_animation_t* animation, visualizer_state_t* state); -// Animates the LCD backlight color between the current color and the target color (of the state) -bool keyframe_animate_backlight_color(keyframe_animation_t* animation, visualizer_state_t* state); -// Sets the backlight color to the target color -bool keyframe_set_backlight_color(keyframe_animation_t* animation, visualizer_state_t* state); bool keyframe_disable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state); bool keyframe_enable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state); diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk index 325cefd6f8..c9eb8c5bbd 100644 --- a/quantum/visualizer/visualizer.mk +++ b/quantum/visualizer/visualizer.mk @@ -35,6 +35,7 @@ endif ifeq ($(strip $(LCD_ENABLE)), yes) SRC += $(VISUALIZER_DIR)/lcd_backlight.c SRC += $(VISUALIZER_DIR)/lcd_keyframes.c +SRC += $(VISUALIZER_DIR)/lcd_backlight_keyframes.c OPT_DEFS += -DLCD_BACKLIGHT_ENABLE endif From 1e7585e76771e1a2d8ca733fc09c19f9fa0e903c Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Wed, 5 Apr 2017 09:21:18 +0300 Subject: [PATCH 21/34] Separated backlight and LCD disable/enable Also moved them to correct places --- keyboards/ergodox/infinity/visualizer.c | 14 +++++++------ .../ergodox/keymaps/default/visualizer.c | 14 +++++++------ quantum/visualizer/lcd_backlight_keyframes.c | 16 ++++++++++++++ quantum/visualizer/lcd_backlight_keyframes.h | 3 +++ quantum/visualizer/lcd_keyframes.c | 14 +++++++++++++ quantum/visualizer/lcd_keyframes.h | 4 ++++ quantum/visualizer/visualizer.c | 21 ------------------- quantum/visualizer/visualizer.h | 3 --- 8 files changed, 53 insertions(+), 36 deletions(-) diff --git a/keyboards/ergodox/infinity/visualizer.c b/keyboards/ergodox/infinity/visualizer.c index bbed4e9897..8e684d9919 100644 --- a/keyboards/ergodox/infinity/visualizer.c +++ b/keyboards/ergodox/infinity/visualizer.c @@ -186,22 +186,24 @@ static keyframe_animation_t lcd_bitmap_leds_animation = { }; static keyframe_animation_t suspend_animation = { - .num_frames = 3, + .num_frames = 4, .loop = false, - .frame_lengths = {0, gfxMillisecondsToTicks(1000), 0}, + .frame_lengths = {0, gfxMillisecondsToTicks(1000), 0, 0}, .frame_functions = { lcd_keyframe_display_layer_text, backlight_keyframe_animate_color, - keyframe_disable_lcd_and_backlight, + lcd_keyframe_disable, + lcd_keyframe_disable, }, }; static keyframe_animation_t resume_animation = { - .num_frames = 4, + .num_frames = 5, .loop = false, - .frame_lengths = {0, 0, gfxMillisecondsToTicks(10000), 0}, + .frame_lengths = {0, 0, 0, gfxMillisecondsToTicks(10000), 0}, .frame_functions = { - keyframe_enable_lcd_and_backlight, + lcd_keyframe_enable, + backlight_keyframe_enable, display_logo, backlight_keyframe_animate_color, enable_visualization, diff --git a/keyboards/ergodox/keymaps/default/visualizer.c b/keyboards/ergodox/keymaps/default/visualizer.c index 07f5a44ab3..5ee49c9bc2 100644 --- a/keyboards/ergodox/keymaps/default/visualizer.c +++ b/keyboards/ergodox/keymaps/default/visualizer.c @@ -128,22 +128,24 @@ static keyframe_animation_t lcd_layer_display = { }; static keyframe_animation_t suspend_animation = { - .num_frames = 3, + .num_frames = 4, .loop = false, - .frame_lengths = {0, gfxMillisecondsToTicks(1000), 0}, + .frame_lengths = {0, gfxMillisecondsToTicks(1000), 0, 0}, .frame_functions = { lcd_keyframe_display_layer_text, backlight_keyframe_animate_color, - keyframe_disable_lcd_and_backlight, + lcd_keyframe_disable, + lcd_keyframe_disable, }, }; static keyframe_animation_t resume_animation = { - .num_frames = 4, + .num_frames = 5, .loop = false, - .frame_lengths = {0, 0, gfxMillisecondsToTicks(10000), 0}, + .frame_lengths = {0, 0, 0, gfxMillisecondsToTicks(10000), 0}, .frame_functions = { - keyframe_enable_lcd_and_backlight, + lcd_keyframe_enable, + backlight_keyframe_enable, display_logo, backlight_keyframe_animate_color, enable_visualization, diff --git a/quantum/visualizer/lcd_backlight_keyframes.c b/quantum/visualizer/lcd_backlight_keyframes.c index 0964737087..8436d4e3dd 100644 --- a/quantum/visualizer/lcd_backlight_keyframes.c +++ b/quantum/visualizer/lcd_backlight_keyframes.c @@ -59,3 +59,19 @@ bool backlight_keyframe_set_color(keyframe_animation_t* animation, visualizer_st LCD_INT(state->current_lcd_color)); return false; } + +bool backlight_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) { + (void)animation; + (void)state; + lcd_backlight_hal_color(0, 0, 0); + return false; +} + +bool backlight_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) { + (void)animation; + (void)state; + lcd_backlight_color(LCD_HUE(state->current_lcd_color), + LCD_SAT(state->current_lcd_color), + LCD_INT(state->current_lcd_color)); + return false; +} diff --git a/quantum/visualizer/lcd_backlight_keyframes.h b/quantum/visualizer/lcd_backlight_keyframes.h index 8cd5a46c6a..e1c125cf91 100644 --- a/quantum/visualizer/lcd_backlight_keyframes.h +++ b/quantum/visualizer/lcd_backlight_keyframes.h @@ -24,4 +24,7 @@ bool backlight_keyframe_animate_color(keyframe_animation_t* animation, visualize // Sets the backlight color to the target color bool backlight_keyframe_set_color(keyframe_animation_t* animation, visualizer_state_t* state); +bool backlight_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state); +bool backlight_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state); + #endif /* QUANTUM_VISUALIZER_LCD_BACKLIGHT_KEYFRAMES_H_ */ diff --git a/quantum/visualizer/lcd_keyframes.c b/quantum/visualizer/lcd_keyframes.c index 00d9734e6a..74f6e3b470 100644 --- a/quantum/visualizer/lcd_keyframes.c +++ b/quantum/visualizer/lcd_keyframes.c @@ -158,3 +158,17 @@ bool lcd_keyframe_display_layer_and_led_states(keyframe_animation_t* animation, gdispFlush(); return false; } + +bool lcd_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) { + (void)animation; + (void)state; + gdispSetPowerMode(powerOff); + return false; +} + +bool lcd_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) { + (void)animation; + (void)state; + gdispSetPowerMode(powerOn); + return false; +} diff --git a/quantum/visualizer/lcd_keyframes.h b/quantum/visualizer/lcd_keyframes.h index 0c9f39ab8c..8f79a541c8 100644 --- a/quantum/visualizer/lcd_keyframes.h +++ b/quantum/visualizer/lcd_keyframes.h @@ -30,4 +30,8 @@ bool lcd_keyframe_display_led_states(keyframe_animation_t* animation, visualizer // Displays both the layer text and the led states bool lcd_keyframe_display_layer_and_led_states(keyframe_animation_t* animation, visualizer_state_t* state); +bool lcd_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state); +bool lcd_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state); + + #endif /* QUANTUM_VISUALIZER_LCD_KEYFRAMES_H_ */ diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c index 6ebd806e40..98cd7ba554 100644 --- a/quantum/visualizer/visualizer.c +++ b/quantum/visualizer/visualizer.c @@ -228,27 +228,6 @@ bool keyframe_no_operation(keyframe_animation_t* animation, visualizer_state_t* return false; } -bool keyframe_disable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state) { - (void)animation; - (void)state; -#ifdef LCD_ENABLE - gdispSetPowerMode(powerOff); -#endif -#ifdef LCD_BACKLIGHT_ENABLE - lcd_backlight_hal_color(0, 0, 0); -#endif - return false; -} - -bool keyframe_enable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state) { - (void)animation; - (void)state; -#ifdef LCD_ENABLE - gdispSetPowerMode(powerOn); -#endif - return false; -} - bool enable_visualization(keyframe_animation_t* animation, visualizer_state_t* state) { (void)animation; (void)state; diff --git a/quantum/visualizer/visualizer.h b/quantum/visualizer/visualizer.h index 5c870dbfe9..f37ce8416e 100644 --- a/quantum/visualizer/visualizer.h +++ b/quantum/visualizer/visualizer.h @@ -130,9 +130,6 @@ void run_next_keyframe(keyframe_animation_t* animation, visualizer_state_t* stat // Does nothing, useful for adding delays bool keyframe_no_operation(keyframe_animation_t* animation, visualizer_state_t* state); -bool keyframe_disable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state); -bool keyframe_enable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state); - // Call this once, when the initial animation has finished, alternatively you can call it // directly from the initalize_user_visualizer function (the animation can be null) bool enable_visualization(keyframe_animation_t* animation, visualizer_state_t* state); From 64d63ab42281318d891434fbc00277043298dd70 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Wed, 5 Apr 2017 10:08:25 +0300 Subject: [PATCH 22/34] Remove the need to manually enable the visualizer --- keyboards/ergodox/infinity/visualizer.c | 6 ++-- .../ergodox/keymaps/default/visualizer.c | 6 ++-- quantum/visualizer/visualizer.c | 28 ++++++++++--------- quantum/visualizer/visualizer.h | 14 ++++++---- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/keyboards/ergodox/infinity/visualizer.c b/keyboards/ergodox/infinity/visualizer.c index 8e684d9919..0897ea348b 100644 --- a/keyboards/ergodox/infinity/visualizer.c +++ b/keyboards/ergodox/infinity/visualizer.c @@ -136,13 +136,12 @@ bool display_logo(keyframe_animation_t* animation, visualizer_state_t* state) { // Don't worry, if the startup animation is long, you can use the keyboard like normal // during that time static keyframe_animation_t startup_animation = { - .num_frames = 3, + .num_frames = 2, .loop = false, .frame_lengths = {0, gfxMillisecondsToTicks(10000), 0}, .frame_functions = { display_logo, backlight_keyframe_animate_color, - enable_visualization }, }; @@ -198,7 +197,7 @@ static keyframe_animation_t suspend_animation = { }; static keyframe_animation_t resume_animation = { - .num_frames = 5, + .num_frames = 4, .loop = false, .frame_lengths = {0, 0, 0, gfxMillisecondsToTicks(10000), 0}, .frame_functions = { @@ -206,7 +205,6 @@ static keyframe_animation_t resume_animation = { backlight_keyframe_enable, display_logo, backlight_keyframe_animate_color, - enable_visualization, }, }; diff --git a/keyboards/ergodox/keymaps/default/visualizer.c b/keyboards/ergodox/keymaps/default/visualizer.c index 5ee49c9bc2..73d864c646 100644 --- a/keyboards/ergodox/keymaps/default/visualizer.c +++ b/keyboards/ergodox/keymaps/default/visualizer.c @@ -110,13 +110,12 @@ bool display_logo(keyframe_animation_t* animation, visualizer_state_t* state) { // Don't worry, if the startup animation is long, you can use the keyboard like normal // during that time static keyframe_animation_t startup_animation = { - .num_frames = 3, + .num_frames = 2, .loop = false, .frame_lengths = {0, gfxMillisecondsToTicks(10000), 0}, .frame_functions = { display_logo, backlight_keyframe_animate_color, - enable_visualization }, }; @@ -140,7 +139,7 @@ static keyframe_animation_t suspend_animation = { }; static keyframe_animation_t resume_animation = { - .num_frames = 5, + .num_frames = 4, .loop = false, .frame_lengths = {0, 0, 0, gfxMillisecondsToTicks(10000), 0}, .frame_functions = { @@ -148,7 +147,6 @@ static keyframe_animation_t resume_animation = { backlight_keyframe_enable, display_logo, backlight_keyframe_animate_color, - enable_visualization, }, }; diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c index 98cd7ba554..5fbd12031e 100644 --- a/quantum/visualizer/visualizer.c +++ b/quantum/visualizer/visualizer.c @@ -154,6 +154,14 @@ void stop_all_keyframe_animations(void) { } } +static uint8_t get_num_running_animations(void) { + uint8_t count = 0; + for (int i=0;icurrent_frame, @@ -228,14 +236,6 @@ bool keyframe_no_operation(keyframe_animation_t* animation, visualizer_state_t* return false; } -bool enable_visualization(keyframe_animation_t* animation, visualizer_state_t* state) { - (void)animation; - (void)state; - dprint("User visualizer inited\n"); - visualizer_enabled = true; - return false; -} - // TODO: Optimize the stack size, this is probably way too big static DECLARE_THREAD_STACK(visualizerThreadStack, 1024); static DECLARE_THREAD_FUNCTION(visualizerThread, arg) { @@ -276,13 +276,15 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) { systemticks_t sleep_time = TIME_INFINITE; systemticks_t current_time = gfxSystemTicks(); + bool force_update = true; while(true) { systemticks_t new_time = gfxSystemTicks(); systemticks_t delta = new_time - current_time; current_time = new_time; bool enabled = visualizer_enabled; - if (!same_status(&state.status, ¤t_status)) { + if (force_update || !same_status(&state.status, ¤t_status)) { + force_update = false; if (visualizer_enabled) { if (current_status.suspended) { stop_all_keyframe_animations(); @@ -320,10 +322,10 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) { #ifdef EMULATOR draw_emulator(); #endif - // The animation can enable the visualizer - // And we might need to update the state when that happens - // so don't sleep - if (enabled != visualizer_enabled) { + // Enable the visualizer when the startup or the suspend animation has finished + if (!visualizer_enabled && state.status.suspended == false && get_num_running_animations() == 0) { + visualizer_enabled = true; + force_update = true; sleep_time = 0; } diff --git a/quantum/visualizer/visualizer.h b/quantum/visualizer/visualizer.h index f37ce8416e..4639348492 100644 --- a/quantum/visualizer/visualizer.h +++ b/quantum/visualizer/visualizer.h @@ -130,20 +130,22 @@ void run_next_keyframe(keyframe_animation_t* animation, visualizer_state_t* stat // Does nothing, useful for adding delays bool keyframe_no_operation(keyframe_animation_t* animation, visualizer_state_t* state); -// Call this once, when the initial animation has finished, alternatively you can call it -// directly from the initalize_user_visualizer function (the animation can be null) -bool enable_visualization(keyframe_animation_t* animation, visualizer_state_t* state); - // The master can set userdata which will be transferred to the slave #ifdef VISUALIZER_USER_DATA_SIZE void visualizer_set_user_data(void* user_data); #endif // These functions have to be implemented by the user -void initialize_user_visualizer(visualizer_state_t* state); +// Called regularly each time the state has changed (but not every scan loop) void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status); +// Called when the computer goes to suspend, will also stop calling update_user_visualizer_state void user_visualizer_suspend(visualizer_state_t* state); +// You have to start at least one animation as a response to the following two functions +// When the animation has finished the visualizer will resume normal operation and start calling the +// update_user_visualizer_state again +// Called when the keyboard boots up +void initialize_user_visualizer(visualizer_state_t* state); +// Called when the computer resumes from a suspend void user_visualizer_resume(visualizer_state_t* state); - #endif /* VISUALIZER_H */ From b7041d06aef4dcf2f2a47504a699e538cfb1d9ac Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Wed, 5 Apr 2017 10:14:24 +0300 Subject: [PATCH 23/34] Move common visualizer keyframes into visualizer_keyframes.h --- keyboards/ergodox/infinity/visualizer.c | 1 + .../ergodox/keymaps/default/visualizer.c | 1 + quantum/visualizer/visualizer.c | 6 ----- quantum/visualizer/visualizer.h | 6 +---- quantum/visualizer/visualizer.mk | 3 ++- quantum/visualizer/visualizer_keyframes.c | 23 ++++++++++++++++ quantum/visualizer/visualizer_keyframes.h | 26 +++++++++++++++++++ 7 files changed, 54 insertions(+), 12 deletions(-) create mode 100644 quantum/visualizer/visualizer_keyframes.c create mode 100644 quantum/visualizer/visualizer_keyframes.h diff --git a/keyboards/ergodox/infinity/visualizer.c b/keyboards/ergodox/infinity/visualizer.c index 0897ea348b..2e10fdd709 100644 --- a/keyboards/ergodox/infinity/visualizer.c +++ b/keyboards/ergodox/infinity/visualizer.c @@ -27,6 +27,7 @@ along with this program. If not, see . #endif #include "visualizer.h" +#include "visualizer_keyframes.h" #include "lcd_keyframes.h" #include "lcd_backlight_keyframes.h" #include "system/serial_link.h" diff --git a/keyboards/ergodox/keymaps/default/visualizer.c b/keyboards/ergodox/keymaps/default/visualizer.c index 73d864c646..f6159e1ef1 100644 --- a/keyboards/ergodox/keymaps/default/visualizer.c +++ b/keyboards/ergodox/keymaps/default/visualizer.c @@ -27,6 +27,7 @@ along with this program. If not, see . #endif #include "visualizer.h" +#include "visualizer_keyframes.h" #include "lcd_keyframes.h" #include "lcd_backlight_keyframes.h" #include "system/serial_link.h" diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c index 5fbd12031e..2479a64c7f 100644 --- a/quantum/visualizer/visualizer.c +++ b/quantum/visualizer/visualizer.c @@ -230,12 +230,6 @@ void run_next_keyframe(keyframe_animation_t* animation, visualizer_state_t* stat (*temp_animation.frame_functions[next_frame])(&temp_animation, &temp_state); } -bool keyframe_no_operation(keyframe_animation_t* animation, visualizer_state_t* state) { - (void)animation; - (void)state; - return false; -} - // TODO: Optimize the stack size, this is probably way too big static DECLARE_THREAD_STACK(visualizerThreadStack, 1024); static DECLARE_THREAD_FUNCTION(visualizerThread, arg) { diff --git a/quantum/visualizer/visualizer.h b/quantum/visualizer/visualizer.h index 4639348492..d6f279e101 100644 --- a/quantum/visualizer/visualizer.h +++ b/quantum/visualizer/visualizer.h @@ -34,7 +34,7 @@ SOFTWARE. #include "lcd_backlight.h" #endif -// use this function to merget both real_mods and oneshot_mods in a uint16_t +// use this function to merge both real_mods and oneshot_mods in a uint16_t uint8_t visualizer_get_mods(void); // This need to be called once at the start @@ -126,10 +126,6 @@ void stop_keyframe_animation(keyframe_animation_t* animation); // Useful for crossfades for example void run_next_keyframe(keyframe_animation_t* animation, visualizer_state_t* state); -// Some predefined keyframe functions that can be used by the user code -// Does nothing, useful for adding delays -bool keyframe_no_operation(keyframe_animation_t* animation, visualizer_state_t* state); - // The master can set userdata which will be transferred to the slave #ifdef VISUALIZER_USER_DATA_SIZE void visualizer_set_user_data(void* user_data); diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk index c9eb8c5bbd..799379e3d6 100644 --- a/quantum/visualizer/visualizer.mk +++ b/quantum/visualizer/visualizer.mk @@ -20,7 +20,8 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -SRC += $(VISUALIZER_DIR)/visualizer.c +SRC += $(VISUALIZER_DIR)/visualizer.c \ + $(VISUALIZER_DIR)/visualizer_keyframes.c EXTRAINCDIRS += $(GFXINC) $(VISUALIZER_DIR) GFXLIB = $(LIB_PATH)/ugfx VPATH += $(VISUALIZER_PATH) diff --git a/quantum/visualizer/visualizer_keyframes.c b/quantum/visualizer/visualizer_keyframes.c new file mode 100644 index 0000000000..8f6a7e15a4 --- /dev/null +++ b/quantum/visualizer/visualizer_keyframes.c @@ -0,0 +1,23 @@ +/* Copyright 2017 Fred Sundvik + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "visualizer_keyframes.h" + +bool keyframe_no_operation(keyframe_animation_t* animation, visualizer_state_t* state) { + (void)animation; + (void)state; + return false; +} diff --git a/quantum/visualizer/visualizer_keyframes.h b/quantum/visualizer/visualizer_keyframes.h new file mode 100644 index 0000000000..9ef7653c5e --- /dev/null +++ b/quantum/visualizer/visualizer_keyframes.h @@ -0,0 +1,26 @@ +/* Copyright 2017 Fred Sundvik + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef QUANTUM_VISUALIZER_VISUALIZER_KEYFRAMES_H_ +#define QUANTUM_VISUALIZER_VISUALIZER_KEYFRAMES_H_ + +#include "visualizer.h" + +// Some predefined keyframe functions that can be used by the user code +// Does nothing, useful for adding delays +bool keyframe_no_operation(keyframe_animation_t* animation, visualizer_state_t* state); + +#endif /* QUANTUM_VISUALIZER_VISUALIZER_KEYFRAMES_H_ */ From 3994fb1e79615af849aa03378293831f59c9b259 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Fri, 7 Apr 2017 10:51:53 +0300 Subject: [PATCH 24/34] Yet another try to fix the LCD corruption It turns out that the ChibiOS K20 SPI driver doesn't handle the chip select, so it needs to be done manually. Acquiring the bus is not enough since the pin was in the wrong mode. This is now fixed. Also increase the frequency of the SPI from around 200kHz to nearly 20 Mhz. --- .../gdisp/st7565ergodox/board_ST7565.h | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/board_ST7565.h b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/board_ST7565.h index c2092b5e8d..e8c17e6e33 100644 --- a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/board_ST7565.h +++ b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/board_ST7565.h @@ -45,15 +45,28 @@ static const SPIConfig spi1config = { .sspad=ST7565_SS_PIN, // SPI initialization data. .tar0 = - SPIx_CTARn_FMSZ(7) - | SPIx_CTARn_ASC(7) - | SPIx_CTARn_DT(7) - | SPIx_CTARn_CSSCK(7) - | SPIx_CTARn_PBR(0) - | SPIx_CTARn_BR(7) - //SPI_CR1_BR_0 + SPIx_CTARn_FMSZ(7) // Frame size = 8 bytes + | SPIx_CTARn_ASC(1) // After SCK Delay Scaler (min 50 ns) = 55.56ns + | SPIx_CTARn_DT(0) // Delay After Transfer Scaler (no minimum)= 27.78ns + | SPIx_CTARn_CSSCK(0) // PCS to SCK Delay Scaler (min 20 ns) = 27.78ns + | SPIx_CTARn_PBR(0) // Baud Rate Prescaler = 2 + | SPIx_CTARn_BR(0) // Baud rate (min 50ns) = 55.56ns }; +static GFXINLINE void acquire_bus(GDisplay *g) { + (void) g; + // Only the LCD is using the SPI bus, so no need to acquire + // spiAcquireBus(&SPID1); + spiSelect(&SPID1); +} + +static GFXINLINE void release_bus(GDisplay *g) { + (void) g; + // Only the LCD is using the SPI bus, so no need to release + //spiReleaseBus(&SPID1); + spiUnselect(&SPID1); +} + static GFXINLINE void init_board(GDisplay *g) { (void) g; palSetPadModeNamed(A0, PAL_MODE_OUTPUT_PUSHPULL); @@ -62,10 +75,11 @@ static GFXINLINE void init_board(GDisplay *g) { palSetPad(ST7565_GPIOPORT, ST7565_RST_PIN); palSetPadModeRaw(MOSI, ST7565_SPI_MODE); palSetPadModeRaw(SLCK, ST7565_SPI_MODE); - palSetPadModeRaw(SS, ST7565_SPI_MODE); + palSetPadModeRaw(SS, PAL_MODE_OUTPUT_PUSHPULL); spiInit(); spiStart(&SPID1, &spi1config); + release_bus(g); } static GFXINLINE void post_init_board(GDisplay *g) { @@ -82,20 +96,6 @@ static GFXINLINE void setpin_reset(GDisplay *g, bool_t state) { } } -static GFXINLINE void acquire_bus(GDisplay *g) { - (void) g; - // Only the LCD is using the SPI bus, so no need to acquire - // spiAcquireBus(&SPID1); - spiSelect(&SPID1); -} - -static GFXINLINE void release_bus(GDisplay *g) { - (void) g; - // Only the LCD is using the SPI bus, so no need to release - //spiReleaseBus(&SPID1); - spiUnselect(&SPID1); -} - static GFXINLINE void enter_data_mode(GDisplay *g) { palSetPad(ST7565_GPIOPORT, ST7565_A0_PIN); } From 995002fa912545128625ec2d8c53cff5de560b97 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Fri, 7 Apr 2017 10:55:29 +0300 Subject: [PATCH 25/34] LCD initialization sequence according to the docs The LCD initialization show now be much better and faster with no flickering at the startup. Also fix the contrast control. --- .../gdisp/st7565ergodox/gdisp_lld_ST7565.c | 40 +++++-------------- .../drivers/gdisp/st7565ergodox/st7565.h | 2 + 2 files changed, 13 insertions(+), 29 deletions(-) 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 2c8a168e76..0de457a7ae 100644 --- a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c +++ b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c @@ -26,7 +26,7 @@ #define GDISP_SCREEN_WIDTH 128 #endif #ifndef GDISP_INITIAL_CONTRAST -#define GDISP_INITIAL_CONTRAST 0 +#define GDISP_INITIAL_CONTRAST 35 #endif #ifndef GDISP_INITIAL_BACKLIGHT #define GDISP_INITIAL_BACKLIGHT 100 @@ -111,41 +111,25 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { gfxSleepMilliseconds(20); setpin_reset(g, FALSE); gfxSleepMilliseconds(20); - acquire_bus(g); enter_cmd_mode(g); - write_cmd(g, ST7565_DISPLAY_OFF); + + write_cmd(g, ST7565_RESET); write_cmd(g, ST7565_LCD_BIAS); write_cmd(g, ST7565_ADC); write_cmd(g, ST7565_COM_SCAN); - write_cmd(g, ST7565_START_LINE | 0); + write_cmd(g, ST7565_RESISTOR_RATIO | 0x1); + write_cmd2(g, ST7565_CONTRAST, GDISP_INITIAL_CONTRAST); - write_cmd(g, ST7565_RESISTOR_RATIO | 0x6); - - // turn on voltage converter (VC=1, VR=0, VF=0) - write_cmd(g, ST7565_POWER_CONTROL | 0x04); - flush_cmd(g); - delay_ms(50); - - // turn on voltage regulator (VC=1, VR=1, VF=0) - write_cmd(g, ST7565_POWER_CONTROL | 0x06); - flush_cmd(g); - delay_ms(50); - - // turn on voltage follower (VC=1, VR=1, VF=1) + // turn on internal power supply (VC=1, VR=1, VF=1) write_cmd(g, ST7565_POWER_CONTROL | 0x07); - flush_cmd(g); - delay_ms(50); - write_cmd(g, 0xE2); - write_cmd(g, ST7565_COM_SCAN); - write_cmd2(g, ST7565_CONTRAST, GDISP_INITIAL_CONTRAST*64/101); - //write_cmd2(g, ST7565_CONTRAST, 0); - write_cmd(g, ST7565_DISPLAY_ON); - write_cmd(g, ST7565_ALLON_NORMAL); write_cmd(g, ST7565_INVERT_DISPLAY); + write_cmd(g, ST7565_ALLON_NORMAL); + write_cmd(g, ST7565_DISPLAY_ON); + write_cmd(g, ST7565_START_LINE | 0); write_cmd(g, ST7565_RMW); flush_cmd(g); @@ -331,14 +315,12 @@ LLDSPEC void gdisp_lld_control(GDisplay *g) { return; case GDISP_CONTROL_CONTRAST: - if ((unsigned)g->p.ptr > 100) - g->p.ptr = (void *)100; + g->g.Contrast = (unsigned)g->p.ptr & 63; acquire_bus(g); enter_cmd_mode(g); - write_cmd2(g, ST7565_CONTRAST, ((((unsigned)g->p.ptr)<<6)/101) & 0x3F); + write_cmd2(g, ST7565_CONTRAST, g->g.Contrast); flush_cmd(g); release_bus(g); - g->g.Contrast = (unsigned)g->p.ptr; return; } } diff --git a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/st7565.h b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/st7565.h index 48636b33d6..24924ff050 100644 --- a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/st7565.h +++ b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/st7565.h @@ -34,4 +34,6 @@ #define ST7565_RESISTOR_RATIO 0x20 #define ST7565_POWER_CONTROL 0x28 +#define ST7565_RESET 0xE2 + #endif /* _ST7565_H */ From 3eb8785e8770c07e6a4280c50240d5d951461911 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sat, 8 Apr 2017 20:10:20 +0300 Subject: [PATCH 26/34] Add automatic flush for the LCD screen --- .../infinity/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c | 1 + keyboards/ergodox/infinity/visualizer.c | 2 -- keyboards/ergodox/keymaps/default/visualizer.c | 2 -- quantum/visualizer/lcd_keyframes.c | 5 ----- quantum/visualizer/visualizer.c | 4 ++++ 5 files changed, 5 insertions(+), 9 deletions(-) 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 0de457a7ae..5b7b6d44c4 100644 --- a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c +++ b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c @@ -262,6 +262,7 @@ LLDSPEC void gdisp_lld_blit_area(GDisplay *g) { srcbit++; } } + g->flags |= GDISP_FLG_NEEDFLUSH; } #if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL diff --git a/keyboards/ergodox/infinity/visualizer.c b/keyboards/ergodox/infinity/visualizer.c index 2e10fdd709..6f9b0210a7 100644 --- a/keyboards/ergodox/infinity/visualizer.c +++ b/keyboards/ergodox/infinity/visualizer.c @@ -127,8 +127,6 @@ bool display_logo(keyframe_animation_t* animation, visualizer_state_t* state) { // if you have full screen image, then just use 128 and 32 for both source and target dimensions gdispGBlitArea(GDISP, 0, 0, 128, 32, 0, 0, 128, (pixel_t*)image_data_lcd_logo); - // Always remember to flush the display - gdispFlush(); return false; } diff --git a/keyboards/ergodox/keymaps/default/visualizer.c b/keyboards/ergodox/keymaps/default/visualizer.c index f6159e1ef1..1b0f12f250 100644 --- a/keyboards/ergodox/keymaps/default/visualizer.c +++ b/keyboards/ergodox/keymaps/default/visualizer.c @@ -101,8 +101,6 @@ bool display_logo(keyframe_animation_t* animation, visualizer_state_t* state) { // if you have full screen image, then just use 128 and 32 for both source and target dimensions gdispGBlitArea(GDISP, 0, 0, 128, 32, 0, 0, 128, (pixel_t*)image_data_lcd_logo); - // Always remember to flush the display - gdispFlush(); return false; } diff --git a/quantum/visualizer/lcd_keyframes.c b/quantum/visualizer/lcd_keyframes.c index 74f6e3b470..c6e04d0ca4 100644 --- a/quantum/visualizer/lcd_keyframes.c +++ b/quantum/visualizer/lcd_keyframes.c @@ -23,7 +23,6 @@ bool lcd_keyframe_display_layer_text(keyframe_animation_t* animation, visualizer (void)animation; gdispClear(White); gdispDrawString(0, 10, state->layer_text, state->font_dejavusansbold12, Black); - gdispFlush(); return false; } @@ -62,7 +61,6 @@ bool lcd_keyframe_display_layer_bitmap(keyframe_animation_t* animation, visualiz gdispDrawString(0, 10, layer_buffer, state->font_fixed5x8, Black); format_layer_bitmap_string(state->status.default_layer >> 16, state->status.layer >> 16, layer_buffer); gdispDrawString(0, 20, layer_buffer, state->font_fixed5x8, Black); - gdispFlush(); return false; } @@ -101,7 +99,6 @@ bool lcd_keyframe_display_mods_bitmap(keyframe_animation_t* animation, visualize format_mods_bitmap_string(state->status.mods, status_buffer); gdispDrawString(0, 20, status_buffer, state->font_fixed5x8, Black); - gdispFlush(); return false; } @@ -140,7 +137,6 @@ bool lcd_keyframe_display_led_states(keyframe_animation_t* animation, visualizer get_led_state_string(output, state); gdispClear(White); gdispDrawString(0, 10, output, state->font_dejavusansbold12, Black); - gdispFlush(); return false; } @@ -155,7 +151,6 @@ bool lcd_keyframe_display_layer_and_led_states(keyframe_animation_t* animation, y = 17; } gdispDrawString(0, y, state->layer_text, state->font_dejavusansbold12, Black); - gdispFlush(); return false; } diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c index 2479a64c7f..6f134097f0 100644 --- a/quantum/visualizer/visualizer.c +++ b/quantum/visualizer/visualizer.c @@ -313,6 +313,10 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) { gdispGFlush(LED_DISPLAY); #endif +#ifdef LCD_ENABLE + gdispGFlush(LCD_DISPLAY); +#endif + #ifdef EMULATOR draw_emulator(); #endif From df67169d4260881443d88b142855d4aa2def6dc3 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sat, 8 Apr 2017 21:19:44 +0300 Subject: [PATCH 27/34] Move LCD logo to visualizer resources --- keyboards/ergodox/infinity/visualizer.c | 44 +------------ .../ergodox/keymaps/default/visualizer.c | 44 +------------ quantum/visualizer/resources/lcd_logo.c | 61 ++++++++++++++++++ .../visualizer/resources}/lcd_logo.png | Bin quantum/visualizer/resources/resources.h | 27 ++++++++ quantum/visualizer/visualizer.mk | 2 + 6 files changed, 94 insertions(+), 84 deletions(-) create mode 100644 quantum/visualizer/resources/lcd_logo.c rename {keyboards/ergodox/infinity => quantum/visualizer/resources}/lcd_logo.png (100%) create mode 100644 quantum/visualizer/resources/resources.h diff --git a/keyboards/ergodox/infinity/visualizer.c b/keyboards/ergodox/infinity/visualizer.c index 6f9b0210a7..90933b00a4 100644 --- a/keyboards/ergodox/infinity/visualizer.c +++ b/keyboards/ergodox/infinity/visualizer.c @@ -32,47 +32,7 @@ along with this program. If not, see . #include "lcd_backlight_keyframes.h" #include "system/serial_link.h" -// To generate an image array like this -// Ensure the image is 128 x 32 or smaller -// Convert the bitmap to a C array using a program like http://www.riuson.com/lcd-image-converter/ -// Ensure the the conversion process produces a monochrome format array - 1 bit/pixel, left to right, top to bottom -// Update array in the source code with the C array produced by the conversion program - -// The image below is generated from lcd_logo.png -static const uint8_t image_data_lcd_logo[512] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xf8, 0xfe, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x38, 0x38, 0x06, 0x29, 0x41, 0x24, 0x52, 0x24, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x38, 0x38, 0x09, 0x55, 0x42, 0xaa, 0xaa, 0xaa, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x38, 0x38, 0x09, 0x55, 0x82, 0x28, 0xaa, 0xae, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x38, 0x38, 0x09, 0x55, 0x43, 0x28, 0xaa, 0xaa, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x38, 0x38, 0x0a, 0x55, 0x42, 0x28, 0xaa, 0xaa, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x38, 0x38, 0x05, 0x45, 0x42, 0x28, 0x89, 0x4a, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x38, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x1c, 0x38, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0e, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xff, 0x80, 0x04, 0x45, 0x14, 0xa4, 0x92, 0x83, 0x52, 0x22, 0x22, 0x36, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x00, 0x0a, 0xaa, 0xaa, 0xaa, 0xba, 0x84, 0x55, 0x55, 0x57, 0x45, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x00, 0x08, 0xaa, 0xaa, 0xaa, 0x92, 0xb2, 0x55, 0x55, 0x42, 0x65, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x00, 0x08, 0xaa, 0xaa, 0xaa, 0x92, 0x81, 0x56, 0x65, 0x42, 0x45, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x00, 0x0a, 0xaa, 0xaa, 0xaa, 0x92, 0x81, 0x54, 0x45, 0x42, 0x45, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x00, 0x04, 0x48, 0xa2, 0x4a, 0x89, 0x06, 0x24, 0x42, 0x41, 0x36, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; +#include "resources/resources.h" static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0xFF); static const uint32_t initial_color = LCD_COLOR(0, 0, 0); @@ -125,7 +85,7 @@ bool display_logo(keyframe_animation_t* animation, visualizer_state_t* state) { //gdispGBlitArea is a tricky function to use since it supports blitting part of the image // if you have full screen image, then just use 128 and 32 for both source and target dimensions - gdispGBlitArea(GDISP, 0, 0, 128, 32, 0, 0, 128, (pixel_t*)image_data_lcd_logo); + gdispGBlitArea(GDISP, 0, 0, 128, 32, 0, 0, 128, (pixel_t*)resource_lcd_logo); return false; } diff --git a/keyboards/ergodox/keymaps/default/visualizer.c b/keyboards/ergodox/keymaps/default/visualizer.c index 1b0f12f250..f03702f602 100644 --- a/keyboards/ergodox/keymaps/default/visualizer.c +++ b/keyboards/ergodox/keymaps/default/visualizer.c @@ -33,47 +33,7 @@ along with this program. If not, see . #include "system/serial_link.h" #include "led.h" -// To generate an image array like this -// Ensure the image is 128 x 32 or smaller -// Convert the bitmap to a C array using a program like http://www.riuson.com/lcd-image-converter/ -// Ensure the the conversion process produces a monochrome format array - 1 bit/pixel, left to right, top to bottom -// Update array in the source code with the C array produced by the conversion program - -// The image below is generated from lcd_logo.png -static const uint8_t image_data_lcd_logo[512] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xf8, 0xfe, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x38, 0x38, 0x06, 0x29, 0x41, 0x24, 0x52, 0x24, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x38, 0x38, 0x09, 0x55, 0x42, 0xaa, 0xaa, 0xaa, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x38, 0x38, 0x09, 0x55, 0x82, 0x28, 0xaa, 0xae, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x38, 0x38, 0x09, 0x55, 0x43, 0x28, 0xaa, 0xaa, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x38, 0x38, 0x0a, 0x55, 0x42, 0x28, 0xaa, 0xaa, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x38, 0x38, 0x05, 0x45, 0x42, 0x28, 0x89, 0x4a, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x38, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x1c, 0x38, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0e, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xff, 0x80, 0x04, 0x45, 0x14, 0xa4, 0x92, 0x83, 0x52, 0x22, 0x22, 0x36, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x00, 0x0a, 0xaa, 0xaa, 0xaa, 0xba, 0x84, 0x55, 0x55, 0x57, 0x45, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x00, 0x08, 0xaa, 0xaa, 0xaa, 0x92, 0xb2, 0x55, 0x55, 0x42, 0x65, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x00, 0x08, 0xaa, 0xaa, 0xaa, 0x92, 0x81, 0x56, 0x65, 0x42, 0x45, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x00, 0x0a, 0xaa, 0xaa, 0xaa, 0x92, 0x81, 0x54, 0x45, 0x42, 0x45, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x00, 0x04, 0x48, 0xa2, 0x4a, 0x89, 0x06, 0x24, 0x42, 0x41, 0x36, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; +#include "resources/resources.h" static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0xFF); static const uint32_t initial_color = LCD_COLOR(0, 0, 0); @@ -99,7 +59,7 @@ bool display_logo(keyframe_animation_t* animation, visualizer_state_t* state) { //gdispGBlitArea is a tricky function to use since it supports blitting part of the image // if you have full screen image, then just use 128 and 32 for both source and target dimensions - gdispGBlitArea(GDISP, 0, 0, 128, 32, 0, 0, 128, (pixel_t*)image_data_lcd_logo); + gdispGBlitArea(GDISP, 0, 0, 128, 32, 0, 0, 128, (pixel_t*)resource_lcd_logo); return false; } diff --git a/quantum/visualizer/resources/lcd_logo.c b/quantum/visualizer/resources/lcd_logo.c new file mode 100644 index 0000000000..d1a0ffa7f9 --- /dev/null +++ b/quantum/visualizer/resources/lcd_logo.c @@ -0,0 +1,61 @@ +/* Copyright 2017 Fred Sundvik + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "resources.h" + + +// To generate an image array like this +// Ensure the image is 128 x 32 or smaller +// Convert the bitmap to a C array using a program like http://www.riuson.com/lcd-image-converter/ +// Ensure the the conversion process produces a monochrome format array - 1 bit/pixel, left to right, top to bottom +// Update array in the source code with the C array produced by the conversion program + +// The image below is generated from lcd_logo.png +const uint8_t resource_lcd_logo[512] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0xfe, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x38, 0x38, 0x06, 0x29, 0x41, 0x24, 0x52, 0x24, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x38, 0x38, 0x09, 0x55, 0x42, 0xaa, 0xaa, 0xaa, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x38, 0x38, 0x09, 0x55, 0x82, 0x28, 0xaa, 0xae, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x38, 0x38, 0x09, 0x55, 0x43, 0x28, 0xaa, 0xaa, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x38, 0x38, 0x0a, 0x55, 0x42, 0x28, 0xaa, 0xaa, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x38, 0x38, 0x05, 0x45, 0x42, 0x28, 0x89, 0x4a, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x38, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1c, 0x38, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0e, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xff, 0x80, 0x04, 0x45, 0x14, 0xa4, 0x92, 0x83, 0x52, 0x22, 0x22, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x00, 0x0a, 0xaa, 0xaa, 0xaa, 0xba, 0x84, 0x55, 0x55, 0x57, 0x45, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x00, 0x08, 0xaa, 0xaa, 0xaa, 0x92, 0xb2, 0x55, 0x55, 0x42, 0x65, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x00, 0x08, 0xaa, 0xaa, 0xaa, 0x92, 0x81, 0x56, 0x65, 0x42, 0x45, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x00, 0x0a, 0xaa, 0xaa, 0xaa, 0x92, 0x81, 0x54, 0x45, 0x42, 0x45, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x00, 0x04, 0x48, 0xa2, 0x4a, 0x89, 0x06, 0x24, 0x42, 0x41, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + diff --git a/keyboards/ergodox/infinity/lcd_logo.png b/quantum/visualizer/resources/lcd_logo.png similarity index 100% rename from keyboards/ergodox/infinity/lcd_logo.png rename to quantum/visualizer/resources/lcd_logo.png diff --git a/quantum/visualizer/resources/resources.h b/quantum/visualizer/resources/resources.h new file mode 100644 index 0000000000..1ea27a5364 --- /dev/null +++ b/quantum/visualizer/resources/resources.h @@ -0,0 +1,27 @@ +/* Copyright 2017 Fred Sundvik + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef QUANTUM_VISUALIZER_RESOURCES_RESOURCES_H_ +#define QUANTUM_VISUALIZER_RESOURCES_RESOURCES_H_ + +#include + +#ifdef LCD_ENABLE +extern const uint8_t resource_lcd_logo[]; +#endif + + +#endif /* QUANTUM_VISUALIZER_RESOURCES_RESOURCES_H_ */ diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk index 799379e3d6..7c8e98d67b 100644 --- a/quantum/visualizer/visualizer.mk +++ b/quantum/visualizer/visualizer.mk @@ -37,6 +37,8 @@ ifeq ($(strip $(LCD_ENABLE)), yes) SRC += $(VISUALIZER_DIR)/lcd_backlight.c SRC += $(VISUALIZER_DIR)/lcd_keyframes.c SRC += $(VISUALIZER_DIR)/lcd_backlight_keyframes.c +# Note, that the linker will strip out any resources that are not actually in use +SRC += $(VISUALIZER_DIR)/resources/lcd_logo.c OPT_DEFS += -DLCD_BACKLIGHT_ENABLE endif From 3074269c4a07ff7f1ab2a76ebdb8904cd642e283 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sat, 8 Apr 2017 21:30:11 +0300 Subject: [PATCH 28/34] Move the logo drawing keyframe to lcd_keyframes --- keyboards/ergodox/infinity/visualizer.c | 22 ++----------------- .../ergodox/keymaps/default/visualizer.c | 22 ++----------------- quantum/visualizer/lcd_keyframes.c | 19 ++++++++++++++++ quantum/visualizer/lcd_keyframes.h | 2 ++ 4 files changed, 25 insertions(+), 40 deletions(-) diff --git a/keyboards/ergodox/infinity/visualizer.c b/keyboards/ergodox/infinity/visualizer.c index 90933b00a4..bac85c593c 100644 --- a/keyboards/ergodox/infinity/visualizer.c +++ b/keyboards/ergodox/infinity/visualizer.c @@ -72,24 +72,6 @@ static visualizer_user_data_t user_data_keyboard = { _Static_assert(sizeof(visualizer_user_data_t) <= VISUALIZER_USER_DATA_SIZE, "Please increase the VISUALIZER_USER_DATA_SIZE"); -bool display_logo(keyframe_animation_t* animation, visualizer_state_t* state) { - (void)state; - (void)animation; - (void)state; - // Read the uGFX documentation for information how to use the displays - // http://wiki.ugfx.org/index.php/Main_Page - gdispClear(White); - - // You can use static variables for things that can't be found in the animation - // or state structs, here we use the image - - //gdispGBlitArea is a tricky function to use since it supports blitting part of the image - // if you have full screen image, then just use 128 and 32 for both source and target dimensions - gdispGBlitArea(GDISP, 0, 0, 128, 32, 0, 0, 128, (pixel_t*)resource_lcd_logo); - - return false; -} - // Feel free to modify the animations below, or even add new ones if needed // Don't worry, if the startup animation is long, you can use the keyboard like normal @@ -99,7 +81,7 @@ static keyframe_animation_t startup_animation = { .loop = false, .frame_lengths = {0, gfxMillisecondsToTicks(10000), 0}, .frame_functions = { - display_logo, + lcd_keyframe_draw_logo, backlight_keyframe_animate_color, }, }; @@ -162,7 +144,7 @@ static keyframe_animation_t resume_animation = { .frame_functions = { lcd_keyframe_enable, backlight_keyframe_enable, - display_logo, + lcd_keyframe_draw_logo, backlight_keyframe_animate_color, }, }; diff --git a/keyboards/ergodox/keymaps/default/visualizer.c b/keyboards/ergodox/keymaps/default/visualizer.c index f03702f602..afa6f1bdd7 100644 --- a/keyboards/ergodox/keymaps/default/visualizer.c +++ b/keyboards/ergodox/keymaps/default/visualizer.c @@ -46,24 +46,6 @@ typedef enum { static lcd_state_t lcd_state = LCD_STATE_INITIAL; -bool display_logo(keyframe_animation_t* animation, visualizer_state_t* state) { - (void)state; - (void)animation; - (void)state; - // Read the uGFX documentation for information how to use the displays - // http://wiki.ugfx.org/index.php/Main_Page - gdispClear(White); - - // You can use static variables for things that can't be found in the animation - // or state structs, here we use the image - - //gdispGBlitArea is a tricky function to use since it supports blitting part of the image - // if you have full screen image, then just use 128 and 32 for both source and target dimensions - gdispGBlitArea(GDISP, 0, 0, 128, 32, 0, 0, 128, (pixel_t*)resource_lcd_logo); - - return false; -} - // Feel free to modify the animations below, or even add new ones if needed // Don't worry, if the startup animation is long, you can use the keyboard like normal @@ -73,7 +55,7 @@ static keyframe_animation_t startup_animation = { .loop = false, .frame_lengths = {0, gfxMillisecondsToTicks(10000), 0}, .frame_functions = { - display_logo, + lcd_keyframe_draw_logo, backlight_keyframe_animate_color, }, }; @@ -104,7 +86,7 @@ static keyframe_animation_t resume_animation = { .frame_functions = { lcd_keyframe_enable, backlight_keyframe_enable, - display_logo, + lcd_keyframe_draw_logo, backlight_keyframe_animate_color, }, }; diff --git a/quantum/visualizer/lcd_keyframes.c b/quantum/visualizer/lcd_keyframes.c index c6e04d0ca4..df11861ddc 100644 --- a/quantum/visualizer/lcd_keyframes.c +++ b/quantum/visualizer/lcd_keyframes.c @@ -18,6 +18,7 @@ #include #include "action_util.h" #include "led.h" +#include "resources/resources.h" bool lcd_keyframe_display_layer_text(keyframe_animation_t* animation, visualizer_state_t* state) { (void)animation; @@ -154,6 +155,24 @@ bool lcd_keyframe_display_layer_and_led_states(keyframe_animation_t* animation, return false; } +bool lcd_keyframe_draw_logo(keyframe_animation_t* animation, visualizer_state_t* state) { + (void)state; + (void)animation; + // Read the uGFX documentation for information how to use the displays + // http://wiki.ugfx.org/index.php/Main_Page + gdispClear(White); + + // You can use static variables for things that can't be found in the animation + // or state structs, here we use the image + + //gdispGBlitArea is a tricky function to use since it supports blitting part of the image + // if you have full screen image, then just use 128 and 32 for both source and target dimensions + gdispGBlitArea(GDISP, 0, 0, 128, 32, 0, 0, 128, (pixel_t*)resource_lcd_logo); + + return false; +} + + bool lcd_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) { (void)animation; (void)state; diff --git a/quantum/visualizer/lcd_keyframes.h b/quantum/visualizer/lcd_keyframes.h index 8f79a541c8..2e912b4c73 100644 --- a/quantum/visualizer/lcd_keyframes.h +++ b/quantum/visualizer/lcd_keyframes.h @@ -29,6 +29,8 @@ bool lcd_keyframe_display_mods_bitmap(keyframe_animation_t* animation, visualize bool lcd_keyframe_display_led_states(keyframe_animation_t* animation, visualizer_state_t* state); // Displays both the layer text and the led states bool lcd_keyframe_display_layer_and_led_states(keyframe_animation_t* animation, visualizer_state_t* state); +// Displays the QMK logo on the LCD screen +bool lcd_keyframe_draw_logo(keyframe_animation_t* animation, visualizer_state_t* state); bool lcd_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state); bool lcd_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state); From ed1710589f2f63e485c8780c7c8c03e0f65136a0 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sat, 8 Apr 2017 21:34:30 +0300 Subject: [PATCH 29/34] Fix suspend not disabling backlight --- keyboards/ergodox/infinity/visualizer.c | 2 +- keyboards/ergodox/keymaps/default/visualizer.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/keyboards/ergodox/infinity/visualizer.c b/keyboards/ergodox/infinity/visualizer.c index bac85c593c..8c3f3f29fc 100644 --- a/keyboards/ergodox/infinity/visualizer.c +++ b/keyboards/ergodox/infinity/visualizer.c @@ -133,7 +133,7 @@ static keyframe_animation_t suspend_animation = { lcd_keyframe_display_layer_text, backlight_keyframe_animate_color, lcd_keyframe_disable, - lcd_keyframe_disable, + backlight_keyframe_disable, }, }; diff --git a/keyboards/ergodox/keymaps/default/visualizer.c b/keyboards/ergodox/keymaps/default/visualizer.c index afa6f1bdd7..6a7178968b 100644 --- a/keyboards/ergodox/keymaps/default/visualizer.c +++ b/keyboards/ergodox/keymaps/default/visualizer.c @@ -75,7 +75,7 @@ static keyframe_animation_t suspend_animation = { lcd_keyframe_display_layer_text, backlight_keyframe_animate_color, lcd_keyframe_disable, - lcd_keyframe_disable, + backlight_keyframe_disable, }, }; From c6ca996f4eaa4cce90e02c123230e1e655c9465a Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sat, 8 Apr 2017 22:30:37 +0300 Subject: [PATCH 30/34] Combine startup and resume animations --- .../gdisp/st7565ergodox/gdisp_lld_ST7565.c | 3 +-- keyboards/ergodox/infinity/visualizer.c | 20 +++++-------------- quantum/visualizer/lcd_backlight.c | 8 ++++---- 3 files changed, 10 insertions(+), 21 deletions(-) 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 5b7b6d44c4..b04ad02935 100644 --- a/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c +++ b/keyboards/ergodox/infinity/drivers/gdisp/st7565ergodox/gdisp_lld_ST7565.c @@ -127,7 +127,6 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { write_cmd(g, ST7565_INVERT_DISPLAY); write_cmd(g, ST7565_ALLON_NORMAL); - write_cmd(g, ST7565_DISPLAY_ON); write_cmd(g, ST7565_START_LINE | 0); write_cmd(g, ST7565_RMW); @@ -143,7 +142,7 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { g->g.Width = GDISP_SCREEN_WIDTH; g->g.Height = GDISP_SCREEN_HEIGHT; g->g.Orientation = GDISP_ROTATE_0; - g->g.Powermode = powerOn; + g->g.Powermode = powerOff; g->g.Backlight = GDISP_INITIAL_BACKLIGHT; g->g.Contrast = GDISP_INITIAL_CONTRAST; return TRUE; diff --git a/keyboards/ergodox/infinity/visualizer.c b/keyboards/ergodox/infinity/visualizer.c index 8c3f3f29fc..7ae371c5fc 100644 --- a/keyboards/ergodox/infinity/visualizer.c +++ b/keyboards/ergodox/infinity/visualizer.c @@ -77,10 +77,12 @@ _Static_assert(sizeof(visualizer_user_data_t) <= VISUALIZER_USER_DATA_SIZE, // Don't worry, if the startup animation is long, you can use the keyboard like normal // during that time static keyframe_animation_t startup_animation = { - .num_frames = 2, + .num_frames = 4, .loop = false, - .frame_lengths = {0, gfxMillisecondsToTicks(10000), 0}, + .frame_lengths = {0, 0, 0, gfxMillisecondsToTicks(10000), 0}, .frame_functions = { + lcd_keyframe_enable, + backlight_keyframe_enable, lcd_keyframe_draw_logo, backlight_keyframe_animate_color, }, @@ -137,18 +139,6 @@ static keyframe_animation_t suspend_animation = { }, }; -static keyframe_animation_t resume_animation = { - .num_frames = 4, - .loop = false, - .frame_lengths = {0, 0, 0, gfxMillisecondsToTicks(10000), 0}, - .frame_functions = { - lcd_keyframe_enable, - backlight_keyframe_enable, - lcd_keyframe_draw_logo, - backlight_keyframe_animate_color, - }, -}; - void initialize_user_visualizer(visualizer_state_t* state) { // The brightness will be dynamically adjustable in the future // But for now, change it here. @@ -312,7 +302,7 @@ void user_visualizer_resume(visualizer_state_t* state) { state->current_lcd_color = initial_color; state->target_lcd_color = logo_background_color; lcd_state = LCD_STATE_INITIAL; - start_keyframe_animation(&resume_animation); + start_keyframe_animation(&startup_animation); } void ergodox_board_led_on(void){ diff --git a/quantum/visualizer/lcd_backlight.c b/quantum/visualizer/lcd_backlight.c index 70187d1e00..00de3fab52 100644 --- a/quantum/visualizer/lcd_backlight.c +++ b/quantum/visualizer/lcd_backlight.c @@ -25,10 +25,10 @@ SOFTWARE. #include "lcd_backlight.h" #include -static uint8_t current_hue = 0x00; -static uint8_t current_saturation = 0x00; -static uint8_t current_intensity = 0xFF; -static uint8_t current_brightness = 0x7F; +static uint8_t current_hue = 0; +static uint8_t current_saturation = 0; +static uint8_t current_intensity = 0; +static uint8_t current_brightness = 0; void lcd_backlight_init(void) { lcd_backlight_hal_init(); From 306353bf06e5e5a76890ffb0c48a4dcca76c4399 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sat, 8 Apr 2017 22:48:18 +0300 Subject: [PATCH 31/34] Create a file for shared Ergodox Infinity animations --- keyboards/ergodox/infinity/animations.c | 54 +++++++++++++++++++ keyboards/ergodox/infinity/animations.h | 25 +++++++++ keyboards/ergodox/infinity/rules.mk | 5 +- keyboards/ergodox/infinity/visualizer.c | 38 ++----------- .../ergodox/keymaps/default/visualizer.c | 45 ++-------------- 5 files changed, 90 insertions(+), 77 deletions(-) create mode 100644 keyboards/ergodox/infinity/animations.c create mode 100644 keyboards/ergodox/infinity/animations.h diff --git a/keyboards/ergodox/infinity/animations.c b/keyboards/ergodox/infinity/animations.c new file mode 100644 index 0000000000..54ab994607 --- /dev/null +++ b/keyboards/ergodox/infinity/animations.c @@ -0,0 +1,54 @@ +/* Copyright 2017 Fred Sundvik + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "animations.h" +#include "visualizer.h" +#ifdef LCD_ENABLE +#include "lcd_keyframes.h" +#endif +#ifdef LCD_BACKLIGHT_ENABLE +#include "lcd_backlight_keyframes.h" +#endif + +#if defined(VISUALIZER_ENABLE) && defined(LCD_ENABLE) && defined(LCD_BACKLIGHT_ENABLE) + +// Don't worry, if the startup animation is long, you can use the keyboard like normal +// during that time +keyframe_animation_t default_startup_animation = { + .num_frames = 4, + .loop = false, + .frame_lengths = {0, 0, 0, gfxMillisecondsToTicks(5000), 0}, + .frame_functions = { + lcd_keyframe_enable, + backlight_keyframe_enable, + lcd_keyframe_draw_logo, + backlight_keyframe_animate_color, + }, +}; + +keyframe_animation_t default_suspend_animation = { + .num_frames = 4, + .loop = false, + .frame_lengths = {0, gfxMillisecondsToTicks(1000), 0, 0}, + .frame_functions = { + lcd_keyframe_display_layer_text, + backlight_keyframe_animate_color, + lcd_keyframe_disable, + backlight_keyframe_disable, + }, +}; + +#endif diff --git a/keyboards/ergodox/infinity/animations.h b/keyboards/ergodox/infinity/animations.h new file mode 100644 index 0000000000..0c441ff7e9 --- /dev/null +++ b/keyboards/ergodox/infinity/animations.h @@ -0,0 +1,25 @@ +/* Copyright 2017 Fred Sundvik + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef KEYBOARDS_ERGODOX_INFINITY_ANIMATIONS_H_ +#define KEYBOARDS_ERGODOX_INFINITY_ANIMATIONS_H_ + +#include "visualizer.h" + +extern keyframe_animation_t default_startup_animation; +extern keyframe_animation_t default_suspend_animation; + +#endif /* KEYBOARDS_ERGODOX_INFINITY_ANIMATIONS_H_ */ diff --git a/keyboards/ergodox/infinity/rules.mk b/keyboards/ergodox/infinity/rules.mk index aaadfe34b5..9e6170d89a 100644 --- a/keyboards/ergodox/infinity/rules.mk +++ b/keyboards/ergodox/infinity/rules.mk @@ -1,6 +1,7 @@ # project specific files SRC = matrix.c \ - led.c + led.c \ + animations.c ## chip/board settings # - the next two should match the directories in @@ -72,4 +73,4 @@ endif ifdef LED_ENABLE include $(SUBPROJECT_PATH)/drivers/gdisp/IS31FL3731C/driver.mk -endif +endif \ No newline at end of file diff --git a/keyboards/ergodox/infinity/visualizer.c b/keyboards/ergodox/infinity/visualizer.c index 7ae371c5fc..a4b09a34d0 100644 --- a/keyboards/ergodox/infinity/visualizer.c +++ b/keyboards/ergodox/infinity/visualizer.c @@ -31,8 +31,7 @@ along with this program. If not, see . #include "lcd_keyframes.h" #include "lcd_backlight_keyframes.h" #include "system/serial_link.h" - -#include "resources/resources.h" +#include "animations.h" static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0xFF); static const uint32_t initial_color = LCD_COLOR(0, 0, 0); @@ -74,19 +73,6 @@ _Static_assert(sizeof(visualizer_user_data_t) <= VISUALIZER_USER_DATA_SIZE, // Feel free to modify the animations below, or even add new ones if needed -// Don't worry, if the startup animation is long, you can use the keyboard like normal -// during that time -static keyframe_animation_t startup_animation = { - .num_frames = 4, - .loop = false, - .frame_lengths = {0, 0, 0, gfxMillisecondsToTicks(10000), 0}, - .frame_functions = { - lcd_keyframe_enable, - backlight_keyframe_enable, - lcd_keyframe_draw_logo, - backlight_keyframe_animate_color, - }, -}; // The color animation animates the LCD color when you change layers static keyframe_animation_t one_led_color = { @@ -127,18 +113,6 @@ static keyframe_animation_t lcd_bitmap_leds_animation = { .frame_functions = {lcd_keyframe_display_layer_bitmap, lcd_keyframe_display_led_states}, }; -static keyframe_animation_t suspend_animation = { - .num_frames = 4, - .loop = false, - .frame_lengths = {0, gfxMillisecondsToTicks(1000), 0, 0}, - .frame_functions = { - lcd_keyframe_display_layer_text, - backlight_keyframe_animate_color, - lcd_keyframe_disable, - backlight_keyframe_disable, - }, -}; - void initialize_user_visualizer(visualizer_state_t* state) { // The brightness will be dynamically adjustable in the future // But for now, change it here. @@ -146,13 +120,9 @@ void initialize_user_visualizer(visualizer_state_t* state) { state->current_lcd_color = initial_color; state->target_lcd_color = logo_background_color; lcd_state = LCD_STATE_INITIAL; - start_keyframe_animation(&startup_animation); + start_keyframe_animation(&default_startup_animation); } -static const uint32_t red; -static const uint32_t green; -static const uint32_t blue; - inline bool is_led_on(visualizer_user_data_t* user_data, uint8_t num) { return user_data->led_on & (1u << num); } @@ -295,14 +265,14 @@ void user_visualizer_suspend(visualizer_state_t* state) { uint8_t hue = LCD_HUE(state->current_lcd_color); uint8_t sat = LCD_SAT(state->current_lcd_color); state->target_lcd_color = LCD_COLOR(hue, sat, 0); - start_keyframe_animation(&suspend_animation); + start_keyframe_animation(&default_suspend_animation); } void user_visualizer_resume(visualizer_state_t* state) { state->current_lcd_color = initial_color; state->target_lcd_color = logo_background_color; lcd_state = LCD_STATE_INITIAL; - start_keyframe_animation(&startup_animation); + start_keyframe_animation(&default_startup_animation); } void ergodox_board_led_on(void){ diff --git a/keyboards/ergodox/keymaps/default/visualizer.c b/keyboards/ergodox/keymaps/default/visualizer.c index 6a7178968b..779de00506 100644 --- a/keyboards/ergodox/keymaps/default/visualizer.c +++ b/keyboards/ergodox/keymaps/default/visualizer.c @@ -32,8 +32,7 @@ along with this program. If not, see . #include "lcd_backlight_keyframes.h" #include "system/serial_link.h" #include "led.h" - -#include "resources/resources.h" +#include "animations.h" static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0xFF); static const uint32_t initial_color = LCD_COLOR(0, 0, 0); @@ -48,18 +47,6 @@ static lcd_state_t lcd_state = LCD_STATE_INITIAL; // Feel free to modify the animations below, or even add new ones if needed -// Don't worry, if the startup animation is long, you can use the keyboard like normal -// during that time -static keyframe_animation_t startup_animation = { - .num_frames = 2, - .loop = false, - .frame_lengths = {0, gfxMillisecondsToTicks(10000), 0}, - .frame_functions = { - lcd_keyframe_draw_logo, - backlight_keyframe_animate_color, - }, -}; - static keyframe_animation_t lcd_layer_display = { .num_frames = 1, .loop = false, @@ -67,30 +54,6 @@ static keyframe_animation_t lcd_layer_display = { .frame_functions = {lcd_keyframe_display_layer_and_led_states} }; -static keyframe_animation_t suspend_animation = { - .num_frames = 4, - .loop = false, - .frame_lengths = {0, gfxMillisecondsToTicks(1000), 0, 0}, - .frame_functions = { - lcd_keyframe_display_layer_text, - backlight_keyframe_animate_color, - lcd_keyframe_disable, - backlight_keyframe_disable, - }, -}; - -static keyframe_animation_t resume_animation = { - .num_frames = 4, - .loop = false, - .frame_lengths = {0, 0, 0, gfxMillisecondsToTicks(10000), 0}, - .frame_functions = { - lcd_keyframe_enable, - backlight_keyframe_enable, - lcd_keyframe_draw_logo, - backlight_keyframe_animate_color, - }, -}; - // The color animation animates the LCD color when you change layers static keyframe_animation_t color_animation = { .num_frames = 2, @@ -109,7 +72,7 @@ void initialize_user_visualizer(visualizer_state_t* state) { state->current_lcd_color = initial_color; state->target_lcd_color = logo_background_color; lcd_state = LCD_STATE_INITIAL; - start_keyframe_animation(&startup_animation); + start_keyframe_animation(&default_startup_animation); } void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) { @@ -156,12 +119,12 @@ void user_visualizer_suspend(visualizer_state_t* state) { uint8_t hue = LCD_HUE(state->current_lcd_color); uint8_t sat = LCD_SAT(state->current_lcd_color); state->target_lcd_color = LCD_COLOR(hue, sat, 0); - start_keyframe_animation(&suspend_animation); + start_keyframe_animation(&default_suspend_animation); } void user_visualizer_resume(visualizer_state_t* state) { state->current_lcd_color = initial_color; state->target_lcd_color = logo_background_color; lcd_state = LCD_STATE_INITIAL; - start_keyframe_animation(&resume_animation); + start_keyframe_animation(&default_startup_animation); } From c5d2b7ff16f81a8061127e0ec636cf9b914725c5 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sat, 8 Apr 2017 23:04:27 +0300 Subject: [PATCH 32/34] Rename led test to led_keyframes and move animation to Ergodox --- keyboards/ergodox/infinity/animations.c | 55 +++++++++++++++++- keyboards/ergodox/infinity/animations.h | 5 ++ .../{led_test.c => led_keyframes.c} | 57 +++---------------- .../{led_test.h => led_keyframes.h} | 20 +++---- quantum/visualizer/visualizer.mk | 2 +- 5 files changed, 78 insertions(+), 61 deletions(-) rename quantum/visualizer/{led_test.c => led_keyframes.c} (68%) rename quantum/visualizer/{led_test.h => led_keyframes.h} (69%) diff --git a/keyboards/ergodox/infinity/animations.c b/keyboards/ergodox/infinity/animations.c index 54ab994607..4c9f6d9c85 100644 --- a/keyboards/ergodox/infinity/animations.c +++ b/keyboards/ergodox/infinity/animations.c @@ -14,6 +14,8 @@ * along with this program. If not, see . */ +#if defined(VISUALIZER_ENABLE) + #include "animations.h" #include "visualizer.h" #ifdef LCD_ENABLE @@ -23,7 +25,14 @@ #include "lcd_backlight_keyframes.h" #endif -#if defined(VISUALIZER_ENABLE) && defined(LCD_ENABLE) && defined(LCD_BACKLIGHT_ENABLE) +#ifdef LED_ENABLE +#include "led_keyframes.h" +#endif + +#include "visualizer_keyframes.h" + + +#if defined(LCD_ENABLE) && defined(LCD_BACKLIGHT_ENABLE) // Don't worry, if the startup animation is long, you can use the keyboard like normal // during that time @@ -50,5 +59,49 @@ keyframe_animation_t default_suspend_animation = { backlight_keyframe_disable, }, }; +#endif + +#if defined(LED_ENABLE) +#define CROSSFADE_TIME 1000 +#define GRADIENT_TIME 3000 + +keyframe_animation_t led_test_animation = { + .num_frames = 14, + .loop = true, + .frame_lengths = { + gfxMillisecondsToTicks(1000), // fade in + gfxMillisecondsToTicks(1000), // no op (leds on) + gfxMillisecondsToTicks(1000), // fade out + gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade + gfxMillisecondsToTicks(GRADIENT_TIME), // left to rigt (outside in) + gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade + gfxMillisecondsToTicks(GRADIENT_TIME), // top_to_bottom + 0, // mirror leds + gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade + gfxMillisecondsToTicks(GRADIENT_TIME), // left_to_right (mirrored, so inside out) + gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade + gfxMillisecondsToTicks(GRADIENT_TIME), // top_to_bottom + 0, // normal leds + gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade + + }, + .frame_functions = { + led_keyframe_fade_in_all, + keyframe_no_operation, + led_keyframe_fade_out_all, + led_keyframe_crossfade, + led_keyframe_left_to_right_gradient, + led_keyframe_crossfade, + led_keyframe_top_to_bottom_gradient, + led_keyframe_mirror_orientation, + led_keyframe_crossfade, + led_keyframe_left_to_right_gradient, + led_keyframe_crossfade, + led_keyframe_top_to_bottom_gradient, + led_keyframe_normal_orientation, + led_keyframe_crossfade, + }, +}; +#endif #endif diff --git a/keyboards/ergodox/infinity/animations.h b/keyboards/ergodox/infinity/animations.h index 0c441ff7e9..6d8b9830d9 100644 --- a/keyboards/ergodox/infinity/animations.h +++ b/keyboards/ergodox/infinity/animations.h @@ -19,7 +19,12 @@ #include "visualizer.h" +// You can use these default animations, but of course you can also write your own custom ones instead extern keyframe_animation_t default_startup_animation; extern keyframe_animation_t default_suspend_animation; +// An animation for testing and demonstrating the led support, should probably not be used for real world +// cases +extern keyframe_animation_t led_test_animation; + #endif /* KEYBOARDS_ERGODOX_INFINITY_ANIMATIONS_H_ */ diff --git a/quantum/visualizer/led_test.c b/quantum/visualizer/led_keyframes.c similarity index 68% rename from quantum/visualizer/led_test.c rename to quantum/visualizer/led_keyframes.c index a9abace8df..2dacd990d1 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, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "led_test.h" #include "gfx.h" #include "math.h" - -#define CROSSFADE_TIME 1000 -#define GRADIENT_TIME 3000 - -keyframe_animation_t led_test_animation = { - .num_frames = 14, - .loop = true, - .frame_lengths = { - gfxMillisecondsToTicks(1000), // fade in - gfxMillisecondsToTicks(1000), // no op (leds on) - gfxMillisecondsToTicks(1000), // fade out - gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade - gfxMillisecondsToTicks(GRADIENT_TIME), // left to rigt (outside in) - gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade - gfxMillisecondsToTicks(GRADIENT_TIME), // top_to_bottom - 0, // mirror leds - gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade - gfxMillisecondsToTicks(GRADIENT_TIME), // left_to_right (mirrored, so inside out) - gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade - gfxMillisecondsToTicks(GRADIENT_TIME), // top_to_bottom - 0, // normal leds - gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade - - }, - .frame_functions = { - keyframe_fade_in_all_leds, - keyframe_no_operation, - keyframe_fade_out_all_leds, - keyframe_led_crossfade, - keyframe_led_left_to_right_gradient, - keyframe_led_crossfade, - keyframe_led_top_to_bottom_gradient, - keyframe_mirror_led_orientation, - keyframe_led_crossfade, - keyframe_led_left_to_right_gradient, - keyframe_led_crossfade, - keyframe_led_top_to_bottom_gradient, - keyframe_normal_led_orientation, - keyframe_led_crossfade, - }, -}; +#include "led_keyframes.h" static uint8_t fade_led_color(keyframe_animation_t* animation, int from, int to) { 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) { return (uint8_t)(255.0f * v); } -bool keyframe_fade_in_all_leds(keyframe_animation_t* animation, visualizer_state_t* state) { +bool led_keyframe_fade_in_all(keyframe_animation_t* animation, visualizer_state_t* state) { (void)state; keyframe_fade_all_leds_from_to(animation, 0, 255); return true; } -bool keyframe_fade_out_all_leds(keyframe_animation_t* animation, visualizer_state_t* state) { +bool led_keyframe_fade_out_all(keyframe_animation_t* animation, visualizer_state_t* state) { (void)state; keyframe_fade_all_leds_from_to(animation, 255, 0); return true; } -bool keyframe_led_left_to_right_gradient(keyframe_animation_t* animation, visualizer_state_t* state) { +bool led_keyframe_left_to_right_gradient(keyframe_animation_t* animation, visualizer_state_t* state) { (void)state; float frame_length = animation->frame_lengths[animation->current_frame]; 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 return true; } -bool keyframe_led_top_to_bottom_gradient(keyframe_animation_t* animation, visualizer_state_t* state) { +bool led_keyframe_top_to_bottom_gradient(keyframe_animation_t* animation, visualizer_state_t* state) { (void)state; float frame_length = animation->frame_lengths[animation->current_frame]; float current_pos = frame_length - animation->time_left_in_frame; @@ -139,7 +98,7 @@ static void copy_current_led_state(uint8_t* dest) { } } } -bool keyframe_led_crossfade(keyframe_animation_t* animation, visualizer_state_t* state) { +bool led_keyframe_crossfade(keyframe_animation_t* animation, visualizer_state_t* state) { (void)state; if (animation->first_update_of_frame) { copy_current_led_state(&crossfade_start_frame[0][0]); @@ -155,14 +114,14 @@ bool keyframe_led_crossfade(keyframe_animation_t* animation, visualizer_state_t* return true; } -bool keyframe_mirror_led_orientation(keyframe_animation_t* animation, visualizer_state_t* state) { +bool led_keyframe_mirror_orientation(keyframe_animation_t* animation, visualizer_state_t* state) { (void)state; (void)animation; gdispGSetOrientation(LED_DISPLAY, GDISP_ROTATE_180); return false; } -bool keyframe_normal_led_orientation(keyframe_animation_t* animation, visualizer_state_t* state) { +bool led_keyframe_normal_orientation(keyframe_animation_t* animation, visualizer_state_t* state) { (void)state; (void)animation; gdispGSetOrientation(LED_DISPLAY, GDISP_ROTATE_0); diff --git a/quantum/visualizer/led_test.h b/quantum/visualizer/led_keyframes.h similarity index 69% rename from quantum/visualizer/led_test.h rename to quantum/visualizer/led_keyframes.h index 5e2325753e..a689430417 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 SOFTWARE. */ -#ifndef TMK_VISUALIZER_LED_TEST_H_ -#define TMK_VISUALIZER_LED_TEST_H_ +#ifndef LED_KEYFRAMES_H +#define LED_KEYFRAMES_H #include "visualizer.h" -bool keyframe_fade_in_all_leds(keyframe_animation_t* animation, visualizer_state_t* state); -bool keyframe_fade_out_all_leds(keyframe_animation_t* animation, visualizer_state_t* state); -bool keyframe_led_left_to_right_gradient(keyframe_animation_t* animation, visualizer_state_t* state); -bool keyframe_led_top_to_bottom_gradient(keyframe_animation_t* animation, visualizer_state_t* state); -bool keyframe_led_crossfade(keyframe_animation_t* animation, visualizer_state_t* state); -bool keyframe_mirror_led_orientation(keyframe_animation_t* animation, visualizer_state_t* state); -bool keyframe_normal_led_orientation(keyframe_animation_t* animation, visualizer_state_t* state); +bool led_keyframe_fade_in_all(keyframe_animation_t* animation, visualizer_state_t* state); +bool led_keyframe_fade_out_all(keyframe_animation_t* animation, visualizer_state_t* state); +bool led_keyframe_left_to_right_gradient(keyframe_animation_t* animation, visualizer_state_t* state); +bool led_keyframe_top_to_bottom_gradient(keyframe_animation_t* animation, visualizer_state_t* state); +bool led_keyframe_crossfade(keyframe_animation_t* animation, visualizer_state_t* state); +bool led_keyframe_mirror_orientation(keyframe_animation_t* animation, visualizer_state_t* state); +bool led_keyframe_normal_orientation(keyframe_animation_t* animation, visualizer_state_t* state); extern keyframe_animation_t led_test_animation; -#endif /* TMK_VISUALIZER_LED_TEST_H_ */ +#endif /* LED_KEYFRAMES_H */ diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk index 7c8e98d67b..5f710124bc 100644 --- a/quantum/visualizer/visualizer.mk +++ b/quantum/visualizer/visualizer.mk @@ -43,7 +43,7 @@ OPT_DEFS += -DLCD_BACKLIGHT_ENABLE endif ifeq ($(strip $(LED_ENABLE)), yes) -SRC += $(VISUALIZER_DIR)/led_test.c +SRC += $(VISUALIZER_DIR)/led_keyframes.c OPT_DEFS += -DLED_ENABLE endif From 65b7bf68785b5b1d4257ba4fd95c3f53df230985 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Sun, 9 Apr 2017 18:32:10 +0300 Subject: [PATCH 33/34] Extract Ergodox default visualizer into simple_visualizer It's good enough if you only want to change the lcd text and color. --- .../ergodox/infinity/simple_visualizer.h | 123 ++++++++++++++++++ .../ergodox/keymaps/default/visualizer.c | 102 +-------------- 2 files changed, 130 insertions(+), 95 deletions(-) create mode 100644 keyboards/ergodox/infinity/simple_visualizer.h diff --git a/keyboards/ergodox/infinity/simple_visualizer.h b/keyboards/ergodox/infinity/simple_visualizer.h new file mode 100644 index 0000000000..ded8a3222e --- /dev/null +++ b/keyboards/ergodox/infinity/simple_visualizer.h @@ -0,0 +1,123 @@ +/* Copyright 2017 Fred Sundvik + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef KEYBOARDS_ERGODOX_INFINITY_SIMPLE_VISUALIZER_H_ +#define KEYBOARDS_ERGODOX_INFINITY_SIMPLE_VISUALIZER_H_ + +// Currently we are assuming that both the backlight and LCD are enabled +// But it's entirely possible to write a custom visualizer that use only +// one of them +#ifndef LCD_BACKLIGHT_ENABLE +#error This visualizer needs that LCD backlight is enabled +#endif + +#ifndef LCD_ENABLE +#error This visualizer needs that LCD is enabled +#endif + +#include "visualizer.h" +#include "visualizer_keyframes.h" +#include "lcd_keyframes.h" +#include "lcd_backlight_keyframes.h" +#include "system/serial_link.h" +#include "led.h" +#include "animations.h" + +static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0xFF); +static const uint32_t initial_color = LCD_COLOR(0, 0, 0); + +static bool initial_update = true; + +// Feel free to modify the animations below, or even add new ones if needed + +static keyframe_animation_t lcd_layer_display = { + .num_frames = 1, + .loop = false, + .frame_lengths = {gfxMillisecondsToTicks(0)}, + .frame_functions = {lcd_keyframe_display_layer_and_led_states} +}; + +// The color animation animates the LCD color when you change layers +static keyframe_animation_t color_animation = { + .num_frames = 2, + .loop = false, + // Note that there's a 200 ms no-operation frame, + // this prevents the color from changing when activating the layer + // momentarily + .frame_lengths = {gfxMillisecondsToTicks(200), gfxMillisecondsToTicks(500)}, + .frame_functions = {keyframe_no_operation, backlight_keyframe_animate_color}, +}; + +void initialize_user_visualizer(visualizer_state_t* state) { + // The brightness will be dynamically adjustable in the future + // But for now, change it here. + lcd_backlight_brightness(130); + state->current_lcd_color = initial_color; + state->target_lcd_color = logo_background_color; + initial_update = true; + start_keyframe_animation(&default_startup_animation); +} + + +// This function should be implemented by the keymap visualizer +// Don't change anything else than state->target_lcd_color and state->layer_text as that's the only thing +// that the simple_visualizer assumes that you are updating +// Also make sure that the buffer passed to state->layer_text remains valid until the previous animation is +// stopped. This can be done by either double buffering it or by using constant strings +static void get_visualizer_layer_and_color(visualizer_state_t* state); + +void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) { + // Add more tests, change the colors and layer texts here + // Usually you want to check the high bits (higher layers first) + // because that's the order layers are processed for keypresses + // You can for check for example: + // state->status.layer + // state->status.default_layer + // state->status.leds (see led.h for available statuses) + + uint32_t prev_color = state->target_lcd_color; + const char* prev_layer_text = state->layer_text; + + get_visualizer_layer_and_color(state); + + if (initial_update || prev_color != state->target_lcd_color) { + start_keyframe_animation(&color_animation); + } + + if (initial_update || prev_layer_text != state->layer_text) { + start_keyframe_animation(&lcd_layer_display); + } + // You can also stop existing animations, and start your custom ones here + // remember that you should normally have only one animation for the LCD + // and one for the background. But you can also combine them if you want. +} + +void user_visualizer_suspend(visualizer_state_t* state) { + state->layer_text = "Suspending..."; + uint8_t hue = LCD_HUE(state->current_lcd_color); + uint8_t sat = LCD_SAT(state->current_lcd_color); + state->target_lcd_color = LCD_COLOR(hue, sat, 0); + start_keyframe_animation(&default_suspend_animation); +} + +void user_visualizer_resume(visualizer_state_t* state) { + state->current_lcd_color = initial_color; + state->target_lcd_color = logo_background_color; + initial_update = true; + start_keyframe_animation(&default_startup_animation); +} + +#endif /* KEYBOARDS_ERGODOX_INFINITY_SIMPLE_VISUALIZER_H_ */ diff --git a/keyboards/ergodox/keymaps/default/visualizer.c b/keyboards/ergodox/keymaps/default/visualizer.c index 779de00506..502e53f3d1 100644 --- a/keyboards/ergodox/keymaps/default/visualizer.c +++ b/keyboards/ergodox/keymaps/default/visualizer.c @@ -15,75 +15,14 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -// Currently we are assuming that both the backlight and LCD are enabled -// But it's entirely possible to write a custom visualizer that use only -// one of them -#ifndef LCD_BACKLIGHT_ENABLE -#error This visualizer needs that LCD backlight is enabled -#endif - -#ifndef LCD_ENABLE -#error This visualizer needs that LCD is enabled -#endif - -#include "visualizer.h" -#include "visualizer_keyframes.h" -#include "lcd_keyframes.h" -#include "lcd_backlight_keyframes.h" -#include "system/serial_link.h" -#include "led.h" -#include "animations.h" - -static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0xFF); -static const uint32_t initial_color = LCD_COLOR(0, 0, 0); - -typedef enum { - LCD_STATE_INITIAL, - LCD_STATE_LAYER_BITMAP, - LCD_STATE_BITMAP_AND_LEDS, -} lcd_state_t; - -static lcd_state_t lcd_state = LCD_STATE_INITIAL; - -// Feel free to modify the animations below, or even add new ones if needed - -static keyframe_animation_t lcd_layer_display = { - .num_frames = 1, - .loop = false, - .frame_lengths = {gfxMillisecondsToTicks(0)}, - .frame_functions = {lcd_keyframe_display_layer_and_led_states} -}; - -// The color animation animates the LCD color when you change layers -static keyframe_animation_t color_animation = { - .num_frames = 2, - .loop = false, - // Note that there's a 200 ms no-operation frame, - // this prevents the color from changing when activating the layer - // momentarily - .frame_lengths = {gfxMillisecondsToTicks(200), gfxMillisecondsToTicks(500)}, - .frame_functions = {keyframe_no_operation, backlight_keyframe_animate_color}, -}; - -void initialize_user_visualizer(visualizer_state_t* state) { - // The brightness will be dynamically adjustable in the future - // But for now, change it here. - lcd_backlight_brightness(130); - state->current_lcd_color = initial_color; - state->target_lcd_color = logo_background_color; - lcd_state = LCD_STATE_INITIAL; - start_keyframe_animation(&default_startup_animation); -} - -void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) { - // Add more tests, change the colors and layer texts here - // Usually you want to check the high bits (higher layers first) - // because that's the order layers are processed for keypresses - // You can for check for example: - // state->status.layer - // state->status.default_layer - // state->status.leds (see led.h for available statuses) +#include "simple_visualizer.h" +// This function should be implemented by the keymap visualizer +// Don't change anything else than state->target_lcd_color and state->layer_text as that's the only thing +// that the simple_visualizer assumes that you are updating +// Also make sure that the buffer passed to state->layer_text remains valid until the previous animation is +// stopped. This can be done by either double buffering it or by using constant strings +static void get_visualizer_layer_and_color(visualizer_state_t* state) { uint8_t saturation = 60; if (state->status.leds & (1u << USB_LED_CAPS_LOCK)) { saturation = 255; @@ -100,31 +39,4 @@ void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard state->target_lcd_color = LCD_COLOR(84, saturation, 0xFF); state->layer_text = "Default"; } - - if (lcd_state == LCD_STATE_INITIAL || - state->status.layer != prev_status->layer || - state->status.default_layer != prev_status->default_layer || - state->status.leds != prev_status->leds) { - start_keyframe_animation(&color_animation); - start_keyframe_animation(&lcd_layer_display); - } - - // You can also stop existing animations, and start your custom ones here - // remember that you should normally have only one animation for the LCD - // and one for the background. But you can also combine them if you want. -} - -void user_visualizer_suspend(visualizer_state_t* state) { - state->layer_text = "Suspending..."; - uint8_t hue = LCD_HUE(state->current_lcd_color); - uint8_t sat = LCD_SAT(state->current_lcd_color); - state->target_lcd_color = LCD_COLOR(hue, sat, 0); - start_keyframe_animation(&default_suspend_animation); -} - -void user_visualizer_resume(visualizer_state_t* state) { - state->current_lcd_color = initial_color; - state->target_lcd_color = logo_background_color; - lcd_state = LCD_STATE_INITIAL; - start_keyframe_animation(&default_startup_animation); } From 1d5567a3a9ae1ca45bd5ff09f21edb7d1388afc3 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Wed, 12 Apr 2017 09:52:40 +0300 Subject: [PATCH 34/34] Fix code formatting in build_keyboard.mk --- build_keyboard.mk | 165 +++++++++++++++++++++++----------------------- 1 file changed, 83 insertions(+), 82 deletions(-) diff --git a/build_keyboard.mk b/build_keyboard.mk index 79d2b6b0f0..9da8277db9 100644 --- a/build_keyboard.mk +++ b/build_keyboard.mk @@ -7,11 +7,11 @@ endif include common.mk ifneq ($(SUBPROJECT),) - TARGET ?= $(KEYBOARD)_$(SUBPROJECT)_$(KEYMAP) - KEYBOARD_OUTPUT := $(BUILD_DIR)/obj_$(KEYBOARD)_$(SUBPROJECT) + TARGET ?= $(KEYBOARD)_$(SUBPROJECT)_$(KEYMAP) + KEYBOARD_OUTPUT := $(BUILD_DIR)/obj_$(KEYBOARD)_$(SUBPROJECT) else - TARGET ?= $(KEYBOARD)_$(KEYMAP) - KEYBOARD_OUTPUT := $(BUILD_DIR)/obj_$(KEYBOARD) + TARGET ?= $(KEYBOARD)_$(KEYMAP) + KEYBOARD_OUTPUT := $(BUILD_DIR)/obj_$(KEYBOARD) endif # Force expansion @@ -20,15 +20,15 @@ TARGET := $(TARGET) MASTER ?= left ifdef master - MASTER = $(master) + MASTER = $(master) endif ifeq ($(MASTER),right) - OPT_DEFS += -DMASTER_IS_ON_RIGHT + OPT_DEFS += -DMASTER_IS_ON_RIGHT else - ifneq ($(MASTER),left) + ifneq ($(MASTER),left) $(error MASTER does not have a valid value(left/right)) - endif + endif endif @@ -56,31 +56,31 @@ endif # We can assume a ChibiOS target When MCU_FAMILY is defined, since it's not used for LUFA ifdef MCU_FAMILY - PLATFORM=CHIBIOS + PLATFORM=CHIBIOS else - PLATFORM=AVR + PLATFORM=AVR endif ifeq ($(PLATFORM),CHIBIOS) - include $(TMK_PATH)/protocol/chibios.mk - include $(TMK_PATH)/chibios.mk - OPT_OS = chibios - ifneq ("$(wildcard $(SUBPROJECT_PATH)/bootloader_defs.h)","") - OPT_DEFS += -include $(SUBPROJECT_PATH)/bootloader_defs.h - else ifneq ("$(wildcard $(SUBPROJECT_PATH)/boards/$(BOARD)/bootloader_defs.h)","") - OPT_DEFS += -include $(SUBPROJECT_PATH)/boards/$(BOARD)/bootloader_defs.h - else ifneq ("$(wildcard $(KEYBOARD_PATH)/bootloader_defs.h)","") - OPT_DEFS += -include $(KEYBOARD_PATH)/bootloader_defs.h - else ifneq ("$(wildcard $(KEYBOARD_PATH)/boards/$(BOARD)/bootloader_defs.h)","") - OPT_DEFS += -include $(KEYBOARD_PATH)/boards/$(BOARD)/bootloader_defs.h - endif + include $(TMK_PATH)/protocol/chibios.mk + include $(TMK_PATH)/chibios.mk + OPT_OS = chibios + ifneq ("$(wildcard $(SUBPROJECT_PATH)/bootloader_defs.h)","") + OPT_DEFS += -include $(SUBPROJECT_PATH)/bootloader_defs.h + else ifneq ("$(wildcard $(SUBPROJECT_PATH)/boards/$(BOARD)/bootloader_defs.h)","") + OPT_DEFS += -include $(SUBPROJECT_PATH)/boards/$(BOARD)/bootloader_defs.h + else ifneq ("$(wildcard $(KEYBOARD_PATH)/bootloader_defs.h)","") + OPT_DEFS += -include $(KEYBOARD_PATH)/bootloader_defs.h + else ifneq ("$(wildcard $(KEYBOARD_PATH)/boards/$(BOARD)/bootloader_defs.h)","") + OPT_DEFS += -include $(KEYBOARD_PATH)/boards/$(BOARD)/bootloader_defs.h + endif endif CONFIG_H = $(KEYBOARD_PATH)/config.h ifneq ($(SUBPROJECT),) - ifneq ("$(wildcard $(SUBPROJECT_C))","") - CONFIG_H = $(SUBPROJECT_PATH)/config.h - endif + ifneq ("$(wildcard $(SUBPROJECT_C))","") + CONFIG_H = $(SUBPROJECT_PATH)/config.h + endif endif # 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) ifneq ("$(wildcard $(KEYMAP_PATH)/config.h)","") - CONFIG_H = $(KEYMAP_PATH)/config.h + CONFIG_H = $(KEYMAP_PATH)/config.h endif # # project specific files SRC += $(KEYBOARD_C) \ - $(KEYMAP_C) \ - $(QUANTUM_DIR)/quantum.c \ - $(QUANTUM_DIR)/keymap_common.c \ - $(QUANTUM_DIR)/keycode_config.c \ - $(QUANTUM_DIR)/process_keycode/process_leader.c + $(KEYMAP_C) \ + $(QUANTUM_DIR)/quantum.c \ + $(QUANTUM_DIR)/keymap_common.c \ + $(QUANTUM_DIR)/keycode_config.c \ + $(QUANTUM_DIR)/process_keycode/process_leader.c ifneq ($(SUBPROJECT),) - SRC += $(SUBPROJECT_C) + SRC += $(SUBPROJECT_C) endif ifndef CUSTOM_MATRIX - SRC += $(QUANTUM_DIR)/matrix.c + SRC += $(QUANTUM_DIR)/matrix.c endif ifeq ($(strip $(API_SYSEX_ENABLE)), yes) - OPT_DEFS += -DAPI_SYSEX_ENABLE - SRC += $(QUANTUM_DIR)/api/api_sysex.c - OPT_DEFS += -DAPI_ENABLE - SRC += $(QUANTUM_DIR)/api.c + OPT_DEFS += -DAPI_SYSEX_ENABLE + SRC += $(QUANTUM_DIR)/api/api_sysex.c + OPT_DEFS += -DAPI_ENABLE + SRC += $(QUANTUM_DIR)/api.c MIDI_ENABLE=yes endif @@ -144,25 +144,25 @@ MUSIC_ENABLE := 0 ifeq ($(strip $(AUDIO_ENABLE)), yes) OPT_DEFS += -DAUDIO_ENABLE MUSIC_ENABLE := 1 - SRC += $(QUANTUM_DIR)/process_keycode/process_audio.c - SRC += $(QUANTUM_DIR)/audio/audio.c - SRC += $(QUANTUM_DIR)/audio/voices.c - SRC += $(QUANTUM_DIR)/audio/luts.c + SRC += $(QUANTUM_DIR)/process_keycode/process_audio.c + SRC += $(QUANTUM_DIR)/audio/audio.c + SRC += $(QUANTUM_DIR)/audio/voices.c + SRC += $(QUANTUM_DIR)/audio/luts.c endif ifeq ($(strip $(MIDI_ENABLE)), yes) OPT_DEFS += -DMIDI_ENABLE - MUSIC_ENABLE := 1 - SRC += $(QUANTUM_DIR)/process_keycode/process_midi.c + MUSIC_ENABLE := 1 + SRC += $(QUANTUM_DIR)/process_keycode/process_midi.c endif ifeq ($(MUSIC_ENABLE), 1) - SRC += $(QUANTUM_DIR)/process_keycode/process_music.c + SRC += $(QUANTUM_DIR)/process_keycode/process_music.c endif ifeq ($(strip $(COMBO_ENABLE)), yes) OPT_DEFS += -DCOMBO_ENABLE - SRC += $(QUANTUM_DIR)/process_keycode/process_combo.c + SRC += $(QUANTUM_DIR)/process_keycode/process_combo.c endif ifeq ($(strip $(VIRTSER_ENABLE)), yes) @@ -171,79 +171,80 @@ endif ifeq ($(strip $(FAUXCLICKY_ENABLE)), yes) OPT_DEFS += -DFAUXCLICKY_ENABLE - SRC += $(QUANTUM_DIR)/fauxclicky.c + SRC += $(QUANTUM_DIR)/fauxclicky.c endif ifeq ($(strip $(UCIS_ENABLE)), yes) - OPT_DEFS += -DUCIS_ENABLE - SRC += $(QUANTUM_DIR)/process_keycode/process_unicode_common.c - SRC += $(QUANTUM_DIR)/process_keycode/process_ucis.c + OPT_DEFS += -DUCIS_ENABLE + SRC += $(QUANTUM_DIR)/process_keycode/process_unicode_common.c + SRC += $(QUANTUM_DIR)/process_keycode/process_ucis.c endif ifeq ($(strip $(UNICODEMAP_ENABLE)), yes) - OPT_DEFS += -DUNICODEMAP_ENABLE - SRC += $(QUANTUM_DIR)/process_keycode/process_unicode_common.c - SRC += $(QUANTUM_DIR)/process_keycode/process_unicodemap.c + OPT_DEFS += -DUNICODEMAP_ENABLE + SRC += $(QUANTUM_DIR)/process_keycode/process_unicode_common.c + SRC += $(QUANTUM_DIR)/process_keycode/process_unicodemap.c endif ifeq ($(strip $(UNICODE_ENABLE)), yes) OPT_DEFS += -DUNICODE_ENABLE - SRC += $(QUANTUM_DIR)/process_keycode/process_unicode_common.c - SRC += $(QUANTUM_DIR)/process_keycode/process_unicode.c + SRC += $(QUANTUM_DIR)/process_keycode/process_unicode_common.c + SRC += $(QUANTUM_DIR)/process_keycode/process_unicode.c endif ifeq ($(strip $(RGBLIGHT_ENABLE)), yes) - OPT_DEFS += -DRGBLIGHT_ENABLE - SRC += $(QUANTUM_DIR)/light_ws2812.c - SRC += $(QUANTUM_DIR)/rgblight.c + OPT_DEFS += -DRGBLIGHT_ENABLE + SRC += $(QUANTUM_DIR)/light_ws2812.c + SRC += $(QUANTUM_DIR)/rgblight.c CIE1931_CURVE = yes LED_BREATHING_TABLE = yes endif ifeq ($(strip $(TAP_DANCE_ENABLE)), yes) - OPT_DEFS += -DTAP_DANCE_ENABLE - SRC += $(QUANTUM_DIR)/process_keycode/process_tap_dance.c + OPT_DEFS += -DTAP_DANCE_ENABLE + SRC += $(QUANTUM_DIR)/process_keycode/process_tap_dance.c endif ifeq ($(strip $(PRINTING_ENABLE)), yes) - OPT_DEFS += -DPRINTING_ENABLE - SRC += $(QUANTUM_DIR)/process_keycode/process_printer.c - SRC += $(TMK_DIR)/protocol/serial_uart.c + OPT_DEFS += -DPRINTING_ENABLE + SRC += $(QUANTUM_DIR)/process_keycode/process_printer.c + SRC += $(TMK_DIR)/protocol/serial_uart.c endif ifeq ($(strip $(SERIAL_LINK_ENABLE)), yes) - SRC += $(patsubst $(QUANTUM_PATH)/%,%,$(SERIAL_SRC)) - OPT_DEFS += $(SERIAL_DEFS) - VAPTH += $(SERIAL_PATH) + SRC += $(patsubst $(QUANTUM_PATH)/%,%,$(SERIAL_SRC)) + OPT_DEFS += $(SERIAL_DEFS) + VAPTH += $(SERIAL_PATH) endif ifneq ($(strip $(VARIABLE_TRACE)),) - SRC += $(QUANTUM_DIR)/variable_trace.c - OPT_DEFS += -DNUM_TRACED_VARIABLES=$(strip $(VARIABLE_TRACE)) + SRC += $(QUANTUM_DIR)/variable_trace.c + OPT_DEFS += -DNUM_TRACED_VARIABLES=$(strip $(VARIABLE_TRACE)) ifneq ($(strip $(MAX_VARIABLE_TRACE_SIZE)),) - OPT_DEFS += -DMAX_VARIABLE_TRACE_SIZE=$(strip $(MAX_VARIABLE_TRACE_SIZE)) + OPT_DEFS += -DMAX_VARIABLE_TRACE_SIZE=$(strip $(MAX_VARIABLE_TRACE_SIZE)) endif endif ifeq ($(strip $(LCD_ENABLE)), yes) -CIE1931_CURVE = yes + CIE1931_CURVE = yes endif ifeq ($(strip $(LED_ENABLE)), yes) -CIE1931_CURVE = yes + CIE1931_CURVE = yes endif ifeq ($(strip $(CIE1931_CURVE)), yes) - OPT_DEFS += -DUSE_CIE1931_CURVE - LED_TABLES = yes + OPT_DEFS += -DUSE_CIE1931_CURVE + LED_TABLES = yes endif + ifeq ($(strip $(LED_BREATHING_TABLE)), yes) - OPT_DEFS += -DUSE_LED_BREATHING_TABLE - LED_TABLES = yes + OPT_DEFS += -DUSE_LED_BREATHING_TABLE + LED_TABLES = yes endif ifeq ($(strip $(LED_TABLES)), yes) - SRC += $(QUANTUM_DIR)/led_tables.c + SRC += $(QUANTUM_DIR)/led_tables.c endif # Optimize size but this may cause error "relocation truncated to fit" @@ -252,7 +253,7 @@ endif # Search Path VPATH += $(KEYMAP_PATH) ifneq ($(SUBPROJECT),) - VPATH += $(SUBPROJECT_PATH) + VPATH += $(SUBPROJECT_PATH) endif VPATH += $(KEYBOARD_PATH) VPATH += $(COMMON_VPATH) @@ -266,17 +267,17 @@ EXTRALDFLAGS += $(TMK_COMMON_LDFLAGS) ifeq ($(PLATFORM),AVR) ifeq ($(strip $(PROTOCOL)), VUSB) - include $(TMK_PATH)/protocol/vusb.mk + include $(TMK_PATH)/protocol/vusb.mk else - include $(TMK_PATH)/protocol/lufa.mk + include $(TMK_PATH)/protocol/lufa.mk endif - include $(TMK_PATH)/avr.mk + include $(TMK_PATH)/avr.mk endif ifeq ($(strip $(VISUALIZER_ENABLE)), yes) - VISUALIZER_DIR = $(QUANTUM_DIR)/visualizer - VISUALIZER_PATH = $(QUANTUM_PATH)/visualizer - include $(VISUALIZER_PATH)/visualizer.mk + VISUALIZER_DIR = $(QUANTUM_DIR)/visualizer + VISUALIZER_PATH = $(QUANTUM_PATH)/visualizer + include $(VISUALIZER_PATH)/visualizer.mk endif OUTPUTS := $(KEYMAP_OUTPUT) $(KEYBOARD_OUTPUT)