diff options
| author | Fred Sundvik <fsundvik@gmail.com> | 2017-04-02 01:31:04 +0300 |
|---|---|---|
| committer | Fred Sundvik <fsundvik@gmail.com> | 2017-04-09 18:34:59 +0300 |
| commit | 39385144e7dc3337e623cdc8147b4a441f22fd62 (patch) | |
| tree | c553b85bbd7c0754296f999e83647ac7b779a22d | |
| parent | 9a4ce28683b667ab67d48d92196bab7e277d4800 (diff) | |
| download | qmk_firmware-39385144e7dc3337e623cdc8147b4a441f22fd62.tar.gz qmk_firmware-39385144e7dc3337e623cdc8147b4a441f22fd62.zip | |
Emulate Ergodox EZ leds by LCD colors
| -rw-r--r-- | keyboards/ergodox/infinity/config.h | 2 | ||||
| -rw-r--r-- | keyboards/ergodox/infinity/infinity.c | 22 | ||||
| -rw-r--r-- | keyboards/ergodox/infinity/infinity.h | 71 | ||||
| -rw-r--r-- | keyboards/ergodox/infinity/visualizer.c | 175 | ||||
| -rw-r--r-- | quantum/visualizer/visualizer.c | 25 | ||||
| -rw-r--r-- | quantum/visualizer/visualizer.h | 8 |
6 files changed, 258 insertions, 45 deletions
diff --git a/keyboards/ergodox/infinity/config.h b/keyboards/ergodox/infinity/config.h index 9e264083b..6cde193e1 100644 --- a/keyboards/ergodox/infinity/config.h +++ b/keyboards/ergodox/infinity/config.h | |||
| @@ -54,6 +54,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 54 | // The visualizer needs gfx thread priorities | 54 | // The visualizer needs gfx thread priorities |
| 55 | #define VISUALIZER_THREAD_PRIORITY (NORMAL_PRIORITY - 2) | 55 | #define VISUALIZER_THREAD_PRIORITY (NORMAL_PRIORITY - 2) |
| 56 | 56 | ||
| 57 | #define VISUALIZER_USER_DATA_SIZE 16 | ||
| 58 | |||
| 57 | /* | 59 | /* |
| 58 | * Feature disable options | 60 | * Feature disable options |
| 59 | * These options are also useful to firmware size reduction. | 61 | * These options are also useful to firmware size reduction. |
diff --git a/keyboards/ergodox/infinity/infinity.c b/keyboards/ergodox/infinity/infinity.c index ecc072abb..62259ed3f 100644 --- a/keyboards/ergodox/infinity/infinity.c +++ b/keyboards/ergodox/infinity/infinity.c | |||
| @@ -126,34 +126,48 @@ void matrix_scan_kb(void) { | |||
| 126 | matrix_scan_user(); | 126 | matrix_scan_user(); |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | __attribute__ ((weak)) | ||
| 129 | void ergodox_board_led_on(void){ | 130 | void ergodox_board_led_on(void){ |
| 130 | } | 131 | } |
| 131 | 132 | ||
| 133 | __attribute__ ((weak)) | ||
| 132 | void ergodox_right_led_1_on(void){ | 134 | void ergodox_right_led_1_on(void){ |
| 133 | } | 135 | } |
| 134 | 136 | ||
| 137 | __attribute__ ((weak)) | ||
| 135 | void ergodox_right_led_2_on(void){ | 138 | void ergodox_right_led_2_on(void){ |
| 136 | } | 139 | } |
| 137 | 140 | ||
| 141 | __attribute__ ((weak)) | ||
| 138 | void ergodox_right_led_3_on(void){ | 142 | void ergodox_right_led_3_on(void){ |
| 139 | } | 143 | } |
| 140 | 144 | ||
| 141 | void ergodox_right_led_on(uint8_t led){ | 145 | __attribute__ ((weak)) |
| 142 | } | ||
| 143 | |||
| 144 | void ergodox_board_led_off(void){ | 146 | void ergodox_board_led_off(void){ |
| 145 | } | 147 | } |
| 146 | 148 | ||
| 149 | __attribute__ ((weak)) | ||
| 147 | void ergodox_right_led_1_off(void){ | 150 | void ergodox_right_led_1_off(void){ |
| 148 | } | 151 | } |
| 149 | 152 | ||
| 153 | __attribute__ ((weak)) | ||
| 150 | void ergodox_right_led_2_off(void){ | 154 | void ergodox_right_led_2_off(void){ |
| 151 | } | 155 | } |
| 152 | 156 | ||
| 157 | __attribute__ ((weak)) | ||
| 153 | void ergodox_right_led_3_off(void){ | 158 | void ergodox_right_led_3_off(void){ |
| 154 | } | 159 | } |
| 155 | 160 | ||
| 156 | void ergodox_right_led_off(uint8_t led){ | 161 | __attribute__ ((weak)) |
| 162 | void ergodox_right_led_1_set(uint8_t n) { | ||
| 163 | } | ||
| 164 | |||
| 165 | __attribute__ ((weak)) | ||
| 166 | void ergodox_right_led_2_set(uint8_t n) { | ||
| 167 | } | ||
| 168 | |||
| 169 | __attribute__ ((weak)) | ||
| 170 | void ergodox_right_led_3_set(uint8_t n) { | ||
| 157 | } | 171 | } |
| 158 | 172 | ||
| 159 | #ifdef ONEHAND_ENABLE | 173 | #ifdef ONEHAND_ENABLE |
diff --git a/keyboards/ergodox/infinity/infinity.h b/keyboards/ergodox/infinity/infinity.h index fec9e565c..73a0f4bf7 100644 --- a/keyboards/ergodox/infinity/infinity.h +++ b/keyboards/ergodox/infinity/infinity.h | |||
| @@ -7,13 +7,38 @@ void ergodox_board_led_on(void); | |||
| 7 | void ergodox_right_led_1_on(void); | 7 | void ergodox_right_led_1_on(void); |
| 8 | void ergodox_right_led_2_on(void); | 8 | void ergodox_right_led_2_on(void); |
| 9 | void ergodox_right_led_3_on(void); | 9 | void ergodox_right_led_3_on(void); |
| 10 | void ergodox_right_led_on(uint8_t led); | 10 | |
| 11 | inline void ergodox_right_led_on(uint8_t led) { | ||
| 12 | switch (led) { | ||
| 13 | case 0: | ||
| 14 | ergodox_right_led_1_on(); | ||
| 15 | break; | ||
| 16 | case 1: | ||
| 17 | ergodox_right_led_2_on(); | ||
| 18 | break; | ||
| 19 | case 2: | ||
| 20 | ergodox_right_led_3_on(); | ||
| 21 | break; | ||
| 22 | } | ||
| 23 | } | ||
| 11 | 24 | ||
| 12 | void ergodox_board_led_off(void); | 25 | void ergodox_board_led_off(void); |
| 13 | void ergodox_right_led_1_off(void); | 26 | void ergodox_right_led_1_off(void); |
| 14 | void ergodox_right_led_2_off(void); | 27 | void ergodox_right_led_2_off(void); |
| 15 | void ergodox_right_led_3_off(void); | 28 | void ergodox_right_led_3_off(void); |
| 16 | void ergodox_right_led_off(uint8_t led); | 29 | inline void ergodox_right_led_off(uint8_t led) { |
| 30 | switch (led) { | ||
| 31 | case 0: | ||
| 32 | ergodox_right_led_1_off(); | ||
| 33 | break; | ||
| 34 | case 1: | ||
| 35 | ergodox_right_led_2_off(); | ||
| 36 | break; | ||
| 37 | case 2: | ||
| 38 | ergodox_right_led_3_off(); | ||
| 39 | break; | ||
| 40 | } | ||
| 41 | } | ||
| 17 | 42 | ||
| 18 | inline void ergodox_led_all_on(void) | 43 | inline void ergodox_led_all_on(void) |
| 19 | { | 44 | { |
| @@ -31,36 +56,22 @@ inline void ergodox_led_all_off(void) | |||
| 31 | ergodox_right_led_3_off(); | 56 | ergodox_right_led_3_off(); |
| 32 | } | 57 | } |
| 33 | 58 | ||
| 34 | inline void ergodox_right_led_1_set(uint8_t n){ | 59 | void ergodox_right_led_1_set(uint8_t n); |
| 35 | if (n) { | 60 | void ergodox_right_led_2_set(uint8_t n); |
| 36 | ergodox_right_led_1_on(); | 61 | void ergodox_right_led_3_set(uint8_t n); |
| 37 | } else { | ||
| 38 | ergodox_right_led_1_off(); | ||
| 39 | } | ||
| 40 | } | ||
| 41 | |||
| 42 | inline void ergodox_right_led_2_set(uint8_t n){ | ||
| 43 | if (n) { | ||
| 44 | ergodox_right_led_2_on(); | ||
| 45 | } else { | ||
| 46 | ergodox_right_led_2_off(); | ||
| 47 | } | ||
| 48 | } | ||
| 49 | |||
| 50 | inline void ergodox_right_led_3_set(uint8_t n){ | ||
| 51 | if (n) { | ||
| 52 | ergodox_right_led_3_on(); | ||
| 53 | } else { | ||
| 54 | ergodox_right_led_3_off(); | ||
| 55 | } | ||
| 56 | } | ||
| 57 | 62 | ||
| 58 | inline void ergodox_right_led_set(uint8_t led, uint8_t n){ | 63 | inline void ergodox_right_led_set(uint8_t led, uint8_t n){ |
| 59 | if (n) { | 64 | switch (led) { |
| 60 | ergodox_right_led_on(led); | 65 | case 0: |
| 61 | } else { | 66 | ergodox_right_led_1_set(n); |
| 62 | ergodox_right_led_off(led); | 67 | break; |
| 63 | } | 68 | case 1: |
| 69 | ergodox_right_led_2_set(n); | ||
| 70 | break; | ||
| 71 | case 2: | ||
| 72 | ergodox_right_led_3_set(n); | ||
| 73 | break; | ||
| 74 | } | ||
| 64 | } | 75 | } |
| 65 | 76 | ||
| 66 | inline void ergodox_led_all_set(uint8_t n) { | 77 | inline void ergodox_led_all_set(uint8_t n) { |
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 | } | ||
diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c index 62ebebcee..bff0df494 100644 --- a/quantum/visualizer/visualizer.c +++ b/quantum/visualizer/visualizer.c | |||
| @@ -64,6 +64,9 @@ static visualizer_keyboard_status_t current_status = { | |||
| 64 | .mods = 0xFF, | 64 | .mods = 0xFF, |
| 65 | .leds = 0xFFFFFFFF, | 65 | .leds = 0xFFFFFFFF, |
| 66 | .suspended = false, | 66 | .suspended = false, |
| 67 | #ifdef VISUALIZER_USER_DATA_SIZE | ||
| 68 | .user_data = {0} | ||
| 69 | #endif | ||
| 67 | }; | 70 | }; |
| 68 | 71 | ||
| 69 | static bool same_status(visualizer_keyboard_status_t* status1, visualizer_keyboard_status_t* status2) { | 72 | static bool same_status(visualizer_keyboard_status_t* status1, visualizer_keyboard_status_t* status2) { |
| @@ -71,11 +74,19 @@ static bool same_status(visualizer_keyboard_status_t* status1, visualizer_keyboa | |||
| 71 | status1->default_layer == status2->default_layer && | 74 | status1->default_layer == status2->default_layer && |
| 72 | status1->mods == status2->mods && | 75 | status1->mods == status2->mods && |
| 73 | status1->leds == status2->leds && | 76 | status1->leds == status2->leds && |
| 74 | status1->suspended == status2->suspended; | 77 | status1->suspended == status2->suspended |
| 78 | #ifdef VISUALIZER_USER_DATA_SIZE | ||
| 79 | && memcmp(status1->user_data, status2->user_data, VISUALIZER_USER_DATA_SIZE) == 0 | ||
| 80 | #endif | ||
| 81 | ; | ||
| 75 | } | 82 | } |
| 76 | 83 | ||
| 77 | static bool visualizer_enabled = false; | 84 | static bool visualizer_enabled = false; |
| 78 | 85 | ||
| 86 | #ifdef VISUALIZER_USER_DATA_SIZE | ||
| 87 | static uint8_t user_data[VISUALIZER_USER_DATA_SIZE]; | ||
| 88 | #endif | ||
| 89 | |||
| 79 | #define MAX_SIMULTANEOUS_ANIMATIONS 4 | 90 | #define MAX_SIMULTANEOUS_ANIMATIONS 4 |
| 80 | static keyframe_animation_t* animations[MAX_SIMULTANEOUS_ANIMATIONS] = {}; | 91 | static keyframe_animation_t* animations[MAX_SIMULTANEOUS_ANIMATIONS] = {}; |
| 81 | 92 | ||
| @@ -431,6 +442,9 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) { | |||
| 431 | .mods = 0xFF, | 442 | .mods = 0xFF, |
| 432 | .leds = 0xFFFFFFFF, | 443 | .leds = 0xFFFFFFFF, |
| 433 | .suspended = false, | 444 | .suspended = false, |
| 445 | #ifdef VISUALIZER_USER_DATA_SIZE | ||
| 446 | .user_data = {0}, | ||
| 447 | #endif | ||
| 434 | }; | 448 | }; |
| 435 | 449 | ||
| 436 | visualizer_state_t state = { | 450 | visualizer_state_t state = { |
| @@ -590,6 +604,12 @@ uint8_t visualizer_get_mods() { | |||
| 590 | return mods; | 604 | return mods; |
| 591 | } | 605 | } |
| 592 | 606 | ||
| 607 | #ifdef VISUALIZER_USER_DATA_SIZE | ||
| 608 | void visualizer_set_user_data(void* u) { | ||
| 609 | memcpy(user_data, u, VISUALIZER_USER_DATA_SIZE); | ||
| 610 | } | ||
| 611 | #endif | ||
| 612 | |||
| 593 | void visualizer_update(uint32_t default_state, uint32_t state, uint8_t mods, uint32_t leds) { | 613 | void visualizer_update(uint32_t default_state, uint32_t state, uint8_t mods, uint32_t leds) { |
| 594 | // Note that there's a small race condition here, the thread could read | 614 | // Note that there's a small race condition here, the thread could read |
| 595 | // a state where one of these are set but not the other. But this should | 615 | // a state where one of these are set but not the other. But this should |
| @@ -618,6 +638,9 @@ void visualizer_update(uint32_t default_state, uint32_t state, uint8_t mods, uin | |||
| 618 | .leds = leds, | 638 | .leds = leds, |
| 619 | .suspended = current_status.suspended, | 639 | .suspended = current_status.suspended, |
| 620 | }; | 640 | }; |
| 641 | #ifdef VISUALIZER_USER_DATA_SIZE | ||
| 642 | memcpy(new_status.user_data, user_data, VISUALIZER_USER_DATA_SIZE); | ||
| 643 | #endif | ||
| 621 | if (!same_status(¤t_status, &new_status)) { | 644 | if (!same_status(¤t_status, &new_status)) { |
| 622 | changed = true; | 645 | changed = true; |
| 623 | current_status = new_status; | 646 | current_status = new_status; |
diff --git a/quantum/visualizer/visualizer.h b/quantum/visualizer/visualizer.h index 2c81cb9f7..beb8f2ab4 100644 --- a/quantum/visualizer/visualizer.h +++ b/quantum/visualizer/visualizer.h | |||
| @@ -68,6 +68,9 @@ typedef struct { | |||
| 68 | uint8_t mods; | 68 | uint8_t mods; |
| 69 | uint32_t leds; // See led.h for available statuses | 69 | uint32_t leds; // See led.h for available statuses |
| 70 | bool suspended; | 70 | bool suspended; |
| 71 | #ifdef VISUALIZER_USER_DATA_SIZE | ||
| 72 | uint8_t user_data[VISUALIZER_USER_DATA_SIZE]; | ||
| 73 | #endif | ||
| 71 | } visualizer_keyboard_status_t; | 74 | } visualizer_keyboard_status_t; |
| 72 | 75 | ||
| 73 | // The state struct is used by the various keyframe functions | 76 | // The state struct is used by the various keyframe functions |
| @@ -146,6 +149,11 @@ bool keyframe_enable_lcd_and_backlight(keyframe_animation_t* animation, visualiz | |||
| 146 | // directly from the initalize_user_visualizer function (the animation can be null) | 149 | // directly from the initalize_user_visualizer function (the animation can be null) |
| 147 | bool enable_visualization(keyframe_animation_t* animation, visualizer_state_t* state); | 150 | bool enable_visualization(keyframe_animation_t* animation, visualizer_state_t* state); |
| 148 | 151 | ||
| 152 | // The master can set userdata which will be transferred to the slave | ||
| 153 | #ifdef VISUALIZER_USER_DATA_SIZE | ||
| 154 | void visualizer_set_user_data(void* user_data); | ||
| 155 | #endif | ||
| 156 | |||
| 149 | // These functions have to be implemented by the user | 157 | // These functions have to be implemented by the user |
| 150 | void initialize_user_visualizer(visualizer_state_t* state); | 158 | void initialize_user_visualizer(visualizer_state_t* state); |
| 151 | void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t prev_status); | 159 | void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t prev_status); |
