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 --- bin/flash-tiny1634-fuses.sh | 9 + bin/flash-tiny1634.sh | 3 + bin/level_calc.py | 10 + hwdef-Emisar_D4v2.h | 100 +++++++++ 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 + tk-attiny.h | 55 ++++- 24 files changed, 819 insertions(+), 188 deletions(-) create mode 100755 bin/flash-tiny1634-fuses.sh create mode 100755 bin/flash-tiny1634.sh create mode 100644 hwdef-Emisar_D4v2.h create mode 100644 spaghetti-monster/anduril/cfg-emisar-d4v2-219.h create mode 100644 spaghetti-monster/anduril/cfg-emisar-d4v2.h diff --git a/bin/flash-tiny1634-fuses.sh b/bin/flash-tiny1634-fuses.sh new file mode 100755 index 0000000..1bc73e1 --- /dev/null +++ b/bin/flash-tiny1634-fuses.sh @@ -0,0 +1,9 @@ +#/bin/sh +# 8 MHz, 64ms boot delay, enable flashing +# (everything else disabled) +# Use low fuse 0xD2 for 4ms startup delay, +# or 0xE2 for 64ms (useful on a twisty light) +# Use high fuse 0xDE for BOD 1.8V, +# or 0xDF for no BOD +avrdude -c usbasp -p t1634 -u -U lfuse:w:0xe2:m -U hfuse:w:0xde:m -U efuse:w:0xff:m + diff --git a/bin/flash-tiny1634.sh b/bin/flash-tiny1634.sh new file mode 100755 index 0000000..2eb9b77 --- /dev/null +++ b/bin/flash-tiny1634.sh @@ -0,0 +1,3 @@ +#/bin/sh +FIRMWARE=$1 +avrdude -c usbasp -p t1634 -u -Uflash:w:$FIRMWARE diff --git a/bin/level_calc.py b/bin/level_calc.py index f16f8ce..f1e7d16 100755 --- a/bin/level_calc.py +++ b/bin/level_calc.py @@ -152,6 +152,16 @@ def multi_pwm(answers, channels): (cnum+1, ','.join([str(int(round(i))) for i in channel.modes]))) + # Show highest level for each channel before next channel starts + for cnum, channel in enumerate(channels[:-1]): + prev = 0 + i = 1 + while (i < answers.num_levels) \ + and (channel.modes[i] >= channel.modes[i-1]) \ + and (channels[cnum+1].modes[i] == 0): + i += 1 + print('Ch%i max: %i (%.2f/255)' % (cnum, i, channel.modes[i-1])) + def get_value(text, default, args): """Get input from the user, or from the command line args.""" diff --git a/hwdef-Emisar_D4v2.h b/hwdef-Emisar_D4v2.h new file mode 100644 index 0000000..0460fad --- /dev/null +++ b/hwdef-Emisar_D4v2.h @@ -0,0 +1,100 @@ +#ifndef HWDEF_EMISAR_D4V2_H +#define HWDEF_EMISAR_D4V2_H + +/* Emisar D4v2 driver layout (attiny1634) + * + * Pin / Name / Function + * 1 PA6 FET PWM (PWM1B) + * 2 PA5 red aux LED (PWM0B) + * 3 PA4 green aux LED + * 4 PA3 blue aux LED + * 5 PA2 e-switch + * 6 PA1 (none) + * 7 PA0 (none) + * 8 GND GND + * 9 VCC VCC + * 10 PC5 (none) + * 11 PC4 (none) + * 12 PC3 RESET + * 13 PC2 (none) + * 14 PC1 SCK + * 15 PC0 (none) PWM0A + * 16 PB3 7135 PWM (PWM1A) + * 17 PB2 MISO + * 18 PB1 MOSI + * 19 PB0 (none) + * 20 PA7 (none) + * ADC12 thermal sensor + */ + +#ifdef ATTINY +#undef ATTINY +#endif +#define ATTINY 1634 +#include + +#define PWM_CHANNELS 2 + +#define SWITCH_PIN PA2 // pin 5 +#define SWITCH_PCINT PCINT2 // pin 5 pin change interrupt +#define SWITCH_PCIE PCIE0 // PCIE0 is for PCINT[7:0] +#define SWITCH_PCMSK PCMSK0 // PCMSK0 is for PCINT[7:0] +#define SWITCH_PORT PINA // PINA or PINB or PINC + +#define PWM1_PIN PB3 // pin 16, 1x7135 PWM +#define PWM1_LVL OCR1A // OCR1A is the output compare register for PB3 + +#define PWM2_PIN PA6 // pin 1, FET PWM +#define PWM2_LVL OCR1B // OCR1B is the output compare register for PB1 + + +#define ADC_PRSCL 0x06 // clk/64 + +// average drop across diode on this hardware +#ifndef VOLTAGE_FUDGE_FACTOR +#define VOLTAGE_FUDGE_FACTOR 4 // add 0.20V (measured 0.22V) +#endif + +#define TEMP_CHANNEL 0b00001111 + +// this light has aux LEDs under the optic +#define AUXLED_R_PIN PA5 // pin 2 +#define AUXLED_G_PIN PA4 // pin 3 +#define AUXLED_B_PIN PA3 // pin 4 +#define AUXLED_RGB_PORT PORTA // PORTA or PORTB or PORTC +#define AUXLED_RGB_DDR DDRA // DDRA or DDRB or DDRC +#define AUXLED_RGB_PUE PUEA // PUEA or PUEB or PUEC + +// with so many pins, doing this all with #ifdefs gets awkward... +// ... so just hardcode it in each hwdef file instead +inline void hwdef_setup() { + // enable output ports + // 7135 + DDRB = (1 << PWM1_PIN); + // FET, aux R/G/B + DDRA = (1 << PWM2_PIN) + | (1 << AUXLED_R_PIN) + | (1 << AUXLED_G_PIN) + | (1 << AUXLED_B_PIN) + ; + + // configure PWM + // Setup PWM. F_pwm = F_clkio / 2 / N / TOP, where N = prescale factor, TOP = top of counter + // pre-scale for timer: N = 1 + TCCR1A = (0< 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" diff --git a/tk-attiny.h b/tk-attiny.h index 3c985f2..947a87c 100644 --- a/tk-attiny.h +++ b/tk-attiny.h @@ -28,24 +28,26 @@ /******************** hardware-specific values **************************/ #if (ATTINY == 13) #define F_CPU 4800000UL - #define EEPSIZE 64 + //#define EEPSIZE 64 #define V_REF REFS0 #define BOGOMIPS 950 #define ADMUX_VCC 0b00001100 #define DELAY_ZERO_TIME 252 + #define SWITCH_PORT PINB // PINA or PINB or PINC #elif (ATTINY == 25) // TODO: Use 6.4 MHz instead of 8 MHz? #define F_CPU 8000000UL - #define EEPSIZE 128 + //#define EEPSIZE 128 #define V_REF REFS1 #define BOGOMIPS (F_CPU/4000) #define ADMUX_VCC 0b00001100 #define ADMUX_THERM 0b10001111 #define DELAY_ZERO_TIME 1020 + #define SWITCH_PORT PINB // PINA or PINB or PINC #elif (ATTINY == 85) // TODO: Use 6.4 MHz instead of 8 MHz? #define F_CPU 8000000UL - #define EEPSIZE 512 + //#define EEPSIZE 512 #define V_REF REFS1 #define BOGOMIPS (F_CPU/4000) // (1 << V_REF) | (0 << ADLAR) | (VCC_CHANNEL) @@ -53,10 +55,30 @@ // (1 << V_REF) | (0 << ADLAR) | (THERM_CHANNEL) #define ADMUX_THERM 0b10001111 #define DELAY_ZERO_TIME 1020 + #define SWITCH_PORT PINB // PINA or PINB or PINC +#elif (ATTINY == 1634) + #define F_CPU 8000000UL + #define V_REF REFS1 + #define BOGOMIPS (F_CPU/4000) + // (1 << V_REF) | (0 << ADLAR) | (VCC_CHANNEL) + #define ADMUX_VCC 0b00001101 + // (1 << V_REF) | (0 << ADLAR) | (THERM_CHANNEL) + #define ADMUX_THERM 0b10001110 + #define DELAY_ZERO_TIME 1020 + //#define SWITCH_PORT PINA // set this in hwdef #else #error Hey, you need to define ATTINY. #endif +// auto-detect eeprom size from avr-libc headers +#ifndef EEPSIZE +#ifdef E2SIZE +#define EEPSIZE E2SIZE +#else +#define EEPSIZE (E2END+1) +#endif +#endif + #include @@ -86,4 +108,31 @@ #error Hey, you need to define an I/O pin layout. #endif +#if (ATTINY==25) || (ATTINY==45) || (ATTINY==85) + // use clock_prescale_set(n) instead; it's safer + //#define CLOCK_DIVIDER_SET(n) {CLKPR = 1<= channel.modes[i-1]) \ and (channels[cnum+1].modes[i] == 0): i += 1 - print('Ch%i max: %i (%.2f/255)' % (cnum, i, channel.modes[i-1])) + print('Ch%i max: %i (%.2f/%s)' % (cnum, i, channel.modes[i-1], max_pwm)) def get_value(text, default, args): -- cgit v1.2.3 From b4faa446aca1271d918d8a809c770ebeb5efa8a4 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Tue, 30 Jul 2019 15:59:23 -0600 Subject: fsm-ramping: made it possible to change bit depth of PWM values (8-bit or 16-bit) --- spaghetti-monster/fsm-ramping.c | 26 +++++++++--------- spaghetti-monster/fsm-ramping.h | 58 +++++++++++++++++++++++++---------------- 2 files changed, 48 insertions(+), 36 deletions(-) diff --git a/spaghetti-monster/fsm-ramping.c b/spaghetti-monster/fsm-ramping.c index efa07e4..69e20bc 100644 --- a/spaghetti-monster/fsm-ramping.c +++ b/spaghetti-monster/fsm-ramping.c @@ -71,7 +71,7 @@ void set_level(uint8_t level) { #ifdef USE_TINT_RAMPING // calculate actual PWM levels based on a single-channel ramp // and a global tint value - uint8_t brightness = pgm_read_byte(pwm1_levels + level); + uint8_t brightness = PWM_GET(pwm1_levels, level); uint8_t warm_PWM, cool_PWM; // auto-tint modes @@ -104,16 +104,16 @@ void set_level(uint8_t level) { #else #if PWM_CHANNELS >= 1 - PWM1_LVL = pgm_read_byte(pwm1_levels + level); + PWM1_LVL = PWM_GET(pwm1_levels, level); #endif #if PWM_CHANNELS >= 2 - PWM2_LVL = pgm_read_byte(pwm2_levels + level); + PWM2_LVL = PWM_GET(pwm2_levels, level); #endif #if PWM_CHANNELS >= 3 - PWM3_LVL = pgm_read_byte(pwm3_levels + level); + PWM3_LVL = PWM_GET(pwm3_levels, level); #endif #if PWM_CHANNELS >= 4 - PWM4_LVL = pgm_read_byte(pwm4_levels + level); + PWM4_LVL = PWM_GET(pwm4_levels, level); #endif #endif // ifdef USE_TINT_RAMPING @@ -140,7 +140,7 @@ void gradual_tick() { uint8_t target; #if PWM_CHANNELS >= 1 - target = pgm_read_byte(pwm1_levels + gt); + target = PWM_GET(pwm1_levels, gt); if ((gt < actual_level) // special case for FET-only turbo && (PWM1_LVL == 0) // (bypass adjustment period for first step) && (target == 255)) PWM1_LVL = 255; @@ -148,32 +148,32 @@ void gradual_tick() { else if (PWM1_LVL > target) PWM1_LVL --; #endif #if PWM_CHANNELS >= 2 - target = pgm_read_byte(pwm2_levels + gt); + target = PWM_GET(pwm2_levels, gt); if (PWM2_LVL < target) PWM2_LVL ++; else if (PWM2_LVL > target) PWM2_LVL --; #endif #if PWM_CHANNELS >= 3 - target = pgm_read_byte(pwm3_levels + gt); + target = PWM_GET(pwm3_levels, gt); if (PWM3_LVL < target) PWM3_LVL ++; else if (PWM3_LVL > target) PWM3_LVL --; #endif #if PWM_CHANNELS >= 4 - target = pgm_read_byte(pwm4_levels + gt); + target = PWM_GET(pwm4_levels, gt); if (PWM4_LVL < target) PWM4_LVL ++; else if (PWM4_LVL > target) PWM4_LVL --; #endif // did we go far enough to hit the next defined ramp level? // if so, update the main ramp level tracking var - if ((PWM1_LVL == pgm_read_byte(pwm1_levels + gt)) + if ((PWM1_LVL == PWM_GET(pwm1_levels, gt)) #if PWM_CHANNELS >= 2 - && (PWM2_LVL == pgm_read_byte(pwm2_levels + gt)) + && (PWM2_LVL == PWM_GET(pwm2_levels, gt)) #endif #if PWM_CHANNELS >= 3 - && (PWM3_LVL == pgm_read_byte(pwm3_levels + gt)) + && (PWM3_LVL == PWM_GET(pwm3_levels, gt)) #endif #if PWM_CHANNELS >= 4 - && (PWM4_LVL == pgm_read_byte(pwm4_levels + gt)) + && (PWM4_LVL == PWM_GET(pwm4_levels, gt)) #endif ) { diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h index dcc3b74..7233474 100644 --- a/spaghetti-monster/fsm-ramping.h +++ b/spaghetti-monster/fsm-ramping.h @@ -38,18 +38,30 @@ inline void set_level_gradually(uint8_t lvl); void gradual_tick(); #endif +// auto-detect the data type for PWM tables +#ifndef PWM_BITS +#define PWM_BITS 8 +#endif +#if PWM_BITS <= 8 +#define PWM_DATATYPE uint8_t +#define PWM_GET(x,y) pgm_read_byte(x+y) +#else +#define PWM_DATATYPE uint16_t +#define PWM_GET(x,y) pgm_read_word(x+(2*y)) +#endif + // use UI-defined ramp tables if they exist #ifdef PWM1_LEVELS -PROGMEM const uint8_t pwm1_levels[] = { PWM1_LEVELS }; +PROGMEM const PWM_DATATYPE pwm1_levels[] = { PWM1_LEVELS }; #endif #ifdef PWM2_LEVELS -PROGMEM const uint8_t pwm2_levels[] = { PWM2_LEVELS }; +PROGMEM const PWM_DATATYPE pwm2_levels[] = { PWM2_LEVELS }; #endif #ifdef PWM3_LEVELS -PROGMEM const uint8_t pwm3_levels[] = { PWM3_LEVELS }; +PROGMEM const PWM_DATATYPE pwm3_levels[] = { PWM3_LEVELS }; #endif #ifdef PWM4_LEVELS -PROGMEM const uint8_t pwm4_levels[] = { PWM4_LEVELS }; +PROGMEM const PWM_DATATYPE pwm4_levels[] = { PWM4_LEVELS }; #endif // default / example ramps @@ -57,31 +69,31 @@ PROGMEM const uint8_t pwm4_levels[] = { PWM4_LEVELS }; #if PWM_CHANNELS == 1 #if RAMP_LENGTH == 50 // ../../bin/level_calc.py 1 50 7135 3 0.25 980 - PROGMEM const uint8_t pwm1_levels[] = { 3,3,3,3,4,4,4,5,5,6,7,8,9,11,12,14,16,18,20,23,25,28,32,35,39,43,47,52,57,62,68,74,80,87,94,102,110,118,127,136,146,156,167,178,189,201,214,227,241,255 }; + PROGMEM const PWM_DATATYPE pwm1_levels[] = { 3,3,3,3,4,4,4,5,5,6,7,8,9,11,12,14,16,18,20,23,25,28,32,35,39,43,47,52,57,62,68,74,80,87,94,102,110,118,127,136,146,156,167,178,189,201,214,227,241,255 }; #elif RAMP_LENGTH == 75 // ../../bin/level_calc.py 1 75 7135 3 0.25 980 - PROGMEM const uint8_t pwm1_levels[] = { 3,3,3,3,3,3,4,4,4,4,5,5,5,6,6,7,8,8,9,10,11,12,13,14,15,17,18,20,21,23,25,27,29,31,33,36,38,41,44,47,50,53,56,59,63,67,71,75,79,83,88,93,98,103,108,113,119,125,131,137,143,150,157,164,171,178,186,194,202,210,219,227,236,246,255 }; + PROGMEM const PWM_DATATYPE pwm1_levels[] = { 3,3,3,3,3,3,4,4,4,4,5,5,5,6,6,7,8,8,9,10,11,12,13,14,15,17,18,20,21,23,25,27,29,31,33,36,38,41,44,47,50,53,56,59,63,67,71,75,79,83,88,93,98,103,108,113,119,125,131,137,143,150,157,164,171,178,186,194,202,210,219,227,236,246,255 }; #elif RAMP_LENGTH == 150 // ../../bin/level_calc.py 1 150 7135 3 0.25 980 - PROGMEM const uint8_t pwm1_levels[] = { 3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,7,7,7,8,8,8,9,9,9,10,10,11,11,12,12,13,13,14,15,15,16,17,17,18,19,19,20,21,22,23,24,24,25,26,27,28,29,31,32,33,34,35,36,38,39,40,42,43,44,46,47,49,50,52,53,55,57,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,89,91,93,96,98,101,103,106,109,111,114,117,120,123,125,128,131,134,138,141,144,147,151,154,157,161,164,168,171,175,179,183,186,190,194,198,202,206,210,215,219,223,228,232,236,241,246,250,255 }; + PROGMEM const PWM_DATATYPE pwm1_levels[] = { 3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,7,7,7,8,8,8,9,9,9,10,10,11,11,12,12,13,13,14,15,15,16,17,17,18,19,19,20,21,22,23,24,24,25,26,27,28,29,31,32,33,34,35,36,38,39,40,42,43,44,46,47,49,50,52,53,55,57,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,89,91,93,96,98,101,103,106,109,111,114,117,120,123,125,128,131,134,138,141,144,147,151,154,157,161,164,168,171,175,179,183,186,190,194,198,202,206,210,215,219,223,228,232,236,241,246,250,255 }; #endif #elif PWM_CHANNELS == 2 #if RAMP_LENGTH == 50 // ../../bin/level_calc.py 2 50 7135 4 0.33 150 FET 1 10 1500 - PROGMEM const uint8_t pwm1_levels[] = { 4,5,6,8,10,13,17,22,28,35,44,54,65,78,93,109,128,149,171,197,224,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 }; - PROGMEM const uint8_t pwm2_levels[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,7,11,15,20,26,31,37,44,51,58,65,73,82,91,100,110,121,132,143,155,168,181,194,209,224,239,255 }; + PROGMEM const PWM_DATATYPE pwm1_levels[] = { 4,5,6,8,10,13,17,22,28,35,44,54,65,78,93,109,128,149,171,197,224,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 }; + PROGMEM const PWM_DATATYPE pwm2_levels[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,7,11,15,20,26,31,37,44,51,58,65,73,82,91,100,110,121,132,143,155,168,181,194,209,224,239,255 }; #define MAX_1x7135 22 #elif RAMP_LENGTH == 75 // ../../bin/level_calc.py 2 75 7135 4 0.33 150 FET 1 10 1500 - PROGMEM const uint8_t pwm1_levels[] = { 4,4,5,6,7,8,10,12,14,17,20,24,28,32,37,43,49,56,64,72,82,91,102,114,126,139,153,168,184,202,220,239,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 }; - PROGMEM const uint8_t 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,2,5,7,10,13,16,19,23,26,30,34,38,42,47,51,56,61,66,72,77,83,89,95,101,108,115,122,129,136,144,152,160,168,177,186,195,204,214,224,234,244,255 }; + PROGMEM const PWM_DATATYPE pwm1_levels[] = { 4,4,5,6,7,8,10,12,14,17,20,24,28,32,37,43,49,56,64,72,82,91,102,114,126,139,153,168,184,202,220,239,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 }; + PROGMEM const PWM_DATATYPE 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,2,5,7,10,13,16,19,23,26,30,34,38,42,47,51,56,61,66,72,77,83,89,95,101,108,115,122,129,136,144,152,160,168,177,186,195,204,214,224,234,244,255 }; #define MAX_1x7135 33 #elif RAMP_LENGTH == 150 // ../../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 - PROGMEM const uint8_t 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 }; - PROGMEM const uint8_t 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 }; + PROGMEM const PWM_DATATYPE 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 }; + PROGMEM const PWM_DATATYPE 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 @@ -89,25 +101,25 @@ PROGMEM const uint8_t pwm4_levels[] = { PWM4_LEVELS }; #elif PWM_CHANNELS == 3 #if RAMP_LENGTH == 50 // ../../bin/level_calc.py 3 50 7135 4 0.33 150 7135 4 1 840 FET 1 10 2000 - PROGMEM const uint8_t pwm1_levels[] = { 4,5,6,8,11,15,20,26,34,43,54,67,82,99,118,140,165,192,221,254,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 }; - PROGMEM const uint8_t pwm2_levels[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,17,25,33,42,52,62,73,85,97,111,125,140,157,174,192,210,230,251,255,255,255,255,255,255,255,255,255,255,0 }; - PROGMEM const uint8_t pwm3_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,14,34,54,76,98,122,146,172,198,226,255 }; + PROGMEM const PWM_DATATYPE pwm1_levels[] = { 4,5,6,8,11,15,20,26,34,43,54,67,82,99,118,140,165,192,221,254,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 }; + PROGMEM const PWM_DATATYPE pwm2_levels[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,17,25,33,42,52,62,73,85,97,111,125,140,157,174,192,210,230,251,255,255,255,255,255,255,255,255,255,255,0 }; + PROGMEM const PWM_DATATYPE pwm3_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,14,34,54,76,98,122,146,172,198,226,255 }; #define MAX_1x7135 20 #define MAX_Nx7135 39 #elif RAMP_LENGTH == 75 // ../../bin/level_calc.py 3 75 7135 4 0.33 150 7135 4 1 840 FET 1 10 2000 - PROGMEM const uint8_t pwm1_levels[] = { 4,4,5,6,7,9,11,14,16,20,24,28,34,40,46,54,62,71,81,92,104,117,130,146,162,179,198,218,239,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 }; - PROGMEM const uint8_t 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,5,9,14,18,23,29,34,40,47,53,60,67,75,83,91,99,108,117,127,137,148,158,170,181,193,206,219,232,246,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 }; - PROGMEM const uint8_t pwm3_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,3,15,28,42,55,70,84,99,115,131,147,164,181,199,217,236,255 }; + PROGMEM const PWM_DATATYPE pwm1_levels[] = { 4,4,5,6,7,9,11,14,16,20,24,28,34,40,46,54,62,71,81,92,104,117,130,146,162,179,198,218,239,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 }; + PROGMEM const PWM_DATATYPE 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,5,9,14,18,23,29,34,40,47,53,60,67,75,83,91,99,108,117,127,137,148,158,170,181,193,206,219,232,246,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 }; + PROGMEM const PWM_DATATYPE pwm3_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,3,15,28,42,55,70,84,99,115,131,147,164,181,199,217,236,255 }; #define MAX_1x7135 30 #define MAX_Nx7135 59 #elif RAMP_LENGTH == 150 // ../../bin/level_calc.py 1 65 7135 1 0.8 150 // ... mixed with this: // ../../../bin/level_calc.py 3 150 7135 1 0.33 150 7135 1 1 850 FET 1 10 1500 - PROGMEM const uint8_t 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 }; - PROGMEM const uint8_t 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,2,4,6,8,10,13,15,17,19,22,24,26,29,31,34,37,39,42,45,48,51,54,57,60,64,67,70,74,77,81,85,88,92,96,100,104,108,112,116,121,125,130,134,139,143,148,153,158,163,168,173,179,184,189,195,201,206,212,218,224,230,236,243,249,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 }; - PROGMEM const uint8_t pwm3_levels[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,19,31,43,55,67,79,91,104,117,130,143,157,170,184,198,212,226,240,255 }; + PROGMEM const PWM_DATATYPE 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 }; + PROGMEM const PWM_DATATYPE 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,2,4,6,8,10,13,15,17,19,22,24,26,29,31,34,37,39,42,45,48,51,54,57,60,64,67,70,74,77,81,85,88,92,96,100,104,108,112,116,121,125,130,134,139,143,148,153,158,163,168,173,179,184,189,195,201,206,212,218,224,230,236,243,249,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 }; + PROGMEM const PWM_DATATYPE pwm3_levels[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,19,31,43,55,67,79,91,104,117,130,143,157,170,184,198,212,226,240,255 }; #define MAX_1x7135 65 #define MAX_Nx7135 130 #define HALFSPEED_LEVEL 14 @@ -119,7 +131,7 @@ PROGMEM const uint8_t pwm4_levels[] = { PWM4_LEVELS }; #endif // RAMP_SIZE / MAX_LVL -#define RAMP_SIZE sizeof(pwm1_levels) +#define RAMP_SIZE (sizeof(pwm1_levels)/sizeof(PWM_DATATYPE)) #define MAX_LEVEL RAMP_SIZE void set_level(uint8_t level); -- cgit v1.2.3 From 26c61658ff87710d9528f6749202245464675a1c Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Tue, 30 Jul 2019 15:59:58 -0600 Subject: anduril: made it possible for config files to disable underclocking at low levels --- spaghetti-monster/anduril/anduril.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c index 8ab66f5..9853878 100644 --- a/spaghetti-monster/anduril/anduril.c +++ b/spaghetti-monster/anduril/anduril.c @@ -89,6 +89,10 @@ //#define USE_POLICE_STROBE_MODE //#define USE_SOS_MODE +// cut clock speed at very low modes for better efficiency +// (defined here so config files can override it) +#define USE_DYNAMIC_UNDERCLOCKING + /***** specific settings for known driver types *****/ #include "tk.h" #include incfile(CONFIGFILE) @@ -128,7 +132,6 @@ #endif #endif #define USE_IDLE_MODE // reduce power use while awake and no tasks are pending -#define USE_DYNAMIC_UNDERCLOCKING // cut clock speed at very low modes for better efficiency // full FET strobe can be a bit much... use max regulated level instead, // if there's a bright enough regulated level -- cgit v1.2.3 From 9fdb43496a1d2b54ab5c4f030d480d8f69d7529c Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Tue, 30 Jul 2019 16:00:57 -0600 Subject: added an early version of Emisar D1S v2 hwdef and cfg files (it compiles, but most likely doesn't actually work because it's far from finished) --- hwdef-Emisar_D1Sv2.h | 113 +++++++++++++++++++++++++++ spaghetti-monster/anduril/cfg-emisar-d1sv2.h | 51 ++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 hwdef-Emisar_D1Sv2.h create mode 100644 spaghetti-monster/anduril/cfg-emisar-d1sv2.h diff --git a/hwdef-Emisar_D1Sv2.h b/hwdef-Emisar_D1Sv2.h new file mode 100644 index 0000000..c51e827 --- /dev/null +++ b/hwdef-Emisar_D1Sv2.h @@ -0,0 +1,113 @@ +#ifndef HWDEF_EMISAR_D1SV2_H +#define HWDEF_EMISAR_D1SV2_H + +/* Emisar D1Sv2 driver layout (attiny1634) + * + * Pin / Name / Function + * 1 PA6 red aux LED (PWM1B) + * 2 PA5 green aux LED (PWM0B) + * 3 PA4 blue aux LED + * 4 PA3 battery voltage (ADC0) + * 5 PA2 (none) + * 6 PA1 (none) + * 7 PA0 (none) + * 8 GND GND + * 9 VCC VCC + * 10 PC5 (none) + * 11 PC4 (none) + * 12 PC3 RESET + * 13 PC2 (none) + * 14 PC1 SCK + * 15 PC0 (none) PWM0A + * 16 PB3 main LED PWM (PWM1A) + * 17 PB2 MISO + * 18 PB1 MOSI + * 19 PB0 Opamp power + * 20 PA7 e-switch (PCINT7) + * ADC12 thermal sensor + * + * Main LED power uses one pin to turn the Opamp on/off, + * and one pin to control Opamp power level. + * All brightness control uses the power level pin, with 4 kHz 10-bit PWM. + * The on/off pin is only used to turn the main LED on and off, + * not to change brightness. + */ + +#ifdef ATTINY +#undef ATTINY +#endif +#define ATTINY 1634 +#include + +#define PWM_CHANNELS 1 +#define PWM_BITS 10 // 0 to 1023 at 4 kHz, not 0 to 255 at 16 kHz + +#define SWITCH_PIN PA7 // pin 20 +#define SWITCH_PCINT PCINT7 // pin 20 pin change interrupt +#define SWITCH_PCIE PCIE0 // PCIE0 is for PCINT[7:0] +#define SWITCH_PCMSK PCMSK0 // PCMSK0 is for PCINT[7:0] +#define SWITCH_PORT PINA // PINA or PINB or PINC + +#define PWM1_PIN PB3 // pin 16, Opamp reference +#define PWM1_LVL OCR1A // OCR1A is the output compare register for PB3 + +#define LED_ENABLE_PIN PB0 // pin 19, Opamp power +//#define PWM2_PIN PB0 // pin 19, Opamp power +// FIXME: +//#define PWM2_LVL OCR1B // OCR1B is the output compare register for PB1 + + +#define ADC_PRSCL 0x06 // clk/64 + +// average drop across diode on this hardware +#ifndef VOLTAGE_FUDGE_FACTOR +#define VOLTAGE_FUDGE_FACTOR 4 // add 0.20V (measured 0.22V) +#endif + +#define TEMP_CHANNEL 0b00001111 + +// this light has aux LEDs under the optic +#define AUXLED_R_PIN PA6 // pin 1 +#define AUXLED_G_PIN PA5 // pin 2 +#define AUXLED_B_PIN PA4 // pin 3 +#define AUXLED_RGB_PORT PORTA // PORTA or PORTB or PORTC +#define AUXLED_RGB_DDR DDRA // DDRA or DDRB or DDRC +#define AUXLED_RGB_PUE PUEA // PUEA or PUEB or PUEC + +// with so many pins, doing this all with #ifdefs gets awkward... +// ... so just hardcode it in each hwdef file instead +inline void hwdef_setup() { + // enable output ports + // Opamp level and Opamp on/off + DDRB = (1 << PWM1_PIN) + | (1 << LED_ENABLE_PIN); + // aux R/G/B + DDRA = (1 << AUXLED_R_PIN) + | (1 << AUXLED_G_PIN) + | (1 << AUXLED_B_PIN) + ; + + // configure PWM + // Setup PWM. F_pwm = F_clkio / 2 / N / TOP, where N = prescale factor, TOP = top of counter + // pre-scale for timer: N = 1 + // WGM1[3:0]: 0,0,1,1: PWM, Phase Correct, 10-bit (DS table 12-5) + // CS1[2:0]: 0,0,1: clk/1 (No prescaling) (DS table 12-6) + // COM1A[1:0]: 1,0: PWM OC1A in the normal direction (DS table 12-4) + // COM1B[1:0]: 0,0: PWM OC1B disabled (DS table 12-4) + TCCR1A = (1<= 4 PWM4_LVL = 0; #endif + // disable the power channel, if relevant + #ifdef LED_ENABLE_PIN + LED_ENABLE_PORT &= ~(1 << LED_ENABLE_PIN); + #endif } else { level --; + // enable the power channel, if relevant + #ifdef LED_ENABLE_PIN + LED_ENABLE_PORT |= (1 << LED_ENABLE_PIN); + #endif + #ifdef USE_TINT_RAMPING // calculate actual PWM levels based on a single-channel ramp // and a global tint value -- cgit v1.2.3 From 319fbbcb6de77d26fd5d3e935dea47cd4c12ed07 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Tue, 30 Jul 2019 20:16:16 -0600 Subject: anduril: allow RGB LEDs to stay on (in voltage mode) while main LEDs are on (also, refactored RGB aux LED code a little; moved color table to ROM) --- spaghetti-monster/anduril/anduril.c | 61 ++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c index 9853878..a82ba4b 100644 --- a/spaghetti-monster/anduril/anduril.c +++ b/spaghetti-monster/anduril/anduril.c @@ -310,6 +310,7 @@ 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); +void rgb_led_voltage_readout(uint8_t bright); /* * 0: R * 1: RG @@ -321,6 +322,15 @@ void rgb_led_update(uint8_t mode, uint8_t arg); * 7: rainbow * 8: voltage */ +const PROGMEM uint8_t rgb_led_colors[] = { + 0b00000001, // 0: red + 0b00000101, // 1: yellow + 0b00000100, // 2: green + 0b00010100, // 3: cyan + 0b00010000, // 4: blue + 0b00010001, // 5: purple + 0b00010101, // 6: white +}; #define RGB_LED_NUM_COLORS 10 #define RGB_LED_NUM_PATTERNS 4 #ifndef RGB_LED_OFF_DEFAULT @@ -2269,36 +2279,28 @@ void rgb_led_update(uint8_t mode, uint8_t arg) { 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 - }; + const uint8_t *colors = rgb_led_colors; uint8_t actual_color = 0; if (color < 7) { // normal color - actual_color = colors[color]; + actual_color = pgm_read_byte(colors + color); } else if (color == 7) { // rainbow if (0 == (arg & 0x03)) { rainbow = (rainbow + 1) % 6; } - actual_color = colors[rainbow]; + actual_color = pgm_read_byte(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]; + if (volts >= 38) actual_color = pgm_read_byte(colors + 4); + else if (volts >= 33) actual_color = pgm_read_byte(colors + 2); + else actual_color = pgm_read_byte(colors + 0); } // ... but during preview, cycle colors quickly else { - actual_color = colors[((arg>>1) % 3) << 1]; + actual_color = pgm_read_byte(colors + (((arg>>1) % 3) << 1)); } } @@ -2322,6 +2324,31 @@ void rgb_led_update(uint8_t mode, uint8_t arg) { break; } } + +void rgb_led_voltage_readout(uint8_t bright) { + uint8_t volts = voltage; + if (volts < 29) { + rgb_led_set(0); + } + else { + uint8_t levels[] = { + 30, 0, + 33, 1, + 35, 2, + 37, 3, + 39, 4, + 40, 5, + 255, 6, + }; + uint8_t i; + for (i = 0; volts > levels[i]; i += 2) { + if (levels[i] >= volts) break; + } + uint8_t color = pgm_read_byte(rgb_led_colors + i); + if (bright) color = color << 1; + rgb_led_set(color); + } +} #endif @@ -2559,6 +2586,10 @@ void loop() { StatePtr state = current_state; + #ifdef USE_AUX_RGB_LEDS_WHILE_RAMPING + rgb_led_voltage_readout(1); + #endif + if (0) {} #ifdef USE_STROBE_STATE -- cgit v1.2.3 From a68560963d9dd7a16982bc67d5b5ef100a51c8a6 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Mon, 5 Aug 2019 21:34:37 -0600 Subject: fixed weird ramp behavior on D1S v2 (by trusting the compiler more) --- spaghetti-monster/fsm-ramping.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h index 7233474..24c19c0 100644 --- a/spaghetti-monster/fsm-ramping.h +++ b/spaghetti-monster/fsm-ramping.h @@ -47,7 +47,10 @@ void gradual_tick(); #define PWM_GET(x,y) pgm_read_byte(x+y) #else #define PWM_DATATYPE uint16_t -#define PWM_GET(x,y) pgm_read_word(x+(2*y)) +// pointer plus 2*y bytes +//#define PWM_GET(x,y) pgm_read_word(x+(2*y)) +// nope, the compiler was already doing the math correctly +#define PWM_GET(x,y) pgm_read_word(x+y) #endif // use UI-defined ramp tables if they exist -- cgit v1.2.3 From 6c3b0a6b5b71f1b587ec290284923a77177d713a Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Mon, 5 Aug 2019 21:35:47 -0600 Subject: fixed voltage measurement on D1S v2 --- hwdef-Emisar_D1Sv2.h | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/hwdef-Emisar_D1Sv2.h b/hwdef-Emisar_D1Sv2.h index 6895e73..e1f8029 100644 --- a/hwdef-Emisar_D1Sv2.h +++ b/hwdef-Emisar_D1Sv2.h @@ -58,11 +58,29 @@ //#define PWM2_LVL OCR1B // OCR1B is the output compare register for PB1 +#define USE_VOLTAGE_DIVIDER // use a dedicated pin, not VCC, because VCC input is flattened +#define VOLTAGE_PIN PA3 // Pin 4 / PA3 / ADC0 +#define VOLTAGE_ADC_DIDR ADC0D // digital input disable pin for PA3 +// DS tables 19-3, 19-4 +// Bit 7 6 5 4 3 2 1 0 +// REFS1 REFS0 REFEN ADC0EN MUX3 MUX2 MUX1 MUX0 +// MUX[3:0] = 0, 0, 0, 0 for ADC0 / PA3 +// divided by ... +// REFS[1:0] = 1, 0 for internal 1.1V reference +// other bits reserved +#define ADMUX_VOLTAGE_DIVIDER 0b10000000 #define ADC_PRSCL 0x06 // clk/64 -// average drop across diode on this hardware -#ifndef VOLTAGE_FUDGE_FACTOR -#define VOLTAGE_FUDGE_FACTOR 4 // add 0.20V (measured 0.22V) +// Raw ADC readings at 4.4V and 2.2V +// calibrate the voltage readout here +// estimated / calculated values are: +// (voltage - D1) * (R2/(R2+R1) * 256 / 1.1) +// D1, R1, R2 = 0, 330, 100 +#ifndef ADC_44 +#define ADC_44 235 +#endif +#ifndef ADC_22 +#define ADC_22 116 #endif #define TEMP_CHANNEL 0b00001111 -- cgit v1.2.3 From d8841fd80ae1366b9d9f31ca0bd1971b405ef327 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Mon, 5 Aug 2019 21:37:48 -0600 Subject: fixed party strobe on D1S v2, set better default aux LED modes, enabled aux LEDs in blinky modes, fixed user feedback when changing aux LED mode, refactored voltage-to-auxled-color code --- spaghetti-monster/anduril/anduril.c | 70 +++++++++++++++++----------- spaghetti-monster/anduril/cfg-emisar-d1sv2.h | 8 +++- 2 files changed, 49 insertions(+), 29 deletions(-) diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c index a82ba4b..8625946 100644 --- a/spaghetti-monster/anduril/anduril.c +++ b/spaghetti-monster/anduril/anduril.c @@ -309,6 +309,7 @@ void blip(); void indicator_blink(uint8_t arg); #endif #if defined(USE_AUX_RGB_LEDS) && defined(TICK_DURING_STANDBY) +uint8_t setting_rgb_mode_now = 0; void rgb_led_update(uint8_t mode, uint8_t arg); void rgb_led_voltage_readout(uint8_t bright); /* @@ -674,6 +675,7 @@ uint8_t off_state(Event event, uint16_t arg) { } // 7 clicks (hold last): change RGB aux LED color else if (event == EV_click7_hold) { + setting_rgb_mode_now = 1; if (0 == (arg & 0x3f)) { uint8_t mode = (rgb_led_off_mode & 0x0f) + 1; mode = mode % RGB_LED_NUM_COLORS; @@ -684,6 +686,7 @@ uint8_t off_state(Event event, uint16_t arg) { return MISCHIEF_MANAGED; } else if (event == EV_click7_hold_release) { + setting_rgb_mode_now = 0; save_config(); return MISCHIEF_MANAGED; } @@ -1245,8 +1248,12 @@ inline void party_tactical_strobe_mode_iter(uint8_t st) { if (0) {} // placeholde0 #ifdef USE_PARTY_STROBE_MODE else if (st == party_strobe_e) { // party strobe + #ifdef PARTY_STROBE_ONTIME + nice_delay_ms(PARTY_STROBE_ONTIME); + #else if (del < 42) delay_zero(); else nice_delay_ms(1); + #endif } #endif #ifdef USE_TACTICAL_STROBE_MODE @@ -1738,6 +1745,7 @@ uint8_t lockout_state(Event event, uint16_t arg) { } // click, click, hold: change RGB aux LED color else if (event == EV_click3_hold) { + setting_rgb_mode_now = 1; if (0 == (arg & 0x3f)) { uint8_t mode = (rgb_led_lockout_mode & 0x0f) + 1; mode = mode % RGB_LED_NUM_COLORS; @@ -1749,6 +1757,7 @@ uint8_t lockout_state(Event event, uint16_t arg) { } // click, click, hold, release: save new color else if (event == EV_click3_hold_release) { + setting_rgb_mode_now = 0; save_config(); return MISCHIEF_MANAGED; } @@ -2260,6 +2269,27 @@ void indicator_blink(uint8_t arg) { #endif #if defined(USE_AUX_RGB_LEDS) && defined(TICK_DURING_STANDBY) +uint8_t voltage_to_rgb() { + uint8_t levels[] = { + // voltage, color + 0, 0, // 0, R + 33, 1, // 1, R+G + 35, 2, // 2, G + // 0, 3, // 3, G+B // skip; looks too similar to R+G+B + 38, 4, // 4, B + 40, 5, // 5, R + B + 42, 6, // 6, R+G+B + 255, 6, // 7, R+G+B + }; + uint8_t volts = voltage; + if (volts < 29) return 0; + + uint8_t i; + for (i = 0; volts >= levels[i]; i += 2) {} + uint8_t color_num = levels[(i - 2) + 1]; + return pgm_read_byte(rgb_led_colors + color_num); +} + // do fancy stuff with the RGB aux LEDs // mode: 0bPPPPCCCC where PPPP is the pattern and CCCC is the color // arg: time slice number @@ -2285,7 +2315,9 @@ void rgb_led_update(uint8_t mode, uint8_t arg) { actual_color = pgm_read_byte(colors + color); } else if (color == 7) { // rainbow - if (0 == (arg & 0x03)) { + uint8_t speed = 0x03; // awake speed + if (go_to_standby) speed = 0x0f; // asleep speed + if (0 == (arg & speed)) { rainbow = (rainbow + 1) % 6; } actual_color = pgm_read_byte(colors + rainbow); @@ -2293,10 +2325,11 @@ void rgb_led_update(uint8_t mode, uint8_t arg) { else { // voltage // show actual voltage while asleep... if (go_to_standby) { + actual_color = voltage_to_rgb(); // choose a color based on battery voltage - if (volts >= 38) actual_color = pgm_read_byte(colors + 4); - else if (volts >= 33) actual_color = pgm_read_byte(colors + 2); - else actual_color = pgm_read_byte(colors + 0); + //if (volts >= 38) actual_color = pgm_read_byte(colors + 4); + //else if (volts >= 33) actual_color = pgm_read_byte(colors + 2); + //else actual_color = pgm_read_byte(colors + 0); } // ... but during preview, cycle colors quickly else { @@ -2326,28 +2359,9 @@ void rgb_led_update(uint8_t mode, uint8_t arg) { } void rgb_led_voltage_readout(uint8_t bright) { - uint8_t volts = voltage; - if (volts < 29) { - rgb_led_set(0); - } - else { - uint8_t levels[] = { - 30, 0, - 33, 1, - 35, 2, - 37, 3, - 39, 4, - 40, 5, - 255, 6, - }; - uint8_t i; - for (i = 0; volts > levels[i]; i += 2) { - if (levels[i] >= volts) break; - } - uint8_t color = pgm_read_byte(rgb_led_colors + i); - if (bright) color = color << 1; - rgb_led_set(color); - } + uint8_t color = voltage_to_rgb(); + if (bright) color = color << 1; + rgb_led_set(color); } #endif @@ -2586,8 +2600,8 @@ void loop() { StatePtr state = current_state; - #ifdef USE_AUX_RGB_LEDS_WHILE_RAMPING - rgb_led_voltage_readout(1); + #ifdef USE_AUX_RGB_LEDS_WHILE_ON + if (! setting_rgb_mode_now) rgb_led_voltage_readout(1); #endif if (0) {} diff --git a/spaghetti-monster/anduril/cfg-emisar-d1sv2.h b/spaghetti-monster/anduril/cfg-emisar-d1sv2.h index 45424b3..d53d938 100644 --- a/spaghetti-monster/anduril/cfg-emisar-d1sv2.h +++ b/spaghetti-monster/anduril/cfg-emisar-d1sv2.h @@ -4,7 +4,10 @@ // this light has three aux LED channels: R, G, B #define USE_AUX_RGB_LEDS -#define USE_AUX_RGB_LEDS_WHILE_RAMPING +#define USE_AUX_RGB_LEDS_WHILE_ON +#define USE_INDICATOR_LED_WHILE_RAMPING +#define RGB_LED_OFF_DEFAULT 0x18 // low, voltage +#define RGB_LED_LOCKOUT_DEFAULT 0x37 // blinking, rainbow // enable blinking aux LEDs #define TICK_DURING_STANDBY @@ -48,4 +51,7 @@ // easier access to thermal config mode, for Emisar #define USE_TENCLICK_THERMAL_CONFIG +// slow down party strobe; this driver can't pulse for 1ms or less +#define PARTY_STROBE_ONTIME 2 + #define THERM_CAL_OFFSET 5 -- cgit v1.2.3 From 2813cc0130eb3bcc9d0dc1fca5135ee6720764c5 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Tue, 6 Aug 2019 16:52:11 -0600 Subject: turn off button LED when muggle mode turns off the main LED (to reduce power use in standby) --- spaghetti-monster/anduril/anduril.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c index 8625946..f8492fc 100644 --- a/spaghetti-monster/anduril/anduril.c +++ b/spaghetti-monster/anduril/anduril.c @@ -1941,6 +1941,9 @@ uint8_t muggle_state(Event event, uint16_t arg) { // turn off, but don't go to the main "off" state if (muggle_off_mode) { if (arg > TICKS_PER_SECOND*1) { // sleep after 1 second + #ifdef USE_AUX_RGB_LEDS_WHILE_ON + rgb_led_set(0); + #endif go_to_standby = 1; // sleep while light is off } } -- cgit v1.2.3 From 8084f6083ed387b6eb4246758778e99deb781ac9 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Tue, 6 Aug 2019 16:52:58 -0600 Subject: measured and adjusted D1S v2 ramp parameters --- spaghetti-monster/anduril/cfg-emisar-d1sv2.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/spaghetti-monster/anduril/cfg-emisar-d1sv2.h b/spaghetti-monster/anduril/cfg-emisar-d1sv2.h index d53d938..33b240d 100644 --- a/spaghetti-monster/anduril/cfg-emisar-d1sv2.h +++ b/spaghetti-monster/anduril/cfg-emisar-d1sv2.h @@ -18,7 +18,7 @@ // (with max_pwm set to 1023) #define RAMP_LENGTH 150 #define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,6,6,7,8,9,10,11,12,13,14,15,16,17,18,20,21,23,24,26,27,29,31,32,34,36,38,40,43,45,47,49,52,54,57,60,62,65,68,71,74,77,81,84,87,91,95,98,102,106,110,114,118,122,127,131,136,141,145,150,155,160,166,171,176,182,188,193,199,205,211,218,224,231,237,244,251,258,265,272,280,287,295,303,310,319,327,335,344,352,361,370,379,388,397,407,416,426,436,446,457,467,477,488,499,510,521,533,544,556,568,580,592,604,617,629,642,655,668,682,695,709,723,737,751,766,781,795,810,826,841,857,872,888,904,921,937,954,971,988,1005,1023 -#define MAX_1x7135 65 +#define MAX_1x7135 50 // the entire ramp is regulated; don't blink halfway up #ifdef BLINK_AT_RAMP_MIDDLE @@ -33,10 +33,14 @@ #define RAMP_SMOOTH_FLOOR 1 #define RAMP_SMOOTH_CEIL 130 -#define RAMP_DISCRETE_FLOOR 20 +// 10, 30, [50], 70, 90, 110, 130 +#define RAMP_DISCRETE_FLOOR 10 #define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL #define RAMP_DISCRETE_STEPS 7 +#define MUGGLE_FLOOR RAMP_DISCRETE_FLOOR +#define MUGGLE_CEILING 70 + // 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 -- cgit v1.2.3 From 7d09466da0552c17b9968fa92d8ede534abfbbb6 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Tue, 6 Aug 2019 20:17:09 -0600 Subject: un-hardcoded 255 as the highest PWM level, and used a "PWM_TOP" value instead (should make gradual adjustments work better on devices with more than 8 bits of PWM resolution) --- hwdef-Emisar_D1Sv2.h | 1 + spaghetti-monster/fsm-ramping.c | 4 ++-- spaghetti-monster/fsm-ramping.h | 3 +++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/hwdef-Emisar_D1Sv2.h b/hwdef-Emisar_D1Sv2.h index e1f8029..5912ea8 100644 --- a/hwdef-Emisar_D1Sv2.h +++ b/hwdef-Emisar_D1Sv2.h @@ -41,6 +41,7 @@ #define PWM_CHANNELS 1 #define PWM_BITS 10 // 0 to 1023 at 4 kHz, not 0 to 255 at 16 kHz +#define PWM_TOP 1023 #define SWITCH_PIN PA7 // pin 20 #define SWITCH_PCINT PCINT7 // pin 20 pin change interrupt diff --git a/spaghetti-monster/fsm-ramping.c b/spaghetti-monster/fsm-ramping.c index 52a7246..7bee07e 100644 --- a/spaghetti-monster/fsm-ramping.c +++ b/spaghetti-monster/fsm-ramping.c @@ -146,13 +146,13 @@ void gradual_tick() { gt --; // convert 1-based number to 0-based - uint8_t target; + PWM_DATATYPE target; #if PWM_CHANNELS >= 1 target = PWM_GET(pwm1_levels, gt); if ((gt < actual_level) // special case for FET-only turbo && (PWM1_LVL == 0) // (bypass adjustment period for first step) - && (target == 255)) PWM1_LVL = 255; + && (target == PWM_TOP)) PWM1_LVL = PWM_TOP; else if (PWM1_LVL < target) PWM1_LVL ++; else if (PWM1_LVL > target) PWM1_LVL --; #endif diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h index 24c19c0..c650e21 100644 --- a/spaghetti-monster/fsm-ramping.h +++ b/spaghetti-monster/fsm-ramping.h @@ -41,12 +41,15 @@ void gradual_tick(); // auto-detect the data type for PWM tables #ifndef PWM_BITS #define PWM_BITS 8 +#define PWM_TOP 255 #endif #if PWM_BITS <= 8 #define PWM_DATATYPE uint8_t +#define PWM_TOP 255 #define PWM_GET(x,y) pgm_read_byte(x+y) #else #define PWM_DATATYPE uint16_t +#define PWM_TOP 1023 // 10 bits by default // pointer plus 2*y bytes //#define PWM_GET(x,y) pgm_read_word(x+(2*y)) // nope, the compiler was already doing the math correctly -- cgit v1.2.3 From 0df827391ced9bb0b7114248c78b696de4676b25 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Sat, 28 Sep 2019 23:14:16 -0600 Subject: remapped D1S V2 pins to match new driver (and changed a bit about how ADC / DIDR definitions work, since this now uses DIDR1 instead of DIDR0) --- hwdef-BLF_GT.h | 4 +++- hwdef-Emisar_D1Sv2.h | 32 ++++++++++++++++---------------- hwdef-Mateminco_MF01S.h | 4 +++- spaghetti-monster/fsm-adc.c | 4 ++-- tk-attiny.h | 4 ++++ 5 files changed, 28 insertions(+), 20 deletions(-) diff --git a/hwdef-BLF_GT.h b/hwdef-BLF_GT.h index 01dbdbd..dd8d80a 100644 --- a/hwdef-BLF_GT.h +++ b/hwdef-BLF_GT.h @@ -34,7 +34,9 @@ #ifndef VOLTAGE_PIN #define VOLTAGE_PIN PB2 // pin 7, voltage ADC #define VOLTAGE_CHANNEL 0x01 // MUX 01 corresponds with PB2 -#define VOLTAGE_ADC_DIDR ADC1D // Digital input disable bit corresponding with PB2 +#define VOLTAGE_ADC ADC1D // Digital input disable bit corresponding with PB2 +// inherited from tk-attiny.h +//#define VOLTAGE_ADC_DIDR DIDR0 // DIDR for ADC1 // 1.1V reference, left-adjust, ADC1/PB2 //#define ADMUX_VOLTAGE_DIVIDER ((1 << V_REF) | (1 << ADLAR) | VOLTAGE_CHANNEL) // 1.1V reference, no left-adjust, ADC1/PB2 diff --git a/hwdef-Emisar_D1Sv2.h b/hwdef-Emisar_D1Sv2.h index 5912ea8..856643b 100644 --- a/hwdef-Emisar_D1Sv2.h +++ b/hwdef-Emisar_D1Sv2.h @@ -4,11 +4,11 @@ /* Emisar D1Sv2 driver layout (attiny1634) * * Pin / Name / Function - * 1 PA6 red aux LED (PWM1B) - * 2 PA5 green aux LED (PWM0B) - * 3 PA4 blue aux LED - * 4 PA3 battery voltage (ADC0) - * 5 PA2 (none) + * 1 PA6 (none) (PWM1B) (reserved for DD drivers) + * 2 PA5 R: red aux LED (PWM0B) + * 3 PA4 G: green aux LED + * 4 PA3 B: blue aux LED + * 5 PA2 (none) (reserved for L: button LED (on some models)) * 6 PA1 (none) * 7 PA0 (none) * 8 GND GND @@ -21,7 +21,7 @@ * 15 PC0 (none) PWM0A * 16 PB3 main LED PWM (PWM1A) * 17 PB2 MISO - * 18 PB1 MOSI + * 18 PB1 MOSI / battery voltage (ADC6) * 19 PB0 Opamp power * 20 PA7 e-switch (PCINT7) * ADC12 thermal sensor @@ -54,22 +54,22 @@ #define LED_ENABLE_PIN PB0 // pin 19, Opamp power #define LED_ENABLE_PORT PORTB // control port for PB0 -//#define PWM2_PIN PB0 // pin 19, Opamp power -// FIXME: -//#define PWM2_LVL OCR1B // OCR1B is the output compare register for PB1 #define USE_VOLTAGE_DIVIDER // use a dedicated pin, not VCC, because VCC input is flattened -#define VOLTAGE_PIN PA3 // Pin 4 / PA3 / ADC0 -#define VOLTAGE_ADC_DIDR ADC0D // digital input disable pin for PA3 +#define VOLTAGE_PIN PB1 // Pin 18 / PB1 / ADC6 +// pin to ADC mappings are in DS table 19-4 +#define VOLTAGE_ADC ADC6D // digital input disable pin for PB1 +// DIDR0/DIDR1 mappings are in DS section 19.13.5, 19.13.6 +#define VOLTAGE_ADC_DIDR DIDR1 // DIDR channel for ADC6D // DS tables 19-3, 19-4 // Bit 7 6 5 4 3 2 1 0 // REFS1 REFS0 REFEN ADC0EN MUX3 MUX2 MUX1 MUX0 -// MUX[3:0] = 0, 0, 0, 0 for ADC0 / PA3 +// MUX[3:0] = 0, 1, 1, 0 for ADC6 / PB1 // divided by ... // REFS[1:0] = 1, 0 for internal 1.1V reference // other bits reserved -#define ADMUX_VOLTAGE_DIVIDER 0b10000000 +#define ADMUX_VOLTAGE_DIVIDER 0b10000110 #define ADC_PRSCL 0x06 // clk/64 // Raw ADC readings at 4.4V and 2.2V @@ -87,9 +87,9 @@ #define TEMP_CHANNEL 0b00001111 // this light has aux LEDs under the optic -#define AUXLED_R_PIN PA6 // pin 1 -#define AUXLED_G_PIN PA5 // pin 2 -#define AUXLED_B_PIN PA4 // pin 3 +#define AUXLED_R_PIN PA5 // pin 2 +#define AUXLED_G_PIN PA4 // pin 3 +#define AUXLED_B_PIN PA3 // pin 4 #define AUXLED_RGB_PORT PORTA // PORTA or PORTB or PORTC #define AUXLED_RGB_DDR DDRA // DDRA or DDRB or DDRC #define AUXLED_RGB_PUE PUEA // PUEA or PUEB or PUEC diff --git a/hwdef-Mateminco_MF01S.h b/hwdef-Mateminco_MF01S.h index ab1c5bf..ad6194c 100644 --- a/hwdef-Mateminco_MF01S.h +++ b/hwdef-Mateminco_MF01S.h @@ -34,7 +34,9 @@ #ifndef VOLTAGE_PIN #define VOLTAGE_PIN PB2 // pin 7, voltage ADC #define VOLTAGE_CHANNEL 0x01 // MUX 01 corresponds with PB2 -#define VOLTAGE_ADC_DIDR ADC1D // Digital input disable bit corresponding with PB2 +#define VOLTAGE_ADC ADC1D // Digital input disable bit corresponding with PB2 +// inherited from tk-attiny.h +//#define VOLTAGE_ADC_DIDR DIDR0 // DIDR for ADC1 // 1.1V reference, left-adjust, ADC1/PB2 //#define ADMUX_VOLTAGE_DIVIDER ((1 << V_REF) | (1 << ADLAR) | VOLTAGE_CHANNEL) // 1.1V reference, no left-adjust, ADC1/PB2 diff --git a/spaghetti-monster/fsm-adc.c b/spaghetti-monster/fsm-adc.c index 6832e32..a5507a9 100644 --- a/spaghetti-monster/fsm-adc.c +++ b/spaghetti-monster/fsm-adc.c @@ -69,10 +69,10 @@ inline void ADC_on() set_admux_voltage(); #ifdef USE_VOLTAGE_DIVIDER // disable digital input on divider pin to reduce power consumption - DIDR0 |= (1 << VOLTAGE_ADC_DIDR); + VOLTAGE_ADC_DIDR |= (1 << VOLTAGE_ADC); #else // disable digital input on VCC pin to reduce power consumption - //DIDR0 |= (1 << ADC_DIDR); // FIXME: unsure how to handle for VCC pin + //VOLTAGE_ADC_DIDR |= (1 << VOLTAGE_ADC); // FIXME: unsure how to handle for VCC pin #endif #if (ATTINY == 1634) ACSRA |= (1 << ACD); // turn off analog comparator to save power diff --git a/tk-attiny.h b/tk-attiny.h index 947a87c..4d0c7e0 100644 --- a/tk-attiny.h +++ b/tk-attiny.h @@ -34,6 +34,7 @@ #define ADMUX_VCC 0b00001100 #define DELAY_ZERO_TIME 252 #define SWITCH_PORT PINB // PINA or PINB or PINC + #define VOLTAGE_ADC_DIDR DIDR0 // this MCU only has one DIDR #elif (ATTINY == 25) // TODO: Use 6.4 MHz instead of 8 MHz? #define F_CPU 8000000UL @@ -44,6 +45,7 @@ #define ADMUX_THERM 0b10001111 #define DELAY_ZERO_TIME 1020 #define SWITCH_PORT PINB // PINA or PINB or PINC + #define VOLTAGE_ADC_DIDR DIDR0 // this MCU only has one DIDR #elif (ATTINY == 85) // TODO: Use 6.4 MHz instead of 8 MHz? #define F_CPU 8000000UL @@ -56,6 +58,7 @@ #define ADMUX_THERM 0b10001111 #define DELAY_ZERO_TIME 1020 #define SWITCH_PORT PINB // PINA or PINB or PINC + #define VOLTAGE_ADC_DIDR DIDR0 // this MCU only has one DIDR #elif (ATTINY == 1634) #define F_CPU 8000000UL #define V_REF REFS1 @@ -66,6 +69,7 @@ #define ADMUX_THERM 0b10001110 #define DELAY_ZERO_TIME 1020 //#define SWITCH_PORT PINA // set this in hwdef + //#define VOLTAGE_ADC_DIDR DIDR0 // set this in hwdef #else #error Hey, you need to define ATTINY. #endif -- cgit v1.2.3 From 02ba399f83371d3c8dba866fefb2519767d809b7 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Wed, 20 Nov 2019 15:34:48 -0700 Subject: made the button LED turn off in momentary mode, instead of staying on forever --- spaghetti-monster/anduril/anduril.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c index a86af16..5c5a6ee 100644 --- a/spaghetti-monster/anduril/anduril.c +++ b/spaghetti-monster/anduril/anduril.c @@ -1863,9 +1863,14 @@ uint8_t momentary_state(Event event, uint16_t arg) { } } else { - if (arg > TICKS_PER_SECOND*15) { // sleep after 15 seconds + if (arg > TICKS_PER_SECOND*5) { // sleep after 5 seconds go_to_standby = 1; // sleep while light is off - // TODO: lighted button should use lockout config? + // turn off lighted button + #ifdef USE_INDICATOR_LED + indicator_led(0); + #elif defined(USE_AUX_RGB_LEDS) + rgb_led_update(0, 0); + #endif } } return MISCHIEF_MANAGED; -- cgit v1.2.3 From 1ab6cd428c3b43a80ffac01f29ca0c27a438e3b1 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Mon, 25 Nov 2019 18:41:24 -0700 Subject: calibrated Noctigon K1, changed voltage divider calibration values to 10-bit (was 8-bit before) --- hwdef-BLF_GT.h | 4 ++-- hwdef-Emisar_D1Sv2.h | 6 ++++-- hwdef-Mateminco_MF01S.h | 4 ++-- spaghetti-monster/fsm-adc.c | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/hwdef-BLF_GT.h b/hwdef-BLF_GT.h index dd8d80a..8ad99c7 100644 --- a/hwdef-BLF_GT.h +++ b/hwdef-BLF_GT.h @@ -46,10 +46,10 @@ // Raw ADC readings at 4.4V and 2.2V (in-between, we assume values form a straight line) #ifndef ADC_44 -#define ADC_44 184 +#define ADC_44 (184*4) #endif #ifndef ADC_22 -#define ADC_22 92 +#define ADC_22 (92*4) #endif #define TEMP_CHANNEL 0b00001111 diff --git a/hwdef-Emisar_D1Sv2.h b/hwdef-Emisar_D1Sv2.h index 856643b..d76d701 100644 --- a/hwdef-Emisar_D1Sv2.h +++ b/hwdef-Emisar_D1Sv2.h @@ -78,10 +78,12 @@ // (voltage - D1) * (R2/(R2+R1) * 256 / 1.1) // D1, R1, R2 = 0, 330, 100 #ifndef ADC_44 -#define ADC_44 235 +//#define ADC_44 981 // raw value at 4.40V +#define ADC_44 967 // manually tweaked so 4.16V will blink out 4.2 #endif #ifndef ADC_22 -#define ADC_22 116 +//#define ADC_22 489 // raw value at 2.20V +#define ADC_22 482 // manually tweaked so 4.16V will blink out 4.2 #endif #define TEMP_CHANNEL 0b00001111 diff --git a/hwdef-Mateminco_MF01S.h b/hwdef-Mateminco_MF01S.h index ad6194c..03508ab 100644 --- a/hwdef-Mateminco_MF01S.h +++ b/hwdef-Mateminco_MF01S.h @@ -46,10 +46,10 @@ // Raw ADC readings at 4.4V and 2.2V (in-between, we assume values form a straight line) #ifndef ADC_44 -#define ADC_44 234 +#define ADC_44 (234*4) #endif #ifndef ADC_22 -#define ADC_22 117 +#define ADC_22 (117*4) #endif #define TEMP_CHANNEL 0b00001111 diff --git a/spaghetti-monster/fsm-adc.c b/spaghetti-monster/fsm-adc.c index 9e52ab6..b8b00de 100644 --- a/spaghetti-monster/fsm-adc.c +++ b/spaghetti-monster/fsm-adc.c @@ -101,7 +101,7 @@ inline void ADC_off() { #ifdef USE_VOLTAGE_DIVIDER static inline uint8_t calc_voltage_divider(uint16_t value) { // use 9.7 fixed-point to get sufficient precision - uint16_t adc_per_volt = ((ADC_44<<7) - (ADC_22<<7)) / (44-22); + uint16_t adc_per_volt = ((ADC_44<<5) - (ADC_22<<5)) / (44-22); // incoming value is 8.2 fixed-point, so shift it 2 bits less uint8_t result = ((value<<5) / adc_per_volt) + VOLTAGE_FUDGE_FACTOR; return result; -- cgit v1.2.3 From 87022ebce2be6da2bffe467d4489c528fc607ea4 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Mon, 25 Nov 2019 18:42:37 -0700 Subject: increased Noctigon K1's default temperature limit to 55 C --- spaghetti-monster/anduril/cfg-emisar-d1sv2.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spaghetti-monster/anduril/cfg-emisar-d1sv2.h b/spaghetti-monster/anduril/cfg-emisar-d1sv2.h index 19610dc..2bf6ccb 100644 --- a/spaghetti-monster/anduril/cfg-emisar-d1sv2.h +++ b/spaghetti-monster/anduril/cfg-emisar-d1sv2.h @@ -2,6 +2,10 @@ #include "hwdef-Emisar_D1Sv2.h" // ATTINY: 1634 +// this light can safely run a bit hotter than most +#undef DEFAULT_THERM_CEIL +#define DEFAULT_THERM_CEIL 55 + // this light has three aux LED channels: R, G, B #define USE_AUX_RGB_LEDS #define USE_AUX_RGB_LEDS_WHILE_ON -- cgit v1.2.3 From 87ab9d1162174c1844b1d60c6444391ebf9afddf Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Mon, 25 Nov 2019 18:56:37 -0700 Subject: renamed Emisar D1S V2 -> Noctigon K1 --- hwdef-Emisar_D1Sv2.h | 135 -------------------------- hwdef-Noctigon_K1.h | 136 +++++++++++++++++++++++++++ spaghetti-monster/anduril/cfg-emisar-d1sv2.h | 70 -------------- spaghetti-monster/anduril/cfg-noctigon-k1.h | 71 ++++++++++++++ 4 files changed, 207 insertions(+), 205 deletions(-) delete mode 100644 hwdef-Emisar_D1Sv2.h create mode 100644 hwdef-Noctigon_K1.h delete mode 100644 spaghetti-monster/anduril/cfg-emisar-d1sv2.h create mode 100644 spaghetti-monster/anduril/cfg-noctigon-k1.h diff --git a/hwdef-Emisar_D1Sv2.h b/hwdef-Emisar_D1Sv2.h deleted file mode 100644 index d76d701..0000000 --- a/hwdef-Emisar_D1Sv2.h +++ /dev/null @@ -1,135 +0,0 @@ -#ifndef HWDEF_EMISAR_D1SV2_H -#define HWDEF_EMISAR_D1SV2_H - -/* Emisar D1Sv2 driver layout (attiny1634) - * - * Pin / Name / Function - * 1 PA6 (none) (PWM1B) (reserved for DD drivers) - * 2 PA5 R: red aux LED (PWM0B) - * 3 PA4 G: green aux LED - * 4 PA3 B: blue aux LED - * 5 PA2 (none) (reserved for L: button LED (on some models)) - * 6 PA1 (none) - * 7 PA0 (none) - * 8 GND GND - * 9 VCC VCC - * 10 PC5 (none) - * 11 PC4 (none) - * 12 PC3 RESET - * 13 PC2 (none) - * 14 PC1 SCK - * 15 PC0 (none) PWM0A - * 16 PB3 main LED PWM (PWM1A) - * 17 PB2 MISO - * 18 PB1 MOSI / battery voltage (ADC6) - * 19 PB0 Opamp power - * 20 PA7 e-switch (PCINT7) - * ADC12 thermal sensor - * - * Main LED power uses one pin to turn the Opamp on/off, - * and one pin to control Opamp power level. - * All brightness control uses the power level pin, with 4 kHz 10-bit PWM. - * The on/off pin is only used to turn the main LED on and off, - * not to change brightness. - */ - -#ifdef ATTINY -#undef ATTINY -#endif -#define ATTINY 1634 -#include - -#define PWM_CHANNELS 1 -#define PWM_BITS 10 // 0 to 1023 at 4 kHz, not 0 to 255 at 16 kHz -#define PWM_TOP 1023 - -#define SWITCH_PIN PA7 // pin 20 -#define SWITCH_PCINT PCINT7 // pin 20 pin change interrupt -#define SWITCH_PCIE PCIE0 // PCIE0 is for PCINT[7:0] -#define SWITCH_PCMSK PCMSK0 // PCMSK0 is for PCINT[7:0] -#define SWITCH_PORT PINA // PINA or PINB or PINC - -#define PWM1_PIN PB3 // pin 16, Opamp reference -#define PWM1_LVL OCR1A // OCR1A is the output compare register for PB3 - -#define LED_ENABLE_PIN PB0 // pin 19, Opamp power -#define LED_ENABLE_PORT PORTB // control port for PB0 - - -#define USE_VOLTAGE_DIVIDER // use a dedicated pin, not VCC, because VCC input is flattened -#define VOLTAGE_PIN PB1 // Pin 18 / PB1 / ADC6 -// pin to ADC mappings are in DS table 19-4 -#define VOLTAGE_ADC ADC6D // digital input disable pin for PB1 -// DIDR0/DIDR1 mappings are in DS section 19.13.5, 19.13.6 -#define VOLTAGE_ADC_DIDR DIDR1 // DIDR channel for ADC6D -// DS tables 19-3, 19-4 -// Bit 7 6 5 4 3 2 1 0 -// REFS1 REFS0 REFEN ADC0EN MUX3 MUX2 MUX1 MUX0 -// MUX[3:0] = 0, 1, 1, 0 for ADC6 / PB1 -// divided by ... -// REFS[1:0] = 1, 0 for internal 1.1V reference -// other bits reserved -#define ADMUX_VOLTAGE_DIVIDER 0b10000110 -#define ADC_PRSCL 0x06 // clk/64 - -// Raw ADC readings at 4.4V and 2.2V -// calibrate the voltage readout here -// estimated / calculated values are: -// (voltage - D1) * (R2/(R2+R1) * 256 / 1.1) -// D1, R1, R2 = 0, 330, 100 -#ifndef ADC_44 -//#define ADC_44 981 // raw value at 4.40V -#define ADC_44 967 // manually tweaked so 4.16V will blink out 4.2 -#endif -#ifndef ADC_22 -//#define ADC_22 489 // raw value at 2.20V -#define ADC_22 482 // manually tweaked so 4.16V will blink out 4.2 -#endif - -#define TEMP_CHANNEL 0b00001111 - -// this light has aux LEDs under the optic -#define AUXLED_R_PIN PA5 // pin 2 -#define AUXLED_G_PIN PA4 // pin 3 -#define AUXLED_B_PIN PA3 // pin 4 -#define AUXLED_RGB_PORT PORTA // PORTA or PORTB or PORTC -#define AUXLED_RGB_DDR DDRA // DDRA or DDRB or DDRC -#define AUXLED_RGB_PUE PUEA // PUEA or PUEB or PUEC - -// with so many pins, doing this all with #ifdefs gets awkward... -// ... so just hardcode it in each hwdef file instead -inline void hwdef_setup() { - // enable output ports - // Opamp level and Opamp on/off - DDRB = (1 << PWM1_PIN) - | (1 << LED_ENABLE_PIN); - // aux R/G/B - DDRA = (1 << AUXLED_R_PIN) - | (1 << AUXLED_G_PIN) - | (1 << AUXLED_B_PIN) - ; - - // configure PWM - // Setup PWM. F_pwm = F_clkio / 2 / N / TOP, where N = prescale factor, TOP = top of counter - // pre-scale for timer: N = 1 - // WGM1[3:0]: 0,0,1,1: PWM, Phase Correct, 10-bit (DS table 12-5) - // CS1[2:0]: 0,0,1: clk/1 (No prescaling) (DS table 12-6) - // COM1A[1:0]: 1,0: PWM OC1A in the normal direction (DS table 12-4) - // COM1B[1:0]: 0,0: PWM OC1B disabled (DS table 12-4) - TCCR1A = (1< + +#define PWM_CHANNELS 1 +#define PWM_BITS 10 // 0 to 1023 at 4 kHz, not 0 to 255 at 16 kHz +#define PWM_TOP 1023 + +#define SWITCH_PIN PA7 // pin 20 +#define SWITCH_PCINT PCINT7 // pin 20 pin change interrupt +#define SWITCH_PCIE PCIE0 // PCIE0 is for PCINT[7:0] +#define SWITCH_PCMSK PCMSK0 // PCMSK0 is for PCINT[7:0] +#define SWITCH_PORT PINA // PINA or PINB or PINC + +#define PWM1_PIN PB3 // pin 16, Opamp reference +#define PWM1_LVL OCR1A // OCR1A is the output compare register for PB3 + +#define LED_ENABLE_PIN PB0 // pin 19, Opamp power +#define LED_ENABLE_PORT PORTB // control port for PB0 + + +#define USE_VOLTAGE_DIVIDER // use a dedicated pin, not VCC, because VCC input is flattened +#define VOLTAGE_PIN PB1 // Pin 18 / PB1 / ADC6 +// pin to ADC mappings are in DS table 19-4 +#define VOLTAGE_ADC ADC6D // digital input disable pin for PB1 +// DIDR0/DIDR1 mappings are in DS section 19.13.5, 19.13.6 +#define VOLTAGE_ADC_DIDR DIDR1 // DIDR channel for ADC6D +// DS tables 19-3, 19-4 +// Bit 7 6 5 4 3 2 1 0 +// REFS1 REFS0 REFEN ADC0EN MUX3 MUX2 MUX1 MUX0 +// MUX[3:0] = 0, 1, 1, 0 for ADC6 / PB1 +// divided by ... +// REFS[1:0] = 1, 0 for internal 1.1V reference +// other bits reserved +#define ADMUX_VOLTAGE_DIVIDER 0b10000110 +#define ADC_PRSCL 0x06 // clk/64 + +// Raw ADC readings at 4.4V and 2.2V +// calibrate the voltage readout here +// estimated / calculated values are: +// (voltage - D1) * (R2/(R2+R1) * 256 / 1.1) +// D1, R1, R2 = 0, 330, 100 +#ifndef ADC_44 +//#define ADC_44 981 // raw value at 4.40V +#define ADC_44 967 // manually tweaked so 4.16V will blink out 4.2 +#endif +#ifndef ADC_22 +//#define ADC_22 489 // raw value at 2.20V +#define ADC_22 482 // manually tweaked so 4.16V will blink out 4.2 +#endif + +#define TEMP_CHANNEL 0b00001111 + +// this light has aux LEDs under the optic +#define AUXLED_R_PIN PA5 // pin 2 +#define AUXLED_G_PIN PA4 // pin 3 +#define AUXLED_B_PIN PA3 // pin 4 +#define AUXLED_RGB_PORT PORTA // PORTA or PORTB or PORTC +#define AUXLED_RGB_DDR DDRA // DDRA or DDRB or DDRC +#define AUXLED_RGB_PUE PUEA // PUEA or PUEB or PUEC + +// with so many pins, doing this all with #ifdefs gets awkward... +// ... so just hardcode it in each hwdef file instead +inline void hwdef_setup() { + // enable output ports + // Opamp level and Opamp on/off + DDRB = (1 << PWM1_PIN) + | (1 << LED_ENABLE_PIN); + // aux R/G/B + DDRA = (1 << AUXLED_R_PIN) + | (1 << AUXLED_G_PIN) + | (1 << AUXLED_B_PIN) + ; + + // configure PWM + // Setup PWM. F_pwm = F_clkio / 2 / N / TOP, where N = prescale factor, TOP = top of counter + // pre-scale for timer: N = 1 + // WGM1[3:0]: 0,0,1,1: PWM, Phase Correct, 10-bit (DS table 12-5) + // CS1[2:0]: 0,0,1: clk/1 (No prescaling) (DS table 12-6) + // COM1A[1:0]: 1,0: PWM OC1A in the normal direction (DS table 12-4) + // COM1B[1:0]: 0,0: PWM OC1B disabled (DS table 12-4) + TCCR1A = (1<