@ -17,9 +17,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# include "arm_atsam_protocol.h"
# include "arm_atsam_protocol.h"
# include "tmk_core/common/led.h"
# include "tmk_core/common/led.h"
# include "rgb_matrix.h"
# include <string.h>
# include <string.h>
# include <math.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 )
void SERCOM1_0_Handler ( void )
{
{
if ( SERCOM1 - > I2CM . INTFLAG . bit . ERROR )
if ( SERCOM1 - > I2CM . INTFLAG . bit . ERROR )
@ -51,14 +61,17 @@ void DMAC_0_Handler( void )
issi3733_driver_t issidrv [ ISSI3733_DRIVER_COUNT ] ;
issi3733_driver_t issidrv [ ISSI3733_DRIVER_COUNT ] ;
issi3733_led_t led_map [ ISSI3733_LED_COUNT + 1 ] = ISSI3733_LED_MAP ;
issi3733_led_t led_map [ ISSI3733_LED_COUNT ] = ISSI3733_LED_MAP ;
issi3733_led_t * lede = led_map + ISSI3733_LED_COUNT ; //End pointer of mapping
RGB led_buffer [ ISSI3733_LED_COUNT ] ;
uint8_t gcr_desired ;
uint8_t gcr_desired ;
uint8_t gcr_breathe ;
uint8_t gcr_use ;
uint8_t gcr_actual ;
uint8_t gcr_actual ;
uint8_t gcr_actual_last ;
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_NONE 0
# define ACT_GCR_INC 1
# define ACT_GCR_INC 1
@ -73,11 +86,14 @@ static uint8_t v_5v_cat_hit;
void gcr_compute ( void )
void gcr_compute ( void )
{
{
uint8_t action = ACT_GCR_NONE ;
uint8_t action = ACT_GCR_NONE ;
uint8_t gcr_use = gcr_desired ;
# ifdef USE_MASSDROP_CONFIGURATOR
if ( led_animation_breathing )
if ( led_animation_breathing )
{
gcr_use = gcr_breathe ;
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 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 )
if ( v_5v < V5_CAT )
@ -151,6 +167,7 @@ void gcr_compute(void)
gcr_actual - = LED_GCR_STEP_AUTO ;
gcr_actual - = LED_GCR_STEP_AUTO ;
gcr_min_counter = 0 ;
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
//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
//So set the breathe GCR to where it becomes stable
if ( led_animation_breathing = = 1 )
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
// 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
// powering through one full breathe and letting gcr settle completely
}
}
# endif
}
}
}
}
}
}
led_disp_t disp ;
void issi3733_prepare_arrays ( void )
void issi3733_prepare_arrays ( void )
{
{
memset ( issidrv , 0 , sizeof ( issi3733_driver_t ) * ISSI3733_DRIVER_COUNT ) ;
memset ( issidrv , 0 , sizeof ( issi3733_driver_t ) * ISSI3733_DRIVER_COUNT ) ;
@ -178,361 +194,309 @@ void issi3733_prepare_arrays(void)
issidrv [ i ] . addr = addrs [ i ] ;
issidrv [ i ] . addr = addrs [ i ] ;
}
}
issi3733_led_t * cur = led_map ;
for ( uint8_t i = 0 ; i < ISSI3733_LED_COUNT ; i + + )
while ( cur < lede )
{
{
//BYTE: 1 + (SW-1)*16 + (CS-1)
//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 ) ) ;
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 ) ) ;
cur- > rgb . r = issidrv [ cur - > adr . drv - 1 ] . pwm + 1 + ( ( cur- > adr . swr - 1 ) * 16 + ( cur- > 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 ) ) ;
cur- > rgb . b = issidrv [ cur - > adr . drv - 1 ] . pwm + 1 + ( ( cur- > adr . swb - 1 ) * 16 + ( cur- > 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
//BYTE: 1 + (SW-1)*2 + (CS-1)/8
//BIT: (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 [ 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 [ cur - > adr . drv - 1 ] . onoff + 1 + ( cur - > adr . swr - 1 ) * 2 + ( cur - > adr . cs - 1 ) / 8 ) | = ( 1 < < ( ( cur - > 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 [ cur - > adr . drv - 1 ] . onoff + 1 + ( cur - > adr . swb - 1 ) * 2 + ( cur - > adr . cs - 1 ) / 8 ) | = ( 1 < < ( ( cur - > 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 ) ) ;
cur + + ;
}
}
}
}
void disp_calc_extents ( void )
void led_matrix_prepare ( void )
{
{
issi3733_led_t * cur = led_map ;
for ( uint8_t i = 0 ; i < ISSI3733_LED_COUNT ; i + + )
disp . left = 1e10 ;
disp . right = - 1e10 ;
disp . top = - 1e10 ;
disp . bottom = 1e10 ;
while ( cur < lede )
{
{
if ( cur - > x < disp . left ) disp . left = cur - > x ;
* led_map [ i ] . rgb . r = 0 ;
if ( cur - > x > disp . right ) disp . right = cur - > x ;
* led_map [ i ] . rgb . g = 0 ;
if ( cur - > y < disp . bottom ) disp . bottom = cur - > y ;
* led_map [ i ] . rgb . b = 0 ;
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 )
void led_set_one ( int i , uint8_t r , uint8_t g , uint8_t b )
{
{
issi3733_led_t * cur = led_map ;
if ( i < ISSI3733_LED_COUNT )
while ( cur < lede )
{
{
cur - > px = ( cur - > x - disp . left ) / disp . width * 100 ;
# ifdef USE_MASSDROP_CONFIGURATOR
cur - > py = ( cur - > y - disp . bottom ) / disp . height * 100 ;
led_matrix_massdrop_config_override ( i ) ;
* cur - > rgb . r = 0 ;
# else
* cur - > rgb . g = 0 ;
led_buffer [ i ] . r = r ;
* cur - > rgb . b = 0 ;
led_buffer [ i ] . g = g ;
led_buffer [ i ] . b = b ;
cur + + ;
# endif
}
}
}
}
void led_ matrix_prepare( void )
void led_ set_all( uint8_t r , uint8_t g , uint8_t b )
{
{
disp_calc_extents ( ) ;
for ( uint8_t i = 0 ; i < ISSI3733_LED_COUNT ; i + + )
disp_pixel_setup ( ) ;
{
led_set_one ( i , r , g , b ) ;
}
}
}
uint8_t led_enabled ;
void init ( void )
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 )
{
{
float ro ;
DBGC ( DC_LED_MATRIX_INIT_BEGIN ) ;
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 ;
disp . frame + = 1 ;
issi3733_prepare_arrays ( ) ;
breathe_mult = 1 ;
led_matrix_prepare ( ) ;
if ( led_animation_breathing )
gcr_min_counter = 0 ;
{
v_5v_cat_hit = 0 ;
led_animation_breathe_cur + = breathe_step * breathe_dir ;
if ( led_animation_breathe_cur > = BREATHE_MAX_STEP )
DBGC ( DC_LED_MATRIX_INIT_COMPLETE ) ;
breathe_dir = - 1 ;
}
else if ( led_animation_breathe_cur < = BREATHE_MIN_STEP )
breathe_dir = 1 ;
//Brightness curve created for 256 steps, 0 - ~98%
void flush ( void )
breathe_mult = 0.000015 * led_animation_breathe_cur * led_animation_breathe_cur ;
{
if ( breathe_mult > 1 ) breathe_mult = 1 ;
# ifdef USE_MASSDROP_CONFIGURATOR
else if ( breathe_mult < 0 ) breathe_mult = 0 ;
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 ;
// Wait for previous transfer to complete
uint8_t fmax = 0 ;
while ( i2c_led_q_running ) { }
// Frames setup
// Copy buffer to live DMA region
while ( f [ fcur ] . end ! = 1 )
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 ;
//+60us 119 LED
go = 0 ;
led_animation_breathe_cur + = BREATHE_STEP * breathe_dir ;
bo = 0 ;
if ( led_animation_breathe_cur > = BREATHE_MAX_STEP )
if ( led_lighting_mode = = LED_MODE_KEYS_ONLY & & led_cur - > scan = = 255 )
breathe_dir = - 1 ;
{
else if ( led_animation_breathe_cur < = BREATHE_MIN_STEP )
//Do not act on this LED
breathe_dir = 1 ;
}
else if ( led_lighting_mode = = LED_MODE_NON_KEYS_ONLY & & led_cur - > scan ! = 255 )
//Brightness curve created for 256 steps, 0 - ~98%
{
breathe_mult = 0.000015 * led_animation_breathe_cur * led_animation_breathe_cur ;
//Do not act on this LED
if ( breathe_mult > 1 ) breathe_mult = 1 ;
}
else if ( breathe_mult < 0 ) breathe_mult = 0 ;
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 ;
}
//Check if LED's po is in current frame
//This should only be performed once per frame
if ( po < f [ fcur ] . hs ) continue ;
pomod = ( float ) ( ( g_rgb_counters . tick / 10 ) % ( uint32_t ) ( 1000.0f / led_animation_speed ) ) / 10.0f * led_animation_speed ;
if ( po > f [ fcur ] . he ) continue ;
pomod * = 100.0f ;
//note: < 0 or > 100 continue
pomod = ( uint32_t ) pomod % 10000 ;
pomod / = 100.0f ;
//Calculate the po within the start-stop percentage for color blending
# endif // USE_MASSDROP_CONFIGURATOR
po = ( po - f [ fcur ] . hs ) / ( f [ fcur ] . he - f [ fcur ] . hs ) ;
//Add in any color effects
uint8_t drvid ;
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;
}
}
}
//Clamp values 0-255
//NOTE: GCR does not need to be timed with LED processing, but there is really no harm
if ( ro > 255 ) ro = 255 ; else if ( ro < 0 ) ro = 0 ;
if ( gcr_actual ! = gcr_actual_last )
if ( go > 255 ) go = 255 ; else if ( go < 0 ) go = 0 ;
{
if ( bo > 255 ) bo = 255 ; else if ( bo < 0 ) bo = 0 ;
for ( drvid = 0 ; drvid < ISSI3733_DRIVER_COUNT ; drvid + + )
I2C_LED_Q_GCR ( drvid ) ; //Queue data
gcr_actual_last = gcr_actual ;
}
if ( led_animation_breathing )
for ( drvid = 0 ; drvid < ISSI3733_DRIVER_COUNT ; drvid + + )
{
I2C_LED_Q_PWM ( drvid ) ; //Queue data
ro * = breathe_mult ;
go * = breathe_mult ;
bo * = breathe_mult ;
}
* led_cur - > rgb . r = ( uint8_t ) ro ;
i2c_led_q_run ( ) ;
* led_cur - > rgb . g = ( uint8_t ) go ;
}
* led_cur - > rgb . b = ( uint8_t ) bo ;
# ifdef USB_LED_INDICATOR_ENABLE
void led_matrix_indicators ( void )
if ( keyboard_leds ( ) )
{
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 (
# if USB_LED_NUM_LOCK_SCANCODE != 255
# if USB_LED_NUM_LOCK_SCANCODE != 255
( led_ cur- > scan = = USB_LED_NUM_LOCK_SCANCODE & & kbled & ( 1 < < USB_LED_NUM_LOCK ) ) | |
( led_map [ i ] . scan = = USB_LED_NUM_LOCK_SCANCODE & & ( kbled & ( 1 < < USB_LED_NUM_LOCK ) ) ) | |
# endif //NUM LOCK
# endif //NUM LOCK
# if USB_LED_CAPS_LOCK_SCANCODE != 255
# if USB_LED_CAPS_LOCK_SCANCODE != 255
( led_ cur- > scan = = USB_LED_CAPS_LOCK_SCANCODE & & kbled & ( 1 < < USB_LED_CAPS_LOCK ) ) | |
( led_map [ i ] . scan = = USB_LED_CAPS_LOCK_SCANCODE & & ( kbled & ( 1 < < USB_LED_CAPS_LOCK ) ) ) | |
# endif //CAPS LOCK
# endif //CAPS LOCK
# if USB_LED_SCROLL_LOCK_SCANCODE != 255
# if USB_LED_SCROLL_LOCK_SCANCODE != 255
( led_ cur- > scan = = USB_LED_SCROLL_LOCK_SCANCODE & & kbled & ( 1 < < USB_LED_SCROLL_LOCK ) ) | |
( led_map [ i ] . scan = = USB_LED_SCROLL_LOCK_SCANCODE & & ( kbled & ( 1 < < USB_LED_SCROLL_LOCK ) ) ) | |
# endif //SCROLL LOCK
# endif //SCROLL LOCK
# if USB_LED_COMPOSE_SCANCODE != 255
# if USB_LED_COMPOSE_SCANCODE != 255
( led_ cur- > scan = = USB_LED_COMPOSE_SCANCODE & & kbled & ( 1 < < USB_LED_COMPOSE ) ) | |
( led_map [ i ] . scan = = USB_LED_COMPOSE_SCANCODE & & ( kbled & ( 1 < < USB_LED_COMPOSE ) ) ) | |
# endif //COMPOSE
# endif //COMPOSE
# if USB_LED_KANA_SCANCODE != 255
# if USB_LED_KANA_SCANCODE != 255
( led_ cur- > scan = = USB_LED_KANA_SCANCODE & & kbled & ( 1 < < USB_LED_KANA ) ) | |
( led_map [ i ] . scan = = USB_LED_KANA_SCANCODE & & ( kbled & ( 1 < < USB_LED_KANA ) ) ) | |
# endif //KANA
# endif //KANA
( 0 ) )
( 0 ) )
{
{
if ( * led_cur - > rgb . r > 127 ) * led_cur - > rgb . r = 0 ;
led_buffer [ i ] . r = 255 - led_buffer [ i ] . r ;
else * led_cur - > rgb . r = 255 ;
led_buffer [ i ] . g = 255 - led_buffer [ i ] . g ;
if ( * led_cur - > rgb . g > 127 ) * led_cur - > rgb . g = 0 ;
led_buffer [ i ] . b = 255 - led_buffer [ i ] . b ;
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 ( ) ;
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 ;
//Add in any moving effects
led_next_run = 0 ;
if ( ( ! led_animation_direction & & f - > ef & EF_SCR_R ) | | ( led_animation_direction & & ( f - > ef & EF_SCR_L ) ) )
{
led_enabled = 1 ;
po - = pomod ;
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 ;
if ( po > 100 ) po - = 100 ;
v_5v_cat_hit = 0 ;
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
if ( po > 100 ) po - = 100 ;
led_cur = 0 ;
else if ( po < 0 ) po + = 100 ;
rgb_matrix_init_user ( ) ;
}
led_matrix_run ( ) ;
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 ) )
//Add in any color effects
void rgb_matrix_init_user ( void ) {
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
static void led_matrix_massdrop_config_override ( int i )
//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 )
float ro = 0 ;
{
float go = 0 ;
//If an update may run and frame processing has completed
float bo = 0 ;
if ( timer_read64 ( ) > = led_next_run & & led_cur = = lede )
{
float po = ( led_animation_orientation )
uint8_t drvid ;
? ( 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 ( led_cur_instruction - > flags & LED_FLAG_USE_RGB ) {
if ( gcr_actual ! = gcr_actual_last )
ro = led_cur_instruction - > r ;
{
go = led_cur_instruction - > g ;
for ( drvid = 0 ; drvid < ISSI3733_DRIVER_COUNT ; drvid + + )
bo = led_cur_instruction - > b ;
I2C_LED_Q_GCR ( drvid ) ; //Queue data
} else if ( led_cur_instruction - > flags & LED_FLAG_USE_PATTERN ) {
gcr_actual_last = gcr_actual ;
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 + + )
next_iter :
I2C_LED_Q_PWM ( drvid ) ; //Queue data
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
led_buffer [ i ] . r = ( uint8_t ) ro ;
if ( led_cur ! = lede )
led_buffer [ i ] . g = ( uint8_t ) go ;
{
led_buffer [ i ] . b = ( uint8_t ) bo ;
//DBG_1_OFF; //debug profiling
led_matrix_run ( ) ;
//DBG_1_ON; //debug profiling
}
}
}
# endif // USE_MASSDROP_CONFIGURATOR