aboutsummaryrefslogtreecommitdiff
path: root/quantum/rgb_matrix
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/rgb_matrix')
-rw-r--r--quantum/rgb_matrix/animations/alpha_mods_anim.h26
-rw-r--r--quantum/rgb_matrix/animations/breathing_anim.h20
-rw-r--r--quantum/rgb_matrix/animations/colorband_pinwheel_sat_anim.h13
-rw-r--r--quantum/rgb_matrix/animations/colorband_pinwheel_val_anim.h13
-rw-r--r--quantum/rgb_matrix/animations/colorband_sat_anim.h14
-rw-r--r--quantum/rgb_matrix/animations/colorband_spiral_sat_anim.h13
-rw-r--r--quantum/rgb_matrix/animations/colorband_spiral_val_anim.h13
-rw-r--r--quantum/rgb_matrix/animations/colorband_val_anim.h14
-rw-r--r--quantum/rgb_matrix/animations/cycle_all_anim.h13
-rw-r--r--quantum/rgb_matrix/animations/cycle_left_right_anim.h13
-rw-r--r--quantum/rgb_matrix/animations/cycle_out_in_anim.h13
-rw-r--r--quantum/rgb_matrix/animations/cycle_out_in_dual_anim.h15
-rw-r--r--quantum/rgb_matrix/animations/cycle_pinwheel_anim.h13
-rw-r--r--quantum/rgb_matrix/animations/cycle_spiral_anim.h13
-rw-r--r--quantum/rgb_matrix/animations/cycle_up_down_anim.h13
-rw-r--r--quantum/rgb_matrix/animations/digital_rain_anim.h75
-rw-r--r--quantum/rgb_matrix/animations/dual_beacon_anim.h13
-rw-r--r--quantum/rgb_matrix/animations/gradient_left_right_anim.h22
-rw-r--r--quantum/rgb_matrix/animations/gradient_up_down_anim.h22
-rw-r--r--quantum/rgb_matrix/animations/hue_breathing_anim.h22
-rw-r--r--quantum/rgb_matrix/animations/hue_pendulum_anim.h17
-rw-r--r--quantum/rgb_matrix/animations/hue_wave_anim.h17
-rw-r--r--quantum/rgb_matrix/animations/jellybean_raindrops_anim.h29
-rw-r--r--quantum/rgb_matrix/animations/rainbow_beacon_anim.h13
-rw-r--r--quantum/rgb_matrix/animations/rainbow_moving_chevron_anim.h13
-rw-r--r--quantum/rgb_matrix/animations/rainbow_pinwheels_anim.h13
-rw-r--r--quantum/rgb_matrix/animations/raindrops_anim.h39
-rw-r--r--quantum/rgb_matrix/animations/rgb_matrix_effects.inc37
-rw-r--r--quantum/rgb_matrix/animations/runners/effect_runner_dx_dy.h17
-rw-r--r--quantum/rgb_matrix/animations/runners/effect_runner_dx_dy_dist.h18
-rw-r--r--quantum/rgb_matrix/animations/runners/effect_runner_i.h15
-rw-r--r--quantum/rgb_matrix/animations/runners/effect_runner_reactive.h29
-rw-r--r--quantum/rgb_matrix/animations/runners/effect_runner_reactive_splash.h29
-rw-r--r--quantum/rgb_matrix/animations/runners/effect_runner_sin_cos_i.h17
-rw-r--r--quantum/rgb_matrix/animations/runners/rgb_matrix_runners.inc6
-rw-r--r--quantum/rgb_matrix/animations/solid_color_anim.h15
-rw-r--r--quantum/rgb_matrix/animations/solid_reactive_anim.h15
-rw-r--r--quantum/rgb_matrix/animations/solid_reactive_cross.h36
-rw-r--r--quantum/rgb_matrix/animations/solid_reactive_nexus.h34
-rw-r--r--quantum/rgb_matrix/animations/solid_reactive_simple_anim.h15
-rw-r--r--quantum/rgb_matrix/animations/solid_reactive_wide.h31
-rw-r--r--quantum/rgb_matrix/animations/solid_splash_anim.h31
-rw-r--r--quantum/rgb_matrix/animations/splash_anim.h32
-rw-r--r--quantum/rgb_matrix/animations/typing_heatmap_anim.h86
-rw-r--r--quantum/rgb_matrix/rgb_matrix.c640
-rw-r--r--quantum/rgb_matrix/rgb_matrix.h228
-rw-r--r--quantum/rgb_matrix/rgb_matrix_drivers.c247
-rw-r--r--quantum/rgb_matrix/rgb_matrix_legacy_enables.h153
-rw-r--r--quantum/rgb_matrix/rgb_matrix_types.h98
49 files changed, 2343 insertions, 0 deletions
diff --git a/quantum/rgb_matrix/animations/alpha_mods_anim.h b/quantum/rgb_matrix/animations/alpha_mods_anim.h
new file mode 100644
index 000000000..3f2c9b799
--- /dev/null
+++ b/quantum/rgb_matrix/animations/alpha_mods_anim.h
@@ -0,0 +1,26 @@
1#ifdef ENABLE_RGB_MATRIX_ALPHAS_MODS
2RGB_MATRIX_EFFECT(ALPHAS_MODS)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5// alphas = color1, mods = color2
6bool ALPHAS_MODS(effect_params_t* params) {
7 RGB_MATRIX_USE_LIMITS(led_min, led_max);
8
9 HSV hsv = rgb_matrix_config.hsv;
10 RGB rgb1 = rgb_matrix_hsv_to_rgb(hsv);
11 hsv.h += rgb_matrix_config.speed;
12 RGB rgb2 = rgb_matrix_hsv_to_rgb(hsv);
13
14 for (uint8_t i = led_min; i < led_max; i++) {
15 RGB_MATRIX_TEST_LED_FLAGS();
16 if (HAS_FLAGS(g_led_config.flags[i], LED_FLAG_MODIFIER)) {
17 rgb_matrix_set_color(i, rgb2.r, rgb2.g, rgb2.b);
18 } else {
19 rgb_matrix_set_color(i, rgb1.r, rgb1.g, rgb1.b);
20 }
21 }
22 return led_max < DRIVER_LED_TOTAL;
23}
24
25# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
26#endif // DISABLE_RGB_MATRIX_ALPHAS_MODS
diff --git a/quantum/rgb_matrix/animations/breathing_anim.h b/quantum/rgb_matrix/animations/breathing_anim.h
new file mode 100644
index 000000000..a00ccb83a
--- /dev/null
+++ b/quantum/rgb_matrix/animations/breathing_anim.h
@@ -0,0 +1,20 @@
1#ifdef ENABLE_RGB_MATRIX_BREATHING
2RGB_MATRIX_EFFECT(BREATHING)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5bool BREATHING(effect_params_t* params) {
6 RGB_MATRIX_USE_LIMITS(led_min, led_max);
7
8 HSV hsv = rgb_matrix_config.hsv;
9 uint16_t time = scale16by8(g_rgb_timer, rgb_matrix_config.speed / 8);
10 hsv.v = scale8(abs8(sin8(time) - 128) * 2, hsv.v);
11 RGB rgb = rgb_matrix_hsv_to_rgb(hsv);
12 for (uint8_t i = led_min; i < led_max; i++) {
13 RGB_MATRIX_TEST_LED_FLAGS();
14 rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
15 }
16 return led_max < DRIVER_LED_TOTAL;
17}
18
19# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
20#endif // DISABLE_RGB_MATRIX_BREATHING
diff --git a/quantum/rgb_matrix/animations/colorband_pinwheel_sat_anim.h b/quantum/rgb_matrix/animations/colorband_pinwheel_sat_anim.h
new file mode 100644
index 000000000..ac9578922
--- /dev/null
+++ b/quantum/rgb_matrix/animations/colorband_pinwheel_sat_anim.h
@@ -0,0 +1,13 @@
1#ifdef ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT
2RGB_MATRIX_EFFECT(BAND_PINWHEEL_SAT)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static HSV BAND_PINWHEEL_SAT_math(HSV hsv, int16_t dx, int16_t dy, uint8_t time) {
6 hsv.s = scale8(hsv.s - time - atan2_8(dy, dx) * 3, hsv.s);
7 return hsv;
8}
9
10bool BAND_PINWHEEL_SAT(effect_params_t* params) { return effect_runner_dx_dy(params, &BAND_PINWHEEL_SAT_math); }
11
12# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
13#endif // DISABLE_RGB_MATRIX_BAND_PINWHEEL_SAT
diff --git a/quantum/rgb_matrix/animations/colorband_pinwheel_val_anim.h b/quantum/rgb_matrix/animations/colorband_pinwheel_val_anim.h
new file mode 100644
index 000000000..f7fe4b76e
--- /dev/null
+++ b/quantum/rgb_matrix/animations/colorband_pinwheel_val_anim.h
@@ -0,0 +1,13 @@
1#ifdef ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL
2RGB_MATRIX_EFFECT(BAND_PINWHEEL_VAL)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static HSV BAND_PINWHEEL_VAL_math(HSV hsv, int16_t dx, int16_t dy, uint8_t time) {
6 hsv.v = scale8(hsv.v - time - atan2_8(dy, dx) * 3, hsv.v);
7 return hsv;
8}
9
10bool BAND_PINWHEEL_VAL(effect_params_t* params) { return effect_runner_dx_dy(params, &BAND_PINWHEEL_VAL_math); }
11
12# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
13#endif // DISABLE_RGB_MATRIX_BAND_PINWHEEL_VAL
diff --git a/quantum/rgb_matrix/animations/colorband_sat_anim.h b/quantum/rgb_matrix/animations/colorband_sat_anim.h
new file mode 100644
index 000000000..96a6cbf5c
--- /dev/null
+++ b/quantum/rgb_matrix/animations/colorband_sat_anim.h
@@ -0,0 +1,14 @@
1#ifdef ENABLE_RGB_MATRIX_BAND_SAT
2RGB_MATRIX_EFFECT(BAND_SAT)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static HSV BAND_SAT_math(HSV hsv, uint8_t i, uint8_t time) {
6 int16_t s = hsv.s - abs(scale8(g_led_config.point[i].x, 228) + 28 - time) * 8;
7 hsv.s = scale8(s < 0 ? 0 : s, hsv.s);
8 return hsv;
9}
10
11bool BAND_SAT(effect_params_t* params) { return effect_runner_i(params, &BAND_SAT_math); }
12
13# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
14#endif // DISABLE_RGB_MATRIX_BAND_SAT
diff --git a/quantum/rgb_matrix/animations/colorband_spiral_sat_anim.h b/quantum/rgb_matrix/animations/colorband_spiral_sat_anim.h
new file mode 100644
index 000000000..52f6040d8
--- /dev/null
+++ b/quantum/rgb_matrix/animations/colorband_spiral_sat_anim.h
@@ -0,0 +1,13 @@
1#ifdef ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT
2RGB_MATRIX_EFFECT(BAND_SPIRAL_SAT)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static HSV BAND_SPIRAL_SAT_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint8_t time) {
6 hsv.s = scale8(hsv.s + dist - time - atan2_8(dy, dx), hsv.s);
7 return hsv;
8}
9
10bool BAND_SPIRAL_SAT(effect_params_t* params) { return effect_runner_dx_dy_dist(params, &BAND_SPIRAL_SAT_math); }
11
12# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
13#endif // DISABLE_RGB_MATRIX_BAND_SPIRAL_SAT
diff --git a/quantum/rgb_matrix/animations/colorband_spiral_val_anim.h b/quantum/rgb_matrix/animations/colorband_spiral_val_anim.h
new file mode 100644
index 000000000..d5752e27f
--- /dev/null
+++ b/quantum/rgb_matrix/animations/colorband_spiral_val_anim.h
@@ -0,0 +1,13 @@
1#ifdef ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL
2RGB_MATRIX_EFFECT(BAND_SPIRAL_VAL)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static HSV BAND_SPIRAL_VAL_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint8_t time) {
6 hsv.v = scale8(hsv.v + dist - time - atan2_8(dy, dx), hsv.v);
7 return hsv;
8}
9
10bool BAND_SPIRAL_VAL(effect_params_t* params) { return effect_runner_dx_dy_dist(params, &BAND_SPIRAL_VAL_math); }
11
12# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
13#endif // DISABLE_RGB_MATRIX_BAND_SPIRAL_VAL
diff --git a/quantum/rgb_matrix/animations/colorband_val_anim.h b/quantum/rgb_matrix/animations/colorband_val_anim.h
new file mode 100644
index 000000000..32bc6f52a
--- /dev/null
+++ b/quantum/rgb_matrix/animations/colorband_val_anim.h
@@ -0,0 +1,14 @@
1#ifdef ENABLE_RGB_MATRIX_BAND_VAL
2RGB_MATRIX_EFFECT(BAND_VAL)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static HSV BAND_VAL_math(HSV hsv, uint8_t i, uint8_t time) {
6 int16_t v = hsv.v - abs(scale8(g_led_config.point[i].x, 228) + 28 - time) * 8;
7 hsv.v = scale8(v < 0 ? 0 : v, hsv.v);
8 return hsv;
9}
10
11bool BAND_VAL(effect_params_t* params) { return effect_runner_i(params, &BAND_VAL_math); }
12
13# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
14#endif // DISABLE_RGB_MATRIX_BAND_VAL
diff --git a/quantum/rgb_matrix/animations/cycle_all_anim.h b/quantum/rgb_matrix/animations/cycle_all_anim.h
new file mode 100644
index 000000000..20af94b6b
--- /dev/null
+++ b/quantum/rgb_matrix/animations/cycle_all_anim.h
@@ -0,0 +1,13 @@
1#ifdef ENABLE_RGB_MATRIX_CYCLE_ALL
2RGB_MATRIX_EFFECT(CYCLE_ALL)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static HSV CYCLE_ALL_math(HSV hsv, uint8_t i, uint8_t time) {
6 hsv.h = time;
7 return hsv;
8}
9
10bool CYCLE_ALL(effect_params_t* params) { return effect_runner_i(params, &CYCLE_ALL_math); }
11
12# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
13#endif // DISABLE_RGB_MATRIX_CYCLE_ALL
diff --git a/quantum/rgb_matrix/animations/cycle_left_right_anim.h b/quantum/rgb_matrix/animations/cycle_left_right_anim.h
new file mode 100644
index 000000000..7f84f4bd5
--- /dev/null
+++ b/quantum/rgb_matrix/animations/cycle_left_right_anim.h
@@ -0,0 +1,13 @@
1#ifdef ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
2RGB_MATRIX_EFFECT(CYCLE_LEFT_RIGHT)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static HSV CYCLE_LEFT_RIGHT_math(HSV hsv, uint8_t i, uint8_t time) {
6 hsv.h = g_led_config.point[i].x - time;
7 return hsv;
8}
9
10bool CYCLE_LEFT_RIGHT(effect_params_t* params) { return effect_runner_i(params, &CYCLE_LEFT_RIGHT_math); }
11
12# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
13#endif // DISABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
diff --git a/quantum/rgb_matrix/animations/cycle_out_in_anim.h b/quantum/rgb_matrix/animations/cycle_out_in_anim.h
new file mode 100644
index 000000000..2277f16a2
--- /dev/null
+++ b/quantum/rgb_matrix/animations/cycle_out_in_anim.h
@@ -0,0 +1,13 @@
1#ifdef ENABLE_RGB_MATRIX_CYCLE_OUT_IN
2RGB_MATRIX_EFFECT(CYCLE_OUT_IN)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static HSV CYCLE_OUT_IN_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint8_t time) {
6 hsv.h = 3 * dist / 2 + time;
7 return hsv;
8}
9
10bool CYCLE_OUT_IN(effect_params_t* params) { return effect_runner_dx_dy_dist(params, &CYCLE_OUT_IN_math); }
11
12# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
13#endif // DISABLE_RGB_MATRIX_CYCLE_OUT_IN
diff --git a/quantum/rgb_matrix/animations/cycle_out_in_dual_anim.h b/quantum/rgb_matrix/animations/cycle_out_in_dual_anim.h
new file mode 100644
index 000000000..981c0afd0
--- /dev/null
+++ b/quantum/rgb_matrix/animations/cycle_out_in_dual_anim.h
@@ -0,0 +1,15 @@
1#ifdef ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL
2RGB_MATRIX_EFFECT(CYCLE_OUT_IN_DUAL)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static HSV CYCLE_OUT_IN_DUAL_math(HSV hsv, int16_t dx, int16_t dy, uint8_t time) {
6 dx = (k_rgb_matrix_center.x / 2) - abs8(dx);
7 uint8_t dist = sqrt16(dx * dx + dy * dy);
8 hsv.h = 3 * dist + time;
9 return hsv;
10}
11
12bool CYCLE_OUT_IN_DUAL(effect_params_t* params) { return effect_runner_dx_dy(params, &CYCLE_OUT_IN_DUAL_math); }
13
14# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
15#endif // DISABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL
diff --git a/quantum/rgb_matrix/animations/cycle_pinwheel_anim.h b/quantum/rgb_matrix/animations/cycle_pinwheel_anim.h
new file mode 100644
index 000000000..1a7db4a4c
--- /dev/null
+++ b/quantum/rgb_matrix/animations/cycle_pinwheel_anim.h
@@ -0,0 +1,13 @@
1#ifdef ENABLE_RGB_MATRIX_CYCLE_PINWHEEL
2RGB_MATRIX_EFFECT(CYCLE_PINWHEEL)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static HSV CYCLE_PINWHEEL_math(HSV hsv, int16_t dx, int16_t dy, uint8_t time) {
6 hsv.h = atan2_8(dy, dx) + time;
7 return hsv;
8}
9
10bool CYCLE_PINWHEEL(effect_params_t* params) { return effect_runner_dx_dy(params, &CYCLE_PINWHEEL_math); }
11
12# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
13#endif // DISABLE_RGB_MATRIX_CYCLE_PINWHEEL
diff --git a/quantum/rgb_matrix/animations/cycle_spiral_anim.h b/quantum/rgb_matrix/animations/cycle_spiral_anim.h
new file mode 100644
index 000000000..245cdc237
--- /dev/null
+++ b/quantum/rgb_matrix/animations/cycle_spiral_anim.h
@@ -0,0 +1,13 @@
1#ifdef ENABLE_RGB_MATRIX_CYCLE_SPIRAL
2RGB_MATRIX_EFFECT(CYCLE_SPIRAL)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static HSV CYCLE_SPIRAL_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint8_t time) {
6 hsv.h = dist - time - atan2_8(dy, dx);
7 return hsv;
8}
9
10bool CYCLE_SPIRAL(effect_params_t* params) { return effect_runner_dx_dy_dist(params, &CYCLE_SPIRAL_math); }
11
12# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
13#endif // DISABLE_RGB_MATRIX_CYCLE_SPIRAL
diff --git a/quantum/rgb_matrix/animations/cycle_up_down_anim.h b/quantum/rgb_matrix/animations/cycle_up_down_anim.h
new file mode 100644
index 000000000..c9b5a5413
--- /dev/null
+++ b/quantum/rgb_matrix/animations/cycle_up_down_anim.h
@@ -0,0 +1,13 @@
1#ifdef ENABLE_RGB_MATRIX_CYCLE_UP_DOWN
2RGB_MATRIX_EFFECT(CYCLE_UP_DOWN)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static HSV CYCLE_UP_DOWN_math(HSV hsv, uint8_t i, uint8_t time) {
6 hsv.h = g_led_config.point[i].y - time;
7 return hsv;
8}
9
10bool CYCLE_UP_DOWN(effect_params_t* params) { return effect_runner_i(params, &CYCLE_UP_DOWN_math); }
11
12# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
13#endif // DISABLE_RGB_MATRIX_CYCLE_UP_DOWN
diff --git a/quantum/rgb_matrix/animations/digital_rain_anim.h b/quantum/rgb_matrix/animations/digital_rain_anim.h
new file mode 100644
index 000000000..1de45f8e8
--- /dev/null
+++ b/quantum/rgb_matrix/animations/digital_rain_anim.h
@@ -0,0 +1,75 @@
1#if defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) && !defined(DISABLE_RGB_MATRIX_DIGITAL_RAIN)
2RGB_MATRIX_EFFECT(DIGITAL_RAIN)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5# ifndef RGB_DIGITAL_RAIN_DROPS
6// lower the number for denser effect/wider keyboard
7# define RGB_DIGITAL_RAIN_DROPS 24
8# endif
9
10bool DIGITAL_RAIN(effect_params_t* params) {
11 // algorithm ported from https://github.com/tremby/Kaleidoscope-LEDEffect-DigitalRain
12 const uint8_t drop_ticks = 28;
13 const uint8_t pure_green_intensity = 0xd0;
14 const uint8_t max_brightness_boost = 0xc0;
15 const uint8_t max_intensity = 0xff;
16
17 static uint8_t drop = 0;
18
19 if (params->init) {
20 rgb_matrix_set_color_all(0, 0, 0);
21 memset(g_rgb_frame_buffer, 0, sizeof(g_rgb_frame_buffer));
22 drop = 0;
23 }
24
25 for (uint8_t col = 0; col < MATRIX_COLS; col++) {
26 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
27 if (row == 0 && drop == 0 && rand() < RAND_MAX / RGB_DIGITAL_RAIN_DROPS) {
28 // top row, pixels have just fallen and we're
29 // making a new rain drop in this column
30 g_rgb_frame_buffer[row][col] = max_intensity;
31 } else if (g_rgb_frame_buffer[row][col] > 0 && g_rgb_frame_buffer[row][col] < max_intensity) {
32 // neither fully bright nor dark, decay it
33 g_rgb_frame_buffer[row][col]--;
34 }
35 // set the pixel colour
36 uint8_t led[LED_HITS_TO_REMEMBER];
37 uint8_t led_count = rgb_matrix_map_row_column_to_led(row, col, led);
38
39 // TODO: multiple leds are supported mapped to the same row/column
40 if (led_count > 0) {
41 if (g_rgb_frame_buffer[row][col] > pure_green_intensity) {
42 const uint8_t boost = (uint8_t)((uint16_t)max_brightness_boost * (g_rgb_frame_buffer[row][col] - pure_green_intensity) / (max_intensity - pure_green_intensity));
43 rgb_matrix_set_color(led[0], boost, max_intensity, boost);
44 } else {
45 const uint8_t green = (uint8_t)((uint16_t)max_intensity * g_rgb_frame_buffer[row][col] / pure_green_intensity);
46 rgb_matrix_set_color(led[0], 0, green, 0);
47 }
48 }
49 }
50 }
51
52 if (++drop > drop_ticks) {
53 // reset drop timer
54 drop = 0;
55 for (uint8_t row = MATRIX_ROWS - 1; row > 0; row--) {
56 for (uint8_t col = 0; col < MATRIX_COLS; col++) {
57 // if ths is on the bottom row and bright allow decay
58 if (row == MATRIX_ROWS - 1 && g_rgb_frame_buffer[row][col] == max_intensity) {
59 g_rgb_frame_buffer[row][col]--;
60 }
61 // check if the pixel above is bright
62 if (g_rgb_frame_buffer[row - 1][col] == max_intensity) {
63 // allow old bright pixel to decay
64 g_rgb_frame_buffer[row - 1][col]--;
65 // make this pixel bright
66 g_rgb_frame_buffer[row][col] = max_intensity;
67 }
68 }
69 }
70 }
71 return false;
72}
73
74# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
75#endif // defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) && !defined(DISABLE_RGB_MATRIX_DIGITAL_RAIN)
diff --git a/quantum/rgb_matrix/animations/dual_beacon_anim.h b/quantum/rgb_matrix/animations/dual_beacon_anim.h
new file mode 100644
index 000000000..5c06080a2
--- /dev/null
+++ b/quantum/rgb_matrix/animations/dual_beacon_anim.h
@@ -0,0 +1,13 @@
1#ifdef ENABLE_RGB_MATRIX_DUAL_BEACON
2RGB_MATRIX_EFFECT(DUAL_BEACON)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static HSV DUAL_BEACON_math(HSV hsv, int8_t sin, int8_t cos, uint8_t i, uint8_t time) {
6 hsv.h += ((g_led_config.point[i].y - k_rgb_matrix_center.y) * cos + (g_led_config.point[i].x - k_rgb_matrix_center.x) * sin) / 128;
7 return hsv;
8}
9
10bool DUAL_BEACON(effect_params_t* params) { return effect_runner_sin_cos_i(params, &DUAL_BEACON_math); }
11
12# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
13#endif // DISABLE_RGB_MATRIX_DUAL_BEACON
diff --git a/quantum/rgb_matrix/animations/gradient_left_right_anim.h b/quantum/rgb_matrix/animations/gradient_left_right_anim.h
new file mode 100644
index 000000000..b4f2752ff
--- /dev/null
+++ b/quantum/rgb_matrix/animations/gradient_left_right_anim.h
@@ -0,0 +1,22 @@
1#ifdef ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT
2RGB_MATRIX_EFFECT(GRADIENT_LEFT_RIGHT)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5bool GRADIENT_LEFT_RIGHT(effect_params_t* params) {
6 RGB_MATRIX_USE_LIMITS(led_min, led_max);
7
8 HSV hsv = rgb_matrix_config.hsv;
9 uint8_t scale = scale8(64, rgb_matrix_config.speed);
10 for (uint8_t i = led_min; i < led_max; i++) {
11 RGB_MATRIX_TEST_LED_FLAGS();
12 // The x range will be 0..224, map this to 0..7
13 // Relies on hue being 8-bit and wrapping
14 hsv.h = rgb_matrix_config.hsv.h + (scale * g_led_config.point[i].x >> 5);
15 RGB rgb = rgb_matrix_hsv_to_rgb(hsv);
16 rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
17 }
18 return led_max < DRIVER_LED_TOTAL;
19}
20
21# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
22#endif // DISABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT
diff --git a/quantum/rgb_matrix/animations/gradient_up_down_anim.h b/quantum/rgb_matrix/animations/gradient_up_down_anim.h
new file mode 100644
index 000000000..3fd45cf99
--- /dev/null
+++ b/quantum/rgb_matrix/animations/gradient_up_down_anim.h
@@ -0,0 +1,22 @@
1#ifdef ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN
2RGB_MATRIX_EFFECT(GRADIENT_UP_DOWN)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5bool GRADIENT_UP_DOWN(effect_params_t* params) {
6 RGB_MATRIX_USE_LIMITS(led_min, led_max);
7
8 HSV hsv = rgb_matrix_config.hsv;
9 uint8_t scale = scale8(64, rgb_matrix_config.speed);
10 for (uint8_t i = led_min; i < led_max; i++) {
11 RGB_MATRIX_TEST_LED_FLAGS();
12 // The y range will be 0..64, map this to 0..4
13 // Relies on hue being 8-bit and wrapping
14 hsv.h = rgb_matrix_config.hsv.h + scale * (g_led_config.point[i].y >> 4);
15 RGB rgb = rgb_matrix_hsv_to_rgb(hsv);
16 rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
17 }
18 return led_max < DRIVER_LED_TOTAL;
19}
20
21# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
22#endif // DISABLE_RGB_MATRIX_GRADIENT_UP_DOWN
diff --git a/quantum/rgb_matrix/animations/hue_breathing_anim.h b/quantum/rgb_matrix/animations/hue_breathing_anim.h
new file mode 100644
index 000000000..6d974b8c3
--- /dev/null
+++ b/quantum/rgb_matrix/animations/hue_breathing_anim.h
@@ -0,0 +1,22 @@
1#ifdef ENABLE_RGB_MATRIX_HUE_BREATHING
2RGB_MATRIX_EFFECT(HUE_BREATHING)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5// Change huedelta to adjust range of hue change. 0-255.
6// Hue Breathing - All LED's light up
7bool HUE_BREATHING(effect_params_t* params) {
8 RGB_MATRIX_USE_LIMITS(led_min, led_max);
9 uint8_t huedelta = 12;
10 HSV hsv = rgb_matrix_config.hsv;
11 uint16_t time = scale16by8(g_rgb_timer, rgb_matrix_config.speed / 8);
12 hsv.h = hsv.h + scale8(abs8(sin8(time) - 128) * 2, huedelta);
13 RGB rgb = hsv_to_rgb(hsv);
14 for (uint8_t i = led_min; i < led_max; i++) {
15 RGB_MATRIX_TEST_LED_FLAGS();
16 rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
17 }
18 return led_max < DRIVER_LED_TOTAL;
19}
20
21# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
22#endif // DISABLE_RGB_HUE_BREATHING
diff --git a/quantum/rgb_matrix/animations/hue_pendulum_anim.h b/quantum/rgb_matrix/animations/hue_pendulum_anim.h
new file mode 100644
index 000000000..a6e1c1074
--- /dev/null
+++ b/quantum/rgb_matrix/animations/hue_pendulum_anim.h
@@ -0,0 +1,17 @@
1#ifdef ENABLE_RGB_MATRIX_HUE_PENDULUM
2RGB_MATRIX_EFFECT(HUE_PENDULUM)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5// Change huedelta to adjust range of hue change. 0-255.
6// Looks better with a low value and slow speed for subtle change.
7// Hue Pendulum - color changes in a wave to the right before reversing direction
8static HSV HUE_PENDULUM_math(HSV hsv, uint8_t i, uint8_t time) {
9 uint8_t huedelta = 12;
10 hsv.h = hsv.h + scale8(abs8(sin8(time) + (g_led_config.point[i].x) - 128) * 2, huedelta);
11 return hsv;
12}
13
14bool HUE_PENDULUM(effect_params_t* params) { return effect_runner_i(params, &HUE_PENDULUM_math); }
15
16# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
17#endif // DISABLE_RGB_HUE_PENDULUM
diff --git a/quantum/rgb_matrix/animations/hue_wave_anim.h b/quantum/rgb_matrix/animations/hue_wave_anim.h
new file mode 100644
index 000000000..b1c72b733
--- /dev/null
+++ b/quantum/rgb_matrix/animations/hue_wave_anim.h
@@ -0,0 +1,17 @@
1#ifdef ENABLE_RGB_MATRIX_HUE_WAVE
2RGB_MATRIX_EFFECT(HUE_WAVE)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5// Change huedelta to adjust range of hue change. 0-255.
6// Looks better with a low value and slow speed for subtle change.
7// Hue Wave - color changes in a wave to the right
8static HSV HUE_WAVE_math(HSV hsv, uint8_t i, uint8_t time) {
9 uint8_t huedelta = 24;
10 hsv.h = hsv.h + scale8(abs8(g_led_config.point[i].x - time), huedelta);
11 return hsv;
12}
13
14bool HUE_WAVE(effect_params_t* params) { return effect_runner_i(params, &HUE_WAVE_math); }
15
16# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
17#endif // DISABLE_RGB_HUE_WAVE
diff --git a/quantum/rgb_matrix/animations/jellybean_raindrops_anim.h b/quantum/rgb_matrix/animations/jellybean_raindrops_anim.h
new file mode 100644
index 000000000..7d8eafffb
--- /dev/null
+++ b/quantum/rgb_matrix/animations/jellybean_raindrops_anim.h
@@ -0,0 +1,29 @@
1#ifdef ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
2RGB_MATRIX_EFFECT(JELLYBEAN_RAINDROPS)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static void jellybean_raindrops_set_color(int i, effect_params_t* params) {
6 if (!HAS_ANY_FLAGS(g_led_config.flags[i], params->flags)) return;
7 HSV hsv = {rand() & 0xFF, qadd8(rand() & 0x7F, 0x80), rgb_matrix_config.hsv.v};
8 RGB rgb = rgb_matrix_hsv_to_rgb(hsv);
9 rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
10}
11
12bool JELLYBEAN_RAINDROPS(effect_params_t* params) {
13 if (!params->init) {
14 // Change one LED every tick, make sure speed is not 0
15 if (scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 16)) % 5 == 0) {
16 jellybean_raindrops_set_color(rand() % DRIVER_LED_TOTAL, params);
17 }
18 return false;
19 }
20
21 RGB_MATRIX_USE_LIMITS(led_min, led_max);
22 for (int i = led_min; i < led_max; i++) {
23 jellybean_raindrops_set_color(i, params);
24 }
25 return led_max < DRIVER_LED_TOTAL;
26}
27
28# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
29#endif // DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
diff --git a/quantum/rgb_matrix/animations/rainbow_beacon_anim.h b/quantum/rgb_matrix/animations/rainbow_beacon_anim.h
new file mode 100644
index 000000000..b54d997f6
--- /dev/null
+++ b/quantum/rgb_matrix/animations/rainbow_beacon_anim.h
@@ -0,0 +1,13 @@
1#ifdef ENABLE_RGB_MATRIX_RAINBOW_BEACON
2RGB_MATRIX_EFFECT(RAINBOW_BEACON)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static HSV RAINBOW_BEACON_math(HSV hsv, int8_t sin, int8_t cos, uint8_t i, uint8_t time) {
6 hsv.h += ((g_led_config.point[i].y - k_rgb_matrix_center.y) * 2 * cos + (g_led_config.point[i].x - k_rgb_matrix_center.x) * 2 * sin) / 128;
7 return hsv;
8}
9
10bool RAINBOW_BEACON(effect_params_t* params) { return effect_runner_sin_cos_i(params, &RAINBOW_BEACON_math); }
11
12# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
13#endif // DISABLE_RGB_MATRIX_RAINBOW_BEACON
diff --git a/quantum/rgb_matrix/animations/rainbow_moving_chevron_anim.h b/quantum/rgb_matrix/animations/rainbow_moving_chevron_anim.h
new file mode 100644
index 000000000..50db92201
--- /dev/null
+++ b/quantum/rgb_matrix/animations/rainbow_moving_chevron_anim.h
@@ -0,0 +1,13 @@
1#ifdef ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
2RGB_MATRIX_EFFECT(RAINBOW_MOVING_CHEVRON)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static HSV RAINBOW_MOVING_CHEVRON_math(HSV hsv, uint8_t i, uint8_t time) {
6 hsv.h += abs8(g_led_config.point[i].y - k_rgb_matrix_center.y) + (g_led_config.point[i].x - time);
7 return hsv;
8}
9
10bool RAINBOW_MOVING_CHEVRON(effect_params_t* params) { return effect_runner_i(params, &RAINBOW_MOVING_CHEVRON_math); }
11
12# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
13#endif // DISABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
diff --git a/quantum/rgb_matrix/animations/rainbow_pinwheels_anim.h b/quantum/rgb_matrix/animations/rainbow_pinwheels_anim.h
new file mode 100644
index 000000000..3299f15df
--- /dev/null
+++ b/quantum/rgb_matrix/animations/rainbow_pinwheels_anim.h
@@ -0,0 +1,13 @@
1#ifdef ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS
2RGB_MATRIX_EFFECT(RAINBOW_PINWHEELS)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static HSV RAINBOW_PINWHEELS_math(HSV hsv, int8_t sin, int8_t cos, uint8_t i, uint8_t time) {
6 hsv.h += ((g_led_config.point[i].y - k_rgb_matrix_center.y) * 3 * cos + (56 - abs8(g_led_config.point[i].x - k_rgb_matrix_center.x)) * 3 * sin) / 128;
7 return hsv;
8}
9
10bool RAINBOW_PINWHEELS(effect_params_t* params) { return effect_runner_sin_cos_i(params, &RAINBOW_PINWHEELS_math); }
11
12# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
13#endif // DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS
diff --git a/quantum/rgb_matrix/animations/raindrops_anim.h b/quantum/rgb_matrix/animations/raindrops_anim.h
new file mode 100644
index 000000000..c01688e2c
--- /dev/null
+++ b/quantum/rgb_matrix/animations/raindrops_anim.h
@@ -0,0 +1,39 @@
1#ifdef ENABLE_RGB_MATRIX_RAINDROPS
2RGB_MATRIX_EFFECT(RAINDROPS)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static void raindrops_set_color(int i, effect_params_t* params) {
6 if (!HAS_ANY_FLAGS(g_led_config.flags[i], params->flags)) return;
7 HSV hsv = {0, rgb_matrix_config.hsv.s, rgb_matrix_config.hsv.v};
8
9 // Take the shortest path between hues
10 int16_t deltaH = ((rgb_matrix_config.hsv.h + 180) % 360 - rgb_matrix_config.hsv.h) / 4;
11 if (deltaH > 127) {
12 deltaH -= 256;
13 } else if (deltaH < -127) {
14 deltaH += 256;
15 }
16
17 hsv.h = rgb_matrix_config.hsv.h + (deltaH * (rand() & 0x03));
18 RGB rgb = rgb_matrix_hsv_to_rgb(hsv);
19 rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
20}
21
22bool RAINDROPS(effect_params_t* params) {
23 if (!params->init) {
24 // Change one LED every tick, make sure speed is not 0
25 if (scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 16)) % 10 == 0) {
26 raindrops_set_color(rand() % DRIVER_LED_TOTAL, params);
27 }
28 return false;
29 }
30
31 RGB_MATRIX_USE_LIMITS(led_min, led_max);
32 for (int i = led_min; i < led_max; i++) {
33 raindrops_set_color(i, params);
34 }
35 return led_max < DRIVER_LED_TOTAL;
36}
37
38# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
39#endif // DISABLE_RGB_MATRIX_RAINDROPS
diff --git a/quantum/rgb_matrix/animations/rgb_matrix_effects.inc b/quantum/rgb_matrix/animations/rgb_matrix_effects.inc
new file mode 100644
index 000000000..302ad79c0
--- /dev/null
+++ b/quantum/rgb_matrix/animations/rgb_matrix_effects.inc
@@ -0,0 +1,37 @@
1// Add your new core rgb matrix effect here, order determines enum order
2#include "solid_color_anim.h"
3#include "alpha_mods_anim.h"
4#include "gradient_up_down_anim.h"
5#include "gradient_left_right_anim.h"
6#include "breathing_anim.h"
7#include "colorband_sat_anim.h"
8#include "colorband_val_anim.h"
9#include "colorband_pinwheel_sat_anim.h"
10#include "colorband_pinwheel_val_anim.h"
11#include "colorband_spiral_sat_anim.h"
12#include "colorband_spiral_val_anim.h"
13#include "cycle_all_anim.h"
14#include "cycle_left_right_anim.h"
15#include "cycle_up_down_anim.h"
16#include "rainbow_moving_chevron_anim.h"
17#include "cycle_out_in_anim.h"
18#include "cycle_out_in_dual_anim.h"
19#include "cycle_pinwheel_anim.h"
20#include "cycle_spiral_anim.h"
21#include "dual_beacon_anim.h"
22#include "rainbow_beacon_anim.h"
23#include "rainbow_pinwheels_anim.h"
24#include "raindrops_anim.h"
25#include "jellybean_raindrops_anim.h"
26#include "hue_breathing_anim.h"
27#include "hue_pendulum_anim.h"
28#include "hue_wave_anim.h"
29#include "typing_heatmap_anim.h"
30#include "digital_rain_anim.h"
31#include "solid_reactive_simple_anim.h"
32#include "solid_reactive_anim.h"
33#include "solid_reactive_wide.h"
34#include "solid_reactive_cross.h"
35#include "solid_reactive_nexus.h"
36#include "splash_anim.h"
37#include "solid_splash_anim.h"
diff --git a/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy.h b/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy.h
new file mode 100644
index 000000000..4867609c8
--- /dev/null
+++ b/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy.h
@@ -0,0 +1,17 @@
1#pragma once
2
3typedef HSV (*dx_dy_f)(HSV hsv, int16_t dx, int16_t dy, uint8_t time);
4
5bool effect_runner_dx_dy(effect_params_t* params, dx_dy_f effect_func) {
6 RGB_MATRIX_USE_LIMITS(led_min, led_max);
7
8 uint8_t time = scale16by8(g_rgb_timer, rgb_matrix_config.speed / 2);
9 for (uint8_t i = led_min; i < led_max; i++) {
10 RGB_MATRIX_TEST_LED_FLAGS();
11 int16_t dx = g_led_config.point[i].x - k_rgb_matrix_center.x;
12 int16_t dy = g_led_config.point[i].y - k_rgb_matrix_center.y;
13 RGB rgb = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, dx, dy, time));
14 rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
15 }
16 return led_max < DRIVER_LED_TOTAL;
17}
diff --git a/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy_dist.h b/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy_dist.h
new file mode 100644
index 000000000..9545b418d
--- /dev/null
+++ b/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy_dist.h
@@ -0,0 +1,18 @@
1#pragma once
2
3typedef HSV (*dx_dy_dist_f)(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint8_t time);
4
5bool effect_runner_dx_dy_dist(effect_params_t* params, dx_dy_dist_f effect_func) {
6 RGB_MATRIX_USE_LIMITS(led_min, led_max);
7
8 uint8_t time = scale16by8(g_rgb_timer, rgb_matrix_config.speed / 2);
9 for (uint8_t i = led_min; i < led_max; i++) {
10 RGB_MATRIX_TEST_LED_FLAGS();
11 int16_t dx = g_led_config.point[i].x - k_rgb_matrix_center.x;
12 int16_t dy = g_led_config.point[i].y - k_rgb_matrix_center.y;
13 uint8_t dist = sqrt16(dx * dx + dy * dy);
14 RGB rgb = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, dx, dy, dist, time));
15 rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
16 }
17 return led_max < DRIVER_LED_TOTAL;
18}
diff --git a/quantum/rgb_matrix/animations/runners/effect_runner_i.h b/quantum/rgb_matrix/animations/runners/effect_runner_i.h
new file mode 100644
index 000000000..1881cd6c6
--- /dev/null
+++ b/quantum/rgb_matrix/animations/runners/effect_runner_i.h
@@ -0,0 +1,15 @@
1#pragma once
2
3typedef HSV (*i_f)(HSV hsv, uint8_t i, uint8_t time);
4
5bool effect_runner_i(effect_params_t* params, i_f effect_func) {
6 RGB_MATRIX_USE_LIMITS(led_min, led_max);
7
8 uint8_t time = scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed / 4, 1));
9 for (uint8_t i = led_min; i < led_max; i++) {
10 RGB_MATRIX_TEST_LED_FLAGS();
11 RGB rgb = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, i, time));
12 rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
13 }
14 return led_max < DRIVER_LED_TOTAL;
15}
diff --git a/quantum/rgb_matrix/animations/runners/effect_runner_reactive.h b/quantum/rgb_matrix/animations/runners/effect_runner_reactive.h
new file mode 100644
index 000000000..75b7c0df4
--- /dev/null
+++ b/quantum/rgb_matrix/animations/runners/effect_runner_reactive.h
@@ -0,0 +1,29 @@
1#pragma once
2
3#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
4
5typedef HSV (*reactive_f)(HSV hsv, uint16_t offset);
6
7bool effect_runner_reactive(effect_params_t* params, reactive_f effect_func) {
8 RGB_MATRIX_USE_LIMITS(led_min, led_max);
9
10 uint16_t max_tick = 65535 / qadd8(rgb_matrix_config.speed, 1);
11 for (uint8_t i = led_min; i < led_max; i++) {
12 RGB_MATRIX_TEST_LED_FLAGS();
13 uint16_t tick = max_tick;
14 // Reverse search to find most recent key hit
15 for (int8_t j = g_last_hit_tracker.count - 1; j >= 0; j--) {
16 if (g_last_hit_tracker.index[j] == i && g_last_hit_tracker.tick[j] < tick) {
17 tick = g_last_hit_tracker.tick[j];
18 break;
19 }
20 }
21
22 uint16_t offset = scale16by8(tick, qadd8(rgb_matrix_config.speed, 1));
23 RGB rgb = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, offset));
24 rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
25 }
26 return led_max < DRIVER_LED_TOTAL;
27}
28
29#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
diff --git a/quantum/rgb_matrix/animations/runners/effect_runner_reactive_splash.h b/quantum/rgb_matrix/animations/runners/effect_runner_reactive_splash.h
new file mode 100644
index 000000000..2e46ffb35
--- /dev/null
+++ b/quantum/rgb_matrix/animations/runners/effect_runner_reactive_splash.h
@@ -0,0 +1,29 @@
1#pragma once
2
3#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
4
5typedef HSV (*reactive_splash_f)(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick);
6
7bool effect_runner_reactive_splash(uint8_t start, effect_params_t* params, reactive_splash_f effect_func) {
8 RGB_MATRIX_USE_LIMITS(led_min, led_max);
9
10 uint8_t count = g_last_hit_tracker.count;
11 for (uint8_t i = led_min; i < led_max; i++) {
12 RGB_MATRIX_TEST_LED_FLAGS();
13 HSV hsv = rgb_matrix_config.hsv;
14 hsv.v = 0;
15 for (uint8_t j = start; j < count; j++) {
16 int16_t dx = g_led_config.point[i].x - g_last_hit_tracker.x[j];
17 int16_t dy = g_led_config.point[i].y - g_last_hit_tracker.y[j];
18 uint8_t dist = sqrt16(dx * dx + dy * dy);
19 uint16_t tick = scale16by8(g_last_hit_tracker.tick[j], qadd8(rgb_matrix_config.speed, 1));
20 hsv = effect_func(hsv, dx, dy, dist, tick);
21 }
22 hsv.v = scale8(hsv.v, rgb_matrix_config.hsv.v);
23 RGB rgb = rgb_matrix_hsv_to_rgb(hsv);
24 rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
25 }
26 return led_max < DRIVER_LED_TOTAL;
27}
28
29#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
diff --git a/quantum/rgb_matrix/animations/runners/effect_runner_sin_cos_i.h b/quantum/rgb_matrix/animations/runners/effect_runner_sin_cos_i.h
new file mode 100644
index 000000000..02351de51
--- /dev/null
+++ b/quantum/rgb_matrix/animations/runners/effect_runner_sin_cos_i.h
@@ -0,0 +1,17 @@
1#pragma once
2
3typedef HSV (*sin_cos_i_f)(HSV hsv, int8_t sin, int8_t cos, uint8_t i, uint8_t time);
4
5bool effect_runner_sin_cos_i(effect_params_t* params, sin_cos_i_f effect_func) {
6 RGB_MATRIX_USE_LIMITS(led_min, led_max);
7
8 uint16_t time = scale16by8(g_rgb_timer, rgb_matrix_config.speed / 4);
9 int8_t cos_value = cos8(time) - 128;
10 int8_t sin_value = sin8(time) - 128;
11 for (uint8_t i = led_min; i < led_max; i++) {
12 RGB_MATRIX_TEST_LED_FLAGS();
13 RGB rgb = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, cos_value, sin_value, i, time));
14 rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
15 }
16 return led_max < DRIVER_LED_TOTAL;
17}
diff --git a/quantum/rgb_matrix/animations/runners/rgb_matrix_runners.inc b/quantum/rgb_matrix/animations/runners/rgb_matrix_runners.inc
new file mode 100644
index 000000000..c09022bb0
--- /dev/null
+++ b/quantum/rgb_matrix/animations/runners/rgb_matrix_runners.inc
@@ -0,0 +1,6 @@
1#include "effect_runner_dx_dy_dist.h"
2#include "effect_runner_dx_dy.h"
3#include "effect_runner_i.h"
4#include "effect_runner_sin_cos_i.h"
5#include "effect_runner_reactive.h"
6#include "effect_runner_reactive_splash.h"
diff --git a/quantum/rgb_matrix/animations/solid_color_anim.h b/quantum/rgb_matrix/animations/solid_color_anim.h
new file mode 100644
index 000000000..79d63cf13
--- /dev/null
+++ b/quantum/rgb_matrix/animations/solid_color_anim.h
@@ -0,0 +1,15 @@
1RGB_MATRIX_EFFECT(SOLID_COLOR)
2#ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
3
4bool SOLID_COLOR(effect_params_t* params) {
5 RGB_MATRIX_USE_LIMITS(led_min, led_max);
6
7 RGB rgb = rgb_matrix_hsv_to_rgb(rgb_matrix_config.hsv);
8 for (uint8_t i = led_min; i < led_max; i++) {
9 RGB_MATRIX_TEST_LED_FLAGS();
10 rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
11 }
12 return led_max < DRIVER_LED_TOTAL;
13}
14
15#endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
diff --git a/quantum/rgb_matrix/animations/solid_reactive_anim.h b/quantum/rgb_matrix/animations/solid_reactive_anim.h
new file mode 100644
index 000000000..d45bb961b
--- /dev/null
+++ b/quantum/rgb_matrix/animations/solid_reactive_anim.h
@@ -0,0 +1,15 @@
1#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
2# ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE
3RGB_MATRIX_EFFECT(SOLID_REACTIVE)
4# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
5
6static HSV SOLID_REACTIVE_math(HSV hsv, uint16_t offset) {
7 hsv.h += qsub8(130, offset);
8 return hsv;
9}
10
11bool SOLID_REACTIVE(effect_params_t* params) { return effect_runner_reactive(params, &SOLID_REACTIVE_math); }
12
13# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
14# endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE
15#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
diff --git a/quantum/rgb_matrix/animations/solid_reactive_cross.h b/quantum/rgb_matrix/animations/solid_reactive_cross.h
new file mode 100644
index 000000000..f76c68e8c
--- /dev/null
+++ b/quantum/rgb_matrix/animations/solid_reactive_cross.h
@@ -0,0 +1,36 @@
1#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
2# if !defined(DISABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS) || !defined(DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS)
3
4# ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS
5RGB_MATRIX_EFFECT(SOLID_REACTIVE_CROSS)
6# endif
7
8# ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS
9RGB_MATRIX_EFFECT(SOLID_REACTIVE_MULTICROSS)
10# endif
11
12# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
13
14static HSV SOLID_REACTIVE_CROSS_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) {
15 uint16_t effect = tick + dist;
16 dx = dx < 0 ? dx * -1 : dx;
17 dy = dy < 0 ? dy * -1 : dy;
18 dx = dx * 16 > 255 ? 255 : dx * 16;
19 dy = dy * 16 > 255 ? 255 : dy * 16;
20 effect += dx > dy ? dy : dx;
21 if (effect > 255) effect = 255;
22 hsv.v = qadd8(hsv.v, 255 - effect);
23 return hsv;
24}
25
26# ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS
27bool SOLID_REACTIVE_CROSS(effect_params_t* params) { return effect_runner_reactive_splash(qsub8(g_last_hit_tracker.count, 1), params, &SOLID_REACTIVE_CROSS_math); }
28# endif
29
30# ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS
31bool SOLID_REACTIVE_MULTICROSS(effect_params_t* params) { return effect_runner_reactive_splash(0, params, &SOLID_REACTIVE_CROSS_math); }
32# endif
33
34# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
35# endif // !defined(DISABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS) || !defined(DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS)
36#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
diff --git a/quantum/rgb_matrix/animations/solid_reactive_nexus.h b/quantum/rgb_matrix/animations/solid_reactive_nexus.h
new file mode 100644
index 000000000..17f94e3c1
--- /dev/null
+++ b/quantum/rgb_matrix/animations/solid_reactive_nexus.h
@@ -0,0 +1,34 @@
1#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
2# if !defined(DISABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS) || !defined(DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS)
3
4# ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS
5RGB_MATRIX_EFFECT(SOLID_REACTIVE_NEXUS)
6# endif
7
8# ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS
9RGB_MATRIX_EFFECT(SOLID_REACTIVE_MULTINEXUS)
10# endif
11
12# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
13
14static HSV SOLID_REACTIVE_NEXUS_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) {
15 uint16_t effect = tick - dist;
16 if (effect > 255) effect = 255;
17 if (dist > 72) effect = 255;
18 if ((dx > 8 || dx < -8) && (dy > 8 || dy < -8)) effect = 255;
19 hsv.v = qadd8(hsv.v, 255 - effect);
20 hsv.h = rgb_matrix_config.hsv.h + dy / 4;
21 return hsv;
22}
23
24# ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS
25bool SOLID_REACTIVE_NEXUS(effect_params_t* params) { return effect_runner_reactive_splash(qsub8(g_last_hit_tracker.count, 1), params, &SOLID_REACTIVE_NEXUS_math); }
26# endif
27
28# ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS
29bool SOLID_REACTIVE_MULTINEXUS(effect_params_t* params) { return effect_runner_reactive_splash(0, params, &SOLID_REACTIVE_NEXUS_math); }
30# endif
31
32# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
33# endif // !defined(DISABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS) || !defined(DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS)
34#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
diff --git a/quantum/rgb_matrix/animations/solid_reactive_simple_anim.h b/quantum/rgb_matrix/animations/solid_reactive_simple_anim.h
new file mode 100644
index 000000000..12eb248cc
--- /dev/null
+++ b/quantum/rgb_matrix/animations/solid_reactive_simple_anim.h
@@ -0,0 +1,15 @@
1#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
2# ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
3RGB_MATRIX_EFFECT(SOLID_REACTIVE_SIMPLE)
4# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
5
6static HSV SOLID_REACTIVE_SIMPLE_math(HSV hsv, uint16_t offset) {
7 hsv.v = scale8(255 - offset, hsv.v);
8 return hsv;
9}
10
11bool SOLID_REACTIVE_SIMPLE(effect_params_t* params) { return effect_runner_reactive(params, &SOLID_REACTIVE_SIMPLE_math); }
12
13# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
14# endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
15#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
diff --git a/quantum/rgb_matrix/animations/solid_reactive_wide.h b/quantum/rgb_matrix/animations/solid_reactive_wide.h
new file mode 100644
index 000000000..1cc4dca72
--- /dev/null
+++ b/quantum/rgb_matrix/animations/solid_reactive_wide.h
@@ -0,0 +1,31 @@
1#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
2# if !defined(DISABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE) || !defined(DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE)
3
4# ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE
5RGB_MATRIX_EFFECT(SOLID_REACTIVE_WIDE)
6# endif
7
8# ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE
9RGB_MATRIX_EFFECT(SOLID_REACTIVE_MULTIWIDE)
10# endif
11
12# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
13
14static HSV SOLID_REACTIVE_WIDE_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) {
15 uint16_t effect = tick + dist * 5;
16 if (effect > 255) effect = 255;
17 hsv.v = qadd8(hsv.v, 255 - effect);
18 return hsv;
19}
20
21# ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE
22bool SOLID_REACTIVE_WIDE(effect_params_t* params) { return effect_runner_reactive_splash(qsub8(g_last_hit_tracker.count, 1), params, &SOLID_REACTIVE_WIDE_math); }
23# endif
24
25# ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE
26bool SOLID_REACTIVE_MULTIWIDE(effect_params_t* params) { return effect_runner_reactive_splash(0, params, &SOLID_REACTIVE_WIDE_math); }
27# endif
28
29# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
30# endif // !defined(DISABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE) || !defined(DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE)
31#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
diff --git a/quantum/rgb_matrix/animations/solid_splash_anim.h b/quantum/rgb_matrix/animations/solid_splash_anim.h
new file mode 100644
index 000000000..99efb4996
--- /dev/null
+++ b/quantum/rgb_matrix/animations/solid_splash_anim.h
@@ -0,0 +1,31 @@
1#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
2# if !defined(DISABLE_RGB_MATRIX_SOLID_SPLASH) || !defined(DISABLE_RGB_MATRIX_SOLID_MULTISPLASH)
3
4# ifndef DISABLE_RGB_MATRIX_SOLID_SPLASH
5RGB_MATRIX_EFFECT(SOLID_SPLASH)
6# endif
7
8# ifndef DISABLE_RGB_MATRIX_SOLID_MULTISPLASH
9RGB_MATRIX_EFFECT(SOLID_MULTISPLASH)
10# endif
11
12# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
13
14HSV SOLID_SPLASH_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) {
15 uint16_t effect = tick - dist;
16 if (effect > 255) effect = 255;
17 hsv.v = qadd8(hsv.v, 255 - effect);
18 return hsv;
19}
20
21# ifndef DISABLE_RGB_MATRIX_SOLID_SPLASH
22bool SOLID_SPLASH(effect_params_t* params) { return effect_runner_reactive_splash(qsub8(g_last_hit_tracker.count, 1), params, &SOLID_SPLASH_math); }
23# endif
24
25# ifndef DISABLE_RGB_MATRIX_SOLID_MULTISPLASH
26bool SOLID_MULTISPLASH(effect_params_t* params) { return effect_runner_reactive_splash(0, params, &SOLID_SPLASH_math); }
27# endif
28
29# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
30# endif // !defined(DISABLE_RGB_MATRIX_SPLASH) && !defined(DISABLE_RGB_MATRIX_MULTISPLASH)
31#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
diff --git a/quantum/rgb_matrix/animations/splash_anim.h b/quantum/rgb_matrix/animations/splash_anim.h
new file mode 100644
index 000000000..1415bcc0f
--- /dev/null
+++ b/quantum/rgb_matrix/animations/splash_anim.h
@@ -0,0 +1,32 @@
1#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
2# if !defined(DISABLE_RGB_MATRIX_SPLASH) || !defined(DISABLE_RGB_MATRIX_MULTISPLASH)
3
4# ifndef DISABLE_RGB_MATRIX_SPLASH
5RGB_MATRIX_EFFECT(SPLASH)
6# endif
7
8# ifndef DISABLE_RGB_MATRIX_MULTISPLASH
9RGB_MATRIX_EFFECT(MULTISPLASH)
10# endif
11
12# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
13
14HSV SPLASH_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) {
15 uint16_t effect = tick - dist;
16 if (effect > 255) effect = 255;
17 hsv.h += effect;
18 hsv.v = qadd8(hsv.v, 255 - effect);
19 return hsv;
20}
21
22# ifndef DISABLE_RGB_MATRIX_SPLASH
23bool SPLASH(effect_params_t* params) { return effect_runner_reactive_splash(qsub8(g_last_hit_tracker.count, 1), params, &SPLASH_math); }
24# endif
25
26# ifndef DISABLE_RGB_MATRIX_MULTISPLASH
27bool MULTISPLASH(effect_params_t* params) { return effect_runner_reactive_splash(0, params, &SPLASH_math); }
28# endif
29
30# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
31# endif // !defined(DISABLE_RGB_MATRIX_SPLASH) || !defined(DISABLE_RGB_MATRIX_MULTISPLASH)
32#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
diff --git a/quantum/rgb_matrix/animations/typing_heatmap_anim.h b/quantum/rgb_matrix/animations/typing_heatmap_anim.h
new file mode 100644
index 000000000..28f040109
--- /dev/null
+++ b/quantum/rgb_matrix/animations/typing_heatmap_anim.h
@@ -0,0 +1,86 @@
1#if defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) && defined(ENABLE_RGB_MATRIX_TYPING_HEATMAP)
2RGB_MATRIX_EFFECT(TYPING_HEATMAP)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5# ifndef RGB_MATRIX_TYPING_HEATMAP_DECREASE_DELAY_MS
6# define RGB_MATRIX_TYPING_HEATMAP_DECREASE_DELAY_MS 25
7# endif
8
9void process_rgb_matrix_typing_heatmap(uint8_t row, uint8_t col) {
10 uint8_t m_row = row - 1;
11 uint8_t p_row = row + 1;
12 uint8_t m_col = col - 1;
13 uint8_t p_col = col + 1;
14
15 if (m_col < col) g_rgb_frame_buffer[row][m_col] = qadd8(g_rgb_frame_buffer[row][m_col], 16);
16 g_rgb_frame_buffer[row][col] = qadd8(g_rgb_frame_buffer[row][col], 32);
17 if (p_col < MATRIX_COLS) g_rgb_frame_buffer[row][p_col] = qadd8(g_rgb_frame_buffer[row][p_col], 16);
18
19 if (p_row < MATRIX_ROWS) {
20 if (m_col < col) g_rgb_frame_buffer[p_row][m_col] = qadd8(g_rgb_frame_buffer[p_row][m_col], 13);
21 g_rgb_frame_buffer[p_row][col] = qadd8(g_rgb_frame_buffer[p_row][col], 16);
22 if (p_col < MATRIX_COLS) g_rgb_frame_buffer[p_row][p_col] = qadd8(g_rgb_frame_buffer[p_row][p_col], 13);
23 }
24
25 if (m_row < row) {
26 if (m_col < col) g_rgb_frame_buffer[m_row][m_col] = qadd8(g_rgb_frame_buffer[m_row][m_col], 13);
27 g_rgb_frame_buffer[m_row][col] = qadd8(g_rgb_frame_buffer[m_row][col], 16);
28 if (p_col < MATRIX_COLS) g_rgb_frame_buffer[m_row][p_col] = qadd8(g_rgb_frame_buffer[m_row][p_col], 13);
29 }
30}
31
32// A timer to track the last time we decremented all heatmap values.
33static uint16_t heatmap_decrease_timer;
34// Whether we should decrement the heatmap values during the next update.
35static bool decrease_heatmap_values;
36
37bool TYPING_HEATMAP(effect_params_t* params) {
38 // Modified version of RGB_MATRIX_USE_LIMITS to work off of matrix row / col size
39 uint8_t led_min = RGB_MATRIX_LED_PROCESS_LIMIT * params->iter;
40 uint8_t led_max = led_min + RGB_MATRIX_LED_PROCESS_LIMIT;
41 if (led_max > sizeof(g_rgb_frame_buffer)) led_max = sizeof(g_rgb_frame_buffer);
42
43 if (params->init) {
44 rgb_matrix_set_color_all(0, 0, 0);
45 memset(g_rgb_frame_buffer, 0, sizeof g_rgb_frame_buffer);
46 }
47
48 // The heatmap animation might run in several iterations depending on
49 // `RGB_MATRIX_LED_PROCESS_LIMIT`, therefore we only want to update the
50 // timer when the animation starts.
51 if (params->iter == 0) {
52 decrease_heatmap_values = timer_elapsed(heatmap_decrease_timer) >= RGB_MATRIX_TYPING_HEATMAP_DECREASE_DELAY_MS;
53
54 // Restart the timer if we are going to decrease the heatmap this frame.
55 if (decrease_heatmap_values) {
56 heatmap_decrease_timer = timer_read();
57 }
58 }
59
60 // Render heatmap & decrease
61 for (int i = led_min; i < led_max; i++) {
62 uint8_t row = i % MATRIX_ROWS;
63 uint8_t col = i / MATRIX_ROWS;
64 uint8_t val = g_rgb_frame_buffer[row][col];
65
66 // set the pixel colour
67 uint8_t led[LED_HITS_TO_REMEMBER];
68 uint8_t led_count = rgb_matrix_map_row_column_to_led(row, col, led);
69 for (uint8_t j = 0; j < led_count; ++j) {
70 if (!HAS_ANY_FLAGS(g_led_config.flags[led[j]], params->flags)) continue;
71
72 HSV hsv = {170 - qsub8(val, 85), rgb_matrix_config.hsv.s, scale8((qadd8(170, val) - 170) * 3, rgb_matrix_config.hsv.v)};
73 RGB rgb = rgb_matrix_hsv_to_rgb(hsv);
74 rgb_matrix_set_color(led[j], rgb.r, rgb.g, rgb.b);
75 }
76
77 if (decrease_heatmap_values) {
78 g_rgb_frame_buffer[row][col] = qsub8(val, 1);
79 }
80 }
81
82 return led_max < sizeof(g_rgb_frame_buffer);
83}
84
85# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
86#endif // defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) && !defined(DISABLE_RGB_MATRIX_TYPING_HEATMAP)
diff --git a/quantum/rgb_matrix/rgb_matrix.c b/quantum/rgb_matrix/rgb_matrix.c
new file mode 100644
index 000000000..e5635ee03
--- /dev/null
+++ b/quantum/rgb_matrix/rgb_matrix.c
@@ -0,0 +1,640 @@
1/* Copyright 2017 Jason Williams
2 * Copyright 2017 Jack Humbert
3 * Copyright 2018 Yiancar
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include "rgb_matrix.h"
20#include "progmem.h"
21#include "config.h"
22#include "eeprom.h"
23#include <string.h>
24#include <math.h>
25
26#include <lib/lib8tion/lib8tion.h>
27
28#ifndef RGB_MATRIX_CENTER
29const led_point_t k_rgb_matrix_center = {112, 32};
30#else
31const led_point_t k_rgb_matrix_center = RGB_MATRIX_CENTER;
32#endif
33
34// clang-format off
35#ifndef RGB_MATRIX_IMMEDIATE_EEPROM
36# define rgb_eeconfig_update(v) rgb_update_eeprom |= v
37#else
38# define rgb_eeconfig_update(v) if (v) eeconfig_update_rgb_matrix()
39#endif
40// clang-format on
41
42__attribute__((weak)) RGB rgb_matrix_hsv_to_rgb(HSV hsv) { return hsv_to_rgb(hsv); }
43
44// Generic effect runners
45#include "rgb_matrix_runners.inc"
46
47// ------------------------------------------
48// -----Begin rgb effect includes macros-----
49#define RGB_MATRIX_EFFECT(name)
50#define RGB_MATRIX_CUSTOM_EFFECT_IMPLS
51
52#include "rgb_matrix_effects.inc"
53#ifdef RGB_MATRIX_CUSTOM_KB
54# include "rgb_matrix_kb.inc"
55#endif
56#ifdef RGB_MATRIX_CUSTOM_USER
57# include "rgb_matrix_user.inc"
58#endif
59
60#undef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
61#undef RGB_MATRIX_EFFECT
62// -----End rgb effect includes macros-------
63// ------------------------------------------
64
65#if defined(RGB_DISABLE_AFTER_TIMEOUT) && !defined(RGB_DISABLE_TIMEOUT)
66# define RGB_DISABLE_TIMEOUT (RGB_DISABLE_AFTER_TIMEOUT * 1200UL)
67#endif
68
69#ifndef RGB_DISABLE_TIMEOUT
70# define RGB_DISABLE_TIMEOUT 0
71#endif
72
73#if !defined(RGB_MATRIX_MAXIMUM_BRIGHTNESS) || RGB_MATRIX_MAXIMUM_BRIGHTNESS > UINT8_MAX
74# undef RGB_MATRIX_MAXIMUM_BRIGHTNESS
75# define RGB_MATRIX_MAXIMUM_BRIGHTNESS UINT8_MAX
76#endif
77
78#if !defined(RGB_MATRIX_HUE_STEP)
79# define RGB_MATRIX_HUE_STEP 8
80#endif
81
82#if !defined(RGB_MATRIX_SAT_STEP)
83# define RGB_MATRIX_SAT_STEP 16
84#endif
85
86#if !defined(RGB_MATRIX_VAL_STEP)
87# define RGB_MATRIX_VAL_STEP 16
88#endif
89
90#if !defined(RGB_MATRIX_SPD_STEP)
91# define RGB_MATRIX_SPD_STEP 16
92#endif
93
94#if !defined(RGB_MATRIX_STARTUP_MODE)
95# ifdef ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
96# define RGB_MATRIX_STARTUP_MODE RGB_MATRIX_CYCLE_LEFT_RIGHT
97# else
98// fallback to solid colors if RGB_MATRIX_CYCLE_LEFT_RIGHT is disabled in userspace
99# define RGB_MATRIX_STARTUP_MODE RGB_MATRIX_SOLID_COLOR
100# endif
101#endif
102
103#if !defined(RGB_MATRIX_STARTUP_HUE)
104# define RGB_MATRIX_STARTUP_HUE 0
105#endif
106
107#if !defined(RGB_MATRIX_STARTUP_SAT)
108# define RGB_MATRIX_STARTUP_SAT UINT8_MAX
109#endif
110
111#if !defined(RGB_MATRIX_STARTUP_VAL)
112# define RGB_MATRIX_STARTUP_VAL RGB_MATRIX_MAXIMUM_BRIGHTNESS
113#endif
114
115#if !defined(RGB_MATRIX_STARTUP_SPD)
116# define RGB_MATRIX_STARTUP_SPD UINT8_MAX / 2
117#endif
118
119// globals
120rgb_config_t rgb_matrix_config; // TODO: would like to prefix this with g_ for global consistancy, do this in another pr
121uint32_t g_rgb_timer;
122#ifdef RGB_MATRIX_FRAMEBUFFER_EFFECTS
123uint8_t g_rgb_frame_buffer[MATRIX_ROWS][MATRIX_COLS] = {{0}};
124#endif // RGB_MATRIX_FRAMEBUFFER_EFFECTS
125#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
126last_hit_t g_last_hit_tracker;
127#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
128
129// internals
130static bool suspend_state = false;
131static bool rgb_update_eeprom = false;
132static uint8_t rgb_last_enable = UINT8_MAX;
133static uint8_t rgb_last_effect = UINT8_MAX;
134static effect_params_t rgb_effect_params = {0, LED_FLAG_ALL, false};
135static rgb_task_states rgb_task_state = SYNCING;
136#if RGB_DISABLE_TIMEOUT > 0
137static uint32_t rgb_anykey_timer;
138#endif // RGB_DISABLE_TIMEOUT > 0
139
140// double buffers
141static uint32_t rgb_timer_buffer;
142#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
143static last_hit_t last_hit_buffer;
144#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
145
146// split rgb matrix
147#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
148const uint8_t k_rgb_matrix_split[2] = RGB_MATRIX_SPLIT;
149#endif
150
151void eeconfig_read_rgb_matrix(void) { eeprom_read_block(&rgb_matrix_config, EECONFIG_RGB_MATRIX, sizeof(rgb_matrix_config)); }
152
153void eeconfig_update_rgb_matrix(void) { eeprom_update_block(&rgb_matrix_config, EECONFIG_RGB_MATRIX, sizeof(rgb_matrix_config)); }
154
155void eeconfig_update_rgb_matrix_default(void) {
156 dprintf("eeconfig_update_rgb_matrix_default\n");
157 rgb_matrix_config.enable = 1;
158 rgb_matrix_config.mode = RGB_MATRIX_STARTUP_MODE;
159 rgb_matrix_config.hsv = (HSV){RGB_MATRIX_STARTUP_HUE, RGB_MATRIX_STARTUP_SAT, RGB_MATRIX_STARTUP_VAL};
160 rgb_matrix_config.speed = RGB_MATRIX_STARTUP_SPD;
161 rgb_matrix_config.flags = LED_FLAG_ALL;
162 eeconfig_update_rgb_matrix();
163}
164
165void eeconfig_debug_rgb_matrix(void) {
166 dprintf("rgb_matrix_config EEPROM\n");
167 dprintf("rgb_matrix_config.enable = %d\n", rgb_matrix_config.enable);
168 dprintf("rgb_matrix_config.mode = %d\n", rgb_matrix_config.mode);
169 dprintf("rgb_matrix_config.hsv.h = %d\n", rgb_matrix_config.hsv.h);
170 dprintf("rgb_matrix_config.hsv.s = %d\n", rgb_matrix_config.hsv.s);
171 dprintf("rgb_matrix_config.hsv.v = %d\n", rgb_matrix_config.hsv.v);
172 dprintf("rgb_matrix_config.speed = %d\n", rgb_matrix_config.speed);
173 dprintf("rgb_matrix_config.flags = %d\n", rgb_matrix_config.flags);
174}
175
176__attribute__((weak)) uint8_t rgb_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i) { return 0; }
177
178uint8_t rgb_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i) {
179 uint8_t led_count = rgb_matrix_map_row_column_to_led_kb(row, column, led_i);
180 uint8_t led_index = g_led_config.matrix_co[row][column];
181 if (led_index != NO_LED) {
182 led_i[led_count] = led_index;
183 led_count++;
184 }
185 return led_count;
186}
187
188void rgb_matrix_update_pwm_buffers(void) { rgb_matrix_driver.flush(); }
189
190void rgb_matrix_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
191#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
192 if (!is_keyboard_left() && index >= k_rgb_matrix_split[0])
193 rgb_matrix_driver.set_color(index - k_rgb_matrix_split[0], red, green, blue);
194 else if (is_keyboard_left() && index < k_rgb_matrix_split[0])
195#endif
196 rgb_matrix_driver.set_color(index, red, green, blue);
197}
198
199void rgb_matrix_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
200#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
201 for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) rgb_matrix_set_color(i, red, green, blue);
202#else
203 rgb_matrix_driver.set_color_all(red, green, blue);
204#endif
205}
206
207void process_rgb_matrix(uint8_t row, uint8_t col, bool pressed) {
208#ifndef RGB_MATRIX_SPLIT
209 if (!is_keyboard_master()) return;
210#endif
211#if RGB_DISABLE_TIMEOUT > 0
212 rgb_anykey_timer = 0;
213#endif // RGB_DISABLE_TIMEOUT > 0
214
215#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
216 uint8_t led[LED_HITS_TO_REMEMBER];
217 uint8_t led_count = 0;
218
219# if defined(RGB_MATRIX_KEYRELEASES)
220 if (!pressed)
221# elif defined(RGB_MATRIX_KEYPRESSES)
222 if (pressed)
223# endif // defined(RGB_MATRIX_KEYRELEASES)
224 {
225 led_count = rgb_matrix_map_row_column_to_led(row, col, led);
226 }
227
228 if (last_hit_buffer.count + led_count > LED_HITS_TO_REMEMBER) {
229 memcpy(&last_hit_buffer.x[0], &last_hit_buffer.x[led_count], LED_HITS_TO_REMEMBER - led_count);
230 memcpy(&last_hit_buffer.y[0], &last_hit_buffer.y[led_count], LED_HITS_TO_REMEMBER - led_count);
231 memcpy(&last_hit_buffer.tick[0], &last_hit_buffer.tick[led_count], (LED_HITS_TO_REMEMBER - led_count) * 2); // 16 bit
232 memcpy(&last_hit_buffer.index[0], &last_hit_buffer.index[led_count], LED_HITS_TO_REMEMBER - led_count);
233 last_hit_buffer.count = LED_HITS_TO_REMEMBER - led_count;
234 }
235
236 for (uint8_t i = 0; i < led_count; i++) {
237 uint8_t index = last_hit_buffer.count;
238 last_hit_buffer.x[index] = g_led_config.point[led[i]].x;
239 last_hit_buffer.y[index] = g_led_config.point[led[i]].y;
240 last_hit_buffer.index[index] = led[i];
241 last_hit_buffer.tick[index] = 0;
242 last_hit_buffer.count++;
243 }
244#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
245
246#if defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) && defined(ENABLE_RGB_MATRIX_TYPING_HEATMAP)
247 if (rgb_matrix_config.mode == RGB_MATRIX_TYPING_HEATMAP) {
248 process_rgb_matrix_typing_heatmap(row, col);
249 }
250#endif // defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) && defined(ENABLE_RGB_MATRIX_TYPING_HEATMAP)
251}
252
253void rgb_matrix_test(void) {
254 // Mask out bits 4 and 5
255 // Increase the factor to make the test animation slower (and reduce to make it faster)
256 uint8_t factor = 10;
257 switch ((g_rgb_timer & (0b11 << factor)) >> factor) {
258 case 0: {
259 rgb_matrix_set_color_all(20, 0, 0);
260 break;
261 }
262 case 1: {
263 rgb_matrix_set_color_all(0, 20, 0);
264 break;
265 }
266 case 2: {
267 rgb_matrix_set_color_all(0, 0, 20);
268 break;
269 }
270 case 3: {
271 rgb_matrix_set_color_all(20, 20, 20);
272 break;
273 }
274 }
275}
276
277static bool rgb_matrix_none(effect_params_t *params) {
278 if (!params->init) {
279 return false;
280 }
281
282 rgb_matrix_set_color_all(0, 0, 0);
283 return false;
284}
285
286static void rgb_task_timers(void) {
287#if defined(RGB_MATRIX_KEYREACTIVE_ENABLED) || RGB_DISABLE_TIMEOUT > 0
288 uint32_t deltaTime = sync_timer_elapsed32(rgb_timer_buffer);
289#endif // defined(RGB_MATRIX_KEYREACTIVE_ENABLED) || RGB_DISABLE_TIMEOUT > 0
290 rgb_timer_buffer = sync_timer_read32();
291
292 // Update double buffer timers
293#if RGB_DISABLE_TIMEOUT > 0
294 if (rgb_anykey_timer < UINT32_MAX) {
295 if (UINT32_MAX - deltaTime < rgb_anykey_timer) {
296 rgb_anykey_timer = UINT32_MAX;
297 } else {
298 rgb_anykey_timer += deltaTime;
299 }
300 }
301#endif // RGB_DISABLE_TIMEOUT > 0
302
303 // Update double buffer last hit timers
304#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
305 uint8_t count = last_hit_buffer.count;
306 for (uint8_t i = 0; i < count; ++i) {
307 if (UINT16_MAX - deltaTime < last_hit_buffer.tick[i]) {
308 last_hit_buffer.count--;
309 continue;
310 }
311 last_hit_buffer.tick[i] += deltaTime;
312 }
313#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
314}
315
316static void rgb_task_sync(void) {
317 // next task
318 if (rgb_update_eeprom) eeconfig_update_rgb_matrix();
319 rgb_update_eeprom = false;
320 if (sync_timer_elapsed32(g_rgb_timer) >= RGB_MATRIX_LED_FLUSH_LIMIT) rgb_task_state = STARTING;
321}
322
323static void rgb_task_start(void) {
324 // reset iter
325 rgb_effect_params.iter = 0;
326
327 // update double buffers
328 g_rgb_timer = rgb_timer_buffer;
329#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
330 g_last_hit_tracker = last_hit_buffer;
331#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
332
333 // next task
334 rgb_task_state = RENDERING;
335}
336
337static void rgb_task_render(uint8_t effect) {
338 bool rendering = false;
339 rgb_effect_params.init = (effect != rgb_last_effect) || (rgb_matrix_config.enable != rgb_last_enable);
340 if (rgb_effect_params.flags != rgb_matrix_config.flags) {
341 rgb_effect_params.flags = rgb_matrix_config.flags;
342 rgb_matrix_set_color_all(0, 0, 0);
343 }
344
345 // each effect can opt to do calculations
346 // and/or request PWM buffer updates.
347 switch (effect) {
348 case RGB_MATRIX_NONE:
349 rendering = rgb_matrix_none(&rgb_effect_params);
350 break;
351
352// ---------------------------------------------
353// -----Begin rgb effect switch case macros-----
354#define RGB_MATRIX_EFFECT(name, ...) \
355 case RGB_MATRIX_##name: \
356 rendering = name(&rgb_effect_params); \
357 break;
358#include "rgb_matrix_effects.inc"
359#undef RGB_MATRIX_EFFECT
360
361#if defined(RGB_MATRIX_CUSTOM_KB) || defined(RGB_MATRIX_CUSTOM_USER)
362# define RGB_MATRIX_EFFECT(name, ...) \
363 case RGB_MATRIX_CUSTOM_##name: \
364 rendering = name(&rgb_effect_params); \
365 break;
366# ifdef RGB_MATRIX_CUSTOM_KB
367# include "rgb_matrix_kb.inc"
368# endif
369# ifdef RGB_MATRIX_CUSTOM_USER
370# include "rgb_matrix_user.inc"
371# endif
372# undef RGB_MATRIX_EFFECT
373#endif
374 // -----End rgb effect switch case macros-------
375 // ---------------------------------------------
376
377 // Factory default magic value
378 case UINT8_MAX: {
379 rgb_matrix_test();
380 rgb_task_state = FLUSHING;
381 }
382 return;
383 }
384
385 rgb_effect_params.iter++;
386
387 // next task
388 if (!rendering) {
389 rgb_task_state = FLUSHING;
390 if (!rgb_effect_params.init && effect == RGB_MATRIX_NONE) {
391 // We only need to flush once if we are RGB_MATRIX_NONE
392 rgb_task_state = SYNCING;
393 }
394 }
395}
396
397static void rgb_task_flush(uint8_t effect) {
398 // update last trackers after the first full render so we can init over several frames
399 rgb_last_effect = effect;
400 rgb_last_enable = rgb_matrix_config.enable;
401
402 // update pwm buffers
403 rgb_matrix_update_pwm_buffers();
404
405 // next task
406 rgb_task_state = SYNCING;
407}
408
409void rgb_matrix_task(void) {
410 rgb_task_timers();
411
412 // Ideally we would also stop sending zeros to the LED driver PWM buffers
413 // while suspended and just do a software shutdown. This is a cheap hack for now.
414 bool suspend_backlight = suspend_state ||
415#if RGB_DISABLE_TIMEOUT > 0
416 (rgb_anykey_timer > (uint32_t)RGB_DISABLE_TIMEOUT) ||
417#endif // RGB_DISABLE_TIMEOUT > 0
418 false;
419
420 uint8_t effect = suspend_backlight || !rgb_matrix_config.enable ? 0 : rgb_matrix_config.mode;
421
422 switch (rgb_task_state) {
423 case STARTING:
424 rgb_task_start();
425 break;
426 case RENDERING:
427 rgb_task_render(effect);
428 if (effect) {
429 rgb_matrix_indicators();
430 rgb_matrix_indicators_advanced(&rgb_effect_params);
431 }
432 break;
433 case FLUSHING:
434 rgb_task_flush(effect);
435 break;
436 case SYNCING:
437 rgb_task_sync();
438 break;
439 }
440}
441
442void rgb_matrix_indicators(void) {
443 rgb_matrix_indicators_kb();
444 rgb_matrix_indicators_user();
445}
446
447__attribute__((weak)) void rgb_matrix_indicators_kb(void) {}
448
449__attribute__((weak)) void rgb_matrix_indicators_user(void) {}
450
451void rgb_matrix_indicators_advanced(effect_params_t *params) {
452 /* special handling is needed for "params->iter", since it's already been incremented.
453 * Could move the invocations to rgb_task_render, but then it's missing a few checks
454 * and not sure which would be better. Otherwise, this should be called from
455 * rgb_task_render, right before the iter++ line.
456 */
457#if defined(RGB_MATRIX_LED_PROCESS_LIMIT) && RGB_MATRIX_LED_PROCESS_LIMIT > 0 && RGB_MATRIX_LED_PROCESS_LIMIT < DRIVER_LED_TOTAL
458 uint8_t min = RGB_MATRIX_LED_PROCESS_LIMIT * (params->iter - 1);
459 uint8_t max = min + RGB_MATRIX_LED_PROCESS_LIMIT;
460 if (max > DRIVER_LED_TOTAL) max = DRIVER_LED_TOTAL;
461#else
462 uint8_t min = 0;
463 uint8_t max = DRIVER_LED_TOTAL;
464#endif
465 rgb_matrix_indicators_advanced_kb(min, max);
466 rgb_matrix_indicators_advanced_user(min, max);
467}
468
469__attribute__((weak)) void rgb_matrix_indicators_advanced_kb(uint8_t led_min, uint8_t led_max) {}
470
471__attribute__((weak)) void rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {}
472
473void rgb_matrix_init(void) {
474 rgb_matrix_driver.init();
475
476#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
477 g_last_hit_tracker.count = 0;
478 for (uint8_t i = 0; i < LED_HITS_TO_REMEMBER; ++i) {
479 g_last_hit_tracker.tick[i] = UINT16_MAX;
480 }
481
482 last_hit_buffer.count = 0;
483 for (uint8_t i = 0; i < LED_HITS_TO_REMEMBER; ++i) {
484 last_hit_buffer.tick[i] = UINT16_MAX;
485 }
486#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
487
488 if (!eeconfig_is_enabled()) {
489 dprintf("rgb_matrix_init_drivers eeconfig is not enabled.\n");
490 eeconfig_init();
491 eeconfig_update_rgb_matrix_default();
492 }
493
494 eeconfig_read_rgb_matrix();
495 if (!rgb_matrix_config.mode) {
496 dprintf("rgb_matrix_init_drivers rgb_matrix_config.mode = 0. Write default values to EEPROM.\n");
497 eeconfig_update_rgb_matrix_default();
498 }
499 eeconfig_debug_rgb_matrix(); // display current eeprom values
500}
501
502void rgb_matrix_set_suspend_state(bool state) {
503#ifdef RGB_DISABLE_WHEN_USB_SUSPENDED
504 if (state) {
505 rgb_matrix_set_color_all(0, 0, 0); // turn off all LEDs when suspending
506 }
507 suspend_state = state;
508#endif
509}
510
511bool rgb_matrix_get_suspend_state(void) { return suspend_state; }
512
513void rgb_matrix_toggle_eeprom_helper(bool write_to_eeprom) {
514 rgb_matrix_config.enable ^= 1;
515 rgb_task_state = STARTING;
516 rgb_eeconfig_update(write_to_eeprom);
517 dprintf("rgb matrix toggle [%s]: rgb_matrix_config.enable = %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", rgb_matrix_config.enable);
518}
519void rgb_matrix_toggle_noeeprom(void) { rgb_matrix_toggle_eeprom_helper(false); }
520void rgb_matrix_toggle(void) { rgb_matrix_toggle_eeprom_helper(true); }
521
522void rgb_matrix_enable(void) {
523 rgb_matrix_enable_noeeprom();
524 rgb_eeconfig_update(true);
525}
526
527void rgb_matrix_enable_noeeprom(void) {
528 if (!rgb_matrix_config.enable) rgb_task_state = STARTING;
529 rgb_matrix_config.enable = 1;
530}
531
532void rgb_matrix_disable(void) {
533 rgb_matrix_disable_noeeprom();
534 rgb_eeconfig_update(true);
535}
536
537void rgb_matrix_disable_noeeprom(void) {
538 if (rgb_matrix_config.enable) rgb_task_state = STARTING;
539 rgb_matrix_config.enable = 0;
540}
541
542uint8_t rgb_matrix_is_enabled(void) { return rgb_matrix_config.enable; }
543
544void rgb_matrix_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {
545 if (!rgb_matrix_config.enable) {
546 return;
547 }
548 if (mode < 1) {
549 rgb_matrix_config.mode = 1;
550 } else if (mode >= RGB_MATRIX_EFFECT_MAX) {
551 rgb_matrix_config.mode = RGB_MATRIX_EFFECT_MAX - 1;
552 } else {
553 rgb_matrix_config.mode = mode;
554 }
555 rgb_task_state = STARTING;
556 rgb_eeconfig_update(write_to_eeprom);
557 dprintf("rgb matrix mode [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", rgb_matrix_config.mode);
558}
559void rgb_matrix_mode_noeeprom(uint8_t mode) { rgb_matrix_mode_eeprom_helper(mode, false); }
560void rgb_matrix_mode(uint8_t mode) { rgb_matrix_mode_eeprom_helper(mode, true); }
561
562uint8_t rgb_matrix_get_mode(void) { return rgb_matrix_config.mode; }
563
564void rgb_matrix_step_helper(bool write_to_eeprom) {
565 uint8_t mode = rgb_matrix_config.mode + 1;
566 rgb_matrix_mode_eeprom_helper((mode < RGB_MATRIX_EFFECT_MAX) ? mode : 1, write_to_eeprom);
567}
568void rgb_matrix_step_noeeprom(void) { rgb_matrix_step_helper(false); }
569void rgb_matrix_step(void) { rgb_matrix_step_helper(true); }
570
571void rgb_matrix_step_reverse_helper(bool write_to_eeprom) {
572 uint8_t mode = rgb_matrix_config.mode - 1;
573 rgb_matrix_mode_eeprom_helper((mode < 1) ? RGB_MATRIX_EFFECT_MAX - 1 : mode, write_to_eeprom);
574}
575void rgb_matrix_step_reverse_noeeprom(void) { rgb_matrix_step_reverse_helper(false); }
576void rgb_matrix_step_reverse(void) { rgb_matrix_step_reverse_helper(true); }
577
578void rgb_matrix_sethsv_eeprom_helper(uint16_t hue, uint8_t sat, uint8_t val, bool write_to_eeprom) {
579 if (!rgb_matrix_config.enable) {
580 return;
581 }
582 rgb_matrix_config.hsv.h = hue;
583 rgb_matrix_config.hsv.s = sat;
584 rgb_matrix_config.hsv.v = (val > RGB_MATRIX_MAXIMUM_BRIGHTNESS) ? RGB_MATRIX_MAXIMUM_BRIGHTNESS : val;
585 rgb_eeconfig_update(write_to_eeprom);
586 dprintf("rgb matrix set hsv [%s]: %u,%u,%u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", rgb_matrix_config.hsv.h, rgb_matrix_config.hsv.s, rgb_matrix_config.hsv.v);
587}
588void rgb_matrix_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val) { rgb_matrix_sethsv_eeprom_helper(hue, sat, val, false); }
589void rgb_matrix_sethsv(uint16_t hue, uint8_t sat, uint8_t val) { rgb_matrix_sethsv_eeprom_helper(hue, sat, val, true); }
590
591HSV rgb_matrix_get_hsv(void) { return rgb_matrix_config.hsv; }
592uint8_t rgb_matrix_get_hue(void) { return rgb_matrix_config.hsv.h; }
593uint8_t rgb_matrix_get_sat(void) { return rgb_matrix_config.hsv.s; }
594uint8_t rgb_matrix_get_val(void) { return rgb_matrix_config.hsv.v; }
595
596void rgb_matrix_increase_hue_helper(bool write_to_eeprom) { rgb_matrix_sethsv_eeprom_helper(rgb_matrix_config.hsv.h + RGB_MATRIX_HUE_STEP, rgb_matrix_config.hsv.s, rgb_matrix_config.hsv.v, write_to_eeprom); }
597void rgb_matrix_increase_hue_noeeprom(void) { rgb_matrix_increase_hue_helper(false); }
598void rgb_matrix_increase_hue(void) { rgb_matrix_increase_hue_helper(true); }
599
600void rgb_matrix_decrease_hue_helper(bool write_to_eeprom) { rgb_matrix_sethsv_eeprom_helper(rgb_matrix_config.hsv.h - RGB_MATRIX_HUE_STEP, rgb_matrix_config.hsv.s, rgb_matrix_config.hsv.v, write_to_eeprom); }
601void rgb_matrix_decrease_hue_noeeprom(void) { rgb_matrix_decrease_hue_helper(false); }
602void rgb_matrix_decrease_hue(void) { rgb_matrix_decrease_hue_helper(true); }
603
604void rgb_matrix_increase_sat_helper(bool write_to_eeprom) { rgb_matrix_sethsv_eeprom_helper(rgb_matrix_config.hsv.h, qadd8(rgb_matrix_config.hsv.s, RGB_MATRIX_SAT_STEP), rgb_matrix_config.hsv.v, write_to_eeprom); }
605void rgb_matrix_increase_sat_noeeprom(void) { rgb_matrix_increase_sat_helper(false); }
606void rgb_matrix_increase_sat(void) { rgb_matrix_increase_sat_helper(true); }
607
608void rgb_matrix_decrease_sat_helper(bool write_to_eeprom) { rgb_matrix_sethsv_eeprom_helper(rgb_matrix_config.hsv.h, qsub8(rgb_matrix_config.hsv.s, RGB_MATRIX_SAT_STEP), rgb_matrix_config.hsv.v, write_to_eeprom); }
609void rgb_matrix_decrease_sat_noeeprom(void) { rgb_matrix_decrease_sat_helper(false); }
610void rgb_matrix_decrease_sat(void) { rgb_matrix_decrease_sat_helper(true); }
611
612void rgb_matrix_increase_val_helper(bool write_to_eeprom) { rgb_matrix_sethsv_eeprom_helper(rgb_matrix_config.hsv.h, rgb_matrix_config.hsv.s, qadd8(rgb_matrix_config.hsv.v, RGB_MATRIX_VAL_STEP), write_to_eeprom); }
613void rgb_matrix_increase_val_noeeprom(void) { rgb_matrix_increase_val_helper(false); }
614void rgb_matrix_increase_val(void) { rgb_matrix_increase_val_helper(true); }
615
616void rgb_matrix_decrease_val_helper(bool write_to_eeprom) { rgb_matrix_sethsv_eeprom_helper(rgb_matrix_config.hsv.h, rgb_matrix_config.hsv.s, qsub8(rgb_matrix_config.hsv.v, RGB_MATRIX_VAL_STEP), write_to_eeprom); }
617void rgb_matrix_decrease_val_noeeprom(void) { rgb_matrix_decrease_val_helper(false); }
618void rgb_matrix_decrease_val(void) { rgb_matrix_decrease_val_helper(true); }
619
620void rgb_matrix_set_speed_eeprom_helper(uint8_t speed, bool write_to_eeprom) {
621 rgb_matrix_config.speed = speed;
622 rgb_eeconfig_update(write_to_eeprom);
623 dprintf("rgb matrix set speed [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", rgb_matrix_config.speed);
624}
625void rgb_matrix_set_speed_noeeprom(uint8_t speed) { rgb_matrix_set_speed_eeprom_helper(speed, false); }
626void rgb_matrix_set_speed(uint8_t speed) { rgb_matrix_set_speed_eeprom_helper(speed, true); }
627
628uint8_t rgb_matrix_get_speed(void) { return rgb_matrix_config.speed; }
629
630void rgb_matrix_increase_speed_helper(bool write_to_eeprom) { rgb_matrix_set_speed_eeprom_helper(qadd8(rgb_matrix_config.speed, RGB_MATRIX_SPD_STEP), write_to_eeprom); }
631void rgb_matrix_increase_speed_noeeprom(void) { rgb_matrix_increase_speed_helper(false); }
632void rgb_matrix_increase_speed(void) { rgb_matrix_increase_speed_helper(true); }
633
634void rgb_matrix_decrease_speed_helper(bool write_to_eeprom) { rgb_matrix_set_speed_eeprom_helper(qsub8(rgb_matrix_config.speed, RGB_MATRIX_SPD_STEP), write_to_eeprom); }
635void rgb_matrix_decrease_speed_noeeprom(void) { rgb_matrix_decrease_speed_helper(false); }
636void rgb_matrix_decrease_speed(void) { rgb_matrix_decrease_speed_helper(true); }
637
638led_flags_t rgb_matrix_get_flags(void) { return rgb_matrix_config.flags; }
639
640void rgb_matrix_set_flags(led_flags_t flags) { rgb_matrix_config.flags = flags; }
diff --git a/quantum/rgb_matrix/rgb_matrix.h b/quantum/rgb_matrix/rgb_matrix.h
new file mode 100644
index 000000000..f53e011c1
--- /dev/null
+++ b/quantum/rgb_matrix/rgb_matrix.h
@@ -0,0 +1,228 @@
1/* Copyright 2017 Jason Williams
2 * Copyright 2017 Jack Humbert
3 * Copyright 2018 Yiancar
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#pragma once
20
21#include <stdint.h>
22#include <stdbool.h>
23#include "rgb_matrix_types.h"
24#include "color.h"
25#include "quantum.h"
26#include "rgb_matrix_legacy_enables.h"
27
28#ifdef IS31FL3731
29# include "is31fl3731.h"
30#elif defined(IS31FL3733)
31# include "is31fl3733.h"
32#elif defined(IS31FL3737)
33# include "is31fl3737.h"
34#elif defined(IS31FL3741)
35# include "is31fl3741.h"
36#elif defined(AW20216)
37# include "aw20216.h"
38#elif defined(WS2812)
39# include "ws2812.h"
40#endif
41
42#ifndef RGB_MATRIX_LED_FLUSH_LIMIT
43# define RGB_MATRIX_LED_FLUSH_LIMIT 16
44#endif
45
46#ifndef RGB_MATRIX_LED_PROCESS_LIMIT
47# define RGB_MATRIX_LED_PROCESS_LIMIT (DRIVER_LED_TOTAL + 4) / 5
48#endif
49
50#if defined(RGB_MATRIX_LED_PROCESS_LIMIT) && RGB_MATRIX_LED_PROCESS_LIMIT > 0 && RGB_MATRIX_LED_PROCESS_LIMIT < DRIVER_LED_TOTAL
51# define RGB_MATRIX_USE_LIMITS(min, max) \
52 uint8_t min = RGB_MATRIX_LED_PROCESS_LIMIT * params->iter; \
53 uint8_t max = min + RGB_MATRIX_LED_PROCESS_LIMIT; \
54 if (max > DRIVER_LED_TOTAL) max = DRIVER_LED_TOTAL;
55#else
56# define RGB_MATRIX_USE_LIMITS(min, max) \
57 uint8_t min = 0; \
58 uint8_t max = DRIVER_LED_TOTAL;
59#endif
60
61#define RGB_MATRIX_INDICATOR_SET_COLOR(i, r, g, b) \
62 if (i >= led_min && i <= led_max) { \
63 rgb_matrix_set_color(i, r, g, b); \
64 }
65
66#define RGB_MATRIX_TEST_LED_FLAGS() \
67 if (!HAS_ANY_FLAGS(g_led_config.flags[i], params->flags)) continue
68
69enum rgb_matrix_effects {
70 RGB_MATRIX_NONE = 0,
71
72// --------------------------------------
73// -----Begin rgb effect enum macros-----
74#define RGB_MATRIX_EFFECT(name, ...) RGB_MATRIX_##name,
75#include "rgb_matrix_effects.inc"
76#undef RGB_MATRIX_EFFECT
77
78#if defined(RGB_MATRIX_CUSTOM_KB) || defined(RGB_MATRIX_CUSTOM_USER)
79# define RGB_MATRIX_EFFECT(name, ...) RGB_MATRIX_CUSTOM_##name,
80# ifdef RGB_MATRIX_CUSTOM_KB
81# include "rgb_matrix_kb.inc"
82# endif
83# ifdef RGB_MATRIX_CUSTOM_USER
84# include "rgb_matrix_user.inc"
85# endif
86# undef RGB_MATRIX_EFFECT
87#endif
88 // --------------------------------------
89 // -----End rgb effect enum macros-------
90
91 RGB_MATRIX_EFFECT_MAX
92};
93
94void eeconfig_update_rgb_matrix_default(void);
95void eeconfig_update_rgb_matrix(void);
96
97uint8_t rgb_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i);
98uint8_t rgb_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i);
99
100void rgb_matrix_set_color(int index, uint8_t red, uint8_t green, uint8_t blue);
101void rgb_matrix_set_color_all(uint8_t red, uint8_t green, uint8_t blue);
102
103void process_rgb_matrix(uint8_t row, uint8_t col, bool pressed);
104
105void rgb_matrix_task(void);
106
107// This runs after another backlight effect and replaces
108// colors already set
109void rgb_matrix_indicators(void);
110void rgb_matrix_indicators_kb(void);
111void rgb_matrix_indicators_user(void);
112
113void rgb_matrix_indicators_advanced(effect_params_t *params);
114void rgb_matrix_indicators_advanced_kb(uint8_t led_min, uint8_t led_max);
115void rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max);
116
117void rgb_matrix_init(void);
118
119void rgb_matrix_set_suspend_state(bool state);
120bool rgb_matrix_get_suspend_state(void);
121void rgb_matrix_toggle(void);
122void rgb_matrix_toggle_noeeprom(void);
123void rgb_matrix_enable(void);
124void rgb_matrix_enable_noeeprom(void);
125void rgb_matrix_disable(void);
126void rgb_matrix_disable_noeeprom(void);
127uint8_t rgb_matrix_is_enabled(void);
128void rgb_matrix_mode(uint8_t mode);
129void rgb_matrix_mode_noeeprom(uint8_t mode);
130uint8_t rgb_matrix_get_mode(void);
131void rgb_matrix_step(void);
132void rgb_matrix_step_noeeprom(void);
133void rgb_matrix_step_reverse(void);
134void rgb_matrix_step_reverse_noeeprom(void);
135void rgb_matrix_sethsv(uint16_t hue, uint8_t sat, uint8_t val);
136void rgb_matrix_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val);
137HSV rgb_matrix_get_hsv(void);
138uint8_t rgb_matrix_get_hue(void);
139uint8_t rgb_matrix_get_sat(void);
140uint8_t rgb_matrix_get_val(void);
141void rgb_matrix_increase_hue(void);
142void rgb_matrix_increase_hue_noeeprom(void);
143void rgb_matrix_decrease_hue(void);
144void rgb_matrix_decrease_hue_noeeprom(void);
145void rgb_matrix_increase_sat(void);
146void rgb_matrix_increase_sat_noeeprom(void);
147void rgb_matrix_decrease_sat(void);
148void rgb_matrix_decrease_sat_noeeprom(void);
149void rgb_matrix_increase_val(void);
150void rgb_matrix_increase_val_noeeprom(void);
151void rgb_matrix_decrease_val(void);
152void rgb_matrix_decrease_val_noeeprom(void);
153void rgb_matrix_set_speed(uint8_t speed);
154void rgb_matrix_set_speed_noeeprom(uint8_t speed);
155uint8_t rgb_matrix_get_speed(void);
156void rgb_matrix_increase_speed(void);
157void rgb_matrix_increase_speed_noeeprom(void);
158void rgb_matrix_decrease_speed(void);
159void rgb_matrix_decrease_speed_noeeprom(void);
160led_flags_t rgb_matrix_get_flags(void);
161void rgb_matrix_set_flags(led_flags_t flags);
162
163#ifndef RGBLIGHT_ENABLE
164# define eeconfig_update_rgblight_current eeconfig_update_rgb_matrix
165# define rgblight_toggle rgb_matrix_toggle
166# define rgblight_toggle_noeeprom rgb_matrix_toggle_noeeprom
167# define rgblight_enable rgb_matrix_enable
168# define rgblight_enable_noeeprom rgb_matrix_enable_noeeprom
169# define rgblight_disable rgb_matrix_disable
170# define rgblight_disable_noeeprom rgb_matrix_disable_noeeprom
171# define rgblight_is_enabled rgb_matrix_is_enabled
172# define rgblight_mode rgb_matrix_mode
173# define rgblight_mode_noeeprom rgb_matrix_mode_noeeprom
174# define rgblight_get_mode rgb_matrix_get_mode
175# define rgblight_get_hue rgb_matrix_get_hue
176# define rgblight_get_sat rgb_matrix_get_sat
177# define rgblight_get_val rgb_matrix_get_val
178# define rgblight_get_hsv rgb_matrix_get_hsv
179# define rgblight_step rgb_matrix_step
180# define rgblight_step_noeeprom rgb_matrix_step_noeeprom
181# define rgblight_step_reverse rgb_matrix_step_reverse
182# define rgblight_step_reverse_noeeprom rgb_matrix_step_reverse_noeeprom
183# define rgblight_sethsv rgb_matrix_sethsv
184# define rgblight_sethsv_noeeprom rgb_matrix_sethsv_noeeprom
185# define rgblight_increase_hue rgb_matrix_increase_hue
186# define rgblight_increase_hue_noeeprom rgb_matrix_increase_hue_noeeprom
187# define rgblight_decrease_hue rgb_matrix_decrease_hue
188# define rgblight_decrease_hue_noeeprom rgb_matrix_decrease_hue_noeeprom
189# define rgblight_increase_sat rgb_matrix_increase_sat
190# define rgblight_increase_sat_noeeprom rgb_matrix_increase_sat_noeeprom
191# define rgblight_decrease_sat rgb_matrix_decrease_sat
192# define rgblight_decrease_sat_noeeprom rgb_matrix_decrease_sat_noeeprom
193# define rgblight_increase_val rgb_matrix_increase_val
194# define rgblight_increase_val_noeeprom rgb_matrix_increase_val_noeeprom
195# define rgblight_decrease_val rgb_matrix_decrease_val
196# define rgblight_decrease_val_noeeprom rgb_matrix_decrease_val_noeeprom
197# define rgblight_set_speed rgb_matrix_set_speed
198# define rgblight_set_speed_noeeprom rgb_matrix_set_speed_noeeprom
199# define rgblight_get_speed rgb_matrix_get_speed
200# define rgblight_increase_speed rgb_matrix_increase_speed
201# define rgblight_increase_speed_noeeprom rgb_matrix_increase_speed_noeeprom
202# define rgblight_decrease_speed rgb_matrix_decrease_speed
203# define rgblight_decrease_speed_noeeprom rgb_matrix_decrease_speed_noeeprom
204#endif
205
206typedef struct {
207 /* Perform any initialisation required for the other driver functions to work. */
208 void (*init)(void);
209 /* Set the colour of a single LED in the buffer. */
210 void (*set_color)(int index, uint8_t r, uint8_t g, uint8_t b);
211 /* Set the colour of all LEDS on the keyboard in the buffer. */
212 void (*set_color_all)(uint8_t r, uint8_t g, uint8_t b);
213 /* Flush any buffered changes to the hardware. */
214 void (*flush)(void);
215} rgb_matrix_driver_t;
216
217extern const rgb_matrix_driver_t rgb_matrix_driver;
218
219extern rgb_config_t rgb_matrix_config;
220
221extern uint32_t g_rgb_timer;
222extern led_config_t g_led_config;
223#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
224extern last_hit_t g_last_hit_tracker;
225#endif
226#ifdef RGB_MATRIX_FRAMEBUFFER_EFFECTS
227extern uint8_t g_rgb_frame_buffer[MATRIX_ROWS][MATRIX_COLS];
228#endif
diff --git a/quantum/rgb_matrix/rgb_matrix_drivers.c b/quantum/rgb_matrix/rgb_matrix_drivers.c
new file mode 100644
index 000000000..bfaedaa4a
--- /dev/null
+++ b/quantum/rgb_matrix/rgb_matrix_drivers.c
@@ -0,0 +1,247 @@
1/* Copyright 2018 James Laird-Wah
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "rgb_matrix.h"
18
19/* Each driver needs to define the struct
20 * const rgb_matrix_driver_t rgb_matrix_driver;
21 * All members must be provided.
22 * Keyboard custom drivers can define this in their own files, it should only
23 * be here if shared between boards.
24 */
25
26#if defined(IS31FL3731) || defined(IS31FL3733) || defined(IS31FL3737) || defined(IS31FL3741)
27
28# include "i2c_master.h"
29
30static void init(void) {
31 i2c_init();
32# ifdef IS31FL3731
33 IS31FL3731_init(DRIVER_ADDR_1);
34# ifdef DRIVER_ADDR_2
35 IS31FL3731_init(DRIVER_ADDR_2);
36# endif
37# ifdef DRIVER_ADDR_3
38 IS31FL3731_init(DRIVER_ADDR_3);
39# endif
40# ifdef DRIVER_ADDR_4
41 IS31FL3731_init(DRIVER_ADDR_4);
42# endif
43# elif defined(IS31FL3733)
44# ifndef DRIVER_SYNC_1
45# define DRIVER_SYNC_1 0
46# endif
47 IS31FL3733_init(DRIVER_ADDR_1, DRIVER_SYNC_1);
48# if defined DRIVER_ADDR_2 && (DRIVER_ADDR_1 != DRIVER_ADDR_2)
49# ifndef DRIVER_SYNC_2
50# define DRIVER_SYNC_2 0
51# endif
52 IS31FL3733_init(DRIVER_ADDR_2, DRIVER_SYNC_2);
53# endif
54# ifdef DRIVER_ADDR_3
55# ifndef DRIVER_SYNC_3
56# define DRIVER_SYNC_3 0
57# endif
58 IS31FL3733_init(DRIVER_ADDR_3, DRIVER_SYNC_3);
59# endif
60# ifdef DRIVER_ADDR_4
61# ifndef DRIVER_SYNC_4
62# define DRIVER_SYNC_4 0
63# endif
64 IS31FL3733_init(DRIVER_ADDR_4, DRIVER_SYNC_4);
65# endif
66# elif defined(IS31FL3737)
67 IS31FL3737_init(DRIVER_ADDR_1);
68# if defined(DRIVER_ADDR_2) && (DRIVER_ADDR_2 != DRIVER_ADDR_1) // provides backward compatibility
69 IS31FL3737_init(DRIVER_ADDR_2);
70# endif
71# else
72 IS31FL3741_init(DRIVER_ADDR_1);
73# endif
74 for (int index = 0; index < DRIVER_LED_TOTAL; index++) {
75 bool enabled = true;
76 // This only caches it for later
77# ifdef IS31FL3731
78 IS31FL3731_set_led_control_register(index, enabled, enabled, enabled);
79# elif defined(IS31FL3733)
80 IS31FL3733_set_led_control_register(index, enabled, enabled, enabled);
81# elif defined(IS31FL3737)
82 IS31FL3737_set_led_control_register(index, enabled, enabled, enabled);
83# else
84 IS31FL3741_set_led_control_register(index, enabled, enabled, enabled);
85# endif
86 }
87 // This actually updates the LED drivers
88# ifdef IS31FL3731
89 IS31FL3731_update_led_control_registers(DRIVER_ADDR_1, 0);
90# ifdef DRIVER_ADDR_2
91 IS31FL3731_update_led_control_registers(DRIVER_ADDR_2, 1);
92# endif
93# ifdef DRIVER_ADDR_3
94 IS31FL3731_update_led_control_registers(DRIVER_ADDR_3, 2);
95# endif
96# ifdef DRIVER_ADDR_4
97 IS31FL3731_update_led_control_registers(DRIVER_ADDR_4, 3);
98# endif
99# elif defined(IS31FL3733)
100 IS31FL3733_update_led_control_registers(DRIVER_ADDR_1, 0);
101# ifdef DRIVER_ADDR_2
102 IS31FL3733_update_led_control_registers(DRIVER_ADDR_2, 1);
103# endif
104# ifdef DRIVER_ADDR_3
105 IS31FL3733_update_led_control_registers(DRIVER_ADDR_3, 2);
106# endif
107# ifdef DRIVER_ADDR_4
108 IS31FL3733_update_led_control_registers(DRIVER_ADDR_4, 3);
109# endif
110# elif defined(IS31FL3737)
111 IS31FL3737_update_led_control_registers(DRIVER_ADDR_1, 0);
112# if defined(DRIVER_ADDR_2) && (DRIVER_ADDR_2 != DRIVER_ADDR_1) // provides backward compatibility
113 IS31FL3737_update_led_control_registers(DRIVER_ADDR_2, 1);
114# endif
115# else
116 IS31FL3741_update_led_control_registers(DRIVER_ADDR_1, 0);
117# endif
118}
119
120# ifdef IS31FL3731
121static void flush(void) {
122 IS31FL3731_update_pwm_buffers(DRIVER_ADDR_1, 0);
123# ifdef DRIVER_ADDR_2
124 IS31FL3731_update_pwm_buffers(DRIVER_ADDR_2, 1);
125# endif
126# ifdef DRIVER_ADDR_3
127 IS31FL3731_update_pwm_buffers(DRIVER_ADDR_3, 2);
128# endif
129# ifdef DRIVER_ADDR_4
130 IS31FL3731_update_pwm_buffers(DRIVER_ADDR_4, 3);
131# endif
132}
133
134const rgb_matrix_driver_t rgb_matrix_driver = {
135 .init = init,
136 .flush = flush,
137 .set_color = IS31FL3731_set_color,
138 .set_color_all = IS31FL3731_set_color_all,
139};
140# elif defined(IS31FL3733)
141static void flush(void) {
142 IS31FL3733_update_pwm_buffers(DRIVER_ADDR_1, 0);
143# ifdef DRIVER_ADDR_2
144 IS31FL3733_update_pwm_buffers(DRIVER_ADDR_2, 1);
145# endif
146# ifdef DRIVER_ADDR_3
147 IS31FL3733_update_pwm_buffers(DRIVER_ADDR_3, 2);
148# endif
149# ifdef DRIVER_ADDR_4
150 IS31FL3733_update_pwm_buffers(DRIVER_ADDR_4, 3);
151# endif
152}
153
154const rgb_matrix_driver_t rgb_matrix_driver = {
155 .init = init,
156 .flush = flush,
157 .set_color = IS31FL3733_set_color,
158 .set_color_all = IS31FL3733_set_color_all,
159};
160# elif defined(IS31FL3737)
161static void flush(void) {
162 IS31FL3737_update_pwm_buffers(DRIVER_ADDR_1, 0);
163# if defined(DRIVER_ADDR_2) && (DRIVER_ADDR_2 != DRIVER_ADDR_1) // provides backward compatibility
164 IS31FL3737_update_pwm_buffers(DRIVER_ADDR_2, 1);
165# endif
166}
167
168const rgb_matrix_driver_t rgb_matrix_driver = {
169 .init = init,
170 .flush = flush,
171 .set_color = IS31FL3737_set_color,
172 .set_color_all = IS31FL3737_set_color_all,
173};
174# else
175static void flush(void) { IS31FL3741_update_pwm_buffers(DRIVER_ADDR_1, DRIVER_ADDR_2); }
176
177const rgb_matrix_driver_t rgb_matrix_driver = {
178 .init = init,
179 .flush = flush,
180 .set_color = IS31FL3741_set_color,
181 .set_color_all = IS31FL3741_set_color_all,
182};
183# endif
184
185#elif defined(AW20216)
186# include "spi_master.h"
187static void init(void) {
188 spi_init();
189 AW20216_init(DRIVER_1_CS, DRIVER_1_EN);
190# ifdef DRIVER_2_CS
191 AW20216_init(DRIVER_2_CS, DRIVER_2_EN);
192# endif
193}
194
195static void flush(void) {
196 AW20216_update_pwm_buffers(DRIVER_1_CS, 0);
197# ifdef DRIVER_2_CS
198 AW20216_update_pwm_buffers(DRIVER_2_CS, 1);
199# endif
200}
201
202const rgb_matrix_driver_t rgb_matrix_driver = {
203 .init = init,
204 .flush = flush,
205 .set_color = AW20216_set_color,
206 .set_color_all = AW20216_set_color_all,
207};
208
209#elif defined(WS2812)
210# if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_CUSTOM_DRIVER)
211# pragma message "Cannot use RGBLIGHT and RGB Matrix using WS2812 at the same time."
212# pragma message "You need to use a custom driver, or re-implement the WS2812 driver to use a different configuration."
213# endif
214
215// LED color buffer
216LED_TYPE rgb_matrix_ws2812_array[DRIVER_LED_TOTAL];
217
218static void init(void) {}
219
220static void flush(void) {
221 // Assumes use of RGB_DI_PIN
222 ws2812_setleds(rgb_matrix_ws2812_array, DRIVER_LED_TOTAL);
223}
224
225// Set an led in the buffer to a color
226static inline void setled(int i, uint8_t r, uint8_t g, uint8_t b) {
227 rgb_matrix_ws2812_array[i].r = r;
228 rgb_matrix_ws2812_array[i].g = g;
229 rgb_matrix_ws2812_array[i].b = b;
230# ifdef RGBW
231 convert_rgb_to_rgbw(&rgb_matrix_ws2812_array[i]);
232# endif
233}
234
235static void setled_all(uint8_t r, uint8_t g, uint8_t b) {
236 for (int i = 0; i < sizeof(rgb_matrix_ws2812_array) / sizeof(rgb_matrix_ws2812_array[0]); i++) {
237 setled(i, r, g, b);
238 }
239}
240
241const rgb_matrix_driver_t rgb_matrix_driver = {
242 .init = init,
243 .flush = flush,
244 .set_color = setled,
245 .set_color_all = setled_all,
246};
247#endif
diff --git a/quantum/rgb_matrix/rgb_matrix_legacy_enables.h b/quantum/rgb_matrix/rgb_matrix_legacy_enables.h
new file mode 100644
index 000000000..398858ebc
--- /dev/null
+++ b/quantum/rgb_matrix/rgb_matrix_legacy_enables.h
@@ -0,0 +1,153 @@
1/* Copyright 2021 QMK
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17// to-do: remove this
18
19#pragma once
20
21#ifndef DISABLE_RGB_MATRIX_ALPHAS_MODS
22# define ENABLE_RGB_MATRIX_ALPHAS_MODS
23#endif
24#ifndef DISABLE_RGB_MATRIX_GRADIENT_UP_DOWN
25# define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN
26#endif
27#ifndef DISABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT
28# define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT
29#endif
30#ifndef DISABLE_RGB_MATRIX_BREATHING
31# define ENABLE_RGB_MATRIX_BREATHING
32#endif
33#ifndef DISABLE_RGB_MATRIX_BAND_SAT
34# define ENABLE_RGB_MATRIX_BAND_SAT
35#endif
36#ifndef DISABLE_RGB_MATRIX_BAND_VAL
37# define ENABLE_RGB_MATRIX_BAND_VAL
38#endif
39#ifndef DISABLE_RGB_MATRIX_BAND_PINWHEEL_SAT
40# define ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT
41#endif
42#ifndef DISABLE_RGB_MATRIX_BAND_PINWHEEL_VAL
43# define ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL
44#endif
45#ifndef DISABLE_RGB_MATRIX_BAND_SPIRAL_SAT
46# define ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT
47#endif
48#ifndef DISABLE_RGB_MATRIX_BAND_SPIRAL_VAL
49# define ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL
50#endif
51#ifndef DISABLE_RGB_MATRIX_CYCLE_ALL
52# define ENABLE_RGB_MATRIX_CYCLE_ALL
53#endif
54#ifndef DISABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
55# define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
56#endif
57#ifndef DISABLE_RGB_MATRIX_CYCLE_UP_DOWN
58# define ENABLE_RGB_MATRIX_CYCLE_UP_DOWN
59#endif
60#ifndef DISABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
61# define ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
62#endif
63#ifndef DISABLE_RGB_MATRIX_CYCLE_OUT_IN
64# define ENABLE_RGB_MATRIX_CYCLE_OUT_IN
65#endif
66#ifndef DISABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL
67# define ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL
68#endif
69#ifndef DISABLE_RGB_MATRIX_CYCLE_PINWHEEL
70# define ENABLE_RGB_MATRIX_CYCLE_PINWHEEL
71#endif
72#ifndef DISABLE_RGB_MATRIX_CYCLE_SPIRAL
73# define ENABLE_RGB_MATRIX_CYCLE_SPIRAL
74#endif
75#ifndef DISABLE_RGB_MATRIX_DUAL_BEACON
76# define ENABLE_RGB_MATRIX_DUAL_BEACON
77#endif
78#ifndef DISABLE_RGB_MATRIX_RAINBOW_BEACON
79# define ENABLE_RGB_MATRIX_RAINBOW_BEACON
80#endif
81#ifndef DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS
82# define ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS
83#endif
84#ifndef DISABLE_RGB_MATRIX_RAINDROPS
85# define ENABLE_RGB_MATRIX_RAINDROPS
86#endif
87#ifndef DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
88# define ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
89#endif
90#ifndef DISABLE_RGB_MATRIX_HUE_BREATHING
91# define ENABLE_RGB_MATRIX_HUE_BREATHING
92#endif
93#ifndef DISABLE_RGB_MATRIX_HUE_PENDULUM
94# define ENABLE_RGB_MATRIX_HUE_PENDULUM
95#endif
96#ifndef DISABLE_RGB_MATRIX_HUE_WAVE
97# define ENABLE_RGB_MATRIX_HUE_WAVE
98#endif
99#ifndef DISABLE_RGB_MATRIX_PIXEL_RAIN
100# define ENABLE_RGB_MATRIX_PIXEL_RAIN
101#endif
102#ifndef DISABLE_RGB_MATRIX_PIXEL_FLOW
103# define ENABLE_RGB_MATRIX_PIXEL_FLOW
104#endif
105#ifndef DISABLE_RGB_MATRIX_PIXEL_FRACTAL
106# define ENABLE_RGB_MATRIX_PIXEL_FRACTAL
107#endif
108#if defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS)
109# ifndef DISABLE_RGB_MATRIX_TYPING_HEATMAP
110# define ENABLE_RGB_MATRIX_TYPING_HEATMAP
111# endif
112# ifndef DISABLE_RGB_MATRIX_DIGITAL_RAIN
113# define ENABLE_RGB_MATRIX_DIGITAL_RAIN
114# endif
115#endif
116#if defined(RGB_MATRIX_KEYREACTIVE_ENABLED)
117# ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
118# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
119# endif
120# ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE
121# define ENABLE_RGB_MATRIX_SOLID_REACTIVE
122# endif
123# ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE
124# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE
125# endif
126# ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE
127# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE
128# endif
129# ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS
130# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS
131# endif
132# ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS
133# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS
134# endif
135# ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS
136# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS
137# endif
138# ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS
139# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS
140# endif
141# ifndef DISABLE_RGB_MATRIX_SPLASH
142# define ENABLE_RGB_MATRIX_SPLASH
143# endif
144# ifndef DISABLE_RGB_MATRIX_MULTISPLASH
145# define ENABLE_RGB_MATRIX_MULTISPLASH
146# endif
147# ifndef DISABLE_RGB_MATRIX_SOLID_SPLASH
148# define ENABLE_RGB_MATRIX_SOLID_SPLASH
149# endif
150# ifndef DISABLE_RGB_MATRIX_SOLID_MULTISPLASH
151# define ENABLE_RGB_MATRIX_SOLID_MULTISPLASH
152# endif
153#endif
diff --git a/quantum/rgb_matrix/rgb_matrix_types.h b/quantum/rgb_matrix/rgb_matrix_types.h
new file mode 100644
index 000000000..df575d657
--- /dev/null
+++ b/quantum/rgb_matrix/rgb_matrix_types.h
@@ -0,0 +1,98 @@
1/* Copyright 2021
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#pragma once
18
19#include <stdint.h>
20#include <stdbool.h>
21#include "color.h"
22
23#if defined(__GNUC__)
24# define PACKED __attribute__((__packed__))
25#else
26# define PACKED
27#endif
28
29#if defined(_MSC_VER)
30# pragma pack(push, 1)
31#endif
32
33#if defined(RGB_MATRIX_KEYPRESSES) || defined(RGB_MATRIX_KEYRELEASES)
34# define RGB_MATRIX_KEYREACTIVE_ENABLED
35#endif
36
37// Last led hit
38#ifndef LED_HITS_TO_REMEMBER
39# define LED_HITS_TO_REMEMBER 8
40#endif // LED_HITS_TO_REMEMBER
41
42#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
43typedef struct PACKED {
44 uint8_t count;
45 uint8_t x[LED_HITS_TO_REMEMBER];
46 uint8_t y[LED_HITS_TO_REMEMBER];
47 uint8_t index[LED_HITS_TO_REMEMBER];
48 uint16_t tick[LED_HITS_TO_REMEMBER];
49} last_hit_t;
50#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
51
52typedef enum rgb_task_states { STARTING, RENDERING, FLUSHING, SYNCING } rgb_task_states;
53
54typedef uint8_t led_flags_t;
55
56typedef struct PACKED {
57 uint8_t iter;
58 led_flags_t flags;
59 bool init;
60} effect_params_t;
61
62typedef struct PACKED {
63 uint8_t x;
64 uint8_t y;
65} led_point_t;
66
67#define HAS_FLAGS(bits, flags) ((bits & flags) == flags)
68#define HAS_ANY_FLAGS(bits, flags) ((bits & flags) != 0x00)
69
70#define LED_FLAG_ALL 0xFF
71#define LED_FLAG_NONE 0x00
72#define LED_FLAG_MODIFIER 0x01
73#define LED_FLAG_UNDERGLOW 0x02
74#define LED_FLAG_KEYLIGHT 0x04
75#define LED_FLAG_INDICATOR 0x08
76
77#define NO_LED 255
78
79typedef struct PACKED {
80 uint8_t matrix_co[MATRIX_ROWS][MATRIX_COLS];
81 led_point_t point[DRIVER_LED_TOTAL];
82 uint8_t flags[DRIVER_LED_TOTAL];
83} led_config_t;
84
85typedef union {
86 uint32_t raw;
87 struct PACKED {
88 uint8_t enable : 2;
89 uint8_t mode : 6;
90 HSV hsv;
91 uint8_t speed; // EECONFIG needs to be increased to support this
92 led_flags_t flags;
93 };
94} rgb_config_t;
95
96#if defined(_MSC_VER)
97# pragma pack(pop)
98#endif