diff options
Diffstat (limited to 'fsm/ramping.h')
| -rw-r--r-- | fsm/ramping.h | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/fsm/ramping.h b/fsm/ramping.h new file mode 100644 index 0000000..c4b7d48 --- /dev/null +++ b/fsm/ramping.h @@ -0,0 +1,167 @@ +// fsm-ramping.h: Ramping functions for SpaghettiMonster. +// Copyright (C) 2017-2023 Selene ToyKeeper +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#ifdef USE_RAMPING + +// actual_level: last ramp level set by set_level() +uint8_t actual_level = 0; +// the level used before actual +uint8_t prev_level = 0; + +void set_level(uint8_t level); +//void set_level_smooth(uint8_t level); +void set_level_zero(); // implement this in a hwdef + +#ifdef USE_SET_LEVEL_GRADUALLY +// adjust brightness very smoothly +uint8_t gradual_target; +inline void set_level_gradually(uint8_t lvl); +void gradual_tick(); + +// reduce repetition with macros +#define GRADUAL_TICK_SETUP() \ + PWM_DATATYPE target; + +// tick to a specific value +#define GRADUAL_ADJUST_SIMPLE(TARGET,PWM) \ + if (PWM < TARGET) PWM ++; \ + else if (PWM > TARGET) PWM --; + +// tick to a specific value, except when immediate 0 to 255 is needed +#define GRADUAL_ADJUST_STACKED(TARGET,PWM,TOP) \ + if ( ((PWM == 0) && (TARGET == TOP)) \ + || ((PWM == TOP) && (TARGET == 0))) \ + PWM = TARGET; \ + else GRADUAL_ADJUST_SIMPLE(TARGET,PWM) + +// tick the top layer of the stack +#define GRADUAL_ADJUST_1CH(TABLE,PWM) \ + target = PWM_GET(TABLE, gt); \ + if (PWM < target) PWM ++; \ + else if (PWM > target) PWM --; + +// tick a base level of the stack +// (with support for special DD FET behavior +// like "low=0, high=255" --> "low=255, high=254") +#define GRADUAL_ADJUST(TABLE,PWM,TOP) \ + target = PWM_GET(TABLE, gt); \ + if ((gt < actual_level) \ + && (PWM == 0) \ + && (target == TOP)) PWM = TOP; \ + else \ + if (PWM < target) PWM ++; \ + else if (PWM > target) PWM --; + +#endif // ifdef USE_SET_LEVEL_GRADUALLY + +// auto-detect the data type for PWM tables +// FIXME: PWM bits and data type should be per PWM table +// FIXME: this whole thing is a mess and should be removed +#ifndef PWM1_BITS + #define PWM1_BITS 8 + #define PWM1_TOP 255 + #define STACKED_PWM_TOP 255 +#endif +#if PWM_BITS <= 8 + #define STACKED_PWM_DATATYPE uint8_t + #define PWM_DATATYPE uint8_t + #define PWM_DATATYPE2 uint16_t + #ifndef PWM_TOP + #define PWM_TOP 255 + #endif + #define STACKED_PWM_TOP 255 + #ifndef PWM_GET + #define PWM_GET(x,y) pgm_read_byte(x+y) + #endif +#else + #define STACKED_PWM_DATATYPE uint16_t + #define PWM_DATATYPE uint16_t + #ifndef PWM_DATATYPE2 + #define PWM_DATATYPE2 uint32_t + #endif + #ifndef PWM_TOP + #define PWM_TOP 1023 // 10 bits by default + #endif + #ifndef STACKED_PWM_TOP + #define STACKED_PWM_TOP 1023 + #endif + // pointer plus 2*y bytes + //#define PWM_GET(x,y) pgm_read_word(x+(2*y)) + // nope, the compiler was already doing the math correctly + #ifndef PWM_GET + #define PWM_GET(x,y) pgm_read_word(x+y) + #endif +#endif +#define PWM_GET8(x,y) pgm_read_byte(x+y) +#define PWM_GET16(x,y) pgm_read_word(x+y) + +// use UI-defined ramp tables if they exist +#ifdef PWM1_LEVELS +PROGMEM const PWM1_DATATYPE pwm1_levels[] = { PWM1_LEVELS }; +#endif +#ifdef PWM2_LEVELS +PROGMEM const PWM2_DATATYPE pwm2_levels[] = { PWM2_LEVELS }; +#endif +#ifdef PWM3_LEVELS +PROGMEM const PWM3_DATATYPE pwm3_levels[] = { PWM3_LEVELS }; +#endif +#ifdef PWM4_LEVELS +PROGMEM const PWM4_DATATYPE pwm4_levels[] = { PWM4_LEVELS }; +#endif +#ifdef PWM5_LEVELS +PROGMEM const PWM5_DATATYPE pwm5_levels[] = { PWM5_LEVELS }; +#endif + +// convenience defs for 1 LED with stacked channels +// FIXME: remove this, use pwm1/2/3 instead +#ifdef LOW_PWM_LEVELS +PROGMEM const PWM_DATATYPE low_pwm_levels[] = { LOW_PWM_LEVELS }; +#endif +#ifdef MED_PWM_LEVELS +PROGMEM const PWM_DATATYPE med_pwm_levels[] = { MED_PWM_LEVELS }; +#endif +#ifdef HIGH_PWM_LEVELS +PROGMEM const PWM_DATATYPE high_pwm_levels[] = { HIGH_PWM_LEVELS }; +#endif + +// 2 channel CCT blending ramp +#ifdef BLEND_PWM_LEVELS +// FIXME: remove this, use pwm1/2/3 instead +PROGMEM const PWM_DATATYPE blend_pwm_levels[] = { BLEND_PWM_LEVELS }; +#endif + + +// pulse frequency modulation, a.k.a. dynamic PWM +// (different ceiling / frequency at each ramp level) +// FIXME: dynamic PWM should be a per-channel option, not global +#ifdef PWM_TOPS +PROGMEM const PWM_DATATYPE pwm_tops[] = { PWM_TOPS }; +#endif + +// FIXME: jump start should be per channel / channel mode +#ifdef USE_JUMP_START + #ifndef JUMP_START_TIME + #define JUMP_START_TIME 8 // in ms, should be 4, 8, or 12 + #endif + #ifndef DEFAULT_JUMP_START_LEVEL + #define DEFAULT_JUMP_START_LEVEL 10 + #endif + #ifdef USE_CFG + #define JUMP_START_LEVEL cfg.jump_start_level + #else + #define JUMP_START_LEVEL jump_start_level + uint8_t jump_start_level = DEFAULT_JUMP_START_LEVEL; + #endif +#endif + +// RAMP_SIZE / MAX_LVL +// cfg-*.h should define RAMP_SIZE +//#define RAMP_SIZE (sizeof(stacked_pwm1_levels)/sizeof(STACKED_PWM_DATATYPE)) +#define MAX_LEVEL RAMP_SIZE + + +#endif // ifdef USE_RAMPING + |
