RGB Matrix support for Massdrop CTRL/ALT (#5328)
* port Massdrop CTRL/ALT to use RGB Matrix Co-authored-by: Matt Schneeberger <helluvamatt@gmail.com> * Massdrop lighting support working This commit is to get the Massdrop lighting code working again through use of the compilation define USE_MASSDROP_CONFIGURATOR added to a keymap's rules.mk. Added keymaps for both CTRL and ALT named default_md and mac_md. These should be used if the Massdrop style lighting is desired. * Updating config based on testing results with patrickmt & compile errors * Updates for PR5328 For CTRL and ALT: Moved location of new RGB Matrix macros from config_led.h to config.h. Added RGB_MATRIX_LED_FLUSH_LIMIT (time between flushes) to config.h for correct LED driver update timing. Re-added missing breathing code for when Massdrop configurator mode is defined. * remove prilik keymap form PR
This commit is contained in:
		
							parent
							
								
									63177760de
								
							
						
					
					
						commit
						763b26cdb9
					
				
					 38 changed files with 1688 additions and 1070 deletions
				
			
		| 
						 | 
				
			
			@ -34,7 +34,10 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#ifndef MD_BOOTLOADER
 | 
			
		||||
 | 
			
		||||
#include "main_arm_atsam.h"
 | 
			
		||||
#ifdef RGB_MATRIX_ENABLE
 | 
			
		||||
#include "led_matrix.h"
 | 
			
		||||
#include "rgb_matrix.h"
 | 
			
		||||
#endif
 | 
			
		||||
#include "issi3733_driver.h"
 | 
			
		||||
#include "./usb/compiler.h"
 | 
			
		||||
#include "./usb/udc.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
 | 
			
		||||
#include "arm_atsam_protocol.h"
 | 
			
		||||
 | 
			
		||||
#ifndef MD_BOOTLOADER
 | 
			
		||||
#if !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE)
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -37,7 +37,7 @@ static uint8_t dma_sendbuf[I2C_DMA_MAX_SEND]; //Data being written to I2C
 | 
			
		|||
 | 
			
		||||
volatile uint8_t i2c_led_q_running;
 | 
			
		||||
 | 
			
		||||
#endif //MD_BOOTLOADER
 | 
			
		||||
#endif // !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE)
 | 
			
		||||
 | 
			
		||||
void i2c0_init(void)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -112,7 +112,7 @@ void i2c0_stop(void)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifndef MD_BOOTLOADER
 | 
			
		||||
#if !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE)
 | 
			
		||||
void i2c1_init(void)
 | 
			
		||||
{
 | 
			
		||||
    DBGC(DC_I2C1_INIT_BEGIN);
 | 
			
		||||
| 
						 | 
				
			
			@ -583,4 +583,4 @@ uint8_t i2c_led_q_run(void)
 | 
			
		|||
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
#endif //MD_BOOTLOADER
 | 
			
		||||
#endif // !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,230 +194,294 @@ 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++;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void disp_calc_extents(void)
 | 
			
		||||
{
 | 
			
		||||
    issi3733_led_t *cur = led_map;
 | 
			
		||||
 | 
			
		||||
    disp.left = 1e10;
 | 
			
		||||
    disp.right = -1e10;
 | 
			
		||||
    disp.top = -1e10;
 | 
			
		||||
    disp.bottom = 1e10;
 | 
			
		||||
 | 
			
		||||
    while (cur < lede)
 | 
			
		||||
    {
 | 
			
		||||
        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++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
{
 | 
			
		||||
    issi3733_led_t *cur = led_map;
 | 
			
		||||
 | 
			
		||||
    while (cur < lede)
 | 
			
		||||
    {
 | 
			
		||||
        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++;
 | 
			
		||||
        *(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 led_matrix_prepare(void)
 | 
			
		||||
{
 | 
			
		||||
    disp_calc_extents();
 | 
			
		||||
    disp_pixel_setup();
 | 
			
		||||
    for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++)
 | 
			
		||||
    {
 | 
			
		||||
        *led_map[i].rgb.r = 0;
 | 
			
		||||
        *led_map[i].rgb.g = 0;
 | 
			
		||||
        *led_map[i].rgb.b = 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 led_set_one(int i, uint8_t r, uint8_t g, uint8_t b)
 | 
			
		||||
{
 | 
			
		||||
    float ro;
 | 
			
		||||
    float go;
 | 
			
		||||
    float bo;
 | 
			
		||||
    if (i < ISSI3733_LED_COUNT)
 | 
			
		||||
    {
 | 
			
		||||
#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_set_all(uint8_t r, uint8_t g, uint8_t b)
 | 
			
		||||
{
 | 
			
		||||
  for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++)
 | 
			
		||||
  {
 | 
			
		||||
    led_set_one(i, r, g, b);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void init(void)
 | 
			
		||||
{
 | 
			
		||||
    DBGC(DC_LED_MATRIX_INIT_BEGIN);
 | 
			
		||||
 | 
			
		||||
    issi3733_prepare_arrays();
 | 
			
		||||
 | 
			
		||||
    led_matrix_prepare();
 | 
			
		||||
 | 
			
		||||
    gcr_min_counter = 0;
 | 
			
		||||
    v_5v_cat_hit = 0;
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_LED_MATRIX_INIT_COMPLETE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
    // Wait for previous transfer to complete
 | 
			
		||||
    while (i2c_led_q_running) {}
 | 
			
		||||
 | 
			
		||||
    // Copy buffer to live DMA region
 | 
			
		||||
    for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++)
 | 
			
		||||
    {
 | 
			
		||||
        *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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
    breathe_mult = 1;
 | 
			
		||||
 | 
			
		||||
    if (led_animation_breathing)
 | 
			
		||||
    {
 | 
			
		||||
        //+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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //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;
 | 
			
		||||
 | 
			
		||||
#endif // USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
 | 
			
		||||
    uint8_t drvid;
 | 
			
		||||
 | 
			
		||||
    //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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (drvid=0;drvid<ISSI3733_DRIVER_COUNT;drvid++)
 | 
			
		||||
        I2C_LED_Q_PWM(drvid); //Queue data
 | 
			
		||||
 | 
			
		||||
    i2c_led_q_run();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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++)
 | 
			
		||||
        {
 | 
			
		||||
            if (
 | 
			
		||||
            #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))
 | 
			
		||||
            {
 | 
			
		||||
                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;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
    while (f->end != 1)
 | 
			
		||||
    {
 | 
			
		||||
        led_cur = led_map;
 | 
			
		||||
        po = pos; //Reset po for new frame
 | 
			
		||||
 | 
			
		||||
        disp.frame += 1;
 | 
			
		||||
 | 
			
		||||
        breathe_mult = 1;
 | 
			
		||||
 | 
			
		||||
        if (led_animation_breathing)
 | 
			
		||||
        //Add in any moving effects
 | 
			
		||||
        if ((!led_animation_direction && f->ef & EF_SCR_R) || (led_animation_direction && (f->ef & EF_SCR_L)))
 | 
			
		||||
        {
 | 
			
		||||
            led_animation_breathe_cur += breathe_step * breathe_dir;
 | 
			
		||||
            po -= pomod;
 | 
			
		||||
 | 
			
		||||
            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;
 | 
			
		||||
            if (po > 100) po -= 100;
 | 
			
		||||
            else if (po < 0) po += 100;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint8_t fcur = 0;
 | 
			
		||||
    uint8_t fmax = 0;
 | 
			
		||||
 | 
			
		||||
    //Frames setup
 | 
			
		||||
    while (f[fcur].end != 1)
 | 
			
		||||
    {
 | 
			
		||||
        fcur++; //Count frames
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fmax = fcur; //Store total frames count
 | 
			
		||||
 | 
			
		||||
    while (led_cur < lede && led_this_run < led_per_run)
 | 
			
		||||
    {
 | 
			
		||||
        ro = 0;
 | 
			
		||||
        go = 0;
 | 
			
		||||
        bo = 0;
 | 
			
		||||
 | 
			
		||||
        if (led_lighting_mode == LED_MODE_KEYS_ONLY && led_cur->scan == 255)
 | 
			
		||||
        else if ((!led_animation_direction && f->ef & EF_SCR_L) || (led_animation_direction && (f->ef & EF_SCR_R)))
 | 
			
		||||
        {
 | 
			
		||||
            //Do not act on this LED
 | 
			
		||||
            po += pomod;
 | 
			
		||||
 | 
			
		||||
            if (po > 100) po -= 100;
 | 
			
		||||
            else if (po < 0) po += 100;
 | 
			
		||||
        }
 | 
			
		||||
        else if (led_lighting_mode == LED_MODE_NON_KEYS_ONLY && led_cur->scan != 255)
 | 
			
		||||
 | 
			
		||||
        //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
 | 
			
		||||
 | 
			
		||||
        //Calculate the po within the start-stop percentage for color blending
 | 
			
		||||
        po = (po - f->hs) / (f->he - f->hs);
 | 
			
		||||
 | 
			
		||||
        //Add in any color effects
 | 
			
		||||
        if (f->ef & EF_OVER)
 | 
			
		||||
        {
 | 
			
		||||
            //Do not act on this LED
 | 
			
		||||
            *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 (led_lighting_mode == LED_MODE_INDICATORS_ONLY)
 | 
			
		||||
        else if (f->ef & EF_SUBTRACT)
 | 
			
		||||
        {
 | 
			
		||||
            //Do not act on this LED (Only show indicators)
 | 
			
		||||
            *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
 | 
			
		||||
        {
 | 
			
		||||
            //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;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                //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
 | 
			
		||||
 | 
			
		||||
                //Calculate the po within the start-stop percentage for color blending
 | 
			
		||||
                po = (po - f[fcur].hs) / (f[fcur].he - f[fcur].hs);
 | 
			
		||||
 | 
			
		||||
                //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;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            *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++;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void led_matrix_massdrop_config_override(int i)
 | 
			
		||||
{
 | 
			
		||||
    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;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // 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;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            next_iter:
 | 
			
		||||
                led_cur_instruction++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //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;
 | 
			
		||||
| 
						 | 
				
			
			@ -412,127 +492,11 @@ void led_matrix_run(void)
 | 
			
		|||
            go *= breathe_mult;
 | 
			
		||||
            bo *= breathe_mult;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        *led_cur->rgb.r = (uint8_t)ro;
 | 
			
		||||
        *led_cur->rgb.g = (uint8_t)go;
 | 
			
		||||
        *led_cur->rgb.b = (uint8_t)bo;
 | 
			
		||||
 | 
			
		||||
#ifdef USB_LED_INDICATOR_ENABLE
 | 
			
		||||
        if (keyboard_leds())
 | 
			
		||||
        {
 | 
			
		||||
            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 (*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;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
#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();
 | 
			
		||||
 | 
			
		||||
    led_matrix_prepare();
 | 
			
		||||
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
    gcr_min_counter = 0;
 | 
			
		||||
    v_5v_cat_hit = 0;
 | 
			
		||||
 | 
			
		||||
    //Run led matrix code once for initial LED coloring
 | 
			
		||||
    led_cur = 0;
 | 
			
		||||
    rgb_matrix_init_user();
 | 
			
		||||
    led_matrix_run();
 | 
			
		||||
 | 
			
		||||
    DBGC(DC_LED_MATRIX_INIT_COMPLETE);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__ ((weak))
 | 
			
		||||
void rgb_matrix_init_user(void) {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#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)
 | 
			
		||||
{
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
            led_next_run = timer_read64() + LED_UPDATE_RATE;  //Set next frame update time
 | 
			
		||||
 | 
			
		||||
            //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;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for (drvid=0;drvid<ISSI3733_DRIVER_COUNT;drvid++)
 | 
			
		||||
                I2C_LED_Q_PWM(drvid); //Queue data
 | 
			
		||||
 | 
			
		||||
            i2c_led_q_run();
 | 
			
		||||
 | 
			
		||||
            led_cur = 0; //Signal next frame calculations may begin
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#ifndef _LED_MATRIX_H_
 | 
			
		||||
#define _LED_MATRIX_H_
 | 
			
		||||
 | 
			
		||||
#include "quantum.h"
 | 
			
		||||
 | 
			
		||||
//From keyboard
 | 
			
		||||
#include "config_led.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -75,25 +77,20 @@ typedef struct issi3733_led_s {
 | 
			
		|||
    uint8_t scan;               //Key scan code from wiring (set 0xFF if no key)
 | 
			
		||||
} issi3733_led_t;
 | 
			
		||||
 | 
			
		||||
typedef struct led_disp_s {
 | 
			
		||||
    uint64_t frame;
 | 
			
		||||
    float left;
 | 
			
		||||
    float right;
 | 
			
		||||
    float top;
 | 
			
		||||
    float bottom;
 | 
			
		||||
    float width;
 | 
			
		||||
    float height;
 | 
			
		||||
    float max_distance;
 | 
			
		||||
} led_disp_t;
 | 
			
		||||
extern issi3733_driver_t issidrv[ISSI3733_DRIVER_COUNT];
 | 
			
		||||
 | 
			
		||||
uint8_t led_matrix_init(void);
 | 
			
		||||
void rgb_matrix_init_user(void);
 | 
			
		||||
extern uint8_t gcr_desired;
 | 
			
		||||
extern uint8_t gcr_breathe;
 | 
			
		||||
extern uint8_t gcr_actual;
 | 
			
		||||
extern uint8_t gcr_actual_last;
 | 
			
		||||
 | 
			
		||||
#define LED_MODE_NORMAL             0   //Must be 0
 | 
			
		||||
#define LED_MODE_KEYS_ONLY          1
 | 
			
		||||
#define LED_MODE_NON_KEYS_ONLY      2
 | 
			
		||||
#define LED_MODE_INDICATORS_ONLY    3
 | 
			
		||||
#define LED_MODE_MAX_INDEX          LED_MODE_INDICATORS_ONLY   //Must be highest value
 | 
			
		||||
void gcr_compute(void);
 | 
			
		||||
 | 
			
		||||
void led_matrix_indicators(void);
 | 
			
		||||
 | 
			
		||||
/*-------------------------  Legacy Lighting Support  ------------------------*/
 | 
			
		||||
 | 
			
		||||
#ifdef USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
 | 
			
		||||
#define EF_NONE         0x00000000  //No effect
 | 
			
		||||
#define EF_OVER         0x00000001  //Overwrite any previous color information with new
 | 
			
		||||
| 
						 | 
				
			
			@ -114,33 +111,48 @@ typedef struct led_setup_s {
 | 
			
		|||
  uint8_t end;      //Set to signal end of the setup
 | 
			
		||||
} led_setup_t;
 | 
			
		||||
 | 
			
		||||
extern issi3733_driver_t issidrv[ISSI3733_DRIVER_COUNT];
 | 
			
		||||
 | 
			
		||||
extern uint8_t gcr_desired;
 | 
			
		||||
extern uint8_t gcr_breathe;
 | 
			
		||||
extern uint8_t gcr_actual;
 | 
			
		||||
extern uint8_t gcr_actual_last;
 | 
			
		||||
 | 
			
		||||
extern uint8_t led_animation_id;
 | 
			
		||||
extern uint8_t led_enabled;
 | 
			
		||||
extern float led_animation_speed;
 | 
			
		||||
extern uint8_t led_lighting_mode;
 | 
			
		||||
extern uint8_t led_animation_direction;
 | 
			
		||||
extern uint8_t led_animation_orientation;
 | 
			
		||||
extern uint8_t led_animation_breathing;
 | 
			
		||||
extern uint8_t led_animation_breathe_cur;
 | 
			
		||||
extern uint8_t breathe_dir;
 | 
			
		||||
extern uint8_t led_animation_circular;
 | 
			
		||||
extern const uint8_t led_setups_count;
 | 
			
		||||
 | 
			
		||||
extern void *led_setups[];
 | 
			
		||||
 | 
			
		||||
extern issi3733_led_t *led_cur;
 | 
			
		||||
extern issi3733_led_t *lede;
 | 
			
		||||
//LED Extra Instructions
 | 
			
		||||
#define LED_FLAG_NULL                0x00       //Matching and coloring not used (default)
 | 
			
		||||
#define LED_FLAG_MATCH_ID            0x01       //Match on the ID of the LED (set id#'s to desired bit pattern, first LED is id 1)
 | 
			
		||||
#define LED_FLAG_MATCH_LAYER         0x02       //Match on the current active layer (set layer to desired match layer)
 | 
			
		||||
#define LED_FLAG_USE_RGB             0x10       //Use a specific RGB value (set r, g, b to desired output color values)
 | 
			
		||||
#define LED_FLAG_USE_PATTERN         0x20       //Use a specific pattern ID (set pattern_id to desired output pattern)
 | 
			
		||||
#define LED_FLAG_USE_ROTATE_PATTERN  0x40       //Use pattern the user has cycled to manually
 | 
			
		||||
 | 
			
		||||
void led_matrix_run(void);
 | 
			
		||||
void led_matrix_task(void);
 | 
			
		||||
typedef struct led_instruction_s {
 | 
			
		||||
    uint16_t flags; // Bitfield for LED instructions
 | 
			
		||||
    uint32_t id0; // Bitwise id, IDs 0-31
 | 
			
		||||
    uint32_t id1; // Bitwise id, IDs 32-63
 | 
			
		||||
    uint32_t id2; // Bitwise id, IDs 64-95
 | 
			
		||||
    uint32_t id3; // Bitwise id, IDs 96-127
 | 
			
		||||
    uint8_t layer;
 | 
			
		||||
    uint8_t r;
 | 
			
		||||
    uint8_t g;
 | 
			
		||||
    uint8_t b;
 | 
			
		||||
    uint8_t pattern_id;
 | 
			
		||||
    uint8_t end;
 | 
			
		||||
} led_instruction_t;
 | 
			
		||||
 | 
			
		||||
void gcr_compute(void);
 | 
			
		||||
extern led_instruction_t led_instructions[];
 | 
			
		||||
 | 
			
		||||
extern uint8_t led_animation_breathing;
 | 
			
		||||
extern uint8_t led_animation_id;
 | 
			
		||||
extern float led_animation_speed;
 | 
			
		||||
extern uint8_t led_lighting_mode;
 | 
			
		||||
extern uint8_t led_enabled;
 | 
			
		||||
extern uint8_t led_animation_breathe_cur;
 | 
			
		||||
extern uint8_t led_animation_direction;
 | 
			
		||||
extern uint8_t breathe_dir;
 | 
			
		||||
 | 
			
		||||
#define LED_MODE_NORMAL             0   //Must be 0
 | 
			
		||||
#define LED_MODE_KEYS_ONLY          1
 | 
			
		||||
#define LED_MODE_NON_KEYS_ONLY      2
 | 
			
		||||
#define LED_MODE_INDICATORS_ONLY    3
 | 
			
		||||
#define LED_MODE_MAX_INDEX          LED_MODE_INDICATORS_ONLY   //Must be highest value
 | 
			
		||||
 | 
			
		||||
#endif // USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
 | 
			
		||||
#endif //_LED_MATRIX_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										123
									
								
								tmk_core/protocol/arm_atsam/led_matrix_programs.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								tmk_core/protocol/arm_atsam/led_matrix_programs.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,123 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2018 Massdrop Inc.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifdef USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
 | 
			
		||||
#include "led_matrix.h"
 | 
			
		||||
 | 
			
		||||
//Teal <-> Salmon
 | 
			
		||||
led_setup_t leds_teal_salmon[] = {
 | 
			
		||||
    { .hs = 0,  .he = 33,  .rs = 24,  .re = 24,  .gs = 215, .ge = 215, .bs = 204, .be = 204, .ef = EF_NONE },
 | 
			
		||||
    { .hs = 33, .he = 66,  .rs = 24,  .re = 255, .gs = 215, .ge = 114, .bs = 204, .be = 118, .ef = EF_NONE },
 | 
			
		||||
    { .hs = 66, .he = 100, .rs = 255, .re = 255, .gs = 114, .ge = 114, .bs = 118, .be = 118, .ef = EF_NONE },
 | 
			
		||||
    { .end = 1 },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//Yellow
 | 
			
		||||
led_setup_t leds_yellow[] = {
 | 
			
		||||
    { .hs = 0, .he = 100, .rs = 255, .re = 255, .gs = 255, .ge = 255, .bs = 0, .be = 0, .ef = EF_NONE },
 | 
			
		||||
    { .end = 1 },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//Off
 | 
			
		||||
led_setup_t leds_off[] = {
 | 
			
		||||
    { .hs = 0, .he = 100, .rs = 0, .re = 0, .gs = 0, .ge = 0, .bs = 0, .be = 0, .ef = EF_NONE },
 | 
			
		||||
    { .end = 1 },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//Red
 | 
			
		||||
led_setup_t leds_red[] = {
 | 
			
		||||
    { .hs = 0, .he = 100, .rs = 255, .re = 255, .gs = 0, .ge = 0, .bs = 0, .be = 0, .ef = EF_NONE },
 | 
			
		||||
    { .end = 1 },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//Green
 | 
			
		||||
led_setup_t leds_green[] = {
 | 
			
		||||
    { .hs = 0, .he = 100, .rs = 0, .re = 0, .gs = 255, .ge = 255, .bs = 0, .be = 0, .ef = EF_NONE },
 | 
			
		||||
    { .end = 1 },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//Blue
 | 
			
		||||
led_setup_t leds_blue[] = {
 | 
			
		||||
    { .hs = 0, .he = 100, .rs = 0, .re = 0, .gs = 0, .ge = 0, .bs = 255, .be = 255, .ef = EF_NONE },
 | 
			
		||||
    { .end = 1 },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//White
 | 
			
		||||
led_setup_t leds_white[] = {
 | 
			
		||||
    { .hs = 0, .he = 100, .rs = 255, .re = 255, .gs = 255, .ge = 255, .bs = 255, .be = 255, .ef = EF_NONE },
 | 
			
		||||
    { .end = 1 },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//White with moving red stripe
 | 
			
		||||
led_setup_t leds_white_with_red_stripe[] = {
 | 
			
		||||
    { .hs = 0, .he = 100, .rs = 255, .re = 255, .gs = 255, .ge = 255, .bs = 255, .be = 255, .ef = EF_NONE },
 | 
			
		||||
    { .hs = 0, .he = 15, .rs = 0, .re = 0, .gs = 0, .ge = 255, .bs = 0, .be = 255, .ef = EF_SCR_R | EF_SUBTRACT },
 | 
			
		||||
    { .hs = 15, .he = 30, .rs = 0, .re = 0, .gs = 255, .ge = 0, .bs = 255, .be = 0, .ef = EF_SCR_R | EF_SUBTRACT },
 | 
			
		||||
    { .end = 1 },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//Black with moving red stripe
 | 
			
		||||
led_setup_t leds_black_with_red_stripe[] = {
 | 
			
		||||
    { .hs = 0, .he = 15, .rs = 0, .re = 255, .gs = 0, .ge = 0, .bs = 0, .be = 0, .ef = EF_SCR_R },
 | 
			
		||||
    { .hs = 15, .he = 30, .rs = 255, .re = 0, .gs = 0, .ge = 0, .bs = 0, .be = 0, .ef = EF_SCR_R },
 | 
			
		||||
    { .end = 1 },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//Rainbow no scrolling
 | 
			
		||||
led_setup_t leds_rainbow_ns[] = {
 | 
			
		||||
    { .hs = 0,      .he = 16.67,  .rs = 255, .re = 255, .gs = 0,   .ge = 255, .bs = 0,   .be = 0,   .ef = EF_OVER },
 | 
			
		||||
    { .hs = 16.67,  .he = 33.33,  .rs = 255, .re = 0,   .gs = 255, .ge = 255, .bs = 0,   .be = 0,   .ef = EF_OVER },
 | 
			
		||||
    { .hs = 33.33,  .he = 50,     .rs = 0,   .re = 0,   .gs = 255, .ge = 255, .bs = 0,   .be = 255, .ef = EF_OVER },
 | 
			
		||||
    { .hs = 50,     .he = 66.67,  .rs = 0,   .re = 0,   .gs = 255, .ge = 0,   .bs = 255, .be = 255, .ef = EF_OVER },
 | 
			
		||||
    { .hs = 66.67,  .he = 83.33,  .rs = 0,   .re = 255, .gs = 0,   .ge = 0,   .bs = 255, .be = 255, .ef = EF_OVER },
 | 
			
		||||
    { .hs = 83.33,  .he = 100,    .rs = 255, .re = 255, .gs = 0,   .ge = 0,   .bs = 255, .be = 0,   .ef = EF_OVER },
 | 
			
		||||
    { .end = 1 },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//Rainbow scrolling
 | 
			
		||||
led_setup_t leds_rainbow_s[] = {
 | 
			
		||||
    { .hs = 0,      .he = 16.67,  .rs = 255, .re = 255, .gs = 0,   .ge = 255, .bs = 0,   .be = 0,   .ef = EF_OVER | EF_SCR_R },
 | 
			
		||||
    { .hs = 16.67,  .he = 33.33,  .rs = 255, .re = 0,   .gs = 255, .ge = 255, .bs = 0,   .be = 0,   .ef = EF_OVER | EF_SCR_R },
 | 
			
		||||
    { .hs = 33.33,  .he = 50,     .rs = 0,   .re = 0,   .gs = 255, .ge = 255, .bs = 0,   .be = 255, .ef = EF_OVER | EF_SCR_R },
 | 
			
		||||
    { .hs = 50,     .he = 66.67,  .rs = 0,   .re = 0,   .gs = 255, .ge = 0,   .bs = 255, .be = 255, .ef = EF_OVER | EF_SCR_R },
 | 
			
		||||
    { .hs = 66.67,  .he = 83.33,  .rs = 0,   .re = 255, .gs = 0,   .ge = 0,   .bs = 255, .be = 255, .ef = EF_OVER | EF_SCR_R },
 | 
			
		||||
    { .hs = 83.33,  .he = 100,    .rs = 255, .re = 255, .gs = 0,   .ge = 0,   .bs = 255, .be = 0,   .ef = EF_OVER | EF_SCR_R },
 | 
			
		||||
    { .end = 1 },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//Add new LED animations here using one from above as example
 | 
			
		||||
//The last entry must be { .end = 1 }
 | 
			
		||||
//Add the new animation name to the list below following its format
 | 
			
		||||
 | 
			
		||||
void *led_setups[] = {
 | 
			
		||||
    leds_rainbow_s,
 | 
			
		||||
    leds_rainbow_ns,
 | 
			
		||||
    leds_teal_salmon,
 | 
			
		||||
    leds_yellow,
 | 
			
		||||
    leds_red,
 | 
			
		||||
    leds_green,
 | 
			
		||||
    leds_blue,
 | 
			
		||||
    leds_white,
 | 
			
		||||
    leds_white_with_red_stripe,
 | 
			
		||||
    leds_black_with_red_stripe,
 | 
			
		||||
    leds_off
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const uint8_t led_setups_count = sizeof(led_setups) / sizeof(led_setups[0]);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -203,13 +203,6 @@ void main_subtask_usb_state(void)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main_subtask_led(void)
 | 
			
		||||
{
 | 
			
		||||
    if (g_usb_state != USB_FSMSTATUS_FSMSTATE_ON_Val) return; //Only run LED tasks if USB is operating
 | 
			
		||||
 | 
			
		||||
    led_matrix_task();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main_subtask_power_check(void)
 | 
			
		||||
{
 | 
			
		||||
    static uint64_t next_5v_checkup = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -221,7 +214,9 @@ void main_subtask_power_check(void)
 | 
			
		|||
        v_5v = adc_get(ADC_5V);
 | 
			
		||||
        v_5v_avg = 0.9 * v_5v_avg + 0.1 * v_5v;
 | 
			
		||||
 | 
			
		||||
#ifdef RGB_MATRIX_ENABLE
 | 
			
		||||
        gcr_compute();
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -240,7 +235,6 @@ void main_subtask_usb_extra_device(void)
 | 
			
		|||
void main_subtasks(void)
 | 
			
		||||
{
 | 
			
		||||
    main_subtask_usb_state();
 | 
			
		||||
    main_subtask_led();
 | 
			
		||||
    main_subtask_power_check();
 | 
			
		||||
    main_subtask_usb_extra_device();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -263,7 +257,9 @@ int main(void)
 | 
			
		|||
 | 
			
		||||
    SR_EXP_Init();
 | 
			
		||||
 | 
			
		||||
#ifdef RGB_MATRIX_ENABLE
 | 
			
		||||
    i2c1_init();
 | 
			
		||||
#endif // RGB_MATRIX_ENABLE
 | 
			
		||||
 | 
			
		||||
    matrix_init();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -281,8 +277,7 @@ int main(void)
 | 
			
		|||
 | 
			
		||||
    DBG_LED_OFF;
 | 
			
		||||
 | 
			
		||||
    led_matrix_init();
 | 
			
		||||
 | 
			
		||||
#ifdef RGB_MATRIX_ENABLE
 | 
			
		||||
    while (I2C3733_Init_Control() != 1) {}
 | 
			
		||||
    while (I2C3733_Init_Drivers() != 1) {}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -292,6 +287,7 @@ int main(void)
 | 
			
		|||
 | 
			
		||||
    for (uint8_t drvid = 0; drvid < ISSI3733_DRIVER_COUNT; drvid++)
 | 
			
		||||
        I2C_LED_Q_ONOFF(drvid); //Queue data
 | 
			
		||||
#endif // RGB_MATRIX_ENABLE
 | 
			
		||||
 | 
			
		||||
    keyboard_setup();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -365,8 +365,10 @@ void USB_ExtraSetState(uint8_t state)
 | 
			
		|||
    if (usb_extra_state == USB_EXTRA_STATE_ENABLED) CDC_print("USB: Extra enabled\r\n");
 | 
			
		||||
    else if (usb_extra_state == USB_EXTRA_STATE_DISABLED)
 | 
			
		||||
    {
 | 
			
		||||
      CDC_print("USB: Extra disabled\r\n");
 | 
			
		||||
      if (led_animation_breathing) gcr_breathe = gcr_desired;
 | 
			
		||||
        CDC_print("USB: Extra disabled\r\n");
 | 
			
		||||
#ifdef USE_MASSDROP_CONFIGURATOR
 | 
			
		||||
        if (led_animation_breathing) gcr_breathe = gcr_desired;
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
    else if (usb_extra_state == USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG) CDC_print("USB: Extra disabled until replug\r\n");
 | 
			
		||||
    else CDC_print("USB: Extra state unknown\r\n");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue