aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSelene ToyKeeper2021-10-31 02:35:49 -0600
committerSelene ToyKeeper2021-10-31 02:35:49 -0600
commit4b4353ade4c026c196e2b6edacbb0dc437e3ddda (patch)
treefdba5c77f4e8b703af0722ff64684f3ead40d8e6
parentClarified Ramp->2C behavior a bit more. (diff)
downloadanduril-4b4353ade4c026c196e2b6edacbb0dc437e3ddda.tar.gz
anduril-4b4353ade4c026c196e2b6edacbb0dc437e3ddda.tar.bz2
anduril-4b4353ade4c026c196e2b6edacbb0dc437e3ddda.zip
added "200%" turbo on tint-ramping lights: D4S and LT1
Normal ramp from 0% to 100% power on levels 1 to 130, then 101% to 200% power at levels 131 to 150 using both channels at maximum for turbo. When either channel would go over 100%, the extra spills over to the other channel.
-rw-r--r--hwdef-BLF_LT1.h4
-rw-r--r--spaghetti-monster/anduril/cfg-blf-lantern.h24
-rw-r--r--spaghetti-monster/anduril/cfg-emisar-d4sv2-tintramp.h13
-rw-r--r--spaghetti-monster/fsm-ramping.c33
-rw-r--r--spaghetti-monster/fsm-ramping.h34
5 files changed, 71 insertions, 37 deletions
diff --git a/hwdef-BLF_LT1.h b/hwdef-BLF_LT1.h
index d0c2821..16e1c90 100644
--- a/hwdef-BLF_LT1.h
+++ b/hwdef-BLF_LT1.h
@@ -14,7 +14,7 @@
#include <avr/io.h>
#define PWM_CHANNELS 1 // 1 virtual channel (1 for main LEDs + 1 for 2nd LEDs)
-#define PWM_BITS 8 // 0 to 255 at 15.6 kHz
+#define PWM_BITS 9 // 0 to 255 at 15.6 kHz, but goes to 510 for "200%" turbo
#define PWM_TOP 255
// dynamic PWM with tint ramping (not supported on attiny85)
@@ -25,7 +25,7 @@
// it out to a soft brightness value, in order to handle tint ramping
// (this allows smooth thermal regulation to work, and makes things
// otherwise simpler and easier)
-uint8_t PWM1_LVL;
+uint16_t PWM1_LVL;
#define PWM1_PIN PB0 // pin 5, warm tint PWM
#define TINT1_LVL OCR0A // OCR0A is the output compare register for PB0
diff --git a/spaghetti-monster/anduril/cfg-blf-lantern.h b/spaghetti-monster/anduril/cfg-blf-lantern.h
index 48ed1f7..edbdca4 100644
--- a/spaghetti-monster/anduril/cfg-blf-lantern.h
+++ b/spaghetti-monster/anduril/cfg-blf-lantern.h
@@ -19,15 +19,20 @@
// (0 = 100% brightness, 64 = 200% brightness)
//#define TINT_RAMPING_CORRECTION 26 // prototype, 140%
#define TINT_RAMPING_CORRECTION 10 // production model, 115%
+//#define TINT_RAMPING_CORRECTION 0 // none
#ifdef RAMP_LENGTH
#undef RAMP_LENGTH
#endif
-// level_calc.py 1 150 7135 1 30 800
+// 1-130: 0 to 100% power
+// level_calc.py 3.0 1 130 7135 1 30 800 --pwm 255
+// 131-150: 101% to 200% power
+// level_calc.py 8.69 1 150 7135 1 1 1600 --pwm 510
#define RAMP_LENGTH 150
-#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,11,11,12,13,13,14,15,15,16,17,18,18,19,20,21,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,43,44,45,46,48,49,50,51,53,54,56,57,58,60,61,63,64,66,67,69,70,72,74,75,77,79,80,82,84,85,87,89,91,93,95,97,98,100,102,104,106,108,111,113,115,117,119,121,124,126,128,130,133,135,137,140,142,145,147,150,152,155,157,160,163,165,168,171,173,176,179,182,185,188,190,193,196,199,202,205,209,212,215,218,221,224,228,231,234,238,241,245,248,251,255
-#define MAX_1x7135 65
+#define PWM1_LEVELS 1,1,2,2,3,3,4,5,5,6,6,7,8,8,9,10,10,11,12,12,13,14,15,16,17,17,18,19,20,21,22,23,24,25,26,27,28,29,31,32,33,34,35,37,38,39,40,42,43,45,46,47,49,50,52,54,55,57,58,60,62,63,65,67,69,70,72,74,76,78,80,82,84,86,88,90,92,95,97,99,101,104,106,108,111,113,115,118,121,123,126,128,131,134,136,139,142,145,148,150,153,156,159,162,166,169,172,175,178,181,185,188,191,195,198,202,205,209,213,216,220,224,227,231,235,239,243,247,251,255,264,274,284,294,305,316,327,339,351,363,376,389,403,417,431,446,461,477,493,510
+#define MAX_1x7135 130
+#define DEFAULT_LEVEL 70
#define HALFSPEED_LEVEL 14
#define QUARTERSPEED_LEVEL 5
@@ -40,7 +45,7 @@
// set floor and ceiling as far apart as possible
// because this lantern isn't overpowered
#define RAMP_SMOOTH_FLOOR 1
-#define RAMP_SMOOTH_CEIL 150
+#define RAMP_SMOOTH_CEIL 130
#define RAMP_DISCRETE_FLOOR 10
#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
#define RAMP_DISCRETE_STEPS 5
@@ -59,14 +64,15 @@
#undef USE_THERMAL_REGULATION
#endif
-// don't blink while ramping
-#ifdef BLINK_AT_RAMP_MIDDLE
-#undef BLINK_AT_RAMP_MIDDLE
-#endif
+// don't blink at floor
#ifdef BLINK_AT_RAMP_FLOOR
#undef BLINK_AT_RAMP_FLOOR
#endif
-// except the top... blink at the top
+// blink at 100% power
+#ifndef BLINK_AT_RAMP_MIDDLE
+#define BLINK_AT_RAMP_MIDDLE
+#endif
+// blink again at the 200% power / ceil / turbo
#ifndef BLINK_AT_RAMP_CEIL
#define BLINK_AT_RAMP_CEIL
#endif
diff --git a/spaghetti-monster/anduril/cfg-emisar-d4sv2-tintramp.h b/spaghetti-monster/anduril/cfg-emisar-d4sv2-tintramp.h
index c170645..bc710c2 100644
--- a/spaghetti-monster/anduril/cfg-emisar-d4sv2-tintramp.h
+++ b/spaghetti-monster/anduril/cfg-emisar-d4sv2-tintramp.h
@@ -28,10 +28,13 @@
// 2nd LEDs
// output: unknown, 2000 lm?
#define RAMP_LENGTH 150
-// level_calc.py 5.01 1 150 7135 1 0.2 2000 --pwm dyn:74:16383:511
// abstract ramp (power is split between both sets of LEDs)
-#define PWM1_LEVELS 1,1,1,2,2,2,3,4,4,5,6,6,7,8,9,10,12,13,14,16,17,19,20,22,24,26,28,30,32,35,37,40,42,45,47,50,53,56,59,62,65,68,71,74,77,80,83,86,89,91,94,96,98,100,102,104,105,106,107,107,107,106,105,103,101,98,94,90,84,78,71,63,54,44,33,35,37,38,40,42,44,46,48,50,53,55,57,60,63,65,68,71,74,77,80,83,87,90,94,98,102,106,110,114,118,123,128,132,137,142,148,153,159,164,170,176,183,189,196,202,209,216,224,231,239,247,255,263,272,281,290,299,309,318,328,339,349,360,371,382,394,406,418,430,443,456,469,483,497,511
-#define PWM_TOPS 16383,13673,10738,15435,11908,8123,12779,14756,12240,13447,14013,11907,12263,12351,12261,12048,12926,12464,11972,12278,11704,11789,11180,11134,11013,10837,10620,10371,10100,10113,9793,9718,9376,9248,8898,8738,8560,8369,8168,7961,7749,7535,7321,7107,6895,6686,6480,6278,6080,5823,5639,5403,5178,4965,4763,4570,4346,4134,3936,3714,3507,3283,3074,2853,2648,2433,2211,2006,1776,1564,1351,1137,924,714,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511
+// 1-130: 0 to 100% power
+// level_calc.py 5.01 1 130 7135 2 0.2 2000 --pwm dyn:64:16383:511
+// 131 to 150: 101% to 200% power
+// level_calc.py 6.44 1 150 7135 1 0.2 2000 --pwm dyn:74:16383:1022
+#define PWM1_LEVELS 2,2,2,3,3,4,4,5,6,7,8,9,10,11,13,14,16,17,19,21,23,25,28,30,33,35,38,41,44,47,50,54,57,60,64,67,71,74,78,81,84,88,91,94,97,99,101,103,105,106,107,107,107,106,105,102,99,95,90,84,77,68,58,47,34,36,38,40,42,44,47,49,52,54,57,60,63,66,69,73,76,80,83,87,91,96,100,104,109,114,119,124,130,135,141,147,153,160,166,173,180,187,195,203,211,219,228,236,245,255,264,274,285,295,306,317,329,340,353,365,378,391,405,419,433,448,463,479,495,511,530,550,570,591,612,634,657,680,705,730,755,782,809,837,865,895,925,957,989,1022
+#define PWM_TOPS 16383,13234,9781,13826,9593,13434,9973,12021,12900,13193,13150,12899,12508,12023,12666,11982,12181,11422,11393,11247,11018,10731,10826,10434,10365,9927,9767,9565,9332,9076,8806,8693,8395,8096,7928,7626,7439,7143,6948,6665,6393,6203,5946,5700,5465,5187,4926,4681,4451,4195,3957,3700,3463,3213,2983,2718,2476,2231,1986,1742,1501,1245,997,756,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511
#define DEFAULT_LEVEL 70
#define MAX_1x7135 150
#define HALFSPEED_LEVEL 10
@@ -54,8 +57,8 @@
#define SIMPLE_UI_STEPS 5
// stop panicking at ~1500 lm
-#define THERM_FASTER_LEVEL 140
-#define MIN_THERM_STEPDOWN 75 // should be above highest dyn_pwm level
+#define THERM_FASTER_LEVEL 130
+#define MIN_THERM_STEPDOWN 65 // should be above highest dyn_pwm level
// use the brightest setting for strobe
#define STROBE_BRIGHTNESS MAX_LEVEL
diff --git a/spaghetti-monster/fsm-ramping.c b/spaghetti-monster/fsm-ramping.c
index 05c2e0e..ee72cd7 100644
--- a/spaghetti-monster/fsm-ramping.c
+++ b/spaghetti-monster/fsm-ramping.c
@@ -293,8 +293,14 @@ void update_tint() {
// calculate actual PWM levels based on a single-channel ramp
// and a global tint value
//PWM_DATATYPE brightness = PWM_GET(pwm1_levels, level);
- PWM_DATATYPE brightness = PWM1_LVL;
- PWM_DATATYPE warm_PWM, cool_PWM;
+ uint16_t brightness = PWM1_LVL;
+ uint16_t warm_PWM, cool_PWM;
+ #ifdef USE_DYN_PWM
+ uint16_t top = PWM1_TOP;
+ //uint16_t top = PWM_GET(pwm_tops, actual_level-1);
+ #else
+ const uint16_t top = PWM_TOP;
+ #endif
// auto-tint modes
uint8_t mytint;
@@ -311,18 +317,37 @@ void update_tint() {
// stretch 1-254 to fit 0-255 range (hits every value except 98 and 198)
else { mytint = (tint * 100 / 99) - 1; }
- // middle tints sag, so correct for that effect
PWM_DATATYPE2 base_PWM = brightness;
- // correction is only necessary when PWM is fast
#if defined(TINT_RAMPING_CORRECTION) && (TINT_RAMPING_CORRECTION > 0)
+ // middle tints sag, so correct for that effect
+ // by adding extra power which peaks at the middle tint
+ // (correction is only necessary when PWM is fast)
if (level > HALFSPEED_LEVEL) {
base_PWM = brightness
+ ((((PWM_DATATYPE2)brightness) * TINT_RAMPING_CORRECTION / 64) * triangle_wave(mytint) / 255);
}
+ // fade the triangle wave out when above 100% power,
+ // so it won't go over 200%
+ if (brightness > top) {
+ base_PWM -= 2 * (
+ ((brightness - top) * TINT_RAMPING_CORRECTION / 64)
+ * triangle_wave(mytint) / 255
+ );
+ }
+ // guarantee no more than 200% power
+ if (base_PWM > (top << 1)) { base_PWM = top << 1; }
#endif
cool_PWM = (((PWM_DATATYPE2)mytint * (PWM_DATATYPE2)base_PWM) + 127) / 255;
warm_PWM = base_PWM - cool_PWM;
+ // when running at > 100% power, spill extra over to other channel
+ if (cool_PWM > top) {
+ warm_PWM += (cool_PWM - top);
+ cool_PWM = top;
+ } else if (warm_PWM > top) {
+ cool_PWM += (warm_PWM - top);
+ warm_PWM = top;
+ }
TINT1_LVL = warm_PWM;
TINT2_LVL = cool_PWM;
diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h
index c1f6064..de090c2 100644
--- a/spaghetti-monster/fsm-ramping.h
+++ b/spaghetti-monster/fsm-ramping.h
@@ -48,26 +48,26 @@ void update_tint();
// auto-detect the data type for PWM tables
#ifndef PWM_BITS
-#define PWM_BITS 8
-#define PWM_TOP 255
+ #define PWM_BITS 8
+ #define PWM_TOP 255
#endif
#if PWM_BITS <= 8
-#define PWM_DATATYPE uint8_t
-#define PWM_DATATYPE2 uint16_t
-#define PWM_TOP 255
-#define PWM_GET(x,y) pgm_read_byte(x+y)
+ #define PWM_DATATYPE uint8_t
+ #define PWM_DATATYPE2 uint16_t
+ #define PWM_TOP 255
+ #define PWM_GET(x,y) pgm_read_byte(x+y)
#else
-#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
-// 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
-#define PWM_GET(x,y) pgm_read_word(x+y)
+ #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
+ // 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
+ #define PWM_GET(x,y) pgm_read_word(x+y)
#endif
// use UI-defined ramp tables if they exist