aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFred Sundvik <fsundvik@gmail.com>2017-04-03 23:00:58 +0300
committerFred Sundvik <fsundvik@gmail.com>2017-04-09 18:34:59 +0300
commitfa6da78ff3c96a71ed65684e276352700843d539 (patch)
treeaabeb20e2d6bda0e7ca3a9bcfa2ba2f1c1b5bc0f
parent65e8127c91c6a0fc027a1a482de443302e00d019 (diff)
downloadqmk_firmware-fa6da78ff3c96a71ed65684e276352700843d539.tar.gz
qmk_firmware-fa6da78ff3c96a71ed65684e276352700843d539.zip
Simple layer display on Infinity Ergodox default layout
-rw-r--r--keyboards/ergodox/keymaps/default/visualizer.c286
1 files changed, 62 insertions, 224 deletions
diff --git a/keyboards/ergodox/keymaps/default/visualizer.c b/keyboards/ergodox/keymaps/default/visualizer.c
index c7afd9384..d99d5f702 100644
--- a/keyboards/ergodox/keymaps/default/visualizer.c
+++ b/keyboards/ergodox/keymaps/default/visualizer.c
@@ -1,5 +1,5 @@
1/* 1/*
2Copyright 2016 Fred Sundvik <fsundvik@gmail.com> 2Copyright 2017 Fred Sundvik
3 3
4This program is free software: you can redistribute it and/or modify 4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by 5it under the terms of the GNU General Public License as published by
@@ -74,15 +74,6 @@ static const uint8_t image_data_lcd_logo[512] = {
74static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0xFF); 74static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0xFF);
75static const uint32_t initial_color = LCD_COLOR(0, 0, 0); 75static const uint32_t initial_color = LCD_COLOR(0, 0, 0);
76 76
77static const uint32_t led_emulation_colors[4] = {
78 LCD_COLOR(0, 0, 0),
79 LCD_COLOR(255, 255, 255),
80 LCD_COLOR(84, 255, 255),
81 LCD_COLOR(168, 255, 255),
82};
83
84static uint32_t next_led_target_color = 0;
85
86typedef enum { 77typedef enum {
87 LCD_STATE_INITIAL, 78 LCD_STATE_INITIAL,
88 LCD_STATE_LAYER_BITMAP, 79 LCD_STATE_LAYER_BITMAP,
@@ -91,24 +82,6 @@ typedef enum {
91 82
92static lcd_state_t lcd_state = LCD_STATE_INITIAL; 83static lcd_state_t lcd_state = LCD_STATE_INITIAL;
93 84
94typedef struct {
95 uint8_t led_on;
96 uint8_t led1;
97 uint8_t led2;
98 uint8_t led3;
99} visualizer_user_data_t;
100
101// Don't access from visualization function, use the visualizer state instead
102static visualizer_user_data_t user_data_keyboard = {
103 .led_on = 0,
104 .led1 = LED_BRIGHTNESS_HI,
105 .led2 = LED_BRIGHTNESS_HI,
106 .led3 = LED_BRIGHTNESS_HI,
107};
108
109_Static_assert(sizeof(visualizer_user_data_t) <= VISUALIZER_USER_DATA_SIZE,
110 "Please increase the VISUALIZER_USER_DATA_SIZE");
111
112bool display_logo(keyframe_animation_t* animation, visualizer_state_t* state) { 85bool display_logo(keyframe_animation_t* animation, visualizer_state_t* state) {
113 (void)state; 86 (void)state;
114 (void)animation; 87 (void)animation;
@@ -144,43 +117,34 @@ static keyframe_animation_t startup_animation = {
144 }, 117 },
145}; 118};
146 119
147// The color animation animates the LCD color when you change layers
148static keyframe_animation_t one_led_color = {
149 .num_frames = 1,
150 .loop = false,
151 .frame_lengths = {gfxMillisecondsToTicks(0)},
152 .frame_functions = {keyframe_set_backlight_color},
153};
154
155bool swap_led_target_color(keyframe_animation_t* animation, visualizer_state_t* state) {
156 uint32_t temp = next_led_target_color;
157 next_led_target_color = state->target_lcd_color;
158 state->target_lcd_color = temp;
159 return false;
160}
161
162// The color animation animates the LCD color when you change layers
163static keyframe_animation_t two_led_colors = {
164 .num_frames = 2,
165 .loop = true,
166 .frame_lengths = {gfxMillisecondsToTicks(1000), gfxMillisecondsToTicks(0)},
167 .frame_functions = {keyframe_set_backlight_color, swap_led_target_color},
168};
169
170// The LCD animation alternates between the layer name display and a 120// The LCD animation alternates between the layer name display and a
171// bitmap that displays all active layers 121// bitmap that displays all active layers
172static keyframe_animation_t lcd_bitmap_animation = { 122static keyframe_animation_t lcd_layer_bitmap_animation = {
173 .num_frames = 1, 123 .num_frames = 2,
174 .loop = false, 124 .loop = true,
175 .frame_lengths = {gfxMillisecondsToTicks(0)}, 125 .frame_lengths = {
176 .frame_functions = {keyframe_display_layer_bitmap}, 126 gfxMillisecondsToTicks(2000),
127 gfxMillisecondsToTicks(2000)
128 },
129 .frame_functions = {
130 keyframe_display_layer_text,
131 keyframe_display_layer_bitmap
132 },
177}; 133};
178 134
179static keyframe_animation_t lcd_bitmap_leds_animation = { 135static keyframe_animation_t lcd_layer_bitmap_leds_animation = {
180 .num_frames = 2, 136 .num_frames = 3,
181 .loop = true, 137 .loop = true,
182 .frame_lengths = {gfxMillisecondsToTicks(2000), gfxMillisecondsToTicks(2000)}, 138 .frame_lengths = {
183 .frame_functions = {keyframe_display_layer_bitmap, keyframe_display_led_states}, 139 gfxMillisecondsToTicks(2000),
140 gfxMillisecondsToTicks(2000),
141 gfxMillisecondsToTicks(2000)
142 },
143 .frame_functions = {
144 keyframe_display_layer_text,
145 keyframe_display_led_states,
146 keyframe_display_layer_bitmap,
147 },
184}; 148};
185 149
186static keyframe_animation_t suspend_animation = { 150static keyframe_animation_t suspend_animation = {
@@ -206,6 +170,17 @@ static keyframe_animation_t resume_animation = {
206 }, 170 },
207}; 171};
208 172
173// The color animation animates the LCD color when you change layers
174static keyframe_animation_t color_animation = {
175 .num_frames = 2,
176 .loop = false,
177 // Note that there's a 200 ms no-operation frame,
178 // this prevents the color from changing when activating the layer
179 // momentarily
180 .frame_lengths = {gfxMillisecondsToTicks(200), gfxMillisecondsToTicks(500)},
181 .frame_functions = {keyframe_no_operation, keyframe_animate_backlight_color},
182};
183
209void initialize_user_visualizer(visualizer_state_t* state) { 184void initialize_user_visualizer(visualizer_state_t* state) {
210 // The brightness will be dynamically adjustable in the future 185 // The brightness will be dynamically adjustable in the future
211 // But for now, change it here. 186 // But for now, change it here.
@@ -216,105 +191,32 @@ void initialize_user_visualizer(visualizer_state_t* state) {
216 start_keyframe_animation(&startup_animation); 191 start_keyframe_animation(&startup_animation);
217} 192}
218 193
219static const uint32_t red; 194void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) {
220static const uint32_t green; 195 // Add more tests, change the colors and layer texts here
221static const uint32_t blue; 196 // Usually you want to check the high bits (higher layers first)
222 197 // because that's the order layers are processed for keypresses
223inline bool is_led_on(visualizer_user_data_t* user_data, uint8_t num) { 198 // You can for check for example:
224 return user_data->led_on & (1u << num); 199 // state->status.layer
225} 200 // state->status.default_layer
226 201 // state->status.leds (see led.h for available statuses)
227static uint8_t get_led_index_master(visualizer_user_data_t* user_data) { 202
228 for (int i=0; i < 3; i++) { 203 if (state->status.layer & 0x4) {
229 if (is_led_on(user_data, i)) { 204 state->target_lcd_color = LCD_COLOR(0, 0xB0, 0xFF);
230 return i + 1; 205 state->layer_text = "Media & Mouse";
231 }
232 }
233 return 0;
234}
235
236static uint8_t get_led_index_slave(visualizer_user_data_t* user_data) {
237 uint8_t master_index = get_led_index_master(user_data);
238 if (master_index!=0) {
239 for (int i=master_index; i < 3; i++) {
240 if (is_led_on(user_data, i)) {
241 return i + 1;
242 }
243 }
244 }
245
246 return 0;
247}
248
249static uint8_t get_secondary_led_index(visualizer_user_data_t* user_data) {
250 if (is_led_on(user_data, 0) &&
251 is_led_on(user_data, 1) &&
252 is_led_on(user_data, 2)) {
253 return 3;
254 }
255 return 0;
256}
257
258static uint8_t get_brightness(visualizer_user_data_t* user_data, uint8_t index) {
259 switch (index) {
260 case 1:
261 return user_data->led1;
262 case 2:
263 return user_data->led2;
264 case 3:
265 return user_data->led3;
266 } 206 }
267 return 0; 207 else if (state->status.layer & 0x2) {
268} 208 state->target_lcd_color = LCD_COLOR(0x80, 0xB0, 0xFF);
269 209 state->layer_text = "Symbol";
270static void update_emulated_leds(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) {
271 visualizer_user_data_t* user_data_new = (visualizer_user_data_t*)state->status.user_data;
272 visualizer_user_data_t* user_data_old = (visualizer_user_data_t*)prev_status->user_data;
273
274 uint8_t new_index;
275 uint8_t old_index;
276
277 if (is_serial_link_master()) {
278 new_index = get_led_index_master(user_data_new);
279 old_index = get_led_index_master(user_data_old);
280 } 210 }
281 else { 211 else {
282 new_index = get_led_index_slave(user_data_new); 212 state->target_lcd_color = LCD_COLOR(0x40, 0xB0, 0xFF);
283 old_index = get_led_index_slave(user_data_old); 213 state->layer_text = "Default";
284 } 214 }
285 uint8_t new_secondary_index = get_secondary_led_index(user_data_new); 215
286 uint8_t old_secondary_index = get_secondary_led_index(user_data_old); 216 if (lcd_state == LCD_STATE_INITIAL || state->status.layer != prev_status->layer) {
287 217 start_keyframe_animation(&color_animation);
288 uint8_t old_brightness = get_brightness(user_data_old, old_index);
289 uint8_t new_brightness = get_brightness(user_data_new, new_index);
290
291 uint8_t old_secondary_brightness = get_brightness(user_data_old, old_secondary_index);
292 uint8_t new_secondary_brightness = get_brightness(user_data_new, new_secondary_index);
293
294 if (lcd_state == LCD_STATE_INITIAL ||
295 new_index != old_index ||
296 new_secondary_index != old_secondary_index ||
297 new_brightness != old_brightness ||
298 new_secondary_brightness != old_secondary_brightness) {
299
300 if (new_secondary_index != 0) {
301 state->target_lcd_color = change_lcd_color_intensity(
302 led_emulation_colors[new_index], new_brightness);
303 next_led_target_color = change_lcd_color_intensity(
304 led_emulation_colors[new_secondary_index], new_secondary_brightness);
305
306 stop_keyframe_animation(&one_led_color);
307 start_keyframe_animation(&two_led_colors);
308 } else {
309 state->target_lcd_color = change_lcd_color_intensity(
310 led_emulation_colors[new_index], new_brightness);
311 stop_keyframe_animation(&two_led_colors);
312 start_keyframe_animation(&one_led_color);
313 }
314 } 218 }
315}
316 219
317static void update_lcd_text(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) {
318 if (state->status.leds) { 220 if (state->status.leds) {
319 if (lcd_state != LCD_STATE_BITMAP_AND_LEDS || 221 if (lcd_state != LCD_STATE_BITMAP_AND_LEDS ||
320 state->status.leds != prev_status->leds || 222 state->status.leds != prev_status->leds ||
@@ -322,39 +224,28 @@ static void update_lcd_text(visualizer_state_t* state, visualizer_keyboard_statu
322 state->status.default_layer != prev_status->default_layer) { 224 state->status.default_layer != prev_status->default_layer) {
323 225
324 // NOTE: that it doesn't matter if the animation isn't playing, stop will do nothing in that case 226 // NOTE: that it doesn't matter if the animation isn't playing, stop will do nothing in that case
325 stop_keyframe_animation(&lcd_bitmap_animation); 227 stop_keyframe_animation(&lcd_layer_bitmap_animation);
326 228
327 lcd_state = LCD_STATE_BITMAP_AND_LEDS; 229 lcd_state = LCD_STATE_BITMAP_AND_LEDS;
328 // For information: 230 // For information:
329 // The logic in this function makes sure that this doesn't happen, but if you call start on an 231 // The logic in this function makes sure that this doesn't happen, but if you call start on an
330 // animation that is already playing it will be restarted. 232 // animation that is already playing it will be restarted.
331 start_keyframe_animation(&lcd_bitmap_leds_animation); 233 start_keyframe_animation(&lcd_layer_bitmap_leds_animation);
332 } 234 }
333 } else { 235 } else {
334 if (lcd_state != LCD_STATE_LAYER_BITMAP || 236 if (lcd_state != LCD_STATE_LAYER_BITMAP ||
335 state->status.layer != prev_status->layer || 237 state->status.layer != prev_status->layer ||
336 state->status.default_layer != prev_status->default_layer) { 238 state->status.default_layer != prev_status->default_layer) {
337 239
338 stop_keyframe_animation(&lcd_bitmap_leds_animation); 240 stop_keyframe_animation(&lcd_layer_bitmap_leds_animation);
339 241
340 lcd_state = LCD_STATE_LAYER_BITMAP; 242 lcd_state = LCD_STATE_LAYER_BITMAP;
341 start_keyframe_animation(&lcd_bitmap_animation); 243 start_keyframe_animation(&lcd_layer_bitmap_animation);
342 } 244 }
343 } 245 }
344} 246 // You can also stop existing animations, and start your custom ones here
345 247 // remember that you should normally have only one animation for the LCD
346void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) { 248 // and one for the background. But you can also combine them if you want.
347 // Check the status here to start and stop animations
348 // You might have to save some state, like the current animation here so that you can start the right
349 // This function is called every time the status changes
350
351 // NOTE that this is called from the visualizer thread, so don't access anything else outside the status
352 // This is also important because the slave won't have access to the active layer for example outside the
353 // status.
354
355 update_emulated_leds(state, prev_status);
356 update_lcd_text(state, prev_status);
357
358} 249}
359 250
360void user_visualizer_suspend(visualizer_state_t* state) { 251void user_visualizer_suspend(visualizer_state_t* state) {
@@ -371,56 +262,3 @@ void user_visualizer_resume(visualizer_state_t* state) {
371 lcd_state = LCD_STATE_INITIAL; 262 lcd_state = LCD_STATE_INITIAL;
372 start_keyframe_animation(&resume_animation); 263 start_keyframe_animation(&resume_animation);
373} 264}
374
375void ergodox_board_led_on(void){
376 // No board led support
377}
378
379void ergodox_right_led_1_on(void){
380 user_data_keyboard.led_on |= (1u << 0);
381 visualizer_set_user_data(&user_data_keyboard);
382}
383
384void ergodox_right_led_2_on(void){
385 user_data_keyboard.led_on |= (1u << 1);
386 visualizer_set_user_data(&user_data_keyboard);
387}
388
389void ergodox_right_led_3_on(void){
390 user_data_keyboard.led_on |= (1u << 2);
391 visualizer_set_user_data(&user_data_keyboard);
392}
393
394void ergodox_board_led_off(void){
395 // No board led support
396}
397
398void ergodox_right_led_1_off(void){
399 user_data_keyboard.led_on &= ~(1u << 0);
400 visualizer_set_user_data(&user_data_keyboard);
401}
402
403void ergodox_right_led_2_off(void){
404 user_data_keyboard.led_on &= ~(1u << 1);
405 visualizer_set_user_data(&user_data_keyboard);
406}
407
408void ergodox_right_led_3_off(void){
409 user_data_keyboard.led_on &= ~(1u << 2);
410 visualizer_set_user_data(&user_data_keyboard);
411}
412
413void ergodox_right_led_1_set(uint8_t n) {
414 user_data_keyboard.led1 = n;
415 visualizer_set_user_data(&user_data_keyboard);
416}
417
418void ergodox_right_led_2_set(uint8_t n) {
419 user_data_keyboard.led2 = n;
420 visualizer_set_user_data(&user_data_keyboard);
421}
422
423void ergodox_right_led_3_set(uint8_t n) {
424 user_data_keyboard.led3 = n;
425 visualizer_set_user_data(&user_data_keyboard);
426}