diff options
| author | Selene ToyKeeper | 2019-07-26 20:51:38 -0600 |
|---|---|---|
| committer | Selene ToyKeeper | 2019-07-26 20:51:38 -0600 |
| commit | 849fcfd3e1b828c6f35d62792a308917b2ef0053 (patch) | |
| tree | 0da7ccd286a2a3d30fa144681b4bd71a756f9531 /spaghetti-monster | |
| parent | merged Mateminco MF01S / MT18 branch, adding support for the new light (diff) | |
| download | anduril-849fcfd3e1b828c6f35d62792a308917b2ef0053.tar.gz anduril-849fcfd3e1b828c6f35d62792a308917b2ef0053.tar.bz2 anduril-849fcfd3e1b828c6f35d62792a308917b2ef0053.zip | |
merged a sanitized copy of the Emisar D4v2 branch; history summarized below:
------------------------------------------------------------
revno: 457
committer: Selene ToyKeeper <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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 <git@toykeeper.net>
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
Diffstat (limited to '')
| -rw-r--r-- | spaghetti-monster/anduril/anduril.c | 282 | ||||
| -rwxr-xr-x | spaghetti-monster/anduril/build-all.sh | 6 | ||||
| -rw-r--r-- | spaghetti-monster/anduril/cfg-emisar-d4.h | 14 | ||||
| -rw-r--r-- | spaghetti-monster/anduril/cfg-emisar-d4s.h | 6 | ||||
| -rw-r--r-- | spaghetti-monster/anduril/cfg-emisar-d4v2-219.h | 8 | ||||
| -rw-r--r-- | spaghetti-monster/anduril/cfg-emisar-d4v2.h | 51 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-adc.c | 137 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-adc.h | 3 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-events.c | 24 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-main.c | 56 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-misc.c | 35 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-misc.h | 7 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-pcint.c | 42 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-ramping.c | 26 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-standby.c | 2 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-wdt.c | 82 | ||||
| -rw-r--r-- | spaghetti-monster/fsm-wdt.h | 5 | ||||
| -rw-r--r-- | spaghetti-monster/rampingios/rampingiosv3.c | 43 | ||||
| -rw-r--r-- | spaghetti-monster/spaghetti-monster.h | 1 |
19 files changed, 645 insertions, 185 deletions
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<NUM_VOLTAGE_VALUES; i++) voltage_values[i] = measurement; - voltage = 42; // Life, the Universe, and Everything (*) + voltage = 42; // the answer to life, the universe, and the voltage of a full li-ion cell } else { uint16_t total = 0; uint8_t i; @@ -181,7 +239,7 @@ ISR(ADC_vect) { // temperature else if (adc_step == 3) { // Convert ADC units to Celsius (ish) - int16_t temp = measurement - 275 + THERM_CAL_OFFSET + therm_cal_offset; + int16_t temp = measurement - 275 + THERM_CAL_OFFSET + (int16_t)therm_cal_offset; // prime on first execution if (reset_thermal_history) { @@ -202,14 +260,18 @@ ISR(ADC_vect) { // guess what the temperature will be in a few seconds int16_t pt; { - uint8_t i; int16_t diff; int16_t t = temperature; // algorithm tweaking; not really intended to be modified // how far ahead should we predict? + #ifndef THERM_PREDICTION_STRENGTH #define THERM_PREDICTION_STRENGTH 4 - // how proportional should the adjustments be? + #endif + // how proportional should the adjustments be? (not used yet) + #ifndef THERM_RESPONSE_MAGNITUDE + #define THERM_RESPONSE_MAGNITUDE 128 + #endif // acceptable temperature window size in C #define THERM_WINDOW_SIZE 5 // highest temperature allowed @@ -219,13 +281,22 @@ ISR(ADC_vect) { // if it's time to rotate the thermal history, do it history_step ++; - if (0 == (history_step & 7)) { + #if (THERMAL_UPDATE_SPEED == 4) // new value every 4s + #define THERM_HISTORY_STEP_MAX 15 + #elif (THERMAL_UPDATE_SPEED == 2) // new value every 2s + #define THERM_HISTORY_STEP_MAX 7 + #elif (THERMAL_UPDATE_SPEED == 1) // new value every 1s + #define THERM_HISTORY_STEP_MAX 3 + #elif (THERMAL_UPDATE_SPEED == 0) // new value every 0.5s + #define THERM_HISTORY_STEP_MAX 1 + #endif + if (0 == (history_step & THERM_HISTORY_STEP_MAX)) { // rotate measurements and add a new one - for (i=0; i<NUM_THERMAL_VALUES_HISTORY-1; i++) { + for (uint8_t i=0; i<NUM_THERMAL_VALUES_HISTORY-1; i++) { temperature_history[i] = temperature_history[i+1]; } + temperature_history[NUM_THERMAL_VALUES_HISTORY-1] = t; } - temperature_history[NUM_THERMAL_VALUES_HISTORY-1] = t; // guess what the temp will be several seconds in the future // diff = rate of temperature change @@ -244,7 +315,8 @@ ISR(ADC_vect) { // cancel counters if appropriate if (pt > 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<<CLKPCE; CLKPR = 2; + clock_prescale_set(clock_div_4); _delay_loop_2(BOGOMIPS*98/100/4); } //else if (level < HALFSPEED_LEVEL) { - // CLKPR = 1<<CLKPCE; CLKPR = 1; + // clock_prescale_set(clock_div_2); // _delay_loop_2(BOGOMIPS*98/100/2); //} else { - CLKPR = 1<<CLKPCE; CLKPR = 0; + clock_prescale_set(clock_div_1); _delay_loop_2(BOGOMIPS*98/100); } // restore regular clock speed - CLKPR = 1<<CLKPCE; CLKPR = 0; + clock_prescale_set(clock_div_1); #else // underclock MCU to save power - CLKPR = 1<<CLKPCE; CLKPR = 2; + clock_prescale_set(clock_div_4); // wait _delay_loop_2(BOGOMIPS*98/100/4); // restore regular clock speed - CLKPR = 1<<CLKPCE; CLKPR = 0; + clock_prescale_set(clock_div_1); #endif // ifdef USE_RAMPING #else // wait @@ -159,11 +160,18 @@ uint8_t nice_delay_ms(uint16_t ms) { void delay_4ms(uint8_t ms) { while(ms-- > 0) { // underclock MCU to save power - CLKPR = 1<<CLKPCE; CLKPR = 2; + clock_prescale_set(clock_div_4); // wait _delay_loop_2(BOGOMIPS*98/100); // restore regular clock speed - CLKPR = 1<<CLKPCE; CLKPR = 0; + clock_prescale_set(clock_div_1); + } +} +#else +void delay_4ms(uint8_t ms) { + while(ms-- > 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<<WDRF); // reset status flag - wdt_disable(); - #endif - - #ifdef HALFSPEED - // run at half speed - CLKPR = 1<<CLKPCE; - CLKPR = 1; - #endif - +#if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) +inline void hw_setup() { // configure PWM channels #if PWM_CHANNELS >= 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<<WDRF); // reset status flag + wdt_disable(); +} +#endif + + +int main() { + // Don't allow interrupts while booting + cli(); + + #ifdef USE_REBOOT + prevent_reboot_loop(); + #endif + + hw_setup(); + + #if 0 + #ifdef HALFSPEED + // run at half speed + // FIXME: not portable (also not needed) + CLKPR = 1<<CLKPCE; + CLKPR = 1; + #endif + #endif #ifdef USE_DEBUG_BLINK //debug_blink(1); diff --git a/spaghetti-monster/fsm-misc.c b/spaghetti-monster/fsm-misc.c index eced482..8e88cbd 100644 --- a/spaghetti-monster/fsm-misc.c +++ b/spaghetti-monster/fsm-misc.c @@ -20,6 +20,7 @@ #ifndef FSM_MISC_C #define FSM_MISC_C + #ifdef USE_DYNAMIC_UNDERCLOCKING void auto_clock_speed() { uint8_t level = actual_level; // volatile, avoid repeat access @@ -27,14 +28,14 @@ void auto_clock_speed() { // run at quarter speed // note: this only works when executed as two consecutive instructions // (don't try to combine them or put other stuff between) - CLKPR = 1<<CLKPCE; CLKPR = 2; + clock_prescale_set(clock_div_4); } else if (level < HALFSPEED_LEVEL) { // run at half speed - CLKPR = 1<<CLKPCE; CLKPR = 1; + clock_prescale_set(clock_div_2); } else { // run at full speed - CLKPR = 1<<CLKPCE; CLKPR = 0; + clock_prescale_set(clock_div_1); } } #endif @@ -146,6 +147,34 @@ void indicator_led_auto() { */ #endif // USE_INDICATOR_LED +#ifdef USE_AUX_RGB_LEDS +void rgb_led_set(uint8_t value) { + // value: 0b00BBGGRR + uint8_t pins[] = { AUXLED_R_PIN, AUXLED_G_PIN, AUXLED_B_PIN }; + for (uint8_t i=0; i<3; i++) { + uint8_t lvl = (value >> (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<<SWITCH_PIN)) == 0); + readings = (readings << 1) | ((SWITCH_PORT & (1<<SWITCH_PIN)) == 0); // wait a moment _delay_loop_2(BOGOMIPS/16); // up to 2ms to stabilize } @@ -40,21 +40,45 @@ uint8_t button_is_pressed() { } inline void PCINT_on() { - // enable pin change interrupt for pin N - GIMSK |= (1 << PCIE); - // only pay attention to the e-switch pin - //PCMSK = (1 << SWITCH_PCINT); - // set bits 1:0 to 0b01 (interrupt on rising *and* falling edge) (default) - // MCUCR &= 0b11111101; MCUCR |= 0b00000001; + #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) + // enable pin change interrupt + GIMSK |= (1 << PCIE); + // only pay attention to the e-switch pin + #if 0 // this is redundant; was already done in main() + PCMSK = (1 << SWITCH_PCINT); + #endif + // set bits 1:0 to 0b01 (interrupt on rising *and* falling edge) (default) + // MCUCR &= 0b11111101; MCUCR |= 0b00000001; + #elif (ATTINY == 1634) + // enable pin change interrupt + #ifdef SWITCH2_PCIE + GIMSK |= ((1 << SWITCH_PCIE) | (1 << SWITCH2_PCIE)); + #else + GIMSK |= (1 << SWITCH_PCIE); + #endif + #else + #error Unrecognized MCU type + #endif } inline void PCINT_off() { - // disable all pin-change interrupts - GIMSK &= ~(1 << PCIE); + #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) + // disable all pin-change interrupts + GIMSK &= ~(1 << PCIE); + #elif (ATTINY == 1634) + // disable all pin-change interrupts + GIMSK &= ~(1 << SWITCH_PCIE); + #else + #error Unrecognized MCU type + #endif } //void button_change_interrupt() { +#if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) || (ATTINY == 1634) EMPTY_INTERRUPT(PCINT0_vect); +#else + #error Unrecognized MCU type +#endif /* ISR(PCINT0_vect) { diff --git a/spaghetti-monster/fsm-ramping.c b/spaghetti-monster/fsm-ramping.c index 082f8c9..efa07e4 100644 --- a/spaghetti-monster/fsm-ramping.c +++ b/spaghetti-monster/fsm-ramping.c @@ -30,17 +30,25 @@ void set_level(uint8_t level) { gradual_target = level; #endif - #ifdef USE_INDICATOR_LED #ifdef USE_INDICATOR_LED_WHILE_RAMPING - if (! go_to_standby) - indicator_led((level > 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<<WDCE) | (1<<WDE); // Start timed sequence - WDTCR = (1<<WDIE); // Enable interrupt every 16ms - //sei(); // Enable interrupts + #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) + // interrupt every 16ms + //cli(); // Disable interrupts + wdt_reset(); // Reset the WDT + WDTCR |= (1<<WDCE) | (1<<WDE); // Start timed sequence + WDTCR = (1<<WDIE); // Enable interrupt every 16ms + //sei(); // Enable interrupts + #elif (ATTINY == 1634) + wdt_reset(); // Reset the WDT + WDTCSR = (1<<WDIE); // Enable interrupt every 16ms + #else + #error Unrecognized MCU type + #endif } #ifdef TICK_DURING_STANDBY inline void WDT_slow() { - // interrupt slower - //cli(); // Disable interrupts - wdt_reset(); // Reset the WDT - WDTCR |= (1<<WDCE) | (1<<WDE); // Start timed sequence - WDTCR = (1<<WDIE) | STANDBY_TICK_SPEED; // Enable interrupt every so often - //sei(); // Enable interrupts + #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) + // interrupt slower + //cli(); // Disable interrupts + wdt_reset(); // Reset the WDT + WDTCR |= (1<<WDCE) | (1<<WDE); // Start timed sequence + WDTCR = (1<<WDIE) | STANDBY_TICK_SPEED; // Enable interrupt every so often + //sei(); // Enable interrupts + #elif (ATTINY == 1634) + wdt_reset(); // Reset the WDT + WDTCSR = (1<<WDIE) | STANDBY_TICK_SPEED; + #else + #error Unrecognized MCU type + #endif } #endif inline void WDT_off() { - //cli(); // Disable interrupts - wdt_reset(); // Reset the WDT - MCUSR &= ~(1<<WDRF); // Clear Watchdog reset flag - WDTCR |= (1<<WDCE) | (1<<WDE); // Start timed sequence - WDTCR = 0x00; // Disable WDT - //sei(); // Enable interrupts + #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) + //cli(); // Disable interrupts + wdt_reset(); // Reset the WDT + MCUSR &= ~(1<<WDRF); // Clear Watchdog reset flag + WDTCR |= (1<<WDCE) | (1<<WDE); // Start timed sequence + WDTCR = 0x00; // Disable WDT + //sei(); // Enable interrupts + #elif (ATTINY == 1634) + cli(); // needed because CCP, below + wdt_reset(); // Reset the WDT + MCUSR &= ~(1<<WDRF); // clear watchdog reset flag + CCP = 0xD8; // enable config changes + WDTCSR = 0; // disable and clear all WDT settings + sei(); + #else + #error Unrecognized MCU type + #endif } // clock tick -- this runs every 16ms (62.5 fps) ISR(WDT_vect) { + static uint8_t adc_trigger = 0; + #ifdef TICK_DURING_STANDBY f_wdt = 1; // WDT event happened @@ -68,9 +95,16 @@ ISR(WDT_vect) { // wrap around from 65535 to 32768, not 0 sleep_counter = (sleep_counter + 1) | (sleep_counter & 0x8000); process_emissions(); - return; + + #if defined(USE_SLEEP_LVP) + // stop here, usually... but proceed often enough for sleep LVP to work + if (0 != (sleep_counter & 0x7f)) return; + adc_trigger = 255; // make sure a measurement will happen + #else + return; // no sleep LVP needed if nothing drains power while off + #endif } - sleep_counter = 0; + else { sleep_counter = 0; } #endif // detect and emit button change events @@ -136,10 +170,14 @@ ISR(WDT_vect) { #if defined(USE_LVP) || defined(USE_THERMAL_REGULATION) // start a new ADC measurement every 4 ticks - static uint8_t adc_trigger = 0; adc_trigger ++; if (0 == (adc_trigger & 3)) { - ADCSRA |= (1 << ADSC) | (1 << ADIE); + #if defined(TICK_DURING_STANDBY) && defined(USE_SLEEP_LVP) + // we shouldn't be here unless it woke up for a LVP check... + // so enable ADC voltage measurement functions temporarily + if (go_to_standby) ADC_on(); + #endif + ADC_start_measurement(); adcint_enable = 1; } #endif diff --git a/spaghetti-monster/fsm-wdt.h b/spaghetti-monster/fsm-wdt.h index 3c395c1..78fe791 100644 --- a/spaghetti-monster/fsm-wdt.h +++ b/spaghetti-monster/fsm-wdt.h @@ -27,6 +27,11 @@ inline void WDT_off(); #ifdef TICK_DURING_STANDBY volatile uint8_t f_wdt = 0; + + #if defined(USE_INDICATOR_LED) || defined(USE_AUX_RGB_LEDS) + // measure battery charge while asleep + #define USE_SLEEP_LVP + #endif #endif #endif diff --git a/spaghetti-monster/rampingios/rampingiosv3.c b/spaghetti-monster/rampingios/rampingiosv3.c index e4eb2fa..d72e971 100644 --- a/spaghetti-monster/rampingios/rampingiosv3.c +++ b/spaghetti-monster/rampingios/rampingiosv3.c @@ -148,9 +148,6 @@ void blink_confirm(uint8_t num); #if defined(USE_INDICATOR_LED) && defined(TICK_DURING_STANDBY) void indicator_blink(uint8_t arg); #endif -#ifdef USE_INDICATOR_LED -uint8_t auxled_next_state(Event event, uint16_t arg); -#endif // remember stuff even after battery was changed void load_config(); @@ -347,7 +344,18 @@ uint8_t off_state(Event event, uint16_t arg) { // 7 clicks: next aux LED mode else if (event == EV_7clicks) { blink_confirm(1); - set_state(auxled_next_state, 0); + uint8_t mode = (indicator_led_mode & 3) + 1; + #ifdef TICK_DURING_STANDBY + mode = mode & 3; + #else + mode = mode % 3; + #endif + #ifdef INDICATOR_LED_SKIP_LOW + if (mode == 1) { mode ++; } + #endif + indicator_led_mode = (indicator_led_mode & 0b11111100) | mode; + indicator_led(mode); + save_config(); return MISCHIEF_MANAGED; } #endif @@ -811,33 +819,6 @@ uint8_t lockout_state(Event event, uint16_t arg) { } -#ifdef USE_INDICATOR_LED -uint8_t auxled_next_state(Event event, uint16_t arg) { - if (event == EV_enter_state) { - uint8_t mode = indicator_led_mode & 3; - #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 + (indicator_led_mode & 0b00001100); - indicator_led(mode); - save_config(); - return MISCHIEF_MANAGED; - } - else if (event == EV_tick) { - set_state(off_state, 0); - return MISCHIEF_MANAGED; - } - - return EVENT_NOT_HANDLED; -} -#endif - - uint8_t momentary_state(Event event, uint16_t arg) { // TODO: momentary strobe here? (for light painting) diff --git a/spaghetti-monster/spaghetti-monster.h b/spaghetti-monster/spaghetti-monster.h index 08690b4..853eac3 100644 --- a/spaghetti-monster/spaghetti-monster.h +++ b/spaghetti-monster/spaghetti-monster.h @@ -25,6 +25,7 @@ #include "tk-attiny.h" #include <avr/eeprom.h> +#include <avr/power.h> // include project definitions to help with recognizing symbols #include "fsm-events.h" |
