~beastlykings/flashlight-firmware/custom

« back to all changes in this revision

Viewing changes to Flashy_Mike/otsm-example/otsm-example-code.c

  • Committer: Selene Scriven
  • Date: 2018-11-03 22:54:18 UTC
  • mfrom: (188.1.36 flash-safer)
  • Revision ID: bzr@toykeeper.net-20181103225418-1vsjrc40xh838ggw
merged trunk and flash-safer branch (clean up flash/build scripts and make flashing less likely to produce bricks)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Simple sample firmware for otc less design (single cell).
 
2
 
 
3
   Half press less than about 300 ms: next mode
 
4
              between 300 and 900 ms: previous mode
 
5
              longer:                 blink out voltage reading 
 
6
                                      (0 to 255) in 3 decimals
 
7
 
 
8
   Suggested capacity of buffer cap (C2): >= 47 uF.
 
9
   Vbatt is connected to PB3 (Pin2).
 
10
   Voltage divider still connected to Pin7.
 
11
   Timing specified for Attiny25 at 10 Mhz.
 
12
   Don't fuse BOD.
 
13
   Created and built with Atmel Studio.
 
14
   Fuses for Attiny25: lfuse: 0xD2, hfuse: 0xDF.
 
15
*/
 
16
 
 
17
#include <avr/interrupt.h>
 
18
#include <avr/sleep.h>
 
19
#include <avr/wdt.h>
 
20
 
 
21
#define PIN_7135            PB0
 
22
#define PIN_FET             PB1
 
23
#define PIN_POWER_DETECT    PB3
 
24
#define INT_POWER_DETECT    PCINT3
 
25
#define VLT_PIN             PB2
 
26
#define VLT_CHANNEL         0x01
 
27
#define VLT_DIDR            ADC1D
 
28
#define ADC_VREF            ((1 << REFS1) | (1 << REFS2))    // 2.56V
 
29
#define ADC_PRESCL          0x06
 
30
 
 
31
#define PWM_PHASE           0xA1
 
32
#define PWM_7135            OCR0A
 
33
#define PWM_FET             OCR0B
 
34
 
 
35
#define MODE_COUNT          6
 
36
#define PWM_LEVELS_7135     30, 80, 255, 255, 255,   0
 
37
#define PWM_LEVELS_FET      0,   0,   0,  30,  80, 255
 
38
 
 
39
// forward declarations
 
40
uint8_t adc_init_and_read();
 
41
void blink_once();
 
42
void blink_once_long();
 
43
void blink_value(uint8_t value);
 
44
void delay_250_micro_sec(uint8_t n);
 
45
void delay_50_milli_sec(uint8_t n);
 
46
void delay_1_sec();
 
47
void led_off();
 
48
void led_on();
 
49
 
 
50
volatile uint8_t s_clicked = 0;
 
51
const uint8_t pwm_levels_7135[] = { PWM_LEVELS_7135 };
 
52
const uint8_t pwm_levels_fet[] = { PWM_LEVELS_FET };
 
53
uint8_t mode_index = 0;
 
54
 
 
55
////////////////////////////////////////////////////////////////////////////////
 
56
 
 
57
int main(void)
 
58
{
 
59
    uint8_t blink_voltage = 0;
 
60
    uint8_t voltage;
 
61
 
 
62
    // set LED ports as output
 
63
    DDRB = (1 << PIN_7135) | (1 << PIN_FET);
 
64
 
 
65
    // initialize PWM
 
66
    TCCR0A = PWM_PHASE;
 
67
    TCCR0B = 0x01;
 
68
 
 
69
    // enable pin change interrupts
 
70
    PCMSK = (1 << INT_POWER_DETECT);
 
71
    GIMSK |= (1 << PCIE);
 
72
    sei();
 
73
 
 
74
    // start with first mode
 
75
    PWM_7135 = pwm_levels_7135[mode_index];
 
76
    PWM_FET = pwm_levels_fet[mode_index];
 
77
 
 
78
    while ( 1 )
 
79
    {
 
80
        if ( s_clicked )
 
81
        {
 
82
            if ( s_clicked <= 10 ) // < about 300 ms
 
83
            {
 
84
                blink_voltage = 0;
 
85
                mode_index++;
 
86
                if ( mode_index >= MODE_COUNT )
 
87
                    mode_index = 0;
 
88
            }
 
89
            else if ( s_clicked <= 30 ) // < about 900 ms
 
90
            {
 
91
                blink_voltage = 0;
 
92
                mode_index--;
 
93
                if  ( mode_index == 255 )
 
94
                    mode_index = MODE_COUNT - 1;
 
95
            }
 
96
            else // > about 900 ms
 
97
            {
 
98
                mode_index = 0;
 
99
                blink_voltage = 1;
 
100
            }
 
101
 
 
102
            s_clicked = 0;
 
103
            PWM_7135 = pwm_levels_7135[mode_index];
 
104
            PWM_FET  = pwm_levels_fet[mode_index];
 
105
        }
 
106
 
 
107
        voltage = adc_init_and_read();
 
108
 
 
109
        if ( blink_voltage )
 
110
            blink_value(voltage);
 
111
 
 
112
        delay_1_sec();
 
113
    }
 
114
 
115
 
 
116
////////////////////////////////////////////////////////////////////////////////
 
117
 
 
118
ISR(PCINT0_vect)
 
119
{
 
120
    // disable output
 
121
    PORTB = 0;
 
122
 
 
123
    // turn off PWM generation (might not be necessary)
 
124
    TCCR0A = 0;
 
125
    TCCR0B = 0;
 
126
 
 
127
    // ADC off
 
128
    ADCSRA &= ~(1 << ADEN);
 
129
 
 
130
    // disable pin change interrupt
 
131
    GIMSK &= ~(1 << PCIE);
 
132
    PCMSK = 0;
 
133
 
 
134
    s_clicked = 0;
 
135
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
 
136
 
 
137
    do
 
138
    {
 
139
        s_clicked++;
 
140
 
 
141
        wdt_reset();
 
142
        WDTCR = (1<<WDIE) | WDTO_30MS;
 
143
 
 
144
        sei();
 
145
        sleep_mode();
 
146
        cli();
 
147
 
 
148
    } while ( (PINB & (1 << PIN_POWER_DETECT)) == 0 );
 
149
 
 
150
    wdt_disable();
 
151
 
 
152
    // debounce
 
153
    delay_250_micro_sec(10); 
 
154
 
 
155
    // activate pwm generation
 
156
    TCCR0A = PWM_PHASE;
 
157
    TCCR0B = 0x01;
 
158
 
 
159
    // enable pin change interrupts
 
160
    PCMSK = (1 << INT_POWER_DETECT);
 
161
    GIMSK |= (1 << PCIE);
 
162
}
 
163
 
 
164
////////////////////////////////////////////////////////////////////////////////
 
165
 
 
166
void delay_250_micro_sec(uint8_t n)
 
167
{
 
168
    while ( n-- )
 
169
    {
 
170
        int k = 180;
 
171
        while ( k-- )
 
172
        {
 
173
            if ( s_clicked )
 
174
                return;
 
175
        }
 
176
    }
 
177
}
 
178
 
 
179
////////////////////////////////////////////////////////////////////////////////
 
180
 
 
181
void  delay_50_milli_sec(uint8_t n)
 
182
{
 
183
    do
 
184
    {
 
185
        delay_250_micro_sec(200);
 
186
        if ( s_clicked )
 
187
            return;
 
188
    } while ( --n );
 
189
}
 
190
 
 
191
////////////////////////////////////////////////////////////////////////////////
 
192
 
 
193
void delay_1_sec()
 
194
{
 
195
    delay_50_milli_sec(20);
 
196
}
 
197
 
 
198
////////////////////////////////////////////////////////////////////////////////
 
199
 
 
200
void led_on()
 
201
{
 
202
    PWM_7135 = pwm_levels_7135[mode_index];
 
203
    PWM_FET  = pwm_levels_fet[mode_index];
 
204
}
 
205
 
 
206
////////////////////////////////////////////////////////////////////////////////
 
207
 
 
208
void led_off()
 
209
{
 
210
    PWM_7135 = 0;
 
211
    PWM_FET = 0;
 
212
}
 
213
 
 
214
////////////////////////////////////////////////////////////////////////////////
 
215
 
 
216
void blink_once()
 
217
{
 
218
    led_on();
 
219
    delay_50_milli_sec(5);
 
220
    led_off();
 
221
    delay_50_milli_sec(5);
 
222
}
 
223
 
 
224
////////////////////////////////////////////////////////////////////////////////
 
225
 
 
226
void blink_once_long()
 
227
{
 
228
    led_on();
 
229
    delay_1_sec();
 
230
    led_off();
 
231
    delay_1_sec();
 
232
}
 
233
 
 
234
////////////////////////////////////////////////////////////////////////////////
 
235
 
 
236
void blink_once_short()
 
237
{
 
238
    led_on();
 
239
    delay_50_milli_sec(1);
 
240
    led_off();
 
241
    delay_50_milli_sec(5);
 
242
}
 
243
 
 
244
////////////////////////////////////////////////////////////////////////////////
 
245
 
 
246
void blink_value(uint8_t value)
 
247
{
 
248
    // 100er
 
249
    if ( value < 100 )
 
250
        blink_once_short();
 
251
 
 
252
    while ( value >= 100 )
 
253
    {
 
254
        value -= 100;
 
255
        blink_once();
 
256
    }
 
257
    delay_1_sec();
 
258
 
 
259
    // 10er
 
260
    if ( value < 10 )
 
261
        blink_once_short();
 
262
 
 
263
    while ( value >= 10 )
 
264
    {
 
265
        value -= 10;
 
266
        blink_once();
 
267
    }
 
268
    delay_1_sec();
 
269
 
 
270
    // 1er
 
271
    if ( value == 0 )
 
272
        blink_once_short();
 
273
 
 
274
    while ( value > 0 )
 
275
    {
 
276
        value--;
 
277
        blink_once();
 
278
    }
 
279
    delay_1_sec();
 
280
}
 
281
 
 
282
////////////////////////////////////////////////////////////////////////////////
 
283
 
 
284
uint8_t adc_read()
 
285
{
 
286
    uint8_t value;
 
287
 
 
288
    while (ADCSRA & (1 << ADSC))
 
289
    {
 
290
        if ( s_clicked )
 
291
            return 0;
 
292
    }
 
293
    value = ADCH;
 
294
    ADCSRA |= (1 << ADSC);
 
295
    return value;
 
296
}
 
297
 
 
298
////////////////////////////////////////////////////////////////////////////////
 
299
 
 
300
uint8_t adc_init_and_read()
 
301
{
 
302
    DIDR0 |= (1 << VLT_DIDR);
 
303
    ADMUX  = ADC_VREF | (1 << ADLAR) | VLT_CHANNEL;
 
304
    ADCSRA = (1 << ADEN) | (1 << ADSC) | ADC_PRESCL;
 
305
    adc_read(); // first run not reliable (see spec)
 
306
    return adc_read();
 
307
}
 
308
 
 
309
////////////////////////////////////////////////////////////////////////////////
 
310
// empty interrupt function required otherwise mcu will reset
 
311
 
 
312
ISR(WDT_vect)
 
313
{
 
314
};
 
315
 
 
316
////////////////////////////////////////////////////////////////////////////////