~gabe/flashlight-firmware/anduril2

« back to all changes in this revision

Viewing changes to ToyKeeper/battcheck/offtime-cap.c

  • Committer: Selene Scriven
  • Date: 2015-03-17 08:56:50 UTC
  • mto: This revision was merged to the branch mainline in revision 124.
  • Revision ID: ubuntu@toykeeper.net-20150317085650-s89wr9h28n2co7z1
Added TheStar firmwares from _the_

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This firmware simply helps calibrate values for voltage readings.
 
3
 * It is not intended to be used as an actual flashlight.
 
4
 *
 
5
 * It will read the voltage, then read out the raw value as a series of
 
6
 * blinks.  It will provide up to three groups of blinks, representing the
 
7
 * hundreds digit, the tens digit, then the ones.  So, for a raw value of 183,
 
8
 * it would blink once, pause, blink eight times, pause, then blink three times.
 
9
 * It will then wait longer and re-read the voltage, then repeat.
 
10
 *
 
11
 * NANJG 105C Diagram
 
12
 *           ---
 
13
 *         -|   |- VCC
 
14
 *  Star 4 -|   |- Voltage ADC
 
15
 *  Star 3 -|   |- PWM
 
16
 *     GND -|   |- Star 2
 
17
 *           ---
 
18
 *
 
19
 * CPU speed is 4.8Mhz without the 8x divider when low fuse is 0x75
 
20
 *
 
21
 * define F_CPU 4800000  CPU: 4.8MHz  PWM: 9.4kHz       ####### use low fuse: 0x75  #######
 
22
 *                             /8     PWM: 1.176kHz     ####### use low fuse: 0x65  #######
 
23
 * define F_CPU 9600000  CPU: 9.6MHz  PWM: 19kHz        ####### use low fuse: 0x7a  #######
 
24
 *                             /8     PWM: 2.4kHz       ####### use low fuse: 0x6a  #######
 
25
 *
 
26
 * Above PWM speeds are for phase-correct PWM.  This program uses Fast-PWM,
 
27
 * which when the CPU is 4.8MHz will be 18.75 kHz
 
28
 *
 
29
 * FUSES
 
30
 *      I use these fuse settings
 
31
 *      Low:  0x75
 
32
 *      High: 0xff
 
33
 *
 
34
 * STARS (not used)
 
35
 *
 
36
 */
 
37
#define F_CPU 4800000UL
 
38
 
 
39
/*
 
40
 * =========================================================================
 
41
 * Settings to modify per driver
 
42
 */
 
43
 
 
44
#define OWN_DELAY   // Should we use the built-in delay or our own?
 
45
 
 
46
#define BLINK_PWM   20
 
47
 
 
48
/*
 
49
 * =========================================================================
 
50
 */
 
51
 
 
52
#ifdef OWN_DELAY
 
53
#include <util/delay_basic.h>
 
54
// Having own _delay_ms() saves some bytes AND adds possibility to use variables as input
 
55
static void _delay_ms(uint16_t n)
 
56
{
 
57
    while(n-- > 0)
 
58
        _delay_loop_2(950);
 
59
}
 
60
#else
 
61
#include <util/delay.h>
 
62
#endif
 
63
 
 
64
#include <avr/pgmspace.h>
 
65
#include <avr/interrupt.h>
 
66
#include <avr/wdt.h>
 
67
#include <avr/eeprom.h>
 
68
#include <avr/sleep.h>
 
69
 
 
70
#define STAR2_PIN   PB0
 
71
#define STAR3_PIN   PB4
 
72
#define STAR4_PIN   PB3
 
73
#define CAP_PIN     PB3
 
74
#define CAP_CHANNEL 0x03    // MUX 03 corresponds with PB3 (Star 4)
 
75
#define CAP_DIDR    ADC3D   // Digital input disable bit corresponding with PB3
 
76
#define PWM_PIN     PB1
 
77
#define VOLTAGE_PIN PB2
 
78
#define ADC_CHANNEL 0x01    // MUX 01 corresponds with PB2
 
79
#define ADC_DIDR    ADC1D   // Digital input disable bit corresponding with PB2
 
80
#define ADC_PRSCL   0x06    // clk/64
 
81
 
 
82
#define PWM_LVL     OCR0B   // OCR0B is the output compare register for PB1
 
83
 
 
84
inline void ADC_on() {
 
85
    ADMUX  = (1 << REFS0) | (1 << ADLAR) | ADC_CHANNEL; // 1.1v reference, left-adjust, ADC1/PB2
 
86
    DIDR0 |= (1 << ADC_DIDR);                           // disable digital input on ADC pin to reduce power consumption
 
87
    ADCSRA = (1 << ADEN ) | (1 << ADSC ) | ADC_PRSCL;   // enable, start, prescale
 
88
}
 
89
 
 
90
inline void ADC_off() {
 
91
    ADCSRA &= ~(1<<7); //ADC off
 
92
}
 
93
 
 
94
uint8_t get_reading() {
 
95
    // Start up ADC for capacitor pin
 
96
    DIDR0 |= (1 << CAP_DIDR);                           // disable digital input on ADC pin to reduce power consumption
 
97
    ADMUX  = (1 << REFS0) | (1 << ADLAR) | CAP_CHANNEL; // 1.1v reference, left-adjust, ADC3/PB3
 
98
    ADCSRA = (1 << ADEN ) | (1 << ADSC ) | ADC_PRSCL;   // enable, start, prescale
 
99
    // Wait for completion
 
100
    while (ADCSRA & (1 << ADSC));
 
101
#if 1
 
102
    // Start again as datasheet says first result is unreliable
 
103
    ADCSRA |= (1 << ADSC);
 
104
    // Wait for completion
 
105
    while (ADCSRA & (1 << ADSC));
 
106
#endif
 
107
    // just return the value
 
108
    return ADCH;
 
109
}
 
110
 
 
111
void noblink() {
 
112
    PWM_LVL = (BLINK_PWM>>2);
 
113
    _delay_ms(5);
 
114
    PWM_LVL = 0;
 
115
    _delay_ms(200);
 
116
}
 
117
 
 
118
void blink() {
 
119
    PWM_LVL = BLINK_PWM;
 
120
    _delay_ms(150);
 
121
    PWM_LVL = 0;
 
122
    _delay_ms(200);
 
123
}
 
124
 
 
125
int main(void)
 
126
{
 
127
    uint16_t value;
 
128
    uint8_t i;
 
129
 
 
130
    // Set PWM pin to output
 
131
    DDRB = (1 << PWM_PIN);
 
132
 
 
133
    // Set timer to do PWM for correct output pin and set prescaler timing
 
134
    TCCR0A = 0x21; // phase corrected PWM is 0x21 for PB1, fast-PWM is 0x23
 
135
    TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...)
 
136
 
 
137
    // Turn features on or off as needed
 
138
    ADC_on();
 
139
    ACSR   |=  (1<<7); //AC off
 
140
 
 
141
    // get an average of several readings
 
142
    /*
 
143
    value = 0;
 
144
    for (i=0; i<8; i++) {
 
145
        value += get_reading();
 
146
        _delay_ms(50);
 
147
    }
 
148
    value = value >> 3;
 
149
    */
 
150
    value = get_reading();
 
151
 
 
152
    // Turn off ADC
 
153
    ADC_off();
 
154
 
 
155
    // Charge up the capacitor by setting CAP_PIN to output
 
156
    DDRB  |= (1 << CAP_PIN);    // Output
 
157
    PORTB |= (1 << CAP_PIN);    // High
 
158
 
 
159
 
 
160
    // blink once on receiving power
 
161
    //PWM_LVL = 255;
 
162
    //_delay_ms(5);
 
163
    //PWM_LVL = 0;
 
164
 
 
165
    // hundreds
 
166
    while (value >= 100) {
 
167
        value -= 100;
 
168
        blink();
 
169
    }
 
170
    _delay_ms(1000);
 
171
 
 
172
    // tens
 
173
    if (value < 10) {
 
174
        noblink();
 
175
    }
 
176
    while (value >= 10) {
 
177
        value -= 10;
 
178
        blink();
 
179
    }
 
180
    _delay_ms(1000);
 
181
 
 
182
    // ones
 
183
    if (value <= 0) {
 
184
        noblink();
 
185
    }
 
186
    while (value > 0) {
 
187
        value -= 1;
 
188
        blink();
 
189
    }
 
190
    _delay_ms(1000);
 
191
 
 
192
    while(1) {
 
193
        _delay_ms(1000);
 
194
    }
 
195
}