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;
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;
674
748
//initial_values(): Intialize default configuration values
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.
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.
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
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
758
#elif firstboot_IDX <= final_toggles
759
firstboot=255; // disables menu toggle
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,
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,
700
memory = INIT_MEMORY; // mode memory, or not
703
offtim3 = INIT_OFFTIM3; // enable medium-press?
704
#elif offtim3_IDX <= final_toggles
705
offtim3=255; //disable menu toggle,
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,
714
#ifdef USE_LOCKSWITCH
715
lockswitch=INIT_LOCKSWITCH; // E-swtich enabled.
716
#elif lockswitch_IDX <= final_toggles
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,
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,
773
memory = INIT_MEMORY; // mode memory, or not
776
offtim3 = INIT_OFFTIM3; // enable medium-press?
777
#elif offtim3_IDX <= final_toggles
778
offtim3=255; //disable menu toggle,
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,
787
#ifdef USE_LOCKSWITCH
788
lockswitch=INIT_LOCKSWITCH; // E-swtich enabled.
789
#elif lockswitch_IDX <= final_toggles
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
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
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:
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
743
// We always need the group select mode toggle:
744
overrides[5]=GROUP_SELECT_MODE;
808
#if TEMP_CAL_IDX <= final_toggles
809
// then disable the toggle:
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
815
// We always need the group select mode toggle:
816
overrides[5]=GROUP_SELECT_MODE;
752
824
// save the mode_idx variable:
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)
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.
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.
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.
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.
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;
907
976
uint8_t my_enable_moon = enable_moon;
909
#define my_enable_moon 0
911
#if defined(USE_REVERSE_MODES) && defined(OFFTIM3)
978
#define my_enable_moon 0
980
#if defined(USE_REVERSE_MODES) && defined(OFFTIM3)
912
981
uint8_t my_reverse_modes = reverse_modes;
914
#define my_reverse_modes 0
983
#define my_reverse_modes 0
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;
922
991
my_enable_moon = 0;
924
#if defined(USE_REVERSE_MODES)&&defined(OFFTIM3)
993
#if defined(USE_REVERSE_MODES)&&defined(OFFTIM3)
925
994
my_reverse_modes = 0;
929
998
//my_modegroup=11;
930
999
//my_reverse_modes=0; // FOR TESTING
933
1002
// const uint8_t *src = modegroups + (my_modegroup<<3);
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;
943
1012
// now find start and end in one pass
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++))){
953
solid_modes=(uint8_t)(src-start);
954
} // every 0 starts a new modegroup, decrement i
1022
solid_modes=(uint8_t)(src-start);
1023
} // every 0 starts a new modegroup, decrement i
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.
1373
// volatile I/O once at the end.
1374
// The constant temp variable calculations get optimized out. Saves ~30 bytes on big builds.
1307
1376
uint8_t t_DDRB=0;
1309
1378
#ifdef USE_CLCK0
1313
1382
#ifdef USE_CLCK1
1317
1386
// start by disabling all digital input.
1318
1387
// PWM pins will get set as output anyway.
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.
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.
1392
// Charge up the capacitor by setting CAP_PIN to output
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)
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
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.
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.
1341
t_DDRB |= (1 << PWM_PIN) ;
1344
t_DDRB |= (1 << PWM2_PIN);
1412
t_DDRB |= (1 << PWM_PIN) ;
1415
t_DDRB |= (1 << PWM2_PIN);
1346
1417
#ifdef PWM3_PIN
1347
t_DDRB |= (1 << PWM3_PIN);
1418
t_DDRB |= (1 << PWM3_PIN);
1349
1420
#ifdef PWM4_PIN
1350
1421
t_DDRB |= (1 << PWM4_PIN);
1354
// Set Timer 0 to do PWM1 and PWM2 or for OTSM powersave timing
1425
// Set Timer 0 to do PWM1 and PWM2 or for OTSM powersave timing
1355
1426
#ifdef USE_CLCK0
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.
1365
1436
#ifdef USE_PWM1
1366
t_TCCR0A |= (1<<COM0B1); // enable PWM on PB1
1369
t_TCCR0A |= (1<<COM0A1); // enable PWM on PB0
1437
t_TCCR0A |= (1<<COM0B1); // enable PWM on PB1
1440
t_TCCR0A |= (1<<COM0A1); // enable PWM on PB0
1373
1444
//Set Timer1 to do PWM3 and PWM4
1376
// FR: this timer does not appear to have any phase mode.
1377
// The frequency appears to be just system clock/255
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
1447
// FR: this timer does not appear to have any phase mode.
1448
// The frequency appears to be just system clock/255
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
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.
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.
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.
1468
t_PORTB|=(~t_DDRB); // Anything that is not an output gets a pullup resistor
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
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
1484
PCMSK |= 1<< ESWITCH_PIN; // catch pin change on eswitch pin
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
1410
#if defined(USE_ESWITCH) || defined(USE_OTSM)
1411
GIMSK |= 1<<PCIE; // enable PIN change interrupt
1413
GIFR |= PCIF; // Clear pin change interrupt flag
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
1416
1501
// save the compiled results out to the I/O registers:
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.
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"
1617
__asm__ __volatile__ (
1618
"sbic %[aGbit_addr] , %[aPwm4zero_bit] \n\t" // if pwm4zero isn't set...
1620
"sbi %[aPortb] , %[aPwm4_pin] \n\t" //set bit in PORTB (0x18) to make PW4_PIN high.
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)
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...
1535
"sbi 0x18 , " Quote(PWM4_PIN) " \n\t" //set bit in PORTB (0x18) to make PW4_PIN high.
1631
__asm__ __volatile__ ( //
1632
"cbi %[aPortb] , %[aPwm4_pin] \n\t"
1634
::[aPortb] "I" (_SFR_IO_ADDR(PORTB)),
1635
[aPwm4_pin] "I" (PWM4_PIN)
1541
1640
#if defined(USE_OTSM) || defined(USE_ESWITCH)
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);
1657
// return from wake ISR's here, both watchdog and pin change.
1659
WDTCR &= ~(1<<WDIE); // disable watchdog interrupt (prevents glitching the strobe sleeps later).
1542
1662
// Off-time sleep mode by -FR, thanks to flashy Mike and Mike C for early feasibility test with similar methods.
1544
1664
//need to declare main here to jump to it from ISR.
1666
void Button_press();
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
1551
// 2017 by Flintrock (C)
1671
void __attribute__((naked, used, externally_visible)) PCINT0_vect (void) {
1672
//ISR(PCINT0_vect) {
1673
// Dual watchdog pin change power-on wake by FR
1675
// 2017 by Flintrock (C)
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().
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.
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.
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;
1580
#define sleep_time_exponent SLEEP_TIME_EXPONENT
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.
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.
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,
1709
__asm__ __volatile__ ("reti");
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.
1725
__asm__ __volatile__ ("CLR R1"); // We do need a clean zero-register (yes, that's R1).
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;
1730
#define sleep_time_exponent SLEEP_TIME_EXPONENT
1587
1733
// we only pass this section once, can do initialization here:
1588
// e_status=0b00000001; //startoff in standby with pin low (button pressed)
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:
1596
1741
uint8_t inputs=0; // temp variable designed to get optimized out.
1598
inputs |= (1 << PWM_PIN) ;
1601
inputs |= (1 << PWM2_PIN) ;
1604
inputs |= (1 << PWM3_PIN) ;
1607
inputs |= (1 << PWM4_PIN) ;
1743
inputs |= (1 << PWM_PIN) ;
1746
inputs |= (1 << PWM2_PIN) ;
1749
inputs |= (1 << PWM3_PIN) ;
1752
inputs |= (1 << PWM4_PIN) ;
1756
#ifdef USE_INDICATOR
1757
// turn off the indicator to acknowledge button is pressed:
1758
PORTB &= ~(1<<INDICATOR_PIN);
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.
1618
while(1) { // keep going to sleep until power is on
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.
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.
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;
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.
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
1654
sleep_time_exponent=9; // 16ms*2^9=8s, maximum watchod timeout.
1657
continue; // still in standby, go back to sleep.
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.
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
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
1768
while(1) { // keep going to sleep until power is on
1770
#if defined(USE_ESWITCH)
1772
//***************DO DEBOUNCING ******************
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.
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.
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.
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
1804
// asm volatile ("" ::: "memory"); // just in case, no i/o reordering around these. It's a no-op.
1807
//**** DETERMINE PRESENT STATE AND RESTART DECISION, EVOLVED THROUGH CLICK HISTORY
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.
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)));
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;
1834
//****** If a switch is released, what do we do? *******
1835
// ** Restart or go to off-sleep?
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.
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.
1862
//***Things to do at start of long-press timeout:
1863
if ( wake_count == wake_count_med){// long press is now inevitable
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,
1873
#ifdef USE_INDICATOR
1874
// re-light the indicator to acknowledge turn-off
1875
PORTB |= (1<<INDICATOR_PIN);
1879
//*** Handle pressing the switch again from off ***//
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);
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
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.
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!
1686
// return from wake ISR's here, both watchdog and pin change.
1688
// Now just figure out what pins are pressed and if we're coming or going, not as simple as it sounds.
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)
1691
/*** Do a soft "reset" of sorts. **/
1905
/******************* Do a soft "reset" of sorts. ********************/
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 )
1698
SREG=0; // clear status register
1913
SREG=0; // clear status register.
1699
1914
main(); // start over, bypassing initialization.
1703
1917
ISR(WDT_vect, ISR_NAKED) // watchdog interrupt handler -FR
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.
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.
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,
1756
1975
wake_count=wake_count_short; // med press, will move back into hidden mode.
1758
#elif defined(REVERSE_CLICK)// power switch reverses modes.
1977
#elif defined(REVERSE_CLICK)// power switch reverses modes.
1759
1978
//not implemented,
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
1777
wake_count=0; // short press
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).
1788
#elif defined(USE_OTC)
1789
#if !defined(USE_OTSM)
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:
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.
1803
init_mcu(); // setup pins, prescalers etc, configure/enable interrupts, etc.
1810
blink_value(cap_val);
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
1996
wake_count=0; // short press
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).
2007
#elif defined(USE_OTC)
2008
#if !defined(USE_OTSM)
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:
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.
1814
2022
restore_state(); // loads user configurations
1816
2024
// Disable e-switch interrupt if it's locked out:
1817
2025
#if defined(USE_ESWITCH_LOCKOUT_TOGGLE) && (ESWITCH_PIN != OTSM_PIN)
1819
2027
PCMSK&=~(1<<ESWITCH_PIN);
2031
count_modes(); // build the working mode group using configured choices.
2033
change_mode(); // advance, reverse, stay put?
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.
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.
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
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.
1829
2058
blink_value(tempval);
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.
1837
// wake_time=0; // use this to make every click act like a fast one for debugging.
1839
count_modes(); // build the working mode group using configured choices.
1841
change_mode(); // advance, reverse, stay put?
1843
#if defined(USE_OTSM) || defined(USE_ESWITCH)
1844
wake_count=0; // reset the wake counter.
2063
blink_value(cap_val);
1850
2072
#if defined(VOLTAGE_MON) || defined(USE_BATTCHECK)