~gabe/flashlight-firmware/anduril2

« back to all changes in this revision

Viewing changes to Tom_E/narsil/Narsil/Narsil.c

  • Committer: Selene Scriven
  • Date: 2016-07-10 01:15:02 UTC
  • Revision ID: ubuntu@toykeeper.net-20160710011502-1lput1t8445t0ufr
Updated Narsil from 2016-03-21 to 2016-06-08 version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
//  - battery voltage level display in n.n format (ex: 4.1v blinks 4 times followed by 1 blink)
19
19
//  - multiple strobe and beacon modes
20
20
//  - mode configuration settings:
 
21
//                      - ramping
21
22
//                      - 12 mode sets to choose from
22
23
//                      - moonlight mode on/off plus setting it's PWM level 1-7
23
24
//                      - lo->hi or hi->lo ordering
24
25
//                      - mode memory on e-switch on/off
25
26
//              - turbo-timeout setting
 
27
//                      - blinkie mode configuration (off, strobe only, all blinkies)
26
28
//
27
29
// Change History
28
30
// --------------
 
31
// 2016-06-08:
 
32
//   - add double-click support to max when ON (already worked from OFF)
 
33
//   - add triple-click to be configurable, currently it's battery voltage level display
 
34
//   - add a pause at moon mode for 0.368 sec delay when ramping up from OFF (allows user to easier stop and engage moon mode)
 
35
//   - add new 2.4 sec ramping tables (older 2.046 sec table is comppiled out)
 
36
//
 
37
// 2016-05-19..25:
 
38
//   - add full ramping support
 
39
// 2016-04-06:
 
40
//   - add a new config setting for blinky mode control: disable, 1 strobe mode only, all blinkies
 
41
// 04/04/2016:
 
42
//   - Bug fix: turn OFF locator LED when in lockout, restore upon exiting
 
43
//   - add feature of toggling locator LED: from OFF, 1 quick click the click&hold til the main LED goes OFF
 
44
//
 
45
// 04/03/2016:
 
46
//   - add turning OFF the AtoD during low power sleep mode - knocked the amps down by half
 
47
//
29
48
// 03/21/2016:
30
49
//   - Bug fix: modes/alt_modes tables (now byPrimModes and bySecModes) was [8] -- too small for new 7 mode entry ([10] now)
31
50
// 03/20/2016:
151
170
//-------------------------------------------------------------------------
152
171
//-------------------------------------------------------------------------
153
172
 
 
173
//#define ADV_RAMP_OPTIONS              // enables lock-out and battery voltage display in ramping, comment out to disable
 
174
//#define TRIPLE_CLICK_LOC              // enable a triple-click to toggle the Locator LED
 
175
#define TRIPLE_CLICK_BATT               // enable a triple-click to display Battery status
 
176
 
 
177
#define SHORT_CLICK_DUR 18              // Short click max duration - 0.288 secs
 
178
#define RAMP_MOON_PAUSE 23              // this results in a 0.368 sec delay, paused in moon mode
 
179
 
 
180
 
154
181
// ----- 2/14 TE: One-Click Turn OFF option --------------------------------------------
155
182
#define IDLE_TIME         75    // make the time-out 1.2 seconds (Comment out to disable)
156
183
 
226
253
#define DB_REL_DUR  0b00001111 // time before we consider the switch released
227
254
                                                           // each bit of 1 from the right equals 16ms, so 0x0f = 64ms
228
255
 
 
256
 
229
257
/*
230
258
 * The actual program
231
259
 * =========================================================================
232
260
 */
233
261
 
 
262
 
 
263
 
 
264
#if 0
 
265
//---------------------------------------------------------------------------------------
 
266
#define RAMP_SIZE  128
 
267
#define TURBO_DROP_MIN 98
 
 
b'\t// min level in ramping the turbo timeout will engage,'
 
268
                                                                                //    level 98 = 105 PWM, this is ~43%
 
269
#define TURBO_DROP_SET 88
 
 
b'\t// the level turbo timeout will set,'
 
270
                                                                                //    level 88 = 71 PWM, this is ~32%
 
271
 
 
272
// Ramping Modes, 128 total entries (2.048 secs)
 
273
//    level_calc.py 2 128 7135 3 0.3 150 FET 1 1 1500
 
274
PROGMEM const byte ramp_7135[] = {
 
275
        3,3,3,4,4,5,5,6,  7,7,8,9,11,12,13,15,
 
276
        17,18,20,22,25,27,30,33,  36,39,43,46,50,54,58,63,
 
277
        68,73,78,84,89,96,102,109,  115,123,130,138,146,155,163,173,
 
278
        182,192,202,213,223,235,246,255,  255,255,255,255,255,255,255,255,      // 49-64
 
279
        255,255,255,255,255,255,255,255,  255,255,255,255,255,255,255,255,      // 65-80
 
280
        255,255,255,255,255,255,255,255,  255,255,255,255,255,255,255,255,      // 81-96
 
281
        255,255,255,255,255,255,255,255,  255,255,255,255,255,255,255,255,      // 97-112
 
282
        255,255,255,255,255,255,255,255,  255,255,255,255,255,255,255,0         // 113-128
 
283
};
 
284
 
 
285
PROGMEM const byte ramp_FET[]  = {
 
286
        0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,
 
287
        0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,
 
288
        0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,
 
289
        0,0,0,0,0,0,0,1,  3,4,5,7,9,10,12,14,                                                                                   // 49-64
 
290
        15,17,19,21,23,25,27,29,  31,33,36,38,41,43,45,48,                                                      // 65-80
 
291
        51,53,56,59,62,65,68,71,  74,77,81,84,87,91,94,98,                                                      // 81-96
 
292
        102,105,109,113,117,121,125,129,  134,138,143,147,152,156,161,166,      // 97-112
 
293
        171,176,181,186,191,197,202,208,  213,219,225,231,237,243,249,255               // 113-128
 
294
};
 
295
//---------------------------------------------------------------------------------------
 
296
#endif
 
297
 
 
298
 
 
299
//#if 0
 
300
//---------------------------------------------------------------------------------------
 
301
#define RAMP_SIZE  150
 
302
#define TURBO_DROP_MIN 115
 
 
b'// min level in ramping the turbo timeout will engage,'
 
303
//    level 115 = 106 PWM, this is ~43%
 
304
#define TURBO_DROP_SET 102
 
 
b'// the level turbo timeout will set,'
 
305
//    level 102 = 71 PWM, this is ~32%
 
306
 
 
307
// Ramping Modes, 150 total entries (2.4 secs)
 
308
//    level_calc.py 2 128 7135 3 0.3 150 FET 1 1 1500
 
309
PROGMEM const byte ramp_7135[] = {
 
310
        3,3,3,4,4,4,5,5,  6,6,7,8,9,10,11,12,
 
311
        13,14,15,17,18,20,22,24,  26,28,30,33,35,38,41,44,
 
312
        47,51,54,58,62,66,70,74,  79,83,88,93,99,104,110,116,
 
313
        122,128,135,142,149,156,164,172,  180,188,196,205,214,223,233,243,      // 49-64
 
314
        253,255,255,255,255,255,255,255,  255,255,255,255,255,255,255,255,
 
315
        255,255,255,255,255,255,255,255,  255,255,255,255,255,255,255,255,
 
316
        255,255,255,255,255,255,255,255,  255,255,255,255,255,255,255,255,
 
317
        255,255,255,255,255,255,255,255,  255,255,255,255,255,255,255,255,
 
318
        255,255,255,255,255,255,255,255,  255,255,255,255,255,255,255,255,
 
319
        255,255,255,255,255,0                                                                                                                           // 145-150
 
320
};
 
321
 
 
322
PROGMEM const byte ramp_FET[]  = {
 
323
        0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,
 
324
        0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,
 
325
        0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,
 
326
        0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,                                                                                              // 49-64
 
327
        0,2,3,4,5,7,8,9,  11,12,14,15,17,18,20,22,
 
328
        23,25,27,29,30,32,34,36,  38,40,42,44,47,49,51,53,
 
329
        56,58,60,63,66,68,71,73,  76,79,82,85,87,90,93,96,                                                      // 96-112
 
330
        100,103,106,109,113,116,119,123,  126,130,134,137,141,145,149,153,      // 113-128
 
331
        157,161,165,169,173,178,182,186,  191,196,200,205,210,214,219,224,      // 129-144
 
332
        229,234,239,244,250,255                                                                                                                         // 145-150
 
333
};
 
334
//---------------------------------------------------------------------------------------
 
335
//#endif
 
336
 
 
337
 
234
338
//------------------- MODE SETS --------------------------
235
339
 
236
340
// 1 mode (max)                         max
314
418
//----------------------------------------------------------------
315
419
// Config Settings via UI, with default values:
316
420
//----------------------------------------------------------------
 
421
volatile byte ramping = 1;                              // ramping mode in effect
317
422
volatile byte modeSetIdx = 3;                   // 0..11, mode set currently in effect, chosen by user (3=4 modes)
318
423
volatile byte moonLightEnable = 1;      // 1: enable moonlight mode, 0: disable moon mode
319
424
volatile byte highToLow = 0;                    // 1: highest to lowest, 0: modes go from lowest to highest
325
430
volatile byte bvldLedOnly = 0;          // BVLD (Battery Voltage Level Display) - 1=BVLD shown only w/onboard LED, 0=both primary and onboard LED's
326
431
volatile byte onboardLedEnable = 1;     // On Board LED support - 1=enabled, 0=disabled
327
432
volatile byte OffTimeEnable = 0;                // 1: Do OFF time mode memory on power switching (tailswitch), 0: disabled
 
433
volatile byte blinkyMode = 2;                   // blinky mode config: 1=strobe only, 2=all blinkies, 0=disable
328
434
 
329
435
//----------------------------------------------------------------
330
436
 
331
437
//----------------------------------------------------------------
332
438
// Global state options
333
439
//----------------------------------------------------------------
 
440
 
334
441
volatile byte byLockOutEnable = 1;                                      // button lock-out feature is enabled
335
442
//----------------------------------------------------------------
336
443
 
 
444
// Ramping :
 
445
#define RAMP_SWITCH_TIMEOUT 32          // make the up/dn ramp switch timeout 1/2 sec
 
446
#define MAX_RAMP_LEVEL (RAMP_SIZE)
 
447
 
 
448
volatile byte rampingLevel = 0;         // 0=OFF, 1..MAX_RAMP_LEVEL is the ramping table index, 255=moon mode
 
449
volatile byte rampState = 0;                    // 0=OFF, 1=in lowest mode (moon) delay, 2=ramping Up, 3=Ramping Down, 4=ramping completed (Up or Dn)
 
450
volatile byte savedLevel = 0;                   // mode memory for ramping (copy of rampingLevel)
 
451
byte outLevel;                                                          // current set rampingLevel
 
452
volatile byte byForceLockOut = 0;       // when the main loop want to temporarily lock-out the ramping switch
 
453
byte rampPauseCntDn;                                            // count down timer for ramping support
 
454
 
337
455
 
338
456
// State and count vars:
339
457
volatile byte byLockOutSet = 0;         // System is in LOCK OUT mode
346
464
 
347
465
volatile byte modeIdx = 0;                      // current mode selected
348
466
volatile byte prevModeIdx = 0;  // used to restore the initial mode when exiting strobe mode
349
 
volatile byte pressDuration = 0;
 
467
volatile word wPressDuration = 0;
350
468
 
351
469
volatile byte last_modeIdx;             // last value for modeIdx
352
470
 
369
487
volatile byte LowBattState = 0; // in a low battery state (it's been triggered)
370
488
volatile byte LowBattBlinkSignal = 0;   // a periodic low battery blink signal
371
489
 
 
490
volatile byte locatorLed;                       // Locator LED feature (ON when light is OFF) - 1=enabled, 0=disabled
372
491
 
373
492
 
374
493
// Configuration settings storage in EEPROM
375
494
word eepos = 0; // (0..n) position of mode/settings stored in EEPROM (128/256/512)
376
495
 
 
496
volatile byte config1;  // keep these global, not on stack local
 
497
volatile byte config2;
 
498
volatile byte config3;
 
499
 
 
500
 
377
501
// OFF Time Detection
378
502
volatile byte noinit_decay __attribute__ ((section (".noinit")));
379
503
 
426
550
 
427
551
 
428
552
/**************************************************************************************
429
 
* strobe
 
553
* Strobe
430
554
* ======
431
555
**************************************************************************************/
432
 
void strobe(byte ontime, byte offtime)
 
556
void Strobe(byte ontime, byte offtime)
433
557
{
434
558
        PWM_LVL = 255;
435
559
        _delay_ms(ontime);
438
562
}
439
563
 
440
564
/**************************************************************************************
441
 
* get_voltage
 
565
* GetVoltage
442
566
* ===========
443
567
**************************************************************************************/
444
 
uint8_t get_voltage()
 
568
uint8_t GetVoltage()
445
569
{
446
570
        ADCSRA |= (1 << ADSC);                          // Start conversion
447
571
        
451
575
}
452
576
 
453
577
/**************************************************************************************
454
 
* battcheck
 
578
* BattCheck
455
579
* =========
456
580
**************************************************************************************/
457
 
inline uint8_t battcheck()
 
581
inline uint8_t BattCheck()
458
582
{
459
583
   // Return an composite int, number of "blinks", for approximate battery charge
460
584
   // Uses the table above for return values
461
585
   // Return value is 3 bits of whole volts and 5 bits of tenths-of-a-volt
462
586
   uint8_t i, voltage;
463
587
 
464
 
   voltage = get_voltage();
 
588
   voltage = GetVoltage();
465
589
 
466
590
   // figure out how many times to blink
467
591
   for (i=0; voltage > pgm_read_byte(voltage_blinks + i); i += 2)  ;
480
604
 
481
605
        // Set OFF mode states (index 0)
482
606
        byPrimModes[0] = bySecModes[0] = 0;
483
 
//      mode_pwm[0] = PHASE;
484
607
 
485
608
        if (moonLightEnable)
486
609
        {
487
610
                offset = 2;
488
611
                byPrimModes[1] = 0;
489
612
                bySecModes[1] = moonlightLevel; // PWM value to use for moonlight mode
490
 
//              mode_pwm[1] = PHASE;
491
613
        }
492
614
 
493
615
        // Populate the RAM based current mode set
495
617
        {
496
618
                byPrimModes[offset+i] = pgm_read_byte(modeTableFet[modeSetIdx]+i);
497
619
                bySecModes[offset+i] = pgm_read_byte(modeTable7135[modeSetIdx]+i);
498
 
//              mode_pwm[offset+i] = pgm_read_byte(modeTablePwm[modeSetIdx]+i);
499
620
        }
500
621
 
501
622
        modesCnt += offset;             // adjust to total mode count
502
623
}
503
624
 
504
625
/**************************************************************************************
505
 
* set_output
506
 
* ==========
 
626
* SetOutput - sets the PWM output value directly
 
627
* =========
507
628
**************************************************************************************/
508
 
void set_output(byte pwm1, byte pwm2)
509
 
 {
510
 
        // Need PHASE to properly turn off the light
511
 
//      if ((pwm1==0) && (pwm2==0))
512
 
//              TCCR0A = PHASE;
 
629
void SetOutput(byte pwm1, byte pwm2)
 
630
{
513
631
        PWM_LVL = pwm1;
514
632
        ALT_PWM_LVL = pwm2;
515
633
}
516
634
 
517
635
/**************************************************************************************
518
 
* set_mode
519
 
* ========
520
 
**************************************************************************************/
521
 
void inline set_mode(byte mode)
 
636
* SetLevel - uses the ramping levels to set the PWM output
 
637
* ========              (0 is OFF, 1..128 is the ramping index level)
 
638
**************************************************************************************/
 
639
void SetLevel(byte level)
 
640
{
 
641
        if (level == 0)
 
642
        {
 
643
                SetOutput(0,0);
 
644
                if (locatorLed)
 
645
                        TurnOnBoardLed(1);
 
646
        }
 
647
        else
 
648
        {
 
649
                level -= 1;     // make it 0 based
 
650
                SetOutput(pgm_read_byte(ramp_FET  + level), pgm_read_byte(ramp_7135 + level));
 
651
                if (locatorLed)
 
652
                        TurnOnBoardLed(0);
 
653
        }
 
654
}
 
655
 
 
656
/**************************************************************************************
 
657
* SetMode
 
658
* =======
 
659
**************************************************************************************/
 
660
void inline SetMode(byte mode)
522
661
{
523
 
//   TCCR0A = mode_pwm[mode];
524
 
 
525
662
        currOutLvl1 = byPrimModes[mode];
526
663
        currOutLvl2 = bySecModes[mode];
527
664
        
528
 
        PWM_LVL = currOutLvl1;
529
 
        ALT_PWM_LVL = currOutLvl2;
530
 
        
531
 
        if ((mode == 0) && locatorLedOn)
 
665
        SetOutput(currOutLvl1, currOutLvl2);
 
666
 
 
667
        if ((mode == 0) && locatorLed)
532
668
                TurnOnBoardLed(1);
533
669
        else if (last_modeIdx == 0)
534
670
                TurnOnBoardLed(0);
535
671
}
536
672
 
537
673
/**************************************************************************************
538
 
* blink - do a # of blinks with a speed in msecs
 
674
* Blink - do a # of blinks with a speed in msecs
539
675
* =====
540
676
**************************************************************************************/
541
 
void blink(byte val, word speed)
 
677
void Blink(byte val, word speed)
542
678
{
543
 
//      TCCR0A = PHASE;
544
679
        for (; val>0; val--)
545
680
        {
546
681
                TurnOnBoardLed(1);
547
 
                set_output(BLINK_BRIGHTNESS);
 
682
                SetOutput(BLINK_BRIGHTNESS);
548
683
                _delay_ms(speed);
549
684
                
550
685
                TurnOnBoardLed(0);
551
 
                set_output(0,0);
 
686
                SetOutput(0,0);
552
687
                _delay_ms(speed<<2);    // 4X delay OFF
553
688
        }
554
689
}
555
690
 
556
691
/**************************************************************************************
557
 
* battBlink - do a # of blinks with a speed in msecs
 
692
* BattBlink - do a # of blinks with a speed in msecs
558
693
* =========
559
694
**************************************************************************************/
560
 
void battBlink(byte val)
 
695
void BattBlink(byte val)
561
696
{
562
 
//      TCCR0A = PHASE;
563
697
        for (; val>0; val--)
564
698
        {
565
699
                TurnOnBoardLed(1);
566
700
                
567
 
                if (bvldLedOnly == 0)
568
 
                        set_output(BLINK_BRIGHTNESS);
 
701
                if ((onboardLedEnable == 0) || (bvldLedOnly == 0))
 
702
                        SetOutput(BLINK_BRIGHTNESS);
569
703
                        
570
704
                _delay_ms(250);
571
705
                
572
706
                TurnOnBoardLed(0);
573
 
                set_output(0,0);
 
707
                SetOutput(0,0);
574
708
                _delay_ms(375);
575
709
                
576
710
                if (modeIdx != BATT_CHECK_MODE)
579
713
}
580
714
 
581
715
/**************************************************************************************
582
 
* configBlink - do 2 quick blinks, followed by num count of long blinks
 
716
* ConfigBlink - do 2 quick blinks, followed by num count of long blinks
583
717
* ===========
584
718
**************************************************************************************/
585
 
void configBlink(byte num)
 
719
void ConfigBlink(byte num)
586
720
{
587
 
        blink(2, 40);
 
721
        Blink(2, 40);
588
722
        _delay_ms(240);
589
 
        blink(num, 100);
 
723
        Blink(num, 100);
590
724
 
591
725
        configIdleTime = 0;             // reset the timeout after the blinks complete
592
726
}
593
727
 
594
728
/**************************************************************************************
595
 
* clickBlink
 
729
* ClickBlink
596
730
* ==========
597
731
**************************************************************************************/
598
 
inline static void clickBlink()
 
732
inline static void ClickBlink()
599
733
{
600
 
//      TCCR0A = PHASE;
601
 
        set_output(0,20);
 
734
        SetOutput(0,20);
602
735
        _delay_ms(100);
603
 
        set_output(0,0);
 
736
        SetOutput(0,0);
604
737
}
605
738
 
606
739
 
607
740
/**************************************************************************************
608
 
* is_pressed - debounce the switch release, not the switch press
 
741
* IsPressed - debounce the switch release, not the switch press
609
742
* ==========
610
743
**************************************************************************************/
611
744
// Debounce switch press value
612
745
#ifdef DEBOUNCE_BOTH
613
 
int is_pressed()
 
746
int IsPressed()
614
747
{
615
748
        static byte pressed = 0;
616
749
        // Keep track of last switch values polled
629
762
        return pressed;
630
763
}
631
764
#else
632
 
static int is_pressed()
 
765
static int IsPressed()
633
766
{
634
767
        // Keep track of last switch values polled
635
768
        static byte buffer = 0x00;
641
774
#endif
642
775
 
643
776
/**************************************************************************************
644
 
* next_mode - switch's to next mode, higher output mode
 
777
* NextMode - switch's to next mode, higher output mode
645
778
* =========
646
779
**************************************************************************************/
647
 
void next_mode()
 
780
void NextMode()
648
781
{
649
782
        if (modeIdx < 16)       // 11/16/14 TE: bug fix to exit strobe mode when doing a long press in strobe mode
650
783
                prevModeIdx      = modeIdx;
657
790
}
658
791
 
659
792
/**************************************************************************************
660
 
* prev_mode - switch's to previous mode, lower output mode
 
793
* PrevMode - switch's to previous mode, lower output mode
661
794
* =========
662
795
**************************************************************************************/
663
 
void prev_mode()
 
796
void PrevMode()
664
797
{
665
798
        prevModeIdx      = modeIdx;
666
799
 
674
807
* PCINT_on - Enable pin change interrupts
675
808
* ========
676
809
**************************************************************************************/
677
 
inline void PCINT_on() {
 
810
inline void PCINT_on()
 
811
{
678
812
        // Enable pin change interrupts
679
813
        GIMSK |= (1 << PCIE);
680
814
}
683
817
* PCINT_off - Disable pin change interrupts
684
818
* =========
685
819
**************************************************************************************/
686
 
inline void PCINT_off() {
 
820
inline void PCINT_off()
 
821
{
687
822
        // Disable pin change interrupts
688
823
        GIMSK &= ~(1 << PCIE);
689
824
}
696
831
* WDT_on - Setup watchdog timer to only interrupt, not reset, every 16ms
697
832
* ======
698
833
**************************************************************************************/
699
 
inline void WDT_on() {
 
834
inline void WDT_on()
 
835
{
700
836
        // Setup watchdog timer to only interrupt, not reset, every 16ms.
701
837
        cli();                                                  // Disable interrupts
702
838
        wdt_reset();                                    // Reset the WDT
723
859
* ADC_on - Turn the AtoD Converter ON
724
860
* ======
725
861
**************************************************************************************/
726
 
inline void ADC_on() {
727
 
// For 13A:     ADMUX  = (1 << REFS0) | (1 << ADLAR) | ADC_CHANNEL; // 1.1v reference, left-adjust, ADC1/PB2
 
862
inline void ADC_on()
 
863
{
 
864
        // For 13A:     ADMUX  = (1 << REFS0) | (1 << ADLAR) | ADC_CHANNEL; // 1.1v reference, left-adjust, ADC1/PB2
728
865
        ADMUX  = (1 << REFS1) | (1 << ADLAR) | ADC_CHANNEL; // 1.1v reference, left-adjust, ADC1/PB2
729
866
   DIDR0 |= (1 << ADC_DIDR);                                                    // disable digital input on ADC pin to reduce power consumption
730
867
        ADCSRA = (1 << ADEN ) | (1 << ADSC ) | ADC_PRSCL;   // enable, start, pre-scale
734
871
* ADC_off - Turn the AtoD Converter OFF
735
872
* =======
736
873
**************************************************************************************/
737
 
inline void ADC_off() {
 
874
inline void ADC_off()
 
875
{
738
876
        ADCSRA &= ~(1<<7); //ADC off
739
877
}
740
878
 
741
879
/**************************************************************************************
742
 
* sleep_until_switch_press - only called with the light OFF
743
 
* ========================
 
880
* SleepUntilSwitchPress - only called with the light OFF
 
881
* =====================
744
882
**************************************************************************************/
745
 
void sleep_until_switch_press()
 
883
void SleepUntilSwitchPress()
746
884
{
747
885
        // This routine takes up a lot of program memory :(
748
 
        // Turn the WDT off so it doesn't wake us from sleep
749
 
        // Will also ensure interrupts are on or we will never wake up
 
886
        
 
887
        //  Turn the WDT off so it doesn't wake us from sleep. Will also ensure interrupts
 
888
        // are on or we will never wake up.
750
889
        WDT_off();
 
890
        
 
891
        ADC_off();              // Save more power -- turn the AtoD OFF
 
892
        
751
893
        // Need to reset press duration since a button release wasn't recorded
752
 
        pressDuration = 0;
753
 
        // Enable a pin change interrupt to wake us up
754
 
        // However, we have to make sure the switch is released otherwise we will wake when the user releases the switch
755
 
        while (is_pressed()) {
 
894
        wPressDuration = 0;
 
895
        
 
896
        //  Enable a pin change interrupt to wake us up. However, we have to make sure the switch
 
897
        // is released otherwise we will wake when the user releases the switch
 
898
        while (IsPressed()) {
756
899
                _delay_ms(16);
757
900
        }
758
901
        PCINT_on();
759
 
        // Enable sleep mode set to Power Down that will be triggered by the sleep_mode() command.
760
 
        //set_sleep_mode(SLEEP_MODE_PWR_DOWN);
761
 
        // Now go to sleep
762
 
        sleep_mode();
763
 
        // Hey, someone must have pressed the switch!!
764
 
        // Disable pin change interrupt because it's only used to wake us up
765
 
        PCINT_off();
766
 
        // Turn the WDT back on to check for switch presses
767
 
        WDT_on();
768
 
        // Go back to main program
769
 
}
 
902
        
 
903
        //-----------------------------------------
 
904
        sleep_mode();   // Now go to sleep
 
905
        //-----------------------------------------
 
906
                                                // Alternate method? --> set_sleep_mode(SLEEP_MODE_PWR_DOWN);
 
907
        
 
908
                                                // Hey, someone must have pressed the switch!!
 
909
        
 
910
        
 
911
        PCINT_off();    // Disable pin change interrupt because it's only used to wake us up
 
912
 
 
913
        ADC_on();               // Turn the AtoD back ON
 
914
        
 
915
        WDT_on();               // Turn the WDT back on to check for switch presses
 
916
        
 
917
}       // Go back to main program
770
918
 
771
919
/**************************************************************************************
772
920
* LoadConfig - gets the configuration settings from EEPROM
774
922
*  config1 - 1st byte of stored configuration settings:
775
923
*   bits 0-2: mode index (0..7), for clicky mode switching
776
924
*   bits 3-6: selected mode set (0..11)
 
925
*   bit 7:    ramping mode
777
926
*
778
927
*  config2 - 2nd byte of stored configuration settings:
779
928
*   bit    0: mode ordering, 1=hi to lo, 0=lo to hi
787
936
*   bit    2: Locator LED feature (ON when light is OFF) - 1=enabled, 0=disabled
788
937
*   bit    3: BVLD LED Only - 1=BVLD only w/onboard LED, 0=both primary and onboard LED's are used
789
938
*   bit    4: 1: moonlight mode - 1=enabled, 0=disabled
 
939
*   bit  5-6: blinky mode config: 1=strobe only, 2=all blinkies, 0=disable
790
940
*
791
941
**************************************************************************************/
792
942
inline void LoadConfig()
793
943
{
794
 
   byte config1, config2, config3;
795
944
 
796
945
   // find the config data
797
946
   for (eepos=0; eepos < 128; eepos+=3)
810
959
        {
811
960
           modeIdx = config1 & 0x7;
812
961
                modeSetIdx = (config1 >> 3) & 0x0f;
 
962
                ramping = (config1 >> 7);
813
963
                
814
964
           highToLow = config2 & 1;
815
965
           modeMemoryEnabled = (config2 >> 1) & 1;
821
971
                locatorLedOn = (config3 >> 2) & 1;
822
972
                bvldLedOnly = (config3 >> 3) & 1;
823
973
                moonLightEnable = (config3 >> 4) & 1;
 
974
                blinkyMode = (config3 >> 5) & 0x03;
824
975
        }
825
976
        else
826
977
                eepos = 0;
 
978
 
 
979
        locatorLed = locatorLedOn;
827
980
}
828
981
 
829
982
/**************************************************************************************
834
987
*  config1 - 1st byte of stored configuration settings:
835
988
*   bits 0-2: mode index (0..7), for clicky mode switching
836
989
*   bits 3-6: selected mode set (0..11)
 
990
*   bit 7:    ramping mode
837
991
*
838
992
*  config2 - 2nd byte of stored configuration settings:
839
993
*   bit    0: mode ordering, 1=hi to lo, 0=lo to hi
847
1001
*   bit    2: Locator LED feature (ON when light is OFF) - 1=enabled, 0=disabled
848
1002
*   bit    3: BVLD LED Only - 1=BVLD only w/onboard LED, 0=both primary and onboard LED's are used
849
1003
*   bit    4: 1: moonlight mode - 1=enabled, 0=disabled
 
1004
*   bit  5-6: blinky mode config: 1=strobe only, 2=all blinkies, 0=disable
850
1005
*
851
1006
**************************************************************************************/
852
1007
void SaveConfig()
853
1008
{  
854
1009
        // Pack all settings into one byte
855
 
        byte config1 = (byte)(word)(modeIdx | (modeSetIdx << 3));
856
 
        byte config2 = (byte)(word)(highToLow | (modeMemoryEnabled << 1) | (moonlightLevel << 2) | (turboTimeoutMode << 5));
857
 
        byte config3 = (byte)(word)(OffTimeEnable | (onboardLedEnable << 1) | (locatorLedOn << 2) | (bvldLedOnly << 3) | (moonLightEnable << 4));
 
1010
        config1 = (byte)(word)(modeIdx | (modeSetIdx << 3) | (ramping << 7));
 
1011
        config2 = (byte)(word)(highToLow | (modeMemoryEnabled << 1) | (moonlightLevel << 2) | (turboTimeoutMode << 5));
 
1012
        config3 = (byte)(word)(OffTimeEnable | (onboardLedEnable << 1) | (locatorLedOn << 2) | (bvldLedOnly << 3) | (moonLightEnable << 4) | (blinkyMode << 5));
858
1013
        
859
1014
        byte oldpos = eepos;
860
1015
        
895
1050
  #endif
896
1051
 
897
1052
        //---------------------------------------------------------------------------------------
 
1053
        //---------------------------------------------------------------------------------------
898
1054
   // Button is pressed
899
1055
        //---------------------------------------------------------------------------------------
900
 
        if (is_pressed())
 
1056
        //---------------------------------------------------------------------------------------
 
1057
        if (IsPressed())
901
1058
        {
902
 
                if (pressDuration < 255)
903
 
                        pressDuration++;
 
1059
                if (wPressDuration < 2000)
 
1060
                        wPressDuration++;
 
1061
 
 
1062
                        
 
1063
                //---------------------------------------------------------------------------------------
 
1064
                // Handle "button stuck" safety timeout
 
1065
                //---------------------------------------------------------------------------------------
 
1066
                if (wPressDuration == 1250)     // 20 seconds
 
1067
                {
 
1068
                        modeIdx = outLevel = rampingLevel = 0;
 
1069
                        rampState = 0;
 
1070
                        byLockOutSet = 1;               // set "LOCK OUT"
 
1071
                        ConfigMode = 0;
 
1072
                        return;
 
1073
                }
904
1074
                
905
1075
                //---------------------------------------------------------------------------------------
906
1076
                // Handle config mode specially right here:
911
1081
                        
912
1082
                        if (!holdHandled)
913
1083
                        {
914
 
                                if (pressDuration == 35)                // hold time for skipping: 35*16 = 560 msecs
 
1084
                                if (wPressDuration == 35)               // hold time for skipping: 35*16 = 560 msecs
915
1085
                                        ++ConfigMode;
916
 
                                else if (pressDuration == 70)   // hold time for bailing out: 70*16 = 1.1 secs
 
1086
                                else if (wPressDuration == 70)  // hold time for bailing out: 70*16 = 1.1 secs
917
1087
                                {
918
1088
                                        holdHandled = 1;                // suppress more hold events on this hold
919
 
                                        ConfigMode = 8;         // Exit Config mode
 
1089
                                        ConfigMode = 10;                // Exit Config mode
920
1090
                                }
921
1091
                        }
922
1092
                        return;
924
1094
 
925
1095
                if (!holdHandled)
926
1096
                {
 
1097
                        //------------------------------------------------------------------------------
 
1098
                        //      Ramping - pressed button
 
1099
                        //------------------------------------------------------------------------------
 
1100
                        if (ramping)
 
1101
                        {
 
1102
                                if ((wPressDuration > SHORT_CLICK_DUR) && !byLockOutSet && !byForceLockOut && (modeIdx != BATT_CHECK_MODE))
 
1103
                                {
 
1104
                                        switch (rampState)
 
1105
                                        {
 
1106
                                         case 0:                // ramping not initialized yet
 
1107
                                                if (rampingLevel == 0)
 
1108
                                                {
 
1109
                                                        rampState = 1;
 
1110
                                                        rampPauseCntDn = RAMP_MOON_PAUSE;               // delay a little on moon
 
1111
 
 
1112
                                                        SetOutput(0,moonlightLevel);
 
1113
                                                        if (locatorLed)
 
1114
                                                                TurnOnBoardLed(0);
 
1115
                                                                
 
1116
                                                        // set this to the 1st level for the current mode
 
1117
                                                        outLevel = rampingLevel = 255;
 
1118
                                                }
 
1119
                                                else
 
1120
                                                {
 
1121
                                                        rampState = 2;
 
1122
                                                        if (rampingLevel == MAX_RAMP_LEVEL)
 
1123
                                                        {
 
1124
                                                                rampState = 3;  // hi->lo
 
1125
                                                                outLevel = rampingLevel = MAX_RAMP_LEVEL;
 
1126
                                                                SetLevel(outLevel);
 
1127
                                                        }
 
1128
                                                        else if (rampingLevel == 255)   // If stopped in ramping moon mode, start from lowest
 
1129
                                                        {
 
1130
                                                                outLevel = rampingLevel = 1;
 
1131
                                                                SetLevel(outLevel);
 
1132
                                                        }
 
1133
                                                }
 
1134
                                                break;
 
1135
                                                
 
1136
                                         case 1:                // in moon mode
 
1137
                                                if (--rampPauseCntDn == 0)
 
1138
                                                {
 
1139
                                                        rampState = 2;
 
1140
                                                        outLevel = rampingLevel = 1;
 
1141
                                                        SetLevel(outLevel);
 
1142
                                                }
 
1143
                                                break;
 
1144
                                                
 
1145
                                         case 2:                // lo->hi
 
1146
                                                if (rampingLevel < MAX_RAMP_LEVEL)
 
1147
                                                {
 
1148
                                                        outLevel = ++rampingLevel;
 
1149
                                                }
 
1150
                                                else
 
1151
                                                        rampState = 4;
 
1152
                                                SetLevel(outLevel);
 
1153
                                                break;
 
1154
                                                
 
1155
                                         case 3:                // hi->lo
 
1156
                                                if (rampingLevel > 1)
 
1157
                                                {
 
1158
                                                        outLevel = --rampingLevel;
 
1159
                                                }
 
1160
                                                else
 
1161
                                                        rampState = 4;
 
1162
                                                SetLevel(outLevel);
 
1163
                                                break;
 
1164
                                        
 
1165
                                         case 4:                // ramping ended - 0 or max reached
 
1166
                                                break;
 
1167
                                                
 
1168
                                        } // switch on rampState
 
1169
                                        
 
1170
                                } // switch help longer than single click
 
1171
                                
 
1172
                        } // ramping
 
1173
                        
927
1174
                        //---------------------------------------------------------------------------------------
928
1175
                        // LONG hold - for previous mode
929
1176
                        //---------------------------------------------------------------------------------------
930
 
                        if ((pressDuration == LONG_PRESS_DUR) && (byLockOutSet == 0))
 
1177
                        if (!ramping && (wPressDuration == LONG_PRESS_DUR) && !byLockOutSet)
931
1178
                        {
932
1179
                                if (modeIdx < 16)
933
1180
                                {
934
1181
                                        // Long press
935
1182
                                        if (highToLow)
936
 
                                                next_mode();
 
1183
                                                NextMode();
937
1184
                                        else
938
 
                                                prev_mode();
 
1185
                                                PrevMode();
939
1186
                                }
940
1187
                                else if (modeIdx > SPECIAL_MODES)
941
1188
                                {
952
1199
                        //---------------------------------------------------------------------------------------
953
1200
                        // XLONG hold - for strobes, battery check, or lock-out (depending on preceding quick clicks)
954
1201
                        //---------------------------------------------------------------------------------------
955
 
                        if (pressDuration == XLONG_PRESS_DUR)
 
1202
                        if (wPressDuration == XLONG_PRESS_DUR)
956
1203
                        {
957
1204
                                if ((byLockOutEnable == 1) && (quickClicks == 2) && (wIdleTicks < LOCK_OUT_TICKS))
958
1205
                                {
959
 
                                        modeIdx = 0;
960
 
                                        byLockOutSet = 1 - byLockOutSet;                // invert "LOCK OUT"
 
1206
                                  #ifndef ADV_RAMP_OPTIONS
 
1207
                                        if (!ramping || (byLockOutSet == 1))
 
1208
                                  #endif
 
1209
                                        {
 
1210
                                                modeIdx = outLevel = rampingLevel = 0;
 
1211
                                                rampState = 0;
 
1212
                                                byLockOutSet = 1 - byLockOutSet;                // invert "LOCK OUT"
 
1213
                                                byForceLockOut = 1;             // force lockout button actions
 
1214
                                        }
961
1215
                                }
962
1216
                                else if (byLockOutSet == 0)
963
1217
                                {
964
1218
                                        if ((quickClicks == 1) && (wIdleTicks < LOCK_OUT_TICKS))
965
1219
                                        {
966
 
                                                modeIdx = BATT_CHECK_MODE;
 
1220
                                          #ifndef ADV_RAMP_OPTIONS
 
1221
                                                if (!ramping)
 
1222
                                          #endif
 
1223
                                                {
 
1224
                                                        modeIdx = BATT_CHECK_MODE;
 
1225
                                                        byForceLockOut = 1;             // force lockout button actions
 
1226
                                                        PWM_LVL = 0;                            // suppress main LED output
 
1227
                                                        ALT_PWM_LVL = 0;
 
1228
                                                }
967
1229
                                        }
968
1230
                                        else if (modeIdx > SPECIAL_MODES)
969
1231
                                        {
974
1236
                                                modeIdx = 0;            // clear main mode
975
1237
                                                PWM_LVL = 0;            // suppress main LED output
976
1238
                                                ALT_PWM_LVL = 0;
977
 
                                
 
1239
                        
978
1240
                                                ConfigMode = 21;                // Initialize Advanced Config mode
979
1241
                                                configClicks = 0;
980
1242
                                                holdHandled = 1;                // suppress more hold events on this hold
981
1243
                                        }
982
 
                                        else
 
1244
                                        else if (!ramping && (blinkyMode > 0))
983
1245
                                        {
984
1246
                                                // Engage first special mode!
985
1247
                                                specModeIdx = 0;
986
1248
                                                modeIdx = specialModes[specModeIdx];
987
 
                                                        
 
1249
                                                
988
1250
                                                TurnOnBoardLed(0);      // be sure the on board LED is OFF here
989
1251
                                        }
990
1252
                                }
993
1255
                        //---------------------------------------------------------------------------------------
994
1256
                        // CONFIG hold - if it is not locked out or lock-out was just exited on this hold
995
1257
                        //---------------------------------------------------------------------------------------
996
 
                        if ((pressDuration == CONFIG_ENTER_DUR) && (byLockOutSet == 0) && (quickClicks != 2))
997
 
                        {
998
 
                                modeIdx = 0;
999
 
                                // turn the light off initially
1000
 
//                              TCCR0A = PHASE;
1001
 
                                PWM_LVL = 0;
1002
 
                                ALT_PWM_LVL = 0;
1003
 
                                        
1004
 
                                ConfigMode = 1;
1005
 
                                configClicks = 0;
1006
 
                        }
 
1258
                        if (byLockOutSet == 0)
 
1259
                        {
 
1260
                                if ((!ramping && (wPressDuration == CONFIG_ENTER_DUR) && (quickClicks != 2))
 
1261
                                                                                        ||
 
1262
                                         (ramping && (wPressDuration == 500)))  // 8 secs in ramping mode
 
1263
                                {
 
1264
                                        modeIdx = 0;
 
1265
                                        rampingLevel = 0;
 
1266
                                        rampState = 0;
 
1267
                                        
 
1268
                                        // turn the light off initially
 
1269
                                        PWM_LVL = 0;
 
1270
                                        ALT_PWM_LVL = 0;
 
1271
                                
 
1272
                                        ConfigMode = 1;
 
1273
                                        configClicks = 0;
 
1274
                                }
 
1275
                        }
1007
1276
                }
1008
1277
 
1009
1278
                wTurboTicks = 0;                // Just always reset turbo timer whenever the button is pressed
1016
1285
        }
1017
1286
        
1018
1287
        //---------------------------------------------------------------------------------------
 
1288
        //---------------------------------------------------------------------------------------
1019
1289
   // Not pressed (debounced qualified)
1020
1290
        //---------------------------------------------------------------------------------------
 
1291
        //---------------------------------------------------------------------------------------
1021
1292
        else
1022
1293
        {
1023
1294
                holdHandled = 0;                // free up any hold suppressed state
1024
1295
 
1025
1296
                if (ConfigMode > 0)
1026
1297
                {
1027
 
                        if (pressDuration > 0)
 
1298
                        if (wPressDuration > 0)
1028
1299
                        {
1029
 
                                if (pressDuration < LONG_PRESS_DUR)
 
1300
                                if (wPressDuration < LONG_PRESS_DUR)
1030
1301
                                        ++configClicks;
1031
1302
                                configIdleTime = 0;
1032
1303
                        }
1034
1305
                        {
1035
1306
                                ++configIdleTime;
1036
1307
                        }
1037
 
                        pressDuration = 0;
 
1308
                        wPressDuration = 0;
1038
1309
                } // config mode
1039
1310
                
1040
 
                else if (pressDuration > 0)
 
1311
                else if (wPressDuration > 0)
1041
1312
                {
1042
1313
                // Was previously pressed
1043
 
                        if (pressDuration < LONG_PRESS_DUR)
 
1314
 
 
1315
                        //------------------------------------------------------------------------------
 
1316
                        //      Ramping - button released
 
1317
                        //------------------------------------------------------------------------------
 
1318
                        if (ramping)
 
1319
                        {
 
1320
                                rampState = 0;  // reset state to not ramping
 
1321
                                
 
1322
                                if (wPressDuration < SHORT_CLICK_DUR)
 
1323
                                {
 
1324
                                        // normal short click
 
1325
                                        if (modeIdx == BATT_CHECK_MODE)         // battery check - reset to OFF
 
1326
                                                modeIdx = 0;
 
1327
                                        else
 
1328
                                        {
 
1329
                                                // track quick clicks in a row from OFF or ON (doesn't matter in ramping)
 
1330
                                                ++quickClicks;
 
1331
                                        }
 
1332
 
 
1333
                                        if (!byLockOutSet)
 
1334
                                        {
 
1335
                                          #ifdef TRIPLE_CLICK_LOC       
 
1336
                                                if (quickClicks == 3)   // triple click: toggle the locator LED
 
1337
                                                {
 
1338
                                                        locatorLed = 1 - locatorLed;
 
1339
                                                        TurnOnBoardLed(locatorLed);
 
1340
                                                }
 
1341
                                          #endif
 
1342
 
 
1343
                                          #ifdef TRIPLE_CLICK_BATT
 
1344
                                          if (quickClicks == 3)         // triple click: display battery check/status
 
1345
                                          {
 
1346
                                                        modeIdx = BATT_CHECK_MODE;
 
1347
                                                        byForceLockOut = 1;             // force lockout button actions
 
1348
                                                        PWM_LVL = 0;                            // suppress main LED output
 
1349
                                                        ALT_PWM_LVL = 0;
 
1350
                                          }
 
1351
                                          #endif
 
1352
 
 
1353
                                                if (quickClicks == 2)           // double click: set to MAX level
 
1354
                                                {
 
1355
                                                        rampingLevel = MAX_RAMP_LEVEL;
 
1356
                                                        outLevel = rampingLevel;
 
1357
                                                        SetLevel(outLevel);
 
1358
                                                }
 
1359
 
 
1360
                                                else if (!byForceLockOut)
 
1361
                                                {
 
1362
                                                        if (rampingLevel == 0)  // light is OFF, turn it ON
 
1363
                                                        {
 
1364
                                                                if (savedLevel == 0)
 
1365
                                                                        savedLevel = 1;
 
1366
                                                                
 
1367
                                                                // Restore the saved level (last mode memory)
 
1368
                                                                outLevel = rampingLevel = savedLevel;
 
1369
                                                        }
 
1370
                                                        else                                    // light is ON, turn it OFF
 
1371
                                                        {
 
1372
                                                                savedLevel = rampingLevel;
 
1373
                                                                outLevel = rampingLevel = 0;
 
1374
                                                        }
 
1375
                                                        if (outLevel == 255)
 
1376
                                                        {
 
1377
                                                                SetOutput(0,moonlightLevel);
 
1378
                                                                if (locatorLed)
 
1379
                                                                TurnOnBoardLed(1);
 
1380
                                                        }
 
1381
                                                        else
 
1382
                                                                SetLevel(outLevel);
 
1383
                                                }
 
1384
                                        } // !byLockOutSet
 
1385
                                } // short click
 
1386
                                else
 
1387
                                        quickClicks = 0;        // reset quick clicks for long holds
 
1388
                                
 
1389
                                wPressDuration = 0;
 
1390
                        } // ramping
 
1391
 
 
1392
                        else if (wPressDuration < LONG_PRESS_DUR)
1044
1393
                        {
1045
1394
                                // normal short click
1046
1395
                                if (modeIdx == BATT_CHECK_MODE)         // battery check - reset to OFF
1072
1421
                                                        {
1073
1422
                                                                // Short press - normal modes
1074
1423
                                                                if (highToLow)
1075
 
                                                                        prev_mode();
 
1424
                                                                        PrevMode();
1076
1425
                                                                else
1077
 
                                                                        next_mode();
 
1426
                                                                        NextMode();
1078
1427
                                                        }
1079
1428
                                                }
1080
1429
                                                else  // special modes
1081
1430
                                                {
 
1431
                                                        // Bail out if timed out the click
1082
1432
                                                        if (wIdleTicks >= IDLE_TIME)
1083
1433
                                                                modeIdx = prevModeIdx;
 
1434
                                                                
 
1435
                                                        // Bail out if configured for only one blinky mode
 
1436
                                                        else if (blinkyMode == 1)
 
1437
                                                                modeIdx = prevModeIdx;
 
1438
                                                                
 
1439
                                                        // Bail out if at last blinky mode
1084
1440
                                                        else if (++specModeIdx > specialModesCnt)
1085
 
                                                                modeIdx = prevModeIdx;  // bail out of special modes
 
1441
                                                                modeIdx = prevModeIdx;
1086
1442
                                                        else
1087
1443
                                                                modeIdx = specialModes[specModeIdx];
1088
1444
                                                }
1089
1445
                                        }
1090
1446
                                } // ...
1091
1447
 
1092
 
                                pressDuration = 0;
 
1448
                                wPressDuration = 0;
1093
1449
                        } // short click
 
1450
                        else
 
1451
                        {
 
1452
                                if (wPressDuration < XLONG_PRESS_DUR)
 
1453
                                {
 
1454
                                        // Special Locator LED toggle sequence: quick click then click&hold
 
1455
                                        if ((quickClicks == 1) && (wIdleTicks < LOCK_OUT_TICKS) && (modeIdx == 0))
 
1456
                                        {
 
1457
                                                locatorLed = 1 - locatorLed;
 
1458
                                                TurnOnBoardLed(locatorLed);
 
1459
                                        }
 
1460
                                }
 
1461
                                quickClicks = 0;        // reset quick clicks for long holds
 
1462
                        }
1094
1463
                        
1095
1464
                        wIdleTicks = 0; // reset idle time
1096
1465
 
1097
1466
                } // previously pressed
1098
1467
                else
1099
1468
                {
1100
 
                        //------------------------------------
 
1469
                        //---------------------------------------------------------------------------------------
 
1470
                        //---------------------------------------------------------------------------------------
1101
1471
                        // Not previously pressed
1102
 
                        //------------------------------------
 
1472
                        //---------------------------------------------------------------------------------------
 
1473
                        //---------------------------------------------------------------------------------------
1103
1474
                        if (++wIdleTicks == 0)
1104
1475
                                wIdleTicks = 30000;             // max it out at 30,000 (8 minutes)
1105
1476
 
1107
1478
                                quickClicks = 0;
1108
1479
 
1109
1480
                        // Only do turbo check when switch isn't pressed
1110
 
                        if ((turboTimeoutMode > 0) && (modeIdx < 16))
1111
 
                                if (byPrimModes[modeIdx] == 255)
1112
 
                                {
1113
 
                                        if (++wTurboTicks > wTurboTickLimit)
1114
 
                                                prev_mode();            // Go to the previous mode
1115
 
                                }
1116
 
 
 
1481
                        if (turboTimeoutMode > 0)
 
1482
                        {
 
1483
                                if (ramping)  // ramping
 
1484
                                {
 
1485
                                        if (outLevel > TURBO_DROP_MIN)
 
1486
                                                if (++wTurboTicks > wTurboTickLimit)
 
1487
                                                {
 
1488
                                                        outLevel = rampingLevel = TURBO_DROP_SET;
 
1489
                                                        SetLevel(outLevel);
 
1490
                                                }
 
1491
                                }
 
1492
                                else          // regular modes
 
1493
                                {
 
1494
                                        if (modeIdx < 16)
 
1495
                                                if (byPrimModes[modeIdx] == 255)
 
1496
                                                {
 
1497
                                                        if (++wTurboTicks > wTurboTickLimit)
 
1498
                                                                PrevMode();             // Go to the previous mode
 
1499
                                                }
 
1500
                                }
 
1501
                        }
 
1502
                        
1117
1503
                        // Only do voltage monitoring when the switch isn't pressed
1118
1504
                  #ifdef VOLTAGE_MON
1119
1505
                        if (adc_ticks > 0)
1123
1509
                                // See if conversion is done
1124
1510
                                if (ADCSRA & (1 << ADIF))
1125
1511
                                {
 
1512
                                        byte atLowLimit;
 
1513
                                        if (ramping)
 
1514
                                                atLowLimit = (outLevel == 1);
 
1515
                                        else
 
1516
                                                atLowLimit = (modeIdx == 1);
 
1517
                                        
1126
1518
                                        // See if voltage is lower than what we were looking for
1127
 
                                        if (ADCH < ((modeIdx == 1) ? ADC_CRIT : ADC_LOW))
 
1519
                                        if (ADCH < (atLowLimit ? ADC_CRIT : ADC_LOW))
1128
1520
                                                ++lowbatt_cnt;
1129
1521
                                        else
1130
1522
                                                lowbatt_cnt = 0;
1159
1551
                  #endif
1160
1552
                } // not previously pressed
1161
1553
                
1162
 
                pressDuration = 0;
 
1554
                wPressDuration = 0;
1163
1555
        } // Not pressed
1164
1556
}
1165
1557
 
1204
1596
 
1205
1597
        wTurboTickLimit = pgm_read_word(turboTimeOutVals+turboTimeoutMode);
1206
1598
        
1207
 
        if (OffTimeEnable)
 
1599
        if (OffTimeEnable && !ramping)
1208
1600
        {
1209
1601
                if (!noinit_decay)
1210
1602
                {
1211
1603
                        // Indicates they did a short press, go to the next mode
1212
 
                        next_mode(); // Will handle wrap arounds
 
1604
                        NextMode(); // Will handle wrap arounds
1213
1605
                        SaveConfig();
1214
1606
                }
1215
1607
        }
1220
1612
                
1221
1613
        if (modeIdx == 0)
1222
1614
        {
1223
 
//         TCCR0A = PHASE;
1224
 
                blink(2, 80);
 
1615
                Blink(2, 80);
1225
1616
        }
1226
1617
 
1227
1618
        // set noinit data for next boot
1234
1625
   byte prevConfigClicks = 0;
1235
1626
 
1236
1627
        WDT_on();               // Turn it on now (mode can be non-zero on startup)
1237
 
        
1238
 
    //  We will never leave this loop.  The WDT will interrupt to check for switch presses
1239
 
    // and will change the mode if needed. If this loop detects that the mode has changed,
1240
 
    // run the logic for that mode while continuing to check for a mode change.
 
1628
 
 
1629
        //------------------------------------------------------------------------------------
 
1630
        //------------------------------------------------------------------------------------  
 
1631
        //  We will never leave this loop.  The WDT will interrupt to check for switch presses
 
1632
        // and will change the mode if needed. If this loop detects that the mode has changed,
 
1633
        // run the logic for that mode while continuing to check for a mode change.
 
1634
        //------------------------------------------------------------------------------------
 
1635
        //------------------------------------------------------------------------------------
1241
1636
        while(1)                // run forever
1242
1637
        {
1243
1638
      //---------------------------------------------------------------------------------------
1248
1643
                        {
1249
1644
                                byPrevLockOutSet = byLockOutSet;
1250
1645
 
1251
 
                                set_output(0,0);
 
1646
                                SetOutput(0,0);
1252
1647
                                _delay_ms(250);
1253
 
                                blink(4, 60);
 
1648
                                Blink(4, 60);
 
1649
                                
 
1650
                                byForceLockOut = 0;             // release the forced lockout
 
1651
                                
 
1652
                                if (byLockOutSet)
 
1653
                                        last_modeIdx = modeIdx; // entering - no need to configure mode 0 (keep the locator LED off)
 
1654
                                else
 
1655
                                        last_modeIdx = 255;             // exiting - force a mode handling to turn on locator LED
1254
1656
                        }
1255
1657
 
 
1658
                        //---------------------------------------------------
 
1659
                        // Mode Handling - did the WDT change the mode?
 
1660
                        //---------------------------------------------------
1256
1661
                        if (modeIdx != last_modeIdx)
1257
1662
                        {
1258
 
                                //---------------------------------------------------
1259
 
                                // Mode Handling - The WDT changed the mode
1260
 
                                //---------------------------------------------------
1261
1663
                                if (modeIdx < 16)
1262
1664
                                {
1263
 
                                        set_mode(modeIdx);      // Set a solid mode here!!
 
1665
                                        SetMode(modeIdx);      // Set a solid mode here!!
1264
1666
                                        last_modeIdx = modeIdx;
1265
1667
                                }
1266
1668
                                else
1272
1674
 
1273
1675
                                        if (modeIdx == BATT_CHECK_MODE)
1274
1676
                                        {
1275
 
//                                              TCCR0A = PHASE;   // set all output for PHASE mode
 
1677
                                                if (ramping)
 
1678
                                                {
 
1679
                                                        PWM_LVL = 0;                            // suppress main LED output
 
1680
                                                        ALT_PWM_LVL = 0;
 
1681
                                                        _delay_ms(250);
 
1682
                                                }
 
1683
                                                byForceLockOut = 0;             // release the forced lockout
 
1684
 
 
1685
                                                
1276
1686
                                                while (modeIdx == BATT_CHECK_MODE)      // Battery Check
1277
1687
                                                {
1278
1688
                                                        // blink out volts and tenths
1279
 
                                                        uint8_t result = battcheck();
1280
 
                                                        battBlink(result >> 5);
 
1689
                                                        uint8_t result = BattCheck();
 
1690
                                                        BattBlink(result >> 5);
1281
1691
                                                        if (modeIdx != BATT_CHECK_MODE)         break;
1282
1692
                                                        _delay_ms(800);
1283
 
                                                        battBlink(result & 0b00011111);
 
1693
                                                        BattBlink(result & 0b00011111);
1284
1694
                                                        if (modeIdx != BATT_CHECK_MODE)         break;
1285
1695
                                                        _delay_ms(2000);
1286
1696
                                                }
1288
1698
 
1289
1699
                                        else if (modeIdx == STROBE_MODE)
1290
1700
                                        {
1291
 
//                                              TCCR0A = PHASE;   // set all output for PHASE mode
1292
1701
                                                while (modeIdx == STROBE_MODE)      // strobe at 16 Hz
1293
1702
                                                {
1294
 
                                                        strobe(16,47);          // 20,60 is 12.5 Hz
 
1703
                                                        Strobe(16,47);          // 20,60 is 12.5 Hz
1295
1704
                                                }
1296
1705
                                        }
1297
1706
 
1298
1707
#if RANDOM_STROBE
1299
1708
                                        else if (modeIdx == RANDOM_STROBE)
1300
1709
                                        {
1301
 
//                                              TCCR0A = PHASE;   // set all output for PHASE mode
1302
1710
                                                while (modeIdx == RANDOM_STROBE)                // pseudo-random strobe
1303
1711
                                                {
1304
1712
                                                        byte ms = 34 + (pgm_rand() & 0x3f);
1305
 
                                                        strobe(ms, ms);
1306
 
                                                        strobe(ms, ms);
 
1713
                                                        Strobe(ms, ms);
 
1714
                                                        Strobe(ms, ms);
1307
1715
                                                }
1308
1716
                                        }
1309
1717
#endif
1310
1718
 
1311
1719
                                        else if (modeIdx == POLICE_STROBE)
1312
1720
                                        {
1313
 
//                                              TCCR0A = PHASE;   // set all output for PHASE mode
1314
1721
                                                while (modeIdx == POLICE_STROBE)                // police strobe
1315
1722
                                                {
1316
1723
                                                        for(i=0;i<8;i++)
1317
1724
                                                        {
1318
1725
                                                                if (modeIdx != POLICE_STROBE)           break;
1319
 
                                                                strobe(20,40);
 
1726
                                                                Strobe(20,40);
1320
1727
                                                        }
1321
1728
                                                        for(i=0;i<8;i++)
1322
1729
                                                        {
1323
1730
                                                                if (modeIdx != POLICE_STROBE)           break;
1324
 
                                                                strobe(40,80);
 
1731
                                                                Strobe(40,80);
1325
1732
                                                        }
1326
1733
                                                }
1327
1734
                                        }
1328
1735
 
1329
1736
                                        else if (modeIdx == BIKING_STROBE)
1330
1737
                                        {
1331
 
//                                              TCCR0A = PHASE;   // set all output for PHASE mode
1332
1738
                                                while (modeIdx == BIKING_STROBE)                // police strobe
1333
1739
                                                {
1334
1740
                                                        // normal version
1335
1741
                                                        for(i=0;i<4;i++)
1336
1742
                                                        {
1337
1743
                                                                if (modeIdx != BIKING_STROBE)           break;
1338
 
                                                                set_output(255,0);
 
1744
                                                                SetOutput(255,0);
1339
1745
                                                                _delay_ms(5);
1340
 
                                                                set_output(0,255);
 
1746
                                                                SetOutput(0,255);
1341
1747
                                                                _delay_ms(65);
1342
1748
                                                        }
1343
1749
                                                        for(i=0;i<10;i++)
1346
1752
                                                                _delay_ms(72);
1347
1753
                                                        }
1348
1754
                                                }
1349
 
                                                set_output(0,0);
 
1755
                                                SetOutput(0,0);
1350
1756
                                        }
1351
1757
 
1352
1758
                                        else if (modeIdx == BEACON_2S_MODE)
1353
1759
                                        {
1354
 
//                                              TCCR0A = PHASE;   // set all output for PHASE mode
1355
1760
                                                while (modeIdx == BEACON_2S_MODE)               // Beacon 2 sec mode
1356
1761
                                                {
1357
1762
                                                        _delay_ms(300); // pause a little initially
1358
1763
                                                
1359
 
                                                        strobe(125,125);                // two flash's
1360
 
                                                        strobe(125,125);
 
1764
                                                        Strobe(125,125);                // two flash's
 
1765
                                                        Strobe(125,125);
1361
1766
                                                
1362
1767
                                                        for (i=0; i < 15; i++)  // 1.5 secs delay
1363
1768
                                                        {
1370
1775
                                        else if (modeIdx == BEACON_10S_MODE)
1371
1776
                                                while (modeIdx == BEACON_10S_MODE)              // Beacon 10 sec mode
1372
1777
                                                {
1373
 
//                                                      TCCR0A = PHASE;   // set all output for PHASE mode
1374
 
 
1375
1778
                                                        _delay_ms(300); // pause a little initially
1376
1779
 
1377
 
                                                        strobe(240,240);                // two slow flash's
1378
 
                                                        strobe(240,240);
 
1780
                                                        Strobe(240,240);                // two slow flash's
 
1781
                                                        Strobe(240,240);
1379
1782
 
1380
1783
                                                        for (i=0; i < 100; i++) // 10 secs delay
1381
1784
                                                        {
1390
1793
                        // Perform low battery indicator tests
1391
1794
                        if (LowBattSignal)
1392
1795
                        {
1393
 
                                if (modeIdx > 0)
1394
 
                                {
1395
 
                                        // Flash 3 times before lowering
1396
 
                                        byte i = 0;
1397
 
                                        while (i++<3)
 
1796
                                if (ramping)
 
1797
                                {
 
1798
                                        if (outLevel > 0)
 
1799
                                        {
 
1800
                                                // Flash 3 times before lowering
 
1801
                                                byte i = 0;
 
1802
                                                while (i++<3)
 
1803
                                                {
 
1804
                                                        SetOutput(0,0);
 
1805
                                                        _delay_ms(250);
 
1806
                                                        TurnOnBoardLed(1);
 
1807
                                                        SetLevel(outLevel);
 
1808
                                                        _delay_ms(500);
 
1809
                                                        TurnOnBoardLed(0);
 
1810
                                                }
 
1811
                                        
 
1812
                                                if (outLevel == 1)
 
1813
                                                        outLevel = 0;
 
1814
                                                else if (outLevel > MAX_RAMP_LEVEL/8)
 
1815
                                                        outLevel -= MAX_RAMP_LEVEL/8;
 
1816
                                                else
 
1817
                                                        outLevel = 1;
 
1818
                                                SetLevel(outLevel);
 
1819
                                        }
 
1820
                                }
 
1821
                                else   // Not ramping
 
1822
                                {
 
1823
                                        if (modeIdx > 0)
1398
1824
                                        {
1399
 
                                                set_output(0,0);
1400
 
                                                _delay_ms(250);
1401
 
                                                TurnOnBoardLed(1);
1402
 
                                                set_output(currOutLvl1, currOutLvl2);
1403
 
                                                _delay_ms(500);
1404
 
                                                TurnOnBoardLed(0);
 
1825
                                                // Flash 3 times before lowering
 
1826
                                                byte i = 0;
 
1827
                                                while (i++<3)
 
1828
                                                {
 
1829
                                                        SetOutput(0,0);
 
1830
                                                        _delay_ms(250);
 
1831
                                                        TurnOnBoardLed(1);
 
1832
                                                        SetOutput(currOutLvl1, currOutLvl2);
 
1833
                                                        _delay_ms(500);
 
1834
                                                        TurnOnBoardLed(0);
 
1835
                                                }
 
1836
                                                if (modeIdx < 16)
 
1837
                                                        PrevMode();
1405
1838
                                        }
1406
 
                                        
1407
 
                                        if (modeIdx < 16)
1408
 
                                                prev_mode();
1409
1839
                                }
 
1840
                                
1410
1841
                                LowBattSignal = 0;
1411
1842
                        }
1412
1843
                        else if (LowBattBlinkSignal)
1414
1845
                                // Blink the Indicator LED twice
1415
1846
                                if (onboardLedEnable)
1416
1847
                                {
1417
 
                                        if ((modeIdx > 0) || (locatorLedOn == 0))
 
1848
                                        if ((modeIdx > 0) || (locatorLed == 0))
1418
1849
                                        {
1419
1850
                                                TurnOnBoardLed(1);
1420
1851
                                                _delay_ms(500);
1444
1875
                        if (LowBattState)
1445
1876
                                wWaitTicks = 22500;     // 6 minutes
1446
1877
                        
1447
 
                        if ((modeIdx == 0) && !is_pressed() && (wIdleTicks > wWaitTicks))
 
1878
                        if (((!ramping && (modeIdx == 0)) || (ramping && outLevel == 0))
 
1879
                                                                         &&
 
1880
                                 !IsPressed() && (wIdleTicks > wWaitTicks))
1448
1881
                        {
1449
1882
                                // If the battery is currently low, then turn OFF the indicator LED before going to sleep
1450
1883
                                //  to help in saving the battery
1451
 
                                if (get_voltage() < ADC_LOW)
1452
 
                                        if (locatorLedOn)
 
1884
                                if (GetVoltage() < ADC_LOW)
 
1885
                                        if (locatorLed)
1453
1886
                                                TurnOnBoardLed(0);
1454
1887
                                
1455
1888
                                wIdleTicks = 0;
1456
1889
                                _delay_ms(1); // Need this here, maybe instructions for PWM output not getting executed before shutdown?
1457
 
                                sleep_until_switch_press();     // Go to sleep
 
1890
                                SleepUntilSwitchPress();        // Go to sleep
1458
1891
                        }
1459
1892
                }
1460
1893
                
1466
1899
                        {
1467
1900
                                prevConfigClicks = configClicks;
1468
1901
                                if (configClicks > 0)
1469
 
                                        clickBlink();
 
1902
                                        ClickBlink();
1470
1903
                        }
1471
1904
                        
1472
1905
                        if (ConfigMode != prevConfigMode)
1479
1912
                                        case 1:
1480
1913
                                                _delay_ms(400);
1481
1914
 
1482
 
                                                configBlink(1);
 
1915
                                                ConfigBlink(1);
1483
1916
                                                ++ConfigMode;
1484
1917
                                                configClicks = 0;
1485
1918
                                                break;
1486
1919
                                                
1487
 
                                        case 3: // 1 - exiting mode set selection
 
1920
                                        case 3: // 1 - exiting ramping mode selection
 
1921
                                                if ((configClicks > 0) && (configClicks <= 8))
 
1922
                                                {
 
1923
                                                        ramping = 1 - (configClicks & 1);
 
1924
                                                        SaveConfig();
 
1925
                                                }
 
1926
                                                ConfigBlink(2);
 
1927
                                                configIdleTime = 0;
 
1928
                                                break;
 
1929
 
 
1930
                                        case 4: // 2 - exiting mode set selection
1488
1931
                                                if ((configClicks > 0) && (configClicks <= 8))
1489
1932
                                                {
1490
1933
                                                        modeSetIdx = configClicks - 1;
1491
1934
                                                        DefineModeSet();
1492
1935
                                                        SaveConfig();
1493
1936
                                                }
1494
 
                                                configBlink(2);
 
1937
                                                ConfigBlink(3);
1495
1938
                                                configIdleTime = 0;
1496
1939
                                                break;
1497
1940
 
1498
 
                                        case 4: // 2 - exiting moonlight enabling
 
1941
                                        case 5: // 3 - exiting moonlight enabling
1499
1942
                                                if (configClicks)
1500
1943
                                                {
1501
1944
                                                        moonLightEnable = 1 - (configClicks & 1);
1502
1945
                                                        DefineModeSet();
1503
1946
                                                        SaveConfig();
1504
1947
                                                }
1505
 
                                                configBlink(3);
 
1948
                                                ConfigBlink(4);
1506
1949
                                                break;
1507
1950
 
1508
 
                                        case 5: // 3 - exiting mode order setting
 
1951
                                        case 6: // 4 - exiting mode order setting
1509
1952
                                                if (configClicks)
1510
1953
                                                {
1511
1954
                                                        highToLow = 1 - (configClicks & 1);
1512
1955
                                                        SaveConfig();
1513
1956
                                                }
1514
 
                                                configBlink(4);
 
1957
                                                ConfigBlink(5);
1515
1958
                                                break;
1516
1959
 
1517
 
                                        case 6: // 4 - exiting mode memory setting
 
1960
                                        case 7: // 5 - exiting mode memory setting
1518
1961
                                                if (configClicks)
1519
1962
                                                {
1520
1963
                                                        modeMemoryEnabled = 1 - (configClicks & 1);
1521
1964
                                                        SaveConfig();
1522
1965
                                                }
1523
 
                                                configBlink(5);
 
1966
                                                ConfigBlink(6);
1524
1967
                                                break;
1525
1968
                                                
1526
 
                                        case 7: // 5 - exiting turbo timeout setting
 
1969
                                        case 8: // 6 - exiting turbo timeout setting
1527
1970
                                                if ((configClicks > 0) && (configClicks <= 8))
1528
1971
                                                {
1529
1972
                                                        turboTimeoutMode = configClicks - 1;
1532
1975
                                                        wTurboTickLimit = pgm_read_word(turboTimeOutVals+turboTimeoutMode);
1533
1976
                                                        SaveConfig();
1534
1977
                                                }
1535
 
                                                ConfigMode = 8;                 // all done, go to exit
1536
 
                                                break;
1537
 
 
1538
 
                                        case 8: // exiting config mode
 
1978
                                                ConfigBlink(7);
 
1979
                                                break;
 
1980
                                                
 
1981
                                        case 9: // 7 - exiting blinky mode setting (0=disable, 1=strobe only, 2=all blinkies)
 
1982
                                                if ((configClicks > 0) && (configClicks <= 3))
 
1983
                                                {
 
1984
                                                        blinkyMode = configClicks - 1;
 
1985
                                                        SaveConfig();
 
1986
                                                }
 
1987
                                                ConfigMode = 10;                        // all done, go to exit
 
1988
                                                break;
 
1989
                                        
 
1990
                                        case 10:        // exiting config mode
1539
1991
                                                ConfigMode = 0;         // Exit Config mode
1540
 
                                                blink(5, 40);
 
1992
                                                Blink(5, 40);
 
1993
                                                outLevel = rampingLevel = 0;
1541
1994
                                                modeIdx = 0;
1542
1995
                                                break;
1543
1996
 
1548
2001
                                        case 21:        // Start Adv Config mode
1549
2002
                                                _delay_ms(400);
1550
2003
 
1551
 
                                                configBlink(1);
 
2004
                                                ConfigBlink(1);
1552
2005
                                                ++ConfigMode;
1553
2006
                                                configClicks = 0;
1554
2007
                                                break;
1557
2010
                                                if (configClicks)
1558
2011
                                                {
1559
2012
                                                        locatorLedOn = 1 - (configClicks & 1);
 
2013
                                                        locatorLed = locatorLedOn;
1560
2014
                                                        SaveConfig();
1561
2015
                                                }
1562
 
                                                configBlink(2);
 
2016
                                                ConfigBlink(2);
1563
2017
                                                break;
1564
2018
                                                
1565
2019
                                        case 24:        // 2 - exiting moonlight level selection
1569
2023
                                                        DefineModeSet();
1570
2024
                                                        SaveConfig();
1571
2025
                                                }
1572
 
                                                configBlink(3);
 
2026
                                                ConfigBlink(3);
1573
2027
                                                break;
1574
2028
 
1575
2029
                                        case 25:        // 3 - exiting BVLD LED config selection
1578
2032
                                                        bvldLedOnly = 1 - (configClicks & 1);
1579
2033
                                                        SaveConfig();
1580
2034
                                                }
1581
 
                                                configBlink(4);
 
2035
                                                ConfigBlink(4);
1582
2036
                                                break;
1583
2037
                                        
1584
2038
                                        case 26:        // 4 - exiting Indicator LED enable selection
1587
2041
                                                        onboardLedEnable = 1 - (configClicks & 1);
1588
2042
                                                        SaveConfig();
1589
2043
                                                }
1590
 
                                                configBlink(5);
 
2044
                                                ConfigBlink(5);
1591
2045
                                                break;
1592
2046
                                        
1593
2047
                                        case 27:        // 5 - power tail switch modes w/mem selection
1596
2050
                                                        OffTimeEnable = 1 - (configClicks & 1);
1597
2051
                                                        SaveConfig();
1598
2052
                                                }
1599
 
                                                ConfigMode = 8;                 // all done, go to exit
 
2053
                                                ConfigMode = 10;                        // all done, go to exit
1600
2054
                                                break;
1601
2055
                                        
1602
2056
                                } // switch on new config mode