aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbin/build.sh2
-rw-r--r--hwdef-BLF_LT1-t1616.h107
-rw-r--r--hwdef-BLF_LT1.h55
-rw-r--r--hwdef-Emisar_D4Sv2-tintramp.h182
-rw-r--r--hwdef-Noctigon_KR4.h2
-rw-r--r--spaghetti-monster/anduril/MODELS5
-rw-r--r--spaghetti-monster/anduril/cfg-blf-lantern-t1616.h18
-rw-r--r--spaghetti-monster/anduril/cfg-blf-lantern.h23
-rw-r--r--spaghetti-monster/anduril/cfg-emisar-d4sv2-tintramp-fet.h62
-rw-r--r--spaghetti-monster/anduril/cfg-emisar-d4sv2-tintramp.h84
-rw-r--r--spaghetti-monster/anduril/cfg-ff-rot66.h2
-rw-r--r--spaghetti-monster/anduril/cfg-mateminco-mf01-mini.h2
-rw-r--r--spaghetti-monster/anduril/cfg-noctigon-k9.3-tintramp-219.h10
-rw-r--r--spaghetti-monster/anduril/cfg-noctigon-k9.3-tintramp-fet.h63
-rw-r--r--spaghetti-monster/anduril/cfg-noctigon-k9.3-tintramp-nofet.h84
-rw-r--r--spaghetti-monster/fsm-main.c4
-rw-r--r--spaghetti-monster/fsm-ramping.c138
-rw-r--r--spaghetti-monster/fsm-ramping.h8
18 files changed, 764 insertions, 87 deletions
diff --git a/bin/build.sh b/bin/build.sh
index aa983c8..58896a5 100755
--- a/bin/build.sh
+++ b/bin/build.sh
@@ -30,7 +30,7 @@ export CC=avr-gcc
export OBJCOPY=avr-objcopy
export DFPFLAGS="-B $ATTINY_DFP/gcc/dev/$MCU/ -I $ATTINY_DFP/include/"
export CFLAGS="-Wall -g -Os -mmcu=$MCU -c -std=gnu99 -fgnu89-inline -fwhole-program -DATTINY=$ATTINY -I.. -I../.. -I../../.. -fshort-enums $DFPFLAGS"
-export OFLAGS="-Wall -g -Os -mmcu=$MCU $DFPFLAGS"
+export OFLAGS="-Wall -g -Os -mmcu=$MCU -mrelax $DFPFLAGS"
export LDFLAGS="-fgnu89-inline"
export OBJCOPYFLAGS='--set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0 --no-change-warnings -O ihex'
export OBJS=$PROGRAM.o
diff --git a/hwdef-BLF_LT1-t1616.h b/hwdef-BLF_LT1-t1616.h
new file mode 100644
index 0000000..8e5c58b
--- /dev/null
+++ b/hwdef-BLF_LT1-t1616.h
@@ -0,0 +1,107 @@
+#ifndef HWDEF_BLF_LANTERN_T1616_H
+#define HWDEF_BLF_LANTERN_T1616_H
+
+/* BLF LT1 driver layout using the Attiny1616
+
+Driver pinout:
+ * eSwitch: PA5
+ * Aux LED: PB5
+ * PWM FET: PB0 (TCA0 WO0)
+ * PWM 1x7135: PB1 (TCA0 WO1)
+ * Voltage: VCC
+
+*/
+
+
+#define LAYOUT_DEFINED
+
+#ifdef ATTINY
+#undef ATTINY
+#endif
+#define ATTINY 1616
+#include <avr/io.h>
+
+#define PWM_CHANNELS 1
+
+#ifndef SWITCH_PIN
+#define SWITCH_PIN PIN5_bp
+#define SWITCH_PORT VPORTA.IN
+#define SWITCH_ISC_REG PORTA.PIN2CTRL
+#define SWITCH_VECT PORTA_PORT_vect
+#define SWITCH_INTFLG VPORTA.INTFLAGS
+#endif
+
+
+// usually PWM1_LVL would be a hardware register, but we need to abstract
+// 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;
+
+// warm tint channel
+#ifndef PWM1_PIN
+#define PWM1_PIN PB1 //
+#define TINT1_LVL TCA0.SINGLE.CMP1 // CMP1 is the output compare register for PB1
+#endif
+
+// cold tint channel
+#ifndef PWM2_PIN
+#define PWM2_PIN PB0 //
+#define TINT2_LVL TCA0.SINGLE.CMP0 // CMP0 is the output compare register for PB0
+#endif
+
+// average drop across diode on this hardware
+#ifndef VOLTAGE_FUDGE_FACTOR
+#define VOLTAGE_FUDGE_FACTOR 7 // add 0.35V
+#endif
+
+
+// lighted button
+#ifndef AUXLED_PIN
+#define AUXLED_PIN PIN5_bp
+#define AUXLED_PORT PORTB
+#endif
+
+
+// with so many pins, doing this all with #ifdefs gets awkward...
+// ... so just hardcode it in each hwdef file instead
+inline void hwdef_setup() {
+
+ // set up the system clock to run at 5 MHz instead of the default 3.33 MHz
+ _PROTECTED_WRITE( CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_4X_gc | CLKCTRL_PEN_bm );
+
+ //VPORTA.DIR = ...;
+ VPORTB.DIR = PIN0_bm | PIN1_bm | PIN5_bm; // Outputs: Aux LED and PWMs
+ //VPORTC.DIR = ...;
+
+ // enable pullups on the unused pins to reduce power
+ PORTA.PIN0CTRL = PORT_PULLUPEN_bm;
+ PORTA.PIN1CTRL = PORT_PULLUPEN_bm;
+ PORTA.PIN2CTRL = PORT_PULLUPEN_bm;
+ PORTA.PIN3CTRL = PORT_PULLUPEN_bm;
+ PORTA.PIN4CTRL = PORT_PULLUPEN_bm;
+ PORTA.PIN5CTRL = PORT_PULLUPEN_bm | PORT_ISC_BOTHEDGES_gc; // eSwitch
+ PORTA.PIN6CTRL = PORT_PULLUPEN_bm;
+ PORTA.PIN7CTRL = PORT_PULLUPEN_bm;
+
+ //PORTB.PIN0CTRL = PORT_PULLUPEN_bm; // cold tint channel
+ //PORTB.PIN1CTRL = PORT_PULLUPEN_bm; // warm tint channel
+ PORTB.PIN2CTRL = PORT_PULLUPEN_bm;
+ PORTB.PIN3CTRL = PORT_PULLUPEN_bm;
+ PORTB.PIN4CTRL = PORT_PULLUPEN_bm;
+ //PORTB.PIN5CTRL = PORT_PULLUPEN_bm; // Aux LED
+
+ PORTC.PIN0CTRL = PORT_PULLUPEN_bm;
+ PORTC.PIN1CTRL = PORT_PULLUPEN_bm;
+ PORTC.PIN2CTRL = PORT_PULLUPEN_bm;
+ PORTC.PIN3CTRL = PORT_PULLUPEN_bm;
+
+ // set up the PWM
+ // TODO: add references to MCU documentation
+ TCA0.SINGLE.CTRLB = TCA_SINGLE_CMP0EN_bm | TCA_SINGLE_CMP1EN_bm | TCA_SINGLE_WGMODE_SINGLESLOPE_gc;
+ TCA0.SINGLE.PER = 255;
+ TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV1_gc | TCA_SINGLE_ENABLE_bm;
+}
+
+
+#endif
diff --git a/hwdef-BLF_LT1.h b/hwdef-BLF_LT1.h
new file mode 100644
index 0000000..d0c2821
--- /dev/null
+++ b/hwdef-BLF_LT1.h
@@ -0,0 +1,55 @@
+#ifndef HWDEF_BLF_LT1_H
+#define HWDEF_BLF_LT1_H
+
+/* BLF LT1 driver layout
+ * ----
+ * Reset -|1 8|- VCC
+ * eswitch -|2 7|- (unused)
+ * aux LED -|3 6|- PWM (5000K)
+ * GND -|4 5|- PWM (3000K)
+ * ----
+ */
+
+#define ATTINY 85
+#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_TOP 255
+
+// dynamic PWM with tint ramping (not supported on attiny85)
+//#define USE_DYN_PWM // dynamic frequency and speed
+//#define PWM1_CNT TCNT0 // for dynamic PWM, reset phase
+
+// usually PWM1_LVL would be a hardware register, but we need to abstract
+// 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;
+
+#define PWM1_PIN PB0 // pin 5, warm tint PWM
+#define TINT1_LVL OCR0A // OCR0A is the output compare register for PB0
+
+#define PWM2_PIN PB1 // pin 6, cold tint PWM
+#define TINT2_LVL OCR0B // OCR0B is the output compare register for PB1
+
+
+#define AUXLED_PIN PB4 // pin 3
+
+#define SWITCH_PIN PB3 // pin 2
+#define SWITCH_PCINT PCINT3 // pin 2 pin change interrupt
+
+#define ADC_PRSCL 0x07 // clk/128
+
+// average drop across diode on this hardware
+#ifndef VOLTAGE_FUDGE_FACTOR
+#define VOLTAGE_FUDGE_FACTOR 7 // add 0.35V
+#endif
+
+#define FAST 0xA3 // fast PWM both channels
+#define PHASE 0xA1 // phase-correct PWM both channels
+
+#define LAYOUT_DEFINED
+
+
+#endif
diff --git a/hwdef-Emisar_D4Sv2-tintramp.h b/hwdef-Emisar_D4Sv2-tintramp.h
new file mode 100644
index 0000000..76f6097
--- /dev/null
+++ b/hwdef-Emisar_D4Sv2-tintramp.h
@@ -0,0 +1,182 @@
+#ifndef HWDEF_D4SV2_TINTRAMP_H
+#define HWDEF_D4SV2_TINTRAMP_H
+
+/* Emisar D4Sv2 w/ tint ramping
+ * (based on the Noctigon K9.3 driver layout (attiny1634))
+ *
+ * Pin / Name / Function
+ * 1 PA6 2nd LED PWM (linear) (PWM1B)
+ * 2 PA5 R: red aux LED (PWM0B)
+ * 3 PA4 G: green aux LED
+ * 4 PA3 B: blue aux LED
+ * 5 PA2 button LED
+ * 6 PA1 Opamp 2 enable (2nd LEDs)
+ * 7 PA0 Opamp 1 enable (main LEDs)
+ * 8 GND GND
+ * 9 VCC VCC
+ * 10 PC5 (none)
+ * 11 PC4 (none)
+ * 12 PC3 RESET
+ * 13 PC2 (none)
+ * 14 PC1 SCK
+ * 15 PC0 main LED PWM (FET) (PWM0A) (unused on some models because tint ramping)
+ * 16 PB3 main LED PWM (linear) (PWM1A)
+ * 17 PB2 MISO
+ * 18 PB1 MOSI / battery voltage (ADC6)
+ * 19 PB0 (none)
+ * 20 PA7 e-switch (PCINT7)
+ * ADC12 thermal sensor
+ *
+ * Main LED power uses one pin to turn the Opamp on/off,
+ * and one pin to control Opamp power level.
+ * Main brightness control uses the power level pin, with 4 kHz 10-bit PWM.
+ * The on/off pin is only used to turn the main LED on and off,
+ * not to change brightness.
+ */
+
+#ifdef ATTINY
+#undef ATTINY
+#endif
+#define ATTINY 1634
+#include <avr/io.h>
+
+#define PWM_CHANNELS 1 // 1 virtual channel (1 for main LEDs + 1 for 2nd LEDs)
+#define PWM_BITS 14 // 0 to 16383 at variable Hz, not 0 to 255 at 16 kHz
+#define PWM_TOP 511
+// dynamic PWM with tint ramping
+#define USE_DYN_PWM // dynamic frequency and speed
+#define PWM_DATATYPE2 uint32_t // only needs 32-bit if ramp values go over 255
+
+#define SWITCH_PIN PA7 // pin 20
+#define SWITCH_PCINT PCINT7 // pin 20 pin change interrupt
+#define SWITCH_PCIE PCIE0 // PCIE1 is for PCINT[7:0]
+#define SWITCH_PCMSK PCMSK0 // PCMSK1 is for PCINT[7:0]
+#define SWITCH_PORT PINA // PINA or PINB or PINC
+#define PCINT_vect PCINT0_vect // ISR for PCINT[7:0]
+
+// usually PWM1_LVL would be a hardware register, but we need to abstract
+// 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)
+uint16_t PWM1_LVL;
+#define PWM1_PIN PB3 // pin 16, Opamp reference
+#define TINT1_LVL OCR1A // OCR1A is the output compare register for PB3
+#define PWM1_CNT TCNT1 // for dynamic PWM, reset phase
+
+// gah, this driver is weird...
+// two linear channels are treated as one,
+// while there's also a FET on one channel for turbo on half the LEDs
+// so the FET needs to be "PWM2" but the second linear is "TINT2"
+#define PWM3_PIN PA6 // pin 1, 2nd LED Opamp reference
+#define TINT2_LVL OCR1B // OCR1B is the output compare register for PA6
+
+#define PWM2_PIN PC0 // pin 15, DD FET PWM
+#define PWM2_LVL OCR0A // OCR0A is the output compare register for PC0
+
+// PWM parameters of both channels are tied together because they share a counter
+#define PWM1_TOP ICR1 // holds the TOP value for for variable-resolution PWM
+
+#define LED_ENABLE_PIN PA0 // pin 7, Opamp power
+#define LED_ENABLE_PORT PORTA // control port for PA0
+
+#define LED2_ENABLE_PIN PA1 // pin 6, Opamp power
+#define LED2_ENABLE_PORT PORTA // control port for PA1
+
+
+#define USE_VOLTAGE_DIVIDER // use a dedicated pin, not VCC, because VCC input is flattened
+#define VOLTAGE_PIN PB1 // Pin 18 / PB1 / ADC6
+// pin to ADC mappings are in DS table 19-4
+#define VOLTAGE_ADC ADC6D // digital input disable pin for PB1
+// DIDR0/DIDR1 mappings are in DS section 19.13.5, 19.13.6
+#define VOLTAGE_ADC_DIDR DIDR1 // DIDR channel for ADC6D
+// DS tables 19-3, 19-4
+// Bit 7 6 5 4 3 2 1 0
+// REFS1 REFS0 REFEN ADC0EN MUX3 MUX2 MUX1 MUX0
+// MUX[3:0] = 0, 1, 1, 0 for ADC6 / PB1
+// divided by ...
+// REFS[1:0] = 1, 0 for internal 1.1V reference
+// other bits reserved
+#define ADMUX_VOLTAGE_DIVIDER 0b10000110
+#define ADC_PRSCL 0x07 // clk/128
+
+// Raw ADC readings at 4.4V and 2.2V
+// calibrate the voltage readout here
+// estimated / calculated values are:
+// (voltage - D1) * (R2/(R2+R1) * 1024 / 1.1)
+// D1, R1, R2 = 0, 330, 100
+#ifndef ADC_44
+//#define ADC_44 981 // raw value at 4.40V
+#define ADC_44 967 // manually tweaked so 4.16V will blink out 4.2
+#endif
+#ifndef ADC_22
+//#define ADC_22 489 // raw value at 2.20V
+#define ADC_22 482 // manually tweaked so 4.16V will blink out 4.2
+#endif
+
+// this light has aux LEDs under the optic
+#define AUXLED_R_PIN PA5 // pin 2
+#define AUXLED_G_PIN PA4 // pin 3
+#define AUXLED_B_PIN PA3 // pin 4
+#define AUXLED_RGB_PORT PORTA // PORTA or PORTB or PORTC
+#define AUXLED_RGB_DDR DDRA // DDRA or DDRB or DDRC
+#define AUXLED_RGB_PUE PUEA // PUEA or PUEB or PUEC
+
+#define BUTTON_LED_PIN PA2 // pin 5
+#define BUTTON_LED_PORT PORTA // for all "PA" pins
+#define BUTTON_LED_DDR DDRA // for all "PA" pins
+#define BUTTON_LED_PUE PUEA // for all "PA" pins
+
+// with so many pins, doing this all with #ifdefs gets awkward...
+// ... so just hardcode it in each hwdef file instead
+inline void hwdef_setup() {
+ // enable output ports
+ DDRC = (1 << PWM2_PIN);
+ DDRB = (1 << PWM1_PIN);
+ DDRA = (1 << PWM3_PIN)
+ | (1 << AUXLED_R_PIN)
+ | (1 << AUXLED_G_PIN)
+ | (1 << AUXLED_B_PIN)
+ | (1 << BUTTON_LED_PIN)
+ | (1 << LED_ENABLE_PIN)
+ | (1 << LED2_ENABLE_PIN)
+ ;
+
+ // configure PWM
+ // Setup PWM. F_pwm = F_clkio / 2 / N / TOP, where N = prescale factor, TOP = top of counter
+ // pre-scale for timer: N = 1
+ // Linear opamp PWM for both main and 2nd LEDs (10-bit)
+ // WGM1[3:0]: 1,0,1,0: PWM, Phase Correct, adjustable (DS table 12-5)
+ // CS1[2:0]: 0,0,1: clk/1 (No prescaling) (DS table 12-6)
+ // COM1A[1:0]: 1,0: PWM OC1A in the normal direction (DS table 12-4)
+ // COM1B[1:0]: 1,0: PWM OC1B in the normal direction (DS table 12-4)
+ TCCR1A = (1<<WGM11) | (0<<WGM10) // adjustable PWM (TOP=ICR1) (DS table 12-5)
+ | (1<<COM1A1) | (0<<COM1A0) // PWM 1A in normal direction (DS table 12-4)
+ | (1<<COM1B1) | (0<<COM1B0) // PWM 1B in normal direction (DS table 12-4)
+ ;
+ TCCR1B = (0<<CS12) | (0<<CS11) | (1<<CS10) // clk/1 (no prescaling) (DS table 12-6)
+ | (1<<WGM13) | (0<<WGM12) // phase-correct adjustable PWM (DS table 12-5)
+ ;
+
+ // FET PWM (8-bit; this channel can't do 10-bit)
+ // WGM0[2:0]: 0,0,1: PWM, Phase Correct, 8-bit (DS table 11-8)
+ // CS0[2:0]: 0,0,1: clk/1 (No prescaling) (DS table 11-9)
+ // COM0A[1:0]: 1,0: PWM OC0A in the normal direction (DS table 11-4)
+ // COM0B[1:0]: 1,0: PWM OC0B in the normal direction (DS table 11-7)
+ TCCR0A = (0<<WGM01) | (1<<WGM00) // 8-bit (TOP=0xFF) (DS table 11-8)
+ | (1<<COM0A1) | (0<<COM0A0) // PWM 0A in normal direction (DS table 11-4)
+ //| (1<<COM0B1) | (0<<COM0B0) // PWM 0B in normal direction (DS table 11-7)
+ ;
+ TCCR0B = (0<<CS02) | (0<<CS01) | (1<<CS00) // clk/1 (no prescaling) (DS table 11-9)
+ | (0<<WGM02) // phase-correct PWM (DS table 11-8)
+ ;
+ // set PWM resolution
+ PWM1_TOP = PWM_TOP;
+
+ // set up e-switch
+ PUEA = (1 << SWITCH_PIN); // pull-up for e-switch
+ SWITCH_PCMSK = (1 << SWITCH_PCINT); // enable pin change interrupt
+}
+
+#define LAYOUT_DEFINED
+
+#endif
diff --git a/hwdef-Noctigon_KR4.h b/hwdef-Noctigon_KR4.h
index eee4e08..75dd4c6 100644
--- a/hwdef-Noctigon_KR4.h
+++ b/hwdef-Noctigon_KR4.h
@@ -132,7 +132,7 @@ inline void hwdef_setup() {
// configure PWM
// Setup PWM. F_pwm = F_clkio / 2 / N / TOP, where N = prescale factor, TOP = top of counter
// pre-scale for timer: N = 1
- // WGM1[3:0]: 0,0,1,1: PWM, Phase Correct, 10-bit (DS table 12-5)
+ // WGM1[3:0]: 1,0,1,0: PWM, Phase Correct, adjustable (DS table 12-5)
// CS1[2:0]: 0,0,1: clk/1 (No prescaling) (DS table 12-6)
// COM1A[1:0]: 1,0: PWM OC1A in the normal direction (DS table 12-4)
// COM1B[1:0]: 1,0: PWM OC1B in the normal direction (DS table 12-4)
diff --git a/spaghetti-monster/anduril/MODELS b/spaghetti-monster/anduril/MODELS
index f4a0531..11f7dfa 100644
--- a/spaghetti-monster/anduril/MODELS
+++ b/spaghetti-monster/anduril/MODELS
@@ -11,6 +11,8 @@ Model numbers:
0132 emisar-d4s-219c
0133 emisar-d4sv2
0134 emisar-d4sv2-219
+0135 emisar-d4sv2-tintramp
+0136 emisar-d4sv2-tintramp-fet
0141 emisar-d18
0142 emisar-d18-219
0211 noctigon-kr4
@@ -23,6 +25,9 @@ Model numbers:
0261 noctigon-k9.3
0262 noctigon-k9.3-nofet
0263 noctigon-k9.3-219
+0265 noctigon-k9.3-tintramp-nofet
+0266 noctigon-k9.3-tintramp-fet
+0267 noctigon-k9.3-tintramp-219
0311 fw3a
0312 fw3a-219
0313 fw3a-nofet
diff --git a/spaghetti-monster/anduril/cfg-blf-lantern-t1616.h b/spaghetti-monster/anduril/cfg-blf-lantern-t1616.h
index 51c3d6a..56c7275 100644
--- a/spaghetti-monster/anduril/cfg-blf-lantern-t1616.h
+++ b/spaghetti-monster/anduril/cfg-blf-lantern-t1616.h
@@ -1,12 +1,6 @@
// BLF Lantern config options for Anduril using the Attiny1616
#define MODEL_NUMBER "0622"
-/* BLF Lantern pinout
- * PB0 is 5000K channel
- * PB1 is 3000K channel
- */
-
-// basically the same as a Q8... sort of
-#include "hwdef-BLF_Q8-T1616.h"
+#include "hwdef-BLF_LT1-t1616.h"
// ATTINY: 1616
// the button lights up
@@ -53,7 +47,7 @@
// LT1 can handle heat well, so don't limit simple mode
#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR
-#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL
+#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL
#define SIMPLE_UI_STEPS RAMP_DISCRETE_STEPS
#define USE_SOS_MODE
@@ -65,14 +59,6 @@
#undef USE_THERMAL_REGULATION
#endif
-// also, the set_level_gradually() thing isn't compatible with tint ramping
-// (but unsetting it here doesn't actually do anything, because the thermal
-// regulation define enables it later... so this is mostly just a note to
-// make this compatibility issue explicit)
-#ifdef USE_SET_LEVEL_GRADUALLY
-#undef USE_SET_LEVEL_GRADUALLY
-#endif
-
// don't blink while ramping
#ifdef BLINK_AT_RAMP_MIDDLE
#undef BLINK_AT_RAMP_MIDDLE
diff --git a/spaghetti-monster/anduril/cfg-blf-lantern.h b/spaghetti-monster/anduril/cfg-blf-lantern.h
index 28c7dbb..48ed1f7 100644
--- a/spaghetti-monster/anduril/cfg-blf-lantern.h
+++ b/spaghetti-monster/anduril/cfg-blf-lantern.h
@@ -1,16 +1,7 @@
// BLF Lantern config options for Anduril
#define MODEL_NUMBER "0621"
-/* BLF Lantern pinout
- * ----
- * Reset -|1 8|- VCC
- * eswitch -|2 7|- powerbank enable?
- * aux LED -|3 6|- PWM (5000K)
- * GND -|4 5|- PWM (3000K)
- * ----
- */
-
-// basically the same as a Q8... sort of
-#include "hwdef-BLF_Q8.h"
+#include "hwdef-BLF_LT1.h"
+// ATTINY: 85
// the button lights up
#define USE_INDICATOR_LED
@@ -56,7 +47,7 @@
// LT1 can handle heat well, so don't limit simple mode
#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR
-#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL
+#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL
#define SIMPLE_UI_STEPS RAMP_DISCRETE_STEPS
#define USE_SOS_MODE
@@ -68,14 +59,6 @@
#undef USE_THERMAL_REGULATION
#endif
-// also, the set_level_gradually() thing isn't compatible with tint ramping
-// (but unsetting it here doesn't actually do anything, because the thermal
-// regulation define enables it later... so this is mostly just a note to
-// make this compatibility issue explicit)
-#ifdef USE_SET_LEVEL_GRADUALLY
-#undef USE_SET_LEVEL_GRADUALLY
-#endif
-
// don't blink while ramping
#ifdef BLINK_AT_RAMP_MIDDLE
#undef BLINK_AT_RAMP_MIDDLE
diff --git a/spaghetti-monster/anduril/cfg-emisar-d4sv2-tintramp-fet.h b/spaghetti-monster/anduril/cfg-emisar-d4sv2-tintramp-fet.h
new file mode 100644
index 0000000..3c638a7
--- /dev/null
+++ b/spaghetti-monster/anduril/cfg-emisar-d4sv2-tintramp-fet.h
@@ -0,0 +1,62 @@
+// Emisar D4S V2 tint-ramping (plus FET) config options for Anduril (based on Noctigon K9.3)
+#include "cfg-emisar-d4sv2-tintramp.h"
+#undef MODEL_NUMBER
+#define MODEL_NUMBER "0136"
+// ATTINY: 1634
+
+// enable the FET channel, even though it's ... kinda funky
+#undef PWM_CHANNELS
+#define PWM_CHANNELS 2
+
+// main LEDs
+// output: unknown, 2000 lm?
+// FET: unknown, 3000 lm?
+// 2nd LEDs
+// output: unknown, 2000 lm?
+#define RAMP_LENGTH 150
+// level_calc.py 5.01 1 140 7135 1 0.2 2000 --pwm dyn:69:16383:511
+// plus a FET segment
+// level_calc.py 2 1 10 7135 5 50.0 3000 --pwm 255
+// abstract ramp (power is split between both sets of LEDs)
+// append: ,500,482,456,420,374,318,252,178,94,0
+#undef PWM1_LEVELS
+#define PWM1_LEVELS 1,1,1,2,2,3,3,4,5,5,6,7,8,9,10,12,13,14,16,18,19,21,23,25,27,30,32,35,37,40,43,45,48,51,54,58,61,64,67,70,74,77,80,83,86,89,92,95,97,99,101,103,105,106,106,107,106,106,104,102,100,96,92,87,81,73,65,56,45,33,35,37,39,41,43,45,47,49,52,54,57,59,62,65,68,71,74,78,81,85,89,92,96,100,105,109,114,118,123,128,133,139,144,150,156,162,168,175,181,188,195,202,210,217,225,233,242,250,259,268,278,287,297,307,318,328,339,351,362,374,386,399,412,425,438,452,466,481,496,511,500,482,456,420,374,318,252,178,94,0
+// append: ,511,511,511,511,511,511,511,511,511,511
+#undef PWM_TOPS
+#define PWM_TOPS 16383,13469,10296,14694,10845,14620,11496,13507,14400,11954,12507,12676,12605,12376,12036,12805,12240,11650,11882,11933,11243,11155,10988,10763,10497,10569,10223,10164,9781,9646,9475,9071,8870,8652,8422,8330,8077,7823,7569,7318,7169,6919,6676,6439,6209,5986,5770,5561,5305,5063,4834,4618,4413,4180,3925,3723,3468,3264,3016,2787,2576,2333,2111,1885,1658,1412,1189,968,734,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
+// prepend: 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,0,0,0,0,0,0,0,0,0,0,
+#define 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,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,5,14,27,45,68,96,129,166,208,255
+#undef DEFAULT_LEVEL
+#define DEFAULT_LEVEL 70
+#undef MAX_1x7135
+#define MAX_1x7135 140
+
+#undef RAMP_SMOOTH_FLOOR
+#define RAMP_SMOOTH_FLOOR 10 // level 1 is unreliable (?)
+#undef RAMP_SMOOTH_CEIL
+#define RAMP_SMOOTH_CEIL 130
+// 10, 30, 50, [70], 90, 110, [130]
+#undef RAMP_DISCRETE_FLOOR
+#define RAMP_DISCRETE_FLOOR 10
+#undef RAMP_DISCRETE_CEIL
+#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#undef RAMP_DISCRETE_STEPS
+#define RAMP_DISCRETE_STEPS 7
+
+// safe limit highest regulated power (no FET or turbo)
+#undef SIMPLE_UI_FLOOR
+#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR
+#undef SIMPLE_UI_CEIL
+#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL
+#undef SIMPLE_UI_STEPS
+#define SIMPLE_UI_STEPS 5
+
+// stop panicking at ~2000 lm
+#undef THERM_FASTER_LEVEL
+#define THERM_FASTER_LEVEL 140
+#undef MIN_THERM_STEPDOWN
+#define MIN_THERM_STEPDOWN 70 // should be above highest dyn_pwm level
+
+// speed up party strobe; the FET is really fast
+#undef PARTY_STROBE_ONTIME
+
diff --git a/spaghetti-monster/anduril/cfg-emisar-d4sv2-tintramp.h b/spaghetti-monster/anduril/cfg-emisar-d4sv2-tintramp.h
new file mode 100644
index 0000000..c170645
--- /dev/null
+++ b/spaghetti-monster/anduril/cfg-emisar-d4sv2-tintramp.h
@@ -0,0 +1,84 @@
+// Emisar D4S V2 tint-ramping config options for Anduril (based on Noctigon K9.3)
+#define MODEL_NUMBER "0135"
+#include "hwdef-Emisar_D4Sv2-tintramp.h"
+#include "hank-cfg.h"
+// ATTINY: 1634
+
+// this light has three aux LED channels: R, G, B
+#define USE_AUX_RGB_LEDS
+// the aux LEDs are front-facing, so turn them off while main LEDs are on
+// it also has an independent LED in the button
+#define USE_BUTTON_LED
+// TODO: the whole "indicator LED" thing needs to be refactored into
+// "aux LED(s)" and "button LED(s)" since they work a bit differently
+// enabling this option breaks the button LED on D4v2.5
+#ifdef USE_INDICATOR_LED_WHILE_RAMPING
+#undef USE_INDICATOR_LED_WHILE_RAMPING
+#endif
+
+// has two channels of independent LEDs
+#define USE_TINT_RAMPING
+// how much to increase total brightness at middle tint
+// (0 = 100% brightness, 64 = 200% brightness)
+#define TINT_RAMPING_CORRECTION 0 // none, linear regulator doesn't need it
+
+// main LEDs
+// output: unknown, 2000 lm?
+// FET: absent / unused?
+// 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
+#define DEFAULT_LEVEL 70
+#define MAX_1x7135 150
+#define HALFSPEED_LEVEL 10
+#define QUARTERSPEED_LEVEL 2
+
+#define USE_MANUAL_MEMORY_TIMER_FOR_TINT
+//#define DEFAULT_MANUAL_MEMORY DEFAULT_LEVEL
+//#define DEFAULT_MANUAL_MEMORY_TIMER 10
+
+#define RAMP_SMOOTH_FLOOR 10 // level 1 is unreliable (?)
+#define RAMP_SMOOTH_CEIL 130
+// 10, 30, 50, [70], 90, 110, [130]
+#define RAMP_DISCRETE_FLOOR 10
+#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#define RAMP_DISCRETE_STEPS 7
+
+// safe limit highest regulated power (no FET or turbo)
+#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR
+#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL
+#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
+
+// use the brightest setting for strobe
+#define STROBE_BRIGHTNESS MAX_LEVEL
+// slow down party strobe; this driver can't pulse for 1ms or less
+#define PARTY_STROBE_ONTIME 2
+
+// the default of 26 looks a bit flat, so increase it
+#define CANDLE_AMPLITUDE 40
+
+// the power regulator is a bit slow, so push it harder for a quick response from off
+#define DEFAULT_JUMP_START_LEVEL 21
+#define BLINK_BRIGHTNESS DEFAULT_LEVEL
+#define BLINK_ONCE_TIME 12 // longer blink, since main LEDs are slow
+
+#define THERM_CAL_OFFSET 5
+
+#ifdef BLINK_AT_RAMP_MIDDLE
+#undef BLINK_AT_RAMP_MIDDLE
+#endif
+
+// for consistency with KR4 (not otherwise necessary though)
+#define USE_SOFT_FACTORY_RESET
+
+
+// work around bizarre bug: lockout mode fails when set to solid color blinking
+#define USE_K93_LOCKOUT_KLUDGE
diff --git a/spaghetti-monster/anduril/cfg-ff-rot66.h b/spaghetti-monster/anduril/cfg-ff-rot66.h
index 7e21fe7..48541a7 100644
--- a/spaghetti-monster/anduril/cfg-ff-rot66.h
+++ b/spaghetti-monster/anduril/cfg-ff-rot66.h
@@ -43,3 +43,5 @@
// too big, remove stuff to make room
#undef USE_RAMP_AFTER_MOON_CONFIG
+#undef USE_RAMP_SPEED_CONFIG
+//#undef USE_2C_STYLE_CONFIG
diff --git a/spaghetti-monster/anduril/cfg-mateminco-mf01-mini.h b/spaghetti-monster/anduril/cfg-mateminco-mf01-mini.h
index 962317e..86e8c26 100644
--- a/spaghetti-monster/anduril/cfg-mateminco-mf01-mini.h
+++ b/spaghetti-monster/anduril/cfg-mateminco-mf01-mini.h
@@ -53,4 +53,6 @@
// too big, remove stuff to make room
+#undef USE_RAMP_AFTER_MOON_CONFIG
#undef USE_RAMP_SPEED_CONFIG
+//#undef USE_2C_STYLE_CONFIG
diff --git a/spaghetti-monster/anduril/cfg-noctigon-k9.3-tintramp-219.h b/spaghetti-monster/anduril/cfg-noctigon-k9.3-tintramp-219.h
new file mode 100644
index 0000000..04efa83
--- /dev/null
+++ b/spaghetti-monster/anduril/cfg-noctigon-k9.3-tintramp-219.h
@@ -0,0 +1,10 @@
+// Noctigon K9.3 tint-ramping (reduced FET) config options for Anduril
+#include "cfg-noctigon-k9.3-tintramp-fet.h"
+#undef MODEL_NUMBER
+#define MODEL_NUMBER "0267"
+// ATTINY: 1634
+
+// 85% FET power
+#undef PWM2_LEVELS
+#define 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,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,4,11,17,24,33,41,51,60,70,80,91,103,116,129,141,156,170,185,200,216
+
diff --git a/spaghetti-monster/anduril/cfg-noctigon-k9.3-tintramp-fet.h b/spaghetti-monster/anduril/cfg-noctigon-k9.3-tintramp-fet.h
new file mode 100644
index 0000000..8535c57
--- /dev/null
+++ b/spaghetti-monster/anduril/cfg-noctigon-k9.3-tintramp-fet.h
@@ -0,0 +1,63 @@
+// Noctigon K9.3 tint-ramping (plus FET) config options for Anduril
+#include "cfg-noctigon-k9.3-tintramp-nofet.h"
+#undef MODEL_NUMBER
+#define MODEL_NUMBER "0266"
+// ATTINY: 1634
+
+// enable the FET channel, even though it's ... kinda funky
+#undef PWM_CHANNELS
+#define PWM_CHANNELS 2
+
+// main LEDs
+// output: 3000 lm?
+// FET: 5000 to 7500 lm
+// 2nd LEDs
+// output: 1500 lm?
+#define RAMP_LENGTH 150
+// level_calc.py 5.01 1 130 7135 1 0.2 2000 --pwm dyn:64:16383:511
+// plus a FET segment
+// level_calc.py 2 1 20 7135 5 1000.0 7000 --pwm 255
+// abstract ramp (power is split between both sets of LEDs)
+// ','.join([str(511 - int(x*2.005)) for x in fet])
+#undef PWM1_LEVELS
+// append: ,501,485,469,453,433,413,391,369,345,321,295,267,237,207,177,143,108,74,38,0
+#define PWM1_LEVELS 1,1,1,2,2,3,3,4,5,6,7,8,9,10,12,13,15,16,18,20,22,24,27,29,32,34,37,40,43,46,49,53,56,59,63,66,70,73,77,80,83,87,90,93,96,98,100,103,104,105,106,107,106,105,104,101,98,94,89,83,76,67,57,46,33,35,37,39,41,43,46,48,51,53,56,59,62,65,68,72,75,79,83,86,91,95,99,104,108,113,118,123,129,135,140,146,153,159,166,172,179,187,194,202,210,218,227,236,245,254,264,274,284,295,306,317,328,340,352,365,378,391,405,419,433,448,463,479,495,511,501,485,469,453,433,413,391,369,345,321,295,267,237,207,177,143,108,74,38,0
+#undef PWM_TOPS
+// append: ,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511
+#define PWM_TOPS 16383,13233,9780,13825,9592,13434,9971,12020,12899,13192,13149,12898,12507,12022,12665,11981,12180,11421,11392,11246,11017,10730,10825,10433,10364,9926,9766,9564,9331,9075,8805,8692,8394,8095,7927,7625,7438,7142,6947,6664,6392,6202,5945,5699,5464,5186,4925,4726,4450,4194,3956,3734,3462,3212,2982,2717,2475,2230,1985,1741,1500,1244,996,755,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
+// prepend: 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,
+#define 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,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,5,13,21,29,39,49,60,71,83,95,108,122,137,152,167,184,201,218,236,255
+#undef DEFAULT_LEVEL
+#define DEFAULT_LEVEL 70
+#undef MAX_1x7135
+#define MAX_1x7135 130
+
+#undef RAMP_SMOOTH_FLOOR
+#define RAMP_SMOOTH_FLOOR 10 // level 1 is unreliable (?)
+#undef RAMP_SMOOTH_CEIL
+#define RAMP_SMOOTH_CEIL 130
+// 10, 30, 50, [70], 90, 110, [130]
+#undef RAMP_DISCRETE_FLOOR
+#define RAMP_DISCRETE_FLOOR 10
+#undef RAMP_DISCRETE_CEIL
+#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#undef RAMP_DISCRETE_STEPS
+#define RAMP_DISCRETE_STEPS 7
+
+// safe limit highest regulated power (no FET or turbo)
+#undef SIMPLE_UI_FLOOR
+#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR
+#undef SIMPLE_UI_CEIL
+#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL
+#undef SIMPLE_UI_STEPS
+#define SIMPLE_UI_STEPS 5
+
+// stop panicking at ~3000 lm
+#undef THERM_FASTER_LEVEL
+#define THERM_FASTER_LEVEL 130
+#undef MIN_THERM_STEPDOWN
+#define MIN_THERM_STEPDOWN 65 // should be above highest dyn_pwm level
+
+// speed up party strobe; the FET is really fast
+#undef PARTY_STROBE_ONTIME
+
diff --git a/spaghetti-monster/anduril/cfg-noctigon-k9.3-tintramp-nofet.h b/spaghetti-monster/anduril/cfg-noctigon-k9.3-tintramp-nofet.h
new file mode 100644
index 0000000..21ab415
--- /dev/null
+++ b/spaghetti-monster/anduril/cfg-noctigon-k9.3-tintramp-nofet.h
@@ -0,0 +1,84 @@
+// Noctigon K9.3 noFET tint-ramping config options for Anduril
+#define MODEL_NUMBER "0265"
+#include "hwdef-Emisar_D4Sv2-tintramp.h"
+#include "hank-cfg.h"
+// ATTINY: 1634
+
+// this light has three aux LED channels: R, G, B
+#define USE_AUX_RGB_LEDS
+// the aux LEDs are front-facing, so turn them off while main LEDs are on
+// it also has an independent LED in the button
+#define USE_BUTTON_LED
+// TODO: the whole "indicator LED" thing needs to be refactored into
+// "aux LED(s)" and "button LED(s)" since they work a bit differently
+// enabling this option breaks the button LED on D4v2.5
+#ifdef USE_INDICATOR_LED_WHILE_RAMPING
+#undef USE_INDICATOR_LED_WHILE_RAMPING
+#endif
+
+// has two channels of independent LEDs
+#define USE_TINT_RAMPING
+// how much to increase total brightness at middle tint
+// (0 = 100% brightness, 64 = 200% brightness)
+#define TINT_RAMPING_CORRECTION 0 // none, linear regulator doesn't need it
+
+// main LEDs
+// output: 3000 lm?
+// FET: disabled
+// 2nd LEDs
+// output: 1500 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
+#define DEFAULT_LEVEL 70
+#define MAX_1x7135 150
+#define HALFSPEED_LEVEL 10
+#define QUARTERSPEED_LEVEL 2
+
+#define USE_MANUAL_MEMORY_TIMER_FOR_TINT
+//#define DEFAULT_MANUAL_MEMORY DEFAULT_LEVEL
+//#define DEFAULT_MANUAL_MEMORY_TIMER 10
+
+#define RAMP_SMOOTH_FLOOR 10 // level 1 is unreliable (?)
+#define RAMP_SMOOTH_CEIL 130
+// 10, 30, 50, [70], 90, 110, [130]
+#define RAMP_DISCRETE_FLOOR 10
+#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#define RAMP_DISCRETE_STEPS 7
+
+// safe limit highest regulated power (no FET or turbo)
+#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR
+#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL
+#define SIMPLE_UI_STEPS 5
+
+// stop panicking at ~2000 lm
+#define THERM_FASTER_LEVEL 140
+#define MIN_THERM_STEPDOWN 75 // should be above highest dyn_pwm level
+
+// use the brightest setting for strobe
+#define STROBE_BRIGHTNESS MAX_LEVEL
+// slow down party strobe; this driver can't pulse for 1ms or less
+#define PARTY_STROBE_ONTIME 2
+
+// the default of 26 looks a bit flat, so increase it
+#define CANDLE_AMPLITUDE 40
+
+// the power regulator is a bit slow, so push it harder for a quick response from off
+#define DEFAULT_JUMP_START_LEVEL 21
+#define BLINK_BRIGHTNESS DEFAULT_LEVEL
+#define BLINK_ONCE_TIME 12 // longer blink, since main LEDs are slow
+
+#define THERM_CAL_OFFSET 9
+
+#ifdef BLINK_AT_RAMP_MIDDLE
+#undef BLINK_AT_RAMP_MIDDLE
+#endif
+
+// for consistency with KR4 (not otherwise necessary though)
+#define USE_SOFT_FACTORY_RESET
+
+
+// work around bizarre bug: lockout mode fails when set to solid color blinking
+#define USE_K93_LOCKOUT_KLUDGE
diff --git a/spaghetti-monster/fsm-main.c b/spaghetti-monster/fsm-main.c
index f3c319c..7031009 100644
--- a/spaghetti-monster/fsm-main.c
+++ b/spaghetti-monster/fsm-main.c
@@ -47,7 +47,9 @@ static inline void hw_setup() {
TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...)
TCCR0A = PHASE;
#endif
- #if PWM_CHANNELS >= 2
+ // tint ramping needs second channel enabled,
+ // despite PWM_CHANNELS being only 1
+ #if (PWM_CHANNELS >= 2) || defined(USE_TINT_RAMPING)
DDRB |= (1 << PWM2_PIN);
#endif
#if PWM_CHANNELS >= 3
diff --git a/spaghetti-monster/fsm-ramping.c b/spaghetti-monster/fsm-ramping.c
index 54ca45c..e8fcde7 100644
--- a/spaghetti-monster/fsm-ramping.c
+++ b/spaghetti-monster/fsm-ramping.c
@@ -89,6 +89,10 @@ void set_level(uint8_t level) {
#if PWM_CHANNELS >= 4
PWM4_LVL = 0;
#endif
+ #ifdef USE_TINT_RAMPING
+ TINT1_LVL = 0;
+ TINT2_LVL = 0;
+ #endif
// disable the power channel, if relevant
#ifdef LED_ENABLE_PIN
LED_ENABLE_PORT &= ~(1 << LED_ENABLE_PIN);
@@ -117,44 +121,6 @@ void set_level(uint8_t level) {
// PWM array index = level - 1
level --;
- #ifdef USE_TINT_RAMPING
- #ifndef TINT_RAMPING_CORRECTION
- #define TINT_RAMPING_CORRECTION 26 // 140% brightness at middle tint
- #endif
- // calculate actual PWM levels based on a single-channel ramp
- // and a global tint value
- uint8_t brightness = PWM_GET(pwm1_levels, level);
- uint8_t warm_PWM, cool_PWM;
-
- // auto-tint modes
- uint8_t mytint;
- #if 1
- // perceptual by ramp level
- if (tint == 0) { mytint = 255 * (uint16_t)level / RAMP_SIZE; }
- else if (tint == 255) { mytint = 255 - (255 * (uint16_t)level / RAMP_SIZE); }
- #else
- // linear with power level
- //if (tint == 0) { mytint = brightness; }
- //else if (tint == 255) { mytint = 255 - brightness; }
- #endif
- // 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
- uint16_t base_PWM = brightness;
- // correction is only necessary when PWM is fast
- if (level > HALFSPEED_LEVEL) {
- base_PWM = brightness
- + ((((uint16_t)brightness) * TINT_RAMPING_CORRECTION / 64) * triangle_wave(mytint) / 255);
- }
-
- cool_PWM = (((uint16_t)mytint * (uint16_t)base_PWM) + 127) / 255;
- warm_PWM = base_PWM - cool_PWM;
-
- PWM1_LVL = warm_PWM;
- PWM2_LVL = cool_PWM;
- #else // ifdef USE_TINT_RAMPING
-
#if PWM_CHANNELS >= 1
PWM1_LVL = PWM_GET(pwm1_levels, level);
#endif
@@ -168,8 +134,6 @@ void set_level(uint8_t level) {
PWM4_LVL = PWM_GET(pwm4_levels, level);
#endif
- #endif // ifdef USE_TINT_RAMPING
-
#ifdef USE_DYN_PWM
uint16_t top = PWM_GET(pwm_tops, level);
#ifdef PWM1_CNT
@@ -214,6 +178,10 @@ void set_level(uint8_t level) {
}
#endif
}
+ #ifdef USE_TINT_RAMPING
+ update_tint();
+ #endif
+
#ifdef PWM1_CNT
prev_level = api_level;
#endif
@@ -236,6 +204,7 @@ void gradual_tick() {
if (gt < actual_level) gt = actual_level - 1;
else if (gt > actual_level) gt = actual_level + 1;
+ /*
#ifdef LED_ENABLE_PIN_LEVEL_MIN
// only enable during part of the ramp
if ((gt >= LED_ENABLE_PIN_LEVEL_MIN)
@@ -244,6 +213,7 @@ void gradual_tick() {
else // disable during other parts of the ramp
LED_ENABLE_PORT &= ~(1 << LED_ENABLE_PIN);
#endif
+ */
gt --; // convert 1-based number to 0-based
@@ -251,14 +221,23 @@ void gradual_tick() {
#if PWM_CHANNELS >= 1
target = PWM_GET(pwm1_levels, gt);
- if ((gt < actual_level) // special case for FET-only turbo
- && (PWM1_LVL == 0) // (bypass adjustment period for first step)
- && (target == PWM_TOP)) PWM1_LVL = PWM_TOP;
- else if (PWM1_LVL < target) PWM1_LVL ++;
+ #if PWM_CHANNELS > 1
+ if ((gt < actual_level) // special case for FET-only turbo
+ && (PWM1_LVL == 0) // (bypass adjustment period for first step)
+ && (target == PWM_TOP)) PWM1_LVL = PWM_TOP;
+ else
+ #endif
+ if (PWM1_LVL < target) PWM1_LVL ++;
else if (PWM1_LVL > target) PWM1_LVL --;
#endif
#if PWM_CHANNELS >= 2
target = PWM_GET(pwm2_levels, gt);
+ #if PWM_CHANNELS > 2
+ if ((gt < actual_level) // special case for FET-only turbo
+ && (PWM2_LVL == 0) // (bypass adjustment period for first step)
+ && (target == PWM_TOP)) PWM2_LVL = PWM_TOP;
+ else
+ #endif
if (PWM2_LVL < target) PWM2_LVL ++;
else if (PWM2_LVL > target) PWM2_LVL --;
#endif
@@ -287,14 +266,77 @@ void gradual_tick() {
#endif
)
{
- actual_level = gt + 1;
+ //actual_level = gt + 1;
+ set_level(gt + 1);
}
- #ifdef USE_DYNAMIC_UNDERCLOCKING
- auto_clock_speed();
- #endif
+ // is handled in set_level()
+ //#ifdef USE_TINT_RAMPING
+ //update_tint();
+ //#endif
+ // is handled in set_level()
+ //#ifdef USE_DYNAMIC_UNDERCLOCKING
+ //auto_clock_speed();
+ //#endif
}
#endif // ifdef OVERRIDE_GRADUAL_TICK
#endif // ifdef USE_SET_LEVEL_GRADUALLY
+
+#if defined(USE_TINT_RAMPING) && (!defined(TINT_RAMP_TOGGLE_ONLY))
+void update_tint() {
+ #ifndef TINT_RAMPING_CORRECTION
+ #define TINT_RAMPING_CORRECTION 26 // 140% brightness at middle tint
+ #endif
+
+ // 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;
+
+ // auto-tint modes
+ uint8_t mytint;
+ uint8_t level = actual_level - 1;
+ #if 1
+ // perceptual by ramp level
+ if (tint == 0) { mytint = 255 * (uint16_t)level / RAMP_SIZE; }
+ else if (tint == 255) { mytint = 255 - (255 * (uint16_t)level / RAMP_SIZE); }
+ #else
+ // linear with power level
+ //if (tint == 0) { mytint = brightness; }
+ //else if (tint == 255) { mytint = 255 - brightness; }
+ #endif
+ // 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)
+ if (level > HALFSPEED_LEVEL) {
+ base_PWM = brightness
+ + ((((PWM_DATATYPE2)brightness) * TINT_RAMPING_CORRECTION / 64) * triangle_wave(mytint) / 255);
+ }
+ #endif
+
+ cool_PWM = (((PWM_DATATYPE2)mytint * (PWM_DATATYPE2)base_PWM) + 127) / 255;
+ warm_PWM = base_PWM - cool_PWM;
+
+ TINT1_LVL = warm_PWM;
+ TINT2_LVL = cool_PWM;
+
+ // disable the power channel, if relevant
+ #ifdef LED_ENABLE_PIN
+ if (! warm_PWM)
+ LED_ENABLE_PORT &= ~(1 << LED_ENABLE_PIN);
+ #endif
+ #ifdef LED2_ENABLE_PIN
+ if (! cool_PWM)
+ LED2_ENABLE_PORT &= ~(1 << LED2_ENABLE_PIN);
+ #endif
+}
+#endif // ifdef USE_TINT_RAMPING
+
+
#endif // ifdef USE_RAMPING
#endif
diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h
index 7a4fa3b..c1f6064 100644
--- a/spaghetti-monster/fsm-ramping.h
+++ b/spaghetti-monster/fsm-ramping.h
@@ -42,6 +42,10 @@ 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
@@ -49,10 +53,14 @@ void gradual_tick();
#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)
#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