~toykeeper/flashlight-firmware/trunk

« back to all changes in this revision

Viewing changes to ToyKeeper/blf-a6/blf-a6.c

  • Committer: Selene Scriven
  • Date: 2015-03-17 08:56:50 UTC
  • mto: This revision was merged to the branch mainline in revision 124.
  • Revision ID: ubuntu@toykeeper.net-20150317085650-s89wr9h28n2co7z1
Added TheStar firmwares from _the_

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
 *           ---
31
31
 *
32
32
 * FUSES
33
 
 *      (check bin/flash*.sh for recommended values)
 
33
 *      I use these fuse settings
 
34
 *      Low:  0x75  (4.8MHz CPU without 8x divider, 9.4kHz phase-correct PWM or 18.75kHz fast-PWM)
 
35
 *      High: 0xff
 
36
 *
 
37
 *      For more details on these settings, visit http://github.com/JCapSolutions/blf-firmware/wiki/PWM-Frequency
34
38
 *
35
39
 * STARS
36
40
 *      Star 2 = second PWM output channel
60
64
 *
61
65
 *   Same for off-time capacitor values.  Measure, don't guess.
62
66
 */
63
 
// Choose your MCU here, or in the build script
64
 
//#define ATTINY 13
65
 
//#define ATTINY 25
66
 
// FIXME: make 1-channel vs 2-channel power a single #define option
67
 
#define FET_7135_LAYOUT  // specify an I/O pin layout
68
 
// Also, assign I/O pins in this file:
69
 
#include "../tk-attiny.h"
 
67
#define F_CPU 4800000UL
70
68
 
71
69
/*
72
70
 * =========================================================================
79
77
#define PHASE 0xA1          // phase-correct PWM both channels
80
78
 
81
79
#define VOLTAGE_MON         // Comment out to disable LVP
 
80
#define OWN_DELAY           // Should we use the built-in delay or our own?
 
81
// Adjust the timing per-driver, since the hardware has high variance
 
82
// Higher values will run slower, lower values run faster.
 
83
#define DELAY_TWEAK         950
82
84
 
83
85
#define OFFTIM3             // Use short/med/long off-time presses
84
86
                            // instead of just short/long
85
87
 
86
88
// comment out to use extended config mode instead of a solderable star
87
89
// (controls whether mode memory is on the star or if it's a setting in config mode)
88
 
//#define CONFIG_STARS
89
 
 
90
 
// output to use for blinks on battery check mode (primary PWM level, alt PWM level)
91
 
// Use 20,0 for a single-channel driver or 0,20 for a two-channel driver
92
 
#define BLINK_BRIGHTNESS    0,20
 
90
#define CONFIG_STARS
93
91
 
94
92
// Mode group 1
95
93
#define NUM_MODES1          7
96
94
// PWM levels for the big circuit (FET or Nx7135)
97
 
#define MODESNx1            0,0,0,7,56,137,255
 
95
#define MODESNx1            0,0,0,6,56,135,255
98
96
// PWM levels for the small circuit (1x7135)
99
 
#define MODES1x1            3,20,110,255,255,255,0
100
 
// My sample:     6=0..6,  7=2..11,  8=8..21(15..32)
101
 
// Krono sample:  6=5..21, 7=17..32, 8=33..96(50..78)
102
 
// Manker2:       2=21, 3=39, 4=47, ... 6?=68
 
97
#define MODES1x1            3,20,100,255,255,255,0
103
98
// PWM speed for each mode
104
99
#define MODES_PWM1          PHASE,FAST,FAST,FAST,FAST,FAST,PHASE
105
100
// Mode group 2
106
101
#define NUM_MODES2          4
107
 
#define MODESNx2            0,0,90,255
108
 
#define MODES1x2            20,230,255,0
 
102
#define MODESNx2            0,0,79,255
 
103
#define MODES1x2            20,200,255,0
109
104
#define MODES_PWM2          FAST,FAST,FAST,PHASE
110
105
// Hidden modes are *before* the lowest (moon) mode, and should be specified
111
106
// in reverse order.  So, to go backward from moon to turbo to strobe to
112
107
// battcheck, use BATTCHECK,STROBE,TURBO .
113
 
#define NUM_HIDDEN          4
114
 
#define HIDDENMODES         BIKING_STROBE,BATTCHECK,STROBE,TURBO
115
 
#define HIDDENMODES_PWM     PHASE,PHASE,PHASE,PHASE
116
 
#define HIDDENMODES_ALT     0,0,0,0   // Zeroes, same length as NUM_HIDDEN
 
108
#define NUM_HIDDEN          3
 
109
#define HIDDENMODES         BATTCHECK,STROBE,TURBO
 
110
#define HIDDENMODES_PWM     PHASE,PHASE,PHASE
117
111
 
118
 
#define TURBO     255       // Convenience code for turbo mode
119
 
#define BATTCHECK 254       // Convenience code for battery check mode
120
 
// Uncomment to enable tactical strobe mode
121
 
#define STROBE    253       // Convenience code for strobe mode
122
 
// Uncomment to unable a 2-level stutter beacon instead of a tactical strobe
123
 
#define BIKING_STROBE 252   // Convenience code for biking strobe mode
124
 
// comment out to use minimal version instead (smaller)
125
 
#define FULL_BIKING_STROBE
 
112
// Uncomment to use a 2-level stutter beacon instead of a tactical strobe
 
113
//#define BIKING_STROBE
126
114
 
127
115
#define NON_WDT_TURBO            // enable turbo step-down without WDT
128
116
// How many timer ticks before before dropping down.
129
117
// Each timer tick is 500ms, so "60" would be a 30-second stepdown.
130
118
// Max value of 255 unless you change "ticks"
131
 
#define TURBO_TIMEOUT       90
132
 
 
133
 
// Calibrate voltage and OTC in this file:
134
 
#include "../tk-calibration.h"
 
119
#define TURBO_TIMEOUT       60
 
120
 
 
121
// These values were measured using wight's "A17HYBRID-S" driver built by DBCstm.
 
122
// Your mileage may vary.
 
123
#define ADC_42          174 // the ADC value we expect for 4.20 volts
 
124
#define ADC_100         174 // the ADC value for 100% full (4.2V resting)
 
125
#define ADC_75          165 // the ADC value for 75% full (4.0V resting)
 
126
#define ADC_50          155 // the ADC value for 50% full (3.8V resting)
 
127
#define ADC_25          141 // the ADC value for 25% full (3.5V resting)
 
128
#define ADC_0           118 // the ADC value for 0% full (3.0V resting)
 
129
#define ADC_LOW         109 // When do we start ramping down (2.8V)
 
130
#define ADC_CRIT        104 // When do we shut the light off (2.7V)
 
131
// These values were copied from s7.c.
 
132
// Your mileage may vary.
 
133
//#define ADC_42          185 // the ADC value we expect for 4.20 volts
 
134
//#define ADC_100         185 // the ADC value for 100% full (4.2V resting)
 
135
//#define ADC_75          175 // the ADC value for 75% full (4.0V resting)
 
136
//#define ADC_50          164 // the ADC value for 50% full (3.8V resting)
 
137
//#define ADC_25          154 // the ADC value for 25% full (3.5V resting)
 
138
//#define ADC_0           139 // the ADC value for 0% full (3.0V resting)
 
139
//#define ADC_LOW         123 // When do we start ramping down (2.8V)
 
140
//#define ADC_CRIT        113 // When do we shut the light off (2.7V)
 
141
// Values for testing only:
 
142
//#define ADC_LOW         125 // When do we start ramping down (2.8V)
 
143
//#define ADC_CRIT        124 // When do we shut the light off (2.7V)
 
144
 
 
145
// the BLF EE A6 driver may have different offtime cap values than most other drivers
 
146
#ifdef OFFTIM3
 
147
#define CAP_SHORT           250  // Value between 1 and 255 corresponding with cap voltage (0 - 1.1v) where we consider it a short press to move to the next mode
 
148
#define CAP_MED             190  // Value between 1 and 255 corresponding with cap voltage (0 - 1.1v) where we consider it a short press to move to the next mode
 
149
#else
 
150
#define CAP_SHORT           190  // Value between 1 and 255 corresponding with cap voltage (0 - 1.1v) where we consider it a short press to move to the next mode
 
151
                                 // Not sure the lowest you can go before getting bad readings, but with a value of 70 and a 1uF cap, it seemed to switch sometimes
 
152
                                 // even when waiting 10 seconds between presses.
 
153
#endif
 
154
 
 
155
#define TURBO     255       // Convenience code for turbo mode
 
156
#define STROBE    254       // Convenience code for strobe mode
 
157
#define BATTCHECK 253       // Convenience code for battery check mode
135
158
 
136
159
/*
137
160
 * =========================================================================
138
161
 */
139
162
 
140
 
// Ignore a spurious warning, we did the cast on purpose
141
 
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
 
163
#ifdef OWN_DELAY
 
164
#include <util/delay_basic.h>
 
165
// Having own _delay_ms() saves some bytes AND adds possibility to use variables as input
 
166
void _delay_ms(uint16_t n)
 
167
{
 
168
    // TODO: make this take tenths of a ms instead of ms,
 
169
    // for more precise timing?
 
170
    while(n-- > 0) _delay_loop_2(DELAY_TWEAK);
 
171
}
 
172
void _delay_s()  // because it saves a bit of ROM space to do it this way
 
173
{
 
174
    _delay_ms(1000);
 
175
}
 
176
#else
 
177
#include <util/delay.h>
 
178
#endif
142
179
 
143
180
#include <avr/pgmspace.h>
144
181
//#include <avr/io.h>
147
184
#include <avr/sleep.h>
148
185
//#include <avr/power.h>
149
186
 
150
 
#define OWN_DELAY           // Don't use stock delay functions.
151
 
#define USE_DELAY_MS        // use _delay_ms()
152
 
#define USE_DELAY_S         // Also use _delay_s(), not just _delay_ms()
153
 
#include "../tk-delay.h"
154
 
#define USE_BATTCHECK
155
 
//#define BATTCHECK_4bars
156
 
#define BATTCHECK_8bars
157
 
#define BLINK_SPEED 500
158
 
#include "../tk-voltage.h"
 
187
#define STAR2_PIN   PB0     // But note that there is no star 2.
 
188
#define STAR3_PIN   PB4
 
189
#define CAP_PIN     PB3
 
190
#define CAP_CHANNEL 0x03    // MUX 03 corresponds with PB3 (Star 4)
 
191
#define CAP_DIDR    ADC3D   // Digital input disable bit corresponding with PB3
 
192
#define PWM_PIN     PB1
 
193
#define ALT_PWM_PIN PB0
 
194
#define VOLTAGE_PIN PB2
 
195
#define ADC_CHANNEL 0x01    // MUX 01 corresponds with PB2
 
196
#define ADC_DIDR    ADC1D   // Digital input disable bit corresponding with PB2
 
197
#define ADC_PRSCL   0x06    // clk/64
 
198
 
 
199
#define PWM_LVL     OCR0B   // OCR0B is the output compare register for PB1
 
200
#define ALT_PWM_LVL OCR0A   // OCR0A is the output compare register for PB0
159
201
 
160
202
/*
161
203
 * global variables
166
208
uint8_t memory = 0;        // mode memory, or not (set via soldered star)
167
209
uint8_t modegroup = 0;     // which mode group (set above in #defines)
168
210
uint8_t mode_idx = 0;      // current or last-used mode number
169
 
// counter for entering config mode
170
 
// (needs to be remembered while off, but only for up to half a second)
171
 
uint8_t fast_presses __attribute__ ((section (".noinit")));
 
211
uint8_t fast_presses = 0;  // counter for entering config mode
172
212
 
173
213
// NOTE: Only '1' is known to work; -1 will probably break and is untested.
174
214
// In other words, short press goes to the next (higher) mode,
188
228
PROGMEM const uint8_t modesNx2[] = { MODESNx2, HIDDENMODES };
189
229
const uint8_t *modesNx;  // gets pointed at whatever group is current
190
230
 
191
 
PROGMEM const uint8_t modes1x1[] = { MODES1x1, HIDDENMODES_ALT };
192
 
PROGMEM const uint8_t modes1x2[] = { MODES1x2, HIDDENMODES_ALT };
 
231
PROGMEM const uint8_t modes1x1[] = { MODES1x1, HIDDENMODES };
 
232
PROGMEM const uint8_t modes1x2[] = { MODES1x2, HIDDENMODES };
193
233
const uint8_t *modes1x;
194
234
 
195
235
PROGMEM const uint8_t modes_pwm1[] = { MODES_PWM1, HIDDENMODES_PWM };
196
236
PROGMEM const uint8_t modes_pwm2[] = { MODES_PWM2, HIDDENMODES_PWM };
197
237
const uint8_t *modes_pwm;
198
238
 
 
239
PROGMEM const uint8_t voltage_blinks[] = {
 
240
    ADC_0,    // 1 blink  for 0%-25%
 
241
    ADC_25,   // 2 blinks for 25%-50%
 
242
    ADC_50,   // 3 blinks for 50%-75%
 
243
    ADC_75,   // 4 blinks for 75%-100%
 
244
    ADC_100,  // 5 blinks for >100%
 
245
};
 
246
 
199
247
void save_state() {  // central method for writing (with wear leveling)
 
248
    uint8_t oldpos=eepos;
200
249
    // a single 16-bit write uses less ROM space than two 8-bit writes
201
 
    uint8_t eep;
202
 
    uint8_t oldpos=eepos;
 
250
    uint16_t eep;
203
251
 
204
 
    eepos = (eepos+1) & (EEPSIZE-1);  // wear leveling, use next cell
 
252
    eepos=(eepos+2)&63;  // wear leveling, use next cell
205
253
 
206
254
#ifdef CONFIG_STARS
207
 
    eep = mode_idx | (modegroup << 5);
 
255
    eep = mode_idx | (fast_presses << 12) | (modegroup << 8);
208
256
#else
209
 
    eep = mode_idx | (modegroup << 5) | (memory << 6);
 
257
    eep = mode_idx | (fast_presses << 12) | (modegroup << 8) | (memory << 9);
210
258
#endif
211
 
    eeprom_write_byte((uint8_t *)(eepos), eep);      // save current state
212
 
    eeprom_write_byte((uint8_t *)(oldpos), 0xff);    // erase old state
 
259
    eeprom_write_word((uint16_t *)(eepos), eep);      // save current state
 
260
    eeprom_write_word((uint16_t *)(oldpos), 0xffff);  // erase old state
213
261
}
214
262
 
215
263
void restore_state() {
216
 
    uint8_t eep;
 
264
    // two 8-bit reads use less ROM space than a single 16-bit write
 
265
    uint8_t eep1;
 
266
    uint8_t eep2;
217
267
    // find the config data
218
 
    for(eepos=0; eepos<EEPSIZE; eepos++) {
219
 
        eep = eeprom_read_byte((const uint8_t *)eepos);
220
 
        if (eep != 0xff) break;
 
268
    for(eepos=0; eepos<64; eepos+=2) {
 
269
        eep1 = eeprom_read_byte((const uint8_t *)eepos);
 
270
        eep2 = eeprom_read_byte((const uint8_t *)eepos+1);
 
271
        if (eep1 != 0xff) break;
221
272
    }
222
273
    // unpack the config data
223
 
    if (eepos < EEPSIZE) {
224
 
        mode_idx = eep & 0x0f;
225
 
        modegroup = (eep >> 5) & 1;
 
274
    if (eepos < 64) {
 
275
        mode_idx = eep1;
 
276
        fast_presses = (eep2 >> 4);
 
277
        modegroup = eep2 & 1;
226
278
#ifndef CONFIG_STARS
227
 
        memory = (eep >> 6) & 1;
 
279
        memory = (eep2 >> 1) & 1;
228
280
#endif
229
281
    }
230
 
    // unnecessary, save_state handles wrap-around
231
 
    // (and we don't really care about it skipping cell 0 once in a while)
232
 
    //else eepos=0;
 
282
    //else eepos=0;  // unnecessary, save_state handles wrap-around
233
283
}
234
284
 
235
285
inline void next_mode() {
308
358
    mode_cnt = solid_modes + NUM_HIDDEN;
309
359
}
310
360
 
 
361
#ifdef VOLTAGE_MON
 
362
inline void ADC_on() {
 
363
    DIDR0 |= (1 << ADC_DIDR);                           // disable digital input on ADC pin to reduce power consumption
 
364
    ADMUX  = (1 << REFS0) | (1 << ADLAR) | ADC_CHANNEL; // 1.1v reference, left-adjust, ADC1/PB2
 
365
    ADCSRA = (1 << ADEN ) | (1 << ADSC ) | ADC_PRSCL;   // enable, start, prescale
 
366
}
 
367
#else
 
368
inline void ADC_off() {
 
369
    ADCSRA &= ~(1<<7); //ADC off
 
370
}
 
371
#endif
 
372
 
311
373
void set_output(uint8_t pwm1, uint8_t pwm2) {
312
374
    // Need PHASE to properly turn off the light
313
375
    if ((pwm1==0) && (pwm2==0)) {
317
379
    ALT_PWM_LVL = pwm2;
318
380
}
319
381
 
320
 
void set_mode(uint8_t mode) {
 
382
void set_mode(mode) {
321
383
    TCCR0A = pgm_read_byte(modes_pwm + mode);
322
384
    set_output(pgm_read_byte(modesNx + mode), pgm_read_byte(modes1x + mode));
323
385
    /*
329
391
    */
330
392
}
331
393
 
 
394
#ifdef VOLTAGE_MON
 
395
uint8_t get_voltage() {
 
396
    // Start conversion
 
397
    ADCSRA |= (1 << ADSC);
 
398
    // Wait for completion
 
399
    while (ADCSRA & (1 << ADSC));
 
400
    // See if voltage is lower than what we were looking for
 
401
    return ADCH;
 
402
}
 
403
#endif
 
404
 
332
405
void blink(uint8_t val)
333
406
{
334
407
    for (; val>0; val--)
335
408
    {
336
 
        set_output(BLINK_BRIGHTNESS);
337
 
        _delay_ms(BLINK_SPEED / 5);
 
409
        set_output(0,20);
 
410
        _delay_ms(100);
338
411
        set_output(0,0);
339
 
        _delay_ms(BLINK_SPEED * 4 / 5);
 
412
        _delay_ms(400);
340
413
    }
341
414
}
342
415
 
343
 
#ifndef CONFIG_STARS
344
 
void toggle(uint8_t *var) {
345
 
    // Used for extended config mode
346
 
    // Changes the value of a config option, waits for the user to "save"
347
 
    // by turning the light off, then changes the value back in case they
348
 
    // didn't save.  Can be used repeatedly on different options, allowing
349
 
    // the user to change and save only one at a time.
350
 
    *var ^= 1;
351
 
    save_state();
352
 
    blink(2);
353
 
    *var ^= 1;
354
 
    save_state();
355
 
    _delay_s();
356
 
}
357
 
#endif // ifndef CONFIG_STARS
358
 
 
359
416
int main(void)
360
417
{
361
418
    uint8_t cap_val;
363
420
    // Read the off-time cap *first* to get the most accurate reading
364
421
    // Start up ADC for capacitor pin
365
422
    DIDR0 |= (1 << CAP_DIDR);                           // disable digital input on ADC pin to reduce power consumption
366
 
    ADMUX  = (1 << V_REF) | (1 << ADLAR) | CAP_CHANNEL; // 1.1v reference, left-adjust, ADC3/PB3
 
423
    ADMUX  = (1 << REFS0) | (1 << ADLAR) | CAP_CHANNEL; // 1.1v reference, left-adjust, ADC3/PB3
367
424
    ADCSRA = (1 << ADEN ) | (1 << ADSC ) | ADC_PRSCL;   // enable, start, prescale
368
425
 
369
426
    // Wait for completion
374
431
    while (ADCSRA & (1 << ADSC));
375
432
    cap_val = ADCH; // save this for later
376
433
 
377
 
#ifdef CONFIG_STARS
378
434
    // All ports default to input, but turn pull-up resistors on for the stars (not the ADC input!  Made that mistake already)
379
435
    // only one star, because one is used for PWM channel 2
380
436
    // and the other is used for the off-time capacitor
381
437
    PORTB = (1 << STAR3_PIN);
382
 
#endif
383
438
 
384
439
    // Set PWM pin to output
385
440
    DDRB |= (1 << PWM_PIN);     // enable main channel
401
456
    count_modes();
402
457
 
403
458
 
404
 
    // memory decayed, reset it
405
 
    // (should happen on med/long press instead
406
 
    //  because mem decay is *much* slower when the OTC is charged
407
 
    //  so let's not wait until it decays to reset it)
408
 
    //if (fast_presses > 0x20) { fast_presses = 0; }
409
 
 
410
459
    if (cap_val > CAP_SHORT) {
411
 
        // We don't care what the value is as long as it's over 15
412
 
        fast_presses = (fast_presses+1) & 0x1f;
413
460
        // Indicates they did a short press, go to the next mode
414
461
        next_mode(); // Will handle wrap arounds
 
462
        if (fast_presses < 15) fast_presses ++;
415
463
#ifdef OFFTIM3
416
464
    } else if (cap_val > CAP_MED) {
417
 
        fast_presses = 0;
418
465
        // User did a medium press, go back one mode
419
466
        prev_mode(); // Will handle "negative" modes and wrap-arounds
 
467
        fast_presses = 0;
420
468
#endif
421
469
    } else {
422
470
        // Long press, keep the same mode
461
509
#endif
462
510
    while(1) {
463
511
        output = pgm_read_byte(modesNx + mode_idx);
464
 
        if (fast_presses > 0x0f) {  // Config mode
 
512
        if (fast_presses == 0x0f) {  // Config mode
465
513
            _delay_s();       // wait for user to stop fast-pressing button
466
514
            fast_presses = 0; // exit this mode after one use
467
515
            mode_idx = 0;
476
524
#else
477
525
            // Longer/larger version of the config mode
478
526
            // Toggle the mode group, blink, un-toggle, continue
479
 
            toggle(&modegroup);
 
527
            modegroup ^= 1;
 
528
            save_state();
 
529
            blink(2);
 
530
            modegroup ^= 1;
 
531
 
 
532
            _delay_s();
480
533
 
481
534
            // Toggle memory, blink, untoggle, exit
482
 
            toggle(&memory);
 
535
            memory ^= 1;
 
536
            save_state();
 
537
            blink(2);
 
538
            memory ^= 1;
 
539
 
 
540
            save_state();
483
541
#endif  // ifdef CONFIG_STARS
484
542
        }
485
 
#ifdef STROBE
486
543
        else if (output == STROBE) {
487
 
            // 10Hz tactical strobe
488
 
            set_output(255,0);
489
 
            _delay_ms(50);
490
 
            set_output(0,0);
491
 
            _delay_ms(50);
492
 
        }
493
 
#endif // ifdef STROBE
494
544
#ifdef BIKING_STROBE
495
 
        else if (output == BIKING_STROBE) {
496
545
            // 2-level stutter beacon for biking and such
497
 
#ifdef FULL_BIKING_STROBE
498
 
            // normal version
499
546
            for(i=0;i<4;i++) {
500
547
                set_output(255,0);
501
548
                _delay_ms(5);
504
551
            }
505
552
            _delay_ms(720);
506
553
#else
507
 
            // small/minimal version
508
 
            set_output(255,0);
509
 
            _delay_ms(10);
510
 
            set_output(0,255);
511
 
            _delay_s();
512
 
#endif
513
 
        }
 
554
            // 10Hz tactical strobe
 
555
            set_output(255,255);
 
556
            _delay_ms(50);
 
557
            set_output(0,0);
 
558
            _delay_ms(50);
514
559
#endif  // ifdef BIKING_STROBE
515
 
#ifdef BATTCHECK
 
560
        }
516
561
        else if (output == BATTCHECK) {
517
 
            // blink zero to five times to show voltage
 
562
            uint8_t blinks = 0;
 
563
            // turn off and wait one second before showing the value
 
564
            // (also, ensure voltage is measured while not under load)
 
565
            set_output(0,0);
 
566
            _delay_s();
 
567
            voltage = get_voltage();
 
568
            voltage = get_voltage(); // the first one is unreliable
 
569
            // division takes too much flash space
 
570
            //voltage = (voltage-ADC_LOW) / (((ADC_42 - 15) - ADC_LOW) >> 2);
 
571
            // a table uses less space than 5 logic clauses
 
572
            for (i=0; i<sizeof(voltage_blinks); i++) {
 
573
                if (voltage > pgm_read_byte(voltage_blinks + i)) {
 
574
                    blinks ++;
 
575
                }
 
576
            }
 
577
 
 
578
            // blink up to five times to show voltage
518
579
            // (~0%, ~25%, ~50%, ~75%, ~100%, >100%)
519
 
            blink(battcheck());
520
 
            // wait between readouts
521
 
            _delay_s(); _delay_s();
 
580
            blink(blinks);
 
581
            _delay_s();  // wait at least 1 second between readouts
522
582
        }
523
 
#endif // ifdef BATTCHECK
524
583
        else {  // Regular non-hidden solid mode
525
584
            set_mode(mode_idx);
526
585
            // This part of the code will mostly replace the WDT tick code.
527
586
#ifdef NON_WDT_TURBO
528
587
            // Do some magic here to handle turbo step-down
529
 
            //if (ticks < 255) ticks++;  // don't roll over
530
 
            ticks ++;  // actually, we don't care about roll-over prevention
 
588
            if (ticks < 255) ticks++;
531
589
            if ((ticks > TURBO_TIMEOUT) 
532
590
                    && (output == TURBO)) {
533
591
                mode_idx = solid_modes - 2; // step down to second-highest mode
540
598
 
541
599
            // If we got this far, the user has stopped fast-pressing.
542
600
            // So, don't enter config mode.
543
 
            fast_presses = 0;
 
601
            if (fast_presses) {
 
602
                fast_presses = 0;
 
603
                save_state();
 
604
            }
544
605
        }
545
606
#ifdef VOLTAGE_MON
546
607
#if 1
587
648
#endif
588
649
#endif  // ifdef VOLTAGE_MON
589
650
        //sleep_mode();  // incompatible with blinky modes
590
 
 
591
 
        // If we got this far, the user has stopped fast-pressing.
592
 
        // So, don't enter config mode.
593
 
        //fast_presses = 0;  // doesn't interact well with strobe, too fast
594
651
    }
595
652
 
596
653
    //return 0; // Standard Return Code