~toykeeper/flashlight-firmware/trunk

153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
1
/*
153.1.10 by Selene Scriven
Got smooth ramping to work on FET+1 driver. Added a ramp mode for testing.
2
 * "Bistro" firmware
3
 * This code runs on a single-channel or dual-channel driver (FET+7135)
4
 * with an attiny25/45/85 MCU and a capacitor to measure offtime (OTC).
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
5
 *
6
 * Copyright (C) 2015 Selene Scriven
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 *
21
 *
153.1.10 by Selene Scriven
Got smooth ramping to work on FET+1 driver. Added a ramp mode for testing.
22
 * ATTINY25/45/85 Diagram
23
 *           ----
24
 *         -|1  8|- VCC
25
 *     OTC -|2  7|- Voltage ADC
26
 *  Star 3 -|3  6|- PWM (FET, optional)
27
 *     GND -|4  5|- PWM (1x7135)
28
 *           ----
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
29
 *
30
 * FUSES
227 by Selene Scriven
Replaced outdated fuse value messages with a pointer to more actively maintained scripts.
31
 *      (check bin/flash*.sh for recommended values)
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
32
 *
33
 * STARS
153.1.10 by Selene Scriven
Got smooth ramping to work on FET+1 driver. Added a ramp mode for testing.
34
 *      Star 3 = unused
35
 *
36
 * CALIBRATION
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
37
 *
38
 *   To find out what values to use, flash the driver with battcheck.hex
39
 *   and hook the light up to each voltage you need a value for.  This is
40
 *   much more reliable than attempting to calculate the values from a
41
 *   theoretical formula.
42
 *
43
 *   Same for off-time capacitor values.  Measure, don't guess.
44
 */
45
// Choose your MCU here, or in the build script
46
//#define ATTINY 13
47
//#define ATTINY 25
48
// FIXME: make 1-channel vs 2-channel power a single #define option
49
#define FET_7135_LAYOUT  // specify an I/O pin layout
50
// Also, assign I/O pins in this file:
153.1.51 by Selene Scriven
Removed the need to specify header file paths.
51
#include "tk-attiny.h"
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
52
53
/*
54
 * =========================================================================
55
 * Settings to modify per driver
56
 */
57
153.1.10 by Selene Scriven
Got smooth ramping to work on FET+1 driver. Added a ramp mode for testing.
58
// FIXME: make 1-channel vs 2-channel power a single #define option
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
59
//#define FAST 0x23           // fast PWM channel 1 only
60
//#define PHASE 0x21          // phase-correct PWM channel 1 only
61
#define FAST 0xA3           // fast PWM both channels
62
#define PHASE 0xA1          // phase-correct PWM both channels
63
64
#define VOLTAGE_MON         // Comment out to disable LVP
65
66
#define OFFTIM3             // Use short/med/long off-time presses
67
                            // instead of just short/long
68
153.1.54 by Selene Scriven
Adjusted x**3 ramp to match the BLF X6v2 better and give it a 100% 7135 mode.
69
// ../../bin/level_calc.py 64 1 10 1300 y 3 0.23 140
153.1.10 by Selene Scriven
Got smooth ramping to work on FET+1 driver. Added a ramp mode for testing.
70
#define RAMP_SIZE  64
71
// log curve
72
//#define RAMP_7135  3,3,3,3,3,3,4,4,4,4,4,5,5,5,6,6,7,7,8,9,10,11,12,13,15,16,18,21,23,27,30,34,39,44,50,57,65,74,85,97,111,127,145,166,190,217,248,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0
73
//#define RAMP_FET   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,6,11,17,23,30,39,48,59,72,86,103,121,143,168,197,255
74
// x**2 curve
75
//#define RAMP_7135  3,5,8,12,17,24,32,41,51,63,75,90,105,121,139,158,178,200,223,247,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0
76
//#define RAMP_FET   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,4,6,9,12,16,19,22,26,30,33,37,41,45,50,54,59,63,68,73,78,84,89,94,100,106,111,117,123,130,136,142,149,156,162,169,176,184,191,198,206,214,221,255
77
// x**3 curve
153.1.54 by Selene Scriven
Adjusted x**3 ramp to match the BLF X6v2 better and give it a 100% 7135 mode.
78
#define RAMP_7135  3,3,4,5,6,8,10,12,15,19,23,28,33,40,47,55,63,73,84,95,108,122,137,153,171,190,210,232,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0
79
#define RAMP_FET   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,5,8,11,14,18,22,26,30,34,39,44,49,54,59,65,71,77,84,91,98,105,113,121,129,137,146,155,164,174,184,194,205,216,255
153.1.10 by Selene Scriven
Got smooth ramping to work on FET+1 driver. Added a ramp mode for testing.
80
// x**5 curve
153.1.16 by Selene Scriven
Added volts+tenths and 8-bar battery check styles.
81
//#define RAMP_7135  3,3,3,4,4,5,5,6,7,8,10,11,13,15,18,21,24,28,33,38,44,50,57,66,75,85,96,108,122,137,154,172,192,213,237,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0
82
//#define RAMP_FET   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,6,9,13,17,21,25,30,35,41,47,53,60,67,75,83,91,101,111,121,132,144,156,169,183,198,213,255
153.1.10 by Selene Scriven
Got smooth ramping to work on FET+1 driver. Added a ramp mode for testing.
83
153.1.13 by Selene Scriven
Added a soft start option, to ramp up to the desired level instead of jumping straight to it.
84
// uncomment to ramp up/down to a mode instead of jumping directly
85
#define SOFT_START
153.1.12 by Selene Scriven
Replaced two-channel output control with abstracted visual-level ramp.
86
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
87
// Enable battery indicator mode?
88
#define USE_BATTCHECK
89
// Choose a battery indicator style
90
//#define BATTCHECK_4bars  // up to 4 blinks
91
//#define BATTCHECK_8bars  // up to 8 blinks
92
#define BATTCHECK_VpT  // Volts + tenths
93
94
// output to use for blinks on battery check (and other modes)
95
#define BLINK_BRIGHTNESS    RAMP_SIZE/4
96
// ms per normal-speed blink
97
#define BLINK_SPEED         500
98
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
99
// Hidden modes are *before* the lowest (moon) mode, and should be specified
100
// in reverse order.  So, to go backward from moon to turbo to strobe to
101
// battcheck, use BATTCHECK,STROBE,TURBO .
153.1.37 by Selene Scriven
Improved thermal regulation behavior, added no-regulation option,
102
#define HIDDENMODES         BIKING_STROBE,BATTCHECK,POLICE_STROBE,TURBO
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
103
153.1.13 by Selene Scriven
Added a soft start option, to ramp up to the desired level instead of jumping straight to it.
104
#define TURBO     RAMP_SIZE       // Convenience code for turbo mode
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
105
#define BATTCHECK 254       // Convenience code for battery check mode
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
106
#define GROUP_SELECT_MODE 253
107
#define TEMP_CAL_MODE 252
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
108
// Uncomment to enable tactical strobe mode
153.1.37 by Selene Scriven
Improved thermal regulation behavior, added no-regulation option,
109
//#define STROBE    251       // Convenience code for strobe mode
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
110
// Uncomment to unable a 2-level stutter beacon instead of a tactical strobe
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
111
#define BIKING_STROBE 250   // Convenience code for biking strobe mode
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
112
// comment out to use minimal version instead (smaller)
113
#define FULL_BIKING_STROBE
153.1.37 by Selene Scriven
Improved thermal regulation behavior, added no-regulation option,
114
//#define RAMP 249       // ramp test mode for tweaking ramp shape
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
115
#define POLICE_STROBE 248
153.1.37 by Selene Scriven
Improved thermal regulation behavior, added no-regulation option,
116
//#define RANDOM_STROBE 247
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
117
//#define SOS 246
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
118
153.1.23 by Selene Scriven
Replaced bistro's turbo timeout with thermal step-down.
119
// thermal step-down
120
#define TEMPERATURE_MON
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
121
122
// Calibrate voltage and OTC in this file:
153.1.51 by Selene Scriven
Removed the need to specify header file paths.
123
#include "tk-calibration.h"
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
124
125
/*
126
 * =========================================================================
127
 */
128
129
// Ignore a spurious warning, we did the cast on purpose
130
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
131
132
#include <avr/pgmspace.h>
133
//#include <avr/io.h>
134
//#include <avr/interrupt.h>
135
#include <avr/eeprom.h>
136
#include <avr/sleep.h>
137
//#include <avr/power.h>
153.1.26 by Selene Scriven
Gave bistro.c 8 mode groups, made count_modes() build the mode array at runtime.
138
#include <string.h>
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
139
140
#define OWN_DELAY           // Don't use stock delay functions.
188 by Selene Scriven
Made bistro compile again, after last commit's changes to tk-voltage.h.
141
#define USE_DELAY_MS        // Also use _delay_ms()
142
#define USE_DELAY_S         // Also use _delay_s()
153.1.51 by Selene Scriven
Removed the need to specify header file paths.
143
#include "tk-delay.h"
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
144
153.1.51 by Selene Scriven
Removed the need to specify header file paths.
145
#include "tk-voltage.h"
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
146
153.1.21 by Selene Scriven
Added a pseudo-random strobe mode to bistro.c.
147
#ifdef RANDOM_STROBE
153.1.51 by Selene Scriven
Removed the need to specify header file paths.
148
#include "tk-random.h"
153.1.21 by Selene Scriven
Added a pseudo-random strobe mode to bistro.c.
149
#endif
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
150
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
151
/*
152
 * global variables
153
 */
154
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
155
// Config option variables
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
156
#define USE_FIRSTBOOT
157
#ifdef USE_FIRSTBOOT
153.1.49 by Selene Scriven
Added a factory reset config option.
158
#define FIRSTBOOT 0b01010101
159
uint8_t firstboot = FIRSTBOOT;  // detect initial boot or factory reset
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
160
#endif
153.1.37 by Selene Scriven
Improved thermal regulation behavior, added no-regulation option,
161
uint8_t modegroup = 5;     // which mode group (set above in #defines)
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
162
uint8_t enable_moon = 1;   // Should we add moon to the set of modes?
153.1.32 by Selene Scriven
Added mode-reversing option (high to low order).
163
uint8_t reverse_modes = 0; // flip the mode order?
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
164
uint8_t memory = 0;        // mode memory, or not (set via soldered star)
153.1.17 by Selene Scriven
Converted bistro to use top of EEPROM for config, bottom of EEPROM for wear-levelled mode index.
165
#ifdef OFFTIM3
166
uint8_t offtim3 = 1;       // enable medium-press?
167
#endif
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
168
#ifdef TEMPERATURE_MON
153.1.40 by Selene Scriven
Thermal step-down seems to work reasonably well on the BLF X6 now.
169
uint8_t maxtemp = 79;      // temperature step-down threshold
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
170
#endif
153.1.47 by Selene Scriven
Added muggle mode / simple mode / loaning-the-light-to-a-friend mode.
171
uint8_t muggle_mode = 0;   // simple mode designed for muggles
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
172
// Other state variables
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
173
uint8_t mode_override = 0; // do we need to enter a special mode?
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
174
uint8_t mode_idx = 0;      // current or last-used mode number
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
175
uint8_t eepos = 0;
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
176
// counter for entering config mode
177
// (needs to be remembered while off, but only for up to half a second)
178
uint8_t fast_presses __attribute__ ((section (".noinit")));
179
180
// total length of current mode group's array
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
181
#ifdef OFFTIM3
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
182
uint8_t mode_cnt;
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
183
#endif
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
184
// number of regular non-hidden modes in current mode group
185
uint8_t solid_modes;
186
// number of hidden modes in the current mode group
187
// (hardcoded because both groups have the same hidden modes)
188
//uint8_t hidden_modes = NUM_HIDDEN;  // this is never used
189
190
153.1.27 by Selene Scriven
Cleaned out old mode group code. Adjusted new mode group levels. Added half of moon toggle.
191
PROGMEM const uint8_t hiddenmodes[] = { HIDDENMODES };
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
192
// default values calculated by group_calc.py
153.1.42 by Selene Scriven
Made bistro accommodate custom mode groups better,
193
// Each group must be 8 values long, but can be cut short with a zero.
153.1.54 by Selene Scriven
Adjusted x**3 ramp to match the BLF X6v2 better and give it a 100% 7135 mode.
194
#define NUM_MODEGROUPS 9  // don't count muggle mode
153.1.26 by Selene Scriven
Gave bistro.c 8 mode groups, made count_modes() build the mode array at runtime.
195
PROGMEM const uint8_t modegroups[] = {
196
    64,  0,  0,  0,  0,  0,  0,  0,
153.1.54 by Selene Scriven
Adjusted x**3 ramp to match the BLF X6v2 better and give it a 100% 7135 mode.
197
    11, 64,  0,  0,  0,  0,  0,  0,
198
    11, 35, 64,  0,  0,  0,  0,  0,
199
    11, 26, 46, 64,  0,  0,  0,  0,
200
    11, 23, 36, 50, 64,  0,  0,  0,
201
    11, 20, 31, 41, 53, 64,  0,  0,
202
    29, 64,POLICE_STROBE,0,0,0,0,0,  // 7: special group A
203
    BIKING_STROBE,BATTCHECK,11,29,64,0,0,0,  // 8: special group B
204
     9, 18, 29, 46, 64,  0,  0,  0,  // 9: special group C
205
    11, 29, 50,  0,                  // muggle mode, exception to "must be 8 bytes long"
153.1.26 by Selene Scriven
Gave bistro.c 8 mode groups, made count_modes() build the mode array at runtime.
206
};
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
207
//uint8_t modes[] = { 1,2,3,4,5,6,7,8,9, HIDDENMODES };  // make sure this is long enough...
208
uint8_t modes[9 + sizeof(hiddenmodes)];  // make sure this is long enough...
153.1.26 by Selene Scriven
Gave bistro.c 8 mode groups, made count_modes() build the mode array at runtime.
209
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
210
// Modes (gets set when the light starts up based on saved config values)
153.1.10 by Selene Scriven
Got smooth ramping to work on FET+1 driver. Added a ramp mode for testing.
211
PROGMEM const uint8_t ramp_7135[] = { RAMP_7135 };
212
PROGMEM const uint8_t ramp_FET[]  = { RAMP_FET };
213
153.1.17 by Selene Scriven
Converted bistro to use top of EEPROM for config, bottom of EEPROM for wear-levelled mode index.
214
void save_mode() {  // save the current mode index (with wear leveling)
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
215
    uint8_t oldpos=eepos;
216
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
217
    eepos = (eepos+1) & ((EEPSIZE/2)-1);  // wear leveling, use next cell
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
218
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
219
    eeprom_write_byte((uint8_t *)(eepos), mode_idx);  // save current state
220
    eeprom_write_byte((uint8_t *)(oldpos), 0xff);     // erase old state
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
221
}
222
153.1.17 by Selene Scriven
Converted bistro to use top of EEPROM for config, bottom of EEPROM for wear-levelled mode index.
223
#define OPT_firstboot (EEPSIZE-1)
224
#define OPT_modegroup (EEPSIZE-2)
225
#define OPT_memory (EEPSIZE-3)
226
#define OPT_offtim3 (EEPSIZE-4)
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
227
#define OPT_maxtemp (EEPSIZE-5)
228
#define OPT_mode_override (EEPSIZE-6)
153.1.29 by Selene Scriven
Added runtime option for moon. Re-ordered config options.
229
#define OPT_moon (EEPSIZE-7)
153.1.32 by Selene Scriven
Added mode-reversing option (high to low order).
230
#define OPT_revmodes (EEPSIZE-8)
153.1.47 by Selene Scriven
Added muggle mode / simple mode / loaning-the-light-to-a-friend mode.
231
#define OPT_muggle (EEPSIZE-9)
153.1.17 by Selene Scriven
Converted bistro to use top of EEPROM for config, bottom of EEPROM for wear-levelled mode index.
232
void save_state() {  // central method for writing complete state
233
    eeprom_write_byte((uint8_t *)OPT_modegroup, modegroup);
234
    eeprom_write_byte((uint8_t *)OPT_memory, memory);
235
#ifdef OFFTIM3
236
    eeprom_write_byte((uint8_t *)OPT_offtim3, offtim3);
237
#endif
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
238
#ifdef TEMPERATURE_MON
239
    eeprom_write_byte((uint8_t *)OPT_maxtemp, maxtemp);
240
#endif
241
    eeprom_write_byte((uint8_t *)OPT_mode_override, mode_override);
153.1.29 by Selene Scriven
Added runtime option for moon. Re-ordered config options.
242
    eeprom_write_byte((uint8_t *)OPT_moon, enable_moon);
153.1.32 by Selene Scriven
Added mode-reversing option (high to low order).
243
    eeprom_write_byte((uint8_t *)OPT_revmodes, reverse_modes);
153.1.47 by Selene Scriven
Added muggle mode / simple mode / loaning-the-light-to-a-friend mode.
244
    eeprom_write_byte((uint8_t *)OPT_muggle, muggle_mode);
198 by Selene Scriven
Tiny bistro update, should make eeprom less likely to hit a corner case on first boot.
245
#ifdef USE_FIRSTBOOT
246
    eeprom_write_byte((uint8_t *)OPT_firstboot, firstboot);
247
#endif
248
249
    save_mode();
153.1.17 by Selene Scriven
Converted bistro to use top of EEPROM for config, bottom of EEPROM for wear-levelled mode index.
250
}
251
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
252
#ifndef USE_FIRSTBOOT
253
inline void reset_state() {
254
    mode_idx = 0;
255
    modegroup = 5;
256
    save_state();
257
}
258
#endif
259
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
260
void restore_state() {
261
    uint8_t eep;
153.1.17 by Selene Scriven
Converted bistro to use top of EEPROM for config, bottom of EEPROM for wear-levelled mode index.
262
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
263
#ifdef USE_FIRSTBOOT
153.1.17 by Selene Scriven
Converted bistro to use top of EEPROM for config, bottom of EEPROM for wear-levelled mode index.
264
    // check if this is the first time we have powered on
265
    eep = eeprom_read_byte((uint8_t *)OPT_firstboot);
266
    if (eep != FIRSTBOOT) {
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
267
        // not much to do; the defaults should already be set
268
        // while defining the variables above
153.1.17 by Selene Scriven
Converted bistro to use top of EEPROM for config, bottom of EEPROM for wear-levelled mode index.
269
        save_state();
270
        return;
271
    }
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
272
#else
273
    uint8_t first = 1;
274
#endif
153.1.17 by Selene Scriven
Converted bistro to use top of EEPROM for config, bottom of EEPROM for wear-levelled mode index.
275
276
    // find the mode index data
277
    for(eepos=0; eepos<(EEPSIZE/2); eepos++) {
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
278
        eep = eeprom_read_byte((const uint8_t *)eepos);
153.1.17 by Selene Scriven
Converted bistro to use top of EEPROM for config, bottom of EEPROM for wear-levelled mode index.
279
        if (eep != 0xff) {
280
            mode_idx = eep;
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
281
#ifndef USE_FIRSTBOOT
282
            first = 0;
283
#endif
153.1.17 by Selene Scriven
Converted bistro to use top of EEPROM for config, bottom of EEPROM for wear-levelled mode index.
284
            break;
285
        }
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
286
    }
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
287
#ifndef USE_FIRSTBOOT
288
    // if no mode_idx was found, assume this is the first boot
289
    if (first) {
290
        reset_state();
291
        return;
292
    }
293
#endif
153.1.17 by Selene Scriven
Converted bistro to use top of EEPROM for config, bottom of EEPROM for wear-levelled mode index.
294
295
    // load other config values
296
    modegroup = eeprom_read_byte((uint8_t *)OPT_modegroup);
297
    memory    = eeprom_read_byte((uint8_t *)OPT_memory);
298
#ifdef OFFTIM3
299
    offtim3   = eeprom_read_byte((uint8_t *)OPT_offtim3);
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
300
#endif
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
301
#ifdef TEMPERATURE_MON
302
    maxtemp   = eeprom_read_byte((uint8_t *)OPT_maxtemp);
303
#endif
304
    mode_override = eeprom_read_byte((uint8_t *)OPT_mode_override);
153.1.29 by Selene Scriven
Added runtime option for moon. Re-ordered config options.
305
    enable_moon   = eeprom_read_byte((uint8_t *)OPT_moon);
153.1.32 by Selene Scriven
Added mode-reversing option (high to low order).
306
    reverse_modes = eeprom_read_byte((uint8_t *)OPT_revmodes);
153.1.47 by Selene Scriven
Added muggle mode / simple mode / loaning-the-light-to-a-friend mode.
307
    muggle_mode   = eeprom_read_byte((uint8_t *)OPT_muggle);
153.1.17 by Selene Scriven
Converted bistro to use top of EEPROM for config, bottom of EEPROM for wear-levelled mode index.
308
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
309
    // unnecessary, save_state handles wrap-around
310
    // (and we don't really care about it skipping cell 0 once in a while)
311
    //else eepos=0;
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
312
313
#ifndef USE_FIRSTBOOT
314
    if (modegroup >= NUM_MODEGROUPS) reset_state();
315
#endif
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
316
}
317
318
inline void next_mode() {
319
    mode_idx += 1;
320
    if (mode_idx >= solid_modes) {
321
        // Wrap around, skipping the hidden modes
322
        // (note: this also applies when going "forward" from any hidden mode)
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
323
        // FIXME? Allow this to cycle through hidden modes?
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
324
        mode_idx = 0;
325
    }
326
}
327
328
#ifdef OFFTIM3
329
inline void prev_mode() {
153.1.47 by Selene Scriven
Added muggle mode / simple mode / loaning-the-light-to-a-friend mode.
330
    // simple mode has no reverse
331
    if (muggle_mode) { return next_mode(); }
332
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
333
    if (mode_idx == solid_modes) {
334
        // If we hit the end of the hidden modes, go back to moon
335
        mode_idx = 0;
336
    } else if (mode_idx > 0) {
337
        // Regular mode: is between 1 and TOTAL_MODES
338
        mode_idx -= 1;
339
    } else {
340
        // Otherwise, wrap around (this allows entering hidden modes)
341
        mode_idx = mode_cnt - 1;
342
    }
343
}
344
#endif
345
346
void count_modes() {
347
    /*
348
     * Determine how many solid and hidden modes we have.
349
     *
350
     * (this matters because we have more than one set of modes to choose
351
     *  from, so we need to count at runtime)
352
     */
153.1.47 by Selene Scriven
Added muggle mode / simple mode / loaning-the-light-to-a-friend mode.
353
    // copy config to local vars to avoid accidentally overwriting them in muggle mode
354
    // (also, it seems to reduce overall program size)
355
    uint8_t my_modegroup = modegroup;
356
    uint8_t my_enable_moon = enable_moon;
357
    uint8_t my_reverse_modes = reverse_modes;
358
359
    // override config if we're in simple mode
360
    if (muggle_mode) {
361
        my_modegroup = NUM_MODEGROUPS;
362
        my_enable_moon = 0;
363
        my_reverse_modes = 0;
364
    }
365
153.1.27 by Selene Scriven
Cleaned out old mode group code. Adjusted new mode group levels. Added half of moon toggle.
366
    uint8_t *dest;
153.1.47 by Selene Scriven
Added muggle mode / simple mode / loaning-the-light-to-a-friend mode.
367
    const uint8_t *src = modegroups + (my_modegroup<<3);
153.1.27 by Selene Scriven
Cleaned out old mode group code. Adjusted new mode group levels. Added half of moon toggle.
368
    dest = modes;
153.1.42 by Selene Scriven
Made bistro accommodate custom mode groups better,
369
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
370
    // add moon mode (or not) if config says to add it
371
    if (my_enable_moon) {
372
        modes[0] = 1;
373
        dest ++;
374
    }
375
153.1.42 by Selene Scriven
Made bistro accommodate custom mode groups better,
376
    // Figure out how many modes are in this group
377
    //solid_modes = modegroup + 1;  // Assume group N has N modes
378
    // No, how about actually counting the modes instead?
379
    // (in case anyone changes the mode groups above so they don't form a triangle)
380
    for(solid_modes=0;
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
381
        (solid_modes<8) && pgm_read_byte(src);
382
        solid_modes++, src++ )
383
    {
384
        *dest++ = pgm_read_byte(src);
153.1.27 by Selene Scriven
Cleaned out old mode group code. Adjusted new mode group levels. Added half of moon toggle.
385
    }
153.1.42 by Selene Scriven
Made bistro accommodate custom mode groups better,
386
153.1.27 by Selene Scriven
Cleaned out old mode group code. Adjusted new mode group levels. Added half of moon toggle.
387
    // add regular modes
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
388
    //memcpy_P(dest, src, solid_modes);  // was already copied above
153.1.27 by Selene Scriven
Cleaned out old mode group code. Adjusted new mode group levels. Added half of moon toggle.
389
    // add hidden modes
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
390
    //memcpy_P(dest + solid_modes, hiddenmodes, sizeof(hiddenmodes));
391
    // smaller than memcpy_p()
392
    for( src=hiddenmodes; src<hiddenmodes+sizeof(hiddenmodes); src++ )
393
    {
394
        *dest++ = pgm_read_byte(src);
395
    }
153.1.27 by Selene Scriven
Cleaned out old mode group code. Adjusted new mode group levels. Added half of moon toggle.
396
    // final count
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
397
#ifdef OFFTIM3
153.1.44 by Selene Scriven
Simplified how hidden modes are specified.
398
    mode_cnt = solid_modes + sizeof(hiddenmodes);
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
399
#endif
153.1.47 by Selene Scriven
Added muggle mode / simple mode / loaning-the-light-to-a-friend mode.
400
    if (my_reverse_modes) {
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
401
        // TODO: yuck, isn't there a better way to do this?
153.1.32 by Selene Scriven
Added mode-reversing option (high to low order).
402
        int8_t i;
213 by Selene Scriven
bistro: fixed bug where hi-lo mode order didn't work.
403
        src = modegroups + (my_modegroup<<3) + solid_modes;
153.1.32 by Selene Scriven
Added mode-reversing option (high to low order).
404
        dest = modes;
405
        for(i=0; i<solid_modes; i++) {
406
            src --;
407
            *dest = pgm_read_byte(src);
408
            dest ++;
409
        }
153.1.47 by Selene Scriven
Added muggle mode / simple mode / loaning-the-light-to-a-friend mode.
410
        if (my_enable_moon) {
153.1.32 by Selene Scriven
Added mode-reversing option (high to low order).
411
            *dest = 1;
412
        }
413
        mode_cnt --;  // get rid of last hidden mode, since it's a duplicate turbo
414
    }
153.1.47 by Selene Scriven
Added muggle mode / simple mode / loaning-the-light-to-a-friend mode.
415
    if (my_enable_moon) {
153.1.27 by Selene Scriven
Cleaned out old mode group code. Adjusted new mode group levels. Added half of moon toggle.
416
        mode_cnt ++;
417
        solid_modes ++;
418
    }
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
419
}
420
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
421
#ifdef ALT_PWM_LVL
153.1.28 by Selene Scriven
Saved a few bytes related to set_output().
422
inline void set_output(uint8_t pwm1, uint8_t pwm2) {
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
423
#else
424
inline void set_output(uint8_t pwm1) {
425
#endif
153.1.28 by Selene Scriven
Saved a few bytes related to set_output().
426
    /* This is no longer needed since we always use PHASE mode.
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
427
    // Need PHASE to properly turn off the light
428
    if ((pwm1==0) && (pwm2==0)) {
429
        TCCR0A = PHASE;
430
    }
153.1.28 by Selene Scriven
Saved a few bytes related to set_output().
431
    */
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
432
    PWM_LVL = pwm1;
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
433
    #ifdef ALT_PWM_LVL
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
434
    ALT_PWM_LVL = pwm2;
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
435
    #endif
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
436
}
437
153.1.12 by Selene Scriven
Replaced two-channel output control with abstracted visual-level ramp.
438
void set_level(uint8_t level) {
439
    if (level == 0) {
440
        set_output(0,0);
441
    } else {
442
        level -= 1;
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
443
        set_output(pgm_read_byte(ramp_FET  + level),
153.1.12 by Selene Scriven
Replaced two-channel output control with abstracted visual-level ramp.
444
                   pgm_read_byte(ramp_7135 + level));
445
    }
446
}
447
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
448
void set_mode(uint8_t mode) {
153.1.13 by Selene Scriven
Added a soft start option, to ramp up to the desired level instead of jumping straight to it.
449
#ifdef SOFT_START
450
    static uint8_t actual_level = 0;
153.1.23 by Selene Scriven
Replaced bistro's turbo timeout with thermal step-down.
451
    uint8_t target_level = mode;
153.1.13 by Selene Scriven
Added a soft start option, to ramp up to the desired level instead of jumping straight to it.
452
    int8_t shift_amount;
453
    int8_t diff;
454
    do {
455
        diff = target_level - actual_level;
456
        shift_amount = (diff >> 2) | (diff!=0);
457
        actual_level += shift_amount;
458
        set_level(actual_level);
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
459
        //_delay_ms(RAMP_SIZE/20);  // slow ramp
460
        _delay_ms(RAMP_SIZE/4);  // fast ramp
153.1.13 by Selene Scriven
Added a soft start option, to ramp up to the desired level instead of jumping straight to it.
461
    } while (target_level != actual_level);
462
#else
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
463
#define set_mode set_level
464
    //set_level(mode);
153.1.16 by Selene Scriven
Added volts+tenths and 8-bar battery check styles.
465
#endif  // SOFT_START
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
466
}
467
153.1.16 by Selene Scriven
Added volts+tenths and 8-bar battery check styles.
468
void blink(uint8_t val, uint16_t speed)
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
469
{
470
    for (; val>0; val--)
471
    {
153.1.12 by Selene Scriven
Replaced two-channel output control with abstracted visual-level ramp.
472
        set_level(BLINK_BRIGHTNESS);
153.1.16 by Selene Scriven
Added volts+tenths and 8-bar battery check styles.
473
        _delay_ms(speed);
153.1.12 by Selene Scriven
Replaced two-channel output control with abstracted visual-level ramp.
474
        set_level(0);
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
475
        _delay_ms(speed);
476
        _delay_ms(speed);
477
    }
478
}
479
480
inline void strobe(uint8_t ontime, uint8_t offtime) {
481
    uint8_t i;
482
    for(i=0;i<8;i++) {
483
        set_level(RAMP_SIZE);
484
        _delay_ms(ontime);
485
        set_level(0);
486
        _delay_ms(offtime);
487
    }
488
}
489
490
#ifdef SOS
491
inline void SOS_mode() {
492
#define SOS_SPEED 200
493
    blink(3, SOS_SPEED);
494
    _delay_ms(SOS_SPEED*5);
495
    blink(3, SOS_SPEED*5/2);
496
    //_delay_ms(SOS_SPEED);
497
    blink(3, SOS_SPEED);
498
    _delay_s(); _delay_s();
499
}
500
#endif
153.1.35 by Selene Scriven
Made pgm_rand() more erratic (beginning of PROGMEM is boring for this purpose),
501
153.1.14 by Selene Scriven
Made config mode "buzz" during active click window,
502
void toggle(uint8_t *var, uint8_t num) {
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
503
    // Used for config mode
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
504
    // Changes the value of a config option, waits for the user to "save"
505
    // by turning the light off, then changes the value back in case they
506
    // didn't save.  Can be used repeatedly on different options, allowing
507
    // the user to change and save only one at a time.
153.1.16 by Selene Scriven
Added volts+tenths and 8-bar battery check styles.
508
    blink(num, BLINK_SPEED/8);  // indicate which option number this is
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
509
    *var ^= 1;
510
    save_state();
153.1.14 by Selene Scriven
Made config mode "buzz" during active click window,
511
    // "buzz" for a while to indicate the active toggle window
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
512
    blink(32, 500/32);
513
    /*
153.1.14 by Selene Scriven
Made config mode "buzz" during active click window,
514
    for(uint8_t i=0; i<32; i++) {
153.1.45 by Selene Scriven
Made disable-med-press act like short press instead of long press.
515
        set_level(BLINK_BRIGHTNESS * 3 / 4);
153.1.14 by Selene Scriven
Made config mode "buzz" during active click window,
516
        _delay_ms(20);
517
        set_level(0);
518
        _delay_ms(20);
519
    }
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
520
    */
153.1.14 by Selene Scriven
Made config mode "buzz" during active click window,
521
    // if the user didn't click, reset the value and return
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
522
    *var ^= 1;
523
    save_state();
524
    _delay_s();
525
}
526
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
527
#ifdef TEMPERATURE_MON
188 by Selene Scriven
Made bistro compile again, after last commit's changes to tk-voltage.h.
528
uint8_t get_temp() {
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
529
    ADC_on_temperature();
530
    // average a few values; temperature is noisy
531
    uint16_t temp = 0;
532
    uint8_t i;
188 by Selene Scriven
Made bistro compile again, after last commit's changes to tk-voltage.h.
533
    get_temperature();
153.1.36 by Selene Scriven
Made temperature regulation slower, less noisy, more biased toward stepping back up.
534
    for(i=0; i<16; i++) {
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
535
        temp += get_voltage();
536
        _delay_ms(5);
537
    }
153.1.36 by Selene Scriven
Made temperature regulation slower, less noisy, more biased toward stepping back up.
538
    temp >>= 4;
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
539
    return temp;
540
}
541
#endif  // TEMPERATURE_MON
542
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
543
#ifdef OFFTIM3
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
544
inline uint8_t read_otc() {
545
    // Read and return the off-time cap value
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
546
    // Start up ADC for capacitor pin
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
547
    // disable digital input on ADC pin to reduce power consumption
548
    DIDR0 |= (1 << CAP_DIDR);
549
    // 1.1v reference, left-adjust, ADC3/PB3
550
    ADMUX  = (1 << V_REF) | (1 << ADLAR) | CAP_CHANNEL;
551
    // enable, start, prescale
552
    ADCSRA = (1 << ADEN ) | (1 << ADSC ) | ADC_PRSCL;
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
553
554
    // Wait for completion
555
    while (ADCSRA & (1 << ADSC));
556
    // Start again as datasheet says first result is unreliable
557
    ADCSRA |= (1 << ADSC);
558
    // Wait for completion
559
    while (ADCSRA & (1 << ADSC));
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
560
561
    // ADCH should have the value we wanted
562
    return ADCH;
563
}
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
564
#endif
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
565
566
int main(void)
567
{
568
    // check the OTC immediately before it has a chance to charge or discharge
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
569
#ifdef OFFTIM3
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
570
    uint8_t cap_val = read_otc();  // save it for later
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
571
#endif
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
572
573
    // Set PWM pin to output
574
    DDRB |= (1 << PWM_PIN);     // enable main channel
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
575
    #ifdef ALT_PWM_PIN
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
576
    DDRB |= (1 << ALT_PWM_PIN); // enable second channel
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
577
    #endif
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
578
579
    // Set timer to do PWM for correct output pin and set prescaler timing
580
    //TCCR0A = 0x23; // phase corrected PWM is 0x21 for PB1, fast-PWM is 0x23
581
    //TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...)
582
    TCCR0A = PHASE;
583
    // Set timer to do PWM for correct output pin and set prescaler timing
584
    TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...)
585
586
    // Read config values and saved state
587
    restore_state();
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
588
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
589
    // Enable the current mode group
590
    count_modes();
591
592
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
593
    // TODO: Enable this?  (might prevent some corner cases, but requires extra room)
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
594
    // memory decayed, reset it
595
    // (should happen on med/long press instead
596
    //  because mem decay is *much* slower when the OTC is charged
597
    //  so let's not wait until it decays to reset it)
598
    //if (fast_presses > 0x20) { fast_presses = 0; }
599
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
600
    // check button press time, unless the mode is overridden
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
601
    if (! mode_override) {
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
602
#ifdef OFFTIM3
153.1.46 by Selene Scriven
Removed code from failed first attempt.
603
        if (cap_val > CAP_SHORT) {
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
604
#else
605
        if (fast_presses < 0x20) {
606
#endif
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
607
            // Indicates they did a short press, go to the next mode
608
            // We don't care what the fast_presses value is as long as it's over 15
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
609
            fast_presses = (fast_presses+1) & 0x1f;
610
            next_mode(); // Will handle wrap arounds
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
611
#ifdef OFFTIM3
153.1.45 by Selene Scriven
Made disable-med-press act like short press instead of long press.
612
        } else if (cap_val > CAP_MED) {
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
613
            // User did a medium press, go back one mode
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
614
            fast_presses = 0;
153.1.45 by Selene Scriven
Made disable-med-press act like short press instead of long press.
615
            if (offtim3) {
616
                prev_mode();  // Will handle "negative" modes and wrap-arounds
617
            } else {
618
                next_mode();  // disabled-med-press acts like short-press
619
                              // (except that fast_presses isn't reliable then)
620
            }
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
621
#endif
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
622
        } else {
623
            // Long press, keep the same mode
624
            // ... or reset to the first mode
625
            fast_presses = 0;
153.1.47 by Selene Scriven
Added muggle mode / simple mode / loaning-the-light-to-a-friend mode.
626
            if (muggle_mode  || (! memory)) {
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
627
                // Reset to the first mode
628
                mode_idx = 0;
629
            }
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
630
        }
631
    }
153.1.17 by Selene Scriven
Converted bistro to use top of EEPROM for config, bottom of EEPROM for wear-levelled mode index.
632
    save_mode();
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
633
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
634
    #ifdef CAP_PIN
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
635
    // Charge up the capacitor by setting CAP_PIN to output
636
    DDRB  |= (1 << CAP_PIN);    // Output
637
    PORTB |= (1 << CAP_PIN);    // High
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
638
    #endif
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
639
640
    // Turn features on or off as needed
641
    #ifdef VOLTAGE_MON
642
    ADC_on();
643
    #else
644
    ADC_off();
645
    #endif
153.1.17 by Selene Scriven
Converted bistro to use top of EEPROM for config, bottom of EEPROM for wear-levelled mode index.
646
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
647
    uint8_t output;
153.1.23 by Selene Scriven
Replaced bistro's turbo timeout with thermal step-down.
648
    uint8_t actual_level;
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
649
#ifdef TEMPERATURE_MON
650
    uint8_t overheat_count = 0;
651
#endif
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
652
#ifdef VOLTAGE_MON
653
    uint8_t lowbatt_cnt = 0;
654
    uint8_t i = 0;
655
    uint8_t voltage;
656
    // Make sure voltage reading is running for later
657
    ADCSRA |= (1 << ADSC);
658
#endif
153.1.26 by Selene Scriven
Gave bistro.c 8 mode groups, made count_modes() build the mode array at runtime.
659
    //output = pgm_read_byte(modes + mode_idx);
660
    output = modes[mode_idx];
153.1.23 by Selene Scriven
Replaced bistro's turbo timeout with thermal step-down.
661
    actual_level = output;
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
662
    // handle mode overrides, like mode group selection and temperature calibration
663
    if (mode_override) {
664
        // do nothing; mode is already set
665
        //mode_idx = mode_override;
666
        fast_presses = 0;
667
        output = mode_idx;
668
    }
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
669
    while(1) {
670
        if (fast_presses > 0x0f) {  // Config mode
671
            _delay_s();       // wait for user to stop fast-pressing button
672
            fast_presses = 0; // exit this mode after one use
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
673
            mode_idx = 0;
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
674
153.1.47 by Selene Scriven
Added muggle mode / simple mode / loaning-the-light-to-a-friend mode.
675
            // Enter or leave "muggle mode"?
676
            toggle(&muggle_mode, 1);
677
            if (muggle_mode) { continue; };  // don't offer other options in muggle mode
678
153.1.52 by Selene Scriven
Changed order of config mode options.
679
            toggle(&memory, 2);
680
681
            toggle(&enable_moon, 3);
682
683
            toggle(&reverse_modes, 4);
684
153.1.29 by Selene Scriven
Added runtime option for moon. Re-ordered config options.
685
            // Enter the mode group selection mode?
153.1.25 by Selene Scriven
Added the ability to set the mode group to anything from 0 to 7.
686
            mode_idx = GROUP_SELECT_MODE;
153.1.52 by Selene Scriven
Changed order of config mode options.
687
            toggle(&mode_override, 5);
153.1.25 by Selene Scriven
Added the ability to set the mode group to anything from 0 to 7.
688
            mode_idx = 0;
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
689
153.1.45 by Selene Scriven
Made disable-med-press act like short press instead of long press.
690
#ifdef OFFTIM3
153.1.47 by Selene Scriven
Added muggle mode / simple mode / loaning-the-light-to-a-friend mode.
691
            toggle(&offtim3, 6);
153.1.45 by Selene Scriven
Made disable-med-press act like short press instead of long press.
692
#endif
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
693
153.1.37 by Selene Scriven
Improved thermal regulation behavior, added no-regulation option,
694
#ifdef TEMPERATURE_MON
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
695
            // Enter temperature calibration mode?
696
            mode_idx = TEMP_CAL_MODE;
153.1.47 by Selene Scriven
Added muggle mode / simple mode / loaning-the-light-to-a-friend mode.
697
            toggle(&mode_override, 7);
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
698
            mode_idx = 0;
153.1.37 by Selene Scriven
Improved thermal regulation behavior, added no-regulation option,
699
#endif
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
700
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
701
            #ifdef USE_FIRSTBOOT
153.1.49 by Selene Scriven
Added a factory reset config option.
702
            toggle(&firstboot, 8);
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
703
            #endif
153.1.49 by Selene Scriven
Added a factory reset config option.
704
153.1.26 by Selene Scriven
Gave bistro.c 8 mode groups, made count_modes() build the mode array at runtime.
705
            //output = pgm_read_byte(modes + mode_idx);
706
            output = modes[mode_idx];
153.1.23 by Selene Scriven
Replaced bistro's turbo timeout with thermal step-down.
707
            actual_level = output;
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
708
        }
709
#ifdef STROBE
710
        else if (output == STROBE) {
711
            // 10Hz tactical strobe
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
712
            strobe(33,67);
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
713
        }
714
#endif // ifdef STROBE
153.1.13 by Selene Scriven
Added a soft start option, to ramp up to the desired level instead of jumping straight to it.
715
#ifdef POLICE_STROBE
716
        else if (output == POLICE_STROBE) {
717
            // police-like strobe
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
718
            //for(i=0;i<8;i++) {
153.1.35 by Selene Scriven
Made pgm_rand() more erratic (beginning of PROGMEM is boring for this purpose),
719
                strobe(20,40);
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
720
            //}
721
            //for(i=0;i<8;i++) {
153.1.35 by Selene Scriven
Made pgm_rand() more erratic (beginning of PROGMEM is boring for this purpose),
722
                strobe(40,80);
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
723
            //}
153.1.13 by Selene Scriven
Added a soft start option, to ramp up to the desired level instead of jumping straight to it.
724
        }
725
#endif // ifdef POLICE_STROBE
153.1.21 by Selene Scriven
Added a pseudo-random strobe mode to bistro.c.
726
#ifdef RANDOM_STROBE
727
        else if (output == RANDOM_STROBE) {
728
            // pseudo-random strobe
729
            uint8_t ms = 34 + (pgm_rand() & 0x3f);
153.1.35 by Selene Scriven
Made pgm_rand() more erratic (beginning of PROGMEM is boring for this purpose),
730
            strobe(ms, ms);
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
731
            //strobe(ms, ms);
153.1.21 by Selene Scriven
Added a pseudo-random strobe mode to bistro.c.
732
        }
733
#endif // ifdef RANDOM_STROBE
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
734
#ifdef BIKING_STROBE
735
        else if (output == BIKING_STROBE) {
736
            // 2-level stutter beacon for biking and such
737
#ifdef FULL_BIKING_STROBE
738
            // normal version
739
            for(i=0;i<4;i++) {
740
                set_output(255,0);
741
                _delay_ms(5);
742
                set_output(0,255);
743
                _delay_ms(65);
744
            }
745
            _delay_ms(720);
746
#else
747
            // small/minimal version
748
            set_output(255,0);
749
            _delay_ms(10);
750
            set_output(0,255);
751
            _delay_s();
752
#endif
753
        }
754
#endif  // ifdef BIKING_STROBE
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
755
#ifdef SOS
756
        else if (output == SOS) { SOS_mode(); }
757
#endif // ifdef SOS
153.1.10 by Selene Scriven
Got smooth ramping to work on FET+1 driver. Added a ramp mode for testing.
758
#ifdef RAMP
759
        else if (output == RAMP) {
760
            int8_t r;
761
            // simple ramping test
153.1.15 by Selene Scriven
Don't include "off" in ramp test mode.
762
            for(r=1; r<=RAMP_SIZE; r++) {
153.1.10 by Selene Scriven
Got smooth ramping to work on FET+1 driver. Added a ramp mode for testing.
763
                set_level(r);
764
                _delay_ms(25);
765
            }
153.1.15 by Selene Scriven
Don't include "off" in ramp test mode.
766
            for(r=RAMP_SIZE; r>0; r--) {
153.1.10 by Selene Scriven
Got smooth ramping to work on FET+1 driver. Added a ramp mode for testing.
767
                set_level(r);
768
                _delay_ms(25);
769
            }
770
        }
771
#endif  // ifdef RAMP
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
772
#ifdef BATTCHECK
773
        else if (output == BATTCHECK) {
153.1.16 by Selene Scriven
Added volts+tenths and 8-bar battery check styles.
774
#ifdef BATTCHECK_VpT
775
            // blink out volts and tenths
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
776
            _delay_ms(100);
153.1.16 by Selene Scriven
Added volts+tenths and 8-bar battery check styles.
777
            uint8_t result = battcheck();
778
            blink(result >> 5, BLINK_SPEED/8);
779
            _delay_ms(BLINK_SPEED);
780
            blink(1,5);
781
            _delay_ms(BLINK_SPEED*3/2);
782
            blink(result & 0b00011111, BLINK_SPEED/8);
783
#else  // ifdef BATTCHECK_VpT
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
784
            // blink zero to five times to show voltage
785
            // (~0%, ~25%, ~50%, ~75%, ~100%, >100%)
153.1.16 by Selene Scriven
Added volts+tenths and 8-bar battery check styles.
786
            blink(battcheck(), BLINK_SPEED/8);
787
#endif  // ifdef BATTCHECK_VpT
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
788
            // wait between readouts
789
            _delay_s(); _delay_s();
790
        }
791
#endif // ifdef BATTCHECK
153.1.25 by Selene Scriven
Added the ability to set the mode group to anything from 0 to 7.
792
        else if (output == GROUP_SELECT_MODE) {
793
            // exit this mode after one use
794
            mode_idx = 0;
795
            mode_override = 0;
796
797
            for(i=0; i<NUM_MODEGROUPS; i++) {
798
                modegroup = i;
799
                save_state();
800
801
                blink(1, BLINK_SPEED/3);
802
            }
803
            _delay_s(); _delay_s();
804
        }
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
805
#ifdef TEMP_CAL_MODE
806
        else if (output == TEMP_CAL_MODE) {
807
            // make sure we don't stay in this mode after button press
808
            mode_idx = 0;
809
            mode_override = 0;
810
153.1.37 by Selene Scriven
Improved thermal regulation behavior, added no-regulation option,
811
            // Allow the user to turn off thermal regulation if they want
812
            maxtemp = 255;
813
            save_state();
814
            set_mode(RAMP_SIZE/4);  // start somewhat dim during turn-off-regulation mode
815
            _delay_s(); _delay_s();
816
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
817
            // run at highest output level, to generate heat
818
            set_mode(RAMP_SIZE);
819
820
            // measure, save, wait...  repeat
821
            while(1) {
188 by Selene Scriven
Made bistro compile again, after last commit's changes to tk-voltage.h.
822
                maxtemp = get_temp();
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
823
                save_state();
153.1.37 by Selene Scriven
Improved thermal regulation behavior, added no-regulation option,
824
                _delay_s(); _delay_s();
153.1.24 by Selene Scriven
Added thermal calibration mode at config slot 4.
825
            }
826
        }
827
#endif  // TEMP_CAL_MODE
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
828
        else {  // Regular non-hidden solid mode
153.1.23 by Selene Scriven
Replaced bistro's turbo timeout with thermal step-down.
829
            set_mode(actual_level);
830
#ifdef TEMPERATURE_MON
188 by Selene Scriven
Made bistro compile again, after last commit's changes to tk-voltage.h.
831
            uint8_t temp = get_temp();
153.1.23 by Selene Scriven
Replaced bistro's turbo timeout with thermal step-down.
832
833
            // step down? (or step back up?)
153.1.36 by Selene Scriven
Made temperature regulation slower, less noisy, more biased toward stepping back up.
834
            if (temp >= maxtemp) {
835
                overheat_count ++;
836
                // reduce noise, and limit the lowest step-down level
153.1.37 by Selene Scriven
Improved thermal regulation behavior, added no-regulation option,
837
                if ((overheat_count > 15) && (actual_level > (RAMP_SIZE/8))) {
153.1.36 by Selene Scriven
Made temperature regulation slower, less noisy, more biased toward stepping back up.
838
                    actual_level --;
153.1.37 by Selene Scriven
Improved thermal regulation behavior, added no-regulation option,
839
                    //_delay_ms(5000);  // don't ramp down too fast
840
                    overheat_count = 0;  // don't ramp down too fast
153.1.36 by Selene Scriven
Made temperature regulation slower, less noisy, more biased toward stepping back up.
841
                }
842
            } else {
843
                // if we're not overheated, ramp up to the user-requested level
844
                overheat_count = 0;
153.1.40 by Selene Scriven
Thermal step-down seems to work reasonably well on the BLF X6 now.
845
                if ((temp < maxtemp - 2) && (actual_level < output)) {
153.1.36 by Selene Scriven
Made temperature regulation slower, less noisy, more biased toward stepping back up.
846
                    actual_level ++;
847
                }
153.1.23 by Selene Scriven
Replaced bistro's turbo timeout with thermal step-down.
848
            }
849
            set_mode(actual_level);
850
851
            ADC_on();  // return to voltage mode
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
852
#endif
853
            // Otherwise, just sleep.
854
            _delay_ms(500);
855
856
            // If we got this far, the user has stopped fast-pressing.
857
            // So, don't enter config mode.
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
858
            //fast_presses = 0;
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
859
        }
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
860
        fast_presses = 0;
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
861
#ifdef VOLTAGE_MON
862
        if (ADCSRA & (1 << ADIF)) {  // if a voltage reading is ready
153.1.38 by Selene Scriven
Made LVP work again.
863
            voltage = ADCH;  // get the waiting value
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
864
            // See if voltage is lower than what we were looking for
865
            if (voltage < ADC_LOW) {
866
                lowbatt_cnt ++;
867
            } else {
868
                lowbatt_cnt = 0;
869
            }
870
            // See if it's been low for a while, and maybe step down
871
            if (lowbatt_cnt >= 8) {
872
                // DEBUG: blink on step-down:
153.1.12 by Selene Scriven
Replaced two-channel output control with abstracted visual-level ramp.
873
                //set_level(0);  _delay_ms(100);
153.1.38 by Selene Scriven
Made LVP work again.
874
153.1.42 by Selene Scriven
Made bistro accommodate custom mode groups better,
875
                if (actual_level > RAMP_SIZE) {  // hidden / blinky modes
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
876
                    // step down from blinky modes to medium
153.1.38 by Selene Scriven
Made LVP work again.
877
                    actual_level = RAMP_SIZE / 2;
878
                } else if (actual_level > 1) {  // regular solid mode
879
                    // step down from solid modes somewhat gradually
880
                    // drop by 25% each time
881
                    actual_level = (actual_level >> 2) + (actual_level >> 1);
153.1.39 by Selene Scriven
General code cleaning / pruning / organizing.
882
                    // drop by 50% each time
153.1.38 by Selene Scriven
Made LVP work again.
883
                    //actual_level = (actual_level >> 1);
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
884
                } else { // Already at the lowest mode
153.1.38 by Selene Scriven
Made LVP work again.
885
                    //mode_idx = 0;  // unnecessary; we never leave this clause
886
                    //actual_level = 0;  // unnecessary; we never leave this clause
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
887
                    // Turn off the light
153.1.12 by Selene Scriven
Replaced two-channel output control with abstracted visual-level ramp.
888
                    set_level(0);
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
889
                    // Power down as many components as possible
890
                    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
891
                    sleep_mode();
892
                }
153.1.38 by Selene Scriven
Made LVP work again.
893
                set_mode(actual_level);
894
                output = actual_level;
153.1.42 by Selene Scriven
Made bistro accommodate custom mode groups better,
895
                //save_mode();  // we didn't actually change the mode
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
896
                lowbatt_cnt = 0;
175 by Selene Scriven
Applied biscotti's optimizations to bistro. 2048 bytes -> 1910. :)
897
                // Wait before lowering the level again
898
                //_delay_ms(250);
899
                _delay_s();
153.1.9 by Selene Scriven
Copied blf-a6 to a new directory to make it easier to add more features without breaking the old code.
900
            }
901
902
            // Make sure conversion is running for next time through
903
            ADCSRA |= (1 << ADSC);
904
        }
905
#endif  // ifdef VOLTAGE_MON
906
    }
907
908
    //return 0; // Standard Return Code
909
}