136 lines
3.9 KiB
C
136 lines
3.9 KiB
C
#include <malloc.h>
|
|
|
|
#include "logger.h"
|
|
#include "utils.h"
|
|
#include "sk6812.h"
|
|
|
|
#include "fader.h"
|
|
|
|
int fader_init(struct fader_ctx *ctx, uint32_t nMod, struct sk6812_ctx *ledCtx)
|
|
{
|
|
ctx->num_modules = nMod;
|
|
ctx->fadestep = 1;
|
|
|
|
ctx->cur_colour = malloc(nMod * sizeof(struct fader_colour));
|
|
if(!ctx->cur_colour) {
|
|
LOG(LVL_ERR, "fader: could not allocate the array of current colours!");
|
|
return -1;
|
|
}
|
|
|
|
ctx->target_colour = malloc(nMod * sizeof(struct fader_colour));
|
|
if(!ctx->target_colour) {
|
|
LOG(LVL_ERR, "fader: could not allocate the array of target colours!");
|
|
return -1;
|
|
}
|
|
|
|
for(uint32_t i = 0; i < ctx->num_modules; i++) {
|
|
ctx->cur_colour[i].red = ctx->target_colour[i].red = 0;
|
|
ctx->cur_colour[i].green = ctx->target_colour[i].green = 0;
|
|
ctx->cur_colour[i].blue = ctx->target_colour[i].blue = 0;
|
|
ctx->cur_colour[i].white = ctx->target_colour[i].white = 0;
|
|
}
|
|
|
|
// store LED context (initalized externally)
|
|
ctx->led_ctx = ledCtx;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void fader_shutdown(struct fader_ctx *ctx)
|
|
{
|
|
free(ctx->cur_colour);
|
|
free(ctx->target_colour);
|
|
}
|
|
|
|
void fader_set_colour(struct fader_ctx *ctx, uint32_t module, uint8_t r, uint8_t g, uint8_t b, uint8_t w)
|
|
{
|
|
ctx->cur_colour[module].red = ctx->target_colour[module].red = r;
|
|
ctx->cur_colour[module].green = ctx->target_colour[module].green = g;
|
|
ctx->cur_colour[module].blue = ctx->target_colour[module].blue = b;
|
|
ctx->cur_colour[module].white = ctx->target_colour[module].white = w;
|
|
|
|
ctx->something_changed = 1;
|
|
}
|
|
|
|
void fader_fade_colour(struct fader_ctx *ctx, uint32_t module, uint8_t r, uint8_t g, uint8_t b, uint8_t w)
|
|
{
|
|
ctx->target_colour[module].red = r;
|
|
ctx->target_colour[module].green = g;
|
|
ctx->target_colour[module].blue = b;
|
|
ctx->target_colour[module].white = w;
|
|
}
|
|
|
|
void fader_add_colour(struct fader_ctx *ctx, uint32_t module, uint8_t r, uint8_t g, uint8_t b, uint8_t w)
|
|
{
|
|
ctx->cur_colour[module].red += r;
|
|
ctx->cur_colour[module].green += g;
|
|
ctx->cur_colour[module].blue += b;
|
|
ctx->cur_colour[module].white += w;
|
|
|
|
if(ctx->cur_colour[module].red > 255) { ctx->cur_colour[module].red = 255; }
|
|
if(ctx->cur_colour[module].green > 255) { ctx->cur_colour[module].green = 255; }
|
|
if(ctx->cur_colour[module].blue > 255) { ctx->cur_colour[module].blue = 255; }
|
|
if(ctx->cur_colour[module].white > 255) { ctx->cur_colour[module].white = 255; }
|
|
|
|
ctx->target_colour[module] = ctx->cur_colour[module];
|
|
|
|
ctx->something_changed = 1;
|
|
}
|
|
|
|
void fader_set_fadestep(struct fader_ctx *ctx, uint8_t newFadestep)
|
|
{
|
|
ctx->fadestep = newFadestep;
|
|
}
|
|
|
|
/*!
|
|
* Fade the colour value in cur towards target.
|
|
*
|
|
* \param cur The colour value to update.
|
|
* \param target The target value that should be reached.
|
|
* \param changed Output value which is set to 1 if cur was changed.
|
|
*/
|
|
void fade_colour(struct fader_ctx *ctx, float *cur, const float *target, uint8_t *changed)
|
|
{
|
|
float diff;
|
|
if(*cur > *target) {
|
|
diff = *cur - *target;
|
|
if(diff < ctx->fadestep) {
|
|
*cur = *target;
|
|
} else {
|
|
*cur -= ctx->fadestep;
|
|
}
|
|
|
|
*changed = 1;
|
|
} else if(*cur < *target) {
|
|
diff = *target - *cur;
|
|
if(diff < ctx->fadestep) {
|
|
*cur = *target;
|
|
} else {
|
|
*cur += ctx->fadestep;
|
|
}
|
|
|
|
*changed = 1;
|
|
}
|
|
}
|
|
|
|
void fader_update(struct fader_ctx *ctx)
|
|
{
|
|
for(uint32_t i = 0; i < ctx->num_modules; i++) {
|
|
fade_colour(ctx, &(ctx->cur_colour[i].red), &(ctx->target_colour[i].red), &ctx->something_changed);
|
|
fade_colour(ctx, &(ctx->cur_colour[i].green), &(ctx->target_colour[i].green), &ctx->something_changed);
|
|
fade_colour(ctx, &(ctx->cur_colour[i].blue), &(ctx->target_colour[i].blue), &ctx->something_changed);
|
|
fade_colour(ctx, &(ctx->cur_colour[i].white), &(ctx->target_colour[i].white), &ctx->something_changed);
|
|
|
|
sk6812_set_colour(ctx->led_ctx, i,
|
|
(uint8_t)ctx->cur_colour[i].red,
|
|
(uint8_t)ctx->cur_colour[i].green,
|
|
(uint8_t)ctx->cur_colour[i].blue,
|
|
(uint8_t)ctx->cur_colour[i].white);
|
|
}
|
|
|
|
if(ctx->something_changed) {
|
|
sk6812_send_update(ctx->led_ctx);
|
|
ctx->something_changed = 0;
|
|
}
|
|
}
|