2
* "Biscotti" firmware (attiny13a version of "Bistro")
3
* This code runs on a single-channel driver with attiny13a MCU.
4
* It is intended specifically for nanjg 105d drivers from Convoy.
6
* Copyright (C) 2015 Selene Scriven
8
* This program is free software: you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation, either version 3 of the License, or
11
* (at your option) any later version.
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program. If not, see <http://www.gnu.org/licenses/>.
27
* GND -|4 5|- PWM (Nx7135)
31
* I use these fuse settings on attiny13
37
* To find out what values to use, flash the driver with battcheck.hex
38
* and hook the light up to each voltage you need a value for. This is
39
* much more reliable than attempting to calculate the values from a
40
* theoretical formula.
42
* Same for off-time capacitor values. Measure, don't guess.
44
// Choose your MCU here, or in the build script
47
// FIXME: make 1-channel vs 2-channel power a single #define option
48
//#define FET_7135_LAYOUT // specify an I/O pin layout
49
#define NANJG_LAYOUT // specify an I/O pin layout
50
// Also, assign I/O pins in this file:
51
#include "tk-attiny.h"
54
* =========================================================================
55
* Settings to modify per driver
58
// FIXME: make 1-channel vs 2-channel power a single #define option
59
//#define FAST 0x23 // fast PWM channel 1 only
60
//#define PHASE 0x21 // phase-correct PWM channel 1 only
61
#define FAST 0xA3 // fast PWM both channels
62
#define PHASE 0xA1 // phase-correct PWM both channels
64
#define VOLTAGE_MON // Comment out to disable LVP
66
//#define OFFTIM3 // Use short/med/long off-time presses
67
// instead of just short/long
69
// ../../bin/level_calc.py 64 1 10 1300 y 3 0.23 140
72
//#define RAMP_7135 3,3,3,3,3,3,4,4,4,4,4,5,5,5,6,6,7,7,8,9,10,11,12,13,15,16,18,21,23,27,30,34,39,44,50,57,65,74,85,97,111,127,145,166,190,217,248,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0
73
//#define RAMP_FET 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,6,11,17,23,30,39,48,59,72,86,103,121,143,168,197,255
75
//#define RAMP_7135 3,5,8,12,17,24,32,41,51,63,75,90,105,121,139,158,178,200,223,247,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,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
76
//#define RAMP_FET 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,4,6,9,12,16,19,22,26,30,33,37,41,45,50,54,59,63,68,73,78,84,89,94,100,106,111,117,123,130,136,142,149,156,162,169,176,184,191,198,206,214,221,255
78
//#define RAMP_7135 3,3,4,5,6,8,10,12,15,19,23,28,33,40,47,55,63,73,84,95,108,122,137,153,171,190,210,232,255,255,255,255,255,255,255,255,255,255,255,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
79
//#define RAMP_FET 6,12,34,108,255
80
// level_calc.py 1 4 7135 9 8 700
81
// level_calc.py 1 3 7135 9 8 700
82
#define RAMP_FET 1,10,42,75,122,133,255
84
//#define RAMP_7135 3,3,3,4,4,5,5,6,7,8,10,11,13,15,18,21,24,28,33,38,44,50,57,66,75,85,96,108,122,137,154,172,192,213,237,255,255,255,255,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
85
//#define RAMP_FET 0,0,0,0,0,0,0,0,0,0,0,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,6,9,13,17,21,25,30,35,41,47,53,60,67,75,83,91,101,111,121,132,144,156,169,183,198,213,255
87
// uncomment to ramp up/down to a mode instead of jumping directly
90
// Enable battery indicator mode?
92
// Choose a battery indicator style
93
#define BATTCHECK_4bars // up to 4 blinks
94
//#define BATTCHECK_8bars // up to 8 blinks
95
//#define BATTCHECK_VpT // Volts + tenths
97
// output to use for blinks on battery check (and other modes)
98
//#define BLINK_BRIGHTNESS RAMP_SIZE/4
99
#define BLINK_BRIGHTNESS 3
100
// ms per normal-speed blink
101
#define BLINK_SPEED 750
103
// Hidden modes are *before* the lowest (moon) mode, and should be specified
104
// in reverse order. So, to go backward from moon to turbo to strobe to
105
// battcheck, use BATTCHECK,STROBE,TURBO .
106
//#define HIDDENMODES BATTCHECK,STROBE,TURBO
108
#define TURBO RAMP_SIZE // Convenience code for turbo mode
109
#define BATTCHECK 254 // Convenience code for battery check mode
110
#define GROUP_SELECT_MODE 253
111
//#define TEMP_CAL_MODE 252
112
// Uncomment to enable tactical strobe mode
113
#define STROBE 251 // Convenience code for strobe mode
114
// Uncomment to unable a 2-level stutter beacon instead of a tactical strobe
115
#define BIKING_STROBE 250 // Convenience code for biking strobe mode
116
// comment out to use minimal version instead (smaller)
117
#define FULL_BIKING_STROBE
118
//#define RAMP 249 // ramp test mode for tweaking ramp shape
119
//#define POLICE_STROBE 248
120
//#define RANDOM_STROBE 247
124
//#define TEMPERATURE_MON
126
// Calibrate voltage and OTC in this file:
127
#include "tk-calibration.h"
130
* =========================================================================
133
// Ignore a spurious warning, we did the cast on purpose
134
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
136
#include <avr/pgmspace.h>
137
//#include <avr/io.h>
138
#include <avr/interrupt.h>
139
#include <avr/eeprom.h>
140
#include <avr/sleep.h>
141
//#include <avr/power.h>
144
#define OWN_DELAY // Don't use stock delay functions.
145
#define USE_DELAY_S // Also use _delay_s(), not just _delay_ms()
146
#include "tk-delay.h"
148
#include "tk-voltage.h"
151
#include "tk-random.h"
158
// Config option variables
160
#define FIRSTBOOT 0b01010101
161
uint8_t firstboot = FIRSTBOOT; // detect initial boot or factory reset
163
uint8_t modegroup = 0; // which mode group (set above in #defines)
164
#define enable_moon 0 // Should we add moon to the set of modes?
165
#define reverse_modes 0 // flip the mode order?
166
uint8_t memory = 0; // mode memory, or not (set via soldered star)
168
uint8_t offtim3 = 1; // enable medium-press?
170
#ifdef TEMPERATURE_MON
171
uint8_t maxtemp = 79; // temperature step-down threshold
173
#define muggle_mode 0 // simple mode designed for muggles
174
// Other state variables
175
uint8_t mode_override = 0; // do we need to enter a special mode?
176
uint8_t mode_idx = 0; // current or last-used mode number
178
// counter for entering config mode
179
// (needs to be remembered while off, but only for up to half a second)
180
uint8_t fast_presses __attribute__ ((section (".noinit")));
182
// total length of current mode group's array
186
// number of regular non-hidden modes in current mode group
188
// number of hidden modes in the current mode group
189
// (hardcoded because both groups have the same hidden modes)
190
//uint8_t hidden_modes = NUM_HIDDEN; // this is never used
193
//PROGMEM const uint8_t hiddenmodes[] = { HIDDENMODES };
194
// default values calculated by group_calc.py
195
// Each group must be 8 values long, but can be cut short with a zero.
196
#define NUM_MODEGROUPS 12 // don't count muggle mode
197
PROGMEM const uint8_t modegroups[] = {
198
1, 2, 3, 5, 7, STROBE, BIKING_STROBE, BATTCHECK,
199
1, 2, 3, 5, 7, 0, 0, 0,
200
7, 5, 3, 2, 1, 0, 0, 0,
201
2, 4, 7, STROBE, BIKING_STROBE, BATTCHECK, SOS, 0,
202
2, 4, 7, 0, 0, 0, 0, 0,
203
7, 4, 2, 0, 0, 0, 0, 0,
204
1, 2, 3, 6, STROBE, BIKING_STROBE, BATTCHECK, SOS,
205
1, 2, 3, 6, 0, 0, 0, 0,
206
6, 3, 2, 1, 0, 0, 0, 0,
207
2, 3, 5, 7, 0, 0, 0, 0,
208
7, 4, STROBE,0,0, 0, 0, 0,
211
uint8_t modes[] = { 0,0,0,0,0,0,0,0, }; // make sure this is long enough...
213
// Modes (gets set when the light starts up based on saved config values)
214
//PROGMEM const uint8_t ramp_7135[] = { RAMP_7135 };
215
PROGMEM const uint8_t ramp_FET[] = { RAMP_FET };
217
void save_mode() { // save the current mode index (with wear leveling)
218
uint8_t oldpos=eepos;
220
eepos = (eepos+1) & ((EEPSIZE/2)-1); // wear leveling, use next cell
223
if (eepos > (EEPSIZE-4)) {
228
eeprom_write_byte((uint8_t *)(eepos), mode_idx); // save current state
229
eeprom_write_byte((uint8_t *)(oldpos), 0xff); // erase old state
232
//#define OPT_firstboot (EEPSIZE-1)
233
#define OPT_modegroup (EEPSIZE-1)
234
#define OPT_memory (EEPSIZE-2)
235
//#define OPT_offtim3 (EEPSIZE-4)
236
//#define OPT_maxtemp (EEPSIZE-5)
237
#define OPT_mode_override (EEPSIZE-3)
238
//#define OPT_moon (EEPSIZE-7)
239
//#define OPT_revmodes (EEPSIZE-8)
240
//#define OPT_muggle (EEPSIZE-9)
241
void save_state() { // central method for writing complete state
244
eeprom_write_byte((uint8_t *)OPT_firstboot, firstboot);
246
eeprom_write_byte((uint8_t *)OPT_modegroup, modegroup);
247
eeprom_write_byte((uint8_t *)OPT_memory, memory);
249
eeprom_write_byte((uint8_t *)OPT_offtim3, offtim3);
251
#ifdef TEMPERATURE_MON
252
eeprom_write_byte((uint8_t *)OPT_maxtemp, maxtemp);
254
eeprom_write_byte((uint8_t *)OPT_mode_override, mode_override);
255
//eeprom_write_byte((uint8_t *)OPT_moon, enable_moon);
256
//eeprom_write_byte((uint8_t *)OPT_revmodes, reverse_modes);
257
//eeprom_write_byte((uint8_t *)OPT_muggle, muggle_mode);
260
inline void reset_state() {
266
void restore_state() {
270
// check if this is the first time we have powered on
271
eep = eeprom_read_byte((uint8_t *)OPT_firstboot);
272
if (eep != FIRSTBOOT) {
273
// not much to do; the defaults should already be set
274
// while defining the variables above
281
// find the mode index data
282
for(eepos=0; eepos<(EEPSIZE-6); eepos++) {
283
eep = eeprom_read_byte((const uint8_t *)eepos);
290
// if no mode_idx was found, assume this is the first boot
296
// load other config values
297
modegroup = eeprom_read_byte((uint8_t *)OPT_modegroup);
298
memory = eeprom_read_byte((uint8_t *)OPT_memory);
300
offtim3 = eeprom_read_byte((uint8_t *)OPT_offtim3);
302
#ifdef TEMPERATURE_MON
303
maxtemp = eeprom_read_byte((uint8_t *)OPT_maxtemp);
305
mode_override = eeprom_read_byte((uint8_t *)OPT_mode_override);
306
//enable_moon = eeprom_read_byte((uint8_t *)OPT_moon);
307
//reverse_modes = eeprom_read_byte((uint8_t *)OPT_revmodes);
308
//muggle_mode = eeprom_read_byte((uint8_t *)OPT_muggle);
310
// unnecessary, save_state handles wrap-around
311
// (and we don't really care about it skipping cell 0 once in a while)
314
if (modegroup >= NUM_MODEGROUPS) reset_state();
317
inline void next_mode() {
319
if (mode_idx >= solid_modes) {
320
// Wrap around, skipping the hidden modes
321
// (note: this also applies when going "forward" from any hidden mode)
322
// FIXME? Allow this to cycle through hidden modes?
328
inline void prev_mode() {
329
// simple mode has no reverse
330
//if (muggle_mode) { return next_mode(); }
332
if (mode_idx == solid_modes) {
333
// If we hit the end of the hidden modes, go back to moon
335
} else if (mode_idx > 0) {
336
// Regular mode: is between 1 and TOTAL_MODES
339
// Otherwise, wrap around (this allows entering hidden modes)
340
mode_idx = mode_cnt - 1;
347
* Determine how many solid and hidden modes we have.
349
* (this matters because we have more than one set of modes to choose
350
* from, so we need to count at runtime)
352
// copy config to local vars to avoid accidentally overwriting them in muggle mode
353
// (also, it seems to reduce overall program size)
354
uint8_t my_modegroup = modegroup;
355
//uint8_t my_enable_moon = enable_moon;
356
//uint8_t my_reverse_modes = reverse_modes;
358
// override config if we're in simple mode
361
my_modegroup = NUM_MODEGROUPS;
363
my_reverse_modes = 0;
368
const uint8_t *src = modegroups + (my_modegroup<<3);
371
// Figure out how many modes are in this group
372
//solid_modes = modegroup + 1; // Assume group N has N modes
373
// No, how about actually counting the modes instead?
374
// (in case anyone changes the mode groups above so they don't form a triangle)
376
(solid_modes<8) && pgm_read_byte(src);
377
solid_modes++, src++ )
379
*dest++ = pgm_read_byte(src);
382
// add moon mode (or not) if config says to add it
384
if (my_enable_moon) {
391
//memcpy_P(dest, src, solid_modes);
393
//memcpy_P(dest + solid_modes, hiddenmodes, sizeof(hiddenmodes));
396
//mode_cnt = solid_modes + sizeof(hiddenmodes);
397
mode_cnt = solid_modes;
400
if (my_reverse_modes) {
401
// TODO: yuck, isn't there a better way to do this?
405
for(i=0; i<solid_modes; i++) {
407
*dest = pgm_read_byte(src);
410
if (my_enable_moon) {
413
mode_cnt --; // get rid of last hidden mode, since it's a duplicate turbo
417
if (my_enable_moon) {
425
inline void set_output(uint8_t pwm1, uint8_t pwm2) {
427
inline void set_output(uint8_t pwm1) {
429
/* This is no longer needed since we always use PHASE mode.
430
// Need PHASE to properly turn off the light
431
if ((pwm1==0) && (pwm2==0)) {
441
void set_level(uint8_t level) {
448
// divide PWM speed by 8 for moon,
449
// because the nanjg 105d chips are SLOW
453
// divide PWM speed by 2 for moon and low,
454
// because the nanjg 105d chips are SLOW
457
//set_output(pgm_read_byte(ramp_FET + level), 0);
458
set_output(pgm_read_byte(ramp_FET + level));
462
void set_mode(uint8_t mode) {
464
static uint8_t actual_level = 0;
465
uint8_t target_level = mode;
469
diff = target_level - actual_level;
470
shift_amount = (diff >> 2) | (diff!=0);
471
actual_level += shift_amount;
472
set_level(actual_level);
473
//_delay_ms(RAMP_SIZE/20); // slow ramp
474
_delay_ms(RAMP_SIZE/4); // fast ramp
475
} while (target_level != actual_level);
477
#define set_mode set_level
482
void blink(uint8_t val, uint16_t speed)
486
set_level(BLINK_BRIGHTNESS);
495
inline void strobe(uint8_t ontime, uint8_t offtime) {
498
set_level(RAMP_SIZE);
507
inline void SOS_mode() {
508
#define SOS_SPEED 200
510
_delay_ms(SOS_SPEED*5);
511
blink(3, SOS_SPEED*5/2);
512
//_delay_ms(SOS_SPEED);
514
_delay_s(); _delay_s();
518
void toggle(uint8_t *var, uint8_t num) {
519
// Used for config mode
520
// Changes the value of a config option, waits for the user to "save"
521
// by turning the light off, then changes the value back in case they
522
// didn't save. Can be used repeatedly on different options, allowing
523
// the user to change and save only one at a time.
524
blink(num, BLINK_SPEED/4); // indicate which option number this is
527
// "buzz" for a while to indicate the active toggle window
530
for(uint8_t i=0; i<32; i++) {
531
set_level(BLINK_BRIGHTNESS * 3 / 4);
537
// if the user didn't click, reset the value and return
543
#ifdef TEMPERATURE_MON
544
uint8_t get_temperature() {
545
ADC_on_temperature();
546
// average a few values; temperature is noisy
550
for(i=0; i<16; i++) {
551
temp += get_voltage();
557
#endif // TEMPERATURE_MON
559
#if 0 // there is no OTC
560
inline uint8_t read_otc() {
561
// Read and return the off-time cap value
562
// Start up ADC for capacitor pin
563
// disable digital input on ADC pin to reduce power consumption
564
DIDR0 |= (1 << CAP_DIDR);
565
// 1.1v reference, left-adjust, ADC3/PB3
566
ADMUX = (1 << V_REF) | (1 << ADLAR) | CAP_CHANNEL;
567
// enable, start, prescale
568
ADCSRA = (1 << ADEN ) | (1 << ADSC ) | ADC_PRSCL;
570
// Wait for completion
571
while (ADCSRA & (1 << ADSC));
572
// Start again as datasheet says first result is unreliable
573
ADCSRA |= (1 << ADSC);
574
// Wait for completion
575
while (ADCSRA & (1 << ADSC));
577
// ADCH should have the value we wanted
584
// check the OTC immediately before it has a chance to charge or discharge
585
//uint8_t cap_val = read_otc(); // save it for later
587
// Set PWM pin to output
588
DDRB |= (1 << PWM_PIN); // enable main channel
590
DDRB |= (1 << ALT_PWM_PIN); // enable second channel
593
// Set timer to do PWM for correct output pin and set prescaler timing
594
//TCCR0A = 0x23; // phase corrected PWM is 0x21 for PB1, fast-PWM is 0x23
595
//TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...)
597
// Set timer to do PWM for correct output pin and set prescaler timing
598
TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...)
600
// Read config values and saved state
603
// Enable the current mode group
607
// TODO: Enable this? (might prevent some corner cases, but requires extra room)
608
// memory decayed, reset it
609
// (should happen on med/long press instead
610
// because mem decay is *much* slower when the OTC is charged
611
// so let's not wait until it decays to reset it)
612
//if (fast_presses > 0x20) { fast_presses = 0; }
614
// check button press time, unless the mode is overridden
615
if (! mode_override) {
616
//if (cap_val > CAP_SHORT) {
617
if (fast_presses < 0x20) {
618
// Indicates they did a short press, go to the next mode
619
// We don't care what the fast_presses value is as long as it's over 15
620
fast_presses = (fast_presses+1) & 0x1f;
621
next_mode(); // Will handle wrap arounds
623
} else if (cap_val > CAP_MED) {
624
// User did a medium press, go back one mode
627
prev_mode(); // Will handle "negative" modes and wrap-arounds
629
next_mode(); // disabled-med-press acts like short-press
630
// (except that fast_presses isn't reliable then)
634
// Long press, keep the same mode
635
// ... or reset to the first mode
637
//if (muggle_mode || (! memory)) {
639
// Reset to the first mode
647
// Charge up the capacitor by setting CAP_PIN to output
648
DDRB |= (1 << CAP_PIN); // Output
649
PORTB |= (1 << CAP_PIN); // High
652
// Turn features on or off as needed
660
uint8_t actual_level;
661
#ifdef TEMPERATURE_MON
662
uint8_t overheat_count = 0;
665
uint8_t lowbatt_cnt = 0;
668
// Make sure voltage reading is running for later
669
ADCSRA |= (1 << ADSC);
671
//output = pgm_read_byte(modes + mode_idx);
672
output = modes[mode_idx];
673
actual_level = output;
674
// handle mode overrides, like mode group selection and temperature calibration
676
// do nothing; mode is already set
677
//mode_idx = mode_override;
682
if (fast_presses > 9) { // Config mode
683
_delay_s(); // wait for user to stop fast-pressing button
684
fast_presses = 0; // exit this mode after one use
687
// Enter or leave "muggle mode"?
688
//toggle(&muggle_mode, 1);
689
//if (muggle_mode) { continue; }; // don't offer other options in muggle mode
691
//toggle(&memory, 2);
693
//toggle(&enable_moon, 3);
695
//toggle(&reverse_modes, 4);
697
// Enter the mode group selection mode?
698
mode_idx = GROUP_SELECT_MODE;
699
toggle(&mode_override, 1);
708
#ifdef TEMPERATURE_MON
709
// Enter temperature calibration mode?
710
mode_idx = TEMP_CAL_MODE;
711
toggle(&mode_override, 7);
715
//toggle(&firstboot, 8);
717
//output = pgm_read_byte(modes + mode_idx);
718
output = modes[mode_idx];
719
actual_level = output;
722
else if (output == STROBE) {
723
// 10Hz tactical strobe
726
#endif // ifdef STROBE
728
else if (output == POLICE_STROBE) {
729
// police-like strobe
737
#endif // ifdef POLICE_STROBE
739
else if (output == RANDOM_STROBE) {
740
// pseudo-random strobe
741
uint8_t ms = 34 + (pgm_rand() & 0x3f);
745
#endif // ifdef RANDOM_STROBE
747
else if (output == BIKING_STROBE) {
748
// 2-level stutter beacon for biking and such
749
#ifdef FULL_BIKING_STROBE
762
// small/minimal version
771
#endif // ifdef BIKING_STROBE
773
else if (output == SOS) { SOS_mode(); }
776
else if (output == RAMP) {
778
// simple ramping test
779
for(r=1; r<=RAMP_SIZE; r++) {
783
for(r=RAMP_SIZE; r>0; r--) {
790
else if (output == BATTCHECK) {
792
// blink out volts and tenths
794
uint8_t result = battcheck();
795
blink(result >> 5, BLINK_SPEED/8);
796
_delay_ms(BLINK_SPEED);
798
_delay_ms(BLINK_SPEED*3/2);
799
blink(result & 0b00011111, BLINK_SPEED/8);
800
#else // ifdef BATTCHECK_VpT
801
// blink zero to five times to show voltage
802
// (~0%, ~25%, ~50%, ~75%, ~100%, >100%)
803
blink(battcheck(), BLINK_SPEED/4);
804
#endif // ifdef BATTCHECK_VpT
805
// wait between readouts
806
_delay_s(); _delay_s();
808
#endif // ifdef BATTCHECK
809
else if (output == GROUP_SELECT_MODE) {
810
// exit this mode after one use
814
for(i=0; i<NUM_MODEGROUPS; i++) {
818
blink(i+1, BLINK_SPEED/4);
819
_delay_s(); _delay_s();
824
else if (output == TEMP_CAL_MODE) {
825
// make sure we don't stay in this mode after button press
829
// Allow the user to turn off thermal regulation if they want
832
set_mode(RAMP_SIZE/4); // start somewhat dim during turn-off-regulation mode
833
_delay_s(); _delay_s();
835
// run at highest output level, to generate heat
838
// measure, save, wait... repeat
840
maxtemp = get_temperature();
842
_delay_s(); _delay_s();
845
#endif // TEMP_CAL_MODE
846
else { // Regular non-hidden solid mode
847
set_mode(actual_level);
848
#ifdef TEMPERATURE_MON
849
uint8_t temp = get_temperature();
851
// step down? (or step back up?)
852
if (temp >= maxtemp) {
854
// reduce noise, and limit the lowest step-down level
855
if ((overheat_count > 15) && (actual_level > (RAMP_SIZE/8))) {
857
//_delay_ms(5000); // don't ramp down too fast
858
overheat_count = 0; // don't ramp down too fast
861
// if we're not overheated, ramp up to the user-requested level
863
if ((temp < maxtemp - 2) && (actual_level < output)) {
867
set_mode(actual_level);
869
ADC_on(); // return to voltage mode
871
// Otherwise, just sleep.
874
// If we got this far, the user has stopped fast-pressing.
875
// So, don't enter config mode.
880
if (ADCSRA & (1 << ADIF)) { // if a voltage reading is ready
881
voltage = ADCH; // get the waiting value
882
// See if voltage is lower than what we were looking for
883
if (voltage < ADC_LOW) {
888
// See if it's been low for a while, and maybe step down
889
if (lowbatt_cnt >= 8) {
890
// DEBUG: blink on step-down:
891
//set_level(0); _delay_ms(100);
893
if (actual_level > RAMP_SIZE) { // hidden / blinky modes
894
// step down from blinky modes to medium
895
actual_level = RAMP_SIZE / 2;
896
} else if (actual_level > 1) { // regular solid mode
897
// step down from solid modes somewhat gradually
898
// drop by 25% each time
899
//actual_level = (actual_level >> 2) + (actual_level >> 1);
900
actual_level = actual_level - 1;
901
// drop by 50% each time
902
//actual_level = (actual_level >> 1);
903
} else { // Already at the lowest mode
904
//mode_idx = 0; // unnecessary; we never leave this clause
905
//actual_level = 0; // unnecessary; we never leave this clause
906
// Turn off the light
908
// Power down as many components as possible
909
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
912
set_mode(actual_level);
913
output = actual_level;
914
//save_mode(); // we didn't actually change the mode
916
// Wait before lowering the level again
921
// Make sure conversion is running for next time through
922
ADCSRA |= (1 << ADSC);
924
#endif // ifdef VOLTAGE_MON
927
//return 0; // Standard Return Code