]> www.fi.muni.cz Git - tinyboard.git/blob - projects/step-up-1/main.c
Experimental step-up driver for chain of 5630 LEDs.
[tinyboard.git] / projects / step-up-1 / main.c
1 #include <avr/io.h>
2 #include <util/delay.h>
3 #include <avr/sleep.h>
4 #include <avr/interrupt.h>
5 #include <avr/power.h>
6 #include <avr/wdt.h>
7
8 #include "lights.h"
9
10 #if 0
11 static void hw_setup()
12 {
13         power_all_disable();
14
15 //      init_battery();
16         init_pwm();
17 //      init_adc();
18 //      init_wdt();
19 //
20 //      init_buttons();
21
22 //      init_pwmled();
23 //      init_pattern();
24 //      init_control();
25
26 //      set_sleep_mode(SLEEP_MODE_IDLE);
27 }
28
29 static void hw_suspend()
30 {
31         susp_pwm();
32         susp_adc();
33         susp_wdt();
34
35         susp_buttons();
36
37         power_all_disable();
38 }
39
40 void power_down()
41 {
42         hw_suspend();
43
44         do {
45                 // G'night
46                 set_sleep_mode(SLEEP_MODE_PWR_DOWN);
47                 sleep_enable();
48                 sleep_bod_disable();
49                 sei();
50                 sleep_cpu();
51
52                 // G'morning
53                 cli();
54                 sleep_disable();
55
56                 // allow wakeup by long button-press only
57         } while (!buttons_wait_for_release());
58
59         // ok, so I will wake up
60         hw_setup();
61 }
62 #endif
63
64
65 uint16_t read_adc_sync()
66 {
67         uint16_t rv;
68
69         ADCSRA |= _BV(ADSC); // start the conversion
70
71         // wait for the conversion to finish
72         while((ADCSRA & _BV(ADIF)) == 0)
73                 ;
74
75         rv = ADCW;
76         ADCSRA |= _BV(ADIF); // clear the IRQ flag
77
78         return rv;
79 }
80
81 void init_adc()
82 {
83         power_adc_enable();
84         ACSR |= _BV(ACD);       // but disable the analog comparator
85
86         ADCSRA = _BV(ADEN)                      // enable
87                 // | _BV(ADPS1) | _BV(ADPS0)    // CLK/8 = 125 kHz
88                 | _BV(ADPS2)                    // CLK/16 = 62.5 kHz
89                 ;
90
91         // Disable digital input on all bits used by ADC
92         DIDR0 = _BV(ADC3D) | _BV(ADC2D);
93         
94         ADMUX = _BV(REFS1) | _BV(MUX1) | _BV(MUX0);
95
96         /* Do first conversion and drop the result */
97         read_adc_sync();
98
99         // ADCSRA |= _BV(ADIE); // enable IRQ
100 }
101
102 int main(void)
103 {
104         uint16_t a, p, c, target;
105         int32_t sum;
106         uint8_t micro;
107         init_log();
108
109         log_set_state(3);
110
111         init_pwm();
112         init_adc();
113         // init_pwmled();
114
115         pwm_set(1);
116         // setup_mux(0);
117         // pwmled_on_off(1);
118         // pwmled_set_target(1);
119         
120         sum = 0;
121         c = 0;
122         micro = 0;
123         sei();
124
125         target = 0xf0;
126 #if 0
127         while(1) {
128                 unsigned char p;
129                 for (p = 0xd4; p <= 0xd5; p+= 0x1) {
130                         unsigned char i, j;
131                         uint16_t sum;
132
133                         pwm_set(p);
134
135                         for (j = 0; j < 12; j++) {
136                                 sum = 0;
137                                 for (i = 0; i < 2; i++) {
138                                         sum += read_adc_sync();
139                                 }
140                                 log_byte(sum);
141                                 for (i = 0; i < 14; i++) {
142                                         sum += read_adc_sync();
143                                 }
144                         }
145                         log_flush();
146                 }
147         }
148 #endif
149         while (1) {
150                 sum += target - read_adc_sync() - (sum >> 7);
151                 micro++;
152                 if (micro > 7)
153                         micro = 0;
154         
155                 p = ((sum >> 4) + micro) >> 3;
156                 if (p > 0xd8)
157                         p = 0xd8;
158                 pwm_set(p);
159                 if (++c > 200) {
160                         log_byte(p);
161                         log_flush();
162                         c = 0;
163                 }
164         }
165
166         p = a = c = 0;
167         while (1) {
168                 uint16_t i;
169                 for (i = 0; i < 25; i++) {
170                         uint16_t val;
171                         val = read_adc_sync();
172                         a += val - (a >> 5);
173                 }
174                 
175                 if (a < (42 << 5) && p < 250) {
176                         p++;
177                 } else if (p > 1 && a > (38 << 5)) {
178                         p--;
179                 }
180                 pwm_set(p);
181                 if (++c > 1000) {
182                         log_byte(0xbb);
183                         // log_word(read_adc_sync());
184                         log_word(a);
185                         log_word(p);
186                         log_flush();
187                         c = 0;
188                 }
189         }
190
191         while(1) {
192                 uint16_t i, t;
193                 for (t = 0; t < 3; t++) {
194                         pwmled_set_target(t);
195                         for (i = 0; i < 1000; i++) {
196                                 need_pwmled_adc = 1;
197                                 while (need_pwmled_adc == 1)
198                                         ;
199                         }
200                 }
201         }
202
203 #if 0
204         hw_setup();
205         power_down();
206
207 #if 1
208         while (1) {
209                 cli();
210                 if (pwm_enabled) {
211                         set_sleep_mode(SLEEP_MODE_IDLE);
212                 } else if (adc_enabled) {
213                         set_sleep_mode(SLEEP_MODE_ADC);
214                 } else {
215                         set_sleep_mode(SLEEP_MODE_PWR_DOWN);
216                 }
217
218                 sleep_enable();
219                 // keep BOD active, no sleep_bod_disable();
220                 sei();
221                 sleep_cpu();
222                 sleep_disable();
223         }
224 #endif
225
226 #if 0
227         DDRB |= _BV(PB2);
228         while (1) {
229                 PORTB |=  _BV( PB2 );
230                 _delay_ms(200);
231                 PORTB &=~ _BV( PB2 );
232                 _delay_ms(200);
233         }
234 #endif
235 #endif
236 }