forked from mirror/qmk_firmware
CTRL (arm_atsam) support user-defined LED instructions (#2)
* CTRL (arm_atsam) support user-defined LED instructions * ok, layer matching works now * Bitwise LED ID to reduce number of instructions (performance) * Use 32-bit ints to be more compatible with generation in JS * TYpo
This commit is contained in:
committed by
GitHub
parent
1a907a1627
commit
5fb9b45481
@@ -200,4 +200,16 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
|||||||
default:
|
default:
|
||||||
return true; //Process all other keycodes normally
|
return true; //Process all other keycodes normally
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
led_instruction_t led_instructions[] = {
|
||||||
|
// { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 10, .id1 = 9, .r = 255, .g = 0, .b = 0 },
|
||||||
|
// { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_PATTERN, .id0 = 4, .id1 = 0, .pattern_id = 8 },
|
||||||
|
// { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 8, .id1 = 0, .r = 0, .g = 255, .b = 0 },
|
||||||
|
// { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_PATTERN, .id = 16, .id1 = 0, .pattern_id = 9 },
|
||||||
|
// { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 32, .id1 = 0, .r = 0, .g = 0, .b = 255 },
|
||||||
|
// { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_ROTATE_PATTERN, .id0 = 64, .id1 = 0},
|
||||||
|
// { .flags = LED_FLAG_MATCH_ID | LED_FLAG_MATCH_LAYER | LED_FLAG_USE_ROTATE_PATTERN, .id0 = 262144, .id1 = 0, .layer = 0 },
|
||||||
|
// { .flags = LED_FLAG_MATCH_ID | LED_FLAG_MATCH_LAYER | LED_FLAG_USE_ROTATE_PATTERN, .id = 16777216, .id1 = 0, .layer = 1 },
|
||||||
|
{ .end = 1 }
|
||||||
|
};
|
||||||
@@ -257,12 +257,87 @@ issi3733_led_t *led_cur;
|
|||||||
uint8_t led_per_run = 15;
|
uint8_t led_per_run = 15;
|
||||||
float breathe_mult;
|
float breathe_mult;
|
||||||
|
|
||||||
|
void led_run_pattern(led_setup_t *f, float* ro, float* go, float* bo) {
|
||||||
|
float px;
|
||||||
|
|
||||||
|
uint8_t fcur = 0;
|
||||||
|
uint8_t fmax = 0;
|
||||||
|
|
||||||
|
//Frames setup
|
||||||
|
while (f[fcur].end != 1)
|
||||||
|
{
|
||||||
|
fcur++; //Count frames
|
||||||
|
}
|
||||||
|
|
||||||
|
fmax = fcur; //Store total frames count
|
||||||
|
|
||||||
|
for (fcur = 0; fcur < fmax; fcur++)
|
||||||
|
{
|
||||||
|
px = led_cur->px;
|
||||||
|
float pxmod;
|
||||||
|
pxmod = (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)))
|
||||||
|
{
|
||||||
|
pxmod *= 100.0f;
|
||||||
|
pxmod = (uint32_t)pxmod % 10000;
|
||||||
|
pxmod /= 100.0f;
|
||||||
|
|
||||||
|
px -= pxmod;
|
||||||
|
|
||||||
|
if (px > 100) px -= 100;
|
||||||
|
else if (px < 0) px += 100;
|
||||||
|
}
|
||||||
|
else if ((!led_animation_direction && f[fcur].ef & EF_SCR_L) || (led_animation_direction && (f[fcur].ef & EF_SCR_R)))
|
||||||
|
{
|
||||||
|
pxmod *= 100.0f;
|
||||||
|
pxmod = (uint32_t)pxmod % 10000;
|
||||||
|
pxmod /= 100.0f;
|
||||||
|
px += pxmod;
|
||||||
|
|
||||||
|
if (px > 100) px -= 100;
|
||||||
|
else if (px < 0) px += 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check if LED's px is in current frame
|
||||||
|
if (px < f[fcur].hs) continue;
|
||||||
|
if (px > f[fcur].he) continue;
|
||||||
|
//note: < 0 or > 100 continue
|
||||||
|
|
||||||
|
//Calculate the px within the start-stop percentage for color blending
|
||||||
|
px = (px - f[fcur].hs) / (f[fcur].he - f[fcur].hs);
|
||||||
|
|
||||||
|
//Add in any color effects
|
||||||
|
if (f[fcur].ef & EF_OVER)
|
||||||
|
{
|
||||||
|
*ro = (px * (f[fcur].re - f[fcur].rs)) + f[fcur].rs;// + 0.5;
|
||||||
|
*go = (px * (f[fcur].ge - f[fcur].gs)) + f[fcur].gs;// + 0.5;
|
||||||
|
*bo = (px * (f[fcur].be - f[fcur].bs)) + f[fcur].bs;// + 0.5;
|
||||||
|
}
|
||||||
|
else if (f[fcur].ef & EF_SUBTRACT)
|
||||||
|
{
|
||||||
|
*ro -= (px * (f[fcur].re - f[fcur].rs)) + f[fcur].rs;// + 0.5;
|
||||||
|
*go -= (px * (f[fcur].ge - f[fcur].gs)) + f[fcur].gs;// + 0.5;
|
||||||
|
*bo -= (px * (f[fcur].be - f[fcur].bs)) + f[fcur].bs;// + 0.5;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*ro += (px * (f[fcur].re - f[fcur].rs)) + f[fcur].rs;// + 0.5;
|
||||||
|
*go += (px * (f[fcur].ge - f[fcur].gs)) + f[fcur].gs;// + 0.5;
|
||||||
|
*bo += (px * (f[fcur].be - f[fcur].bs)) + f[fcur].bs;// + 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((weak))
|
||||||
|
led_instruction_t led_instructions[] = { { .end = 1 } };
|
||||||
|
|
||||||
void led_matrix_run(led_setup_t *f)
|
void led_matrix_run(led_setup_t *f)
|
||||||
{
|
{
|
||||||
float ro;
|
float ro;
|
||||||
float go;
|
float go;
|
||||||
float bo;
|
float bo;
|
||||||
float px;
|
|
||||||
uint8_t led_this_run = 0;
|
uint8_t led_this_run = 0;
|
||||||
|
|
||||||
if (led_cur == 0) //Denotes start of new processing cycle in the case of chunked processing
|
if (led_cur == 0) //Denotes start of new processing cycle in the case of chunked processing
|
||||||
@@ -289,17 +364,6 @@ void led_matrix_run(led_setup_t *f)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
while (led_cur < lede && led_this_run < led_per_run)
|
||||||
{
|
{
|
||||||
ro = 0;
|
ro = 0;
|
||||||
@@ -320,62 +384,72 @@ void led_matrix_run(led_setup_t *f)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
led_instruction_t *led_cur_instruction;
|
||||||
|
led_cur_instruction = led_instructions;
|
||||||
|
|
||||||
//Act on LED
|
//Act on LED
|
||||||
for (fcur = 0; fcur < fmax; fcur++)
|
if (led_cur_instruction->end) {
|
||||||
{
|
// If no instructions, use normal pattern
|
||||||
px = led_cur->px;
|
led_run_pattern(f, &ro, &go, &bo);
|
||||||
float pxmod;
|
} else {
|
||||||
pxmod = (float)(disp.frame % (uint32_t)(1000.0f / led_animation_speed)) / 10.0f * led_animation_speed;
|
uint8_t skip;
|
||||||
|
|
||||||
//Add in any moving effects
|
while (!led_cur_instruction->end) {
|
||||||
if ((!led_animation_direction && f[fcur].ef & EF_SCR_R) || (led_animation_direction && (f[fcur].ef & EF_SCR_L)))
|
skip = 0;
|
||||||
{
|
|
||||||
pxmod *= 100.0f;
|
|
||||||
pxmod = (uint32_t)pxmod % 10000;
|
|
||||||
pxmod /= 100.0f;
|
|
||||||
|
|
||||||
px -= pxmod;
|
if (led_cur_instruction->flags & LED_FLAG_MATCH_ID) {
|
||||||
|
if (
|
||||||
|
led_cur_instruction->id0 == 0 &&
|
||||||
|
led_cur_instruction->id1 == 0 &&
|
||||||
|
led_cur_instruction->id2 == 0 &&
|
||||||
|
led_cur_instruction->id3 == 0 &&
|
||||||
|
led_cur->id == 0
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
} else if (
|
||||||
|
(0 <= led_cur->id && led_cur->id <= 31) &&
|
||||||
|
(~led_cur_instruction->id0 & ((uint32_t) 1UL << led_cur->id))
|
||||||
|
) {
|
||||||
|
skip = 1;
|
||||||
|
} else if (
|
||||||
|
(32 <= led_cur->id && led_cur->id <= 63) &&
|
||||||
|
(~led_cur_instruction->id1 & ((uint32_t) 1UL << (led_cur->id - 32)))
|
||||||
|
) {
|
||||||
|
skip = 1;
|
||||||
|
} else if (
|
||||||
|
(64 <= led_cur->id && led_cur->id <= 95) &&
|
||||||
|
(~led_cur_instruction->id2 & ((uint32_t) 1UL << (led_cur->id - 64)))
|
||||||
|
) {
|
||||||
|
skip = 1;
|
||||||
|
} else if (
|
||||||
|
(96 <= led_cur->id && led_cur->id <= 127) &&
|
||||||
|
(~led_cur_instruction->id3 & ((uint32_t) 1UL << (led_cur->id - 96)))
|
||||||
|
) {
|
||||||
|
skip = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (px > 100) px -= 100;
|
if (led_cur_instruction->flags & LED_FLAG_MATCH_LAYER) {
|
||||||
else if (px < 0) px += 100;
|
if (layer_state == 0 && led_cur_instruction->layer == 0) {
|
||||||
}
|
//
|
||||||
else if ((!led_animation_direction && f[fcur].ef & EF_SCR_L) || (led_animation_direction && (f[fcur].ef & EF_SCR_R)))
|
} else if (~layer_state & (1UL << led_cur_instruction->layer)) {
|
||||||
{
|
skip = 1;
|
||||||
pxmod *= 100.0f;
|
}
|
||||||
pxmod = (uint32_t)pxmod % 10000;
|
}
|
||||||
pxmod /= 100.0f;
|
|
||||||
px += pxmod;
|
|
||||||
|
|
||||||
if (px > 100) px -= 100;
|
if (!skip) {
|
||||||
else if (px < 0) px += 100;
|
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);
|
||||||
|
} else if (led_cur_instruction->flags & LED_FLAG_USE_ROTATE_PATTERN) {
|
||||||
|
led_run_pattern(f, &ro, &go, &bo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Check if LED's px is in current frame
|
led_cur_instruction++;
|
||||||
if (px < f[fcur].hs) continue;
|
|
||||||
if (px > f[fcur].he) continue;
|
|
||||||
//note: < 0 or > 100 continue
|
|
||||||
|
|
||||||
//Calculate the px within the start-stop percentage for color blending
|
|
||||||
px = (px - f[fcur].hs) / (f[fcur].he - f[fcur].hs);
|
|
||||||
|
|
||||||
//Add in any color effects
|
|
||||||
if (f[fcur].ef & EF_OVER)
|
|
||||||
{
|
|
||||||
ro = (px * (f[fcur].re - f[fcur].rs)) + f[fcur].rs;// + 0.5;
|
|
||||||
go = (px * (f[fcur].ge - f[fcur].gs)) + f[fcur].gs;// + 0.5;
|
|
||||||
bo = (px * (f[fcur].be - f[fcur].bs)) + f[fcur].bs;// + 0.5;
|
|
||||||
}
|
|
||||||
else if (f[fcur].ef & EF_SUBTRACT)
|
|
||||||
{
|
|
||||||
ro -= (px * (f[fcur].re - f[fcur].rs)) + f[fcur].rs;// + 0.5;
|
|
||||||
go -= (px * (f[fcur].ge - f[fcur].gs)) + f[fcur].gs;// + 0.5;
|
|
||||||
bo -= (px * (f[fcur].be - f[fcur].bs)) + f[fcur].bs;// + 0.5;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ro += (px * (f[fcur].re - f[fcur].rs)) + f[fcur].rs;// + 0.5;
|
|
||||||
go += (px * (f[fcur].ge - f[fcur].gs)) + f[fcur].gs;// + 0.5;
|
|
||||||
bo += (px * (f[fcur].be - f[fcur].bs)) + f[fcur].bs;// + 0.5;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,6 +112,28 @@ typedef struct led_setup_s {
|
|||||||
uint8_t end; //Set to signal end of the setup
|
uint8_t end; //Set to signal end of the setup
|
||||||
} led_setup_t;
|
} led_setup_t;
|
||||||
|
|
||||||
|
//LED Extra Instructions
|
||||||
|
#define LED_FLAG_NULL 0x00
|
||||||
|
#define LED_FLAG_MATCH_ID 0x01
|
||||||
|
#define LED_FLAG_MATCH_LAYER 0x02
|
||||||
|
#define LED_FLAG_USE_RGB 0x10
|
||||||
|
#define LED_FLAG_USE_PATTERN 0x20
|
||||||
|
#define LED_FLAG_USE_ROTATE_PATTERN 0x40
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
extern issi3733_driver_t issidrv[ISSI3733_DRIVER_COUNT];
|
extern issi3733_driver_t issidrv[ISSI3733_DRIVER_COUNT];
|
||||||
|
|
||||||
extern uint8_t gcr_desired;
|
extern uint8_t gcr_desired;
|
||||||
@@ -130,6 +152,9 @@ extern uint8_t breathe_dir;
|
|||||||
extern const uint8_t led_setups_count;
|
extern const uint8_t led_setups_count;
|
||||||
|
|
||||||
extern void *led_setups[];
|
extern void *led_setups[];
|
||||||
|
extern led_instruction_t led_instructions[];
|
||||||
|
|
||||||
|
extern uint32_t layer_state;
|
||||||
|
|
||||||
extern issi3733_led_t *led_cur;
|
extern issi3733_led_t *led_cur;
|
||||||
extern issi3733_led_t *lede;
|
extern issi3733_led_t *lede;
|
||||||
|
|||||||
Reference in New Issue
Block a user