~toykeeper/flashlight-firmware/trunk

« back to all changes in this revision

Viewing changes to Flintrock/bistro-hd/bistro-HD.c

  • Committer: Selene Scriven
  • Date: 2017-11-18 19:58:08 UTC
  • Revision ID: bzr@toykeeper.net-20171118195808-1v4if4nvkexp2143
Updated bistro-HD to 1.7.1.
Flintrock suggested skipping the intermediate versions, due to known issues in them.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * "Bistro-HD" firmware  
3
 
 * This code runs on a single-channel or dual-channel (or tripple or quad) driver (FET+7135)
 
3
 * This code runs on a single-channel or dual-channel (or triple or quad) driver (FET+7135)
4
4
 * with an attiny13/25/45/85 MCU and several options for measuring off time.
5
5
 *
6
6
 * Original version Copyright (C) 2015 Selene Scriven, 
7
7
 * Modified significantly by Texas Ace (triple mode groups) and 
8
 
 * Flintrock (code size, Vcc, OTSM, eswitch, 4-chan, delay-sleep,.. more, see manual) 
 
8
 * Flintrock (code size, Vcc, OTSM, eswitch, 4-channel, delay-sleep,.. more, see manual) 
9
9
 *
10
10
 * This program is free software: you can redistribute it and/or modify
11
11
 * it under the terms of the GNU General Public License as published by
55
55
 * CALIBRATION
56
56
 *   FR's new method Just adjust parameters in fr-calibration.h
57
57
 *   Now uses something between fully calculated and fully measured method.
58
 
 *   You can make simple adjustments to the calculations to get a good result.
59
 
 *
60
 
 *   To find out what values to use, flash the driver with battcheck.hex
61
 
 *   and hook the light up to each voltage you need a value for.  This is
62
 
 *   much more reliable than attempting to calculate the values from a
63
 
 *   theoretical formula.
64
 
 *
65
 
 *   Same for off-time capacitor values.  Measure, don't guess.
 
58
 *   You can probably get close using calculations in the comments, and 
 
59
 *   you can make simple adjustments from there to get a good result.
 
60
 *   Or, use the battcheck builds with a full baterry (4.2V) to get a 1-point calibration.
66
61
 *
67
62
 * 
68
63
 */
69
64
 
70
65
 
71
 
/* Latest Changes
72
 
 * Fixed minor startup lag. (hopefully doesn't mess up voltage or temp ADC stabilization).
73
 
 * Fixed an array overwrite, in some cases messed up first boot initialization.
74
 
 *
75
 
 * Bug fix in TURBO_TIMEOUT.
76
 
 *  Added TURBO_STEPDOWN config to control mode to step down to.
77
 
 *
78
 
 * Enabled "OTSM_powersave" (not only for OTSM) in attiny 13, drops current from 4mA to ~2mA.
79
 
 *
80
 
 * Added TEMP_STEP_DOWN thermal control alternative, like BLFA6, steps down to safe mode, tap up, but with temp sensing.
81
 
 *    Brings MINIMUM_TURBO_TIME option (mostly effects tapping up while still hot)
82
 
 *    TURBO_STEPDOWN Variable also applies.
83
 
 *    More space savings. TA tripple with OTSM now about 1770 bytes give or take.
84
 
 *    
85
 
 */ 
86
66
 
87
67
#ifndef ATTINY
88
68
/************ Choose your MCU here, or override in Makefile or build script*********/
90
70
 
91
71
//  choices are now 13, 25, 45, and 85.  Yes, 45 and 85 are now different
92
72
 
93
 
#define ATTINY 25
 
73
#define ATTINY 85
94
74
//#define ATTINY 25
95
75
//#define ATTINY 45  // yes these are different now, hopefully only in ways we already know.
96
76
//#define ATTINY 85  //   bust specifically they have a 2 byte stack pointer that OTSM accesses.
106
86
//#define CONFIG_FILE_H "configs/config_default.h"
107
87
 
108
88
///Or select alternative configuration file, last one wins.///
109
 
//#define CONFIG_FILE_H "configs/config_testing-HD.h"
 
89
//#define CONFIG_FILE_H "configs/config_custom-HD.h"
110
90
//#define CONFIG_FILE_H "configs/config_BLFA6_EMU-HD.h"
111
91
//#define CONFIG_FILE_H "configs/config_biscotti-HD.h"
112
 
//#define CONFIG_FILE_H "configs/config_trippledown-HD.h"
 
92
//#define CONFIG_FILE_H "configs/config_tripledown-HD.h"
113
93
//#define CONFIG_FILE_H "configs/config_classic-HD.h"
114
94
//#define CONFIG_FILE_H "configs/config_TAv1-OTC-HD.h"
115
 
#define CONFIG_FILE_H "configs/config_TAv1-OTSM-HD.h"
 
95
//#define CONFIG_FILE_H "configs/config_TAv1-OTSM-HD.h"
116
96
//#define CONFIG_FILE_H "configs/config_TAv1-OTSM-LDO-HD.h"
 
97
//#define CONFIG_FILE_H "configs/config_eswitch-TA-HD.h"
117
98
//#define CONFIG_FILE_H "configs/config_dual-switch-TA-HD.h"
118
99
//#define CONFIG_FILE_H "configs/config_dual-switch-noinit-TA-HD.h"
119
100
//#define CONFIG_FILE_H "configs/config_dual-switch-dumbclick-TA-HD.h"
120
101
//#define CONFIG_FILE_H "configs/config_dual-switch-turboclick-TA-HD.h"
121
102
//#define CONFIG_FILE_H "configs/config_4channel-dual-switch-HD.h"
 
103
#define CONFIG_FILE_H "configs/config_eswitch-Q8-fetplusone-HD.h"
122
104
 
123
105
//Make it a battcheck build? 
124
106
//#define VOLTAGE_CAL
146
128
 
147
129
#include CONFIG_FILE_H // this is primary configuration file.
148
130
 
149
 
void blink_value(uint8_t value); // declare early so we can use it anywhere
150
 
 
151
 
//*************** Defaults, including ones needed before modegroups.h ***********/
 
131
 
 
132
// This is used to simplify the toggle function
 
133
// eliminating mode_override, using this threshold instead:
 
134
#define MINIMUM_OVERRIDE_MODE 245  // DO NOT EDIT.  DO NOT DEFINE ANY STROBES HIGER OR EQUAL TO THIS.
 
135
 
 
136
#define GROUP_SELECT_MODE 254
 
137
#define TEMP_CAL_MODE 253
 
138
 
 
139
/******* Define strobe magic numbers**** *********************/
 
140
//Now separate from actually selecting which ones are used.
 
141
 
 
142
#define BATTCHECK        244      // Convenience code for battery check mode
 
143
//mode codes for strobes, must be less than MINIMUM_OVERRIDE_MODE
 
144
#define BIKING_STROBE    243     // Single flash biking strobe mode
 
145
#define FULL_BIKING_STROBE     // Stutter bike strobe, uncomment to enable
 
146
#define POLICE_STROBE    242     // Dual mode alternating strobe
 
147
#define RANDOM_STROBE    241
 
148
#define SOS              240
 
149
#define STROBE_8HZ       239
 
150
#define STROBE_10HZ      238
 
151
#define STROBE_16HZ      237
 
152
#define STROBE_OLD_MOVIE  236
 
153
#define STROBE_CREEPY    235     // Creepy strobe mode, or really cool if you have a bunch of friends around
 
154
#define RAMP             234     //Ramping "strobe"
 
155
 
 
156
 
 
157
//*************** Defaults needed before modegroups.h, but NOT yet one's overring modegroups.h ***********/
 
158
 
 
159
 
 
160
// FULL_BIKING_STROBE modifies BIKING_STROBE so BIKING_STROBE must be defined.
 
161
#if defined(FULL_BIKING_STROBE) && !defined(BIKING_STROBE)
 
162
 #define BIKING_STROBE
 
163
#endif
 
164
 
 
165
// If medium clicks are disabled, don't define hidden modes:
 
166
// must come before modegroups.h
 
167
#if !defined(OFFTIM3)
 
168
  #define HIDDENMODES       // No hiddenmodes, defined as empty.
 
169
#endif
 
170
 
 
171
#include "fr-tk-attiny.h" // should be compatible with old ones, but it might not be, so renamed it.
 
172
 
 
173
// Read the modegroups configuration file:
 
174
#include MODEGROUPS_H
 
175
 
 
176
//*********Now can define defaults including ones to override things in MODEGROUPS_H ***********
152
177
 
153
178
// There's really no reason not to use LOOP_TOGGLES NOW, probably will remove the old way in the future:
154
179
#ifdef NO_LOOP_TOGGLES
168
193
 #define USE_LOCKSWITCH
169
194
#endif
170
195
 
171
 
// set a default value for the mode to step down to
172
 
// after timeout or overheat, if it's not already configured.
173
 
#ifndef TURBO_STEPDOWN
174
 
 #define TURBO_STEPDOWN RAMP_SIZE/2
175
 
#endif
176
196
 
177
197
// Apply defaults for what temp regulation modes to use
178
198
// Some historical baggage here probably:
179
199
#if defined(TEMPERATURE_MON)
180
200
    #ifdef TURBO_TIMEOUT
181
201
       #error "You cannot define TURBO_TIMEOUT and TEMPERATURE_MON together"
182
 
           #error "Consider usining TEMP_STEP_DOWN instead"
183
 
        #endif
 
202
       #error "Consider usining TEMP_STEP_DOWN instead"
 
203
    #endif
184
204
  #ifdef TEMP_STEP_DOWN // TEMP method already set, do nothing.
185
205
    #ifndef MINIMUM_TURBO_TIME
186
 
          #define MINIMUM_TURBO_TIME 10 // default minimum turbo time for TEMP_STEP_DOWN.
187
 
        #endif
 
206
      #define MINIMUM_TURBO_TIME 10 // default minimum turbo time for TEMP_STEP_DOWN.
 
207
    #endif
188
208
  #else                          // else set the default
189
209
    #define CLASSIC_TEMPERATURE_MON
190
210
  #endif 
191
211
#endif
192
212
 
193
 
#define GROUP_SELECT_MODE 254
194
 
 
195
 
#ifdef USE_TEMP_CAL
196
 
#define TEMP_CAL_MODE 253
197
 
#endif
198
 
 
199
 
// FULL_BIKING_STROBE modifies BIKING_STROBE so BIKING_STROBE must be defined.
200
 
#if defined(FULL_BIKING_STROBE) && !defined(BIKING_STROBE)
201
 
#define BIKING_STROBE
 
213
// click parsing is more reliable with faster sleep cycles.
 
214
// if a pin is changing during read, it will be read again on next sleep cycle
 
215
// before the click time threshold changes.
 
216
//
 
217
//But what about dual OTSM/ESWITCH? Well for now that also disables debounce 
 
218
// It must unless they are on distinguishable pins at least since debounce will break OTSM.
 
219
// And without debounce delays there won't be missed clicks.
 
220
// If OTSM+e-switch still needs debounce, it just won't work on same pin
 
221
// and will need to apply both debounce and sleep time based on pin detection in that case.
 
222
// will know after testing.
 
223
#if defined(USE_ESWITCH) && (!defined USE_OTSM)
 
224
  #undef SLEEP_TIME_EXPONENT 
 
225
  #define SLEEP_TIME_EXPONENT 1 // 32 ms
202
226
#endif
203
227
 
204
228
#define OWN_DELAY           // Don't use stock delay functions.
207
231
 
208
232
#define USE_DELAY_S         // Also use _delay_s(), not just _delay_ms()
209
233
 
210
 
// If medium clicks are disabled, don't define hidden modes:
211
 
#if !defined(OFFTIM3)
212
 
  #define HIDDENMODES       // No hiddenmodes.
 
234
// set a default value for the mode to step down to
 
235
// after timeout or overheat, if it's not already configured.
 
236
#ifndef TURBO_STEPDOWN
 
237
 #define TURBO_STEPDOWN RAMP_SIZE/2
213
238
#endif
214
239
 
215
 
#include "fr-tk-attiny.h" // should be compatible with old ones, but it might not be, so renamed it.
216
 
 
217
 
// Read the modegroups configuration file:
218
 
#include MODEGROUPS_H
219
240
 
220
241
// how many ms to sleep between voltage/temp/stepdown checks.
221
242
#define LOOP_SLEEP 500 
268
289
#include "fr-calibration.h"
269
290
 
270
291
//USE timed sleeps to save power?  Improves moon mode battery life and OTSM performance:
271
 
#ifdef OTSM_powersave
 
292
#ifdef POWERSAVE
272
293
#include "fr-delay.h" // must include them in this order.
273
294
#define _delay_ms _delay_sleep_ms
274
295
#define _delay_s _delay_sleep_s
277
298
#endif
278
299
 
279
300
 
280
 
#ifdef RANDOM_STROBE
 
301
#ifdef USE_RANDOM_STROBE
281
302
#include "tk-random.h"
282
303
#endif
283
304
 
284
305
// The voltage and teperature ADC functions:
285
306
#include "tk-voltage.h"
286
307
 
 
308
void blink_value(uint8_t value); // declare early so we can use it anywhere
287
309
 
288
310
///////////////////////REGISTER VARIABLES///////////////////////////////////
289
311
// make it a register variable.  Saves many i/o instructions.
290
312
// but could change as code evolves.  Worth testing what works best again later.
291
313
 
292
314
// ************NOTE global_counter is now reserved as r2 in tk-delay.h. (commented out now actually)**********
 
315
// safe registers for avr-gcc are r2 through r7 (always restored by callee and never passed).
 
316
//  r8 through r15 MIGHT be safe (not clear) but are certainly not safe for use in interrupts.
293
317
 
294
318
register uint8_t  mode_idx asm("r6");           // current or last-used mode number
 
319
// stragely, redeclaring this saves 10 bytes, should be illegal no?  And why? -FR
 
320
// Doing only the second declaration however loses about 20~30 bytes, so is not identical to re-declaring.
 
321
//uint8_t mode_idx;
295
322
register uint8_t eepos asm("r7");  // eeprom read/write position for wear-leveling of mode_idx save.
296
 
//uint8_t eepos
 
323
//uint8_t eepos;
297
324
 
298
325
// a counter to see how long the light was off during a click
299
326
// actually counts the number of watchdog wakes while off.
301
328
#if defined(USE_OTSM) || defined(USE_ESWITCH) || defined(USE_OTC)
302
329
//Reserving a register for this allows checking it in re-entrant interrupt without needing register maintenance
303
330
// as a side effect it saves several in/out operations that save more space.
304
 
register uint8_t wake_count asm  ("r8");
 
331
register uint8_t wake_count asm  ("r5");
305
332
#endif
306
333
/////////////////////END REGISTER VARIABLE/////////////////////////////////
307
334
 
330
357
#endif
331
358
 
332
359
 
333
 
 
334
360
// total length of current mode group's array
335
 
uint8_t mode_cnt;
 
361
uint8_t mode_cnt __attribute__ ((section (".noinit")));
336
362
// number of regular non-hidden modes in current mode group
337
 
uint8_t solid_modes;
 
363
uint8_t solid_modes __attribute__ ((section (".noinit")));
338
364
// number of hidden modes in the current mode
339
365
// (hardcoded because both groups have the same hidden modes)
340
366
//uint8_t hidden_modes = NUM_HIDDEN;  // this is never used
377
403
#define offtim3       OPT_array[offtim3_IDX]
378
404
//#define TEMPERATURE_MON_IDX OPT_array[7] // TEMPERATURE_MON, doesn't need to be defined,
379
405
                                           // re-uses mode_override toggle in old method
380
 
                                                                                   // and has no toggle at all in new method.
 
406
                                           // and has no toggle at all in new method.
381
407
#define firstboot     OPT_array[firstboot_IDX]  
382
408
#define lockswitch    OPT_array[lockswitch_IDX]  // don't forget to update n_saves above.
383
409
 
405
431
 
406
432
 
407
433
#define n_saves (n_toggles + n_extra_saves)
408
 
  uint8_t OPT_array[n_saves+1] ;
 
434
  uint8_t OPT_array[n_saves+1] __attribute__ ((section (".noinit")));
409
435
#ifndef LOOP_TOGGLES
410
436
  #define final_toggles  (-1) //disable loop toggles.
411
437
                       // redefining n_toggles breaks modegroup macro and fixing that situation seems ugly.
423
449
//#endif
424
450
#if defined(OFFTIM3)&&defined(USE_ESWITCH)
425
451
  #if defined(DUMB_CLICK)||defined(TURBO_CLICK)
426
 
           #define NEXT_LOCKOUT 1 // compile in support to lockout next mode
 
452
       #define NEXT_LOCKOUT 1 // compile in support to lockout next mode
427
453
  #endif
428
454
#endif
429
455
#if ( defined(TEMPERATURE_MON)&&defined(TEMP_STEP_DOWN) )\
430
 
            || defined(USE_TURBO_TIMEOUT) 
431
 
           #define NEXT_LOCKOUT 1 // compile in support to lockout next mode
 
456
                  || defined(USE_TURBO_TIMEOUT) 
 
457
       #define NEXT_LOCKOUT 1 // compile in support to lockout next mode
432
458
#endif
433
459
#ifndef NEXT_LOCKOUT
434
460
   #define NEXT_LOCKOUT 0
447
473
// this define does NOT disable next mode.  It just defines a signaling value
448
474
// for certain functions to use when those functions need to disable it for one click.
449
475
 
 
476
//#define POWER_LOCKOUT_CHECK 254 // Magic value for fast_presses that locks out power on next boot.
 
477
 
450
478
// Magic number stored in eeprom on first boot. 
451
479
// If it's NOT set, it's a first boot, so we don't read configs.
452
480
#define FIRSTBOOT 0b01010101
453
481
 
 
482
//define PORTB IO address for asm use:
 
483
#define PORTB_IO  _SFR_IO_ADDR(PORTB)
 
484
 
454
485
// define a bit field in an I/O register with sbi/cbi support, for efficient boolean manipulation:
455
486
 
456
487
typedef struct
457
488
{
458
 
        unsigned char bit0:1;
459
 
        unsigned char bit1:1;
460
 
        unsigned char bit2:1;
461
 
        unsigned char bit3:1;
462
 
        unsigned char bit4:1;
463
 
        unsigned char bit5:1;
464
 
        unsigned char bit6:1;
465
 
        unsigned char bit7:1;
 
489
    unsigned char bit0:1;
 
490
    unsigned char bit1:1;
 
491
    unsigned char bit2:1;
 
492
    unsigned char bit3:1;
 
493
    unsigned char bit4:1;
 
494
    unsigned char bit5:1;
 
495
    unsigned char bit6:1;
 
496
    unsigned char bit7:1;
466
497
}io_reg;
 
498
 
467
499
/***************LETS RESERVE GPIOR0 FOR LOCAL VARIABLE USE ********************/
468
500
// This seemed more useful at one point than it maybe actually is, but it works.
 
501
// Still useful though because checking a gpio bit can be done in an interrupt without clobbering working registers.
 
502
//   .. saving bytes and speeding up the interrupt.
469
503
//define a global bitfield in lower 32 IO space with in/out sbi/cbi access
470
 
// unfortunately, attiny13 has no GPIORs,.
471
 
 
472
 
                #define gbit            *((volatile uint8_t*)_SFR_MEM_ADDR(GPIOR2)) // pointer to whole status byte.
473
 
                #define gbit_pwm4zero                   ((volatile io_reg*)_SFR_MEM_ADDR(GPIOR2))->bit0 // pwm4 disable toggle.
474
 
                #define gbit_epress             ((volatile io_reg*)_SFR_MEM_ADDR(GPIOR2))->bit1  // eswitch was pressed.
475
 
//      ...
476
 
        #define gbit_addr  "0x13"  // hack, but whatever, 0x13 is GPIOR2 but GPIOR2 macro is just too clever to work.
477
 
                                            //There's surely a better way, but not worth finding out.
478
 
                #define gbit_pwm4zero_bit "0"  // This gets used for inline asm in PWM ISR.
 
504
// unfortunately, attiny13 has no GPIORs, but can't handle OTSM or pwm4 anyway.
 
505
 
 
506
        #define gbit             *((volatile uint8_t*)_SFR_MEM_ADDR(GPIOR2)) // pointer to whole status byte.
 
507
        #define gbit_pwm4zero                   ((volatile io_reg*)_SFR_MEM_ADDR(GPIOR2))->bit0 // pwm4 disable toggle.
 
508
        #define gbit_pinchange          ((volatile io_reg*)_SFR_MEM_ADDR(GPIOR2))->bit1  // flags interrupt type without 
 
509
                                                                                         // need to clobber a register
 
510
 
 
511
//The bitfield variables work in C, but raw addresses and bit shifts can help for asm:
 
512
        #define gbit_pwm4zero_bit 0 // This gets used for inline asm in PWM ISR.
479
513
 
480
514
 
481
515
// Convert wake_time configurations to number of wake_counts
482
516
// This depends on the wake frequency defined by SLEEP_TIME_EXPONENT
483
517
#if defined(USE_OTSM) || defined(USE_ESWITCH) || defined(USE_OTC)
484
518
// math done by compiler, not runtime:
485
 
// plus 1 because there's always an extra un-timed pin-change wake:
 
519
// plus 1 because there's always an extra un-timed pin-change wake
 
520
//   ex:With 1/4 second wakes anything over 0.5s is 3 or more wakes, not two.
 
521
//   The comparison is done as >=.  If wake_count_short was two, an 0.26 s press
 
522
//   would register as medium, not short.
486
523
 
487
524
#if defined(USE_OTC) && !defined(USE_ESWITCH)
488
 
#define wake_count_med (255-CAP_MED)
489
 
#define wake_count_short (255-CAP_SHORT)
 
525
  #define wake_count_med (255-CAP_MED)
 
526
  #define wake_count_short (255-CAP_SHORT)
490
527
#else
491
528
// updated with two components, first 4 wakecounts are double speed.
492
529
//#define wake_interval ( (uint16_t)1<<(6-SLEEP_TIME_EXPONENT) )
525
562
   #ifndef CAP_PIN
526
563
    #error You must define a CAP_PIN in fr-tk-attiny.h or undefine USE_OTC
527
564
   #endif
 
565
   #if defined(READ_VOLTAGE_FROM_DIVIDER)&& (CAP_PIN==VOLTAGE_PIN)
 
566
    #error You cannot read voltage from the OTC pin, disable one or change the layout.
 
567
   #endif
528
568
#endif
529
569
 
530
570
#ifdef USE_OTSM
537
577
  #error You cannot use READ_VOLTAGE_FROM_VCC with the attiny 13.
538
578
#endif
539
579
 
540
 
#if ATTINY==13 && (defined(PWM3_LVL)||defined (PWM4_LVL))
541
 
#error attiny13 does not support PWM3 or PWM4, modify layout or select a new one.
542
 
#endif
543
 
 
 
580
#if ATTINY==13 && (defined(PWM3_LVL)||defined(PWM4_LVL))
 
581
  #error attiny13 does not support PWM3 or PWM4, modify layout or select a new one.
 
582
#endif
 
583
 
 
584
#if defined(USE_INDICATOR)&&!defined(INDICATOR_PIN)
 
585
  #error You have defined USE_INDICATOR without defining  INDICATOR_PIN
 
586
#endif
 
587
 
 
588
#if (defined(READ_VOLTAGE_FROM_DIVIDER)||defined(USE_OTSM))&&!defined(VOLTAGE_PIN)
 
589
  #error You have defined READ_VOLTAGE_FROM_DIVIDER or USE_OTSM without defining VOLTAGE_PIN
 
590
#endif
544
591
 
545
592
#if defined(VOLTAGE_MON)&&!(defined(READ_VOLTAGE_FROM_VCC)||defined(READ_VOLTAGE_FROM_DIVIDER))
546
 
  #error You must define READ_VOLTAGE_FROM_VCC or READ_VOLTAGE_FROM_DIVEDER when VOLTAGE_MON is defined
 
593
  #error You must define READ_VOLTAGE_FROM_VCC or READ_VOLTAGE_FROM_DIVIDER when VOLTAGE_MON is defined
547
594
#endif
548
595
 
549
596
#if defined(VOLTAGE_MON)&&defined(READ_VOLTAGE_FROM_VCC)&&defined(READ_VOLTAGE_FROM_DIVIDER)
552
599
 
553
600
#if defined(READ_VOLTAGE_FROM_DIVIDER)&&!defined(REFERENCE_DIVIDER_READS_TO_VCC)&&defined(USE_OTSM)&&(OTSM_PIN==VOLTAGE_PIN)&&defined(VOLTAGE_MON)
554
601
  #error You cannot use 1.1V reference to read voltage on the same pin as the OTSM.  OTSM power-on voltage must be >1.8V.
555
 
  #error Use REFERENCE_DIVIDER_READS_TO_VCC instead and set divider resistors to provide > 1.8V on-voltage to voltage pin.
556
 
  #error For 1S non-LDO or 1-S 5.0V LDO lights you can use READ_VOLTAGE_FROM_VCC instead
 
602
  #error FOR LDO builds use REFERENCE_DIVIDER_READS_TO_VCC instead and set divider resistors to provide > 1.8V on-voltage to voltage pin.
 
603
  #error For 1S non-LDO or 1-S 5.0V LDO (LDO below regulation) lights you can use READ_VOLTAGE_FROM_VCC instead
557
604
#endif
558
605
 
559
606
#if defined(READ_VOLTAGE_FROM_DIVIDER)&&!defined(REFERENCE_DIVIDER_READS_TO_VCC)&&defined(USE_ESWITCH)&&(ESWITCH_PIN==VOLTAGE_PIN)&&defined(VOLTAGE_MON)
572
619
  #warning It is highly recommend to define USE_SAFE_PRESSES for capacitor-less off-time detection
573
620
#endif
574
621
 
575
 
 
 
622
#if defined(USE_INDICATOR) // check for conflicts
 
623
  #if defined(USE_OTSM)&&(OTSM_PIN==INDICATOR_PIN)
 
624
   #error "You cannot use OTSM and an indicator on the same pin.  Disable one, or change the layout."
 
625
  #endif
 
626
  #if defined(USE_ESWITCH)&&(ESWITCH_PIN==INDICATOR_PIN)
 
627
   #error "You cannot use an ESWITCH and an indicator on the same pin.  Disable one, or change the layout."
 
628
  #endif
 
629
  #if defined(READ_VOLTAGE_FROM_DIVIDER)&&(VOLTAGE_PIN==INDICATOR_PIN)
 
630
   #error "You cannot use the indicator and voltage reads on the same pin.  Disable one or change the layout."
 
631
  #endif
 
632
  #if defined(USE_OTC)&&(CAP_PIN==INDICATOR_PIN)
 
633
   #error "You cannot use OTC and an indicator on the same PIN, and the two options don't make sense together."  
 
634
   #error "Disable one or change the layout."
 
635
  #endif
 
636
#endif
 
637
 
 
638
 
 
639
 
 
640
  
576
641
// Not really used
577
642
//#define DETECT_ONE_S  // auto-detect 1s vs multi-s light make prev.
578
643
// requiers 5V LDO for multi-s light and will use VCC for 1S.
586
651
// 0 being low for soldered, 1 for pulled-up for not soldered
587
652
#ifdef USE_STARS
588
653
inline void check_stars() { 
589
 
        #if 0  // not implemented, STAR2_PIN is used for second PWM channel
590
 
        // Moon
591
 
        // enable moon mode?
592
 
        if ((PINB & (1 << STAR2_PIN)) == 0) {
593
 
                modes[mode_cnt++] = MODE_MOON;
594
 
        }
595
 
        #endif
596
 
        #if 0  // Mode order not as important as mem/no-mem
597
 
        // Mode order
598
 
        if ((PINB & (1 << STAR3_PIN)) == 0) {
599
 
                // High to Low
600
 
                mode_dir = -1;
601
 
                } else {
602
 
                mode_dir = 1;
603
 
        }
604
 
        #endif
605
 
        // Memory
606
 
        if ((PINB & (1 << STAR3_PIN)) == 0) {
607
 
                memory = 1;  // solder to enable memory
608
 
                } else {
609
 
                memory = 0;  // unsolder to disable memory
610
 
        }
 
654
    #if 0  // not implemented and broken, STAR2_PIN is used for second PWM channel
 
655
    // Moon
 
656
    // enable moon mode?
 
657
    if ((PINB & (1 << STAR2_PIN)) == 0) {
 
658
        modes[mode_cnt++] = MODE_MOON;
 
659
    }
 
660
    #endif
 
661
    #if 0  // broken. Mode order not as important as mem/no-mem
 
662
    // Mode order
 
663
    if ((PINB & (1 << STAR3_PIN)) == 0) {
 
664
        // High to Low
 
665
        mode_dir = -1;
 
666
        } else {
 
667
        mode_dir = 1;
 
668
    }
 
669
    #endif
 
670
    // Memory
 
671
    if ((PINB & (1 << STAR3_PIN)) == 0) {
 
672
        memory = 1;  // solder to enable memory
 
673
        } else {
 
674
        memory = 0;  // unsolder to disable memory
 
675
    }
611
676
}
612
677
#endif
613
678
 
616
681
// Expand fast_presses to mulitple copies.  Set and increment all.
617
682
// Check that all are equal to see if RAM has is still intact (short click) and value still valid.
618
683
void clear_presses() {
619
 
        for (uint8_t i=0;i<N_SAFE_BYTES;++i){
620
 
                // if NEXT_LOCKOUT is 0 this just gets optimized to =0
621
 
                // else we only clear last 7 bits, preserving lockout bit
622
 
                   fast_presses_array[i]=clear_presses_value;
623
 
        }
 
684
    for (uint8_t i=0;i<N_SAFE_BYTES;++i){
 
685
        // if NEXT_LOCKOUT is 0 this just gets optimized to =0
 
686
        // else we only clear last 7 bits, preserving lockout bit
 
687
           fast_presses_array[i]=clear_presses_value;
 
688
    }
624
689
}
625
690
 
626
691
 
627
692
inline uint8_t check_presses(){
628
693
    uint8_t i=N_SAFE_BYTES-1;
629
 
        while (i&&(fast_presses_array[i]==fast_presses_array[i-1])){
630
 
                --i;
631
 
        }
632
 
        return !i; // if we got to 0, they're all equal
 
694
    while (i&&(fast_presses_array[i]==fast_presses_array[i-1])){
 
695
        --i;
 
696
    }
 
697
    return !i; // if we got to 0, they're all equal
633
698
}
634
699
// increment all fast_presses variables by 1
635
700
inline void inc_presses(){
636
 
        for (uint8_t i=0;i<N_SAFE_BYTES;++i){
637
 
                ++fast_presses_array[i];
638
 
        }
 
701
    for (uint8_t i=0;i<N_SAFE_BYTES;++i){
 
702
        ++fast_presses_array[i];
 
703
    }
639
704
}
640
705
 
641
706
// probably unused, and too direct now:
642
707
inline void set_presses(uint8_t val){
643
 
        for (uint8_t i=0;i<N_SAFE_BYTES;++i){
644
 
                fast_presses_array[i]=val;
645
 
        }
 
708
    for (uint8_t i=0;i<N_SAFE_BYTES;++i){
 
709
        fast_presses_array[i]=val;
 
710
    }
646
711
}
647
712
 
648
713
#else 
649
 
 #if NEXT_LOCKOUT == 0
 
714
  #if NEXT_LOCKOUT == 0
650
715
 // determines if a short click was done
651
716
 // The theory is for long clicks, ram decays and random chance will produce a higher value.
652
717
 // FR finds this theory suspect, but this is all 
653
718
 // irrelevant when safe_presses is used or noinit is not used.
654
 
  #define check_presses() (fast_presses < 0x20)
655
 
 #else //if next mode lockout is used, we need to pass the short-press test
 
719
    #define check_presses() (fast_presses < 0x20)
 
720
  #else //if next mode lockout is used, we need to pass the short-press test
656
721
       // when disable_next is set. Disable_next is achieved through the short press logic.
657
 
  #define check_presses() ( fast_presses < 0x20 || fast_presses == DISABLE_NEXT )
658
 
 #endif
 
722
    #define check_presses() ( fast_presses < 0x20 || fast_presses == DISABLE_NEXT )
 
723
  #endif
659
724
  inline void clear_presses() {fast_presses=clear_presses_value;}
660
725
  #define inc_presses() fast_presses=(fast_presses+1)& 0x1f     
661
726
  #define set_presses(val) fast_presses=(val)   
667
732
// So just let clear_presses do it, turns the problem into the solution.
668
733
#if NEXT_LOCKOUT == 1
669
734
inline void disable_next() {
670
 
        clear_presses_value=DISABLE_NEXT;
 
735
    clear_presses_value=DISABLE_NEXT;
671
736
}
672
737
#endif
673
738
 
 
739
// Sets the reset value of clear_presses to a magic number
 
740
//  that signals e-switch power lockout
 
741
//#if POWER_LOCKOUT == 1
 
742
//inline void disable_next() {
 
743
    //clear_presses_value=DISABLE_NEXT;
 
744
//}
 
745
//#endif
 
746
 
 
747
 
674
748
//initial_values(): Intialize default configuration values
675
 
uint8_t mode_idx;
676
749
inline void initial_values() {//FR 2017
677
 
        //for (uint8_t i=1;i<n_toggles+1;i++){ // disable all toggles, enable one by one.
678
 
                //OPT_array[i]=255;
679
 
        //}
680
 
         // configure initial values here, 255 disables the toggle... doesn't save space.
 
750
    //for (uint8_t i=1;i<n_toggles+1;i++){ // disable all toggles, enable one by one.
 
751
        //OPT_array[i]=255;
 
752
    //}
 
753
     // configure initial values here, 255 disables the toggle... doesn't save space.
681
754
    #ifdef USE_FIRSTBOOT
682
 
         firstboot = FIRSTBOOT;               // detect initial boot or factory reset
 
755
     firstboot = FIRSTBOOT;               // detect initial boot or factory reset
683
756
 
684
757
// else we're not using it, but if it's in the range of used toggles  we have to disable it:
685
 
        #elif firstboot_IDX <= final_toggles
686
 
         firstboot=255;                       // disables menu toggle
687
 
        #endif
 
758
    #elif firstboot_IDX <= final_toggles
 
759
     firstboot=255;                       // disables menu toggle
 
760
    #endif
688
761
 
689
762
    #ifdef USE_MOON
690
 
         enable_moon = INIT_ENABLE_MOON;      // Should we add moon to the set of modes?
691
 
        #elif enable_moon_IDX <= final_toggles
692
 
         enable_moon=255;                   //disable menu toggle,       
693
 
        #endif
694
 
 
695
 
        #if defined(USE_REVERSE_MODES) && defined(OFFTIM3)
696
 
         reverse_modes = INIT_REVERSE_MODES;  // flip the mode order?
697
 
        #elif reverse_modes_IDX <= final_toggles
698
 
         reverse_modes=255;                   //disable menu toggle,
699
 
        #endif
700
 
         memory = INIT_MEMORY;                // mode memory, or not
701
 
 
702
 
        #ifdef OFFTIM3
703
 
         offtim3 = INIT_OFFTIM3;              // enable medium-press?
704
 
        #elif offtim3_IDX <= final_toggles
705
 
         offtim3=255;                         //disable menu toggle, 
706
 
        #endif
707
 
 
708
 
        #ifdef USE_MUGGLE_MODE
709
 
         muggle_mode = INIT_MUGGLE_MODE;      // simple mode designed for muggles
710
 
        #elif muggle_mode_IDX <= final_toggles
711
 
         muggle_mode=255;                     //disable menu toggle,
712
 
        #endif
713
 
 
714
 
        #ifdef USE_LOCKSWITCH
715
 
         lockswitch=INIT_LOCKSWITCH;          // E-swtich enabled.
716
 
        #elif lockswitch_IDX <= final_toggles
717
 
         lockswitch=255;
718
 
        #endif
 
763
     enable_moon = INIT_ENABLE_MOON;      // Should we add moon to the set of modes?
 
764
    #elif enable_moon_IDX <= final_toggles
 
765
     enable_moon=255;                   //disable menu toggle,   
 
766
    #endif
 
767
 
 
768
    #if defined(USE_REVERSE_MODES) && defined(OFFTIM3)
 
769
     reverse_modes = INIT_REVERSE_MODES;  // flip the mode order?
 
770
    #elif reverse_modes_IDX <= final_toggles
 
771
     reverse_modes=255;                   //disable menu toggle,
 
772
    #endif
 
773
     memory = INIT_MEMORY;                // mode memory, or not
 
774
 
 
775
    #ifdef OFFTIM3
 
776
     offtim3 = INIT_OFFTIM3;              // enable medium-press?
 
777
    #elif offtim3_IDX <= final_toggles
 
778
     offtim3=255;                         //disable menu toggle, 
 
779
    #endif
 
780
 
 
781
    #ifdef USE_MUGGLE_MODE
 
782
     muggle_mode = INIT_MUGGLE_MODE;      // simple mode designed for muggles
 
783
    #elif muggle_mode_IDX <= final_toggles
 
784
     muggle_mode=255;                     //disable menu toggle,
 
785
    #endif
 
786
 
 
787
    #ifdef USE_LOCKSWITCH
 
788
     lockswitch=INIT_LOCKSWITCH;          // E-swtich enabled.
 
789
    #elif lockswitch_IDX <= final_toggles
 
790
     lockswitch=255;
 
791
    #endif
719
792
 
720
793
 
721
794
// Handle non-toggle saves.
722
 
        modegroup = INIT_MODEGROUP;          // which mode group will be default, mode groups below start at zero, select the mode group you want and subtract one from the number to get it by defualt here
723
 
        #ifdef TEMPERATURE_MON
724
 
        maxtemp = INIT_MAXTEMP;              // temperature step-down threshold, each number is roughly equal to 4c degrees
725
 
        #endif
726
 
        mode_idx=0;                          // initial mode
 
795
    modegroup = INIT_MODEGROUP;          // which mode group will be default, mode groups below start at zero, select the mode group you want and subtract one from the number to get it by defualt here
 
796
    #ifdef TEMPERATURE_MON
 
797
    maxtemp = INIT_MAXTEMP;              // temperature step-down threshold, each number is roughly equal to 4c degrees
 
798
    #endif
727
799
 
728
800
// Some really uncharacteristically un-agressive (poor even) compiler optimizing 
729
801
//  means it saves bytes to do all the overrides initializations after 
730
802
//  the OPT_ARRAY initializations, to free up the best registers.
731
803
// required turning this upside down, and making it confusing.
732
804
    #ifdef LOOP_TOGGLES
733
 
          // If we're not using the temp cal mode:
734
 
       #if !( defined(TEMPERATURE_MON)&&defined(TEMP_CAL_MODE) )
 
805
      // If we're not using the temp cal mode:
 
806
       #if !( defined(TEMPERATURE_MON)&&defined(USE_TEMP_CAL) )
735
807
         // and if the temp cal mode is within the range of used toggles
736
 
             #if TEMP_CAL_IDX <= final_toggles
737
 
                        // then disable the toggle:
738
 
               OPT_array[7]=255; 
739
 
                 #endif
740
 
           #else // we're using temp cal mode, set the override mode for menu to toggle into: 
741
 
            overrides[7]=TEMP_CAL_MODE; // enable temp cal mode menu
742
 
           #endif
743
 
           // We always need the group select mode toggle:
744
 
           overrides[5]=GROUP_SELECT_MODE; 
745
 
        #endif
 
808
         #if TEMP_CAL_IDX <= final_toggles
 
809
            // then disable the toggle:
 
810
           OPT_array[7]=255; 
 
811
         #endif
 
812
       #else // we're using temp cal mode, set the override mode for menu to toggle into: 
 
813
        overrides[7]=TEMP_CAL_MODE; // enable temp cal mode menu
 
814
       #endif
 
815
       // We always need the group select mode toggle:
 
816
       overrides[5]=GROUP_SELECT_MODE; 
 
817
    #endif
746
818
 
747
 
        #ifdef USE_STARS
748
 
          check_stars();
749
 
        #endif
 
819
    #ifdef USE_STARS
 
820
      check_stars();
 
821
    #endif
750
822
}
751
823
 
752
824
// save the mode_idx variable:
766
838
// save and restore all other configuration variables:
767
839
void getsetstate(uint8_t rw){// double up the function to save space.
768
840
   uint8_t i; 
769
 
   i=n_saves;
 
841
   i=1;
770
842
   do{
771
843
       if (rw==gssREAD){// conditional inside loop for space.
772
 
               OPT_array[i]=eeprom_read_byte((uint8_t *)(EEPSIZE-i-1));
773
 
           } else {
774
 
               eeprom_write_byte((uint8_t *)(EEPSIZE-i-1),OPT_array[i]);
 
844
         // -1 isn't needed but could help avoid bugs later
 
845
         //  and must match with firstboot address define above.
 
846
           OPT_array[i]=eeprom_read_byte((uint8_t *)(EEPSIZE-i-1));
 
847
       } else {
 
848
           eeprom_write_byte((uint8_t *)(EEPSIZE-i-1),OPT_array[i]);
775
849
       }
776
 
           i--;
777
 
    } while(i); // don't include 0
 
850
       i++;
 
851
    } while(i<=n_saves); 
778
852
}
779
853
 
780
854
// pretty obvious, just saves the mode and all other variables:
781
855
void save_state() {  // central method for writing complete state
782
 
        save_mode();
783
 
        getsetstate(gssWRITE);
 
856
    save_mode();
 
857
    getsetstate(gssWRITE);
784
858
}
785
859
 
786
860
 
787
 
//#ifndef USE_FIRSTBOOT // obsolete
788
 
//inline void reset_state() {
789
 
////    mode_idx = 0;
790
 
////    modegroup = 0;
791
 
    //save_state();
792
 
//}
793
 
//#endif
794
861
 
795
862
//Recalls all saved variables, generally on startup, 
796
 
//unless this is the firt boot, then save the defaults.  
 
863
//unless this is the firt boot after flash or reset, then save the defaults.  
797
864
inline void restore_state() {
798
865
#ifdef USE_FIRSTBOOT
799
866
    uint8_t eep;
800
867
     //check if this is the first time we have powered on
801
868
    eep = eeprom_read_byte((uint8_t *)OPT_firstboot);
802
869
    if (eep != FIRSTBOOT) {// confusing: if eep = FIRSTBOOT actually means the first boot already happened
803
 
                                   // so eep != FIRSTBOOT means this IS the first boot.
 
870
                           // so eep != FIRSTBOOT means this IS the first boot.
804
871
        // not much to do; the defaults should already be set
805
872
        // while defining the variables above
 
873
        mode_idx=0;
806
874
        save_state(); // this will save FIRSTBOOT to the OPT_firstboot byte.
807
875
        return;
808
876
    }
809
877
#endif
810
878
    eepos=0; 
811
879
    do { // Read until we get a result. Tightened this up slightly -FR
812
 
            mode_idx = eeprom_read_byte((const uint8_t *)((uint16_t)eepos));
 
880
        mode_idx = eeprom_read_byte((const uint8_t *)((uint16_t)eepos));
813
881
    } while((mode_idx == 0xff) && eepos++<(EEPSIZE/2) ) ; // the && left to right eval prevents the last ++.
814
882
#ifndef USE_FIRSTBOOT
815
883
 
816
884
    // if no mode_idx was found, assume this is the first boot
817
885
    if (mode_idx==0xff) {
 
886
          mode_idx=0;
818
887
          save_state(); //redundant with check below -FR
819
888
        return; 
820
889
    }
846
915
// change to the previous mode:
847
916
inline void prev_mode() {
848
917
    // simple mode has no reverse
849
 
        #ifdef USE_MUGGLE_MODE
 
918
    #ifdef USE_MUGGLE_MODE
850
919
      if (muggle_mode) { return next_mode(); }
851
920
    #endif
852
921
    if (mode_idx == solid_modes) { 
868
937
// useful to break it out for preprocessor choices.  -FR
869
938
// Copy starting from end, so takes mode_cnt as input.
870
939
inline void copy_hidden_modes(uint8_t mode_cnt){
871
 
        for(uint8_t j=mode_cnt, i=sizeof(hiddenmodes);i>0; )
872
 
        {
873
 
                // predecrement to get the minus 1 for free and avoid the temp,
874
 
                // probably optimizer knows all this anyway.
875
 
                modes[--j] = pgm_read_byte((uint8_t *)(hiddenmodes+(--i)));
876
 
        }
 
940
    for(uint8_t j=mode_cnt, i=sizeof(hiddenmodes);i>0; )
 
941
    {
 
942
        // predecrement to get the minus 1 for free and avoid the temp,
 
943
        // probably optimizer knows all this anyway.
 
944
        modes[--j] = pgm_read_byte((uint8_t *)(hiddenmodes+(--i)));
 
945
    }
877
946
}
878
947
 
879
948
 
884
953
     * (this matters because we have more than one set of modes to choose
885
954
     *  from, so we need to count at runtime)
886
955
     */
887
 
        /*  
888
 
         * FR: What this routine really does is combine the moon mode, the defined group modes, 
889
 
         * and the hidden modes into one array according to configuration options
890
 
         * such as mode reversal, enable mood mode etc.
891
 
         * The list should like this:
892
 
         * modes ={ moon, solid1, solid2,...,last_solid,hidden1,hidden2,...,last_hidden}
893
 
         * unless reverse_modes is enabled then it looks like this:
894
 
         * modes={last_solid,last_solid-1,..solid1,moon,hidden1,hidden2,...last_hidden}
895
 
         * or if moon is disabled it is just left out of either ordering.
896
 
         * If reverse clicks are disabled the hidden modes are left out.
897
 
         * mode_cnt will hold the final count of modes  -FR.
898
 
         *
899
 
         * Now updated to construct the modes in one pass, even for reverse modes.
900
 
         * Reverse modes are constructed backward and pointer gets moved to begining when done.
901
 
         */      
902
 
        
 
956
    /*  
 
957
     * FR: What this routine really does is combine the moon mode, the defined group modes, 
 
958
     * and the hidden modes into one array according to configuration options
 
959
     * such as mode reversal, enable mood mode etc.
 
960
     * The list should like this:
 
961
     * modes ={ moon, solid1, solid2,...,last_solid,hidden1,hidden2,...,last_hidden}
 
962
     * unless reverse_modes is enabled then it looks like this:
 
963
     * modes={last_solid,last_solid-1,..solid1,moon,hidden1,hidden2,...last_hidden}
 
964
     * or if moon is disabled it is just left out of either ordering.
 
965
     * If reverse clicks are disabled the hidden modes are left out.
 
966
     * mode_cnt will hold the final count of modes  -FR.
 
967
     *
 
968
     * Now updated to construct the modes in one pass, even for reverse modes.
 
969
     * Reverse modes are constructed backward and pointer gets moved to begining when done.
 
970
     */  
 
971
    
903
972
    // copy config to local vars to avoid accidentally overwriting them in muggle mode
904
973
    // (also, it seems to reduce overall program size)
905
974
    uint8_t my_modegroup = modegroup;
906
 
        #ifdef USE_MOON
 
975
    #ifdef USE_MOON
907
976
      uint8_t my_enable_moon = enable_moon;
908
 
        #else
909
 
          #define my_enable_moon 0
910
 
        #endif
911
 
        #if defined(USE_REVERSE_MODES) && defined(OFFTIM3)
 
977
    #else
 
978
      #define my_enable_moon 0
 
979
    #endif
 
980
    #if defined(USE_REVERSE_MODES) && defined(OFFTIM3)
912
981
     uint8_t my_reverse_modes = reverse_modes;
913
 
        #else
914
 
          #define my_reverse_modes 0
915
 
        #endif
 
982
    #else
 
983
      #define my_reverse_modes 0
 
984
    #endif
916
985
 
917
986
    // override config if we're in simple mode
918
 
        #ifdef USE_MUGGLE_MODE
 
987
    #ifdef USE_MUGGLE_MODE
919
988
    if (muggle_mode) {
920
989
        my_modegroup = NUM_MODEGROUPS;
921
 
          #ifdef USE_MOON
 
990
      #ifdef USE_MOON
922
991
        my_enable_moon = 0;
923
 
          #endif
924
 
          #if defined(USE_REVERSE_MODES)&&defined(OFFTIM3)
 
992
      #endif
 
993
      #if defined(USE_REVERSE_MODES)&&defined(OFFTIM3)
925
994
        my_reverse_modes = 0;
926
 
          #endif
 
995
      #endif
927
996
    }
928
 
        #endif
 
997
    #endif
929
998
    //my_modegroup=11;
930
999
    //my_reverse_modes=0; // FOR TESTING
931
 
        //my_enable_moon=1;
932
 
        uint8_t i=0;
 
1000
    //my_enable_moon=1;
 
1001
    uint8_t i=0;
933
1002
//    const uint8_t *src = modegroups + (my_modegroup<<3);
934
1003
 
935
1004
    uint8_t *src=(void *)modegroups;
936
1005
    // FR adds 0-terminated variable length mode groups, saves a bunch in big builds.
937
 
        // some inspiration from gchart here too in tightening this up even more.
 
1006
    // some inspiration from gchart here too in tightening this up even more.
938
1007
    // scan for enough 0's, leave the pointer on the first mode of the group.
939
1008
    i=my_modegroup+1;
940
 
        uint8_t *start=0;
941
 
        solid_modes=0;
 
1009
    uint8_t *start=0;
 
1010
    solid_modes=0;
942
1011
 
943
1012
    // now find start and end in one pass
944
 
        // for 
 
1013
    // for 
945
1014
    while(i) {
946
 
                start=src; // set start to beginning of mode group
947
 
            #if defined(USE_REVERSE_MODES)&&defined(OFFTIM3) //Must find end before we can reverse the copy
948
 
                                                // so copy will happen in second pass below.
949
 
              while(pgm_read_byte(src++)){
950
 
            #else // if no reverse, can do the copy here too.
 
1015
        start=src; // set start to beginning of mode group
 
1016
        #if defined(USE_REVERSE_MODES)&&defined(OFFTIM3) //Must find end before we can reverse the copy
 
1017
                                        // so copy will happen in second pass below.
 
1018
          while(pgm_read_byte(src++)){
 
1019
        #else // if no reverse, can do the copy here too.
951
1020
          while((modes[solid_modes+my_enable_moon]=pgm_read_byte(src++))){
952
 
                #endif
953
 
                                         solid_modes=(uint8_t)(src-start);
954
 
                                } // every 0 starts a new modegroup, decrement i
955
 
            i--;
 
1021
        #endif
 
1022
                         solid_modes=(uint8_t)(src-start);
 
1023
                } // every 0 starts a new modegroup, decrement i
 
1024
        i--;
956
1025
    }
957
1026
 
958
1027
 
960
1029
    #if defined(USE_REVERSE_MODES)&&defined(OFFTIM3)
961
1030
    uint8_t j;
962
1031
    j=solid_modes; // this seems a little redundant now.
963
 
          do{
 
1032
      do{
964
1033
     //note my_enable_moon and my_reverse_modes are either 1 or 0, unlike solid_modes.
965
1034
      modes[(my_reverse_modes?solid_modes-j:j-1+my_enable_moon)] = pgm_read_byte(start+(j-1));
966
1035
       j--;
967
1036
      } while (j);
968
 
        #endif
 
1037
    #endif
969
1038
 
970
1039
    #ifdef USE_MOON
971
 
        solid_modes+=my_enable_moon;
 
1040
    solid_modes+=my_enable_moon;
972
1041
    if (my_enable_moon) {// moon placement already handled, but have to fill in the value.
973
 
            modes[(my_reverse_modes?solid_modes-1:0)] = 1;
 
1042
        modes[(my_reverse_modes?solid_modes-1:0)] = 1;
974
1043
    }
975
 
        #endif
976
 
        
 
1044
    #endif
 
1045
    
977
1046
 
978
1047
// add hidden modes
979
1048
#ifdef OFFTIM3
1020
1089
    if (level == 0) {
1021
1090
#ifdef USE_PWM4
1022
1091
        gbit_pwm4zero=1; // we can't disable the interrupt because we use it for other timing
1023
 
                                 // so have to signal the interrupt instead.
 
1092
                         // so have to signal the interrupt instead.
1024
1093
        PWM4_LVL=0;
1025
1094
#endif
1026
1095
#if defined(USE_PWM3)
1089
1158
// The compiler will omit it if it's not used.  Good for debugging.  -FR.
1090
1159
// uses much memory though.
1091
1160
inline void blink_value(uint8_t value){
1092
 
        blink (10,20);
1093
 
        _delay_ms(500);
1094
 
        blink((value/100)%10,200); // blink hundreds
1095
 
        _delay_s();
1096
 
        blink((value/10)%10,200); // blink tens
1097
 
        _delay_s();
1098
 
        blink(value % 10,200); // blink ones
1099
 
        _delay_s();
1100
 
        blink(10,20);
1101
 
        _delay_ms(500);
 
1161
    blink (10,20);
 
1162
    _delay_ms(500);
 
1163
    blink((value/100)%10,200); // blink hundreds
 
1164
    _delay_s();
 
1165
    blink((value/10)%10,200); // blink tens
 
1166
    _delay_s();
 
1167
    blink(value % 10,200); // blink ones
 
1168
    _delay_s();
 
1169
    blink(10,20);
 
1170
    _delay_ms(500);
1102
1171
}
1103
1172
 
1104
1173
 
1110
1179
// that would solve this more generally, but for now this is slightly smaller and does the job.
1111
1180
    uint8_t i;
1112
1181
    for(i=0;i<8;i++) {
1113
 
            set_level(RAMP_SIZE);
1114
 
            _delay_ms(ontime);
1115
 
            set_level(0);
1116
 
            _delay_ms(offtime);
 
1182
        set_level(RAMP_SIZE);
 
1183
        _delay_ms(ontime);
 
1184
        set_level(0);
 
1185
        _delay_ms(offtime);
1117
1186
    }
1118
1187
}
1119
1188
 
1133
1202
// Looped version of main menu to toggle config variables:
1134
1203
#ifdef LOOP_TOGGLES
1135
1204
inline void toggles() {
1136
 
        // New FR version loops over all toggles, avoids variable passing, saves ~50 bytes.
1137
 
        // mode_overrides ( toggles that cause startup in a special mode or menu) 
1138
 
        // are handled by an array entry for each toggle that provides the  mod_idx to set.
1139
 
        // For normal config toggles, the array value is 0, so the light starts in 
1140
 
        // the first normal mode.
1141
 
        // For override toggles the array value is an identifier for the special mode
1142
 
        // All special modes have idx values above MINUMUM_OVERRIDE_MODE.
1143
 
        // On startup mode_idx is checked to be in the override range or not. 
1144
 
        //
1145
 
        // Used for config mode
1146
 
        // Changes the value of a config option, waits for the user to "save"
1147
 
        // by turning the light off, then changes the value back in case they
1148
 
        // didn't save.  Can be used repeatedly on different options, allowing
1149
 
        // the user to change and save only one at a time.
1150
 
        uint8_t i=0;
1151
 
        do {
1152
 
                i++;
1153
 
                if(OPT_array[i]!=255){
1154
 
                        blink(i, BLINK_SPEED/8);  // indicate which option number this is
1155
 
                        mode_idx=overrides[i];
1156
 
                        OPT_array[i] ^= 1;
1157
 
                        save_state();
1158
 
                        // "buzz" for a while to indicate the active toggle window
1159
 
                        blink(32, 500/32);
1160
 
                        OPT_array[i] ^= 1;
1161
 
                        save_state();
1162
 
                        mode_idx=0;
1163
 
                        _delay_s();
1164
 
                        #ifdef USE_MUGGLE_MODE
1165
 
                        if (muggle_mode) {break;} // go through once on muggle mode
1166
 
                        // this check adds 10 bytes. Is it really needed?
1167
 
                        #endif
1168
 
                }
1169
 
        }while((i<n_toggles));
 
1205
    // New FR version loops over all toggles, avoids variable passing, saves ~50 bytes.
 
1206
    // mode_overrides ( toggles that cause startup in a special mode or menu) 
 
1207
    // are handled by an array entry for each toggle that provides the  mod_idx to set.
 
1208
    // For normal config toggles, the array value is 0, so the light starts in 
 
1209
    // the first normal mode.
 
1210
    // For override toggles the array value is an identifier for the special mode
 
1211
    // All special modes have idx values above MINUMUM_OVERRIDE_MODE.
 
1212
    // On startup mode_idx is checked to be in the override range or not. 
 
1213
    //
 
1214
    // Used for config mode
 
1215
    // Changes the value of a config option, waits for the user to "save"
 
1216
    // by turning the light off, then changes the value back in case they
 
1217
    // didn't save.  Can be used repeatedly on different options, allowing
 
1218
    // the user to change and save only one at a time.
 
1219
    uint8_t i=0;
 
1220
    do {
 
1221
        i++;
 
1222
        if(OPT_array[i]!=255){
 
1223
            blink(i, BLINK_SPEED/8);  // indicate which option number this is
 
1224
            mode_idx=overrides[i];
 
1225
            OPT_array[i] ^= 1;
 
1226
            save_state();
 
1227
            // "buzz" for a while to indicate the active toggle window
 
1228
            blink(32, 500/32);
 
1229
            OPT_array[i] ^= 1;
 
1230
            mode_idx=0;
 
1231
            save_state();
 
1232
            _delay_s();
 
1233
            #ifdef USE_MUGGLE_MODE
 
1234
            if (muggle_mode) {break;} // go through once on muggle mode
 
1235
            // this check adds 10 bytes. Is it really needed?
 
1236
            #endif
 
1237
        }
 
1238
    }while((i<n_toggles));
1170
1239
}
1171
1240
 
1172
1241
#else // use the old way, can come close in space for simple menus:
1281
1350
}
1282
1351
#endif
1283
1352
 
1284
 
// init_mcu: Setup all our initial mcu configuration, mostly including interrupts.
 
1353
// init_mcu: Setup all our initial mcu configuration, pin states and interrupt configuration.
1285
1354
//
1286
1355
// Complete revamp by FR to allow use of any combination of 4 outputs, OTSM, and more
1287
1356
// 2017 by Flintrock (C)
1288
1357
//
1289
1358
inline void init_mcu(){ 
1290
1359
    //DDRB, 1 bit per pin, 1=output default =0.
1291
 
        //PORTB 1 is ouput-high or input-pullup.  0 is output-low or input floating/tri-stated.  Default=0.
1292
 
        //DIDR0 Digital input disable, 1 disable, 0 enable. disable for analog pins to save power. Default 0 (enabled) 
 
1360
    //PORTB 1 is ouput-high or input-pullup.  0 is output-low or input floating/tri-stated.  Default=0.
 
1361
    //DIDR0 Digital input disable, 1 disable, 0 enable. disable for analog pins to save power. Default 0 (enabled) 
1293
1362
 
1294
1363
// Decide which clocks to enable, note OTSM sleep uses clock0 unless PWM4 interrupts are 
1295
1364
//  running anyway, then it uses those.
1296
 
#if defined(USE_PWM1) || defined (USE_PWM2) || (defined OTSM_powersave&&!defined(USE_PWM4))
 
1365
#if defined(USE_PWM1) || defined (USE_PWM2) || (defined POWERSAVE&&!defined(USE_PWM4))
1297
1366
   #define USE_CLCK0
1298
1367
#endif   
1299
1368
#if defined(USE_PWM3) || defined (USE_PWM4)
1301
1370
#endif
1302
1371
 
1303
1372
    // setup some temp variables.  This allows to build up values while only assigning to the real
1304
 
        // volatile I/O once at the end.
1305
 
        // The constant temp variable calculations get optimized out. Saves ~30 bytes on big builds.
1306
 
        uint8_t t_DIDR0=0;
 
1373
    // volatile I/O once at the end.
 
1374
    // The constant temp variable calculations get optimized out. Saves ~30 bytes on big builds.
 
1375
    uint8_t t_DIDR0=0;
1307
1376
    uint8_t t_DDRB=0;
1308
 
        uint8_t t_PORTB=0;
 
1377
    uint8_t t_PORTB=0;
1309
1378
#ifdef USE_CLCK0
1310
 
        uint8_t t_TCCR0B=0;
1311
 
        uint8_t t_TCCR0A=0;
 
1379
    uint8_t t_TCCR0B=0;
 
1380
    uint8_t t_TCCR0A=0;
1312
1381
#endif
1313
1382
#ifdef USE_CLCK1
1314
 
        uint8_t t_TCCR1=0;
 
1383
    uint8_t t_TCCR1=0;
1315
1384
#endif
1316
1385
 
1317
1386
    // start by disabling all digital input.
1318
1387
    // PWM pins will get set as output anyway.
1319
 
        
 
1388
    
1320
1389
    t_DIDR0=0b00111111 ; // tests say makes no difference during sleep,
1321
 
                           // but datasheet claims it helps drain in middle voltages, so during power-off detection maybe.
1322
 
        
1323
 
        // Charge up the capacitor by setting CAP_PIN to output
 
1390
                       // but datasheet claims it helps drain in middle voltages, so during power-off detection maybe.
 
1391
    
 
1392
    // Charge up the capacitor by setting CAP_PIN to output
1324
1393
#ifdef CAP_PIN
1325
1394
    // if using OTSM but no OTC cap, probably better to stay input high on the unused pin.
1326
 
        // If USE_ESWITCH and eswitch pin is defined same as cap pin, the eswitch define overrides, 
1327
 
        //  so again, leave it as input (but not high).
1328
 
    #if ( (defined(USE_OTSM) && !defined(OTSM_USES_OTC) ) || (defined(USE_ESWITCH) && ESWITCH_PIN == CAP_PIN ) )
 
1395
    // ESWITCH will override cap pin setting later, if USE_ESWITCH is defined
 
1396
    // If USE_ESWITCH and eswitch pin is defined same as cap pin, the eswitch define overrides, 
 
1397
    //  so again, leave it as input.
 
1398
    #if (defined(USE_OTSM) && !defined(OTSM_USES_OTC) )
1329
1399
       // just leave cap_pin as an input pin (raised high by default lower down)
1330
1400
    #else
1331
 
        // Charge up the capacitor by setting CAP_PIN to output
1332
 
          t_DDRB  |= (1 << CAP_PIN);    // Output
1333
 
          t_PORTB |= (1 << CAP_PIN);    // High
 
1401
    // Charge up the capacitor by setting CAP_PIN to output
 
1402
      t_DDRB  |= (1 << CAP_PIN);    // Output
 
1403
      t_PORTB |= (1 << CAP_PIN);    // High
1334
1404
    #endif
1335
1405
#endif
1336
 
        
1337
 
        // Set PWM pins to output 
1338
 
        // Regardless if in use or not, we can't set them input high (might have a chip even if unused in config)
1339
 
        // so better set them as output low.
 
1406
    
 
1407
            
 
1408
    // Set PWM pins to output 
 
1409
    // Regardless if in use or not, we can't set them input high (might have a chip even if unused in config)
 
1410
    // so better set them as output low.
1340
1411
    #ifdef PWM_PIN
1341
 
           t_DDRB |= (1 << PWM_PIN) ;    
1342
 
        #endif
1343
 
        #ifdef PWM2_PIN
1344
 
           t_DDRB |= (1 << PWM2_PIN);
1345
 
        #endif 
 
1412
       t_DDRB |= (1 << PWM_PIN) ;    
 
1413
    #endif
 
1414
    #ifdef PWM2_PIN
 
1415
       t_DDRB |= (1 << PWM2_PIN);
 
1416
    #endif 
1346
1417
    #ifdef PWM3_PIN
1347
 
           t_DDRB |= (1 << PWM3_PIN); 
 
1418
       t_DDRB |= (1 << PWM3_PIN); 
1348
1419
    #endif
1349
1420
    #ifdef PWM4_PIN
1350
1421
       t_DDRB |= (1 << PWM4_PIN); 
1351
1422
    #endif
1352
 
          
1353
 
        
1354
 
        // Set Timer 0 to do PWM1 and PWM2 or for OTSM powersave timing
 
1423
      
 
1424
    
 
1425
    // Set Timer 0 to do PWM1 and PWM2 or for OTSM powersave timing
1355
1426
    #ifdef USE_CLCK0
1356
1427
     
1357
 
           t_TCCR0A = PHASE; // phase means counter counts up and down and 
1358
 
                       // compare register triggers on and off symmetrically at same value.
1359
 
                                   // This doubles the time so half the max frequency.
1360
 
        // Set prescaler timing
1361
 
        // This and the phase above now directly impact the delay function in tk-delay.h..
1362
 
        //  make changes there to compensate if this is changed
1363
 
             t_TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...)  1 => 16khz in phase mode or 32 in fast mode.
 
1428
       t_TCCR0A = PHASE; // phase means counter counts up and down and 
 
1429
                   // compare register triggers on and off symmetrically at same value.
 
1430
                   // This doubles the time so half the max frequency.
 
1431
    // Set prescaler timing
 
1432
    // This and the phase above now directly impact the delay function in tk-delay.h..
 
1433
    //  make changes there to compensate if this is changed
 
1434
         t_TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...)  1 => 16khz in phase mode or 32 in fast mode.
1364
1435
 
1365
1436
       #ifdef  USE_PWM1
1366
 
             t_TCCR0A |= (1<<COM0B1);  // enable PWM on PB1
1367
 
           #endif
1368
 
           #ifdef USE_PWM2
1369
 
             t_TCCR0A |= (1<<COM0A1);  // enable PWM on PB0
1370
 
           #endif
1371
 
        #endif       
 
1437
         t_TCCR0A |= (1<<COM0B1);  // enable PWM on PB1
 
1438
       #endif
 
1439
       #ifdef USE_PWM2
 
1440
         t_TCCR0A |= (1<<COM0A1);  // enable PWM on PB0
 
1441
       #endif
 
1442
    #endif       
1372
1443
 
1373
1444
   //Set Timer1 to do PWM3 and PWM4
1374
 
        #ifdef USE_CLCK1
1375
 
          OCR1C = 255;  
1376
 
        // FR: this timer does not appear to have any phase mode.
1377
 
        // The frequency appears to be just system clock/255
1378
 
        #endif
1379
 
        #ifdef USE_PWM3
1380
 
          t_TCCR1 = _BV (CS10);  // prescale of 1 (32 khz PWM)
1381
 
          GTCCR = (1<<COM1B1) | (1<<PWM1B) ; // enable pwm on OCR1B but not OCR1B compliment (PB4 only). 
1382
 
                                            // FR: this timer does not appear to have any phase mode.
1383
 
                                                                                // The frequency appears to be just system clock/255
 
1445
    #ifdef USE_CLCK1
 
1446
      OCR1C = 255;  
 
1447
    // FR: this timer does not appear to have any phase mode.
 
1448
    // The frequency appears to be just system clock/255
 
1449
    #endif
 
1450
    #ifdef USE_PWM3
 
1451
      t_TCCR1 = _BV (CS10);  // prescale of 1 (32 khz PWM)
 
1452
      GTCCR = (1<<COM1B1) | (1<<PWM1B) ; // enable pwm on OCR1B but not OCR1B compliment (PB4 only). 
 
1453
                                        // FR: this timer does not appear to have any phase mode.
 
1454
                                        // The frequency appears to be just system clock/255
1384
1455
    #endif                                                                              
1385
 
        #ifdef USE_PWM4
1386
 
          t_TCCR1 = _BV (CS11);  // override, use prescale of 2 (16khz PWM) for PWM4 because it will have high demand from interrupts.
1387
 
                               // This will still be just as fast as timer 0 in phase mode.
1388
 
          t_TCCR1 |=  _BV (PWM1A) ;           // for PB3 enable pwm for OCR1A but leave it disconnected.  
1389
 
                                                // Its pin is already in use.
1390
 
                                                                    // Must handle it with an interrupt.
 
1456
    #ifdef USE_PWM4
 
1457
      t_TCCR1 = _BV (CS11);  // override, use prescale of 2 (16khz PWM) for PWM4 because it will have high demand from interrupts.
 
1458
                           // This will still be just as fast as timer 0 in phase mode.
 
1459
      t_TCCR1 |=  _BV (PWM1A) ;           // for PB3 enable pwm for OCR1A but leave it disconnected.  
 
1460
                                        // Its pin is already in use.
 
1461
                                        // Must handle it with an interrupt.
1391
1462
      _TIMSK_ |= (1<<OCIE1A) | (1<<TOIE1);        // enable interrupt for compare match and overflow on channel 4 to control PB3 output
1392
 
          // Note: this will then override timer0 as the delay clock interrupt for tk-delay.h.
1393
 
        #endif
1394
 
        
1395
 
                
1396
 
        
1397
 
          t_PORTB|=~t_DDRB&~(1<<VOLTAGE_PIN); // Anything that is not an output 
1398
 
                                       // or the voltage sense pin, gets a pullup resistor
1399
 
        // again, no change measured during sleep, but maybe helps with shutdown?
1400
 
        // exceptions handled below.
 
1463
      // Note: this will then override timer0 as the delay clock interrupt for tk-delay.h.
 
1464
    #endif
 
1465
    
 
1466
        
 
1467
    
 
1468
      t_PORTB|=(~t_DDRB); // Anything that is not an output gets a pullup resistor
 
1469
      // except...
 
1470
#if defined(USE_OTSM)||defined(READ_VOLTAGE_FROM_DIVIDER)
 
1471
      t_PORTB&=~(1<<VOLTAGE_PIN); // The voltage sense pin does not get a pullup resistor
 
1472
#endif
 
1473
 
 
1474
    // again, no change measured during sleep, but maybe helps with shutdown?
 
1475
    // exceptions handled below.
1401
1476
#ifdef USE_ESWITCH
1402
 
         // leave pullup set on E-switch pin
1403
 
          PCMSK |= 1<< ESWITCH_PIN;  // catch pin change on eswitch pin
 
1477
   #if  (!defined(READ_VOLTAGE_FROM_DIVIDER)&&!defined(USE_OTSM)) || (ESWITCH_PIN != VOLTAGE_PIN)
 
1478
     //if eswitch is on voltage divider, input power pulls pin to correct level
 
1479
     // else we need pull it up.
 
1480
     // pullup set on E-switch pin
 
1481
      t_DDRB  |= t_DDRB&~(1 << ESWITCH_PIN);    // Input
 
1482
      t_PORTB |= (1 << ESWITCH_PIN);     // High
 
1483
   #endif
 
1484
   PCMSK |= 1<< ESWITCH_PIN;  // catch pin change on eswitch pin
1404
1485
#endif
 
1486
 
1405
1487
#if defined(USE_OTSM) 
1406
1488
//  no pull-up on OTSM-PIN. 
1407
1489
      t_PORTB=t_PORTB&~(1<<OTSM_PIN); 
1408
 
          PCMSK |= 1<< OTSM_PIN;  // catch pin change on OTSM PIn
 
1490
      PCMSK |= 1<< OTSM_PIN;  // catch pin change on OTSM PIn
1409
1491
#endif
1410
 
#if defined(USE_ESWITCH) || defined(USE_OTSM)
1411
 
         GIMSK |= 1<<PCIE;      // enable PIN change interrupt
1412
1492
 
1413
 
         GIFR |= PCIF;  //    Clear pin change interrupt flag
1414
 
#endif
 
1493
#ifdef USE_INDICATOR
 
1494
    #ifdef INDICATOR_PIN
 
1495
    // Turn on the INDICATOR 
 
1496
    t_DDRB  |= (1 << INDICATOR_PIN);    // Output
 
1497
    t_PORTB |= (1 << INDICATOR_PIN);    // High
 
1498
    #endif
 
1499
#endif 
1415
1500
 
1416
1501
// save the compiled results out to the I/O registers:
1417
1502
     DIDR0=t_DIDR0;
1425
1510
     TCCR1=t_TCCR1;
1426
1511
#endif
1427
1512
 
1428
 
#if defined(USE_ESWITCH) || defined(USE_OTSM) || defined(OTSM_powersave)
1429
 
         sleep_enable();     // just leave it enabled.  It's fine and will help elsewhere.
1430
 
         sei();                         //Enable Global Interrupt
1431
 
#endif
1432
 
 
1433
 
//timer overflow interrupt is presently setup in tk-delay.h for OTS_powersave
 
1513
 
 
1514
#if defined(USE_ESWITCH) || defined(USE_OTSM)
 
1515
     GIMSK |= (1<<PCIE);        // enable PIN change interrupt
 
1516
 
 
1517
     GIFR |= PCIF;  //    Clear pin change interrupt flag
 
1518
#endif
 
1519
 
 
1520
#if defined(USE_ESWITCH) || defined(USE_OTSM) || defined(POWERSAVE)
 
1521
     sleep_enable();     // just leave it enabled.  It's fine and will help elsewhere.
 
1522
     sei();             //Enable global interrupts.
 
1523
 
 
1524
#endif
 
1525
 
 
1526
//timer overflow interrupt is presently setup in fr-delay.h for OTS_powersave
1434
1527
 
1435
1528
}
1436
1529
 
1444
1537
 
1445
1538
// if a special override mode is set, do nothing here:
1446
1539
  if (mode_idx<MINIMUM_OVERRIDE_MODE) {
1447
 
          
 
1540
      
1448
1541
//******** DETECT SHORT PRESS: two methods:
1449
1542
   #if defined(USE_OTSM) || defined(USE_ESWITCH) || defined(USE_OTC) // the wake count method
1450
 
            if (wake_count < wake_count_short   )  { 
 
1543
       if (wake_count < wake_count_short   )  { 
1451
1544
   #else                                         // the noinit method
1452
1545
//              if (fast_presses < 0x20) { // fallback, but this trick needs improvements.
1453
 
                if ( check_presses() ) {// Indicates they did a short press, go to the next mode
 
1546
        if ( check_presses() ) {// Indicates they did a short press, go to the next mode
1454
1547
   #endif
1455
 
                                // after turbo timeout, forward click "stays" in turbo (never truly left).
1456
 
                                // conditional gets optimized out if NEXT_LOCKOUT is 0
1457
 
                                if ( NEXT_LOCKOUT && fast_presses == DISABLE_NEXT ){
1458
 
                                        clear_presses(); // one time only.
1459
 
                                } else {
1460
 
                                   next_mode(); // Will handle wrap arounds
1461
 
                                }
1462
 
                                //// We don't care what the fast_presses value is as long as it's over 15
1463
 
                                //                              fast_presses = (fast_presses+1) & 0x1f;
 
1548
                // after turbo timeout, forward click "stays" in turbo (never truly left).
 
1549
                // conditional gets optimized out if NEXT_LOCKOUT is 0
 
1550
                if ( NEXT_LOCKOUT && fast_presses == DISABLE_NEXT ){
 
1551
                    clear_presses(); // one time only.
 
1552
                } else {
 
1553
                   next_mode(); // Will handle wrap arounds
 
1554
                }
 
1555
                //// We don't care what the fast_presses value is as long as it's over 15
 
1556
                //                              fast_presses = (fast_presses+1) & 0x1f;
1464
1557
                inc_presses();
1465
1558
 
1466
1559
//********** DETECT MEDIUM PRESS.
1467
1560
   #ifdef OFFTIM3
1468
 
                 } else if (wake_count < wake_count_med   )  {
 
1561
         } else if (wake_count < wake_count_med   )  {
1469
1562
 
1470
 
                        // User did a medium press, go back one mode
 
1563
            // User did a medium press, go back one mode
1471
1564
//                      fast_presses = 0;
1472
 
                        clear_presses();
1473
 
                        if (offtim3) {
1474
 
                                prev_mode();  // Will handle "negative" modes and wrap-arounds
1475
 
                        } else {
1476
 
                                next_mode();  // disabled-med-press acts like short-press
1477
 
                                        // (except that fast_presses isn't reliable then)
1478
 
                    }
1479
 
          #endif
1480
 
          
 
1565
            clear_presses();
 
1566
            if (offtim3) {
 
1567
                prev_mode();  // Will handle "negative" modes and wrap-arounds
 
1568
            } else {
 
1569
                next_mode();  // disabled-med-press acts like short-press
 
1570
                    // (except that fast_presses isn't reliable then)
 
1571
            }
 
1572
      #endif
 
1573
      
1481
1574
//********** ELSE LONG PRESS
1482
 
                } else {
1483
 
                                // Long press, keep the same mode
1484
 
                                // ... or reset to the first mode
 
1575
        } else {
 
1576
                // Long press, keep the same mode
 
1577
                // ... or reset to the first mode
1485
1578
//                              fast_presses = 0;
1486
1579
            clear_presses();
1487
 
                    #ifdef USE_MUGGLE_MODE
1488
 
                        if (muggle_mode  || (! memory)) {
1489
 
                        #else 
1490
 
                        if (!memory) {
1491
 
                        #endif
1492
 
                                        // Reset to the first mode
1493
 
                                        mode_idx = 0;
1494
 
                    }
1495
 
           } // short/med/long
 
1580
            #ifdef USE_MUGGLE_MODE
 
1581
            if (muggle_mode  || (! memory)) {
 
1582
            #else 
 
1583
            if (!memory) {
 
1584
            #endif
 
1585
                    // Reset to the first mode
 
1586
                    mode_idx = 0;
 
1587
            }
 
1588
       } // short/med/long
1496
1589
  }// mode override
1497
1590
}
1498
1591
 
1499
1592
// Blinks ADC value for battcheck builds
1500
1593
#ifdef VOLTAGE_CAL
1501
1594
inline void voltage_cal(){
1502
 
        ADC_on();
1503
 
        while(1){
1504
 
          _delay_ms(300);
1505
 
          blink_value(get_voltage());
1506
 
        }
 
1595
    ADC_on();
 
1596
    while(1){
 
1597
      _delay_ms(300);
 
1598
      blink_value(get_voltage());
 
1599
    }
1507
1600
}
1508
1601
#endif
1509
1602
 
1515
1608
// 2017 by Flintrock.
1516
1609
// turn on PWM4_PIN at bottom of clock ramp
1517
1610
// this will also replace the delay-clock interrupt used in fr-delay.h
1518
 
// Since SBI,CBI, and SBIC touch no registers, so no register protection is needed:
 
1611
// Added a control flag for 0 level to disable the light. We need the interrupts running for the delay clock.
 
1612
// Since SBI,CBI, and SBIC touch no registers, not even SREG, so no register protection is needed.
1519
1613
// PWM this way without a phase-mode counter would not shut off the light completely
1520
1614
// Added a control flag for 0 level to disable the light. We need the interrupts running for the delay clock.
1521
1615
 
1522
1616
ISR(TIMER1_OVF_vect,ISR_NAKED){ // hits when counter 1 reaches max
1523
 
          __asm__ __volatile__ (    //0x18 is PORTB
1524
 
          "cbi 0x18 , " Quote(PWM4_PIN) " \n\t"
1525
 
          "reti" "\n\t"
1526
 
          :::);
 
1617
    __asm__ __volatile__ (    
 
1618
    "sbic   %[aGbit_addr]  , %[aPwm4zero_bit] \n\t" // if pwm4zero isn't set...
 
1619
    "rjmp .+2 " "\n\t"
 
1620
    "sbi   %[aPortb]  ,  %[aPwm4_pin] \n\t"  //set bit in PORTB (0x18) to make PW4_PIN high.
 
1621
    "reti" "\n\t"
 
1622
    :: [aGbit_addr] "I" (_SFR_IO_ADDR(gbit)), 
 
1623
       [aPwm4zero_bit] "I" (gbit_pwm4zero_bit), 
 
1624
       [aPortb] "I" (_SFR_IO_ADDR(PORTB)), 
 
1625
       [aPwm4_pin] "I" (PWM4_PIN)
 
1626
       :);
1527
1627
}
1528
1628
 
1529
 
// turn off PWM4_PIN at COMPA register match
1530
 
// this one is only defined here though:
 
1629
// Turn off PWM4_PIN at COMPA register match
1531
1630
ISR(TIMER1_COMPA_vect, ISR_NAKED){ //hits when counter 1 reaches compare value
1532
 
        __asm__ __volatile__ (    //0x18 is PORTB
1533
 
          "sbic  " gbit_addr " , " gbit_pwm4zero_bit " \n\t" // if pwm4zero isn't set...
1534
 
      "rjmp .+2 " "\n\t"
1535
 
          "sbi 0x18 , " Quote(PWM4_PIN) " \n\t"  //set bit in PORTB (0x18) to make PW4_PIN high.
1536
 
          "reti" "\n\t"
1537
 
          :::);
 
1631
      __asm__ __volatile__ (    //
 
1632
      "cbi   %[aPortb]  ,  %[aPwm4_pin]  \n\t"
 
1633
      "reti" "\n\t"
 
1634
      ::[aPortb] "I" (_SFR_IO_ADDR(PORTB)), 
 
1635
        [aPwm4_pin] "I" (PWM4_PIN)
 
1636
        :);
1538
1637
}
1539
1638
#endif
1540
1639
 
1541
1640
#if defined(USE_OTSM) || defined(USE_ESWITCH)
 
1641
 
 
1642
inline void wdt_sleep (uint8_t ste) { //Flintrock 2017
 
1643
    //Setup a watchdog sleep for 16ms * 2^ste.
 
1644
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
 
1645
    // reset watchdog counter so it doesn't trip during clear window.
 
1646
    // and so the clock starts at 0 for next sleep loop.
 
1647
    __asm__ __volatile__ ("wdr");
 
1648
    //          WDTCR = (1<<WDCE) |(1<<WDE); // Enable WDE 4-cycle clear window
 
1649
    // set the watchdog timer: 2^n *16 ms datasheet pg 46 for table.
 
1650
    WDTCR = (1<<WDIE) |(!!(ste&8)<<WDP3)|(ste&7<<WDP0); // also clears WDE 4-cycle window is activated.
 
1651
    sleep_bod_disable();
 
1652
    // clear the watchdog interrupt, not needed, if it went of 4 us ago fine,
 
1653
    //  could as well go of 4us later.  Process it either way.
 
1654
    //    MCUSR&=~(1<<WDRF);
 
1655
    sei();
 
1656
    sleep_cpu();
 
1657
    // return from wake ISR's here, both watchdog and pin change.
 
1658
    cli();
 
1659
    WDTCR &= ~(1<<WDIE); // disable watchdog interrupt (prevents glitching the strobe sleeps later).
 
1660
}
 
1661
 
1542
1662
// Off-time sleep mode by -FR, thanks to flashy Mike and Mike C for early feasibility test with similar methods.
1543
1663
 
1544
1664
//need to declare main here to jump to it from ISR.
1545
1665
int main();
 
1666
void Button_press();
 
1667
 
1546
1668
 
1547
1669
// OS_task is a bit safer than naked,still allocates locals on stack if needed, although presently avoided.
1548
 
void __attribute__((OS_task, used, externally_visible)) PCINT0_vect (void) { 
1549
 
//ISR(PCINT0_vect, ISR_NAKED){// Dual watchdog pin change power-on wake by FR
1550
 
 
1551
 
        // 2017 by Flintrock (C)
 
1670
 
 
1671
void __attribute__((naked, used, externally_visible)) PCINT0_vect (void) { 
 
1672
//ISR(PCINT0_vect) {
 
1673
// Dual watchdog pin change power-on wake by FR
 
1674
 
 
1675
    // 2017 by Flintrock (C)
1552
1676
    //
1553
1677
//PIN change interrupt.  This serves as the power down and power up interrupt, and starts the watchdog.
 
1678
//  Now split into a short ISR and a separate e-switch OTSM subtroutine: Button_press().
1554
1679
//
1555
 
        /* IS_NAKED (or OS_task) IS ***DANGEROUS** remove it if you edit this function significantly
1556
 
         *  and aren't sure. You can remove it, and change the asm reti call below to a return.
1557
 
         * and remove the CLR R1. However, it saves about 40 bytes, which matters.
1558
 
         * The idea here, the compiler normally stores all registers used by the interrupt and
1559
 
         * restores them at the end of the interrupt.  This costs instructions (space).
1560
 
     * We won't return to the caller anyway, we're going to reset (so this is similar to a 
1561
 
         * tail call optimization).
1562
 
         * One tricky bit then is that we  get a re-entrant call here because 
1563
 
         * sleep and wake use the same interrupt, so we'll interrupt the sleep command below with a re-entry
1564
 
         * into this function on wake. The re-entry will pass the "if wake_count" conditional and immediately 
1565
 
         * return to the original instance. 
1566
 
         * We avoid touching much there by using a global register variable for wake_count.
1567
 
         * SREG is probably changed but since it only breaks out of the sleep there are
1568
 
         * no pending checks of result flags occurring. 
1569
 
         *
1570
 
         * Another issue is allocation of locals. Naked has no stack frame,
1571
 
         * but seems to properly force variables to register (better anyway) until it can't, 
1572
 
         * and then fails to compile (gcc 4.9.2) OS_task however will create a stack frame if needed and is 
1573
 
         * more documented/gauranteed/future-proof probably.
1574
 
         */
1575
 
 
1576
 
        __asm__ __volatile__ ("CLR R1"); // We do need a clean zero-register (yes, that's R1).
1577
 
        #ifdef USE_ESWITCH // for eswtich we'll modify the sleep loop after a few seconds.
1578
 
            register uint8_t sleep_time_exponent=SLEEP_TIME_EXPONENT; 
1579
 
        #else
1580
 
            #define sleep_time_exponent SLEEP_TIME_EXPONENT
1581
 
        #endif
1582
 
        if( wake_count ){// if we'=rve already slept, so we're waking up. 
1583
 
                             // This is a register variable; no need to clean space for it.
1584
 
//              return; // we are waking up, do nothing and continue from where we slept (below).
1585
 
                __asm__ __volatile__ ("reti");
1586
 
        } // otherwise, we're  going to sleep
 
1680
    /* IS_NAKED (or OS_main) IS ***DANGEROUS** remove it if you edit this functions significantly
 
1681
     *  and aren't sure. You can remove it, and change the asm reti call below to a return.
 
1682
     * and remove the CLR R1. However, it saves about 40 bytes, which matters.
 
1683
     * The idea here, the compiler normally stores all registers used by the interrupt and
 
1684
     * restores them at the end of the interrupt.  This costs instructions (space).
 
1685
     * This ISR handles initial button presses, which all Button_press.
 
1686
     * And button release interrupts, activated while in button press.
 
1687
     * The button release interrupt carefullly does nothing, so register protection isn't needed.
 
1688
     * SREG is probably changed but since it only breaks out of the sleep in Button_press, there are
 
1689
     * no pending checks of result flags occurring.
 
1690
     * The button press call will never come back.  It will do a soft reset, clearing the
 
1691
     * stack pointer and jumping back to main.  Again, no protection required.
 
1692
     * This is a little similar to a tail call optimization.
 
1693
     *
 
1694
     */
 
1695
 
 
1696
#if defined(USE_ESWITCH)&&!(defined(USE_OTSM))
 
1697
// used for de-bouncing eswitch lights.
 
1698
// distinguishes pin-change wakes from watchdog wakes to decide when to debounce.
 
1699
//  writes to a gpio-register to avoid clobbering working registers.
 
1700
//  can't debounce in here without clobbering registers. 
 
1701
    gbit_pinchange=1;
 
1702
#endif
 
1703
 
 
1704
    if( wake_count ){// if we've already slept, so we're waking up.
 
1705
        // This is a register variable; no need to clean space for it.
 
1706
        // we are waking up, do nothing and continue from where we slept (below).
 
1707
        // with ISR_naked, can use the asm reti,
 
1708
 
 
1709
        __asm__ __volatile__ ("reti");
 
1710
//        return;
 
1711
    } else {
 
1712
        Button_press();
 
1713
    }
 
1714
}
 
1715
 
 
1716
 
 
1717
void __attribute__((OS_main, used, externally_visible)) Button_press (void) {
 
1718
//void Button_press() {  
 
1719
    /* Naked has no stack frame,
 
1720
     * but seems to properly force variables to register (better anyway) until it can't,
 
1721
     * and then fails to compile (gcc 4.9.2) OS_main however will create a 
 
1722
     * stack frame if needed for local variables and is
 
1723
     * more documented/gauranteed/future-proof probably.
 
1724
     */
 
1725
    __asm__ __volatile__ ("CLR R1"); // We do need a clean zero-register (yes, that's R1).
 
1726
    
 
1727
    #ifdef USE_ESWITCH // for eswtich we'll modify the sleep loop after a few seconds.
 
1728
        register uint8_t sleep_time_exponent=SLEEP_TIME_EXPONENT; 
 
1729
    #else
 
1730
        #define sleep_time_exponent SLEEP_TIME_EXPONENT
 
1731
    #endif
 
1732
    
1587
1733
// we only pass this section once, can do initialization here:  
1588
 
//    e_status=0b00000001;       //startoff in standby with pin low (button pressed)
1589
 
        cli();
 
1734
 
1590
1735
    ADCSRA = 0; //disable the ADC.  We're not coming back, no need to save it.
1591
 
        set_level(0); // Set all the outputs low.       
1592
 
        // Just the output-low of above, by itself, doesn't play well with 7135s.  Input high doesn't either
1593
 
        //  Even though in high is high impedance, I guess it's still too much current.
1594
 
        // What does work.. is input low:
 
1736
    set_level(0); // Set all the outputs low.   
 
1737
    // Just the output-low of above, by itself, doesn't play well with 7135s.  Input high doesn't either
 
1738
    //  Even though in high is high impedance, I guess it's still too much current.
 
1739
    // What does work.. is input low:
1595
1740
 
1596
1741
    uint8_t inputs=0; // temp variable designed to get optimized out.
1597
 
        #ifdef PWM_PIN
1598
 
            inputs |= (1 << PWM_PIN) ;
1599
 
        #endif
1600
 
        #ifdef PWM2_PIN
1601
 
            inputs |= (1 << PWM2_PIN) ;
1602
 
        #endif
1603
 
        #ifdef PWM3_PIN
1604
 
            inputs |= (1 << PWM3_PIN) ;
1605
 
        #endif
1606
 
        #ifdef PWM4_PIN
1607
 
            inputs |= (1 << PWM4_PIN) ;
1608
 
        #endif
1609
 
        DDRB&= ~inputs;
 
1742
    #ifdef PWM_PIN
 
1743
        inputs |= (1 << PWM_PIN) ;
 
1744
    #endif
 
1745
    #ifdef PWM2_PIN
 
1746
        inputs |= (1 << PWM2_PIN) ;
 
1747
    #endif
 
1748
    #ifdef PWM3_PIN
 
1749
        inputs |= (1 << PWM3_PIN) ;
 
1750
    #endif
 
1751
    #ifdef PWM4_PIN
 
1752
        inputs |= (1 << PWM4_PIN) ;
 
1753
    #endif
 
1754
    DDRB&= ~inputs;
 
1755
 
 
1756
#ifdef USE_INDICATOR
 
1757
// turn off the indicator to acknowledge button is pressed:
 
1758
    PORTB &= ~(1<<INDICATOR_PIN);
 
1759
#endif 
 
1760
    
1610
1761
 
1611
1762
#ifdef USE_ESWITCH
1612
1763
     register uint8_t e_standdown=1; // pressing off, where we start
1613
1764
     register uint8_t e_standby=0;  // pressing on
1614
 
         register uint8_t pins_state=0; // state of all switch pins.
1615
 
//     register uint8_t old_pins_state=0; // detect a change (a sane one at least).
 
1765
     register uint8_t switch_is_pressed; // 1 means any switch is pressed.
1616
1766
#endif
1617
1767
 
1618
 
        while(1) { // keep going to sleep until power is on
1619
 
 
1620
 
         #ifdef USE_ESWITCH
1621
 
         /*  Three phases, 
1622
 
           * 1:standown: Still armed for short click restart on button release, counting time.
1623
 
           * 2:full off (neither standby nor standown). Long press time-out ocurerd, 
1624
 
           *           -button release does nothing on eswitch.
1625
 
           *           -button press arms standby mode.
1626
 
           * 3:standby:  Button is pressed for turn on, restart on release. No timing presently.
1627
 
           */
1628
 
          
1629
 
// enable digital input (want it off during shutdown to save power according to manual)
1630
 
//  not sure how we ever read these pins with this not done.
1631
 
       #if defined(USE_OTSM) && (OTSM_PIN != ESWITCH_PIN) 
1632
 
              register uint8_t e_pin_state = ((PINB&(1<<ESWITCH_PIN))); 
1633
 
              pins_state = e_pin_state&&(PINB&(1<<OTSM_PIN)); // if either switch is "pressed" (0) this is 0.
1634
 
           #else
1635
 
              pins_state=(PINB&(1<<ESWITCH_PIN));
1636
 
                  #if !defined(USE_OTSM)  // just an alias in this case to merge code paths:
1637
 
                    register uint8_t e_pin_state=pins_state; 
1638
 
                  #endif
1639
 
           #endif
1640
 
            if ( e_standdown){                  
1641
 
                   if ( pins_state ) {// if button released and still in standown, restart 
1642
 
                       break; // goto reset 
1643
 
          #if defined(USE_OTSM) && (OTSM_PIN == ESWITCH_PIN)
1644
 
                        } else if ( (wake_count>wake_count_med)) { // it's a long press
1645
 
                            e_standdown=0; // go to full off, this will stop the wake counter.
1646
 
                           _delay_loop_2(F_CPU/400); // if this was a clicky switch.. this will bring it down, 
1647
 
                                                     // don't want to come on in off mode.
1648
 
                          sleep_time_exponent=9; // 16ms*2^9=8s, maximum watchod timeout.
1649
 
                        }
1650
 
          #else 
1651
 
                        } else if (wake_count>wake_count_med && (!e_pin_state)) { // it's a long e-switch press
1652
 
                          e_standdown=0; // only go full off on e-switch press, count on cap to prevent counter overflow
1653
 
                                            // for clickly.
1654
 
                          sleep_time_exponent=9; // 16ms*2^9=8s, maximum watchod timeout.
1655
 
                        }
1656
 
                  #endif
1657
 
                continue; // still in standby, go back to sleep.
1658
 
            }
1659
 
        if (e_standby && pins_state  ) { // if button release while in standby, restart
1660
 
                break; // goto reset         //could merge this with e_standdown & pins_state above, might be smaller, might not.
1661
 
        }
1662
 
        if (!e_standdown && !e_standby && !pins_state   ) { // if button pressed while off, restart
1663
 
                           e_standby=1; // going to standby, will light when button is released         
1664
 
                } 
1665
 
            wake_count+= e_standdown; // increment click time if still in standdown mode.
1666
 
                // continue.. sleep more.
1667
 
         #else  // for simple OTSM, if power comes back, we're on:
1668
 
                if(PINB&(1<<OTSM_PIN)) {
1669
 
                         break; // goto reset
1670
 
            }  
1671
 
                wake_count++;
1672
 
         #endif
 
1768
    while(1) { // keep going to sleep until power is on
 
1769
 
 
1770
     #if defined(USE_ESWITCH)
 
1771
 
 
1772
//***************DO DEBOUNCING ******************
 
1773
 
 
1774
      asm volatile ("" ::: "memory"); // just in case, no i/o reordering around these. It's a no-op.
 
1775
      #if !defined(USE_OTSM)
 
1776
       asm volatile ("" ::: "memory"); // just in case, no i/o reordering around these. It's a no-op.
 
1777
       //debounce, OTSM probably has enough capacitance not to need it
 
1778
       // and the extra on-time is bad for OTSM, may just change to WDT sleep though.
 
1779
       if (gbit_pinchange){ //don't debounce after watchdog
 
1780
                          // only after pin-change.
 
1781
        //cannot use delay_ms() with powersave without micro-managing interrupts.                                         
 
1782
         _delay_loop_2(0); // let pin settle for 32ms. 0=> 0xffff
 
1783
//         _delay_loop_2(0x6000);  // delay about 10ms
 
1784
         GIFR |= PCIF;  //    Clear pin change interrupt flag
 
1785
         asm volatile ("" ::: "memory"); // just in case, no i/o reordering around these. It's a no-op.
 
1786
       }
 
1787
     #else    // if ewitch AND OTSM     
 
1788
//        // Does OTSM+ eswitch even need debounce?
 
1789
//        // Is it C2 alone that fixes debounce or something about clicky switches?
 
1790
//        // if so it will need to use watchdog wakes to save power.
 
1791
 
 
1792
//        asm volatile ("" ::: "memory"); // just in case, no i/o reordering around these. It's a no-op.
 
1793
//        if (gbit_pinchange){ //don't debounce after watchdog
 
1794
//            // only after pin-change.
 
1795
//          GIMSK &= ~(1<<PCIE);  // disable PIN change interrupt
 
1796
////          debounce time exponent for watchdog prescale
 
1797
////          2^n *16 ms datasheet pg 46 for table.
 
1798
//          uint8_t dbe=1; // 32ms.
 
1799
//          wdt_sleep(dbe);
 
1800
//          GIMSK |= (1<<PCIE);  // re-enable PIN change interrupt
 
1801
//          GIFR |= PCIF;  //    Clear pin change interrupt flag
 
1802
//          gbit_pinchange=0; // clear wake was pin change flag
 
1803
//       }
 
1804
//       asm volatile ("" ::: "memory"); // just in case, no i/o reordering around these. It's a no-op.
 
1805
       #endif
 
1806
     
 
1807
//**** DETERMINE PRESENT STATE AND RESTART DECISION, EVOLVED THROUGH CLICK HISTORY
 
1808
 
 
1809
     /*  Three phases, 
 
1810
       * 1:standown: button was pressed while on, not released yet.
 
1811
       *    If released in short or med click will restart
 
1812
       * 2:full off. (neither standby nor standown). Long press time-out ocurerd, and button was released.
 
1813
       *           -Pressing the button now arms standby mode.
 
1814
       * 3:standby:  Button is pressed for turn on from off-sleep, restart on release. No timing presently.
 
1815
       */
 
1816
 
 
1817
//**** First figure out if buttons are pressed, and to some extent which ones: *******
 
1818
       #if defined(USE_OTSM) && (OTSM_PIN != ESWITCH_PIN) //more than one switch pin 
 
1819
          // define only  on first entry to identify press type.
 
1820
          // This is not a proper bool, it's 0 or ESWITCH_PIN.
 
1821
          // Could store this is the GPIOR if we need to know on wake up.
 
1822
          register uint8_t e_was_pressed = ((PINB^(1<<ESWITCH_PIN)));
 
1823
 
 
1824
          // define on every entry to see if still pressed:
 
1825
          // if either switch is "pressed" (0) this is 0.
 
1826
          // is right shifting cheaper than &&? Is the compiler smart?
 
1827
          switch_is_pressed = ( (PINB^(1<<ESWITCH_PIN)) || (PINB^(1<<OTSM_PIN)) ); 
 
1828
       #else // only one switch pin:
 
1829
          switch_is_pressed =  (PINB^(1<<ESWITCH_PIN)); 
 
1830
             //this gets optomized out of conditional checks:
 
1831
          register uint8_t e_was_pressed=1; 
 
1832
       #endif
 
1833
       
 
1834
//****** If a switch is released, what do we do? *******
 
1835
// **  Restart or go to off-sleep?
 
1836
       
 
1837
//      if ( !switch_is_pressed ) { 
 
1838
 //  If wake count==0, first entry, check pin state
 
1839
 //  If it's already open,process the release.  If not so initially closed,
 
1840
 //    then assume any later pin change must have produced a release at some point
 
1841
 //    even if we missed it, so don't check pin again, just check for pinchange event.
 
1842
      if ( (gbit_pinchange && (wake_count !=0)) || !switch_is_pressed ) {
 
1843
        if ( wake_count<wake_count_med || !e_was_pressed || e_standby ){
 
1844
           // If clicky switch is released ever, or if eswitch is released
 
1845
           // before long click, or if switch is released in standby we restart.
 
1846
               break; // goto reset 
 
1847
         // otherwise if e-switch is released after wake_count_med..
 
1848
        } else { // switch released in long press
 
1849
            //exit standown, go to off-sleep.
 
1850
            e_standdown=0; // allows next press to enter standby
 
1851
            sleep_time_exponent=9; // 16ms*2^9=8s, maximum watchod timeout.
 
1852
        }                 
 
1853
      }
 
1854
      
 
1855
 
 
1856
      // increment click time if still in short or med click
 
1857
      // go one past, why? on == we burn out the OTSM cap below,
 
1858
      // Then we go one past, so we don't repeat the burnout.
 
1859
      wake_count+= (wake_count <= wake_count_med); 
 
1860
                     // then continue.. sleep more.
 
1861
                     
 
1862
//***Things to do at start of long-press timeout:
 
1863
      if ( wake_count == wake_count_med){// long press is now inevitable
 
1864
 
 
1865
      // if e-switch and OTSM-clicky switch are the same.  Prevent releasing clicky into off-sleep 
 
1866
      // by draining the clicky OTSM before user has a chance to release, while interrupts are disabled.
 
1867
      // This will do a full restart (clicky long press).
 
1868
        #if ( defined(USE_OTSM) && (OTSM_PIN == ESWITCH_PIN) ) 
 
1869
          // _delay_loop_2 waits for 4 clocks. so F_CPU/400 is 10ms.
 
1870
          _delay_loop_2(F_CPU/400); // if this was a clicky switch.. this will bring it down,
 
1871
        #endif
 
1872
 
 
1873
        #ifdef USE_INDICATOR
 
1874
          // re-light the indicator to acknowledge turn-off
 
1875
          PORTB |= (1<<INDICATOR_PIN);
 
1876
        #endif
 
1877
      }
 
1878
 
 
1879
//*** Handle pressing the switch again from off ***//
 
1880
 
 
1881
      if (!e_standdown && !e_standby && switch_is_pressed   ) { // if button pressed while off, standby for restart
 
1882
            e_standby=1; // going to standby, will light when button is released
 
1883
         #ifdef USE_INDICATOR
 
1884
           // cut the indicator to acknowledge button press
 
1885
           PORTB &= ~(1<<INDICATOR_PIN);
 
1886
         #endif
 
1887
      }
 
1888
 
 
1889
//**** Finally what do for OTSM-only, no e-switch.  ***********************                                      
 
1890
     #else // if not defined USE_ESWITCH: for simple OTSM, 
 
1891
     //  if power comes back, we're on.  Wake_count will tell main about the click length:
 
1892
        if(PINB&(1<<OTSM_PIN)) {
 
1893
             break; // goto reset
 
1894
        }  
 
1895
        wake_count++;
 
1896
     #endif
1673
1897
 
1674
1898
/***************** Wake on either a power-up (pin change) or a watchdog timeout************/
1675
 
                // At every watchdog wake, increment the wake counter and go back to sleep.
1676
 
            set_sleep_mode(SLEEP_MODE_PWR_DOWN);
1677
 
//              WDTCR = (1<<WDCE) |(1<<WDE);
1678
 
//              WDTCR = (0<<WDE);  // might already be in use, so we have to clear it.
1679
 
        uint8_t ste;
1680
 
                ste=sleep_time_exponent>>(wake_count<5);// for first 4 sleeps, cut wake time in half (right shift 1 if wake_count is <5)
1681
 
//              WDTCR = (1<<WDIE) |(!!(sleep_time_exponent&8)<<WDP3)|(sleep_time_exponent&7<<WDP0); // set the watchdog timer: 2^n *16 ms datasheet pg 46 for table.
1682
 
                WDTCR = (1<<WDIE) |(!!(ste&8)<<WDP3)|(ste&7<<WDP0); // set the watchdog timer: 2^n *16 ms datasheet pg 46 for table.
1683
 
                sleep_bod_disable();
1684
 
                sei(); // yep, we're going to nest interrupts, even re-entrenty into this one!
1685
 
                sleep_cpu();
1686
 
                        // return from wake ISR's here, both watchdog and pin change.
1687
 
                cli();
1688
 
                // Now just figure out what pins are pressed and if we're coming or going, not as simple as it sounds.
1689
 
 
 
1899
// At every watchdog wake, increment the wake counter and go back to sleep.
 
1900
         gbit_pinchange=0; // clear wake was pin change flag
 
1901
        wdt_sleep(sleep_time_exponent);         
 
1902
//        wdt_(sleep_time_exponent>>(wake_count<5));// for first 4 sleeps, cut wake time in half (right shift 1 if wake_count is <5)
1690
1903
     }   
1691
 
         /*** Do a soft "reset" of sorts. **/
 
1904
 
 
1905
/******************* Do a soft "reset" of sorts. ********************/
1692
1906
     //
1693
 
         asm volatile ("" ::: "memory"); // just in case, no i/o reordering around these. It's a noop.
 
1907
     asm volatile ("" ::: "memory"); // just in case, no i/o reordering around these. It's a noop.
1694
1908
     SPL = (RAMEND&0xff); // reset stack pointer, so if we keep going around we don't get a stack overflow. 
 
1909
             // Scary looking perhaps, but a true reset does exactly this (same assembly code).
1695
1910
#if (ATTINY == 45 ) || ( ATTINY == 85 )
1696
 
         SPH = RAMEND>>8; 
 
1911
     SPH = RAMEND>>8; 
1697
1912
#endif
1698
 
         SREG=0;  // clear status register
 
1913
     SREG=0;  // clear status register.
1699
1914
     main(); // start over, bypassing initialization.
1700
 
                
1701
1915
1702
1916
 
1703
1917
ISR(WDT_vect, ISR_NAKED) // watchdog interrupt handler -FR
1706
1920
        __asm__ volatile("reti");
1707
1921
}
1708
1922
 
1709
 
#endif // OTSM
 
1923
#endif // OTSM/E-SWITCH
1710
1924
 
1711
1925
 
1712
1926
 
1718
1932
// be careful in here, local variables are not technically allowed (no stack exists), but subroutine calls are.
1719
1933
void __attribute__ ((naked)) __attribute__ ((section (".init8"))) \
1720
1934
main_init () { 
1721
 
         initial_values(); // load defaults for eeprom config variables.
 
1935
     initial_values(); // load defaults for eeprom config variables.
1722
1936
   // initialize register variables, since gcc stubornly won't do it for us.
1723
 
         eepos=0;
 
1937
     eepos=0;
1724
1938
#if defined(USE_OTSM) || defined(USE_ESWITCH)
1725
1939
     wake_count=255; // initial value on cold reboot, represents large click time.
1726
1940
#endif
1732
1946
// requires initialization on re-entry to main from OTSM sleep.
1733
1947
  clear_presses_value=0; 
1734
1948
#endif
 
1949
#ifdef OTSM_debug // for testing your OTSM hardware
 
1950
  //store the wake_count value to blink it out after mcu initialization.
 
1951
  uint8_t tempval=wake_count;
 
1952
#endif
1735
1953
 
1736
1954
// Handle some click timing scenarios.  We can't processes click timings until we restore the last mode save.
1737
1955
// but need to read OTC as early as possible anyway.
1743
1961
//   short power switch act like a long press with reversed modes.
1744
1962
// Otherwise we have to just keep adding boutique conditionals here:
1745
1963
#if defined(OFFTIM3)
1746
 
        #if defined(USE_ESWITCH)
1747
 
           // handle dual switch cases:
1748
 
            #if defined(DUMB_CLICK) // LEXEL mode, power click just turns the light on the way it came off.
1749
 
                   if(wake_count==255) {// we had a full reset, aka power switch.
1750
 
                          wake_count++; // set to 0, short click.
1751
 
                          disable_next(); //forces short click and disables mode advance.
1752
 
                   }
1753
 
                #elif defined(TURBO_CLICK)// power switch always starts in first hidden mode
1754
 
                   if(wake_count==255) {// we had a full reset, aka power switch.
1755
 
                              mode_idx=0; // set to first (0) mode,
 
1964
    #if defined(USE_ESWITCH)
 
1965
       // handle dual switch cases:
 
1966
        #if defined(DUMB_CLICK) // LEXEL mode, power click just turns the light on the way it came off.
 
1967
           if(wake_count==255) {// we had a full reset, aka power switch.
 
1968
              wake_count++; // set to 0, short click.
 
1969
              disable_next(); //forces short click and disables mode advance.
 
1970
           }
 
1971
        #elif defined(TURBO_CLICK)// power switch always starts in first hidden mode
 
1972
           if(wake_count==255) {// we had a full reset, aka power switch.
 
1973
                  mode_idx=0; // set to first (0) mode,
 
1974
                  save_mode();
1756
1975
                  wake_count=wake_count_short; // med press, will move back into hidden mode.
1757
1976
           }            
1758
 
                #elif defined(REVERSE_CLICK)// power switch reverses modes.
 
1977
        #elif defined(REVERSE_CLICK)// power switch reverses modes.
1759
1978
              //not implemented, 
1760
 
                          // a little tricky.
1761
 
                #elif defined(USE_OTC)
1762
 
                // We have an eswitch and OTC on the clicking switch.
1763
 
                // If Eswitch was pressed, nothing to do,
1764
 
                //   but if click switch was pressed:
1765
 
                   if(wake_count==255) { //255 is re-initialized value, power-outage implies clicky press, must use OTC
1766
 
                        // We can't translate the CAP thresholds, because they are compile-time constants,
1767
 
                        // and this is a run-time conditional.
1768
 
                        // Instead translate the cap values to wake_count values.
1769
 
                        // A matching preprocessor conditional above stores 255-CAP_MED and 255-CAP_SHORT in the wake_count macros.
1770
 
                        //     in the case that OTC is used.  
1771
 
                          uint8_t cap_val = read_otc();
1772
 
                      if (cap_val>CAP_MED) {
1773
 
                                 wake_count=wake_count_med; // long press (>= is long)
1774
 
                          }else if (cap_val>CAP_SHORT){
1775
 
                                 wake_count=wake_count_short; // med press
1776
 
                          }else{
1777
 
                                 wake_count=0;               // short press
1778
 
                          }
1779
 
                   }
1780
 
            #elif  defined(USE_OTSM) // eswitch and OTSM clicking switch
1781
 
               // anything to do here?
1782
 
                   // These switches use the same timing format already.
1783
 
            #elif  defined(USE_ESWITCH)  // eswitch and noinit or no second switch configured.
1784
 
                  #if  defined(DUAL_SWITCH_NOINIT)
1785
 
                      wake_count=255+check_presses(); // 0 if check_presses is 1 (short click),  255 if 0 (long click).
1786
 
                  #endif
1787
 
            #endif 
1788
 
        #elif defined(USE_OTC) 
1789
 
           #if !defined(USE_OTSM)
1790
 
                // OTC only.
1791
 
                // check the OTC immediately before it has a chance to charge or discharge
1792
 
                // We re-use the wake_count variable that measures off time for OTSM:
1793
 
                // But high cap is short time, so have to invert.
1794
 
                  wake_count = 255-read_otc(); // 255 - OTC adc value.
1795
 
                  // define wake_count thresholds from cap thresholds:
1796
 
           #else 
1797
 
                 #error You cannot define USE_OTSM and USE_OTC at the same time.
1798
 
           #endif //handle eswitch and OTC below
1799
 
        // end of OTC possibilities
1800
 
        #endif // end OTC without e-switch.
1801
 
#endif
1802
 
        
1803
 
    init_mcu(); // setup pins, prescalers etc, configure/enable interrupts, etc.
1804
 
 
1805
 
#ifdef VOLTAGE_CAL
1806
 
        voltage_cal();
1807
 
#endif
1808
 
 
1809
 
#ifdef OTC_debug
1810
 
    blink_value(cap_val);
1811
 
    return 0;
1812
 
#endif
1813
 
 
 
1979
              // a little tricky.
 
1980
        #elif defined(USE_OTC)
 
1981
        // We have an eswitch and OTC on the clicking switch.
 
1982
        // If Eswitch was pressed, nothing to do,
 
1983
        //   but if click switch was pressed:
 
1984
           if(wake_count==255) { //255 is re-initialized value, power-outage implies clicky press, must use OTC
 
1985
            // We can't translate the CAP thresholds, because they are compile-time constants,
 
1986
            // and this is a run-time conditional.
 
1987
            // Instead translate the cap values to wake_count values.
 
1988
            // A matching preprocessor conditional above stores 255-CAP_MED and 255-CAP_SHORT in the wake_count macros.
 
1989
            //     in the case that OTC is used.  
 
1990
              uint8_t cap_val = read_otc();
 
1991
              if (cap_val>CAP_MED) {
 
1992
                 wake_count=wake_count_med; // long press (>= is long)
 
1993
              }else if (cap_val>CAP_SHORT){
 
1994
                 wake_count=wake_count_short; // med press
 
1995
              }else{
 
1996
                 wake_count=0;               // short press
 
1997
              }
 
1998
           }
 
1999
        #elif  defined(USE_OTSM) // eswitch and OTSM clicking switch
 
2000
           // anything to do here?
 
2001
           // These switches use the same timing format already.
 
2002
        #elif  defined(USE_ESWITCH)  // eswitch and noinit or no second switch configured.
 
2003
          #if  defined(DUAL_SWITCH_NOINIT)
 
2004
              wake_count=255+check_presses(); // 0 if check_presses is 1 (short click),  255 if 0 (long click).
 
2005
          #endif
 
2006
        #endif 
 
2007
    #elif defined(USE_OTC) 
 
2008
       #if !defined(USE_OTSM)
 
2009
        // OTC only.
 
2010
        // check the OTC immediately before it has a chance to charge or discharge
 
2011
        // We re-use the wake_count variable that measures off time for OTSM:
 
2012
        // But high cap is short time, so have to invert.
 
2013
          wake_count = 255-read_otc(); // 255 - OTC adc value.
 
2014
          // define wake_count thresholds from cap thresholds:
 
2015
       #else 
 
2016
         #error You cannot define USE_OTSM and USE_OTC at the same time.
 
2017
       #endif //handle eswitch and OTC below
 
2018
    // end of OTC possibilities
 
2019
    #endif // end OTC without e-switch.
 
2020
#endif
 
2021
    
1814
2022
    restore_state(); // loads user configurations
1815
2023
 
1816
2024
// Disable e-switch interrupt if it's locked out:
1817
2025
#if defined(USE_ESWITCH_LOCKOUT_TOGGLE) && (ESWITCH_PIN != OTSM_PIN)
1818
 
        if (lockswitch) {
 
2026
    if (lockswitch) {
1819
2027
      PCMSK&=~(1<<ESWITCH_PIN);
1820
 
        }
1821
 
#endif
 
2028
    }
 
2029
#endif
 
2030
 
 
2031
    count_modes(); // build the working mode group using configured choices.
 
2032
 
 
2033
    change_mode(); // advance, reverse, stay put?
 
2034
 
 
2035
// reset the wake counter, must happen after we proccess 
 
2036
//  the click timing in change_mode and before releasing interrupts in init_mcu().
 
2037
#if defined(USE_OTSM) || defined(USE_ESWITCH)
 
2038
    wake_count=0; // reset the wake counter.
 
2039
#endif
 
2040
 
 
2041
 
 
2042
// initialize the pin states and interrupts, and enable interrupts.
 
2043
// First entry into pin change interrupt must have wake_count of 0
 
2044
// or the interrupt will kick back out with interrupts disabled 
 
2045
// causing sleeps to freeze, so enable interrupts after resetting wake_count.
 
2046
 
 
2047
// debounce at power-on?
 
2048
// Not needed because there was already a pin change parse before restart
 
2049
// with a debounce time then. Next pin read after interrupts are re-enabled.
 
2050
// So far OTSM clicky lights don't seem to need debounce.
 
2051
//   _delay_loop_2(0); // let pin settle for 32ms. 0=> 0xff
 
2052
 
 
2053
 
 
2054
    init_mcu();
1822
2055
 
1823
2056
#ifdef OTSM_debug // for testing your OTSM hardware 
1824
 
                 // blink out the wake count, then continue into mode as normal.                 
1825
 
    if (wake_count!=255) {
1826
 
      uint8_t tempval=wake_count;
1827
 
          wake_count=0; // this just resets wake_count while blinking so we can click off early and it still works.
1828
 
                      // use 0 for debugging but will start at 255 in real use.
 
2057
    if (tempval!=255) {
1829
2058
      blink_value(tempval);
1830
 
        } 
1831
 
        //else {
1832
 
        //cli(); 
1833
 
        //_delay_s(); _delay_s(); // this will increase current for two seconds if otsm_powersave is used.
1834
 
                              //// provides a debug signal through the ammeter. 
1835
 
        //sei();
1836
 
        //}
1837
 
//    wake_time=0;  // use this to make every click act like a fast one for debugging.
1838
 
#endif
1839
 
    count_modes(); // build the working mode group using configured choices.
1840
 
 
1841
 
        change_mode(); // advance, reverse, stay put?
1842
 
 
1843
 
#if defined(USE_OTSM) || defined(USE_ESWITCH)
1844
 
        wake_count=0; // reset the wake counter.
1845
 
#endif
1846
 
 
1847
 
 
1848
 
        save_mode();
1849
 
        
 
2059
    } 
 
2060
#endif
 
2061
 
 
2062
#ifdef OTC_debug
 
2063
    blink_value(cap_val);
 
2064
    return 0;
 
2065
#endif
 
2066
 
 
2067
#ifdef VOLTAGE_CAL
 
2068
    voltage_cal();
 
2069
#endif
 
2070
 
 
2071
 
1850
2072
#if defined(VOLTAGE_MON) || defined(USE_BATTCHECK)
1851
2073
    ADC_on(); 
1852
2074
#endif
1864
2086
#ifdef VOLTAGE_MON
1865
2087
    uint8_t lowbatt_cnt = 0;
1866
2088
#endif
1867
 
    // handle mode overrides, like mode group selection and temperature calibration
 
2089
    //  
 
2090
    // modegroups, mode_idx, output, and actual_level explained:
 
2091
    //
 
2092
    // Modegroups are an array of "output" values.  For normal modes these values are normally the same as actual_level values 
 
2093
    //  which are just ramp index values.  (The ramp arrays convert an actual_level into PWM values for all the channels in use).
 
2094
    //
 
2095
    // In normal modes actual_level can become different from nominal "output" value if temperature or voltage regulation has kicked in
 
2096
    //  and this is why there are two separate values.  output remembers the nominal value and actual_level holds the present corrected value.
 
2097
    //  
 
2098
    // mode_idx normally tells which mode we're in within the modegroup array and thus which output value to use from the modegroup.
 
2099
    // Some output values (with high values) in the modegroups correspond to special modes like strobes, not nominal actual_level.  
 
2100
    // Those magic values will get filtered and processed before/instead-of selecting a ramp value.
 
2101
    //
 
2102
    // Still other times mode_idx itself refers to a special "output" value, not a modegroup index. 
 
2103
    // These are values not listed within the modegroup and only selectable from menu functions. 
 
2104
    // They are identified when mode_idx has been set greater than MINIMUM_OVERRIDE_MODE, thus overriding the modegroup lookup.
 
2105
    // In these cases we must first copy the mode_idx value to the output value.  It then gets treated like any other special output value
 
2106
    //    and again filtered before/instead-of selecting a ramp value.
 
2107
    //
 
2108
    //
1868
2109
//    if (mode_override) {
1869
2110
    if (mode_idx>=MINIMUM_OVERRIDE_MODE) {
 
2111
    // handle mode overrides, like mode group selection and temperature calibration
1870
2112
        // do nothing; mode is already set
1871
2113
//        fast_presses = 0;
1872
2114
//              clear_presses(); // redundant, already clear on menu entry
1873
2115
                         // and had to go through menu to get to an override mode.
1874
 
                                                 // at most fast_presses now is 1, saves 6 bytes.
 
2116
                         // at most fast_presses now is 1, saves 6 bytes.
1875
2117
        output = mode_idx; // not a typo. override modes don't get converted to an actual output level.
 
2118
 
 
2119
        // exit these mode after one use by default:
 
2120
        //   (Also prevents getting stuck in a bogus override mode from data corruption, etc.)
 
2121
        mode_idx = 0;  // requires save_mode call below to take effect.
1876
2122
    } else {
1877
2123
      if (fast_presses > 0x0f) {  // Config mode
1878
 
                 _delay_s();       // wait for user to stop fast-pressing button
1879
 
                 //            fast_presses = 0; // exit this mode after one use
1880
 
                 clear_presses();
1881
 
                 //            mode_idx = 0;
1882
 
                 toggles(); // this is the main menu
 
2124
             _delay_s();       // wait for user to stop fast-pressing button
 
2125
             clear_presses(); // exit this mode after one use
 
2126
             //            mode_idx = 0;
 
2127
             toggles(); // this is the main menu
1883
2128
      }
1884
2129
      output = modes[mode_idx];
1885
2130
      actual_level = output;
1886
 
        }
 
2131
    }
 
2132
    
 
2133
    save_mode();
 
2134
  //************Finished startup**********************  
 
2135
    
 
2136
        
 
2137
  //****************************************************
 
2138
  //*********** The main on-time loop *****************
 
2139
    
1887
2140
    while(1) {
1888
2141
//#if defined(VOLTAGE_MON) || defined(USE_BATTCHECK)
1889
2142
//         ADC_on();  // switch (back) to voltage mode before the strobe or regular mode delay.
1893
2146
// Tried saving some space on these strobes, but it's not easy. gcc does ok though.
1894
2147
// Using a switch does create different code (more jump-table-ish, kind of), but it's not shorter.
1895
2148
        if (0) {} // dummy to get the conditionals started,
1896
 
                              // will optimize out.
1897
 
#ifdef STROBE_10HZ
1898
 
                else if (output == STROBE_10HZ) {
 
2149
                  // will optimize out.
 
2150
#ifdef USE_STROBE_10HZ
 
2151
        else if (output == STROBE_10HZ) {
1899
2152
            // 10Hz tactical strobe
1900
2153
            strobe(33,67);
1901
2154
        }
1902
2155
#endif // ifdef STROBE_10HZ
1903
 
#ifdef STROBE_16HZ
 
2156
#ifdef USE_STROBE_16HZ
1904
2157
        else if (output == STROBE_16HZ) {
1905
2158
            // 16.6Hz tactical strobe
1906
2159
            strobe(20,40);
1907
2160
        }
1908
2161
#endif // ifdef STROBE_16HZ
1909
 
#ifdef STROBE_8HZ
 
2162
#ifdef USE_STROBE_8HZ
1910
2163
        else if (output == STROBE_8HZ) {
1911
2164
            // 8.3Hz Tactical strobe
1912
2165
            strobe(40,80);
1913
2166
        }
1914
2167
#endif // ifdef STROBE_8HZ
1915
 
#ifdef STROBE_OLD_MOVIE
 
2168
#ifdef USE_STROBE_OLD_MOVIE
1916
2169
        else if (output == STROBE_OLD_MOVIE) {
1917
2170
            // Old movie effect strobe, like you some stop motion?
1918
2171
            strobe(1,41);
1919
2172
        }
1920
2173
#endif // ifdef STROBE_OLD_MOVIE
1921
 
#ifdef STROBE_CREEPY
 
2174
#ifdef USE_STROBE_CREEPY
1922
2175
        else if (output == STROBE_CREEPY) {
1923
2176
            // Creepy effect strobe stop motion effect that is quite cool or quite creepy, dpends how many friends you have with you I suppose.
1924
2177
            strobe(1,82);
1925
2178
        }
1926
2179
#endif // ifdef STROBE_CREEPY
1927
2180
 
1928
 
#ifdef POLICE_STROBE
 
2181
#ifdef USE_POLICE_STROBE
1929
2182
        else if (output == POLICE_STROBE) {
1930
2183
 
1931
2184
            // police-like strobe
1937
2190
            //}
1938
2191
        }
1939
2192
#endif // ifdef POLICE_STROBE
1940
 
#ifdef RANDOM_STROBE
 
2193
#ifdef USE_RANDOM_STROBE
1941
2194
        else if (output == RANDOM_STROBE) {
1942
2195
            // pseudo-random strobe
1943
2196
            uint8_t ms = 34 + (pgm_rand() & 0x3f);
1945
2198
            //strobe(ms, ms);
1946
2199
        }
1947
2200
#endif // ifdef RANDOM_STROBE
1948
 
#ifdef BIKING_STROBE
 
2201
#ifdef USE_BIKING_STROBE
1949
2202
        else if (output == BIKING_STROBE) {
1950
2203
            // 2-level stutter beacon for biking and such
1951
 
#ifdef FULL_BIKING_STROBE
 
2204
#ifdef USE_FULL_BIKING_STROBE
1952
2205
            // normal version
1953
2206
            for(i=0;i<4;i++) {
1954
2207
                set_level(TURBO);
1970
2223
#endif
1971
2224
        }
1972
2225
#endif  // ifdef BIKING_STROBE
1973
 
#ifdef SOS
 
2226
#ifdef USE_SOS
1974
2227
        else if (output == SOS) { SOS_mode(); }
1975
2228
#endif // ifdef SOS
1976
 
#ifdef RAMP
 
2229
#ifdef USE_RAMP
1977
2230
        else if (output == RAMP) {
1978
2231
            int8_t r;
1979
2232
            // simple ramping test
1991
2244
#ifdef USE_BATTCHECK
1992
2245
        else if (output == BATTCHECK) {
1993
2246
#ifdef BATTCHECK_VpT
1994
 
                        //blink_value(get_voltage()); // for debugging
 
2247
            //blink_value(get_voltage()); // for debugging
1995
2248
            // blink out volts and tenths
1996
2249
            _delay_ms(100);
1997
2250
            uint8_t result = battcheck();
2009
2262
            _delay_s(); _delay_s();
2010
2263
        }
2011
2264
#endif // ifdef USE_BATTCHECK
 
2265
 
 
2266
// **********output values here correspond to override modes. ************
 
2267
 
2012
2268
        else if (output == GROUP_SELECT_MODE) {
2013
2269
            // exit this mode after one use
2014
 
            mode_idx = 0;
2015
 
//            mode_override = 0;
 
2270
            //  Now done as default at top for all override modes.
 
2271
            //          mode_idx = 0;
 
2272
//            mode_override = 0; // old way
2016
2273
 
2017
2274
            for(i=0; i<NUM_MODEGROUPS; i++) {
2018
2275
                modegroup = i;
2022
2279
            }
2023
2280
            _delay_s(); _delay_s();
2024
2281
        }
2025
 
#ifdef TEMP_CAL_MODE
 
2282
#ifdef USE_TEMP_CAL
2026
2283
#ifdef TEMPERATURE_MON
2027
2284
        else if (output == TEMP_CAL_MODE) {
2028
2285
            // make sure we don't stay in this mode after button press
2029
 
            mode_idx = 0;
2030
 
//            mode_override = 0;
 
2286
            //  Now done as default at top for all override modes.
 
2287
            // mode_idx = 0;
 
2288
//            mode_override = 0; // old way
2031
2289
 
2032
2290
            // Allow the user to turn off thermal regulation if they want
2033
2291
            maxtemp = 255;
2047
2305
        }
2048
2306
#endif
2049
2307
#endif  // TEMP_CAL_MODE
2050
 
        else {  // Regular non-hidden solid mode
 
2308
 
 
2309
     //********* Otherwise, regular non-hidden solid modes: ****************
 
2310
 
 
2311
        else {  
2051
2312
//  moved this before temp check.  Temp check result will still apply on next loop.
2052
2313
// reason is with Vcc reads, we switch back and forth between ADC channels.
2053
2314
//  The get temperature includes a delay to stabilize ADC (maybe not needed)
2054
2315
//   That delay results in hesitation at turn on.
2055
2316
//  So turn on first.
2056
 
                set_mode(actual_level);            
 
2317
            set_mode(actual_level);                
2057
2318
#ifdef TEMPERATURE_MON
2058
2319
            temp=get_temperature();
2059
2320
  #if defined(VOLTAGE_MON) || defined(USE_BATTCHECK)
2060
2321
            ADC_on(); // switch back to voltage mode.
2061
2322
  #endif
2062
2323
#endif           
2063
 
                // If get_temp were done at the end of loop, could move temp conditionals outside 
2064
 
                // mode check to affect all modes including strobes,
2065
 
                // but get temp is too slow for strobes, would need to implement it in interrupts.
2066
 
                // Requires interrupt timing of temp, voltage, and delays between them though. :(        
 
2324
        // If get_temp were done at the end of loop, could move temp conditionals outside 
 
2325
        // mode check to affect all modes including strobes,
 
2326
        // but get temp is too slow for strobes, would need to implement it in interrupts.
 
2327
        // Requires interrupt timing of temp, voltage, and delays between them though. :(        
2067
2328
 
2068
2329
// Temp control methods:
2069
2330
// Notice we don't actually have a temp reading yet on first loop, will be zero, that's ok.
2070
2331
#ifdef CLASSIC_TEMPERATURE_MON //this gets set by default.
2071
2332
            // Tries to regulate temparature in all modes.
2072
 
                        // This has issues.  First, it's very hard to get right and very hardware dependent
 
2333
            // This has issues.  First, it's very hard to get right and very hardware dependent
2073
2334
            // If you get it right you likely don't get a turbo boost at all
2074
 
                        // but just stabilize at a sustainable temp.  Even if you do get a 
2075
 
                        //  turbo boost, then you get either
2076
 
                        // eventual stabilization at max temp, no more turbo boosts possible after that really,
2077
 
                        // Or you get up and down and up and down at random times.
2078
 
                        // If we want sustainable regulation we should do that.  
2079
 
                        // If we want controlled tubro boosts we should do that, 
2080
 
                        //  and come back down to cool off and be ready for another turbo on demand.
2081
 
                        // So FR dividing these needs going forward with new options below.
2082
 
                        //
 
2335
            // but just stabilize at a sustainable temp.  Even if you do get a 
 
2336
            //  turbo boost, then you get either
 
2337
            // eventual stabilization at max temp, no more turbo boosts possible after that really,
 
2338
            // Or you get up and down and up and down at random times.
 
2339
            // If we want sustainable regulation we should do that.  
 
2340
            // If we want controlled tubro boosts we should do that, 
 
2341
            //  and come back down to cool off and be ready for another turbo on demand.
 
2342
            // So FR dividing these needs going forward with new options below.
 
2343
            //
2083
2344
            // step down? (or step back up?)
2084
2345
             if (temp > maxtemp) {
2085
2346
                overheat_count ++;
2097
2358
                }
2098
2359
             }
2099
2360
 #elif defined(TEMP_STEP_DOWN)|| defined (USE_TURBO_TIMEOUT) // BLFA6 inspired stepdown modes, by FR
2100
 
                         // now using this to count minimum up time before step down is activated.
2101
 
                         // We do NOT need to be overheated that long though.
2102
 
                 overheat_count ++;                      
2103
 
                 // choose the step_down condition:
 
2361
             // now using this to count minimum up time before step down is activated.
 
2362
             // We do NOT need to be overheated that long though.
 
2363
             overheat_count ++;                  
 
2364
         // choose the step_down condition:
2104
2365
         #ifdef TEMP_STEP_DOWN
2105
 
                    // For stepdown to occur,
2106
 
                    // need to be overheated AND past the MINIMUM_TURBO_TIME and in a level higher than the step down level:
 
2366
            // For stepdown to occur,
 
2367
            // need to be overheated AND past the MINIMUM_TURBO_TIME and in a level higher than the step down level:
2107
2368
             if (temp >= maxtemp && actual_level > TURBO_STEPDOWN 
2108
 
                               && overheat_count > (uint8_t)((double)(MINIMUM_TURBO_TIME)*(double)1000/(double)LOOP_SLEEP)) {
2109
 
                 #elif defined(USE_TURBO_TIMEOUT)
2110
 
                   // for non-temp based method, need to be in TURBO mode and past TURBO_TIMEOUT for step down:
 
2369
                   && overheat_count > (uint8_t)((double)(MINIMUM_TURBO_TIME)*(double)1000/(double)LOOP_SLEEP)) {
 
2370
         #elif defined(USE_TURBO_TIMEOUT)
 
2371
           // for non-temp based method, need to be in TURBO mode and past TURBO_TIMEOUT for step down:
2111
2372
             if ((output == TURBO) && overheat_count > (uint8_t)((double)(TURBO_TIMEOUT)*(double)1000/(double)LOOP_SLEEP) ) {
2112
 
                 #endif
2113
 
                       // can't use BLFA6 mode change since we don't have predictable modes.
2114
 
                       // Must change actual_level, and lockout mode advance on next click.
 
2373
         #endif
 
2374
                   // can't use BLFA6 mode change since we don't have predictable modes.
 
2375
                   // Must change actual_level, and lockout mode advance on next click.
2115
2376
//                     output=TURBO_STEPDOWN;
2116
 
                       actual_level=TURBO_STEPDOWN;
2117
 
                       disable_next(); // next forward press will keep turbo mode.
2118
 
                                                              // this value is immune to clear_presses.
 
2377
                   actual_level=TURBO_STEPDOWN;
 
2378
                   disable_next(); // next forward press will keep turbo mode.
 
2379
                                              // this value is immune to clear_presses.
2119
2380
             } 
2120
2381
             
2121
2382
// end of temperature control methods.
2122
2383
#endif
 
2384
        //the loop delay for regular modes:
2123
2385
         _delay_ms(LOOP_SLEEP);
2124
 
         // We've taken our time, either with regular mode delay or one strobe cycle.
2125
 
         // So the user isn't fast pressing anymore.
2126
 
         // Temp control methods do this above since they use this variable for other purposes too.
2127
 
 
2128
 
          clear_presses();
2129
 
        } // end of mode conditional
2130
 
 
2131
 
 
2132
 
//****** Now things to do in loop after every mode **************/
 
2386
        } 
 
2387
 
 
2388
        // We've taken our time, either with regular mode delay or one strobe cycle.
 
2389
        // So the user isn't fast pressing anymore.
 
2390
 
 
2391
        clear_presses();
 
2392
        // ********end of mode conditional************
 
2393
 
 
2394
        //****** Now things to do in loop after every mode **************/
2133
2395
 
2134
2396
 
2135
2397
#ifdef VOLTAGE_MON
2140
2402
                lowbatt_cnt = 0;
2141
2403
            }
2142
2404
            // See if it's been low for a while, and maybe step down
2143
 
                        // Why do we need 8 checks?  Battcheck works fine with one.
2144
 
                        // Is there some corner condition when this goes wrong?
 
2405
            // Why do we need 8 checks?  Battcheck works fine with one.
 
2406
            // Is there some corner condition when this goes wrong?
2145
2407
            if (lowbatt_cnt >= 8) {
2146
2408
                if (actual_level > RAMP_SIZE) {  // hidden / blinky modes
2147
2409
                    // step down from blinky modes to medium
2155
2417
                    set_level(0);
2156
2418
                    // Power down as many components as possible
2157
2419
                    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
2158
 
                                        cli(); // make sure not to wake back up.
2159
 
                                #if (ATTINY>13) // could macro define it in headers, but this is more clear:
2160
 
                                        sleep_bod_disable();// power goes from 25uA to 4uA.
2161
 
                                #endif
2162
 
                    sleep_mode();
 
2420
                    cli(); // make sure not to wake back up.
 
2421
                #if (ATTINY>13) // could macro define it in headers, but this is more clear:
 
2422
                    sleep_bod_disable();// power goes from 25uA to 4uA.
 
2423
                #endif
 
2424
                    sleep_mode(); 
2163
2425
                }
2164
2426
//                set_mode(actual_level); // redundant
2165
2427
                output = actual_level; //This mostly just pulls out of strobes.
2174
2436
    }// end of main while loop
2175
2437
}// end of main.
2176
2438
 
 
2439
//TODO -FR
 
2440
// Change OTSM debounce to watchdog sleep... maybe (implemented in comments)
 
2441
// fix mode_save commit.
 
2442
//Ideas for farther ahead:
 
2443
//Try shortening medium click for OTSM, may require adding finer timing resulotion for all times, or possibly just early times. (has?a cap performance?cost, but it's performing better than needed now).
 
2444
//Maybe rework dual switch stuff so every click type can be given assigned an action type in the configs. ?Hard to keep the programming tight, and clean, but avoids endless options.
 
2445
//In particular consider reverse click order for power switch, maybe separately from above plan.