Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CTRL (arm_atsam) support user-defined LED instructions #2

Merged
merged 5 commits into from
Sep 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion keyboards/massdrop/ctrl/keymaps/default/keymap.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,4 +200,16 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
default:
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 }
};
202 changes: 138 additions & 64 deletions tmk_core/protocol/arm_atsam/led_matrix.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,12 +257,87 @@ issi3733_led_t *led_cur;
uint8_t led_per_run = 15;
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)
{
float ro;
float go;
float bo;
float px;
uint8_t led_this_run = 0;

if (led_cur == 0) //Denotes start of new processing cycle in the case of chunked processing
Expand All @@ -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)
{
ro = 0;
Expand All @@ -320,62 +384,72 @@ void led_matrix_run(led_setup_t *f)
}
else
{
//Act on LED
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;
led_instruction_t *led_cur_instruction;
led_cur_instruction = led_instructions;

//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;
}
//Act on LED
if (led_cur_instruction->end) {
// If no instructions, use normal pattern
led_run_pattern(f, &ro, &go, &bo);
} else {
uint8_t skip;

while (!led_cur_instruction->end) {
skip = 0;

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;
}
}

//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
if (led_cur_instruction->flags & LED_FLAG_MATCH_LAYER) {
if (layer_state == 0 && led_cur_instruction->layer == 0) {
//
} else if (~layer_state & (1UL << led_cur_instruction->layer)) {
skip = 1;
}
}

//Calculate the px within the start-stop percentage for color blending
px = (px - f[fcur].hs) / (f[fcur].he - f[fcur].hs);
if (!skip) {
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);
}
}

//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;
led_cur_instruction++;
}
}
}
Expand Down
25 changes: 25 additions & 0 deletions tmk_core/protocol/arm_atsam/led_matrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,28 @@ typedef struct led_setup_s {
uint8_t end; //Set to signal end of the setup
} 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 uint8_t gcr_desired;
Expand All @@ -130,6 +152,9 @@ extern uint8_t breathe_dir;
extern const uint8_t led_setups_count;

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 *lede;
Expand Down