From 55541be4a505da3df7d1a2b8bf3b5295b0af58f7 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Thu, 13 Apr 2023 20:38:25 -0600
Subject: refactor progress checkpoint ... got Sofirn LT1S Pro and Emisar D4v2
working with the new channel mode system ... but there's a lot more left to
do
---
spaghetti-monster/fsm-ramping.h | 196 ++++++++++++++++++++++------------------
1 file changed, 106 insertions(+), 90 deletions(-)
(limited to 'spaghetti-monster/fsm-ramping.h')
diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h
index de090c2..3021ff2 100644
--- a/spaghetti-monster/fsm-ramping.h
+++ b/spaghetti-monster/fsm-ramping.h
@@ -18,23 +18,80 @@
* along with this program. If not, see .
*/
-#ifndef FSM_RAMPING_H
-#define FSM_RAMPING_H
+#pragma once
#ifdef USE_RAMPING
// actual_level: last ramp level set by set_level()
uint8_t actual_level = 0;
-#ifdef USE_TINT_RAMPING
-#ifdef TINT_RAMP_TOGGLE_ONLY
-uint8_t tint = 0;
-#else
-uint8_t tint = 128;
+// TODO: size-optimize the case with only 1 channel mode
+// (the arrays and stuff shouldn't be needed)
+
+// current multi-channel mode
+uint8_t channel_mode = DEFAULT_CHANNEL_MODE;
+#ifdef USE_MANUAL_MEMORY
+// reset w/ manual memory
+uint8_t manual_memory_channel_mode = DEFAULT_CHANNEL_MODE;
#endif
-#define USE_TRIANGLE_WAVE
+
+#if NUM_CHANNEL_MODES > 1
+#define USE_CHANNEL_MODES
#endif
+// one function per channel mode
+typedef void SetLevelFunc(uint8_t level);
+typedef SetLevelFunc * SetLevelFuncPtr;
+// TODO: move to progmem
+SetLevelFuncPtr channel_modes[NUM_CHANNEL_MODES];
+
+#ifdef USE_SET_LEVEL_GRADUALLY
+// the gradual tick mechanism may be different per channel
+typedef void GradualTickFunc();
+typedef GradualTickFunc * GradualTickFuncPtr;
+// TODO: move to progmem
+GradualTickFuncPtr gradual_tick_modes[NUM_CHANNEL_MODES];
+#endif
+
+#ifdef USE_CUSTOM_CHANNEL_3H_MODES
+// different 3H behavior per channel?
+// TODO: move to progmem
+StatePtr channel_3H_modes[NUM_CHANNEL_MODES];
+#endif
+
+//#ifdef USE_CHANNEL_MODE_TOGGLES
+#if NUM_CHANNEL_MODES > 1
+// user can take unwanted modes out of the rotation
+// TODO: save to eeprom
+// array
+//uint8_t channel_modes_enabled[NUM_CHANNEL_MODES] = { CHANNEL_MODES_ENABLED };
+// bitmask
+uint8_t channel_modes_enabled = CHANNEL_MODES_ENABLED;
+#define channel_mode_enabled(n) ((channel_modes_enabled >> n) & 1)
+#define channel_mode_enable(n) channel_modes_enabled |= (1 << n)
+#define channel_mode_disable(n) channel_modes_enabled &= ((1 << n) ^ 0xff)
+#endif
+
+#ifdef USE_CHANNEL_MODE_ARGS
+// one byte of extra data per channel mode, like for tint value
+uint8_t channel_mode_args[NUM_CHANNEL_MODES] = { CHANNEL_MODE_ARGS };
+#endif
+
+// TODO: remove this after implementing channel modes
+//#ifdef USE_TINT_RAMPING
+//#ifdef TINT_RAMP_TOGGLE_ONLY
+//uint8_t tint = 0;
+//#else
+//uint8_t tint = 128;
+//#endif
+//#define USE_TRIANGLE_WAVE
+//#endif
+
+void set_channel_mode(uint8_t mode);
+
+void set_level(uint8_t level);
+//void set_level_smooth(uint8_t level);
+
#ifdef USE_SET_LEVEL_GRADUALLY
// adjust brightness very smoothly
uint8_t gradual_target;
@@ -42,21 +99,24 @@ inline void set_level_gradually(uint8_t lvl);
void gradual_tick();
#endif
-#if defined(USE_TINT_RAMPING) && (!defined(TINT_RAMP_TOGGLE_ONLY))
-void update_tint();
-#endif
-
// auto-detect the data type for PWM tables
-#ifndef PWM_BITS
- #define PWM_BITS 8
- #define PWM_TOP 255
+// FIXME: PWM bits and data type should be per PWM table
+#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
#define PWM_TOP 255
+ #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
@@ -64,32 +124,55 @@ void update_tint();
#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 PWM_DATATYPE pwm1_levels[] = { PWM1_LEVELS };
+PROGMEM const PWM1_DATATYPE pwm1_levels[] = { PWM1_LEVELS };
#endif
#ifdef PWM2_LEVELS
-PROGMEM const PWM_DATATYPE pwm2_levels[] = { PWM2_LEVELS };
+PROGMEM const PWM2_DATATYPE pwm2_levels[] = { PWM2_LEVELS };
#endif
#ifdef PWM3_LEVELS
-PROGMEM const PWM_DATATYPE pwm3_levels[] = { PWM3_LEVELS };
+PROGMEM const PWM3_DATATYPE pwm3_levels[] = { PWM3_LEVELS };
+#endif
+
+// convenience defs for 1 LED with stacked channels
+#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
-#ifdef PWM4_LEVELS
-PROGMEM const PWM_DATATYPE pwm4_levels[] = { PWM4_LEVELS };
+
+// 2 channel CCT blending ramp
+#ifdef BLEND_PWM_LEVELS
+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 USE_DYN_PWM
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
@@ -100,78 +183,11 @@ PROGMEM const PWM_DATATYPE pwm_tops[] = { PWM_TOPS };
uint8_t jump_start_level = DEFAULT_JUMP_START_LEVEL;
#endif
-// default / example ramps
-#ifndef PWM1_LEVELS
-#if PWM_CHANNELS == 1
- #if RAMP_LENGTH == 50
- // ../../bin/level_calc.py 1 50 7135 3 0.25 980
- PROGMEM const PWM_DATATYPE pwm1_levels[] = { 3,3,3,3,4,4,4,5,5,6,7,8,9,11,12,14,16,18,20,23,25,28,32,35,39,43,47,52,57,62,68,74,80,87,94,102,110,118,127,136,146,156,167,178,189,201,214,227,241,255 };
- #elif RAMP_LENGTH == 75
- // ../../bin/level_calc.py 1 75 7135 3 0.25 980
- PROGMEM const PWM_DATATYPE pwm1_levels[] = { 3,3,3,3,3,3,4,4,4,4,5,5,5,6,6,7,8,8,9,10,11,12,13,14,15,17,18,20,21,23,25,27,29,31,33,36,38,41,44,47,50,53,56,59,63,67,71,75,79,83,88,93,98,103,108,113,119,125,131,137,143,150,157,164,171,178,186,194,202,210,219,227,236,246,255 };
- #elif RAMP_LENGTH == 150
- // ../../bin/level_calc.py 1 150 7135 3 0.25 980
- PROGMEM const PWM_DATATYPE pwm1_levels[] = { 3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,7,7,7,8,8,8,9,9,9,10,10,11,11,12,12,13,13,14,15,15,16,17,17,18,19,19,20,21,22,23,24,24,25,26,27,28,29,31,32,33,34,35,36,38,39,40,42,43,44,46,47,49,50,52,53,55,57,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,89,91,93,96,98,101,103,106,109,111,114,117,120,123,125,128,131,134,138,141,144,147,151,154,157,161,164,168,171,175,179,183,186,190,194,198,202,206,210,215,219,223,228,232,236,241,246,250,255 };
- #endif
-#elif PWM_CHANNELS == 2
- #if RAMP_LENGTH == 50
- // ../../bin/level_calc.py 2 50 7135 4 0.33 150 FET 1 10 1500
- PROGMEM const PWM_DATATYPE pwm1_levels[] = { 4,5,6,8,10,13,17,22,28,35,44,54,65,78,93,109,128,149,171,197,224,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 };
- PROGMEM const PWM_DATATYPE pwm2_levels[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,7,11,15,20,26,31,37,44,51,58,65,73,82,91,100,110,121,132,143,155,168,181,194,209,224,239,255 };
- #define MAX_1x7135 22
- #elif RAMP_LENGTH == 75
- // ../../bin/level_calc.py 2 75 7135 4 0.33 150 FET 1 10 1500
- PROGMEM const PWM_DATATYPE pwm1_levels[] = { 4,4,5,6,7,8,10,12,14,17,20,24,28,32,37,43,49,56,64,72,82,91,102,114,126,139,153,168,184,202,220,239,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 };
- PROGMEM const PWM_DATATYPE pwm2_levels[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,5,7,10,13,16,19,23,26,30,34,38,42,47,51,56,61,66,72,77,83,89,95,101,108,115,122,129,136,144,152,160,168,177,186,195,204,214,224,234,244,255 };
- #define MAX_1x7135 33
- #elif RAMP_LENGTH == 150
- // ../../bin/level_calc.py 1 65 7135 1 0.8 150
- // ... mixed with this:
- // ../../bin/level_calc.py 2 150 7135 4 0.33 150 FET 1 10 1500
- PROGMEM const PWM_DATATYPE pwm1_levels[] = { 1,1,2,2,3,3,4,4,5,6,7,8,9,10,12,13,14,15,17,19,20,22,24,26,29,31,34,36,39,42,45,48,51,55,59,62,66,70,75,79,84,89,93,99,104,110,115,121,127,134,140,147,154,161,168,176,184,192,200,209,217,226,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 };
- PROGMEM const PWM_DATATYPE pwm2_levels[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,4,5,7,8,9,11,12,14,15,17,19,20,22,24,25,27,29,31,33,35,37,39,41,43,45,48,50,52,55,57,59,62,64,67,70,72,75,78,81,84,87,90,93,96,99,102,105,109,112,115,119,122,126,129,133,137,141,144,148,152,156,160,165,169,173,177,182,186,191,195,200,205,209,214,219,224,229,234,239,244,250,255 };
- #define MAX_1x7135 65
- #define HALFSPEED_LEVEL 14
- #define QUARTERSPEED_LEVEL 5
- #endif
-#elif PWM_CHANNELS == 3
- #if RAMP_LENGTH == 50
- // ../../bin/level_calc.py 3 50 7135 4 0.33 150 7135 4 1 840 FET 1 10 2000
- PROGMEM const PWM_DATATYPE pwm1_levels[] = { 4,5,6,8,11,15,20,26,34,43,54,67,82,99,118,140,165,192,221,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 };
- PROGMEM const PWM_DATATYPE pwm2_levels[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,17,25,33,42,52,62,73,85,97,111,125,140,157,174,192,210,230,251,255,255,255,255,255,255,255,255,255,255,0 };
- PROGMEM const PWM_DATATYPE pwm3_levels[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,34,54,76,98,122,146,172,198,226,255 };
- #define MAX_1x7135 20
- #define MAX_Nx7135 39
- #elif RAMP_LENGTH == 75
- // ../../bin/level_calc.py 3 75 7135 4 0.33 150 7135 4 1 840 FET 1 10 2000
- PROGMEM const PWM_DATATYPE pwm1_levels[] = { 4,4,5,6,7,9,11,14,16,20,24,28,34,40,46,54,62,71,81,92,104,117,130,146,162,179,198,218,239,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 };
- PROGMEM const PWM_DATATYPE pwm2_levels[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,9,14,18,23,29,34,40,47,53,60,67,75,83,91,99,108,117,127,137,148,158,170,181,193,206,219,232,246,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 };
- PROGMEM const PWM_DATATYPE pwm3_levels[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,15,28,42,55,70,84,99,115,131,147,164,181,199,217,236,255 };
- #define MAX_1x7135 30
- #define MAX_Nx7135 59
- #elif RAMP_LENGTH == 150
- // ../../bin/level_calc.py 1 65 7135 1 0.8 150
- // ... mixed with this:
- // ../../../bin/level_calc.py 3 150 7135 1 0.33 150 7135 1 1 850 FET 1 10 1500
- PROGMEM const PWM_DATATYPE pwm1_levels[] = { 1,1,2,2,3,3,4,4,5,6,7,8,9,10,12,13,14,15,17,19,20,22,24,26,29,31,34,36,39,42,45,48,51,55,59,62,66,70,75,79,84,89,93,99,104,110,115,121,127,134,140,147,154,161,168,176,184,192,200,209,217,226,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 };
- PROGMEM const PWM_DATATYPE pwm2_levels[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,4,6,8,10,13,15,17,19,22,24,26,29,31,34,37,39,42,45,48,51,54,57,60,64,67,70,74,77,81,85,88,92,96,100,104,108,112,116,121,125,130,134,139,143,148,153,158,163,168,173,179,184,189,195,201,206,212,218,224,230,236,243,249,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 };
- PROGMEM const PWM_DATATYPE pwm3_levels[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,19,31,43,55,67,79,91,104,117,130,143,157,170,184,198,212,226,240,255 };
- #define MAX_1x7135 65
- #define MAX_Nx7135 130
- #define HALFSPEED_LEVEL 14
- #define QUARTERSPEED_LEVEL 5
- #endif
-#elif PWM_CHANNELS == 4
- 4-channel PWM not really supported yet, sorry.
-#endif
-#endif
-
// RAMP_SIZE / MAX_LVL
-#define RAMP_SIZE (sizeof(pwm1_levels)/sizeof(PWM_DATATYPE))
+// cfg-*.h should define RAMP_SIZE
+//#define RAMP_SIZE (sizeof(stacked_pwm1_levels)/sizeof(STACKED_PWM_DATATYPE))
#define MAX_LEVEL RAMP_SIZE
-void set_level(uint8_t level);
-//void set_level_smooth(uint8_t level);
#endif // ifdef USE_RAMPING
-#endif
+
--
cgit v1.2.3
From f8e1150ba52fb3128d452e68ae2d8dda97a53ff1 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Fri, 14 Apr 2023 18:01:03 -0600
Subject: LT1S Pro: added dynamic PWM (much better low modes!)
---
spaghetti-monster/fsm-ramping.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'spaghetti-monster/fsm-ramping.h')
diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h
index 3021ff2..028157f 100644
--- a/spaghetti-monster/fsm-ramping.h
+++ b/spaghetti-monster/fsm-ramping.h
@@ -168,7 +168,7 @@ PROGMEM const PWM_DATATYPE blend_pwm_levels[] = { BLEND_PWM_LEVELS };
// 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 USE_DYN_PWM
+#ifdef PWM_TOPS
PROGMEM const PWM_DATATYPE pwm_tops[] = { PWM_TOPS };
#endif
--
cgit v1.2.3
From 6142f73db27cef29246291fd09227cc7bc3d4b15 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Fri, 14 Apr 2023 20:51:40 -0600
Subject: LT1S: added thermal regulation ... and a bunch of gradual_tick
functions ... and abstracted out some of the tint calculations ... and moved
some UI settings into cfg.h
---
spaghetti-monster/fsm-ramping.h | 41 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 40 insertions(+), 1 deletion(-)
(limited to 'spaghetti-monster/fsm-ramping.h')
diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h
index 028157f..8a12cc8 100644
--- a/spaghetti-monster/fsm-ramping.h
+++ b/spaghetti-monster/fsm-ramping.h
@@ -97,7 +97,46 @@ void set_level(uint8_t level);
uint8_t gradual_target;
inline void set_level_gradually(uint8_t lvl);
void gradual_tick();
-#endif
+
+// reduce repetition with macros
+// common code at the beginning of every gradual tick handler
+#define GRADUAL_TICK_SETUP() \
+ uint8_t gt = gradual_target; \
+ if (gt < actual_level) gt = actual_level - 1; \
+ else if (gt > actual_level) gt = actual_level + 1; \
+ gt --; \
+ PWM_DATATYPE target;
+
+// tick to a specific value
+#define GRADUAL_ADJUST_SIMPLE(TARGET,PWM) \
+ if (PWM < TARGET) PWM ++; \
+ else if (PWM > 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 --;
+
+// do this when output exactly matches a ramp level
+#define GRADUAL_IS_ACTUAL() \
+ uint8_t orig = gradual_target; \
+ set_level(gt + 1); \
+ gradual_target = orig;
+
+#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
--
cgit v1.2.3
From fbcac59563c32f14de4861449c1b267c247b5b78 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Sun, 16 Apr 2023 18:21:29 -0600
Subject: reduced ROM by ~600 bytes by moving all eeprom config values to a
"cfg" struct (this also made some parts of the code cleaner)
---
spaghetti-monster/fsm-ramping.h | 83 +++++++++++++++++++++++++----------------
1 file changed, 51 insertions(+), 32 deletions(-)
(limited to 'spaghetti-monster/fsm-ramping.h')
diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h
index 8a12cc8..5ffd8d9 100644
--- a/spaghetti-monster/fsm-ramping.h
+++ b/spaghetti-monster/fsm-ramping.h
@@ -28,11 +28,12 @@ uint8_t actual_level = 0;
// TODO: size-optimize the case with only 1 channel mode
// (the arrays and stuff shouldn't be needed)
-// current multi-channel mode
-uint8_t channel_mode = DEFAULT_CHANNEL_MODE;
-#ifdef USE_MANUAL_MEMORY
-// reset w/ manual memory
-uint8_t manual_memory_channel_mode = DEFAULT_CHANNEL_MODE;
+#ifdef USE_CFG
+ #define CH_MODE cfg.channel_mode
+#else
+ // current multi-channel mode
+ uint8_t channel_mode = DEFAULT_CHANNEL_MODE;
+ #define CH_MODE channel_mode
#endif
#if NUM_CHANNEL_MODES > 1
@@ -62,36 +63,49 @@ StatePtr channel_3H_modes[NUM_CHANNEL_MODES];
//#ifdef USE_CHANNEL_MODE_TOGGLES
#if NUM_CHANNEL_MODES > 1
// user can take unwanted modes out of the rotation
-// TODO: save to eeprom
-// array
-//uint8_t channel_modes_enabled[NUM_CHANNEL_MODES] = { CHANNEL_MODES_ENABLED };
// bitmask
-uint8_t channel_modes_enabled = CHANNEL_MODES_ENABLED;
-#define channel_mode_enabled(n) ((channel_modes_enabled >> n) & 1)
-#define channel_mode_enable(n) channel_modes_enabled |= (1 << n)
-#define channel_mode_disable(n) channel_modes_enabled &= ((1 << n) ^ 0xff)
+#ifdef USE_CFG
+ #define channel_mode_enabled(n) ((cfg.channel_modes_enabled >> n) & 1)
+ #define channel_mode_enable(n) cfg.channel_modes_enabled |= (1 << n)
+ #define channel_mode_disable(n) cfg.channel_modes_enabled &= ((1 << n) ^ 0xff)
+#else
+ uint8_t channel_modes_enabled = CHANNEL_MODES_ENABLED;
+ #define channel_mode_enabled(n) ((channel_modes_enabled >> n) & 1)
+ #define channel_mode_enable(n) channel_modes_enabled |= (1 << n)
+ #define channel_mode_disable(n) channel_modes_enabled &= ((1 << n) ^ 0xff)
+ #endif
#endif
-#ifdef USE_CHANNEL_MODE_ARGS
-// one byte of extra data per channel mode, like for tint value
-uint8_t channel_mode_args[NUM_CHANNEL_MODES] = { CHANNEL_MODE_ARGS };
+#ifndef USE_CFG
+ #ifdef USE_CHANNEL_MODE_ARGS
+ // one byte of extra data per channel mode, like for tint value
+ uint8_t channel_mode_args[NUM_CHANNEL_MODES] = { CHANNEL_MODE_ARGS };
+ #endif
#endif
-// TODO: remove this after implementing channel modes
-//#ifdef USE_TINT_RAMPING
-//#ifdef TINT_RAMP_TOGGLE_ONLY
-//uint8_t tint = 0;
-//#else
-//uint8_t tint = 128;
-//#endif
-//#define USE_TRIANGLE_WAVE
-//#endif
-
void set_channel_mode(uint8_t mode);
void set_level(uint8_t level);
//void set_level_smooth(uint8_t level);
+#ifdef USE_CALC_2CH_BLEND
+void calc_2ch_blend(
+ PWM_DATATYPE *warm,
+ PWM_DATATYPE *cool,
+ PWM_DATATYPE brightness,
+ PWM_DATATYPE top,
+ uint8_t blend);
+#endif
+
+#ifdef USE_HSV2RGB
+typedef struct RGB_t {
+ uint8_t r;
+ uint8_t g;
+ uint8_t b;
+} RGB_t;
+RGB_t hsv2rgb(uint8_t h, uint8_t s, uint8_t v);
+#endif // ifdef USE_HSV2RGB
+
#ifdef USE_SET_LEVEL_GRADUALLY
// adjust brightness very smoothly
uint8_t gradual_target;
@@ -213,13 +227,18 @@ PROGMEM const PWM_DATATYPE pwm_tops[] = { PWM_TOPS };
// 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
-uint8_t jump_start_level = DEFAULT_JUMP_START_LEVEL;
+ #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
--
cgit v1.2.3
From 583854e37efde7f461e073e735a1736b02d28c70 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Mon, 17 Apr 2023 00:08:32 -0600
Subject: switched the rest of FSM + Anduril to use SPDX license headers
instead of full GPL headers (or all too often, nothing at all)
There are a few "FIXME" entries where I'm not sure about the correct copyright.
---
spaghetti-monster/fsm-ramping.h | 22 +++-------------------
1 file changed, 3 insertions(+), 19 deletions(-)
(limited to 'spaghetti-monster/fsm-ramping.h')
diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h
index 5ffd8d9..4511508 100644
--- a/spaghetti-monster/fsm-ramping.h
+++ b/spaghetti-monster/fsm-ramping.h
@@ -1,22 +1,6 @@
-/*
- * fsm-ramping.h: Ramping functions for SpaghettiMonster.
- * Handles 1- to 4-channel smooth ramping on a single LED.
- *
- * Copyright (C) 2017 Selene ToyKeeper
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
+// fsm-ramping.h: Ramping functions for SpaghettiMonster.
+// Copyright (C) 2017-2023 Selene ToyKeeper
+// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
--
cgit v1.2.3
From 561a85c175920074fafea33738d24f54317e2f3a Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Mon, 17 Apr 2023 01:30:41 -0600
Subject: made "Ramp 3H" do momentary turbo if current channel mode has no args
---
spaghetti-monster/fsm-ramping.h | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
(limited to 'spaghetti-monster/fsm-ramping.h')
diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h
index 4511508..a9e333e 100644
--- a/spaghetti-monster/fsm-ramping.h
+++ b/spaghetti-monster/fsm-ramping.h
@@ -41,6 +41,7 @@ GradualTickFuncPtr gradual_tick_modes[NUM_CHANNEL_MODES];
#ifdef USE_CUSTOM_CHANNEL_3H_MODES
// different 3H behavior per channel?
// TODO: move to progmem
+// TODO: move to Anduril, not FSM
StatePtr channel_3H_modes[NUM_CHANNEL_MODES];
#endif
@@ -60,11 +61,14 @@ StatePtr channel_3H_modes[NUM_CHANNEL_MODES];
#endif
#endif
-#ifndef USE_CFG
- #ifdef USE_CHANNEL_MODE_ARGS
+#ifdef USE_CHANNEL_MODE_ARGS
+ #ifndef USE_CFG
// one byte of extra data per channel mode, like for tint value
uint8_t channel_mode_args[NUM_CHANNEL_MODES] = { CHANNEL_MODE_ARGS };
#endif
+ // bitmask: which modes respond to their "arg", and which don't?
+ //const uint8_t channel_has_args = CHANNEL_HAS_ARGS;
+ #define channel_has_args(n) ((CHANNEL_HAS_ARGS >> n) & 1)
#endif
void set_channel_mode(uint8_t mode);
--
cgit v1.2.3
From 5f6bb2bda2dd4eccbdfba94e5d35cedc8c0c42dc Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Tue, 25 Apr 2023 01:07:15 -0600
Subject: updated D4Sv2-tintramp -> Emisar 2-channel build target ... ... and
reworked how gradual_tick() works ... and updated LT1S Pro to use new method
---
spaghetti-monster/fsm-ramping.h | 13 +------------
1 file changed, 1 insertion(+), 12 deletions(-)
(limited to 'spaghetti-monster/fsm-ramping.h')
diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h
index a9e333e..7b3722d 100644
--- a/spaghetti-monster/fsm-ramping.h
+++ b/spaghetti-monster/fsm-ramping.h
@@ -32,7 +32,7 @@ SetLevelFuncPtr channel_modes[NUM_CHANNEL_MODES];
#ifdef USE_SET_LEVEL_GRADUALLY
// the gradual tick mechanism may be different per channel
-typedef void GradualTickFunc();
+typedef bool GradualTickFunc(uint8_t gt);
typedef GradualTickFunc * GradualTickFuncPtr;
// TODO: move to progmem
GradualTickFuncPtr gradual_tick_modes[NUM_CHANNEL_MODES];
@@ -101,12 +101,7 @@ inline void set_level_gradually(uint8_t lvl);
void gradual_tick();
// reduce repetition with macros
-// common code at the beginning of every gradual tick handler
#define GRADUAL_TICK_SETUP() \
- uint8_t gt = gradual_target; \
- if (gt < actual_level) gt = actual_level - 1; \
- else if (gt > actual_level) gt = actual_level + 1; \
- gt --; \
PWM_DATATYPE target;
// tick to a specific value
@@ -132,12 +127,6 @@ void gradual_tick();
if (PWM < target) PWM ++; \
else if (PWM > target) PWM --;
-// do this when output exactly matches a ramp level
-#define GRADUAL_IS_ACTUAL() \
- uint8_t orig = gradual_target; \
- set_level(gt + 1); \
- gradual_target = orig;
-
#endif // ifdef USE_SET_LEVEL_GRADUALLY
// auto-detect the data type for PWM tables
--
cgit v1.2.3
From 9765caab66ab628d763a5148efde80b3c3930b31 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Sat, 29 Apr 2023 01:19:42 -0600
Subject: Noctigon KR4: updated to use new channel system (also tweaked D4v2
build to match KR4 as much as possible) (also added Extended Simple UI to
Hank's config)
---
spaghetti-monster/fsm-ramping.h | 7 +++++++
1 file changed, 7 insertions(+)
(limited to 'spaghetti-monster/fsm-ramping.h')
diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h
index 7b3722d..3003ecb 100644
--- a/spaghetti-monster/fsm-ramping.h
+++ b/spaghetti-monster/fsm-ramping.h
@@ -109,6 +109,13 @@ void gradual_tick();
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 = TOP; \
+ else GRADUAL_ADJUST_SIMPLE(TARGET,PWM)
+
// tick the top layer of the stack
#define GRADUAL_ADJUST_1CH(TABLE,PWM) \
target = PWM_GET(TABLE, gt); \
--
cgit v1.2.3
From 00dbf2b76cdbad2dbf2fd3b960bcb09d77f932d1 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Tue, 2 May 2023 23:44:22 -0600
Subject: post-off voltage display: use low brightness when torch was at moon
level before, and skip the voltage display after UI actions which didn't
change the mode (like "Off -> 7C" to change aux LED settings)
---
spaghetti-monster/fsm-ramping.h | 2 ++
1 file changed, 2 insertions(+)
(limited to 'spaghetti-monster/fsm-ramping.h')
diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h
index 3003ecb..8d5ed27 100644
--- a/spaghetti-monster/fsm-ramping.h
+++ b/spaghetti-monster/fsm-ramping.h
@@ -8,6 +8,8 @@
// actual_level: last ramp level set by set_level()
uint8_t actual_level = 0;
+// the level used before actual
+uint8_t prev_level = 0;
// TODO: size-optimize the case with only 1 channel mode
// (the arrays and stuff shouldn't be needed)
--
cgit v1.2.3
From 6415a13625eadb2793b888c3fa2c92e115b9a335 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Tue, 30 May 2023 06:12:18 -0600
Subject: gradual adjustments: handle 0-to-255 in one step on the way up too,
not just down
---
spaghetti-monster/fsm-ramping.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'spaghetti-monster/fsm-ramping.h')
diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h
index 8d5ed27..36cf89c 100644
--- a/spaghetti-monster/fsm-ramping.h
+++ b/spaghetti-monster/fsm-ramping.h
@@ -115,7 +115,7 @@ void gradual_tick();
#define GRADUAL_ADJUST_STACKED(TARGET,PWM,TOP) \
if ( ((PWM == 0) && (TARGET == TOP)) \
|| ((PWM == TOP) && (TARGET == 0))) \
- PWM = TOP; \
+ PWM = TARGET; \
else GRADUAL_ADJUST_SIMPLE(TARGET,PWM)
// tick the top layer of the stack
--
cgit v1.2.3
From 95a9eb6b3078915a2686c7ec55320273ef429838 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Mon, 10 Jul 2023 11:56:04 -0600
Subject: refactored how channel modes are defined, and converted emisar-2ch
build
---
spaghetti-monster/fsm-ramping.h | 85 ++---------------------------------------
1 file changed, 3 insertions(+), 82 deletions(-)
(limited to 'spaghetti-monster/fsm-ramping.h')
diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h
index 36cf89c..0c299c4 100644
--- a/spaghetti-monster/fsm-ramping.h
+++ b/spaghetti-monster/fsm-ramping.h
@@ -11,91 +11,9 @@ uint8_t actual_level = 0;
// the level used before actual
uint8_t prev_level = 0;
-// TODO: size-optimize the case with only 1 channel mode
-// (the arrays and stuff shouldn't be needed)
-
-#ifdef USE_CFG
- #define CH_MODE cfg.channel_mode
-#else
- // current multi-channel mode
- uint8_t channel_mode = DEFAULT_CHANNEL_MODE;
- #define CH_MODE channel_mode
-#endif
-
-#if NUM_CHANNEL_MODES > 1
-#define USE_CHANNEL_MODES
-#endif
-
-// one function per channel mode
-typedef void SetLevelFunc(uint8_t level);
-typedef SetLevelFunc * SetLevelFuncPtr;
-// TODO: move to progmem
-SetLevelFuncPtr channel_modes[NUM_CHANNEL_MODES];
-
-#ifdef USE_SET_LEVEL_GRADUALLY
-// the gradual tick mechanism may be different per channel
-typedef bool GradualTickFunc(uint8_t gt);
-typedef GradualTickFunc * GradualTickFuncPtr;
-// TODO: move to progmem
-GradualTickFuncPtr gradual_tick_modes[NUM_CHANNEL_MODES];
-#endif
-
-#ifdef USE_CUSTOM_CHANNEL_3H_MODES
-// different 3H behavior per channel?
-// TODO: move to progmem
-// TODO: move to Anduril, not FSM
-StatePtr channel_3H_modes[NUM_CHANNEL_MODES];
-#endif
-
-//#ifdef USE_CHANNEL_MODE_TOGGLES
-#if NUM_CHANNEL_MODES > 1
-// user can take unwanted modes out of the rotation
-// bitmask
-#ifdef USE_CFG
- #define channel_mode_enabled(n) ((cfg.channel_modes_enabled >> n) & 1)
- #define channel_mode_enable(n) cfg.channel_modes_enabled |= (1 << n)
- #define channel_mode_disable(n) cfg.channel_modes_enabled &= ((1 << n) ^ 0xff)
-#else
- uint8_t channel_modes_enabled = CHANNEL_MODES_ENABLED;
- #define channel_mode_enabled(n) ((channel_modes_enabled >> n) & 1)
- #define channel_mode_enable(n) channel_modes_enabled |= (1 << n)
- #define channel_mode_disable(n) channel_modes_enabled &= ((1 << n) ^ 0xff)
- #endif
-#endif
-
-#ifdef USE_CHANNEL_MODE_ARGS
- #ifndef USE_CFG
- // one byte of extra data per channel mode, like for tint value
- uint8_t channel_mode_args[NUM_CHANNEL_MODES] = { CHANNEL_MODE_ARGS };
- #endif
- // bitmask: which modes respond to their "arg", and which don't?
- //const uint8_t channel_has_args = CHANNEL_HAS_ARGS;
- #define channel_has_args(n) ((CHANNEL_HAS_ARGS >> n) & 1)
-#endif
-
-void set_channel_mode(uint8_t mode);
-
void set_level(uint8_t level);
//void set_level_smooth(uint8_t level);
-#ifdef USE_CALC_2CH_BLEND
-void calc_2ch_blend(
- PWM_DATATYPE *warm,
- PWM_DATATYPE *cool,
- PWM_DATATYPE brightness,
- PWM_DATATYPE top,
- uint8_t blend);
-#endif
-
-#ifdef USE_HSV2RGB
-typedef struct RGB_t {
- uint8_t r;
- uint8_t g;
- uint8_t b;
-} RGB_t;
-RGB_t hsv2rgb(uint8_t h, uint8_t s, uint8_t v);
-#endif // ifdef USE_HSV2RGB
-
#ifdef USE_SET_LEVEL_GRADUALLY
// adjust brightness very smoothly
uint8_t gradual_target;
@@ -140,6 +58,7 @@ void gradual_tick();
// 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
@@ -188,6 +107,7 @@ PROGMEM const PWM3_DATATYPE pwm3_levels[] = { PWM3_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
@@ -200,6 +120,7 @@ PROGMEM const PWM_DATATYPE high_pwm_levels[] = { HIGH_PWM_LEVELS };
// 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
--
cgit v1.2.3
From bcaa751aa1b29cb3b4c76df2075feb1941d043fe Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Thu, 3 Aug 2023 19:15:34 -0600
Subject: converted all K9.3 builds and D4Sv2-tintramp-fet (now emisar-2ch-fet)
to multi-channel, and removed old K9.3 builds which aren't relevant any more,
and old D4Sv2-tintramp builds
---
spaghetti-monster/fsm-ramping.h | 6 ++++++
1 file changed, 6 insertions(+)
(limited to 'spaghetti-monster/fsm-ramping.h')
diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h
index 0c299c4..cae9a4d 100644
--- a/spaghetti-monster/fsm-ramping.h
+++ b/spaghetti-monster/fsm-ramping.h
@@ -105,6 +105,12 @@ PROGMEM const PWM2_DATATYPE pwm2_levels[] = { PWM2_LEVELS };
#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
--
cgit v1.2.3
From 9e5f2dacebf880f61671974ddd8f604cf1782f37 Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Fri, 25 Aug 2023 17:27:43 -0600
Subject: started splitting set_level(0) into its own set_level_zero(), and
made USE_AUX_RGB_LEDS_WHILE_ON work more like the old indicator LEDs, where
it gets set automatically with set_level()
Using set_level_zero() reduces space used by channel modes, and simplifies
code for each mode's set_level_*() functions. I measured about 220 bytes
less in the emisar-d4k-3ch build this way, while also reducing the chance
of bugs.
---
spaghetti-monster/fsm-ramping.h | 1 +
1 file changed, 1 insertion(+)
(limited to 'spaghetti-monster/fsm-ramping.h')
diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h
index cae9a4d..bfcc5fb 100644
--- a/spaghetti-monster/fsm-ramping.h
+++ b/spaghetti-monster/fsm-ramping.h
@@ -13,6 +13,7 @@ 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
--
cgit v1.2.3
From fd7aa0297954c511d3f0ec2353a8fcc3c68a3b5a Mon Sep 17 00:00:00 2001
From: Selene ToyKeeper
Date: Thu, 26 Oct 2023 08:29:44 -0600
Subject: converted Sofirn LT1-t1616 to new API, using SiteRelEnby's branch for
reference (needs further updates though, to improve ramping, since this
version is basically a straight conversion of the old t85 code with 8-bit
ramps)
---
spaghetti-monster/fsm-ramping.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
(limited to 'spaghetti-monster/fsm-ramping.h')
diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h
index bfcc5fb..c4b7d48 100644
--- a/spaghetti-monster/fsm-ramping.h
+++ b/spaghetti-monster/fsm-ramping.h
@@ -69,7 +69,9 @@ void gradual_tick();
#define STACKED_PWM_DATATYPE uint8_t
#define PWM_DATATYPE uint8_t
#define PWM_DATATYPE2 uint16_t
- #define PWM_TOP 255
+ #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)
--
cgit v1.2.3