diff options
Diffstat (limited to '')
| -rw-r--r-- | hwdef-Noctigon_K1-12V.h | 6 | ||||
| -rw-r--r-- | hwdef-Noctigon_K9.3.h | 164 | ||||
| -rw-r--r-- | spaghetti-monster/anduril/MODELS | 1 | ||||
| -rw-r--r-- | spaghetti-monster/anduril/anduril.c | 5 | ||||
| -rw-r--r-- | spaghetti-monster/anduril/cfg-noctigon-k9.3-nofet.h | 54 | ||||
| -rw-r--r-- | spaghetti-monster/anduril/cfg-noctigon-k9.3.c | 105 | ||||
| -rw-r--r-- | spaghetti-monster/anduril/cfg-noctigon-k9.3.h | 86 | ||||
| -rw-r--r-- | spaghetti-monster/anduril/misc.c | 5 | ||||
| -rw-r--r-- | spaghetti-monster/anduril/off-mode.c | 3 | ||||
| -rw-r--r-- | spaghetti-monster/anduril/ramp-mode.h | 10 | ||||
| -rw-r--r-- | spaghetti-monster/anduril/tint-ramping.c | 28 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-eeprom.c | 8 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-ramping.c | 17 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-ramping.h | 4 |
14 files changed, 481 insertions, 15 deletions
diff --git a/hwdef-Noctigon_K1-12V.h b/hwdef-Noctigon_K1-12V.h index 8781d8e..b17aad0 100644 --- a/hwdef-Noctigon_K1-12V.h +++ b/hwdef-Noctigon_K1-12V.h @@ -56,8 +56,8 @@ #define LED_ENABLE_PIN PB0 // pin 19, Opamp power #define LED_ENABLE_PORT PORTB // control port for PB0 -#define LED_ENABLE2_PIN PC0 // pin 15, boost PMIC enable -#define LED_ENABLE2_PORT PORTC // control port for PC0 +#define LED2_ENABLE_PIN PC0 // pin 15, boost PMIC enable +#define LED2_ENABLE_PORT PORTC // control port for PC0 #define USE_VOLTAGE_DIVIDER // use a dedicated pin, not VCC, because VCC input is flattened @@ -103,7 +103,7 @@ inline void hwdef_setup() { // enable output ports // boost PMIC on/off - DDRC = (1 << LED_ENABLE2_PIN); + DDRC = (1 << LED2_ENABLE_PIN); // Opamp level and Opamp on/off DDRB = (1 << PWM1_PIN) | (1 << LED_ENABLE_PIN); diff --git a/hwdef-Noctigon_K9.3.h b/hwdef-Noctigon_K9.3.h new file mode 100644 index 0000000..6032b4c --- /dev/null +++ b/hwdef-Noctigon_K9.3.h @@ -0,0 +1,164 @@ +#ifndef HWDEF_NOCTIGON_K93_H +#define HWDEF_NOCTIGON_K93_H + +/* 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) + * 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. + * Some models also have a direct-drive FET for turbo. + */ + +#ifdef ATTINY +#undef ATTINY +#endif +#define ATTINY 1634 +#include <avr/io.h> + +#define PWM_CHANNELS 3 // 2 for main LEDs, 1 for 2nd LEDs +#define PWM_BITS 10 // 0 to 1023 at 4 kHz, not 0 to 255 at 16 kHz +#define PWM_TOP 1023 + +#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] + +#define PWM1_PIN PB3 // pin 16, Opamp reference +#define PWM1_LVL OCR1A // OCR1A is the output compare register for PB3 + +#define PWM2_PIN PC0 // pin 15, DD FET PWM +#define PWM2_LVL OCR0A // OCR0A is the output compare register for PC0 + +#define PWM3_PIN PA6 // pin 1, 2nd LED Opamp reference +#define PWM3_LVL OCR1B // OCR1B is the output compare register for PA6 + +#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]: 0,0,1,1: PWM, Phase Correct, 10-bit (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) | (1<<WGM10) // 10-bit (TOP=0x03FF) (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) + | (0<<WGM13) | (0<<WGM12) // phase-correct 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 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/spaghetti-monster/anduril/MODELS b/spaghetti-monster/anduril/MODELS index 84d6795..173620a 100644 --- a/spaghetti-monster/anduril/MODELS +++ b/spaghetti-monster/anduril/MODELS @@ -18,6 +18,7 @@ Model numbers: 0251 noctigon-k1 0252 noctigon-k1-sbt90 0253 noctigon-k1-12v +0261 noctigon-k9.3 0311 fw3a 0312 fw3a-219 0313 fw3a-nofet diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c index f632229..de9b332 100644 --- a/spaghetti-monster/anduril/anduril.c +++ b/spaghetti-monster/anduril/anduril.c @@ -91,6 +91,11 @@ #include "spaghetti-monster.h" +/********* does this build target have special code to include? *********/ +#ifdef OVERRIDES_FILE +#include incfile(OVERRIDES_FILE) +#endif + /********* Include all the regular app headers *********/ diff --git a/spaghetti-monster/anduril/cfg-noctigon-k9.3-nofet.h b/spaghetti-monster/anduril/cfg-noctigon-k9.3-nofet.h new file mode 100644 index 0000000..e91ebc4 --- /dev/null +++ b/spaghetti-monster/anduril/cfg-noctigon-k9.3-nofet.h @@ -0,0 +1,54 @@ +// Noctigon K9.3 (noFET) config options for Anduril +#include "cfg-noctigon-k9.3.h" +#undef MODEL_NUMBER +#define MODEL_NUMBER "0262" +// ATTINY: 1634 + +// don't use the highest power channel +#define K93_NO_FET + +// main LEDs +#undef PWM1_LEVELS +#undef PWM2_LEVELS +#define PWM1_LEVELS 0,0,1,1,2,2,3,3,4,4,5,5,6,7,8,9,10,11,12,13,15,16,17,18,20,21,23,24,26,27,29,31,33,35,37,39,41,43,45,48,50,53,55,58,61,63,66,69,72,75,79,82,85,89,92,96,100,104,108,112,116,120,125,129,134,138,143,148,153,158,163,169,174,180,185,191,197,203,209,215,222,228,235,242,248,255,263,270,277,285,292,300,308,316,324,333,341,350,359,368,377,386,395,405,414,424,434,444,454,465,475,486,497,508,519,531,542,554,566,578,590,603,615,628,641,654,667,680,694,708,722,736,750,765,779,794,809,825,840,856,872,888,904,920,937,954,971,988,1005,1023 +// FET channel: unused, all zeroes +#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,0,0,0,0,0,0,0,0,0,0 +// 2nd LEDs +#undef PWM3_LEVELS +#define PWM3_LEVELS 0,0,1,1,2,2,3,3,4,4,5,5,6,7,8,9,10,11,12,13,15,16,17,18,20,21,23,24,26,27,29,31,33,35,37,39,41,43,45,48,50,53,55,58,61,63,66,69,72,75,79,82,85,89,92,96,100,104,108,112,116,120,125,129,134,138,143,148,153,158,163,169,174,180,185,191,197,203,209,215,222,228,235,242,248,255,263,270,277,285,292,300,308,316,324,333,341,350,359,368,377,386,395,405,414,424,434,444,454,465,475,486,497,508,519,531,542,554,566,578,590,603,615,628,641,654,667,680,694,708,722,736,750,765,779,794,809,825,840,856,872,888,904,920,937,954,971,988,1005,1023 +#undef DEFAULT_LEVEL +#define DEFAULT_LEVEL 50 +#undef MAX_1x7135 +#undef MAX_Nx7135 +#define MAX_1x7135 150 +#define MAX_Nx7135 MAX_1x7135 + +#undef RAMP_SMOOTH_FLOOR +#undef RAMP_SMOOTH_CEIL +#undef RAMP_DISCRETE_FLOOR +#undef RAMP_DISCRETE_CEIL +#undef RAMP_DISCRETE_STEPS + +#define RAMP_SMOOTH_FLOOR 3 // level 1 is unreliable(?) +#define RAMP_SMOOTH_CEIL 130 +// 10, 30, [50], 70, 90, 110, 130 (plus [150] on turbo) +#define RAMP_DISCRETE_FLOOR 10 +#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL +#define RAMP_DISCRETE_STEPS 7 + +// safe limit same as full UI +#undef SIMPLE_UI_FLOOR +#undef SIMPLE_UI_CEIL +#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR +#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL + + +// make candle mode wobble more +#define CANDLE_AMPLITUDE 32 + +// stop panicking at ~90% power or ~1600 lm +#undef THERM_FASTER_LEVEL +#define THERM_FASTER_LEVEL 143 +#undef MIN_THERM_STEPDOWN +#define MIN_THERM_STEPDOWN DEFAULT_LEVEL + diff --git a/spaghetti-monster/anduril/cfg-noctigon-k9.3.c b/spaghetti-monster/anduril/cfg-noctigon-k9.3.c new file mode 100644 index 0000000..5cb027a --- /dev/null +++ b/spaghetti-monster/anduril/cfg-noctigon-k9.3.c @@ -0,0 +1,105 @@ +/* + * K9.3 has unusual power channels, so it must override some of FSM's code. + * There are two sets of LEDs: + * 1. Main LEDs: (9 x white LEDs) + * PWM1 (10-bit, linear) + * PWM2 (8-bit, FET, only used on some K9.3 models) + * 2. 2nd LEDs: (3 x white or color LEDs) + * PWM3 (10-bit, linear) + * + * The two sets are not used at the same time... just one or the other, + * depending on the "tint" variable. (0 = main LEDs, other value = 2nd LEDs) + */ +// if the gradual adjustment mechanism doesn't work, disable it here: +//#ifdef USE_SET_LEVEL_GRADUALLY +//#undef USE_SET_LEVEL_GRADUALLY +//#endif + +// this is inserted into fsm-ramping.c :: set_level() +// (it overrides part of the function, but not all of it) +inline void set_level_override(uint8_t level) { + if (level == 0) { // off + PWM1_LVL = 0; + PWM2_LVL = 0; + PWM3_LVL = 0; + // disable both power channels + LED_ENABLE_PORT &= ~(1 << LED_ENABLE_PIN); + LED2_ENABLE_PORT &= ~(1 << LED2_ENABLE_PIN); + } else { + level --; + + if (! tint) { // main LEDs + // enable this power channel + LED_ENABLE_PORT |= (1 << LED_ENABLE_PIN); + // disable other power channel + LED2_ENABLE_PORT &= ~(1 << LED2_ENABLE_PIN); + // set levels + PWM1_LVL = PWM_GET(pwm1_levels, level); + #ifndef K93_NO_FET + PWM2_LVL = (uint8_t)(PWM_GET(pwm2_levels, level) >> 2); // 8 bits + #endif + PWM3_LVL = 0; + } else { // 2nd LEDs + // disable other power channel + LED_ENABLE_PORT &= ~(1 << LED_ENABLE_PIN); + // enable this power channel + LED2_ENABLE_PORT |= (1 << LED2_ENABLE_PIN); + // set levels + PWM1_LVL = 0; + PWM2_LVL = 0; + PWM3_LVL = PWM_GET(pwm3_levels, level); + } + } +} + +// override fsm-ramping.c :: gradual_tick() +// (because the power handling on this light is weird) +// call this every frame or every few frames to change brightness very smoothly +void gradual_tick() { + // go by only one ramp level at a time instead of directly to the target + uint8_t gt = gradual_target; + if (gt < actual_level) gt = actual_level - 1; + else if (gt > actual_level) gt = actual_level + 1; + + gt --; // convert 1-based number to 0-based + + PWM_DATATYPE target; + + if (! tint) { // main LED channel + 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 ++; + else if (PWM1_LVL > target) PWM1_LVL --; + + #ifndef K93_NO_FET // skip this on E21A model + target = PWM_GET(pwm2_levels, gt) >> 2; // 8 bits, not 10 + if (PWM2_LVL < target) PWM2_LVL ++; + else if (PWM2_LVL > target) PWM2_LVL --; + #endif + + // did we go far enough to hit the next defined ramp level? + // if so, update the main ramp level tracking var + if ((PWM1_LVL == PWM_GET(pwm1_levels, gt)) + #ifndef K93_NO_FET + && (PWM2_LVL == (PWM_GET(pwm2_levels, gt) >> 2)) + #endif + ) + { actual_level = gt + 1; } + } else { // 2nd LED channel + target = PWM_GET(pwm3_levels, gt); + if (PWM3_LVL < target) PWM3_LVL ++; + else if (PWM3_LVL > target) PWM3_LVL --; + + // did we go far enough to hit the next defined ramp level? + // if so, update the main ramp level tracking var + if ( PWM3_LVL == PWM_GET(pwm3_levels, gt) ) + { actual_level = gt + 1; } + } + + #ifdef USE_DYNAMIC_UNDERCLOCKING + auto_clock_speed(); + #endif +} + diff --git a/spaghetti-monster/anduril/cfg-noctigon-k9.3.h b/spaghetti-monster/anduril/cfg-noctigon-k9.3.h new file mode 100644 index 0000000..4d3d3d9 --- /dev/null +++ b/spaghetti-monster/anduril/cfg-noctigon-k9.3.h @@ -0,0 +1,86 @@ +// Noctigon K9.3 config options for Anduril +#define MODEL_NUMBER "0261" +#include "hwdef-Noctigon_K9.3.h" +// ATTINY: 1634 +// this model requires some special code +#define OVERRIDES_FILE cfg-noctigon-k9.3.c +#define OVERRIDE_SET_LEVEL +#define OVERRIDE_GRADUAL_TICK +inline void set_level_override(uint8_t level); + + +// this light has three aux LED channels: R, G, B +#define USE_AUX_RGB_LEDS +#define RGB_LED_OFF_DEFAULT 0x18 // low, rainbow +// the aux LEDs are front-facing, so turn them off while main LEDs are on +//#define USE_AUX_RGB_LEDS_WHILE_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 + +// enable blinking aux LEDs +#define TICK_DURING_STANDBY +#define STANDBY_TICK_SPEED 3 // every 0.128 s + +// has two channels of independent LEDs +#define USE_TINT_RAMPING +// ... but it doesn't make sense to ramp between; only toggle +#define TINT_RAMP_TOGGLE_ONLY + +// main LEDs +// max regulated: ~1750 lm +// FET: ~8000 lm +// 2nd LEDs +// max regulated: ~1500 lm +// maxreg at 120: level_calc.py cube 2 150 7135 0 2.5 1740 FET 1 10 3190 +#define RAMP_LENGTH 150 +// main LEDs +#define PWM1_LEVELS 0,0,1,1,2,2,3,3,4,4,5,6,7,8,9,10,11,13,14,15,17,19,20,22,24,26,28,30,33,35,38,40,43,46,49,52,55,59,62,66,70,74,78,82,86,91,96,100,105,111,116,121,127,133,139,145,151,158,165,172,179,186,193,201,209,217,225,234,243,251,261,270,280,289,299,310,320,331,342,353,364,376,388,400,412,425,438,451,464,478,492,506,521,536,551,566,582,597,614,630,647,664,681,699,717,735,754,772,792,811,831,851,871,892,913,935,956,978,1001,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,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,22,51,79,109,138,168,198,229,260,292,324,357,390,423,457,492,527,562,598,634,671,708,746,784,822,861,901,941,982,1023 +// 2nd LEDs +#define PWM3_LEVELS 0,0,1,1,2,2,3,3,4,4,5,5,6,7,8,9,10,11,12,13,15,16,17,18,20,21,23,24,26,27,29,31,33,35,37,39,41,43,45,48,50,53,55,58,61,63,66,69,72,75,79,82,85,89,92,96,100,104,108,112,116,120,125,129,134,138,143,148,153,158,163,169,174,180,185,191,197,203,209,215,222,228,235,242,248,255,263,270,277,285,292,300,308,316,324,333,341,350,359,368,377,386,395,405,414,424,434,444,454,465,475,486,497,508,519,531,542,554,566,578,590,603,615,628,641,654,667,680,694,708,722,736,750,765,779,794,809,825,840,856,872,888,904,920,937,954,971,988,1005,1023 +#define DEFAULT_LEVEL 46 +#define MAX_1x7135 120 +#define MAX_Nx7135 MAX_1x7135 +#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 3 // level 1 is unreliable (?) +#define RAMP_SMOOTH_CEIL 120 +// 10, 28, [46], 65, 83, 101, [120] +#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 ~25% power or ~1000 lm +#define THERM_FASTER_LEVEL 100 +#define MIN_THERM_STEPDOWN DEFAULT_LEVEL +//#define THERM_NEXT_WARNING_THRESHOLD 16 // accumulate less error before adjusting +//#define THERM_RESPONSE_MAGNITUDE 128 // bigger adjustments + +// 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 + +#define BLINK_ONCE_TIME 12 // longer blink, since main LEDs are slow + +#define THERM_CAL_OFFSET 5 + +// for consistency with KR4 (not otherwise necessary though) +#define USE_SOFT_FACTORY_RESET + diff --git a/spaghetti-monster/anduril/misc.c b/spaghetti-monster/anduril/misc.c index 63b8f48..523bbf0 100644 --- a/spaghetti-monster/anduril/misc.c +++ b/spaghetti-monster/anduril/misc.c @@ -38,13 +38,16 @@ void blink_confirm(uint8_t num) { // make a short, visible pulse // (either brighter or darker, depending on current brightness) +#ifndef BLINK_ONCE_TIME +#define BLINK_ONCE_TIME 10 +#endif void blink_once() { uint8_t brightness = actual_level; uint8_t bump = brightness + (MAX_LEVEL/6); if (bump > MAX_LEVEL) bump = 0; set_level(bump); - delay_4ms(10/4); + delay_4ms(BLINK_ONCE_TIME/4); set_level(brightness); } diff --git a/spaghetti-monster/anduril/off-mode.c b/spaghetti-monster/anduril/off-mode.c index 5ebaa1d..34d9e6d 100644 --- a/spaghetti-monster/anduril/off-mode.c +++ b/spaghetti-monster/anduril/off-mode.c @@ -133,6 +133,9 @@ uint8_t off_state(Event event, uint16_t arg) { && (off_time >= (manual_memory_timer * SLEEP_TICKS_PER_MINUTE)) #endif ) { + #if defined(USE_MANUAL_MEMORY_TIMER_FOR_TINT) && defined(USE_TINT_RAMPING) && defined(TINT_RAMP_TOGGLE_ONLY) + tint = 0; + #endif set_level(nearest_level(manual_memory)); } else #endif diff --git a/spaghetti-monster/anduril/ramp-mode.h b/spaghetti-monster/anduril/ramp-mode.h index b772407..ed806bd 100644 --- a/spaghetti-monster/anduril/ramp-mode.h +++ b/spaghetti-monster/anduril/ramp-mode.h @@ -148,9 +148,15 @@ void set_level_and_therm_target(uint8_t level); // brightness control uint8_t memorized_level = DEFAULT_LEVEL; #ifdef USE_MANUAL_MEMORY -uint8_t manual_memory = 0; +#ifndef DEFAULT_MANUAL_MEMORY +#define DEFAULT_MANUAL_MEMORY 0 +#endif +uint8_t manual_memory = DEFAULT_MANUAL_MEMORY; #ifdef USE_MANUAL_MEMORY_TIMER -uint8_t manual_memory_timer = 0; +#ifndef DEFAULT_MANUAL_MEMORY_TIMER +#define DEFAULT_MANUAL_MEMORY_TIMER 0 +#endif +uint8_t manual_memory_timer = DEFAULT_MANUAL_MEMORY_TIMER; #endif #endif #ifdef USE_SIMPLE_UI diff --git a/spaghetti-monster/anduril/tint-ramping.c b/spaghetti-monster/anduril/tint-ramping.c index 0196bc7..0b077ef 100644 --- a/spaghetti-monster/anduril/tint-ramping.c +++ b/spaghetti-monster/anduril/tint-ramping.c @@ -22,6 +22,32 @@ #include "tint-ramping.h" +#ifdef TINT_RAMP_TOGGLE_ONLY + +uint8_t tint_ramping_state(Event event, uint16_t arg) { + // click, click, hold: change the tint + if (event == EV_click3_hold) { + // toggle once on first frame; ignore other frames + if (! arg) { + tint = !tint; + set_level(actual_level); + blink_once(); + } + return EVENT_HANDLED; + } + + // click, click, hold, release: save config + else if (event == EV_click3_hold_release) { + // remember tint after battery change + save_config(); + return EVENT_HANDLED; + } + + return EVENT_NOT_HANDLED; +} + +#else // no TINT_RAMP_TOGGLE_ONLY + uint8_t tint_ramping_state(Event event, uint16_t arg) { static int8_t tint_ramp_direction = 1; static uint8_t prev_tint = 0; @@ -82,6 +108,8 @@ uint8_t tint_ramping_state(Event event, uint16_t arg) { return EVENT_NOT_HANDLED; } +#endif // ifdef TINT_RAMP_TOGGLE_ONLY + #endif diff --git a/spaghetti-monster/fsm-eeprom.c b/spaghetti-monster/fsm-eeprom.c index 0de7e05..4c734a2 100644 --- a/spaghetti-monster/fsm-eeprom.c +++ b/spaghetti-monster/fsm-eeprom.c @@ -30,7 +30,7 @@ uint8_t eeprom[EEPROM_BYTES]; #endif uint8_t load_eeprom() { - #ifdef LED_ENABLE_PIN + #if defined(LED_ENABLE_PIN) || defined(LED2_ENABLE_PIN) delay_4ms(2); // wait for power to stabilize #endif @@ -48,7 +48,7 @@ uint8_t load_eeprom() { } void save_eeprom() { - #ifdef LED_ENABLE_PIN + #if defined(LED_ENABLE_PIN) || defined(LED2_ENABLE_PIN) delay_4ms(2); // wait for power to stabilize #endif @@ -70,7 +70,7 @@ uint8_t eeprom_wl[EEPROM_WL_BYTES]; uint8_t * eep_wl_prev_offset; uint8_t load_eeprom_wl() { - #ifdef LED_ENABLE_PIN + #if defined(LED_ENABLE_PIN) || defined(LED2_ENABLE_PIN) delay_4ms(2); // wait for power to stabilize #endif @@ -99,7 +99,7 @@ uint8_t load_eeprom_wl() { } void save_eeprom_wl() { - #ifdef LED_ENABLE_PIN + #if defined(LED_ENABLE_PIN) || defined(LED2_ENABLE_PIN) delay_4ms(2); // wait for power to stabilize #endif diff --git a/spaghetti-monster/fsm-ramping.c b/spaghetti-monster/fsm-ramping.c index 8ad4b65..0768f8d 100644 --- a/spaghetti-monster/fsm-ramping.c +++ b/spaghetti-monster/fsm-ramping.c @@ -54,6 +54,10 @@ void set_level(uint8_t level) { #endif #endif + #ifdef OVERRIDE_SET_LEVEL + set_level_override(level); + #else + //TCCR0A = PHASE; if (level == 0) { #if PWM_CHANNELS >= 1 @@ -72,8 +76,8 @@ void set_level(uint8_t level) { #ifdef LED_ENABLE_PIN LED_ENABLE_PORT &= ~(1 << LED_ENABLE_PIN); #endif - #ifdef LED_ENABLE2_PIN - LED_ENABLE2_PORT &= ~(1 << LED_ENABLE2_PIN); + #ifdef LED2_ENABLE_PIN + LED2_ENABLE_PORT &= ~(1 << LED2_ENABLE_PIN); #endif } else { // enable the power channel, if relevant @@ -89,8 +93,8 @@ void set_level(uint8_t level) { LED_ENABLE_PORT &= ~(1 << LED_ENABLE_PIN); #endif #endif - #ifdef LED_ENABLE2_PIN - LED_ENABLE2_PORT |= (1 << LED_ENABLE2_PIN); + #ifdef LED2_ENABLE_PIN + LED2_ENABLE_PORT |= (1 << LED2_ENABLE_PIN); #endif level --; @@ -148,6 +152,7 @@ void set_level(uint8_t level) { #endif // ifdef USE_TINT_RAMPING } + #endif // ifdef OVERRIDE_SET_LEVEL #ifdef USE_DYNAMIC_UNDERCLOCKING auto_clock_speed(); #endif @@ -158,6 +163,7 @@ inline void set_level_gradually(uint8_t lvl) { gradual_target = lvl; } +#ifndef OVERRIDE_GRADUAL_TICK // call this every frame or every few frames to change brightness very smoothly void gradual_tick() { // go by only one ramp level at a time instead of directly to the target @@ -222,7 +228,8 @@ void gradual_tick() { auto_clock_speed(); #endif } -#endif +#endif // ifdef OVERRIDE_GRADUAL_TICK +#endif // ifdef USE_SET_LEVEL_GRADUALLY #endif // ifdef USE_RAMPING #endif diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h index f177db9..8fd89c7 100644 --- a/spaghetti-monster/fsm-ramping.h +++ b/spaghetti-monster/fsm-ramping.h @@ -27,7 +27,11 @@ uint8_t actual_level = 0; #ifdef USE_TINT_RAMPING +#ifdef TINT_RAMP_TOGGLE_ONLY +uint8_t tint = 0; +#else uint8_t tint = 128; +#endif #define USE_TRIANGLE_WAVE #endif |
