|
@@ -17,9 +17,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
#include "arm_atsam_protocol.h"
|
|
|
#include "tmk_core/common/led.h"
|
|
|
+#include "rgb_matrix.h"
|
|
|
#include <string.h>
|
|
|
#include <math.h>
|
|
|
|
|
|
+#ifdef USE_MASSDROP_CONFIGURATOR
|
|
|
+__attribute__((weak))
|
|
|
+led_instruction_t led_instructions[] = { { .end = 1 } };
|
|
|
+static void led_matrix_massdrop_config_override(int i);
|
|
|
+#endif // USE_MASSDROP_CONFIGURATOR
|
|
|
+
|
|
|
+extern rgb_config_t rgb_matrix_config;
|
|
|
+extern rgb_counters_t g_rgb_counters;
|
|
|
+
|
|
|
void SERCOM1_0_Handler( void )
|
|
|
{
|
|
|
if (SERCOM1->I2CM.INTFLAG.bit.ERROR)
|
|
@@ -51,14 +61,17 @@ void DMAC_0_Handler( void )
|
|
|
|
|
|
issi3733_driver_t issidrv[ISSI3733_DRIVER_COUNT];
|
|
|
|
|
|
-issi3733_led_t led_map[ISSI3733_LED_COUNT+1] = ISSI3733_LED_MAP;
|
|
|
-issi3733_led_t *lede = led_map + ISSI3733_LED_COUNT; //End pointer of mapping
|
|
|
+issi3733_led_t led_map[ISSI3733_LED_COUNT] = ISSI3733_LED_MAP;
|
|
|
+RGB led_buffer[ISSI3733_LED_COUNT];
|
|
|
|
|
|
uint8_t gcr_desired;
|
|
|
-uint8_t gcr_breathe;
|
|
|
-uint8_t gcr_use;
|
|
|
uint8_t gcr_actual;
|
|
|
uint8_t gcr_actual_last;
|
|
|
+#ifdef USE_MASSDROP_CONFIGURATOR
|
|
|
+uint8_t gcr_breathe;
|
|
|
+float breathe_mult;
|
|
|
+float pomod;
|
|
|
+#endif
|
|
|
|
|
|
#define ACT_GCR_NONE 0
|
|
|
#define ACT_GCR_INC 1
|
|
@@ -73,11 +86,14 @@ static uint8_t v_5v_cat_hit;
|
|
|
void gcr_compute(void)
|
|
|
{
|
|
|
uint8_t action = ACT_GCR_NONE;
|
|
|
+ uint8_t gcr_use = gcr_desired;
|
|
|
|
|
|
+#ifdef USE_MASSDROP_CONFIGURATOR
|
|
|
if (led_animation_breathing)
|
|
|
+ {
|
|
|
gcr_use = gcr_breathe;
|
|
|
- else
|
|
|
- gcr_use = gcr_desired;
|
|
|
+ }
|
|
|
+#endif
|
|
|
|
|
|
//If the 5v takes a catastrophic hit, disable the LED drivers briefly, assert auto gcr mode, min gcr and let the auto take over
|
|
|
if (v_5v < V5_CAT)
|
|
@@ -151,6 +167,7 @@ void gcr_compute(void)
|
|
|
gcr_actual -= LED_GCR_STEP_AUTO;
|
|
|
gcr_min_counter = 0;
|
|
|
|
|
|
+#ifdef USE_MASSDROP_CONFIGURATOR
|
|
|
//If breathe mode is active, the top end can fluctuate if the host can not supply enough current
|
|
|
//So set the breathe GCR to where it becomes stable
|
|
|
if (led_animation_breathing == 1)
|
|
@@ -160,12 +177,11 @@ void gcr_compute(void)
|
|
|
// and the same would happen maybe one or two more times. Therefore I'm favoring
|
|
|
// powering through one full breathe and letting gcr settle completely
|
|
|
}
|
|
|
+#endif
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-led_disp_t disp;
|
|
|
-
|
|
|
void issi3733_prepare_arrays(void)
|
|
|
{
|
|
|
memset(issidrv,0,sizeof(issi3733_driver_t) * ISSI3733_DRIVER_COUNT);
|
|
@@ -178,361 +194,309 @@ void issi3733_prepare_arrays(void)
|
|
|
issidrv[i].addr = addrs[i];
|
|
|
}
|
|
|
|
|
|
- issi3733_led_t *cur = led_map;
|
|
|
-
|
|
|
- while (cur < lede)
|
|
|
+ for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++)
|
|
|
{
|
|
|
//BYTE: 1 + (SW-1)*16 + (CS-1)
|
|
|
- cur->rgb.g = issidrv[cur->adr.drv-1].pwm + 1 + ((cur->adr.swg-1)*16 + (cur->adr.cs-1));
|
|
|
- cur->rgb.r = issidrv[cur->adr.drv-1].pwm + 1 + ((cur->adr.swr-1)*16 + (cur->adr.cs-1));
|
|
|
- cur->rgb.b = issidrv[cur->adr.drv-1].pwm + 1 + ((cur->adr.swb-1)*16 + (cur->adr.cs-1));
|
|
|
+ led_map[i].rgb.g = issidrv[led_map[i].adr.drv-1].pwm + 1 + ((led_map[i].adr.swg-1)*16 + (led_map[i].adr.cs-1));
|
|
|
+ led_map[i].rgb.r = issidrv[led_map[i].adr.drv-1].pwm + 1 + ((led_map[i].adr.swr-1)*16 + (led_map[i].adr.cs-1));
|
|
|
+ led_map[i].rgb.b = issidrv[led_map[i].adr.drv-1].pwm + 1 + ((led_map[i].adr.swb-1)*16 + (led_map[i].adr.cs-1));
|
|
|
|
|
|
//BYTE: 1 + (SW-1)*2 + (CS-1)/8
|
|
|
//BIT: (CS-1)%8
|
|
|
- *(issidrv[cur->adr.drv-1].onoff + 1 + (cur->adr.swg-1)*2+(cur->adr.cs-1)/8) |= (1<<((cur->adr.cs-1)%8));
|
|
|
- *(issidrv[cur->adr.drv-1].onoff + 1 + (cur->adr.swr-1)*2+(cur->adr.cs-1)/8) |= (1<<((cur->adr.cs-1)%8));
|
|
|
- *(issidrv[cur->adr.drv-1].onoff + 1 + (cur->adr.swb-1)*2+(cur->adr.cs-1)/8) |= (1<<((cur->adr.cs-1)%8));
|
|
|
-
|
|
|
- cur++;
|
|
|
+ *(issidrv[led_map[i].adr.drv-1].onoff + 1 + (led_map[i].adr.swg-1)*2+(led_map[i].adr.cs-1)/8) |= (1<<((led_map[i].adr.cs-1)%8));
|
|
|
+ *(issidrv[led_map[i].adr.drv-1].onoff + 1 + (led_map[i].adr.swr-1)*2+(led_map[i].adr.cs-1)/8) |= (1<<((led_map[i].adr.cs-1)%8));
|
|
|
+ *(issidrv[led_map[i].adr.drv-1].onoff + 1 + (led_map[i].adr.swb-1)*2+(led_map[i].adr.cs-1)/8) |= (1<<((led_map[i].adr.cs-1)%8));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void disp_calc_extents(void)
|
|
|
+void led_matrix_prepare(void)
|
|
|
{
|
|
|
- issi3733_led_t *cur = led_map;
|
|
|
-
|
|
|
- disp.left = 1e10;
|
|
|
- disp.right = -1e10;
|
|
|
- disp.top = -1e10;
|
|
|
- disp.bottom = 1e10;
|
|
|
-
|
|
|
- while (cur < lede)
|
|
|
+ for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++)
|
|
|
{
|
|
|
- if (cur->x < disp.left) disp.left = cur->x;
|
|
|
- if (cur->x > disp.right) disp.right = cur->x;
|
|
|
- if (cur->y < disp.bottom) disp.bottom = cur->y;
|
|
|
- if (cur->y > disp.top) disp.top = cur->y;
|
|
|
-
|
|
|
- cur++;
|
|
|
+ *led_map[i].rgb.r = 0;
|
|
|
+ *led_map[i].rgb.g = 0;
|
|
|
+ *led_map[i].rgb.b = 0;
|
|
|
}
|
|
|
-
|
|
|
- disp.width = disp.right - disp.left;
|
|
|
- disp.height = disp.top - disp.bottom;
|
|
|
- disp.max_distance = sqrtf(powf(disp.width, 2) + powf(disp.height, 2));
|
|
|
}
|
|
|
|
|
|
-void disp_pixel_setup(void)
|
|
|
+void led_set_one(int i, uint8_t r, uint8_t g, uint8_t b)
|
|
|
{
|
|
|
- issi3733_led_t *cur = led_map;
|
|
|
-
|
|
|
- while (cur < lede)
|
|
|
+ if (i < ISSI3733_LED_COUNT)
|
|
|
{
|
|
|
- cur->px = (cur->x - disp.left) / disp.width * 100;
|
|
|
- cur->py = (cur->y - disp.bottom) / disp.height * 100;
|
|
|
- *cur->rgb.r = 0;
|
|
|
- *cur->rgb.g = 0;
|
|
|
- *cur->rgb.b = 0;
|
|
|
-
|
|
|
- cur++;
|
|
|
+#ifdef USE_MASSDROP_CONFIGURATOR
|
|
|
+ led_matrix_massdrop_config_override(i);
|
|
|
+#else
|
|
|
+ led_buffer[i].r = r;
|
|
|
+ led_buffer[i].g = g;
|
|
|
+ led_buffer[i].b = b;
|
|
|
+#endif
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void led_matrix_prepare(void)
|
|
|
+void led_set_all(uint8_t r, uint8_t g, uint8_t b)
|
|
|
{
|
|
|
- disp_calc_extents();
|
|
|
- disp_pixel_setup();
|
|
|
+ for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++)
|
|
|
+ {
|
|
|
+ led_set_one(i, r, g, b);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-uint8_t led_enabled;
|
|
|
-float led_animation_speed;
|
|
|
-uint8_t led_animation_direction;
|
|
|
-uint8_t led_animation_orientation;
|
|
|
-uint8_t led_animation_breathing;
|
|
|
-uint8_t led_animation_breathe_cur;
|
|
|
-uint8_t breathe_step;
|
|
|
-uint8_t breathe_dir;
|
|
|
-uint8_t led_animation_circular;
|
|
|
-uint64_t led_next_run;
|
|
|
-
|
|
|
-uint8_t led_animation_id;
|
|
|
-uint8_t led_lighting_mode;
|
|
|
-
|
|
|
-issi3733_led_t *led_cur;
|
|
|
-uint8_t led_per_run = 15;
|
|
|
-float breathe_mult;
|
|
|
-
|
|
|
-__attribute__ ((weak))
|
|
|
-void led_matrix_run(void)
|
|
|
+void init(void)
|
|
|
{
|
|
|
- float ro;
|
|
|
- float go;
|
|
|
- float bo;
|
|
|
- float po;
|
|
|
-
|
|
|
- uint8_t led_this_run = 0;
|
|
|
- led_setup_t *f = (led_setup_t*)led_setups[led_animation_id];
|
|
|
-
|
|
|
- if (led_cur == 0) //Denotes start of new processing cycle in the case of chunked processing
|
|
|
- {
|
|
|
- led_cur = led_map;
|
|
|
+ DBGC(DC_LED_MATRIX_INIT_BEGIN);
|
|
|
|
|
|
- disp.frame += 1;
|
|
|
+ issi3733_prepare_arrays();
|
|
|
|
|
|
- breathe_mult = 1;
|
|
|
+ led_matrix_prepare();
|
|
|
|
|
|
- if (led_animation_breathing)
|
|
|
- {
|
|
|
- led_animation_breathe_cur += breathe_step * breathe_dir;
|
|
|
+ gcr_min_counter = 0;
|
|
|
+ v_5v_cat_hit = 0;
|
|
|
|
|
|
- if (led_animation_breathe_cur >= BREATHE_MAX_STEP)
|
|
|
- breathe_dir = -1;
|
|
|
- else if (led_animation_breathe_cur <= BREATHE_MIN_STEP)
|
|
|
- breathe_dir = 1;
|
|
|
+ DBGC(DC_LED_MATRIX_INIT_COMPLETE);
|
|
|
+}
|
|
|
|
|
|
- //Brightness curve created for 256 steps, 0 - ~98%
|
|
|
- breathe_mult = 0.000015 * led_animation_breathe_cur * led_animation_breathe_cur;
|
|
|
- if (breathe_mult > 1) breathe_mult = 1;
|
|
|
- else if (breathe_mult < 0) breathe_mult = 0;
|
|
|
- }
|
|
|
- }
|
|
|
+void flush(void)
|
|
|
+{
|
|
|
+#ifdef USE_MASSDROP_CONFIGURATOR
|
|
|
+ if (!led_enabled) { return; } //Prevent calculations and I2C traffic if LED drivers are not enabled
|
|
|
+#else
|
|
|
+ if (!sr_exp_data.bit.SDB_N) { return; } //Prevent calculations and I2C traffic if LED drivers are not enabled
|
|
|
+#endif
|
|
|
|
|
|
- uint8_t fcur = 0;
|
|
|
- uint8_t fmax = 0;
|
|
|
+ // Wait for previous transfer to complete
|
|
|
+ while (i2c_led_q_running) {}
|
|
|
|
|
|
- //Frames setup
|
|
|
- while (f[fcur].end != 1)
|
|
|
+ // Copy buffer to live DMA region
|
|
|
+ for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++)
|
|
|
{
|
|
|
- fcur++; //Count frames
|
|
|
+ *led_map[i].rgb.r = led_buffer[i].r;
|
|
|
+ *led_map[i].rgb.g = led_buffer[i].g;
|
|
|
+ *led_map[i].rgb.b = led_buffer[i].b;
|
|
|
}
|
|
|
|
|
|
- fmax = fcur; //Store total frames count
|
|
|
+#ifdef USE_MASSDROP_CONFIGURATOR
|
|
|
+ breathe_mult = 1;
|
|
|
|
|
|
- while (led_cur < lede && led_this_run < led_per_run)
|
|
|
+ if (led_animation_breathing)
|
|
|
{
|
|
|
- ro = 0;
|
|
|
- go = 0;
|
|
|
- bo = 0;
|
|
|
-
|
|
|
- if (led_lighting_mode == LED_MODE_KEYS_ONLY && led_cur->scan == 255)
|
|
|
- {
|
|
|
- //Do not act on this LED
|
|
|
- }
|
|
|
- else if (led_lighting_mode == LED_MODE_NON_KEYS_ONLY && led_cur->scan != 255)
|
|
|
- {
|
|
|
- //Do not act on this LED
|
|
|
- }
|
|
|
- else if (led_lighting_mode == LED_MODE_INDICATORS_ONLY)
|
|
|
- {
|
|
|
- //Do not act on this LED (Only show indicators)
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- //Act on LED
|
|
|
- for (fcur = 0; fcur < fmax; fcur++)
|
|
|
- {
|
|
|
-
|
|
|
- if (led_animation_circular) {
|
|
|
- po = sqrtf((powf(fabsf((disp.width / 2) - (led_cur->x - disp.left)), 2) + powf(fabsf((disp.height / 2) - (led_cur->y - disp.bottom)), 2))) / disp.max_distance * 100;
|
|
|
- }
|
|
|
- else {
|
|
|
- if (led_animation_orientation)
|
|
|
- {
|
|
|
- po = led_cur->py;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- po = led_cur->px;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- float pomod;
|
|
|
- pomod = (float)(disp.frame % (uint32_t)(1000.0f / led_animation_speed)) / 10.0f * led_animation_speed;
|
|
|
-
|
|
|
- //Add in any moving effects
|
|
|
- if ((!led_animation_direction && f[fcur].ef & EF_SCR_R) || (led_animation_direction && (f[fcur].ef & EF_SCR_L)))
|
|
|
- {
|
|
|
- pomod *= 100.0f;
|
|
|
- pomod = (uint32_t)pomod % 10000;
|
|
|
- pomod /= 100.0f;
|
|
|
-
|
|
|
- po -= pomod;
|
|
|
-
|
|
|
- if (po > 100) po -= 100;
|
|
|
- else if (po < 0) po += 100;
|
|
|
- }
|
|
|
- else if ((!led_animation_direction && f[fcur].ef & EF_SCR_L) || (led_animation_direction && (f[fcur].ef & EF_SCR_R)))
|
|
|
- {
|
|
|
- pomod *= 100.0f;
|
|
|
- pomod = (uint32_t)pomod % 10000;
|
|
|
- pomod /= 100.0f;
|
|
|
- po += pomod;
|
|
|
-
|
|
|
- if (po > 100) po -= 100;
|
|
|
- else if (po < 0) po += 100;
|
|
|
- }
|
|
|
+ //+60us 119 LED
|
|
|
+ led_animation_breathe_cur += BREATHE_STEP * breathe_dir;
|
|
|
+
|
|
|
+ if (led_animation_breathe_cur >= BREATHE_MAX_STEP)
|
|
|
+ breathe_dir = -1;
|
|
|
+ else if (led_animation_breathe_cur <= BREATHE_MIN_STEP)
|
|
|
+ breathe_dir = 1;
|
|
|
+
|
|
|
+ //Brightness curve created for 256 steps, 0 - ~98%
|
|
|
+ breathe_mult = 0.000015 * led_animation_breathe_cur * led_animation_breathe_cur;
|
|
|
+ if (breathe_mult > 1) breathe_mult = 1;
|
|
|
+ else if (breathe_mult < 0) breathe_mult = 0;
|
|
|
+ }
|
|
|
|
|
|
- //Check if LED's po is in current frame
|
|
|
- if (po < f[fcur].hs) continue;
|
|
|
- if (po > f[fcur].he) continue;
|
|
|
- //note: < 0 or > 100 continue
|
|
|
+ //This should only be performed once per frame
|
|
|
+ pomod = (float)((g_rgb_counters.tick / 10) % (uint32_t)(1000.0f / led_animation_speed)) / 10.0f * led_animation_speed;
|
|
|
+ pomod *= 100.0f;
|
|
|
+ pomod = (uint32_t)pomod % 10000;
|
|
|
+ pomod /= 100.0f;
|
|
|
|
|
|
- //Calculate the po within the start-stop percentage for color blending
|
|
|
- po = (po - f[fcur].hs) / (f[fcur].he - f[fcur].hs);
|
|
|
+#endif // USE_MASSDROP_CONFIGURATOR
|
|
|
|
|
|
- //Add in any color effects
|
|
|
- if (f[fcur].ef & EF_OVER)
|
|
|
- {
|
|
|
- ro = (po * (f[fcur].re - f[fcur].rs)) + f[fcur].rs;// + 0.5;
|
|
|
- go = (po * (f[fcur].ge - f[fcur].gs)) + f[fcur].gs;// + 0.5;
|
|
|
- bo = (po * (f[fcur].be - f[fcur].bs)) + f[fcur].bs;// + 0.5;
|
|
|
- }
|
|
|
- else if (f[fcur].ef & EF_SUBTRACT)
|
|
|
- {
|
|
|
- ro -= (po * (f[fcur].re - f[fcur].rs)) + f[fcur].rs;// + 0.5;
|
|
|
- go -= (po * (f[fcur].ge - f[fcur].gs)) + f[fcur].gs;// + 0.5;
|
|
|
- bo -= (po * (f[fcur].be - f[fcur].bs)) + f[fcur].bs;// + 0.5;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- ro += (po * (f[fcur].re - f[fcur].rs)) + f[fcur].rs;// + 0.5;
|
|
|
- go += (po * (f[fcur].ge - f[fcur].gs)) + f[fcur].gs;// + 0.5;
|
|
|
- bo += (po * (f[fcur].be - f[fcur].bs)) + f[fcur].bs;// + 0.5;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ uint8_t drvid;
|
|
|
|
|
|
- //Clamp values 0-255
|
|
|
- if (ro > 255) ro = 255; else if (ro < 0) ro = 0;
|
|
|
- if (go > 255) go = 255; else if (go < 0) go = 0;
|
|
|
- if (bo > 255) bo = 255; else if (bo < 0) bo = 0;
|
|
|
+ //NOTE: GCR does not need to be timed with LED processing, but there is really no harm
|
|
|
+ if (gcr_actual != gcr_actual_last)
|
|
|
+ {
|
|
|
+ for (drvid=0;drvid<ISSI3733_DRIVER_COUNT;drvid++)
|
|
|
+ I2C_LED_Q_GCR(drvid); //Queue data
|
|
|
+ gcr_actual_last = gcr_actual;
|
|
|
+ }
|
|
|
|
|
|
- if (led_animation_breathing)
|
|
|
- {
|
|
|
- ro *= breathe_mult;
|
|
|
- go *= breathe_mult;
|
|
|
- bo *= breathe_mult;
|
|
|
- }
|
|
|
+ for (drvid=0;drvid<ISSI3733_DRIVER_COUNT;drvid++)
|
|
|
+ I2C_LED_Q_PWM(drvid); //Queue data
|
|
|
|
|
|
- *led_cur->rgb.r = (uint8_t)ro;
|
|
|
- *led_cur->rgb.g = (uint8_t)go;
|
|
|
- *led_cur->rgb.b = (uint8_t)bo;
|
|
|
+ i2c_led_q_run();
|
|
|
+}
|
|
|
|
|
|
-#ifdef USB_LED_INDICATOR_ENABLE
|
|
|
- if (keyboard_leds())
|
|
|
+void led_matrix_indicators(void)
|
|
|
+{
|
|
|
+ uint8_t kbled = keyboard_leds();
|
|
|
+ if (kbled && rgb_matrix_config.enable)
|
|
|
+ {
|
|
|
+ for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++)
|
|
|
{
|
|
|
- uint8_t kbled = keyboard_leds();
|
|
|
if (
|
|
|
- #if USB_LED_NUM_LOCK_SCANCODE != 255
|
|
|
- (led_cur->scan == USB_LED_NUM_LOCK_SCANCODE && kbled & (1<<USB_LED_NUM_LOCK)) ||
|
|
|
- #endif //NUM LOCK
|
|
|
- #if USB_LED_CAPS_LOCK_SCANCODE != 255
|
|
|
- (led_cur->scan == USB_LED_CAPS_LOCK_SCANCODE && kbled & (1<<USB_LED_CAPS_LOCK)) ||
|
|
|
- #endif //CAPS LOCK
|
|
|
- #if USB_LED_SCROLL_LOCK_SCANCODE != 255
|
|
|
- (led_cur->scan == USB_LED_SCROLL_LOCK_SCANCODE && kbled & (1<<USB_LED_SCROLL_LOCK)) ||
|
|
|
- #endif //SCROLL LOCK
|
|
|
- #if USB_LED_COMPOSE_SCANCODE != 255
|
|
|
- (led_cur->scan == USB_LED_COMPOSE_SCANCODE && kbled & (1<<USB_LED_COMPOSE)) ||
|
|
|
- #endif //COMPOSE
|
|
|
- #if USB_LED_KANA_SCANCODE != 255
|
|
|
- (led_cur->scan == USB_LED_KANA_SCANCODE && kbled & (1<<USB_LED_KANA)) ||
|
|
|
- #endif //KANA
|
|
|
- (0))
|
|
|
+ #if USB_LED_NUM_LOCK_SCANCODE != 255
|
|
|
+ (led_map[i].scan == USB_LED_NUM_LOCK_SCANCODE && (kbled & (1<<USB_LED_NUM_LOCK))) ||
|
|
|
+ #endif //NUM LOCK
|
|
|
+ #if USB_LED_CAPS_LOCK_SCANCODE != 255
|
|
|
+ (led_map[i].scan == USB_LED_CAPS_LOCK_SCANCODE && (kbled & (1<<USB_LED_CAPS_LOCK))) ||
|
|
|
+ #endif //CAPS LOCK
|
|
|
+ #if USB_LED_SCROLL_LOCK_SCANCODE != 255
|
|
|
+ (led_map[i].scan == USB_LED_SCROLL_LOCK_SCANCODE && (kbled & (1<<USB_LED_SCROLL_LOCK))) ||
|
|
|
+ #endif //SCROLL LOCK
|
|
|
+ #if USB_LED_COMPOSE_SCANCODE != 255
|
|
|
+ (led_map[i].scan == USB_LED_COMPOSE_SCANCODE && (kbled & (1<<USB_LED_COMPOSE))) ||
|
|
|
+ #endif //COMPOSE
|
|
|
+ #if USB_LED_KANA_SCANCODE != 255
|
|
|
+ (led_map[i].scan == USB_LED_KANA_SCANCODE && (kbled & (1<<USB_LED_KANA))) ||
|
|
|
+ #endif //KANA
|
|
|
+ (0))
|
|
|
{
|
|
|
- if (*led_cur->rgb.r > 127) *led_cur->rgb.r = 0;
|
|
|
- else *led_cur->rgb.r = 255;
|
|
|
- if (*led_cur->rgb.g > 127) *led_cur->rgb.g = 0;
|
|
|
- else *led_cur->rgb.g = 255;
|
|
|
- if (*led_cur->rgb.b > 127) *led_cur->rgb.b = 0;
|
|
|
- else *led_cur->rgb.b = 255;
|
|
|
+ led_buffer[i].r = 255 - led_buffer[i].r;
|
|
|
+ led_buffer[i].g = 255 - led_buffer[i].g;
|
|
|
+ led_buffer[i].b = 255 - led_buffer[i].b;
|
|
|
}
|
|
|
}
|
|
|
-#endif //USB_LED_INDICATOR_ENABLE
|
|
|
-
|
|
|
- led_cur++;
|
|
|
- led_this_run++;
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
-uint8_t led_matrix_init(void)
|
|
|
-{
|
|
|
- DBGC(DC_LED_MATRIX_INIT_BEGIN);
|
|
|
+}
|
|
|
|
|
|
- issi3733_prepare_arrays();
|
|
|
+const rgb_matrix_driver_t rgb_matrix_driver = {
|
|
|
+ .init = init,
|
|
|
+ .flush = flush,
|
|
|
+ .set_color = led_set_one,
|
|
|
+ .set_color_all = led_set_all
|
|
|
+};
|
|
|
+
|
|
|
+/*==============================================================================
|
|
|
+= Legacy Lighting Support =
|
|
|
+==============================================================================*/
|
|
|
+
|
|
|
+#ifdef USE_MASSDROP_CONFIGURATOR
|
|
|
+// Ported from Massdrop QMK Github Repo
|
|
|
+
|
|
|
+// TODO?: wire these up to keymap.c
|
|
|
+uint8_t led_animation_orientation = 0;
|
|
|
+uint8_t led_animation_direction = 0;
|
|
|
+uint8_t led_animation_breathing = 0;
|
|
|
+uint8_t led_animation_id = 0;
|
|
|
+float led_animation_speed = 4.0f;
|
|
|
+uint8_t led_lighting_mode = LED_MODE_NORMAL;
|
|
|
+uint8_t led_enabled = 1;
|
|
|
+uint8_t led_animation_breathe_cur = BREATHE_MIN_STEP;
|
|
|
+uint8_t breathe_dir = 1;
|
|
|
+
|
|
|
+static void led_run_pattern(led_setup_t *f, float* ro, float* go, float* bo, float pos) {
|
|
|
+ float po;
|
|
|
|
|
|
- led_matrix_prepare();
|
|
|
+ while (f->end != 1)
|
|
|
+ {
|
|
|
+ po = pos; //Reset po for new frame
|
|
|
|
|
|
- disp.frame = 0;
|
|
|
- led_next_run = 0;
|
|
|
-
|
|
|
- led_enabled = 1;
|
|
|
- led_animation_id = 0;
|
|
|
- led_lighting_mode = LED_MODE_NORMAL;
|
|
|
- led_animation_speed = 4.0f;
|
|
|
- led_animation_direction = 0;
|
|
|
- led_animation_orientation = 0;
|
|
|
- led_animation_breathing = 0;
|
|
|
- led_animation_breathe_cur = BREATHE_MIN_STEP;
|
|
|
- breathe_step = 1;
|
|
|
- breathe_dir = 1;
|
|
|
- led_animation_circular = 0;
|
|
|
+ //Add in any moving effects
|
|
|
+ if ((!led_animation_direction && f->ef & EF_SCR_R) || (led_animation_direction && (f->ef & EF_SCR_L)))
|
|
|
+ {
|
|
|
+ po -= pomod;
|
|
|
|
|
|
- gcr_min_counter = 0;
|
|
|
- v_5v_cat_hit = 0;
|
|
|
+ if (po > 100) po -= 100;
|
|
|
+ else if (po < 0) po += 100;
|
|
|
+ }
|
|
|
+ else if ((!led_animation_direction && f->ef & EF_SCR_L) || (led_animation_direction && (f->ef & EF_SCR_R)))
|
|
|
+ {
|
|
|
+ po += pomod;
|
|
|
|
|
|
- //Run led matrix code once for initial LED coloring
|
|
|
- led_cur = 0;
|
|
|
- rgb_matrix_init_user();
|
|
|
- led_matrix_run();
|
|
|
+ if (po > 100) po -= 100;
|
|
|
+ else if (po < 0) po += 100;
|
|
|
+ }
|
|
|
|
|
|
- DBGC(DC_LED_MATRIX_INIT_COMPLETE);
|
|
|
+ //Check if LED's po is in current frame
|
|
|
+ if (po < f->hs) { f++; continue; }
|
|
|
+ if (po > f->he) { f++; continue; }
|
|
|
+ //note: < 0 or > 100 continue
|
|
|
|
|
|
- return 0;
|
|
|
-}
|
|
|
+ //Calculate the po within the start-stop percentage for color blending
|
|
|
+ po = (po - f->hs) / (f->he - f->hs);
|
|
|
|
|
|
-__attribute__ ((weak))
|
|
|
-void rgb_matrix_init_user(void) {
|
|
|
+ //Add in any color effects
|
|
|
+ if (f->ef & EF_OVER)
|
|
|
+ {
|
|
|
+ *ro = (po * (f->re - f->rs)) + f->rs;// + 0.5;
|
|
|
+ *go = (po * (f->ge - f->gs)) + f->gs;// + 0.5;
|
|
|
+ *bo = (po * (f->be - f->bs)) + f->bs;// + 0.5;
|
|
|
+ }
|
|
|
+ else if (f->ef & EF_SUBTRACT)
|
|
|
+ {
|
|
|
+ *ro -= (po * (f->re - f->rs)) + f->rs;// + 0.5;
|
|
|
+ *go -= (po * (f->ge - f->gs)) + f->gs;// + 0.5;
|
|
|
+ *bo -= (po * (f->be - f->bs)) + f->bs;// + 0.5;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ *ro += (po * (f->re - f->rs)) + f->rs;// + 0.5;
|
|
|
+ *go += (po * (f->ge - f->gs)) + f->gs;// + 0.5;
|
|
|
+ *bo += (po * (f->be - f->bs)) + f->bs;// + 0.5;
|
|
|
+ }
|
|
|
|
|
|
+ f++;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-#define LED_UPDATE_RATE 10 //ms
|
|
|
-
|
|
|
-//led data processing can take time, so process data in chunks to free up the processor
|
|
|
-//this is done through led_cur and lede
|
|
|
-void led_matrix_task(void)
|
|
|
+static void led_matrix_massdrop_config_override(int i)
|
|
|
{
|
|
|
- if (led_enabled)
|
|
|
- {
|
|
|
- //If an update may run and frame processing has completed
|
|
|
- if (timer_read64() >= led_next_run && led_cur == lede)
|
|
|
- {
|
|
|
- uint8_t drvid;
|
|
|
+ float ro = 0;
|
|
|
+ float go = 0;
|
|
|
+ float bo = 0;
|
|
|
+
|
|
|
+ float po = (led_animation_orientation)
|
|
|
+ ? (float)g_rgb_leds[i].point.y / 64.f * 100
|
|
|
+ : (float)g_rgb_leds[i].point.x / 224.f * 100;
|
|
|
+
|
|
|
+ uint8_t highest_active_layer = biton32(layer_state);
|
|
|
+
|
|
|
+ if (led_lighting_mode == LED_MODE_KEYS_ONLY && g_rgb_leds[i].matrix_co.raw == 0xff) {
|
|
|
+ //Do not act on this LED
|
|
|
+ } else if (led_lighting_mode == LED_MODE_NON_KEYS_ONLY && g_rgb_leds[i].matrix_co.raw != 0xff) {
|
|
|
+ //Do not act on this LED
|
|
|
+ } else if (led_lighting_mode == LED_MODE_INDICATORS_ONLY) {
|
|
|
+ //Do not act on this LED (Only show indicators)
|
|
|
+ } else {
|
|
|
+ led_instruction_t* led_cur_instruction = led_instructions;
|
|
|
+ while (!led_cur_instruction->end) {
|
|
|
+ // Check if this applies to current layer
|
|
|
+ if ((led_cur_instruction->flags & LED_FLAG_MATCH_LAYER) &&
|
|
|
+ (led_cur_instruction->layer != highest_active_layer)) {
|
|
|
+ goto next_iter;
|
|
|
+ }
|
|
|
|
|
|
- led_next_run = timer_read64() + LED_UPDATE_RATE; //Set next frame update time
|
|
|
+ // Check if this applies to current index
|
|
|
+ if (led_cur_instruction->flags & LED_FLAG_MATCH_ID) {
|
|
|
+ uint8_t modid = i / 32; //Calculate which id# contains the led bit
|
|
|
+ uint32_t modidbit = 1 << (i % 32); //Calculate the bit within the id#
|
|
|
+ uint32_t *bitfield = &led_cur_instruction->id0 + modid; //Add modid as offset to id0 address. *bitfield is now idX of the led id
|
|
|
+ if (~(*bitfield) & modidbit) { //Check if led bit is not set in idX
|
|
|
+ goto next_iter;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- //NOTE: GCR does not need to be timed with LED processing, but there is really no harm
|
|
|
- if (gcr_actual != gcr_actual_last)
|
|
|
- {
|
|
|
- for (drvid=0;drvid<ISSI3733_DRIVER_COUNT;drvid++)
|
|
|
- I2C_LED_Q_GCR(drvid); //Queue data
|
|
|
- gcr_actual_last = gcr_actual;
|
|
|
+ if (led_cur_instruction->flags & LED_FLAG_USE_RGB) {
|
|
|
+ ro = led_cur_instruction->r;
|
|
|
+ go = led_cur_instruction->g;
|
|
|
+ bo = led_cur_instruction->b;
|
|
|
+ } else if (led_cur_instruction->flags & LED_FLAG_USE_PATTERN) {
|
|
|
+ led_run_pattern(led_setups[led_cur_instruction->pattern_id], &ro, &go, &bo, po);
|
|
|
+ } else if (led_cur_instruction->flags & LED_FLAG_USE_ROTATE_PATTERN) {
|
|
|
+ led_run_pattern(led_setups[led_animation_id], &ro, &go, &bo, po);
|
|
|
}
|
|
|
|
|
|
- for (drvid=0;drvid<ISSI3733_DRIVER_COUNT;drvid++)
|
|
|
- I2C_LED_Q_PWM(drvid); //Queue data
|
|
|
+ next_iter:
|
|
|
+ led_cur_instruction++;
|
|
|
+ }
|
|
|
|
|
|
- i2c_led_q_run();
|
|
|
+ if (ro > 255) ro = 255; else if (ro < 0) ro = 0;
|
|
|
+ if (go > 255) go = 255; else if (go < 0) go = 0;
|
|
|
+ if (bo > 255) bo = 255; else if (bo < 0) bo = 0;
|
|
|
|
|
|
- led_cur = 0; //Signal next frame calculations may begin
|
|
|
+ if (led_animation_breathing)
|
|
|
+ {
|
|
|
+ ro *= breathe_mult;
|
|
|
+ go *= breathe_mult;
|
|
|
+ bo *= breathe_mult;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- //Process more data if not finished
|
|
|
- if (led_cur != lede)
|
|
|
- {
|
|
|
- //DBG_1_OFF; //debug profiling
|
|
|
- led_matrix_run();
|
|
|
- //DBG_1_ON; //debug profiling
|
|
|
- }
|
|
|
+ led_buffer[i].r = (uint8_t)ro;
|
|
|
+ led_buffer[i].g = (uint8_t)go;
|
|
|
+ led_buffer[i].b = (uint8_t)bo;
|
|
|
}
|
|
|
|
|
|
+#endif // USE_MASSDROP_CONFIGURATOR
|