mirror of
				https://github.com/mfulz/qmk_firmware.git
				synced 2025-10-31 05:12:33 +01:00 
			
		
		
		
	Merge pull request #1217 from fredizzimo/ergodox_default_visualizer
Enable Ergodox Infinity LCD visualization
This commit is contained in:
		
						commit
						e5f610b70e
					
				| @ -196,6 +196,8 @@ ifeq ($(strip $(RGBLIGHT_ENABLE)), yes) | |||||||
|     OPT_DEFS += -DRGBLIGHT_ENABLE |     OPT_DEFS += -DRGBLIGHT_ENABLE | ||||||
|     SRC += $(QUANTUM_DIR)/light_ws2812.c |     SRC += $(QUANTUM_DIR)/light_ws2812.c | ||||||
|     SRC += $(QUANTUM_DIR)/rgblight.c |     SRC += $(QUANTUM_DIR)/rgblight.c | ||||||
|  |     CIE1931_CURVE = yes | ||||||
|  |     LED_BREATHING_TABLE = yes | ||||||
| endif | endif | ||||||
| 
 | 
 | ||||||
| ifeq ($(strip $(TAP_DANCE_ENABLE)), yes) | ifeq ($(strip $(TAP_DANCE_ENABLE)), yes) | ||||||
| @ -223,6 +225,28 @@ ifneq ($(strip $(MAX_VARIABLE_TRACE_SIZE)),) | |||||||
| endif | endif | ||||||
| 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"
 | # Optimize size but this may cause error "relocation truncated to fit"
 | ||||||
| #EXTRALDFLAGS = -Wl,--relax
 | #EXTRALDFLAGS = -Wl,--relax
 | ||||||
| 
 | 
 | ||||||
| @ -258,12 +282,12 @@ endif | |||||||
| 
 | 
 | ||||||
| OUTPUTS := $(KEYMAP_OUTPUT) $(KEYBOARD_OUTPUT) | OUTPUTS := $(KEYMAP_OUTPUT) $(KEYBOARD_OUTPUT) | ||||||
| $(KEYMAP_OUTPUT)_SRC := $(SRC) | $(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)_INC :=  $(VPATH) $(EXTRAINCDIRS) | ||||||
| $(KEYMAP_OUTPUT)_CONFIG := $(CONFIG_H) | $(KEYMAP_OUTPUT)_CONFIG := $(CONFIG_H) | ||||||
| $(KEYBOARD_OUTPUT)_SRC := $(CHIBISRC) | $(KEYBOARD_OUTPUT)_SRC := $(CHIBISRC) $(GFXSRC) | ||||||
| $(KEYBOARD_OUTPUT)_DEFS := $(PROJECT_DEFS) | $(KEYBOARD_OUTPUT)_DEFS := $(PROJECT_DEFS) $(GFXDEFS) | ||||||
| $(KEYBOARD_OUTPUT)_INC := $(PROJECT_INC) | $(KEYBOARD_OUTPUT)_INC := $(PROJECT_INC) $(GFXINC) | ||||||
| $(KEYBOARD_OUTPUT)_CONFIG  := $(PROJECT_CONFIG) | $(KEYBOARD_OUTPUT)_CONFIG  := $(PROJECT_CONFIG) | ||||||
| 
 | 
 | ||||||
| # Default target.
 | # Default target.
 | ||||||
|  | |||||||
| @ -74,7 +74,3 @@ OPT_DEFS += -DBOOTLOADER_SIZE=512 | |||||||
| SLEEP_LED_ENABLE = no | SLEEP_LED_ENABLE = no | ||||||
| API_SYSEX_ENABLE ?= no | API_SYSEX_ENABLE ?= no | ||||||
| RGBLIGHT_ENABLE ?= yes | RGBLIGHT_ENABLE ?= yes | ||||||
| 
 |  | ||||||
| ifndef QUANTUM_DIR |  | ||||||
| 	include ../../../Makefile |  | ||||||
| endif |  | ||||||
|  | |||||||
							
								
								
									
										107
									
								
								keyboards/ergodox/infinity/animations.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								keyboards/ergodox/infinity/animations.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,107 @@ | |||||||
|  | /* 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 <http://www.gnu.org/licenses/>.
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #if defined(VISUALIZER_ENABLE) | ||||||
|  | 
 | ||||||
|  | #include "animations.h" | ||||||
|  | #include "visualizer.h" | ||||||
|  | #ifdef LCD_ENABLE | ||||||
|  | #include "lcd_keyframes.h" | ||||||
|  | #endif | ||||||
|  | #ifdef LCD_BACKLIGHT_ENABLE | ||||||
|  | #include "lcd_backlight_keyframes.h" | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #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
 | ||||||
|  | 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 | ||||||
|  | 
 | ||||||
|  | #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 | ||||||
							
								
								
									
										30
									
								
								keyboards/ergodox/infinity/animations.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								keyboards/ergodox/infinity/animations.h
									
									
									
									
									
										Normal file
									
								
							| @ -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 <http://www.gnu.org/licenses/>.
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef KEYBOARDS_ERGODOX_INFINITY_ANIMATIONS_H_ | ||||||
|  | #define KEYBOARDS_ERGODOX_INFINITY_ANIMATIONS_H_ | ||||||
|  | 
 | ||||||
|  | #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_ */ | ||||||
| @ -40,7 +40,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||||||
| /* number of backlight levels */ | /* number of backlight levels */ | ||||||
| #define BACKLIGHT_LEVELS 3 | #define BACKLIGHT_LEVELS 3 | ||||||
| 
 | 
 | ||||||
| #define LED_BRIGHTNESS_LO       15 | #define LED_BRIGHTNESS_LO       100 | ||||||
| #define LED_BRIGHTNESS_HI       255 | #define LED_BRIGHTNESS_HI       255 | ||||||
| 
 | 
 | ||||||
| /* define if matrix has ghost */ | /* define if matrix has ghost */ | ||||||
| @ -54,6 +54,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||||||
| // The visualizer needs gfx thread priorities
 | // The visualizer needs gfx thread priorities
 | ||||||
| #define VISUALIZER_THREAD_PRIORITY (NORMAL_PRIORITY - 2) | #define VISUALIZER_THREAD_PRIORITY (NORMAL_PRIORITY - 2) | ||||||
| 
 | 
 | ||||||
|  | #define VISUALIZER_USER_DATA_SIZE 16 | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Feature disable options |  * Feature disable options | ||||||
|  *  These options are also useful to firmware size reduction. |  *  These options are also useful to firmware size reduction. | ||||||
|  | |||||||
| @ -25,6 +25,10 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||||||
| 
 | 
 | ||||||
| #include "board_IS31FL3731C.h" | #include "board_IS31FL3731C.h" | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | // Can't include led_tables from here
 | ||||||
|  | extern const uint8_t CIE1931_CURVE[]; | ||||||
|  | 
 | ||||||
| /*===========================================================================*/ | /*===========================================================================*/ | ||||||
| /* Driver local definitions.                                                 */ | /* Driver local definitions.                                                 */ | ||||||
| /*===========================================================================*/ | /*===========================================================================*/ | ||||||
| @ -100,37 +104,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||||||
| 
 | 
 | ||||||
| #define IS31 | #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.                                                   */ | /* Driver local functions.                                                   */ | ||||||
| /*===========================================================================*/ | /*===========================================================================*/ | ||||||
| @ -231,7 +204,7 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { | |||||||
| 		uint8_t* src = PRIV(g)->frame_buffer; | 		uint8_t* src = PRIV(g)->frame_buffer; | ||||||
| 		for (int y=0;y<GDISP_SCREEN_HEIGHT;y++) { | 		for (int y=0;y<GDISP_SCREEN_HEIGHT;y++) { | ||||||
| 		    for (int x=0;x<GDISP_SCREEN_WIDTH;x++) { | 		    for (int x=0;x<GDISP_SCREEN_WIDTH;x++) { | ||||||
| 		        PRIV(g)->write_buffer[get_led_address(g, x, y)]=cie[*src]; | 		        PRIV(g)->write_buffer[get_led_address(g, x, y)]=CIE1931_CURVE[*src]; | ||||||
| 		        ++src; | 		        ++src; | ||||||
| 		    } | 		    } | ||||||
| 		} | 		} | ||||||
|  | |||||||
| @ -8,8 +8,6 @@ | |||||||
| #ifndef _GDISP_LLD_BOARD_H | #ifndef _GDISP_LLD_BOARD_H | ||||||
| #define _GDISP_LLD_BOARD_H | #define _GDISP_LLD_BOARD_H | ||||||
| 
 | 
 | ||||||
| #include "print.h" |  | ||||||
| 
 |  | ||||||
| #define ST7565_LCD_BIAS         ST7565_LCD_BIAS_9 // actually 6
 | #define ST7565_LCD_BIAS         ST7565_LCD_BIAS_9 // actually 6
 | ||||||
| #define ST7565_ADC              ST7565_ADC_NORMAL | #define ST7565_ADC              ST7565_ADC_NORMAL | ||||||
| #define ST7565_COM_SCAN         ST7565_COM_SCAN_DEC | #define ST7565_COM_SCAN         ST7565_COM_SCAN_DEC | ||||||
| @ -39,35 +37,49 @@ | |||||||
| // MSB First
 | // MSB First
 | ||||||
| // CLK Low by default
 | // CLK Low by default
 | ||||||
| static const SPIConfig spi1config = { | static const SPIConfig spi1config = { | ||||||
| 	NULL, |    // Operation complete callback or @p NULL.
 | ||||||
| 	/* HW dependent part.*/ |   .end_cb = NULL, | ||||||
| 	ST7565_GPIOPORT, |    //The chip select line port - when not using pcs.
 | ||||||
|     ST7565_SS_PIN, |   .ssport = ST7565_GPIOPORT, | ||||||
|     SPIx_CTARn_FMSZ(7) |    // brief The chip select line pad number - when not using pcs.
 | ||||||
|     | SPIx_CTARn_ASC(7) |   .sspad=ST7565_SS_PIN, | ||||||
|     | SPIx_CTARn_DT(7) |    // SPI initialization data.
 | ||||||
|     | SPIx_CTARn_CSSCK(7) |   .tar0 = | ||||||
|     | SPIx_CTARn_PBR(0) |     SPIx_CTARn_FMSZ(7) // Frame size = 8 bytes
 | ||||||
|     | SPIx_CTARn_BR(7) |     | SPIx_CTARn_ASC(1) // After SCK Delay Scaler (min 50 ns) = 55.56ns
 | ||||||
| 	//SPI_CR1_BR_0
 |     | 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 bool_t st7565_is_data_mode = 1; | 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) { | static GFXINLINE void init_board(GDisplay *g) { | ||||||
|     (void) g; |     (void) g; | ||||||
|     palSetPadModeNamed(A0, PAL_MODE_OUTPUT_PUSHPULL); |     palSetPadModeNamed(A0, PAL_MODE_OUTPUT_PUSHPULL); | ||||||
|     palSetPad(ST7565_GPIOPORT, ST7565_A0_PIN); |     palSetPad(ST7565_GPIOPORT, ST7565_A0_PIN); | ||||||
|     st7565_is_data_mode = 1; |  | ||||||
|     palSetPadModeNamed(RST, PAL_MODE_OUTPUT_PUSHPULL); |     palSetPadModeNamed(RST, PAL_MODE_OUTPUT_PUSHPULL); | ||||||
|     palSetPad(ST7565_GPIOPORT, ST7565_RST_PIN); |     palSetPad(ST7565_GPIOPORT, ST7565_RST_PIN); | ||||||
|     palSetPadModeRaw(MOSI, ST7565_SPI_MODE); |     palSetPadModeRaw(MOSI, ST7565_SPI_MODE); | ||||||
|     palSetPadModeRaw(SLCK, ST7565_SPI_MODE); |     palSetPadModeRaw(SLCK, ST7565_SPI_MODE); | ||||||
|     palSetPadModeRaw(SS, ST7565_SPI_MODE); |     palSetPadModeRaw(SS, PAL_MODE_OUTPUT_PUSHPULL); | ||||||
| 
 | 
 | ||||||
|     spiInit(); |     spiInit(); | ||||||
|     spiStart(&SPID1, &spi1config); |     spiStart(&SPID1, &spi1config); | ||||||
|     spiSelect(&SPID1); |     release_bus(g); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static GFXINLINE void post_init_board(GDisplay *g) { | static GFXINLINE void post_init_board(GDisplay *g) { | ||||||
| @ -84,43 +96,17 @@ static GFXINLINE void setpin_reset(GDisplay *g, bool_t state) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static GFXINLINE void acquire_bus(GDisplay *g) { | static GFXINLINE void enter_data_mode(GDisplay *g) { | ||||||
|     (void) g; |     palSetPad(ST7565_GPIOPORT, ST7565_A0_PIN); | ||||||
|     // Only the LCD is using the SPI bus, so no need to acquire
 |  | ||||||
|     // spiAcquireBus(&SPID1);
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static GFXINLINE void release_bus(GDisplay *g) { | static GFXINLINE void enter_cmd_mode(GDisplay *g) { | ||||||
|     (void) g; |  | ||||||
|     // Only the LCD is using the SPI bus, so no need to release
 |  | ||||||
|     //spiReleaseBus(&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); |     palClearPad(ST7565_GPIOPORT, ST7565_A0_PIN); | ||||||
|         chThdSleep(2); |  | ||||||
|         st7565_is_data_mode = 0; |  | ||||||
| 	} |  | ||||||
| 	spiSend(&SPID1, 1, &cmd); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| static GFXINLINE void write_data(GDisplay *g, uint8_t* data, uint16_t length) { | static GFXINLINE void write_data(GDisplay *g, uint8_t* data, uint16_t length) { | ||||||
| 	(void) g; | 	(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); | 	spiSend(&SPID1, length, data); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -26,7 +26,7 @@ | |||||||
| #define GDISP_SCREEN_WIDTH		128 | #define GDISP_SCREEN_WIDTH		128 | ||||||
| #endif | #endif | ||||||
| #ifndef GDISP_INITIAL_CONTRAST | #ifndef GDISP_INITIAL_CONTRAST | ||||||
| 	#define GDISP_INITIAL_CONTRAST	0 | #define GDISP_INITIAL_CONTRAST	35 | ||||||
| #endif | #endif | ||||||
| #ifndef GDISP_INITIAL_BACKLIGHT | #ifndef GDISP_INITIAL_BACKLIGHT | ||||||
| #define GDISP_INITIAL_BACKLIGHT	100 | #define GDISP_INITIAL_BACKLIGHT	100 | ||||||
| @ -58,12 +58,24 @@ | |||||||
| 
 | 
 | ||||||
| typedef struct{ | typedef struct{ | ||||||
|     bool_t buffer2; |     bool_t buffer2; | ||||||
|  |     uint8_t data_pos; | ||||||
|  |     uint8_t data[16]; | ||||||
|     uint8_t ram[GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH / 8]; |     uint8_t ram[GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH / 8]; | ||||||
| }PrivData; | }PrivData; | ||||||
| 
 | 
 | ||||||
| // Some common routines and macros
 | // Some common routines and macros
 | ||||||
| #define PRIV(g)                         ((PrivData*)g->priv) | #define PRIV(g)                         ((PrivData*)g->priv) | ||||||
| #define RAM(g)							(PRIV(g)->ram) | #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_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); } | #define write_cmd3(g, cmd1, cmd2, cmd3)	{ write_cmd(g, cmd1); write_cmd(g, cmd2); write_cmd(g, cmd3); } | ||||||
| 
 | 
 | ||||||
| @ -89,6 +101,7 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { | |||||||
|     // The private area is the display surface.
 |     // The private area is the display surface.
 | ||||||
|     g->priv = gfxAlloc(sizeof(PrivData)); |     g->priv = gfxAlloc(sizeof(PrivData)); | ||||||
|     PRIV(g)->buffer2 = false; |     PRIV(g)->buffer2 = false; | ||||||
|  |     PRIV(g)->data_pos = 0; | ||||||
| 
 | 
 | ||||||
|     // Initialise the board interface
 |     // Initialise the board interface
 | ||||||
|     init_board(g); |     init_board(g); | ||||||
| @ -98,38 +111,26 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { | |||||||
|     gfxSleepMilliseconds(20); |     gfxSleepMilliseconds(20); | ||||||
|     setpin_reset(g, FALSE); |     setpin_reset(g, FALSE); | ||||||
|     gfxSleepMilliseconds(20); |     gfxSleepMilliseconds(20); | ||||||
| 
 |  | ||||||
|     acquire_bus(g); |     acquire_bus(g); | ||||||
|     write_cmd(g, ST7565_DISPLAY_OFF); |     enter_cmd_mode(g); | ||||||
|  | 
 | ||||||
|  |     write_cmd(g, ST7565_RESET); | ||||||
|     write_cmd(g, ST7565_LCD_BIAS); |     write_cmd(g, ST7565_LCD_BIAS); | ||||||
|     write_cmd(g, ST7565_ADC); |     write_cmd(g, ST7565_ADC); | ||||||
|     write_cmd(g, ST7565_COM_SCAN); |     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 internal power supply (VC=1, VR=1, VF=1)
 | ||||||
| 
 |  | ||||||
| 	// turn on voltage converter (VC=1, VR=0, VF=0)
 |  | ||||||
| 	write_cmd(g, ST7565_POWER_CONTROL | 0x04); |  | ||||||
| 	delay_ms(50); |  | ||||||
| 
 |  | ||||||
| 	// turn on voltage regulator (VC=1, VR=1, VF=0)
 |  | ||||||
| 	write_cmd(g, ST7565_POWER_CONTROL | 0x06); |  | ||||||
| 	delay_ms(50); |  | ||||||
| 
 |  | ||||||
| 	// turn on voltage follower (VC=1, VR=1, VF=1)
 |  | ||||||
|     write_cmd(g, ST7565_POWER_CONTROL | 0x07); |     write_cmd(g, ST7565_POWER_CONTROL | 0x07); | ||||||
| 	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_INVERT_DISPLAY); | ||||||
|  |     write_cmd(g, ST7565_ALLON_NORMAL); | ||||||
| 
 | 
 | ||||||
|  |     write_cmd(g, ST7565_START_LINE | 0); | ||||||
|     write_cmd(g, ST7565_RMW); |     write_cmd(g, ST7565_RMW); | ||||||
|  |     flush_cmd(g); | ||||||
| 
 | 
 | ||||||
|     // Finish Init
 |     // Finish Init
 | ||||||
|     post_init_board(g); |     post_init_board(g); | ||||||
| @ -141,7 +142,7 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { | |||||||
|     g->g.Width = GDISP_SCREEN_WIDTH; |     g->g.Width = GDISP_SCREEN_WIDTH; | ||||||
|     g->g.Height = GDISP_SCREEN_HEIGHT; |     g->g.Height = GDISP_SCREEN_HEIGHT; | ||||||
|     g->g.Orientation = GDISP_ROTATE_0; |     g->g.Orientation = GDISP_ROTATE_0; | ||||||
| 	g->g.Powermode = powerOn; |     g->g.Powermode = powerOff; | ||||||
|     g->g.Backlight = GDISP_INITIAL_BACKLIGHT; |     g->g.Backlight = GDISP_INITIAL_BACKLIGHT; | ||||||
|     g->g.Contrast = GDISP_INITIAL_CONTRAST; |     g->g.Contrast = GDISP_INITIAL_CONTRAST; | ||||||
|     return TRUE; |     return TRUE; | ||||||
| @ -156,16 +157,21 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { | |||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
|     acquire_bus(g); |     acquire_bus(g); | ||||||
|  |     enter_cmd_mode(g); | ||||||
|     unsigned dstOffset = (PRIV(g)->buffer2 ? 4 : 0); |     unsigned dstOffset = (PRIV(g)->buffer2 ? 4 : 0); | ||||||
|     for (p = 0; p < 4; p++) { |     for (p = 0; p < 4; p++) { | ||||||
|         write_cmd(g, ST7565_PAGE | (p + dstOffset)); |         write_cmd(g, ST7565_PAGE | (p + dstOffset)); | ||||||
|         write_cmd(g, ST7565_COLUMN_MSB | 0); |         write_cmd(g, ST7565_COLUMN_MSB | 0); | ||||||
|         write_cmd(g, ST7565_COLUMN_LSB | 0); |         write_cmd(g, ST7565_COLUMN_LSB | 0); | ||||||
|         write_cmd(g, ST7565_RMW); |         write_cmd(g, ST7565_RMW); | ||||||
|  |         flush_cmd(g); | ||||||
|  |         enter_data_mode(g); | ||||||
|         write_data(g, RAM(g) + (p*GDISP_SCREEN_WIDTH), GDISP_SCREEN_WIDTH); |         write_data(g, RAM(g) + (p*GDISP_SCREEN_WIDTH), GDISP_SCREEN_WIDTH); | ||||||
|  |         enter_cmd_mode(g); | ||||||
|     } |     } | ||||||
|     unsigned line = (PRIV(g)->buffer2 ? 32 : 0); |     unsigned line = (PRIV(g)->buffer2 ? 32 : 0); | ||||||
|     write_cmd(g, ST7565_START_LINE | line); |     write_cmd(g, ST7565_START_LINE | line); | ||||||
|  |     flush_cmd(g); | ||||||
|     PRIV(g)->buffer2 = !PRIV(g)->buffer2; |     PRIV(g)->buffer2 = !PRIV(g)->buffer2; | ||||||
|     release_bus(g); |     release_bus(g); | ||||||
| 
 | 
 | ||||||
| @ -231,6 +237,33 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { | |||||||
| } | } | ||||||
| #endif | #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++; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     g->flags |= GDISP_FLG_NEEDFLUSH; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL | #if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL | ||||||
| LLDSPEC void gdisp_lld_control(GDisplay *g) { | LLDSPEC void gdisp_lld_control(GDisplay *g) { | ||||||
|     switch(g->p.x) { |     switch(g->p.x) { | ||||||
| @ -242,12 +275,16 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { | |||||||
|         case powerSleep: |         case powerSleep: | ||||||
|         case powerDeepSleep: |         case powerDeepSleep: | ||||||
|             acquire_bus(g); |             acquire_bus(g); | ||||||
|  |             enter_cmd_mode(g); | ||||||
|             write_cmd(g, ST7565_DISPLAY_OFF); |             write_cmd(g, ST7565_DISPLAY_OFF); | ||||||
|  |             flush_cmd(g); | ||||||
|             release_bus(g); |             release_bus(g); | ||||||
|             break; |             break; | ||||||
|         case powerOn: |         case powerOn: | ||||||
|             acquire_bus(g); |             acquire_bus(g); | ||||||
|  |             enter_cmd_mode(g); | ||||||
|             write_cmd(g, ST7565_DISPLAY_ON); |             write_cmd(g, ST7565_DISPLAY_ON); | ||||||
|  |             flush_cmd(g); | ||||||
|             release_bus(g); |             release_bus(g); | ||||||
|             break; |             break; | ||||||
|         default: |         default: | ||||||
| @ -278,12 +315,12 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { | |||||||
|             return; |             return; | ||||||
| 
 | 
 | ||||||
|             case GDISP_CONTROL_CONTRAST: |             case GDISP_CONTROL_CONTRAST: | ||||||
|             if ((unsigned)g->p.ptr > 100) |                 g->g.Contrast = (unsigned)g->p.ptr & 63; | ||||||
|             	g->p.ptr = (void *)100; |  | ||||||
|                 acquire_bus(g); |                 acquire_bus(g); | ||||||
| 			write_cmd2(g, ST7565_CONTRAST, ((((unsigned)g->p.ptr)<<6)/101) & 0x3F); |                 enter_cmd_mode(g); | ||||||
|  |                 write_cmd2(g, ST7565_CONTRAST, g->g.Contrast); | ||||||
|  |                 flush_cmd(g); | ||||||
|                 release_bus(g); |                 release_bus(g); | ||||||
|             g->g.Contrast = (unsigned)g->p.ptr; |  | ||||||
|                 return; |                 return; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -18,6 +18,7 @@ | |||||||
| #define GDISP_HARDWARE_DRAWPIXEL        TRUE | #define GDISP_HARDWARE_DRAWPIXEL        TRUE | ||||||
| #define GDISP_HARDWARE_PIXELREAD        TRUE | #define GDISP_HARDWARE_PIXELREAD        TRUE | ||||||
| #define GDISP_HARDWARE_CONTROL          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 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -34,4 +34,6 @@ | |||||||
| #define ST7565_RESISTOR_RATIO       0x20 | #define ST7565_RESISTOR_RATIO       0x20 | ||||||
| #define ST7565_POWER_CONTROL        0x28 | #define ST7565_POWER_CONTROL        0x28 | ||||||
| 
 | 
 | ||||||
|  | #define ST7565_RESET                0xE2 | ||||||
|  | 
 | ||||||
| #endif /* _ST7565_H */ | #endif /* _ST7565_H */ | ||||||
|  | |||||||
| @ -143,7 +143,7 @@ | |||||||
|         #define GDISP_HARDWARE_DRAWPIXEL             TRUE |         #define GDISP_HARDWARE_DRAWPIXEL             TRUE | ||||||
|         #define GDISP_HARDWARE_CLEARS                FALSE |         #define GDISP_HARDWARE_CLEARS                FALSE | ||||||
|         #define GDISP_HARDWARE_FILLS                 FALSE |         #define GDISP_HARDWARE_FILLS                 FALSE | ||||||
|         #define GDISP_HARDWARE_BITFILLS              FALSE |         //#define GDISP_HARDWARE_BITFILLS              FALSE
 | ||||||
|         #define GDISP_HARDWARE_SCROLL                FALSE |         #define GDISP_HARDWARE_SCROLL                FALSE | ||||||
|         #define GDISP_HARDWARE_PIXELREAD             TRUE |         #define GDISP_HARDWARE_PIXELREAD             TRUE | ||||||
|         #define GDISP_HARDWARE_CONTROL               TRUE |         #define GDISP_HARDWARE_CONTROL               TRUE | ||||||
|  | |||||||
| @ -70,10 +70,33 @@ void lcd_backlight_hal_init(void) { | |||||||
|     RGB_PORT->PCR[BLUE_PIN] = RGB_MODE; |     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) { | void lcd_backlight_hal_color(uint16_t r, uint16_t g, uint16_t b) { | ||||||
| 	CHANNEL_RED.CnV = r; | 	CHANNEL_RED.CnV = cie_lightness(r); | ||||||
| 	CHANNEL_GREEN.CnV = g; | 	CHANNEL_GREEN.CnV = cie_lightness(g); | ||||||
| 	CHANNEL_BLUE.CnV = b; | 	CHANNEL_BLUE.CnV = cie_lightness(b); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| __attribute__ ((weak)) | __attribute__ ((weak)) | ||||||
| @ -103,34 +126,48 @@ void matrix_scan_kb(void) { | |||||||
| 	matrix_scan_user(); | 	matrix_scan_user(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | __attribute__ ((weak)) | ||||||
| void ergodox_board_led_on(void){ | void ergodox_board_led_on(void){ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | __attribute__ ((weak)) | ||||||
| void ergodox_right_led_1_on(void){ | void ergodox_right_led_1_on(void){ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | __attribute__ ((weak)) | ||||||
| void ergodox_right_led_2_on(void){ | void ergodox_right_led_2_on(void){ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | __attribute__ ((weak)) | ||||||
| void ergodox_right_led_3_on(void){ | void ergodox_right_led_3_on(void){ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ergodox_right_led_on(uint8_t led){ | __attribute__ ((weak)) | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void ergodox_board_led_off(void){ | void ergodox_board_led_off(void){ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | __attribute__ ((weak)) | ||||||
| void ergodox_right_led_1_off(void){ | void ergodox_right_led_1_off(void){ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | __attribute__ ((weak)) | ||||||
| void ergodox_right_led_2_off(void){ | void ergodox_right_led_2_off(void){ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | __attribute__ ((weak)) | ||||||
| void ergodox_right_led_3_off(void){ | 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 | #ifdef ONEHAND_ENABLE | ||||||
|  | |||||||
| @ -7,13 +7,38 @@ void ergodox_board_led_on(void); | |||||||
| void ergodox_right_led_1_on(void); | void ergodox_right_led_1_on(void); | ||||||
| void ergodox_right_led_2_on(void); | void ergodox_right_led_2_on(void); | ||||||
| void ergodox_right_led_3_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_board_led_off(void); | ||||||
| void ergodox_right_led_1_off(void); | void ergodox_right_led_1_off(void); | ||||||
| void ergodox_right_led_2_off(void); | void ergodox_right_led_2_off(void); | ||||||
| void ergodox_right_led_3_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) | inline void ergodox_led_all_on(void) | ||||||
| { | { | ||||||
| @ -31,35 +56,21 @@ inline void ergodox_led_all_off(void) | |||||||
|     ergodox_right_led_3_off(); |     ergodox_right_led_3_off(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| inline void ergodox_right_led_1_set(uint8_t n){ | void ergodox_right_led_1_set(uint8_t n); | ||||||
| 	if (n) { | void ergodox_right_led_2_set(uint8_t n); | ||||||
| 		ergodox_right_led_1_on(); | void ergodox_right_led_3_set(uint8_t n); | ||||||
| 	} 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(); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| inline void ergodox_right_led_set(uint8_t led, uint8_t n){ | inline void ergodox_right_led_set(uint8_t led, uint8_t n){ | ||||||
| 	if (n) { |     switch (led) { | ||||||
| 		ergodox_right_led_on(led); |     case 0: | ||||||
| 	} else { |         ergodox_right_led_1_set(n); | ||||||
| 		ergodox_right_led_off(led); |         break; | ||||||
|  |     case 1: | ||||||
|  |         ergodox_right_led_2_set(n); | ||||||
|  |         break; | ||||||
|  |     case 2: | ||||||
|  |         ergodox_right_led_3_set(n); | ||||||
|  |         break; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| # project specific files
 | # project specific files
 | ||||||
| SRC =	matrix.c \
 | SRC =	matrix.c \
 | ||||||
| 	led.c | 	led.c \
 | ||||||
|  | 	animations.c | ||||||
| 
 | 
 | ||||||
| ## chip/board settings
 | ## chip/board settings
 | ||||||
| # - the next two should match the directories in
 | # - the next two should match the directories in
 | ||||||
| @ -59,17 +60,13 @@ OPT_DEFS += -DCORTEX_VTOR_INIT=0x00002000 | |||||||
| #
 | #
 | ||||||
| CUSTOM_MATRIX ?= yes # Custom matrix file | CUSTOM_MATRIX ?= yes # Custom matrix file | ||||||
| SERIAL_LINK_ENABLE = yes | SERIAL_LINK_ENABLE = yes | ||||||
| VISUALIZER_ENABLE ?= no #temporarily disabled to make everything compile | VISUALIZER_ENABLE ?= yes | ||||||
| LCD_ENABLE ?= yes | LCD_ENABLE ?= yes | ||||||
| LED_ENABLE ?= yes | LED_ENABLE ?= no | ||||||
| LCD_BACKLIGHT_ENABLE ?= yes | LCD_BACKLIGHT_ENABLE ?= yes | ||||||
| MIDI_ENABLE = no | MIDI_ENABLE = no | ||||||
| RGBLIGHT_ENABLE = no | RGBLIGHT_ENABLE = no | ||||||
| 
 | 
 | ||||||
| ifndef QUANTUM_DIR |  | ||||||
| 	include ../../../Makefile |  | ||||||
| endif |  | ||||||
| 
 |  | ||||||
| ifdef LCD_ENABLE | ifdef LCD_ENABLE | ||||||
| include $(SUBPROJECT_PATH)/drivers/gdisp/st7565ergodox/driver.mk | include $(SUBPROJECT_PATH)/drivers/gdisp/st7565ergodox/driver.mk | ||||||
| endif | endif | ||||||
|  | |||||||
							
								
								
									
										123
									
								
								keyboards/ergodox/infinity/simple_visualizer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								keyboards/ergodox/infinity/simple_visualizer.h
									
									
									
									
									
										Normal file
									
								
							| @ -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 <http://www.gnu.org/licenses/>.
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #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_ */ | ||||||
							
								
								
									
										329
									
								
								keyboards/ergodox/infinity/visualizer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										329
									
								
								keyboards/ergodox/infinity/visualizer.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,329 @@ | |||||||
|  | /*
 | ||||||
|  | Copyright 2016 Fred Sundvik <fsundvik@gmail.com> | ||||||
|  | 
 | ||||||
|  | This program is free software: you can redistribute it and/or modify | ||||||
|  | it under the terms of the GNU General Public License as published by | ||||||
|  | the Free Software Foundation, either version 2 of the License, or | ||||||
|  | (at your option) any later version. | ||||||
|  | 
 | ||||||
|  | This program is distributed in the hope that it will be useful, | ||||||
|  | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | GNU General Public License for more details. | ||||||
|  | 
 | ||||||
|  | You should have received a copy of the GNU General Public License | ||||||
|  | along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | // 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 "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 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"); | ||||||
|  | 
 | ||||||
|  | // Feel free to modify the animations below, or even add new ones if needed
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // 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 = {backlight_keyframe_set_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 = {backlight_keyframe_set_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 = {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 = {lcd_keyframe_display_layer_bitmap, lcd_keyframe_display_led_states}, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 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); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 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(&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); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 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); | ||||||
|  | } | ||||||
							
								
								
									
										42
									
								
								keyboards/ergodox/keymaps/default/visualizer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								keyboards/ergodox/keymaps/default/visualizer.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | |||||||
|  | /*
 | ||||||
|  | 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 <http://www.gnu.org/licenses/>.
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #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; | ||||||
|  |     } | ||||||
|  |     if (state->status.layer & 0x4) { | ||||||
|  |         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(168, saturation, 0xFF); | ||||||
|  |         state->layer_text = "Symbol"; | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |         state->target_lcd_color = LCD_COLOR(84, saturation, 0xFF); | ||||||
|  |         state->layer_text = "Default"; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										71
									
								
								quantum/led_tables.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								quantum/led_tables.c
									
									
									
									
									
										Normal file
									
								
							| @ -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 <http://www.gnu.org/licenses/>.
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #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 | ||||||
							
								
								
									
										30
									
								
								quantum/led_tables.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								quantum/led_tables.h
									
									
									
									
									
										Normal file
									
								
							| @ -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 <http://www.gnu.org/licenses/>.
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #ifndef LED_TABLES_H | ||||||
|  | #define LED_TABLES_H | ||||||
|  | 
 | ||||||
|  | #include "progmem.h" | ||||||
|  | #include <stdint.h> | ||||||
|  | 
 | ||||||
|  | #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 | ||||||
| @ -20,56 +20,8 @@ | |||||||
| #include "timer.h" | #include "timer.h" | ||||||
| #include "rgblight.h" | #include "rgblight.h" | ||||||
| #include "debug.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)) | __attribute__ ((weak)) | ||||||
| const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5}; | 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; |         break; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   r = pgm_read_byte(&DIM_CURVE[r]); |   r = pgm_read_byte(&CIE1931_CURVE[r]); | ||||||
|   g = pgm_read_byte(&DIM_CURVE[g]); |   g = pgm_read_byte(&CIE1931_CURVE[g]); | ||||||
|   b = pgm_read_byte(&DIM_CURVE[b]); |   b = pgm_read_byte(&CIE1931_CURVE[b]); | ||||||
| 
 | 
 | ||||||
|   setrgb(r, g, b, led1); |   setrgb(r, g, b, led1); | ||||||
| } | } | ||||||
| @ -509,7 +461,7 @@ void rgblight_effect_breathing(uint8_t interval) { | |||||||
|   } |   } | ||||||
|   last_timer = timer_read(); |   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; |   pos = (pos + 1) % 256; | ||||||
| } | } | ||||||
| void rgblight_effect_rainbow_mood(uint8_t interval) { | void rgblight_effect_rainbow_mood(uint8_t interval) { | ||||||
|  | |||||||
| @ -212,7 +212,7 @@ void serial_link_update(void) { | |||||||
| 
 | 
 | ||||||
|     systime_t current_time = chVTGetSystemTimeX(); |     systime_t current_time = chVTGetSystemTimeX(); | ||||||
|     systime_t delta = current_time - last_update; |     systime_t delta = current_time - last_update; | ||||||
|     if (changed || delta > US2ST(1000)) { |     if (changed || delta > US2ST(5000)) { | ||||||
|         last_update = current_time; |         last_update = current_time; | ||||||
|         last_matrix = matrix; |         last_matrix = matrix; | ||||||
|         matrix_object_t* m = begin_write_keyboard_matrix(); |         matrix_object_t* m = begin_write_keyboard_matrix(); | ||||||
|  | |||||||
| @ -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()); |  | ||||||
| } |  | ||||||
| @ -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 */ |  | ||||||
| @ -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; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| @ -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); |  | ||||||
| } |  | ||||||
| @ -25,10 +25,10 @@ SOFTWARE. | |||||||
| #include "lcd_backlight.h" | #include "lcd_backlight.h" | ||||||
| #include <math.h> | #include <math.h> | ||||||
| 
 | 
 | ||||||
| static uint8_t current_hue = 0x00; | static uint8_t current_hue = 0; | ||||||
| static uint8_t current_saturation = 0x00; | static uint8_t current_saturation = 0; | ||||||
| static uint8_t current_intensity = 0xFF; | static uint8_t current_intensity = 0; | ||||||
| static uint8_t current_brightness = 0x7F; | static uint8_t current_brightness = 0; | ||||||
| 
 | 
 | ||||||
| void lcd_backlight_init(void) { | void lcd_backlight_init(void) { | ||||||
|     lcd_backlight_hal_init(); |     lcd_backlight_hal_init(); | ||||||
|  | |||||||
| @ -32,6 +32,10 @@ SOFTWARE. | |||||||
| #define LCD_SAT(color) ((color >> 8) & 0xFF) | #define LCD_SAT(color) ((color >> 8) & 0xFF) | ||||||
| #define LCD_INT(color) (color & 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_init(void); | ||||||
| void lcd_backlight_color(uint8_t hue, uint8_t saturation, uint8_t intensity); | void lcd_backlight_color(uint8_t hue, uint8_t saturation, uint8_t intensity); | ||||||
| void lcd_backlight_brightness(uint8_t b); | void lcd_backlight_brightness(uint8_t b); | ||||||
|  | |||||||
							
								
								
									
										77
									
								
								quantum/visualizer/lcd_backlight_keyframes.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								quantum/visualizer/lcd_backlight_keyframes.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,77 @@ | |||||||
|  | /* 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 <http://www.gnu.org/licenses/>.
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #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; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 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; | ||||||
|  | } | ||||||
							
								
								
									
										30
									
								
								quantum/visualizer/lcd_backlight_keyframes.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								quantum/visualizer/lcd_backlight_keyframes.h
									
									
									
									
									
										Normal file
									
								
							| @ -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 <http://www.gnu.org/licenses/>.
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #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); | ||||||
|  | 
 | ||||||
|  | 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_ */ | ||||||
							
								
								
									
										188
									
								
								quantum/visualizer/lcd_keyframes.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								quantum/visualizer/lcd_keyframes.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,188 @@ | |||||||
|  | /* 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 <http://www.gnu.org/licenses/>.
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include "lcd_keyframes.h" | ||||||
|  | #include <string.h> | ||||||
|  | #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; | ||||||
|  |     gdispClear(White); | ||||||
|  |     gdispDrawString(0, 10, state->layer_text, state->font_dejavusansbold12, Black); | ||||||
|  |     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); | ||||||
|  |     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); | ||||||
|  | 
 | ||||||
|  |     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); | ||||||
|  |     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); | ||||||
|  |     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; | ||||||
|  |     gdispSetPowerMode(powerOff); | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool lcd_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) { | ||||||
|  |     (void)animation; | ||||||
|  |     (void)state; | ||||||
|  |     gdispSetPowerMode(powerOn); | ||||||
|  |     return false; | ||||||
|  | } | ||||||
							
								
								
									
										39
									
								
								quantum/visualizer/lcd_keyframes.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								quantum/visualizer/lcd_keyframes.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | |||||||
|  | /* 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 <http://www.gnu.org/licenses/>.
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #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); | ||||||
|  | // 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); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif /* QUANTUM_VISUALIZER_LCD_KEYFRAMES_H_ */ | ||||||
| @ -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 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||||
| SOFTWARE. | SOFTWARE. | ||||||
| */ | */ | ||||||
| #include "led_test.h" |  | ||||||
| #include "gfx.h" | #include "gfx.h" | ||||||
| #include "math.h" | #include "math.h" | ||||||
| 
 | #include "led_keyframes.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, |  | ||||||
|     }, |  | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| static uint8_t fade_led_color(keyframe_animation_t* animation, int from, int to) { | static uint8_t fade_led_color(keyframe_animation_t* animation, int from, int to) { | ||||||
|     int frame_length = animation->frame_lengths[animation->current_frame]; |     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); |     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; |     (void)state; | ||||||
|     keyframe_fade_all_leds_from_to(animation, 0, 255); |     keyframe_fade_all_leds_from_to(animation, 0, 255); | ||||||
|     return true; |     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; |     (void)state; | ||||||
|     keyframe_fade_all_leds_from_to(animation, 255, 0); |     keyframe_fade_all_leds_from_to(animation, 255, 0); | ||||||
|     return true; |     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; |     (void)state; | ||||||
|     float frame_length = animation->frame_lengths[animation->current_frame]; |     float frame_length = animation->frame_lengths[animation->current_frame]; | ||||||
|     float current_pos = frame_length - animation->time_left_in_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; |     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; |     (void)state; | ||||||
|     float frame_length = animation->frame_lengths[animation->current_frame]; |     float frame_length = animation->frame_lengths[animation->current_frame]; | ||||||
|     float current_pos = frame_length - animation->time_left_in_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; |     (void)state; | ||||||
|     if (animation->first_update_of_frame) { |     if (animation->first_update_of_frame) { | ||||||
|         copy_current_led_state(&crossfade_start_frame[0][0]); |         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; |     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)state; | ||||||
|     (void)animation; |     (void)animation; | ||||||
|     gdispGSetOrientation(LED_DISPLAY, GDISP_ROTATE_180); |     gdispGSetOrientation(LED_DISPLAY, GDISP_ROTATE_180); | ||||||
|     return false; |     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)state; | ||||||
|     (void)animation; |     (void)animation; | ||||||
|     gdispGSetOrientation(LED_DISPLAY, GDISP_ROTATE_0); |     gdispGSetOrientation(LED_DISPLAY, GDISP_ROTATE_0); | ||||||
| @ -22,20 +22,20 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||||||
| SOFTWARE. | SOFTWARE. | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| #ifndef TMK_VISUALIZER_LED_TEST_H_ | #ifndef LED_KEYFRAMES_H | ||||||
| #define TMK_VISUALIZER_LED_TEST_H_ | #define LED_KEYFRAMES_H | ||||||
| 
 | 
 | ||||||
| #include "visualizer.h" | #include "visualizer.h" | ||||||
| 
 | 
 | ||||||
| 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); | ||||||
| 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); | ||||||
| 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); | ||||||
| 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); | ||||||
| bool keyframe_led_crossfade(keyframe_animation_t* animation, visualizer_state_t* state); | bool led_keyframe_crossfade(keyframe_animation_t* animation, visualizer_state_t* state); | ||||||
| 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); | ||||||
| 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); | ||||||
| 
 | 
 | ||||||
| extern keyframe_animation_t led_test_animation; | extern keyframe_animation_t led_test_animation; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #endif /* TMK_VISUALIZER_LED_TEST_H_ */ | #endif /* LED_KEYFRAMES_H */ | ||||||
							
								
								
									
										61
									
								
								quantum/visualizer/resources/lcd_logo.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								quantum/visualizer/resources/lcd_logo.c
									
									
									
									
									
										Normal file
									
								
							| @ -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 <http://www.gnu.org/licenses/>.
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #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 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
							
								
								
									
										
											BIN
										
									
								
								quantum/visualizer/resources/lcd_logo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								quantum/visualizer/resources/lcd_logo.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 490 B | 
							
								
								
									
										27
									
								
								quantum/visualizer/resources/resources.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								quantum/visualizer/resources/resources.h
									
									
									
									
									
										Normal file
									
								
							| @ -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 <http://www.gnu.org/licenses/>.
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef QUANTUM_VISUALIZER_RESOURCES_RESOURCES_H_ | ||||||
|  | #define QUANTUM_VISUALIZER_RESOURCES_RESOURCES_H_ | ||||||
|  | 
 | ||||||
|  | #include <stdint.h> | ||||||
|  | 
 | ||||||
|  | #ifdef LCD_ENABLE | ||||||
|  | extern const uint8_t resource_lcd_logo[]; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif /* QUANTUM_VISUALIZER_RESOURCES_RESOURCES_H_ */ | ||||||
| @ -48,20 +48,22 @@ SOFTWARE. | |||||||
| #include "serial_link/system/serial_link.h" | #include "serial_link/system/serial_link.h" | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #include "action_util.h" | ||||||
|  | 
 | ||||||
| // Define this in config.h
 | // Define this in config.h
 | ||||||
| #ifndef VISUALIZER_THREAD_PRIORITY | #ifndef VISUALIZER_THREAD_PRIORITY | ||||||
| #define "Visualizer thread priority not defined" | #define "Visualizer thread priority not defined" | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| // mods status
 |  | ||||||
| #include "action_util.h" |  | ||||||
| 
 |  | ||||||
| static visualizer_keyboard_status_t current_status = { | static visualizer_keyboard_status_t current_status = { | ||||||
|     .layer = 0xFFFFFFFF, |     .layer = 0xFFFFFFFF, | ||||||
|     .default_layer = 0xFFFFFFFF, |     .default_layer = 0xFFFFFFFF, | ||||||
|     .mods = 0xFF, |     .mods = 0xFF, | ||||||
|     .leds = 0xFFFFFFFF, |     .leds = 0xFFFFFFFF, | ||||||
|     .suspended = false, |     .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) { | static bool same_status(visualizer_keyboard_status_t* status1, visualizer_keyboard_status_t* status2) { | ||||||
| @ -69,11 +71,19 @@ static bool same_status(visualizer_keyboard_status_t* status1, visualizer_keyboa | |||||||
|         status1->default_layer == status2->default_layer && |         status1->default_layer == status2->default_layer && | ||||||
|         status1->mods == status2->mods && |         status1->mods == status2->mods && | ||||||
|         status1->leds == status2->leds && |         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; | 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 | #define MAX_SIMULTANEOUS_ANIMATIONS 4 | ||||||
| static keyframe_animation_t* animations[MAX_SIMULTANEOUS_ANIMATIONS] = {}; | static keyframe_animation_t* animations[MAX_SIMULTANEOUS_ANIMATIONS] = {}; | ||||||
| 
 | 
 | ||||||
| @ -144,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;i<MAX_SIMULTANEOUS_ANIMATIONS;i++) { | ||||||
|  |         count += animations[i] ? 1 : 0; | ||||||
|  |     } | ||||||
|  |     return count; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static bool update_keyframe_animation(keyframe_animation_t* animation, visualizer_state_t* state, systemticks_t delta, systemticks_t* sleep_time) { | static bool update_keyframe_animation(keyframe_animation_t* animation, visualizer_state_t* state, systemticks_t delta, systemticks_t* sleep_time) { | ||||||
|     // TODO: Clean up this messy code
 |     // TODO: Clean up this messy code
 | ||||||
|     dprintf("Animation frame%d, left %d, delta %d\n", animation->current_frame, |     dprintf("Animation frame%d, left %d, delta %d\n", animation->current_frame, | ||||||
| @ -212,175 +230,6 @@ void run_next_keyframe(keyframe_animation_t* animation, visualizer_state_t* stat | |||||||
|     (*temp_animation.frame_functions[next_frame])(&temp_animation, &temp_state); |     (*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; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #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
 |  | ||||||
| 
 |  | ||||||
| #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; |  | ||||||
| } |  | ||||||
| #endif // LCD_ENABLE
 |  | ||||||
| 
 |  | ||||||
| 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; |  | ||||||
|     dprint("User visualizer inited\n"); |  | ||||||
|     visualizer_enabled = true; |  | ||||||
|     return false; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // TODO: Optimize the stack size, this is probably way too big
 | // TODO: Optimize the stack size, this is probably way too big
 | ||||||
| static DECLARE_THREAD_STACK(visualizerThreadStack, 1024); | static DECLARE_THREAD_STACK(visualizerThreadStack, 1024); | ||||||
| static DECLARE_THREAD_FUNCTION(visualizerThread, arg) { | static DECLARE_THREAD_FUNCTION(visualizerThread, arg) { | ||||||
| @ -396,6 +245,9 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) { | |||||||
|         .mods = 0xFF, |         .mods = 0xFF, | ||||||
|         .leds = 0xFFFFFFFF, |         .leds = 0xFFFFFFFF, | ||||||
|         .suspended = false, |         .suspended = false, | ||||||
|  | #ifdef VISUALIZER_USER_DATA_SIZE | ||||||
|  |         .user_data = {0}, | ||||||
|  | #endif | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     visualizer_state_t state = { |     visualizer_state_t state = { | ||||||
| @ -418,13 +270,15 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) { | |||||||
| 
 | 
 | ||||||
|     systemticks_t sleep_time = TIME_INFINITE; |     systemticks_t sleep_time = TIME_INFINITE; | ||||||
|     systemticks_t current_time = gfxSystemTicks(); |     systemticks_t current_time = gfxSystemTicks(); | ||||||
|  |     bool force_update = true; | ||||||
| 
 | 
 | ||||||
|     while(true) { |     while(true) { | ||||||
|         systemticks_t new_time = gfxSystemTicks(); |         systemticks_t new_time = gfxSystemTicks(); | ||||||
|         systemticks_t delta = new_time - current_time; |         systemticks_t delta = new_time - current_time; | ||||||
|         current_time = new_time; |         current_time = new_time; | ||||||
|         bool enabled = visualizer_enabled; |         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 (visualizer_enabled) { | ||||||
|                 if (current_status.suspended) { |                 if (current_status.suspended) { | ||||||
|                     stop_all_keyframe_animations(); |                     stop_all_keyframe_animations(); | ||||||
| @ -433,8 +287,9 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) { | |||||||
|                     user_visualizer_suspend(&state); |                     user_visualizer_suspend(&state); | ||||||
|                 } |                 } | ||||||
|                 else { |                 else { | ||||||
|  |                     visualizer_keyboard_status_t prev_status = state.status; | ||||||
|                     state.status = current_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; |                 state.prev_lcd_color = state.current_lcd_color; | ||||||
|             } |             } | ||||||
| @ -458,13 +313,17 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) { | |||||||
|         gdispGFlush(LED_DISPLAY); |         gdispGFlush(LED_DISPLAY); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #ifdef LCD_ENABLE | ||||||
|  |         gdispGFlush(LCD_DISPLAY); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| #ifdef EMULATOR | #ifdef EMULATOR | ||||||
|         draw_emulator(); |         draw_emulator(); | ||||||
| #endif | #endif | ||||||
|         // The animation can enable the visualizer
 |         // Enable the visualizer when the startup or the suspend animation has finished
 | ||||||
|         // And we might need to update the state when that happens
 |         if (!visualizer_enabled && state.status.suspended == false && get_num_running_animations() == 0) { | ||||||
|         // so don't sleep
 |             visualizer_enabled = true; | ||||||
|         if (enabled != visualizer_enabled) { |             force_update = true; | ||||||
|             sleep_time = 0; |             sleep_time = 0; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| @ -554,6 +413,12 @@ uint8_t visualizer_get_mods() { | |||||||
|   return 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) { | 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
 |     // 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
 |     // a state where one of these are set but not the other. But this should
 | ||||||
| @ -582,6 +447,9 @@ void visualizer_update(uint32_t default_state, uint32_t state, uint8_t mods, uin | |||||||
|             .leds = leds, |             .leds = leds, | ||||||
|             .suspended = current_status.suspended, |             .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)) { |         if (!same_status(¤t_status, &new_status)) { | ||||||
|             changed = true; |             changed = true; | ||||||
|             current_status = new_status; |             current_status = new_status; | ||||||
|  | |||||||
| @ -34,7 +34,7 @@ SOFTWARE. | |||||||
| #include "lcd_backlight.h" | #include "lcd_backlight.h" | ||||||
| #endif | #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); | uint8_t visualizer_get_mods(void); | ||||||
| 
 | 
 | ||||||
| // This need to be called once at the start
 | // This need to be called once at the start
 | ||||||
| @ -68,6 +68,9 @@ typedef struct { | |||||||
|     uint8_t mods; |     uint8_t mods; | ||||||
|     uint32_t leds; // See led.h for available statuses
 |     uint32_t leds; // See led.h for available statuses
 | ||||||
|     bool suspended; |     bool suspended; | ||||||
|  | #ifdef VISUALIZER_USER_DATA_SIZE | ||||||
|  |     uint8_t user_data[VISUALIZER_USER_DATA_SIZE]; | ||||||
|  | #endif | ||||||
| } visualizer_keyboard_status_t; | } visualizer_keyboard_status_t; | ||||||
| 
 | 
 | ||||||
| // The state struct is used by the various keyframe functions
 | // The state struct is used by the various keyframe functions
 | ||||||
| @ -123,32 +126,22 @@ void stop_keyframe_animation(keyframe_animation_t* animation); | |||||||
| // Useful for crossfades for example
 | // Useful for crossfades for example
 | ||||||
| void run_next_keyframe(keyframe_animation_t* animation, visualizer_state_t* state); | void run_next_keyframe(keyframe_animation_t* animation, visualizer_state_t* state); | ||||||
| 
 | 
 | ||||||
| // Some predefined keyframe functions that can be used by the user code
 | // The master can set userdata which will be transferred to the slave
 | ||||||
| // Does nothing, useful for adding delays
 | #ifdef VISUALIZER_USER_DATA_SIZE | ||||||
| bool keyframe_no_operation(keyframe_animation_t* animation, visualizer_state_t* state); | void visualizer_set_user_data(void* user_data); | ||||||
| // Animates the LCD backlight color between the current color and the target color (of the state)
 | #endif | ||||||
| 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); |  | ||||||
| 
 |  | ||||||
| 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); |  | ||||||
| 
 | 
 | ||||||
| // These functions have to be implemented by the user
 | // 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); | 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); | 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); | void user_visualizer_resume(visualizer_state_t* state); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| #endif /* VISUALIZER_H */ | #endif /* VISUALIZER_H */ | ||||||
|  | |||||||
| @ -20,7 +20,8 @@ | |||||||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | ||||||
| # SOFTWARE.
 | # SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| SRC += $(VISUALIZER_DIR)/visualizer.c | SRC += $(VISUALIZER_DIR)/visualizer.c \
 | ||||||
|  | 	$(VISUALIZER_DIR)/visualizer_keyframes.c | ||||||
| EXTRAINCDIRS += $(GFXINC) $(VISUALIZER_DIR) | EXTRAINCDIRS += $(GFXINC) $(VISUALIZER_DIR) | ||||||
| GFXLIB = $(LIB_PATH)/ugfx | GFXLIB = $(LIB_PATH)/ugfx | ||||||
| VPATH += $(VISUALIZER_PATH) | VPATH += $(VISUALIZER_PATH) | ||||||
| @ -32,25 +33,33 @@ OPT_DEFS += -DLCD_ENABLE | |||||||
| ULIBS += -lm | ULIBS += -lm | ||||||
| endif | endif | ||||||
| 
 | 
 | ||||||
| ifdef LCD_BACKLIGHT_ENABLE | ifeq ($(strip $(LCD_ENABLE)), yes) | ||||||
| SRC += $(VISUALIZER_DIR)/lcd_backlight.c | 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 | OPT_DEFS += -DLCD_BACKLIGHT_ENABLE | ||||||
| endif | endif | ||||||
| 
 | 
 | ||||||
| ifdef LED_ENABLE | ifeq ($(strip $(LED_ENABLE)), yes) | ||||||
| SRC += $(VISUALIZER_DIR)/led_test.c | SRC += $(VISUALIZER_DIR)/led_keyframes.c | ||||||
| OPT_DEFS += -DLED_ENABLE | OPT_DEFS += -DLED_ENABLE | ||||||
| endif | endif | ||||||
| 
 | 
 | ||||||
| include $(GFXLIB)/gfx.mk | include $(GFXLIB)/gfx.mk | ||||||
| SRC += $(patsubst $(TOP_DIR)/%,%,$(GFXSRC)) | GFXSRC := $(patsubst $(TOP_DIR)/%,%,$(GFXSRC)) | ||||||
| OPT_DEFS += $(patsubst %,-D%,$(patsubst -D%,%,$(GFXDEFS))) | GFXDEFS := $(patsubst %,-D%,$(patsubst -D%,%,$(GFXDEFS))) | ||||||
| 
 | 
 | ||||||
| ifneq ("$(wildcard $(KEYMAP_PATH)/visualizer.c)","") | ifneq ("$(wildcard $(KEYMAP_PATH)/visualizer.c)","") | ||||||
| 	SRC += keyboards/$(KEYBOARD)/keymaps/$(KEYMAP)/visualizer.c | 	SRC += keyboards/$(KEYBOARD)/keymaps/$(KEYMAP)/visualizer.c | ||||||
| else  | else  | ||||||
| 	ifeq ("$(wildcard $(SUBPROJECT_PATH)/keymaps/$(KEYMAP)/visualizer.c)","") | 	ifeq ("$(wildcard $(SUBPROJECT_PATH)/keymaps/$(KEYMAP)/visualizer.c)","") | ||||||
|  | 		ifeq ("$(wildcard $(SUBPROJECT_PATH)/visualizer.c)","") | ||||||
| $(error "$(KEYMAP_PATH)/visualizer.c" does not exist) | $(error "$(KEYMAP_PATH)/visualizer.c" does not exist) | ||||||
|  | 		else | ||||||
|  | 			SRC += keyboards/$(KEYBOARD)/$(SUBPROJECT)/visualizer.c | ||||||
|  | 		endif | ||||||
| 	else | 	else | ||||||
| 		SRC += keyboards/$(KEYBOARD)/$(SUBPROJECT)/keymaps/$(KEYMAP)/visualizer.c | 		SRC += keyboards/$(KEYBOARD)/$(SUBPROJECT)/keymaps/$(KEYMAP)/visualizer.c | ||||||
| 	endif | 	endif | ||||||
|  | |||||||
							
								
								
									
										23
									
								
								quantum/visualizer/visualizer_keyframes.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								quantum/visualizer/visualizer_keyframes.c
									
									
									
									
									
										Normal file
									
								
							| @ -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 <http://www.gnu.org/licenses/>.
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include "visualizer_keyframes.h" | ||||||
|  | 
 | ||||||
|  | bool keyframe_no_operation(keyframe_animation_t* animation, visualizer_state_t* state) { | ||||||
|  |     (void)animation; | ||||||
|  |     (void)state; | ||||||
|  |     return false; | ||||||
|  | } | ||||||
							
								
								
									
										26
									
								
								quantum/visualizer/visualizer_keyframes.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								quantum/visualizer/visualizer_keyframes.h
									
									
									
									
									
										Normal file
									
								
							| @ -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 <http://www.gnu.org/licenses/>.
 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #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_ */ | ||||||
| @ -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; } | void clear_oneshot_locked_mods(void) { oneshot_locked_mods = 0; } | ||||||
| #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||||||
| static int16_t oneshot_time = 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; |   return TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT; | ||||||
| } | } | ||||||
|  | #else | ||||||
|  | bool has_oneshot_mods_timed_out(void) { | ||||||
|  |     return false; | ||||||
|  | } | ||||||
| #endif | #endif | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Jack Humbert
						Jack Humbert