aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFred Sundvik <fsundvik@gmail.com>2017-04-01 22:52:58 +0300
committerFred Sundvik <fsundvik@gmail.com>2017-04-09 18:34:59 +0300
commit9a4ce28683b667ab67d48d92196bab7e277d4800 (patch)
treead518ba049f16a6877775d28aa283d2ff8cc8c34
parent951b6f33a0dc479d29831aaa5c73fc526faf0471 (diff)
downloadqmk_firmware-9a4ce28683b667ab67d48d92196bab7e277d4800.tar.gz
qmk_firmware-9a4ce28683b667ab67d48d92196bab7e277d4800.zip
Display layer bitmap and keyboard led states on the LCD
-rw-r--r--keyboards/ergodox/infinity/visualizer.c86
-rw-r--r--quantum/visualizer/visualizer.c38
-rw-r--r--quantum/visualizer/visualizer.h4
3 files changed, 97 insertions, 31 deletions
diff --git a/keyboards/ergodox/infinity/visualizer.c b/keyboards/ergodox/infinity/visualizer.c
index 12336fdc5..6af3a72ee 100644
--- a/keyboards/ergodox/infinity/visualizer.c
+++ b/keyboards/ergodox/infinity/visualizer.c
@@ -73,6 +73,14 @@ static const uint8_t image_data_lcd_logo[512] = {
73static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0xFF); 73static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0xFF);
74static const uint32_t initial_color = LCD_COLOR(0, 0, 0); 74static const uint32_t initial_color = LCD_COLOR(0, 0, 0);
75 75
76typedef enum {
77 LCD_STATE_INITIAL,
78 LCD_STATE_LAYER_BITMAP,
79 LCD_STATE_BITMAP_AND_LEDS,
80} lcd_state_t;
81
82static lcd_state_t lcd_state = LCD_STATE_INITIAL;
83
76bool display_logo(keyframe_animation_t* animation, visualizer_state_t* state) { 84bool display_logo(keyframe_animation_t* animation, visualizer_state_t* state) {
77 (void)state; 85 (void)state;
78 (void)animation; 86 (void)animation;
@@ -122,11 +130,18 @@ static keyframe_animation_t color_animation = {
122 130
123// The LCD animation alternates between the layer name display and a 131// The LCD animation alternates between the layer name display and a
124// bitmap that displays all active layers 132// bitmap that displays all active layers
125static keyframe_animation_t lcd_animation = { 133static keyframe_animation_t lcd_bitmap_animation = {
134 .num_frames = 1,
135 .loop = false,
136 .frame_lengths = {gfxMillisecondsToTicks(0)},
137 .frame_functions = {keyframe_display_layer_bitmap},
138};
139
140static keyframe_animation_t lcd_bitmap_leds_animation = {
126 .num_frames = 2, 141 .num_frames = 2,
127 .loop = true, 142 .loop = true,
128 .frame_lengths = {gfxMillisecondsToTicks(2000), gfxMillisecondsToTicks(2000)}, 143 .frame_lengths = {gfxMillisecondsToTicks(2000), gfxMillisecondsToTicks(2000)},
129 .frame_functions = {keyframe_display_layer_text, keyframe_display_layer_bitmap}, 144 .frame_functions = {keyframe_display_layer_bitmap, keyframe_display_led_states},
130}; 145};
131 146
132static keyframe_animation_t suspend_animation = { 147static keyframe_animation_t suspend_animation = {
@@ -158,38 +173,50 @@ void initialize_user_visualizer(visualizer_state_t* state) {
158 lcd_backlight_brightness(130); 173 lcd_backlight_brightness(130);
159 state->current_lcd_color = initial_color; 174 state->current_lcd_color = initial_color;
160 state->target_lcd_color = logo_background_color; 175 state->target_lcd_color = logo_background_color;
176 lcd_state = LCD_STATE_INITIAL;
161 start_keyframe_animation(&startup_animation); 177 start_keyframe_animation(&startup_animation);
162} 178}
163 179
164void update_user_visualizer_state(visualizer_state_t* state) { 180void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t prev_status) {
165 // Add more tests, change the colors and layer texts here 181 // Check the status here to start and stop animations
166 // Usually you want to check the high bits (higher layers first) 182 // You might have to save some state, like the current animation here so that you can start the right
167 // because that's the order layers are processed for keypresses 183 // This function is called every time the status changes
168 // You can for check for example: 184
169 // state->status.layer 185 // NOTE that this is called from the visualizer thread, so don't access anything else outside the status
170 // state->status.default_layer 186 // This is also important because the slave won't have access to the active layer for example outside the
171 // state->status.leds (see led.h for available statuses) 187 // status.
172 if (state->status.layer & 0x8) { 188
173 state->target_lcd_color = LCD_COLOR(0xC0, 0xB0, 0xFF); 189 if (lcd_state == LCD_STATE_INITIAL) {
174 state->layer_text = "Numpad";
175 }
176 else if (state->status.layer & 0x4) {
177 state->target_lcd_color = LCD_COLOR(0, 0xB0, 0xFF);
178 state->layer_text = "KBD functions";
179 }
180 else if (state->status.layer & 0x2) {
181 state->target_lcd_color = LCD_COLOR(0x80, 0xB0, 0xFF);
182 state->layer_text = "Function keys";
183 }
184 else {
185 state->target_lcd_color = LCD_COLOR(0x40, 0xB0, 0xFF); 190 state->target_lcd_color = LCD_COLOR(0x40, 0xB0, 0xFF);
186 state->layer_text = "Default"; 191 start_keyframe_animation(&color_animation);
192 }
193
194 if (state->status.leds) {
195 if (lcd_state != LCD_STATE_BITMAP_AND_LEDS ||
196 state->status.leds != prev_status.leds ||
197 state->status.layer != prev_status.layer ||
198 state->status.default_layer != prev_status.default_layer) {
199
200 // NOTE: that it doesn't matter if the animation isn't playing, stop will do nothing in that case
201 stop_keyframe_animation(&lcd_bitmap_animation);
202
203 lcd_state = LCD_STATE_BITMAP_AND_LEDS;
204 // For information:
205 // The logic in this function makes sure that this doesn't happen, but if you call start on an
206 // animation that is already playing it will be restarted.
207 start_keyframe_animation(&lcd_bitmap_leds_animation);
208 }
209 } else {
210 if (lcd_state != LCD_STATE_LAYER_BITMAP ||
211 state->status.layer != prev_status.layer ||
212 state->status.default_layer != prev_status.default_layer) {
213
214 stop_keyframe_animation(&lcd_bitmap_leds_animation);
215
216 lcd_state = LCD_STATE_LAYER_BITMAP;
217 start_keyframe_animation(&lcd_bitmap_animation);
218 }
187 } 219 }
188 // You can also stop existing animations, and start your custom ones here
189 // remember that you should normally have only one animation for the LCD
190 // and one for the background. But you can also combine them if you want.
191 start_keyframe_animation(&lcd_animation);
192 start_keyframe_animation(&color_animation);
193} 220}
194 221
195void user_visualizer_suspend(visualizer_state_t* state) { 222void user_visualizer_suspend(visualizer_state_t* state) {
@@ -203,5 +230,6 @@ void user_visualizer_suspend(visualizer_state_t* state) {
203void user_visualizer_resume(visualizer_state_t* state) { 230void user_visualizer_resume(visualizer_state_t* state) {
204 state->current_lcd_color = initial_color; 231 state->current_lcd_color = initial_color;
205 state->target_lcd_color = logo_background_color; 232 state->target_lcd_color = logo_background_color;
233 lcd_state = LCD_STATE_INITIAL;
206 start_keyframe_animation(&resume_animation); 234 start_keyframe_animation(&resume_animation);
207} 235}
diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c
index 5826d909e..62ebebcee 100644
--- a/quantum/visualizer/visualizer.c
+++ b/quantum/visualizer/visualizer.c
@@ -56,6 +56,8 @@ SOFTWARE.
56// mods status 56// mods status
57#include "action_util.h" 57#include "action_util.h"
58 58
59#include "led.h"
60
59static visualizer_keyboard_status_t current_status = { 61static visualizer_keyboard_status_t current_status = {
60 .layer = 0xFFFFFFFF, 62 .layer = 0xFFFFFFFF,
61 .default_layer = 0xFFFFFFFF, 63 .default_layer = 0xFFFFFFFF,
@@ -350,6 +352,39 @@ bool keyframe_display_mods_bitmap(keyframe_animation_t* animation, visualizer_st
350 gdispFlush(); 352 gdispFlush();
351 return false; 353 return false;
352} 354}
355
356bool keyframe_display_led_states(keyframe_animation_t* animation, visualizer_state_t* state)
357{
358 char output[sizeof("NUM CAPS SCRL COMP KANA")];
359 uint8_t pos = 0;
360
361 if (state->status.leds & (1u << USB_LED_NUM_LOCK)) {
362 memcpy(output + pos, "NUM ", 4);
363 pos += 4;
364 }
365 if (state->status.leds & (1u << USB_LED_CAPS_LOCK)) {
366 memcpy(output + pos, "CAPS ", 5);
367 pos += 5;
368 }
369 if (state->status.leds & (1u << USB_LED_SCROLL_LOCK)) {
370 memcpy(output + pos, "SCRL ", 5);
371 pos += 5;
372 }
373 if (state->status.leds & (1u << USB_LED_COMPOSE)) {
374 memcpy(output + pos, "COMP ", 5);
375 pos += 5;
376 }
377 if (state->status.leds & (1u << USB_LED_KANA)) {
378 memcpy(output + pos, "KANA ", 5);
379 pos += 5;
380 }
381 output[pos] = 0;
382 gdispClear(White);
383 gdispDrawString(0, 10, output, state->font_dejavusansbold12, Black);
384 gdispFlush();
385 return false;
386}
387
353#endif // LCD_ENABLE 388#endif // LCD_ENABLE
354 389
355bool keyframe_disable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state) { 390bool keyframe_disable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state) {
@@ -433,8 +468,9 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) {
433 user_visualizer_suspend(&state); 468 user_visualizer_suspend(&state);
434 } 469 }
435 else { 470 else {
471 visualizer_keyboard_status_t prev_status = state.status;
436 state.status = current_status; 472 state.status = current_status;
437 update_user_visualizer_state(&state); 473 update_user_visualizer_state(&state, prev_status);
438 } 474 }
439 state.prev_lcd_color = state.current_lcd_color; 475 state.prev_lcd_color = state.current_lcd_color;
440 } 476 }
diff --git a/quantum/visualizer/visualizer.h b/quantum/visualizer/visualizer.h
index 315af5022..2c81cb9f7 100644
--- a/quantum/visualizer/visualizer.h
+++ b/quantum/visualizer/visualizer.h
@@ -136,6 +136,8 @@ bool keyframe_display_layer_text(keyframe_animation_t* animation, visualizer_sta
136bool keyframe_display_layer_bitmap(keyframe_animation_t* animation, visualizer_state_t* state); 136bool keyframe_display_layer_bitmap(keyframe_animation_t* animation, visualizer_state_t* state);
137// Displays a bitmap (0/1) of all the currently active mods 137// Displays a bitmap (0/1) of all the currently active mods
138bool keyframe_display_mods_bitmap(keyframe_animation_t* animation, visualizer_state_t* state); 138bool keyframe_display_mods_bitmap(keyframe_animation_t* animation, visualizer_state_t* state);
139// Displays the keyboard led states (CAPS (Caps lock), NUM (Num lock), SCRL (Scroll lock), COMP (Compose), KANA)
140bool keyframe_display_led_states(keyframe_animation_t* animation, visualizer_state_t* state);
139 141
140bool keyframe_disable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state); 142bool keyframe_disable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state);
141bool keyframe_enable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state); 143bool keyframe_enable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state);
@@ -146,7 +148,7 @@ bool enable_visualization(keyframe_animation_t* animation, visualizer_state_t* s
146 148
147// These functions have to be implemented by the user 149// These functions have to be implemented by the user
148void initialize_user_visualizer(visualizer_state_t* state); 150void initialize_user_visualizer(visualizer_state_t* state);
149void update_user_visualizer_state(visualizer_state_t* state); 151void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t prev_status);
150void user_visualizer_suspend(visualizer_state_t* state); 152void user_visualizer_suspend(visualizer_state_t* state);
151void user_visualizer_resume(visualizer_state_t* state); 153void user_visualizer_resume(visualizer_state_t* state);
152 154