From 849fcfd3e1b828c6f35d62792a308917b2ef0053 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Fri, 26 Jul 2019 20:51:38 -0600 Subject: merged a sanitized copy of the Emisar D4v2 branch; history summarized below: ------------------------------------------------------------ revno: 457 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Thu 2019-07-18 22:42:50 -0600 message: make sure no thermal events are handled while off (even though it shouldn't be possible, since it only happens after 15 minutes, and the light is only awake in muggle-off mode for 1 second) modified: ToyKeeper/spaghetti-monster/anduril/anduril.c ------------------------------------------------------------ revno: 456 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Thu 2019-07-18 20:09:58 -0600 message: don't measure temperature while asleep (fixes bug on D4 V2, where it would start flashing after 15 minutes turned off in muggle mode) (also should speed up response to battery voltage changes while asleep) modified: ToyKeeper/spaghetti-monster/fsm-adc.c ------------------------------------------------------------ revno: 455 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Thu 2019-07-18 20:05:56 -0600 message: made strobe brightness configurable per build target modified: ToyKeeper/spaghetti-monster/anduril/anduril.c ------------------------------------------------------------ revno: 454 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Wed 2019-07-10 10:22:44 -0600 message: made the "therm faster" code only affect ramping down, and fixed a couple minor logic issues in the thermal regulation code modified: ToyKeeper/spaghetti-monster/anduril/anduril.c ToyKeeper/spaghetti-monster/fsm-adc.c ------------------------------------------------------------ revno: 452 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Sat 2019-07-06 08:18:25 -0600 message: fixed spelling error in D4 / D4V2 files modified: ToyKeeper/spaghetti-monster/anduril/cfg-emisar-d4.h ToyKeeper/spaghetti-monster/anduril/cfg-emisar-d4v2.h ------------------------------------------------------------ revno: 451 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Sat 2019-07-06 08:16:57 -0600 message: fixed placement of #ifdefs on reboot loop prevention modified: ToyKeeper/spaghetti-monster/fsm-main.c ------------------------------------------------------------ revno: 450 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Sat 2019-07-06 08:15:59 -0600 message: made level_calc.py also find and show the channel transition points, so I won't have to do this manually all the time modified: bin/level_calc.py ------------------------------------------------------------ revno: 449 [merge] committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Sat 2019-07-06 05:31:37 -0600 message: merged from fsm branch to get factory reset function modified: ToyKeeper/spaghetti-monster/anduril/anduril-manual.txt ToyKeeper/spaghetti-monster/anduril/anduril.c ToyKeeper/spaghetti-monster/anduril/anduril.txt ToyKeeper/spaghetti-monster/anduril/cfg-fw3a.h ToyKeeper/spaghetti-monster/fsm-main.c ToyKeeper/spaghetti-monster/fsm-misc.c ToyKeeper/spaghetti-monster/fsm-misc.h ------------------------------------------------------------ revno: 448 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Sat 2019-07-06 05:13:40 -0600 message: started adding some ideas for later (maybe), but not currently used... ... may remove again later modified: ToyKeeper/spaghetti-monster/fsm-adc.c ------------------------------------------------------------ revno: 447 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Sat 2019-07-06 05:13:11 -0600 message: adjusted D4 / D4v2 thermal response again; it really doesn't want to behave modified: ToyKeeper/spaghetti-monster/anduril/cfg-emisar-d4.h ToyKeeper/spaghetti-monster/anduril/cfg-emisar-d4v2.h ------------------------------------------------------------ revno: 446 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Mon 2019-06-17 03:18:06 -0600 message: made d4 ramp slightly smoother at clock speed change modified: ToyKeeper/spaghetti-monster/anduril/cfg-emisar-d4.h ToyKeeper/spaghetti-monster/anduril/cfg-emisar-d4v2.h ------------------------------------------------------------ revno: 445 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Mon 2019-06-17 03:17:40 -0600 message: improved D4S thermal response; less prone to overshooting and oscillation modified: ToyKeeper/spaghetti-monster/anduril/cfg-emisar-d4s.h ------------------------------------------------------------ revno: 444 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Thu 2019-06-06 23:12:26 -0600 message: adjusted Emisar D4 thermal response values... (this light really doesn't want to behave thermally, so the values here don't quite get an ideal response, but they're a lot better than they were) modified: ToyKeeper/spaghetti-monster/anduril/cfg-emisar-d4.h ToyKeeper/spaghetti-monster/anduril/cfg-emisar-d4v2.h ------------------------------------------------------------ revno: 443 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Thu 2019-06-06 23:11:08 -0600 message: made anduril raise brightness slower when doing thermal regulation, made hard turbo drop only activate when it's actually at turbo modified: ToyKeeper/spaghetti-monster/anduril/anduril.c ------------------------------------------------------------ revno: 442 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Thu 2019-06-06 23:09:54 -0600 message: made more thermal parameters configurable... - the speed of thermal history rotation (every 1s, 2s, or 4s) - prediction strength also made minimum time between temperature warnings factor in the lowpass, so the default is 5s again instead of 7s modified: ToyKeeper/spaghetti-monster/fsm-adc.c ------------------------------------------------------------ revno: 441 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Wed 2019-06-05 03:39:34 -0600 message: adjusted d4v2 ramp to hit 1x7135 exactly at level 4/7, turned off hard turbo drop because it doesn't seem to be needed any more modified: ToyKeeper/spaghetti-monster/anduril/cfg-emisar-d4v2.h ------------------------------------------------------------ revno: 440 [merge] committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Wed 2019-06-05 03:33:21 -0600 message: merged updates from fsm branch added: ToyKeeper/spaghetti-monster/anduril/cfg-ff-e01.h ToyKeeper/spaghetti-monster/fireflies-ui/cfg-ff-e07-2.h renamed: ToyKeeper/spaghetti-monster/fireflies-ui/cfg-ff-edc-thrower.h => ToyKeeper/spaghetti-monster/fireflies-ui/cfg-ff-e01.h modified: ToyKeeper/spaghetti-monster/anduril/anduril.c ToyKeeper/spaghetti-monster/fireflies-ui/Makefile ToyKeeper/spaghetti-monster/fireflies-ui/build-all.sh ToyKeeper/spaghetti-monster/fireflies-ui/fireflies-ui.c ToyKeeper/spaghetti-monster/fireflies-ui/meta ToyKeeper/spaghetti-monster/fsm-events.h ToyKeeper/spaghetti-monster/fireflies-ui/cfg-ff-e01.h ------------------------------------------------------------ revno: 439 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Fri 2019-05-31 02:10:02 -0600 message: added D4v2-219 build for reduced power (only 75% FET) added: ToyKeeper/spaghetti-monster/anduril/cfg-emisar-d4v2-219.h ------------------------------------------------------------ revno: 438 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Fri 2019-05-31 01:57:14 -0600 message: made MCU stay awake at boot long enough to get accurate voltage reading, sped up return-to-sleep delays, made RGB "voltage" preview mode last twice as long modified: ToyKeeper/spaghetti-monster/anduril/anduril.c ------------------------------------------------------------ revno: 437 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Fri 2019-05-31 01:56:18 -0600 message: sped up button release timeout slightly to reduce lag when turning off light modified: ToyKeeper/spaghetti-monster/fsm-events.h ------------------------------------------------------------ revno: 436 [merge] committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Thu 2019-05-23 00:43:14 -0600 message: merged from fsm branch to get a bunch of recent updates modified: ... a lot of files ------------------------------------------------------------ revno: 435 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Tue 2019-05-21 14:25:28 -0600 message: no muggle mode on D4v2, by request modified: ToyKeeper/spaghetti-monster/anduril/cfg-emisar-d4v2.h ------------------------------------------------------------ revno: 434 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Mon 2019-05-20 00:16:26 -0600 message: improved RGB aux LED previews for voltage mode and blinking mode modified: ToyKeeper/spaghetti-monster/anduril/anduril.c ------------------------------------------------------------ revno: 433 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Fri 2019-05-10 23:53:47 -0600 message: fixed D4v2 ramp shape and thermal limit modified: ToyKeeper/spaghetti-monster/anduril/cfg-emisar-d4v2.h ------------------------------------------------------------ revno: 432 [merge] committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Fri 2019-05-10 23:39:48 -0600 message: merged from lantern branch, to get newer candle mode added: ToyKeeper/spaghetti-monster/anduril/cfg-blf-lantern.h modified: ToyKeeper/spaghetti-monster/anduril/anduril.c ToyKeeper/spaghetti-monster/fsm-ramping.c ToyKeeper/spaghetti-monster/fsm-ramping.h ------------------------------------------------------------ revno: 431 [merge] committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Fri 2019-05-10 23:29:28 -0600 message: merged from upstream fsm branch added: ToyKeeper/spaghetti-monster/anduril/cfg-fw3a-219.h modified: ToyKeeper/spaghetti-monster/anduril/anduril-manual.txt ------------------------------------------------------------ revno: 430 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Fri 2019-05-10 23:27:55 -0600 message: use only red, green, and blue for voltage display... don't do color mixes modified: ToyKeeper/spaghetti-monster/anduril/anduril.c ------------------------------------------------------------ revno: 429 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Fri 2019-05-10 23:27:30 -0600 message: flash-tiny1634-fuses had a typo modified: bin/flash-tiny1634-fuses.sh ------------------------------------------------------------ revno: 428 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Sat 2019-05-04 18:03:28 -0600 message: fixed builds without sleep ticks enabled modified: ToyKeeper/spaghetti-monster/fsm-wdt.c ------------------------------------------------------------ revno: 427 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Sat 2019-05-04 18:01:17 -0600 message: made aux LEDs turn on at boot time, instead of waiting until sleep LVP measures the battery modified: ToyKeeper/spaghetti-monster/anduril/anduril.c ------------------------------------------------------------ revno: 426 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Sat 2019-05-04 18:00:34 -0600 message: implemented LVP in standby mode (which allows LVP to turn off high-drain aux LEDs while asleep, and allows RGB readout to change with battery charge) modified: ToyKeeper/spaghetti-monster/fsm-adc.c ToyKeeper/spaghetti-monster/fsm-adc.h ToyKeeper/spaghetti-monster/fsm-wdt.c ------------------------------------------------------------ revno: 425 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Sat 2019-05-04 03:14:33 -0600 message: enable tenclick thermal config in D4v2 target modified: ToyKeeper/spaghetti-monster/anduril/cfg-emisar-d4v2.h ------------------------------------------------------------ revno: 424 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Sat 2019-05-04 03:14:16 -0600 message: added RGB support to lockout mode, improved RGB behavior, set defaults to low because the high mode is way too bright modified: ToyKeeper/spaghetti-monster/anduril/anduril.c ------------------------------------------------------------ revno: 423 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Sat 2019-05-04 02:36:55 -0600 message: got RGB aux LED modes working -- (off, low, high, blinking) and (7 colors + rainbow + voltage) (off mode only, for now, no lockout) modified: ToyKeeper/spaghetti-monster/anduril/anduril.c ------------------------------------------------------------ revno: 422 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Fri 2019-05-03 18:25:23 -0600 message: Turn off aux LEDs when voltage is low. They use too much power on high mode. modified: ToyKeeper/spaghetti-monster/anduril/anduril.c ------------------------------------------------------------ revno: 421 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Fri 2019-05-03 18:24:15 -0600 message: Calibrated D4v2 voltage. modified: ToyKeeper/hwdef-Emisar_D4v2.h ------------------------------------------------------------ revno: 420 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Fri 2019-05-03 17:48:51 -0600 message: fixed RGB aux LED low mode modified: ToyKeeper/hwdef-Emisar_D4v2.h ToyKeeper/spaghetti-monster/fsm-misc.c ------------------------------------------------------------ revno: 419 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Fri 2019-05-03 17:35:47 -0600 message: started on RGB aux LED support in Anduril, but it's just an early test right now modified: ToyKeeper/spaghetti-monster/anduril/anduril.c ToyKeeper/spaghetti-monster/anduril/cfg-emisar-d4v2.h ------------------------------------------------------------ revno: 418 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Fri 2019-05-03 17:35:05 -0600 message: adjust ramping auto-aux-LED code to include RGB version (shut off when main LEDs are on) modified: ToyKeeper/spaghetti-monster/fsm-ramping.c ------------------------------------------------------------ revno: 417 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Fri 2019-05-03 17:33:08 -0600 message: started on tiny1634 RGB aux LED support (seems to work except for the "low" output mode) modified: ToyKeeper/hwdef-Emisar_D4v2.h ToyKeeper/spaghetti-monster/fsm-misc.c ToyKeeper/spaghetti-monster/fsm-misc.h ------------------------------------------------------------ revno: 416 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Fri 2019-05-03 16:22:15 -0600 message: fixed D4v2 PWM speed and delay speed, fixed hardware setup reference comments modified: ToyKeeper/hwdef-Emisar_D4v2.h ------------------------------------------------------------ revno: 415 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Fri 2019-05-03 16:20:50 -0600 message: fixed attiny1634 clock speed adjustments modified: ToyKeeper/tk-attiny.h ------------------------------------------------------------ revno: 414 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Fri 2019-05-03 15:38:52 -0600 message: renamed SWITCH_PIN_D (pin data) to SWITCH_PORT, to match AVR manual terminology (even though the value should be PINA or PINB or PINC) modified: ToyKeeper/hwdef-Emisar_D4v2.h ToyKeeper/spaghetti-monster/fsm-pcint.c ToyKeeper/tk-attiny.h ------------------------------------------------------------ revno: 413 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Fri 2019-05-03 01:48:10 -0600 message: added tiny1634 flashing scripts added: bin/flash-tiny1634-fuses.sh bin/flash-tiny1634.sh ------------------------------------------------------------ revno: 411 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Fri 2019-05-03 01:42:35 -0600 message: started adding tiny1634 support to FSM ... so much kludge, such need clean modified: ToyKeeper/spaghetti-monster/fsm-adc.c ToyKeeper/spaghetti-monster/fsm-main.c ToyKeeper/spaghetti-monster/fsm-pcint.c ToyKeeper/spaghetti-monster/fsm-wdt.c ToyKeeper/tk-attiny.h ------------------------------------------------------------ revno: 410 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Fri 2019-05-03 01:40:15 -0600 message: added D4v2-1634 config and hwdef files modified: ToyKeeper/hwdef-Emisar_D4v2.h ToyKeeper/spaghetti-monster/anduril/cfg-emisar-d4v2.h ------------------------------------------------------------ revno: 409 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Fri 2019-05-03 01:39:24 -0600 message: made build-all.sh detect attiny type from cfg file, and use it modified: ToyKeeper/spaghetti-monster/anduril/build-all.sh ------------------------------------------------------------ revno: 403 [merge] committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Sun 2019-04-14 18:14:51 -0600 message: merged updates from upstream added/modified: ... lots of files ------------------------------------------------------------ revno: 402 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Sun 2019-04-14 18:08:08 -0600 message: merged in some aux LED code updates from anduril modified: ToyKeeper/spaghetti-monster/rampingios/rampingiosv3.c ------------------------------------------------------------ revno: 401 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Thu 2018-12-27 16:23:09 -0700 message: tk-attiny.h: started adding other MCU support also removed redundant eeprom size hints modified: ToyKeeper/tk-attiny.h ------------------------------------------------------------ revno: 400 committer: Selene ToyKeeper branch nick: emisar-d4v2 timestamp: Thu 2018-12-27 16:21:59 -0700 message: made dynamic clocking safer and more portable (uses library function instead of direct register access) (lib disables interrupts properly, which I wasn't doing) modified: ToyKeeper/spaghetti-monster/anduril/anduril.c ToyKeeper/spaghetti-monster/fsm-events.c ToyKeeper/spaghetti-monster/fsm-misc.c ToyKeeper/spaghetti-monster/spaghetti-monster.h --- spaghetti-monster/anduril/anduril.c | 282 +++++++++++++++++++----- spaghetti-monster/anduril/build-all.sh | 6 +- spaghetti-monster/anduril/cfg-emisar-d4.h | 14 +- spaghetti-monster/anduril/cfg-emisar-d4s.h | 6 +- spaghetti-monster/anduril/cfg-emisar-d4v2-219.h | 8 + spaghetti-monster/anduril/cfg-emisar-d4v2.h | 51 +++++ spaghetti-monster/fsm-adc.c | 137 +++++++++--- spaghetti-monster/fsm-adc.h | 3 +- spaghetti-monster/fsm-events.c | 24 +- spaghetti-monster/fsm-main.c | 56 +++-- spaghetti-monster/fsm-misc.c | 35 ++- spaghetti-monster/fsm-misc.h | 7 + spaghetti-monster/fsm-pcint.c | 42 +++- spaghetti-monster/fsm-ramping.c | 26 ++- spaghetti-monster/fsm-standby.c | 2 + spaghetti-monster/fsm-wdt.c | 82 +++++-- spaghetti-monster/fsm-wdt.h | 5 + spaghetti-monster/rampingios/rampingiosv3.c | 43 +--- spaghetti-monster/spaghetti-monster.h | 1 + 19 files changed, 645 insertions(+), 185 deletions(-) create mode 100644 spaghetti-monster/anduril/cfg-emisar-d4v2-219.h create mode 100644 spaghetti-monster/anduril/cfg-emisar-d4v2.h (limited to 'spaghetti-monster') diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c index c2a4b77..8ab66f5 100644 --- a/spaghetti-monster/anduril/anduril.c +++ b/spaghetti-monster/anduril/anduril.c @@ -132,11 +132,13 @@ // full FET strobe can be a bit much... use max regulated level instead, // if there's a bright enough regulated level +#ifndef STROBE_BRIGHTNESS #ifdef MAX_Nx7135 #define STROBE_BRIGHTNESS MAX_Nx7135 #else #define STROBE_BRIGHTNESS MAX_LEVEL #endif +#endif #if defined(USE_CANDLE_MODE) || defined(USE_BIKE_FLASHER_MODE) || defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE) || defined(USE_LIGHTNING_MODE) #define USE_STROBE_STATE @@ -186,6 +188,10 @@ typedef enum { #ifdef USE_INDICATOR_LED indicator_led_mode_e, #endif + #ifdef USE_AUX_RGB_LEDS + rgb_led_off_mode_e, + rgb_led_lockout_mode_e, + #endif eeprom_indexes_e_END } eeprom_indexes_e; #define EEPROM_BYTES eeprom_indexes_e_END @@ -299,6 +305,31 @@ void blip(); #if defined(USE_INDICATOR_LED) && defined(TICK_DURING_STANDBY) void indicator_blink(uint8_t arg); #endif +#if defined(USE_AUX_RGB_LEDS) && defined(TICK_DURING_STANDBY) +void rgb_led_update(uint8_t mode, uint8_t arg); +/* + * 0: R + * 1: RG + * 2: G + * 3: GB + * 4: B + * 5: R B + * 6: RGB + * 7: rainbow + * 8: voltage + */ +#define RGB_LED_NUM_COLORS 10 +#define RGB_LED_NUM_PATTERNS 4 +#ifndef RGB_LED_OFF_DEFAULT +//#define RGB_LED_OFF_DEFAULT 0x18 // low, voltage +#define RGB_LED_OFF_DEFAULT 0x17 // low, rainbow +#endif +#ifndef RGB_LED_LOCKOUT_DEFAULT +#define RGB_LED_LOCKOUT_DEFAULT 0x37 // blinking, rainbow +#endif +uint8_t rgb_led_off_mode = RGB_LED_OFF_DEFAULT; +uint8_t rgb_led_lockout_mode = RGB_LED_LOCKOUT_DEFAULT; +#endif #ifdef USE_FACTORY_RESET void factory_reset(); @@ -459,27 +490,36 @@ uint8_t off_state(Event event, uint16_t arg) { set_level(0); #ifdef USE_INDICATOR_LED indicator_led(indicator_led_mode & 0x03); + #elif defined(USE_AUX_RGB_LEDS) + rgb_led_update(rgb_led_off_mode, 0); #endif // sleep while off (lower power use) - go_to_standby = 1; + // (unless delay requested; give the ADC some time to catch up) + if (! arg) { go_to_standby = 1; } return MISCHIEF_MANAGED; } // go back to sleep eventually if we got bumped but didn't leave "off" state else if (event == EV_tick) { - if (arg > TICKS_PER_SECOND*2) { + if (arg > HOLD_TIMEOUT) { go_to_standby = 1; #ifdef USE_INDICATOR_LED indicator_led(indicator_led_mode & 0x03); + #elif defined(USE_AUX_RGB_LEDS) + rgb_led_update(rgb_led_off_mode, arg); #endif } return MISCHIEF_MANAGED; } - #if defined(TICK_DURING_STANDBY) && defined(USE_INDICATOR_LED) + #if defined(TICK_DURING_STANDBY) && (defined(USE_INDICATOR_LED) || defined(USE_AUX_RGB_LEDS)) // blink the indicator LED, maybe else if (event == EV_sleep_tick) { + #ifdef USE_INDICATOR_LED if ((indicator_led_mode & 0b00000011) == 0b00000011) { indicator_blink(arg); } + #elif defined(USE_AUX_RGB_LEDS) + rgb_led_update(rgb_led_off_mode, arg); + #endif return MISCHIEF_MANAGED; } #endif @@ -608,7 +648,33 @@ uint8_t off_state(Event event, uint16_t arg) { save_config(); return MISCHIEF_MANAGED; } - #endif + #elif defined(USE_AUX_RGB_LEDS) + // 7 clicks: change RGB aux LED pattern + else if (event == EV_7clicks) { + uint8_t mode = (rgb_led_off_mode >> 4) + 1; + mode = mode % RGB_LED_NUM_PATTERNS; + rgb_led_off_mode = (mode << 4) | (rgb_led_off_mode & 0x0f); + rgb_led_update(rgb_led_off_mode, 0); + save_config(); + blink_confirm(1); + return MISCHIEF_MANAGED; + } + // 7 clicks (hold last): change RGB aux LED color + else if (event == EV_click7_hold) { + if (0 == (arg & 0x3f)) { + uint8_t mode = (rgb_led_off_mode & 0x0f) + 1; + mode = mode % RGB_LED_NUM_COLORS; + rgb_led_off_mode = mode | (rgb_led_off_mode & 0xf0); + //save_config(); + } + rgb_led_update(rgb_led_off_mode, arg); + return MISCHIEF_MANAGED; + } + else if (event == EV_click7_hold_release) { + save_config(); + return MISCHIEF_MANAGED; + } + #endif // end 7 clicks #ifdef USE_TENCLICK_THERMAL_CONFIG // 10 clicks: thermal config mode else if (event == EV_10clicks) { @@ -854,7 +920,10 @@ uint8_t steady_state(Event event, uint16_t arg) { #endif #ifdef USE_SET_LEVEL_GRADUALLY // make thermal adjustment speed scale with magnitude - if ((arg & 1) && (actual_level < THERM_FASTER_LEVEL)) { + // also, adjust slower when going up + if ((arg & 1) && + ((actual_level < THERM_FASTER_LEVEL) || + (actual_level < gradual_target))) { return MISCHIEF_MANAGED; // adjust slower when not a high mode } #ifdef THERM_HARD_TURBO_DROP @@ -872,17 +941,21 @@ uint8_t steady_state(Event event, uint16_t arg) { uint8_t intervals[] = {248, 128, 66, 34, 17, 9, 4, 2}; uint8_t diff; static uint8_t ticks_since_adjust = 0; - ticks_since_adjust ++; - if (gradual_target > actual_level) diff = gradual_target - actual_level; - else { + if (gradual_target > actual_level) { + // rise at half speed (skip half the frames) + if (arg & 2) return MISCHIEF_MANAGED; + diff = gradual_target - actual_level; + } else { diff = actual_level - gradual_target; } + ticks_since_adjust ++; // if there's any adjustment to be made, make it if (diff) { uint8_t magnitude = 0; #ifndef THERM_HARD_TURBO_DROP // if we're on a really high mode, drop faster - if (actual_level >= THERM_FASTER_LEVEL) { magnitude ++; } + if ((actual_level >= THERM_FASTER_LEVEL) + && (actual_level > gradual_target)) { magnitude ++; } #endif while (diff) { magnitude ++; @@ -910,7 +983,8 @@ uint8_t steady_state(Event event, uint16_t arg) { blip(); #endif #ifdef THERM_HARD_TURBO_DROP - if (actual_level > THERM_FASTER_LEVEL) { + //if (actual_level > THERM_FASTER_LEVEL) { + if (actual_level == MAX_LEVEL) { #ifdef USE_SET_LEVEL_GRADUALLY set_level_gradually(THERM_FASTER_LEVEL); target_level = THERM_FASTER_LEVEL; @@ -1553,6 +1627,10 @@ uint8_t lockout_state(Event event, uint16_t arg) { #ifdef MOON_DURING_LOCKOUT_MODE // momentary(ish) moon mode during lockout // button is being held + #ifdef USE_AUX_RGB_LEDS + // don't turn on during RGB aux LED configuration + if (event == EV_click3_hold) { set_level(0); } else + #endif if ((event & (B_CLICK | B_PRESS)) == (B_CLICK | B_PRESS)) { #ifdef LOCKOUT_MOON_LOWEST // Use lowest moon configured @@ -1586,75 +1664,82 @@ uint8_t lockout_state(Event event, uint16_t arg) { if (event == EV_enter_state) { indicator_led(indicator_led_mode >> 2); } else + #elif defined(USE_AUX_RGB_LEDS) + if (event == EV_enter_state) { + rgb_led_update(rgb_led_lockout_mode, 0); + } else #endif if (event == EV_tick) { - if (arg > TICKS_PER_SECOND*2) { + if (arg > HOLD_TIMEOUT) { go_to_standby = 1; #ifdef USE_INDICATOR_LED indicator_led(indicator_led_mode >> 2); + #elif defined(USE_AUX_RGB_LEDS) + rgb_led_update(rgb_led_lockout_mode, arg); #endif } return MISCHIEF_MANAGED; } - #if defined(TICK_DURING_STANDBY) && defined(USE_INDICATOR_LED) + #if defined(TICK_DURING_STANDBY) && (defined(USE_INDICATOR_LED) || defined(USE_AUX_RGB_LEDS)) else if (event == EV_sleep_tick) { + #if defined(USE_INDICATOR_LED) if ((indicator_led_mode & 0b00001100) == 0b00001100) { indicator_blink(arg); } + #elif defined(USE_AUX_RGB_LEDS) + rgb_led_update(rgb_led_lockout_mode, arg); + #endif return MISCHIEF_MANAGED; } #endif - #ifdef USE_INDICATOR_LED + #if defined(USE_INDICATOR_LED) // 3 clicks: rotate through indicator LED modes (lockout mode) else if (event == EV_3clicks) { - uint8_t mode = indicator_led_mode >> 2; - #ifdef TICK_DURING_STANDBY - mode = (mode + 1) & 3; - #else - mode = (mode + 1) % 3; - #endif - #ifdef INDICATOR_LED_SKIP_LOW - if (mode == 1) { mode ++; } + #if defined(USE_INDICATOR_LED) + uint8_t mode = indicator_led_mode >> 2; + #ifdef TICK_DURING_STANDBY + mode = (mode + 1) & 3; + #else + mode = (mode + 1) % 3; + #endif + #ifdef INDICATOR_LED_SKIP_LOW + if (mode == 1) { mode ++; } + #endif + indicator_led_mode = (mode << 2) + (indicator_led_mode & 0x03); + indicator_led(mode); + #elif defined(USE_AUX_RGB_LEDS) #endif - indicator_led_mode = (mode << 2) + (indicator_led_mode & 0x03); - indicator_led(mode); save_config(); return MISCHIEF_MANAGED; } - #if 0 // old method, deprecated in favor of "7 clicks from off" - // click, click, hold: rotate through indicator LED modes (off mode) + #elif defined(USE_AUX_RGB_LEDS) + // 3 clicks: change RGB aux LED pattern + else if (event == EV_3clicks) { + uint8_t mode = (rgb_led_lockout_mode >> 4) + 1; + mode = mode % RGB_LED_NUM_PATTERNS; + rgb_led_lockout_mode = (mode << 4) | (rgb_led_lockout_mode & 0x0f); + rgb_led_update(rgb_led_lockout_mode, 0); + save_config(); + blink_confirm(1); + return MISCHIEF_MANAGED; + } + // click, click, hold: change RGB aux LED color else if (event == EV_click3_hold) { - #ifndef USE_INDICATOR_LED_WHILE_RAMPING - // if main LED obscures aux LEDs, turn it off - set_level(0); - #endif - #ifdef TICK_DURING_STANDBY - uint8_t mode = (arg >> 5) & 3; - #else - uint8_t mode = (arg >> 5) % 3; - #endif - #ifdef INDICATOR_LED_SKIP_LOW - if (mode == 1) { mode ++; } - #endif - indicator_led_mode = (indicator_led_mode & 0b11111100) | mode; - #ifdef TICK_DURING_STANDBY - if (mode == 3) - indicator_led(mode & (arg&3)); - else - indicator_led(mode); - #else - indicator_led(mode); - #endif - //save_config(); + if (0 == (arg & 0x3f)) { + uint8_t mode = (rgb_led_lockout_mode & 0x0f) + 1; + mode = mode % RGB_LED_NUM_COLORS; + rgb_led_lockout_mode = mode | (rgb_led_lockout_mode & 0xf0); + //save_config(); + } + rgb_led_update(rgb_led_lockout_mode, arg); return MISCHIEF_MANAGED; } - // click, click, hold, release: save indicator LED mode (off mode) + // click, click, hold, release: save new color else if (event == EV_click3_hold_release) { save_config(); return MISCHIEF_MANAGED; } #endif - #endif // 4 clicks: exit else if (event == EV_4clicks) { blink_confirm(1); @@ -1845,10 +1930,13 @@ uint8_t muggle_state(Event event, uint16_t arg) { #if 0 blip(); #endif - // step down proportional to the amount of overheating - uint8_t new = actual_level - arg; - if (new < MUGGLE_FLOOR) { new = MUGGLE_FLOOR; } - set_level(new); + // ignore warnings while off + if (! muggle_off_mode) { + // step down proportional to the amount of overheating + int16_t new = actual_level - arg; + if (new < MUGGLE_FLOOR) { new = MUGGLE_FLOOR; } + set_level(new); + } return MISCHIEF_MANAGED; } #endif @@ -2135,6 +2223,9 @@ void blip() { #if defined(USE_INDICATOR_LED) && defined(TICK_DURING_STANDBY) // beacon-like mode for the indicator LED void indicator_blink(uint8_t arg) { + // turn off aux LEDs when battery is empty + if (voltage < VOLTAGE_LOW) { indicator_led(0); return; } + #ifdef USE_FANCIER_BLINKING_INDICATOR // fancy blink, set off/low/high levels here: @@ -2155,6 +2246,81 @@ void indicator_blink(uint8_t arg) { } #endif +#if defined(USE_AUX_RGB_LEDS) && defined(TICK_DURING_STANDBY) +// do fancy stuff with the RGB aux LEDs +// mode: 0bPPPPCCCC where PPPP is the pattern and CCCC is the color +// arg: time slice number +void rgb_led_update(uint8_t mode, uint8_t arg) { + static uint8_t rainbow = 0; // track state of rainbow mode + static uint8_t frame = 0; // track state of animation mode + + // turn off aux LEDs when battery is empty + // (but if voltage==0, that means we just booted and don't know yet) + uint8_t volts = voltage; // save a few bytes by caching volatile value + if ((volts) && (volts < VOLTAGE_LOW)) { rgb_led_set(0); return; } + + uint8_t pattern = (mode>>4); // off, low, high, blinking, ... more? + uint8_t color = mode & 0x0f; + + // preview in blinking mode is awkward... use high instead + if ((! go_to_standby) && (pattern > 2)) { pattern = 2; } + + + uint8_t colors[] = { + 0b00000001, // 0: red + 0b00000101, // 1: yellow + 0b00000100, // 2: green + 0b00010100, // 3: cyan + 0b00010000, // 4: blue + 0b00010001, // 5: purple + 0b00010101, // 6: white + }; + uint8_t actual_color = 0; + if (color < 7) { // normal color + actual_color = colors[color]; + } + else if (color == 7) { // rainbow + if (0 == (arg & 0x03)) { + rainbow = (rainbow + 1) % 6; + } + actual_color = colors[rainbow]; + } + else { // voltage + // show actual voltage while asleep... + if (go_to_standby) { + // choose a color based on battery voltage + if (volts >= 38) actual_color = colors[4]; + else if (volts >= 33) actual_color = colors[2]; + else actual_color = colors[0]; + } + // ... but during preview, cycle colors quickly + else { + actual_color = colors[((arg>>1) % 3) << 1]; + } + } + + // pick a brightness from the animation sequence + if (pattern == 3) { + // uses an odd length to avoid lining up with rainbow loop + uint8_t animation[] = {2, 1, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 1}; + frame = (frame + 1) % sizeof(animation); + pattern = animation[frame]; + } + switch (pattern) { + case 0: // off + rgb_led_set(0); + break; + case 1: // low + rgb_led_set(actual_color); + break; + case 2: // high + rgb_led_set(actual_color << 1); + break; + } +} +#endif + #ifdef USE_FACTORY_RESET void factory_reset() { @@ -2242,6 +2408,10 @@ void load_config() { #ifdef USE_INDICATOR_LED indicator_led_mode = eeprom[indicator_led_mode_e]; #endif + #ifdef USE_AUX_RGB_LEDS + rgb_led_off_mode = eeprom[rgb_led_off_mode_e]; + rgb_led_lockout_mode = eeprom[rgb_led_lockout_mode_e]; + #endif } #ifdef START_AT_MEMORIZED_LEVEL if (load_eeprom_wl()) { @@ -2286,6 +2456,10 @@ void save_config() { #ifdef USE_INDICATOR_LED eeprom[indicator_led_mode_e] = indicator_led_mode; #endif + #ifdef USE_AUX_RGB_LEDS + eeprom[rgb_led_off_mode_e] = rgb_led_off_mode; + eeprom[rgb_led_lockout_mode_e] = rgb_led_lockout_mode; + #endif save_eeprom(); } @@ -2372,7 +2546,7 @@ void setup() { push_state(muggle_state, (MUGGLE_FLOOR+MUGGLE_CEILING)/2); else #endif - push_state(off_state, 0); + push_state(off_state, 1); #endif // ifdef START_AT_MEMORIZED_LEVEL } diff --git a/spaghetti-monster/anduril/build-all.sh b/spaghetti-monster/anduril/build-all.sh index c355f1e..56a88bf 100755 --- a/spaghetti-monster/anduril/build-all.sh +++ b/spaghetti-monster/anduril/build-all.sh @@ -5,7 +5,9 @@ UI=anduril for TARGET in cfg-*.h ; do NAME=$(echo "$TARGET" | perl -ne '/cfg-(.*).h/ && print "$1\n";') echo "===== $NAME =====" - echo ../../../bin/build.sh 85 "$UI" "-DCONFIGFILE=${TARGET}" - ../../../bin/build.sh 85 "$UI" "-DCONFIGFILE=${TARGET}" + ATTINY=$(grep 'ATTINY:' $TARGET | awk '{ print $3 }') + if [ -z "$ATTINY" ]; then ATTINY=85 ; fi + echo ../../../bin/build.sh $ATTINY "$UI" "-DCONFIGFILE=${TARGET}" + ../../../bin/build.sh $ATTINY "$UI" "-DCONFIGFILE=${TARGET}" mv -f "$UI".hex "$UI".$NAME.hex done diff --git a/spaghetti-monster/anduril/cfg-emisar-d4.h b/spaghetti-monster/anduril/cfg-emisar-d4.h index de8f796..c86a534 100644 --- a/spaghetti-monster/anduril/cfg-emisar-d4.h +++ b/spaghetti-monster/anduril/cfg-emisar-d4.h @@ -9,7 +9,14 @@ #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,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 +#define QUARTERSPEED_LEVEL 6 + +#define RAMP_SMOOTH_FLOOR 1 +#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 // optional, makes initial turbo step-down faster so first peak isn't as hot // the D4 runs very very hot, so be extra careful @@ -17,3 +24,8 @@ // stop panicking at ~30% power or ~1200 lm #define THERM_FASTER_LEVEL 105 +// respond to thermal changes faster +#define THERMAL_WARNING_SECONDS 3 +#define THERMAL_UPDATE_SPEED 1 +#define THERM_PREDICTION_STRENGTH 4 + diff --git a/spaghetti-monster/anduril/cfg-emisar-d4s.h b/spaghetti-monster/anduril/cfg-emisar-d4s.h index d19a514..230ac7c 100644 --- a/spaghetti-monster/anduril/cfg-emisar-d4s.h +++ b/spaghetti-monster/anduril/cfg-emisar-d4s.h @@ -36,9 +36,13 @@ #undef MIN_THERM_STEPDOWN // this should be lower, because 3x7135 instead of 1x7135 #endif #define MIN_THERM_STEPDOWN 60 // lowest value it'll step down to -#define THERM_FASTER_LEVEL (RAMP_SIZE-1) // don't throttle back faster when high +#define THERM_FASTER_LEVEL (RAMP_SIZE-20) // don't throttle back faster when high // no need to be extra-careful on this light #ifdef THERM_HARD_TURBO_DROP #undef THERM_HARD_TURBO_DROP #endif + +#define THERMAL_WARNING_SECONDS 3 +#define THERMAL_UPDATE_SPEED 2 +#define THERM_PREDICTION_STRENGTH 4 diff --git a/spaghetti-monster/anduril/cfg-emisar-d4v2-219.h b/spaghetti-monster/anduril/cfg-emisar-d4v2-219.h new file mode 100644 index 0000000..0770935 --- /dev/null +++ b/spaghetti-monster/anduril/cfg-emisar-d4v2-219.h @@ -0,0 +1,8 @@ +// Emisar D4v2-219 config options for Anduril +#include "cfg-emisar-d4v2.h" +// ATTINY: 1634 + +#undef PWM1_LEVELS +#undef PWM2_LEVELS +#define 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,255 +#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,2,3,3,5,6,6,8,9,10,11,12,14,15,16,18,18,20,21,23,24,26,27,29,30,32,33,36,37,39,41,43,44,46,48,50,52,54,56,58,61,63,65,67,70,72,74,77,79,82,84,86,89,92,95,97,100,103,106,108,111,114,117,120,124,127,130,133,137,140,144,147,151,154,157,161,165,169,172,176,180,184,188,192 diff --git a/spaghetti-monster/anduril/cfg-emisar-d4v2.h b/spaghetti-monster/anduril/cfg-emisar-d4v2.h new file mode 100644 index 0000000..b83c65c --- /dev/null +++ b/spaghetti-monster/anduril/cfg-emisar-d4v2.h @@ -0,0 +1,51 @@ +// Emisar D4 config options for Anduril +#include "hwdef-Emisar_D4v2.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 +#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 +//#define STANDBY_TICK_SPEED 4 // every 0.256 s +//#define STANDBY_TICK_SPEED 5 // every 0.512 s + + +// copied from original D4, since it's also a FET+1 and has the same host +// ../../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 +#define RAMP_LENGTH 150 +#define 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 +#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,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 6 + +#define RAMP_SMOOTH_FLOOR 1 +#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 + +// optional, makes initial turbo step-down faster so first peak isn't as hot +// the D4 runs very very hot, so be extra careful +//#define THERM_HARD_TURBO_DROP + +// stop panicking at ~30% power or ~1200 lm +#define THERM_FASTER_LEVEL 105 +// respond to thermal changes faster +#define THERMAL_WARNING_SECONDS 3 +#define THERMAL_UPDATE_SPEED 1 +#define THERM_PREDICTION_STRENGTH 4 +//#define THERM_RESPONSE_MAGNITUDE 128 + +// easier access to thermal config mode, for Emisar +#define USE_TENCLICK_THERMAL_CONFIG + +#define THERM_CAL_OFFSET 5 diff --git a/spaghetti-monster/fsm-adc.c b/spaghetti-monster/fsm-adc.c index bcf49ed..6832e32 100644 --- a/spaghetti-monster/fsm-adc.c +++ b/spaghetti-monster/fsm-adc.c @@ -20,27 +20,76 @@ #ifndef FSM_ADC_C #define FSM_ADC_C -#ifdef USE_VOLTAGE_DIVIDER -// 1.1V / pin7 -#define ADMUX_VOLTAGE ADMUX_VOLTAGE_DIVIDER -#else -// VCC / 1.1V reference -#define ADMUX_VOLTAGE ADMUX_VCC -#endif +inline void set_admux_therm() { + #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) || (ATTINY == 1634) + ADMUX = ADMUX_THERM; + #elif (ATTINY == 841) + ADMUXA = ADMUXA_THERM; + ADMUXB = ADMUXB_THERM; + #else + #error Unrecognized MCU type + #endif +} + +inline void set_admux_voltage() { + #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) || (ATTINY == 1634) + #ifdef USE_VOLTAGE_DIVIDER + // 1.1V / pin7 + ADMUX = ADMUX_VOLTAGE_DIVIDER; + #else + // VCC / 1.1V reference + ADMUX = ADMUX_VCC; + #endif + #elif (ATTINY == 841) + #ifdef USE_VOLTAGE_DIVIDER + ADMUXA = ADMUXA_VOLTAGE_DIVIDER; + ADMUXB = ADMUXB_VOLTAGE_DIVIDER; + #else + ADMUXA = ADMUXA_VCC; + ADMUXB = ADMUXB_VCC; + #endif + #else + #error Unrecognized MCU type + #endif +} + +inline void ADC_start_measurement() { + #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) || (ATTINY == 841) || (ATTINY == 1634) + ADCSRA |= (1 << ADSC) | (1 << ADIE); + #else + #error unrecognized MCU type + #endif +} + +// set up ADC for reading battery voltage inline void ADC_on() { - // read voltage on VCC by default - ADMUX = ADMUX_VOLTAGE; - #ifdef USE_VOLTAGE_DIVIDER - // disable digital input on divider pin to reduce power consumption - DIDR0 |= (1 << VOLTAGE_ADC_DIDR); + #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) || (ATTINY == 1634) + set_admux_voltage(); + #ifdef USE_VOLTAGE_DIVIDER + // disable digital input on divider pin to reduce power consumption + DIDR0 |= (1 << VOLTAGE_ADC_DIDR); + #else + // disable digital input on VCC pin to reduce power consumption + //DIDR0 |= (1 << ADC_DIDR); // FIXME: unsure how to handle for VCC pin + #endif + #if (ATTINY == 1634) + ACSRA |= (1 << ACD); // turn off analog comparator to save power + #endif + // enable, start, prescale + ADCSRA = (1 << ADEN) | (1 << ADSC) | ADC_PRSCL; + // end tiny25/45/85 + #elif (ATTINY == 841) + ADCSRB = 0; // Right adjusted, auto trigger bits cleared. + //ADCSRA = (1 << ADEN ) | 0b011; // ADC on, prescaler division factor 8. + set_admux_voltage(); + // enable, start, prescale + ADCSRA = (1 << ADEN) | (1 << ADSC) | ADC_PRSCL; + //ADCSRA |= (1 << ADSC); // start measuring #else - // disable digital input on VCC pin to reduce power consumption - //DIDR0 |= (1 << ADC_DIDR); // FIXME: unsure how to handle for VCC pin + #error Unrecognized MCU type #endif - // enable, start, prescale - ADCSRA = (1 << ADEN) | (1 << ADSC) | ADC_PRSCL; } inline void ADC_off() { @@ -89,6 +138,9 @@ ISR(ADC_vect) { // thermal declarations #ifdef USE_THERMAL_REGULATION + #ifndef THERMAL_UPDATE_SPEED + #define THERMAL_UPDATE_SPEED 2 + #endif #define NUM_THERMAL_VALUES_HISTORY 8 #define ADC_STEPS 4 static uint8_t history_step = 0; // don't update history as often @@ -96,7 +148,7 @@ ISR(ADC_vect) { static uint8_t temperature_timer = 0; static uint8_t overheat_lowpass = 0; static uint8_t underheat_lowpass = 0; - #define TEMPERATURE_TIMER_START (THERMAL_WARNING_SECONDS*ADC_CYCLES_PER_SECOND) // N seconds between thermal regulation events + #define TEMPERATURE_TIMER_START ((THERMAL_WARNING_SECONDS-2)*ADC_CYCLES_PER_SECOND) // N seconds between thermal regulation events #define OVERHEAT_LOWPASS_STRENGTH (ADC_CYCLES_PER_SECOND*2) // lowpass for 2 seconds #define UNDERHEAT_LOWPASS_STRENGTH (ADC_CYCLES_PER_SECOND*2) // lowpass for 2 seconds #else @@ -110,6 +162,12 @@ ISR(ADC_vect) { pseudo_rand_seed += measurement; #endif + #if defined(TICK_DURING_STANDBY) && defined(USE_SLEEP_LVP) + // only measure battery voltage while asleep + if (go_to_standby) adc_step = 1; + else + #endif + adc_step = (adc_step + 1) & (ADC_STEPS-1); #ifdef USE_LVP @@ -120,7 +178,7 @@ ISR(ADC_vect) { if (voltage == 0) { for(uint8_t i=0; i THERM_FLOOR) { underheat_lowpass = 0; // we're probably not too cold - } else if (pt < THERM_CEIL) { + } + if (pt < THERM_CEIL) { overheat_lowpass = 0; // we're probably not too hot } @@ -261,6 +333,7 @@ ISR(ADC_vect) { overheat_lowpass = 0; temperature_timer = TEMPERATURE_TIMER_START; // how far above the ceiling? + //int16_t howmuch = (pt - THERM_CEIL) * THERM_RESPONSE_MAGNITUDE / 128; int16_t howmuch = pt - THERM_CEIL; // try to send out a warning emit(EV_temperature_high, howmuch); @@ -276,6 +349,7 @@ ISR(ADC_vect) { underheat_lowpass = 0; temperature_timer = TEMPERATURE_TIMER_START; // how far below the floor? + //int16_t howmuch = (THERM_FLOOR - pt) * THERM_RESPONSE_MAGNITUDE / 128; int16_t howmuch = THERM_FLOOR - pt; // try to send out a warning (unless voltage is low) // (LVP and underheat warnings fight each other) @@ -291,16 +365,21 @@ ISR(ADC_vect) { // set the correct type of measurement for next time #ifdef USE_THERMAL_REGULATION #ifdef USE_LVP - if (adc_step < 2) ADMUX = ADMUX_VOLTAGE; - else ADMUX = ADMUX_THERM; + if (adc_step < 2) set_admux_voltage(); + else set_admux_therm(); #else - ADMUX = ADMUX_THERM; + set_admux_therm(); #endif #else #ifdef USE_LVP - ADMUX = ADMUX_VOLTAGE; + set_admux_voltage(); #endif #endif + + #ifdef TICK_DURING_STANDBY + // if we were asleep, go back to sleep + if (go_to_standby) ADC_off(); + #endif } #ifdef USE_BATTCHECK diff --git a/spaghetti-monster/fsm-adc.h b/spaghetti-monster/fsm-adc.h index 6256e2c..274fb4d 100644 --- a/spaghetti-monster/fsm-adc.h +++ b/spaghetti-monster/fsm-adc.h @@ -38,7 +38,7 @@ #define VOLTAGE_FUDGE_FACTOR 5 #endif #endif -volatile uint8_t voltage; +volatile uint8_t voltage = 0; volatile uint8_t adcint_enable; // kludge, because adc auto-retrigger won't turn off void low_voltage(); #ifdef USE_BATTCHECK @@ -84,6 +84,7 @@ volatile uint8_t reset_thermal_history = 1; inline void ADC_on(); inline void ADC_off(); +inline void ADC_start_measurement(); #endif diff --git a/spaghetti-monster/fsm-events.c b/spaghetti-monster/fsm-events.c index 72216ae..362a5cc 100644 --- a/spaghetti-monster/fsm-events.c +++ b/spaghetti-monster/fsm-events.c @@ -20,6 +20,7 @@ #ifndef FSM_EVENTS_C #define FSM_EVENTS_C + void empty_event_sequence() { current_event = EV_none; // when the user completes an input sequence, interrupt any running timers @@ -116,26 +117,26 @@ uint8_t nice_delay_ms(uint16_t ms) { #ifdef USE_RAMPING uint8_t level = actual_level; // volatile, avoid repeat access if (level < QUARTERSPEED_LEVEL) { - CLKPR = 1< 0) { // underclock MCU to save power - CLKPR = 1< 0) { + // wait + _delay_loop_2(BOGOMIPS*398/100); } } #endif diff --git a/spaghetti-monster/fsm-main.c b/spaghetti-monster/fsm-main.c index 1c28f5f..e537a9e 100644 --- a/spaghetti-monster/fsm-main.c +++ b/spaghetti-monster/fsm-main.c @@ -36,21 +36,8 @@ ISR(TIMER1_COMPA_vect) { } #endif -int main() { - // Don't allow interrupts while booting - cli(); - - #ifdef USE_REBOOT // prevent reboot loops - MCUSR &= ~(1<= 1 DDRB |= (1 << PWM1_PIN); @@ -80,6 +67,45 @@ int main() { // configure e-switch PORTB = (1 << SWITCH_PIN); // e-switch is the only input PCMSK = (1 << SWITCH_PIN); // pin change interrupt uses this pin +} +#elif (ATTINY == 1634) +inline void hw_setup() { + // this gets tricky with so many pins... + // ... so punt it to the hwdef file + hwdef_setup(); +} +#else + #error Unrecognized MCU type +#endif + + +#ifdef USE_REBOOT +void prevent_reboot_loop() { + // prevent WDT from rebooting MCU again + MCUSR &= ~(1<> (i<<1)) & 0x03; + uint8_t pin = pins[i]; + switch (lvl) { + case 0: // LED off + AUXLED_RGB_DDR &= 0xff ^ (1 << pin); + AUXLED_RGB_PUE &= 0xff ^ (1 << pin); + AUXLED_RGB_PORT &= 0xff ^ (1 << pin); + break; + case 1: // LED low + AUXLED_RGB_DDR &= 0xff ^ (1 << pin); + AUXLED_RGB_PUE |= (1 << pin); + AUXLED_RGB_PORT |= (1 << pin); + break; + default: // LED high + AUXLED_RGB_DDR |= (1 << pin); + AUXLED_RGB_PUE |= (1 << pin); + AUXLED_RGB_PORT |= (1 << pin); + break; + } + } +} +#endif // ifdef USE_AUX_RGB_LEDS + #ifdef USE_TRIANGLE_WAVE uint8_t triangle_wave(uint8_t phase) { uint8_t result = phase << 1; diff --git a/spaghetti-monster/fsm-misc.h b/spaghetti-monster/fsm-misc.h index 1381ca2..a39d31a 100644 --- a/spaghetti-monster/fsm-misc.h +++ b/spaghetti-monster/fsm-misc.h @@ -43,9 +43,16 @@ uint8_t blink(uint8_t num, uint8_t speed); */ #ifdef USE_INDICATOR_LED +// lvl: 0=off, 1=low, 2=high void indicator_led(uint8_t lvl); #endif +#ifdef USE_AUX_RGB_LEDS +// value: 0b00BBGGRR +// each pair of bits: 0=off, 1=low, 2=high +void rgb_led_set(uint8_t value); +#endif + #ifdef USE_TRIANGLE_WAVE uint8_t triangle_wave(uint8_t phase); #endif diff --git a/spaghetti-monster/fsm-pcint.c b/spaghetti-monster/fsm-pcint.c index acb627d..4928980 100644 --- a/spaghetti-monster/fsm-pcint.c +++ b/spaghetti-monster/fsm-pcint.c @@ -30,7 +30,7 @@ uint8_t button_is_pressed() { // and wait for measurements to settle to all zeroes or all ones do { // shift past readings and add current value - readings = (readings << 1) | ((PINB & (1< 0) + (level > MAX_1x7135)); - //if (level > MAX_1x7135) indicator_led(2); - //else if (level > 0) indicator_led(1); - //else if (! go_to_standby) indicator_led(0); + #ifdef USE_INDICATOR_LED + if (! go_to_standby) + indicator_led((level > 0) + (level > MAX_1x7135)); + #endif + //if (level > MAX_1x7135) indicator_led(2); + //else if (level > 0) indicator_led(1); + //else if (! go_to_standby) indicator_led(0); #else - if (! go_to_standby) - indicator_led(0); - #endif + #if defined(USE_INDICATOR_LED) || defined(USE_AUX_RGB_LEDS) + if (! go_to_standby) { + #ifdef USE_INDICATOR_LED + indicator_led(0); + #endif + #ifdef USE_AUX_RGB_LEDS + rgb_led_set(0); + #endif + } + #endif #endif //TCCR0A = PHASE; diff --git a/spaghetti-monster/fsm-standby.c b/spaghetti-monster/fsm-standby.c index 7d60c1d..44b047a 100644 --- a/spaghetti-monster/fsm-standby.c +++ b/spaghetti-monster/fsm-standby.c @@ -56,7 +56,9 @@ void sleep_until_eswitch_pressed() set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_enable(); + #ifdef BODCR // only do this on MCUs which support it sleep_bod_disable(); + #endif sleep_cpu(); // wait here // something happened; wake up diff --git a/spaghetti-monster/fsm-wdt.c b/spaghetti-monster/fsm-wdt.c index d5bbdb9..6e61e87 100644 --- a/spaghetti-monster/fsm-wdt.c +++ b/spaghetti-monster/fsm-wdt.c @@ -25,38 +25,65 @@ void WDT_on() { - // interrupt every 16ms - //cli(); // Disable interrupts - wdt_reset(); // Reset the WDT - WDTCR |= (1< +#include // include project definitions to help with recognizing symbols #include "fsm-events.h" -- cgit v1.2.3