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