diff options
Diffstat (limited to 'keyboards/ergodox/infinity/visualizer.c')
| -rw-r--r-- | keyboards/ergodox/infinity/visualizer.c | 175 |
1 files changed, 165 insertions, 10 deletions
diff --git a/keyboards/ergodox/infinity/visualizer.c b/keyboards/ergodox/infinity/visualizer.c index 6af3a72ee..7bc42fbc7 100644 --- a/keyboards/ergodox/infinity/visualizer.c +++ b/keyboards/ergodox/infinity/visualizer.c | |||
| @@ -27,6 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 27 | #endif | 27 | #endif |
| 28 | 28 | ||
| 29 | #include "visualizer.h" | 29 | #include "visualizer.h" |
| 30 | #include "system/serial_link.h" | ||
| 30 | 31 | ||
| 31 | // To generate an image array like this | 32 | // To generate an image array like this |
| 32 | // Ensure the image is 128 x 32 or smaller | 33 | // Ensure the image is 128 x 32 or smaller |
| @@ -73,6 +74,15 @@ static const uint8_t image_data_lcd_logo[512] = { | |||
| 73 | static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0xFF); | 74 | static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0xFF); |
| 74 | static const uint32_t initial_color = LCD_COLOR(0, 0, 0); | 75 | static const uint32_t initial_color = LCD_COLOR(0, 0, 0); |
| 75 | 76 | ||
| 77 | static 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 | |||
| 84 | static uint32_t next_led_target_color = 0; | ||
| 85 | |||
| 76 | typedef enum { | 86 | typedef enum { |
| 77 | LCD_STATE_INITIAL, | 87 | LCD_STATE_INITIAL, |
| 78 | LCD_STATE_LAYER_BITMAP, | 88 | LCD_STATE_LAYER_BITMAP, |
| @@ -81,6 +91,19 @@ typedef enum { | |||
| 81 | 91 | ||
| 82 | static lcd_state_t lcd_state = LCD_STATE_INITIAL; | 92 | static lcd_state_t lcd_state = LCD_STATE_INITIAL; |
| 83 | 93 | ||
| 94 | typedef 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 | ||
| 102 | static visualizer_user_data_t user_data_keyboard = {}; | ||
| 103 | |||
| 104 | _Static_assert(sizeof(visualizer_user_data_t) <= VISUALIZER_USER_DATA_SIZE, | ||
| 105 | "Please increase the VISUALIZER_USER_DATA_SIZE"); | ||
| 106 | |||
| 84 | bool display_logo(keyframe_animation_t* animation, visualizer_state_t* state) { | 107 | bool display_logo(keyframe_animation_t* animation, visualizer_state_t* state) { |
| 85 | (void)state; | 108 | (void)state; |
| 86 | (void)animation; | 109 | (void)animation; |
| @@ -117,16 +140,27 @@ static keyframe_animation_t startup_animation = { | |||
| 117 | }; | 140 | }; |
| 118 | 141 | ||
| 119 | // The color animation animates the LCD color when you change layers | 142 | // The color animation animates the LCD color when you change layers |
| 120 | static keyframe_animation_t color_animation = { | 143 | static keyframe_animation_t one_led_color = { |
| 121 | .num_frames = 2, | 144 | .num_frames = 1, |
| 122 | .loop = false, | 145 | .loop = false, |
| 123 | // Note that there's a 200 ms no-operation frame, | 146 | .frame_lengths = {gfxMillisecondsToTicks(0)}, |
| 124 | // this prevents the color from changing when activating the layer | 147 | .frame_functions = {keyframe_set_backlight_color}, |
| 125 | // momentarily | ||
| 126 | .frame_lengths = {gfxMillisecondsToTicks(200), gfxMillisecondsToTicks(500)}, | ||
| 127 | .frame_functions = {keyframe_no_operation, keyframe_animate_backlight_color}, | ||
| 128 | }; | 148 | }; |
| 129 | 149 | ||
| 150 | bool swap_led_target_color(keyframe_animation_t* animation, visualizer_state_t* state) { | ||
| 151 | uint32_t temp = next_led_target_color; | ||
| 152 | next_led_target_color = state->target_lcd_color; | ||
| 153 | state->target_lcd_color = temp; | ||
| 154 | return false; | ||
| 155 | } | ||
| 156 | |||
| 157 | // The color animation animates the LCD color when you change layers | ||
| 158 | static keyframe_animation_t two_led_colors = { | ||
| 159 | .num_frames = 2, | ||
| 160 | .loop = true, | ||
| 161 | .frame_lengths = {gfxMillisecondsToTicks(1000), gfxMillisecondsToTicks(0)}, | ||
| 162 | .frame_functions = {keyframe_set_backlight_color, swap_led_target_color}, | ||
| 163 | }; | ||
| 130 | 164 | ||
| 131 | // The LCD animation alternates between the layer name display and a | 165 | // The LCD animation alternates between the layer name display and a |
| 132 | // bitmap that displays all active layers | 166 | // bitmap that displays all active layers |
| @@ -177,6 +211,45 @@ void initialize_user_visualizer(visualizer_state_t* state) { | |||
| 177 | start_keyframe_animation(&startup_animation); | 211 | start_keyframe_animation(&startup_animation); |
| 178 | } | 212 | } |
| 179 | 213 | ||
| 214 | static const uint32_t red; | ||
| 215 | static const uint32_t green; | ||
| 216 | static const uint32_t blue; | ||
| 217 | |||
| 218 | inline bool is_led_on(visualizer_user_data_t* user_data, uint8_t num) { | ||
| 219 | return user_data->led_on & (1u << num); | ||
| 220 | } | ||
| 221 | |||
| 222 | static uint8_t get_led_index_master(visualizer_user_data_t* user_data) { | ||
| 223 | for (int i=0; i < 3; i++) { | ||
| 224 | if (is_led_on(user_data, i)) { | ||
| 225 | return i + 1; | ||
| 226 | } | ||
| 227 | } | ||
| 228 | return 0; | ||
| 229 | } | ||
| 230 | |||
| 231 | static uint8_t get_led_index_slave(visualizer_user_data_t* user_data) { | ||
| 232 | uint8_t master_index = get_led_index_master(user_data); | ||
| 233 | if (master_index!=0) { | ||
| 234 | for (int i=master_index; i < 3; i++) { | ||
| 235 | if (is_led_on(user_data, i)) { | ||
| 236 | return i + 1; | ||
| 237 | } | ||
| 238 | } | ||
| 239 | } | ||
| 240 | |||
| 241 | return 0; | ||
| 242 | } | ||
| 243 | |||
| 244 | static uint8_t get_secondary_led_index(visualizer_user_data_t* user_data) { | ||
| 245 | if (is_led_on(user_data, 0) && | ||
| 246 | is_led_on(user_data, 1) && | ||
| 247 | is_led_on(user_data, 2)) { | ||
| 248 | return 3; | ||
| 249 | } | ||
| 250 | return 0; | ||
| 251 | } | ||
| 252 | |||
| 180 | void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t prev_status) { | 253 | void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t prev_status) { |
| 181 | // Check the status here to start and stop animations | 254 | // Check the status here to start and stop animations |
| 182 | // You might have to save some state, like the current animation here so that you can start the right | 255 | // You might have to save some state, like the current animation here so that you can start the right |
| @@ -186,9 +259,38 @@ void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard | |||
| 186 | // This is also important because the slave won't have access to the active layer for example outside the | 259 | // This is also important because the slave won't have access to the active layer for example outside the |
| 187 | // status. | 260 | // status. |
| 188 | 261 | ||
| 189 | if (lcd_state == LCD_STATE_INITIAL) { | 262 | |
| 190 | state->target_lcd_color = LCD_COLOR(0x40, 0xB0, 0xFF); | 263 | visualizer_user_data_t* user_data_new = (visualizer_user_data_t*)state->status.user_data; |
| 191 | start_keyframe_animation(&color_animation); | 264 | visualizer_user_data_t* user_data_old = (visualizer_user_data_t*)prev_status.user_data; |
| 265 | |||
| 266 | uint8_t new_index; | ||
| 267 | uint8_t old_index; | ||
| 268 | |||
| 269 | if (is_serial_link_master()) { | ||
| 270 | new_index = get_led_index_master(user_data_new); | ||
| 271 | old_index = get_led_index_master(user_data_old); | ||
| 272 | } | ||
| 273 | else { | ||
| 274 | new_index = get_led_index_slave(user_data_new); | ||
| 275 | old_index = get_led_index_slave(user_data_old); | ||
| 276 | } | ||
| 277 | uint8_t new_secondary_index = get_secondary_led_index(user_data_new); | ||
| 278 | uint8_t old_secondary_index = get_secondary_led_index(user_data_old); | ||
| 279 | |||
| 280 | if (lcd_state == LCD_STATE_INITIAL || | ||
| 281 | new_index != old_index || | ||
| 282 | new_secondary_index != old_secondary_index) { | ||
| 283 | |||
| 284 | if (new_secondary_index != 0) { | ||
| 285 | state->target_lcd_color = led_emulation_colors[new_index]; | ||
| 286 | next_led_target_color = led_emulation_colors[new_secondary_index]; | ||
| 287 | stop_keyframe_animation(&one_led_color); | ||
| 288 | start_keyframe_animation(&two_led_colors); | ||
| 289 | } else { | ||
| 290 | state->target_lcd_color = led_emulation_colors[new_index]; | ||
| 291 | stop_keyframe_animation(&two_led_colors); | ||
| 292 | start_keyframe_animation(&one_led_color); | ||
| 293 | } | ||
| 192 | } | 294 | } |
| 193 | 295 | ||
| 194 | if (state->status.leds) { | 296 | if (state->status.leds) { |
| @@ -233,3 +335,56 @@ void user_visualizer_resume(visualizer_state_t* state) { | |||
| 233 | lcd_state = LCD_STATE_INITIAL; | 335 | lcd_state = LCD_STATE_INITIAL; |
| 234 | start_keyframe_animation(&resume_animation); | 336 | start_keyframe_animation(&resume_animation); |
| 235 | } | 337 | } |
| 338 | |||
| 339 | void ergodox_board_led_on(void){ | ||
| 340 | // No board led support | ||
| 341 | } | ||
| 342 | |||
| 343 | void ergodox_right_led_1_on(void){ | ||
| 344 | user_data_keyboard.led_on |= (1u << 0); | ||
| 345 | visualizer_set_user_data(&user_data_keyboard); | ||
| 346 | } | ||
| 347 | |||
| 348 | void ergodox_right_led_2_on(void){ | ||
| 349 | user_data_keyboard.led_on |= (1u << 1); | ||
| 350 | visualizer_set_user_data(&user_data_keyboard); | ||
| 351 | } | ||
| 352 | |||
| 353 | void ergodox_right_led_3_on(void){ | ||
| 354 | user_data_keyboard.led_on |= (1u << 2); | ||
| 355 | visualizer_set_user_data(&user_data_keyboard); | ||
| 356 | } | ||
| 357 | |||
| 358 | void ergodox_board_led_off(void){ | ||
| 359 | // No board led support | ||
| 360 | } | ||
| 361 | |||
| 362 | void ergodox_right_led_1_off(void){ | ||
| 363 | user_data_keyboard.led_on &= ~(1u << 0); | ||
| 364 | visualizer_set_user_data(&user_data_keyboard); | ||
| 365 | } | ||
| 366 | |||
| 367 | void ergodox_right_led_2_off(void){ | ||
| 368 | user_data_keyboard.led_on &= ~(1u << 1); | ||
| 369 | visualizer_set_user_data(&user_data_keyboard); | ||
| 370 | } | ||
| 371 | |||
| 372 | void ergodox_right_led_3_off(void){ | ||
| 373 | user_data_keyboard.led_on &= ~(1u << 2); | ||
| 374 | visualizer_set_user_data(&user_data_keyboard); | ||
| 375 | } | ||
| 376 | |||
| 377 | void ergodox_right_led_1_set(uint8_t n) { | ||
| 378 | user_data_keyboard.led1 = n; | ||
| 379 | visualizer_set_user_data(&user_data_keyboard); | ||
| 380 | } | ||
| 381 | |||
| 382 | void ergodox_right_led_2_set(uint8_t n) { | ||
| 383 | user_data_keyboard.led2 = n; | ||
| 384 | visualizer_set_user_data(&user_data_keyboard); | ||
| 385 | } | ||
| 386 | |||
| 387 | void ergodox_right_led_3_set(uint8_t n) { | ||
| 388 | user_data_keyboard.led3 = n; | ||
| 389 | visualizer_set_user_data(&user_data_keyboard); | ||
| 390 | } | ||
