2 #include <avr/eeprom.h>
3 #include <util/delay.h>
5 #include <avr/interrupt.h>
7 volatile uint16_t adcval;
8 unsigned char led_is_on = 0;
9 volatile unsigned char adccount = 0;
12 unsigned char pwmval, expected;
15 led_level_t led_modes[2] = {
20 unsigned char led_mode = 0;
21 unsigned char led_mode_changed = 0;
23 static void inline led_on()
30 static void inline led_off()
35 // ADCSRA &= ~(_BV(ADIE) | _BV(ADIF));
38 /* ------------ Logging/Debugging ----------- */
40 unsigned char debug_state EEMEM;
42 static void inline debug_setstate(unsigned char val)
44 eeprom_write_byte(&debug_state, val);
48 uint16_t log_buffer[LOG_BUFFER] EEMEM;
49 unsigned char log_buffer_count;
50 uint16_t log_buffer2[LOG_BUFFER];
51 volatile unsigned char stop = 0;
53 static void inline init_log()
59 static void log_word(uint16_t word) {
60 if (log_buffer_count >= LOG_BUFFER)
63 // eeprom_write_word(&log_buffer[log_buffer_count], word);
64 log_buffer2[log_buffer_count] = word;
67 if (log_buffer_count == LOG_BUFFER) {
69 for (i=0; i < LOG_BUFFER; i++) {
70 eeprom_write_word(&log_buffer[i],
77 /* ------------ Timer ----------- */
79 volatile uint16_t jiffies = 0;
81 static void inline init_tmr()
84 TCCR0B = _BV(CS02) | _BV(CS00); // 1 kHz
92 static void inline tmr_handler()
94 unsigned char c = jiffies & 0x0F;
95 unsigned char c1 = jiffies & 0x7F;
107 if (c == 0x02 || c == 0x08)
110 if (c == 0x05 || c == 0x0b)
116 led_mode_changed = 1;
117 OCR1D = led_modes[led_mode].pwmval;
118 } else if (c1 == 0x70) {
120 led_mode_changed = 1;
121 OCR1D = led_modes[led_mode].pwmval;
127 if (led_is_on && adcval != 0xFFEE) {
130 ADCSRA |= _BV(ADIF) | _BV(ADIE) | _BV(ADSC);
135 ISR(TIMER0_COMPA_vect)
140 /* ------------ PWM ----------- */
142 static void inline init_pwm()
145 PLLCSR = _BV(LSM) | _BV(PLLE);
147 while (PLLCSR & _BV(PLOCK) == 0)
151 TCCR1C = _BV(COM1D0) | _BV(COM1D1) | _BV(PWM1D);
152 TCCR1A = _BV(COM1A0) | _BV(COM1A1) | _BV(COM1B0) | _BV(COM1B1) | _BV(PWM1A) | _BV(PWM1B);
153 // TCCR1B = 0x80| _BV(CS13) | _BV(CS11);
154 TCCR1B = _BV(7) // PWM1X: PWM inversion mode
155 | _BV(CS10) // no clock prescaling
157 OCR1C = 0xFF; // TOP value
158 OCR1D = OCR1B = OCR1A = 0;
161 PORTB &= ~(_BV( PB5 ) | _BV( PB1 ) | _BV( PB3 ));
164 // TIMSK |= _BV(TOIE1);
168 static void inline pwm_handler()
170 // TIMSK &= ~_BV(TOIE1);
180 /* ------------ A/D Converter ----------- */
182 static void inline init_adc()
184 ADCSRA = _BV(ADEN) // enable
185 | _BV(ADPS1) | _BV(ADPS0) // CLK/8 = 125 kHz
186 // | _BV(ADPS2) // CLK/16 = 62.5 kHz
188 ADMUX = _BV(REFS1) // 1.1V internal reference
189 | _BV(MUX4)|_BV(MUX3) // port ADC5-6, gain 1
191 // ADCSRB = _BV(REFS2);
193 // Disable digital input on all bits used by ADC
194 DIDR0 = _BV(ADC5D)|_BV(ADC6D) | _BV(AREFD);
198 static void inline adc_handler()
200 uint16_t new_pwm = led_modes[led_mode].pwmval;
201 uint16_t old_pwm = new_pwm;
202 uint16_t adc_exp = led_modes[led_mode].expected;
207 // log_word(((adcval & 0x3FC) << 6) | pwmval);
212 // ADCSRA &= ~(_BV(ADIE) | _BV(ADIF));
214 if (led_mode_changed) {
215 led_mode_changed = 0;
219 log_word(((adcval & 0xFF) << 8) | old_pwm);
221 if (2*adcval > 5*adc_exp) { // >2.5x expected, lower significantly
222 new_pwm = 2*old_pwm/3;
223 } else if (3*adcval > 4*adc_exp) { // >1.33x expected, lower a bit
224 new_pwm = old_pwm - 1;
225 } else if (4*adcval < 3*adc_exp) { // 0.75x expected, raise a bit
226 new_pwm = old_pwm + 1;
229 if (new_pwm > 0x60) { // odpojeno?
232 if (new_pwm < 2) { // zkrat?
237 if (new_pwm != old_pwm) {
238 led_modes[led_mode].pwmval = new_pwm;
241 // ADCSRA |= _BV(ADSC);
269 PORTA &=~ _BV( PA0 );