diff options
| -rw-r--r-- | spaghetti-monster/anduril/anduril.c | 53 | ||||
| -rw-r--r-- | spaghetti-monster/anduril/cfg-blf-lantern.h | 73 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-ramping.c | 18 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-ramping.h | 4 |
4 files changed, 147 insertions, 1 deletions
diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c index 09c7927..0d35fb0 100644 --- a/spaghetti-monster/anduril/anduril.c +++ b/spaghetti-monster/anduril/anduril.c @@ -125,6 +125,9 @@ typedef enum { ramp_discrete_floor_e, ramp_discrete_ceil_e, ramp_discrete_steps_e, + #ifdef USE_TINT_RAMPING + tint_e, + #endif #ifdef USE_STROBE_STATE strobe_type_e, #endif @@ -174,6 +177,10 @@ uint8_t config_state_values[MAX_CONFIG_VALUES]; // ramping mode and its related config mode uint8_t steady_state(Event event, uint16_t arg); uint8_t ramp_config_state(Event event, uint16_t arg); +#ifdef USE_TINT_RAMPING +// not actually a mode, more of a fallback under other modes +uint8_t tint_ramping_state(Event event, uint16_t arg); +#endif // party and tactical strobes #ifdef USE_STROBE_STATE uint8_t strobe_state(Event event, uint16_t arg); @@ -785,6 +792,39 @@ uint8_t steady_state(Event event, uint16_t arg) { } +#ifdef USE_TINT_RAMPING +uint8_t tint_ramping_state(Event event, uint16_t arg) { + static int8_t tint_ramp_direction = 1; + + // click, click, hold: change the tint + if (event == EV_click3_hold) { + //if ((arg & 1) == 0) { // ramp slower + if ((tint_ramp_direction > 0) && (tint < 255)) { + tint += 1; + } + else if ((tint_ramp_direction < 0) && (tint > 0)) { + tint -= 1; + } + set_level(actual_level); + //} + return EVENT_HANDLED; + } + + // click, click, hold, release: reverse direction for next ramp + else if (event == EV_click3_hold_release) { + tint_ramp_direction = -tint_ramp_direction; + if (tint == 0) tint_ramp_direction = 1; + else if (tint == 255) tint_ramp_direction = -1; + // remember tint after battery change + save_config(); + return EVENT_HANDLED; + } + + return EVENT_NOT_HANDLED; +} +#endif // ifdef USE_TINT_RAMPING + + #ifdef USE_STROBE_STATE uint8_t strobe_state(Event event, uint16_t arg) { // 'st' reduces ROM size by avoiding access to a volatile var @@ -1681,6 +1721,9 @@ void load_config() { ramp_discrete_floor = eeprom[ramp_discrete_floor_e]; ramp_discrete_ceil = eeprom[ramp_discrete_ceil_e]; ramp_discrete_steps = eeprom[ramp_discrete_steps_e]; + #ifdef USE_TINT_RAMPING + tint = eeprom[tint_e]; + #endif #if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE) strobe_type = eeprom[strobe_type_e]; // TODO: move this to eeprom_wl? strobe_delays[0] = eeprom[strobe_delays_0_e]; @@ -1715,6 +1758,9 @@ void save_config() { eeprom[ramp_discrete_floor_e] = ramp_discrete_floor; eeprom[ramp_discrete_ceil_e] = ramp_discrete_ceil; eeprom[ramp_discrete_steps_e] = ramp_discrete_steps; + #ifdef USE_TINT_RAMPING + eeprom[tint_e] = tint; + #endif #if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE) eeprom[strobe_type_e] = strobe_type; // TODO: move this to eeprom_wl? eeprom[strobe_delays_0_e] = strobe_delays[0]; @@ -1811,14 +1857,19 @@ void setup() { load_config(); + #ifdef USE_TINT_RAMPING + // add tint ramping underneath every other state + push_state(tint_ramping_state, 0); + #endif // ifdef USE_TINT_RAMPING + #ifdef USE_MUGGLE_MODE if (muggle_mode_active) push_state(muggle_state, (MUGGLE_FLOOR+MUGGLE_CEILING)/2); else #endif push_state(off_state, 0); - #endif + #endif // ifdef START_AT_MEMORIZED_LEVEL } diff --git a/spaghetti-monster/anduril/cfg-blf-lantern.h b/spaghetti-monster/anduril/cfg-blf-lantern.h new file mode 100644 index 0000000..a1bda7d --- /dev/null +++ b/spaghetti-monster/anduril/cfg-blf-lantern.h @@ -0,0 +1,73 @@ +// BLF Lantern config options for Anduril +/* 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" + +// the button lights up +#define USE_INDICATOR_LED +// the button is visible while main LEDs are on +#define USE_INDICATOR_LED_WHILE_RAMPING +// enable blinking indicator LED while off +#define TICK_DURING_STANDBY +#define STANDBY_TICK_SPEED 3 // every 0.128 s +#define USE_FANCIER_BLINKING_INDICATOR +// off mode: high (2) +// lockout: blinking (3) +#define INDICATOR_LED_DEFAULT_MODE ((3<<2) + 2) + +// the lantern has two PWM channels, but they drive different sets of emitters +// (one channel for warm emitters, one channel for cold) +// so enable a special ramping mode which changes tint instead of brightness +#define USE_TINT_RAMPING + +#ifdef RAMP_LENGTH +#undef RAMP_LENGTH +#endif + +// level_calc.py 1 150 7135 1 30 800 +#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 HALFSPEED_LEVEL 14 +#define QUARTERSPEED_LEVEL 5 + +// 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_DISCRETE_FLOOR 20 +#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL +#define RAMP_DISCRETE_STEPS 5 + +// the sensor (attiny85) is nowhere near the emitters +// so thermal regulation can't work +#ifdef USE_THERMAL_REGULATION +#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_CHANNEL_BOUNDARIES +#undef BLINK_AT_CHANNEL_BOUNDARIES +#endif +#ifdef BLINK_AT_RAMP_CEILING +#undef BLINK_AT_RAMP_CEILING +#endif +#ifdef BLINK_AT_RAMP_FLOOR +#undef BLINK_AT_RAMP_FLOOR +#endif diff --git a/spaghetti-monster/fsm-ramping.c b/spaghetti-monster/fsm-ramping.c index 6cdf5e6..ee816dd 100644 --- a/spaghetti-monster/fsm-ramping.c +++ b/spaghetti-monster/fsm-ramping.c @@ -25,9 +25,11 @@ void set_level(uint8_t level) { actual_level = level; + #ifdef USE_SET_LEVEL_GRADUALLY gradual_target = level; #endif + #ifdef USE_INDICATOR_LED #ifdef USE_INDICATOR_LED_WHILE_RAMPING if (! go_to_standby) @@ -40,6 +42,7 @@ void set_level(uint8_t level) { indicator_led(0); #endif #endif + //TCCR0A = PHASE; if (level == 0) { #if PWM_CHANNELS >= 1 @@ -56,6 +59,19 @@ void set_level(uint8_t level) { #endif } else { level --; + + #ifdef USE_TINT_RAMPING + // calculate actual PWM levels based on a single-channel ramp + // and a global tint value + uint8_t brightness = pgm_read_byte(pwm1_levels + level); + uint8_t warm_PWM, cool_PWM; + cool_PWM = (((uint16_t)tint * (uint16_t)brightness) + 127) / 255; + warm_PWM = brightness - cool_PWM; + + PWM1_LVL = warm_PWM; + PWM2_LVL = cool_PWM; + #else + #if PWM_CHANNELS >= 1 PWM1_LVL = pgm_read_byte(pwm1_levels + level); #endif @@ -68,6 +84,8 @@ void set_level(uint8_t level) { #if PWM_CHANNELS >= 4 PWM4_LVL = pgm_read_byte(pwm4_levels + level); #endif + + #endif // ifdef USE_TINT_RAMPING } #ifdef USE_DYNAMIC_UNDERCLOCKING auto_clock_speed(); diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h index 14c8dae..4ce8015 100644 --- a/spaghetti-monster/fsm-ramping.h +++ b/spaghetti-monster/fsm-ramping.h @@ -26,6 +26,10 @@ // actual_level: last ramp level set by set_level() volatile uint8_t actual_level = 0; +#ifdef USE_TINT_RAMPING +uint8_t tint = 128; +#endif + #ifdef USE_SET_LEVEL_GRADUALLY // adjust brightness very smoothly volatile uint8_t gradual_target; |
