#include <avr/interrupt.h>
volatile uint16_t adcval;
-unsigned char pwmval = 0x28;
-uint16_t pwmints = 0;
+unsigned char led_is_on = 0;
+volatile unsigned char adccount = 0;
-volatile struct
-{
- uint8_t pwm_int: 1;
- uint8_t adc_int: 1;
- uint8_t tmr_int: 1;
-}
-intflags;
+typedef struct {
+ unsigned char pwmval, expected;
+} led_level_t;
+
+led_level_t led_modes[2] = {
+ { 0x50, 0x38 },
+ { 0x38, 0x04 },
+};
+
+unsigned char led_mode = 0;
+unsigned char led_mode_changed = 0;
static void inline led_on()
{
DDRB |= _BV( PB5 );
+ PORTA |= _BV( PA0 );
+ led_is_on = 1;
}
static void inline led_off()
{
+ led_is_on = 0;
DDRB &= ~_BV( PB5 );
+ PORTA &=~ _BV( PA0 );
+// ADCSRA &= ~(_BV(ADIE) | _BV(ADIF));
}
/* ------------ Logging/Debugging ----------- */
eeprom_write_byte(&debug_state, val);
}
-#define LOG_BUFFER 192
+#define LOG_BUFFER 64
uint16_t log_buffer[LOG_BUFFER] EEMEM;
-uint16_t log_buffer_count;
+unsigned char log_buffer_count;
+uint16_t log_buffer2[LOG_BUFFER];
+volatile unsigned char stop = 0;
static void inline init_log()
{
}
static void log_word(uint16_t word) {
- if (log_buffer_count == LOG_BUFFER) {
- debug_setstate(0x42);
- log_buffer_count++;
- }
if (log_buffer_count >= LOG_BUFFER)
return;
- eeprom_write_word(&log_buffer[log_buffer_count], word);
+ // eeprom_write_word(&log_buffer[log_buffer_count], word);
+ log_buffer2[log_buffer_count] = word;
log_buffer_count++;
+
+ if (log_buffer_count == LOG_BUFFER) {
+ unsigned char i;
+ for (i=0; i < LOG_BUFFER; i++) {
+ eeprom_write_word(&log_buffer[i],
+ log_buffer2[i]);
+ }
+ debug_setstate(0x42);
+ }
}
/* ------------ Timer ----------- */
-uint16_t clock = 0;
+volatile uint16_t jiffies = 0;
static void inline init_tmr()
{
TCCR0A = _BV(WGM00);
TCCR0B = _BV(CS02) | _BV(CS00); // 1 kHz
- OCR0A = 10; // 100 Hz
+ OCR0A = 12; // 100 Hz
TIMSK |= _BV(OCIE0A);
DDRA |= _BV( PA0 );
- clock = 0;
+ jiffies = 0;
}
static void inline tmr_handler()
{
- unsigned char c = clock & 0x7F;
- ++clock;
+ unsigned char c = jiffies & 0x0F;
+ unsigned char c1 = jiffies & 0x7F;
- if (c == 10 || c == 30)
+ ++jiffies;
+
+#if 0
+ if (c == 1)
led_on();
- if (c == 20 || c == 40)
+ if (c == 9)
led_off();
+#endif
- log_word(adcval);
- if (adcval != 0xFFEE) {
+ if (c == 0x02 || c == 0x08)
+ led_on();
+
+ if (c == 0x05 || c == 0x0b)
+ led_off();
+
+#if 1
+ if (c1 == 0x10) {
+ led_mode = 0;
+ led_mode_changed = 1;
+ OCR1D = led_modes[led_mode].pwmval;
+ } else if (c1 == 0x70) {
+ led_mode = 1;
+ led_mode_changed = 1;
+ OCR1D = led_modes[led_mode].pwmval;
+ }
+#endif
+
+ ADCSRA |= _BV(ADSC);
+#if 0
+ if (led_is_on && adcval != 0xFFEE) {
adcval = 0xFFEE;
- ADCSRA |= _BV(ADIE) | _BV(ADSC);
+ ADCSRA |= _BV(ADIF) | _BV(ADIE) | _BV(ADSC);
}
+#endif
}
ISR(TIMER0_COMPA_vect)
TCCR1C = _BV(COM1D0) | _BV(COM1D1) | _BV(PWM1D);
TCCR1A = _BV(COM1A0) | _BV(COM1A1) | _BV(COM1B0) | _BV(COM1B1) | _BV(PWM1A) | _BV(PWM1B);
// TCCR1B = 0x80| _BV(CS13) | _BV(CS11);
- TCCR1B = 0x80 | _BV(CS10);
- OCR1C = 0xFF;
- OCR1D = OCR1B = OCR1A = pwmval;
- TCNT1 = 0;
+ TCCR1B = _BV(7) // PWM1X: PWM inversion mode
+ | _BV(CS10) // no clock prescaling
+ ;
+ OCR1C = 0xFF; // TOP value
+ OCR1D = OCR1B = OCR1A = 0;
+ // OCR1D = 0;
DDRB |= _BV( PB5 );
PORTB &= ~(_BV( PB5 ) | _BV( PB1 ) | _BV( PB3 ));
- led_off();
+ // led_off();
// TIMSK |= _BV(TOIE1);
}
#if 0
static void inline pwm_handler()
{
- TCNT1 = 0;
- OCR1D = pwmval;
+ // TIMSK &= ~_BV(TOIE1);
+ // OCR1D = pwmval;
}
ISR(TIMER1_OVF_vect)
{
- TIMSK &= ~_BV(TOIE1);
pwm_handler();
}
#endif
static void inline init_adc()
{
- ADCSRA = _BV(ADEN) | _BV(ADATE) | _BV(ADPS1) | _BV(ADPS0);
- ADMUX = _BV(REFS1) | _BV(MUX0);
+ ADCSRA = _BV(ADEN) // enable
+ | _BV(ADPS1) | _BV(ADPS0) // CLK/8 = 125 kHz
+ // | _BV(ADPS2) // CLK/16 = 62.5 kHz
+ ;
+ ADMUX = _BV(REFS1) // 1.1V internal reference
+ | _BV(MUX4)|_BV(MUX3) // port ADC5-6, gain 1
+ ;
// ADCSRB = _BV(REFS2);
- DIDR0 = _BV(ADC1D) | _BV(AREFD);
+ ADCSRB |= _BV(GSEL);
+ // Disable digital input on all bits used by ADC
+ DIDR0 = _BV(ADC5D)|_BV(ADC6D) | _BV(AREFD);
+ ADCSRA |= _BV(ADIE);
}
static void inline adc_handler()
{
- static unsigned char last_pwmval = 0;
- static unsigned char counter = 0;
- uint16_t tmp = pwmval;
- static uint16_t discard = 5;
+ uint16_t new_pwm = led_modes[led_mode].pwmval;
+ uint16_t old_pwm = new_pwm;
+ uint16_t adc_exp = led_modes[led_mode].expected;
adcval = ADCW;
- ADCSRA &= ~_BV(ADIE); /* disable ADC interrupt */
-#if 0
- if (--discard > 0)
- goto out;
-
- if (adcval > 0x300)
- tmp = 3*tmp/4;
- else if (adcval > 0x280)
- tmp = 7*tmp/8;
- else if (adcval > 0x201)
- tmp--;
- else if (adcval < 0x100)
- tmp = 5*tmp/4;
- else if (adcval < 0x180)
- tmp = 9*tmp/8;
- else if (adcval < 0x1ff)
- tmp++;
-
- if (tmp > 0xFF)
- tmp = 0xFF;
- if (tmp == 0)
- tmp = 1;
-
- counter++;
- if ((last_pwmval > tmp && last_pwmval - tmp > 10)
- || (last_pwmval < tmp && tmp - last_pwmval > 10)
- || (counter > 2)) {
- counter = 0;
-
- if (rv_count < BUFFER-1) {
- eeprom_write_word(&readval[rv_count++], adcval);
- eeprom_write_word(&readval[rv_count++], pwmval);
- if (rv_count >= BUFFER)
- eeprom_write_byte(&debug, 42);
- }
+ adccount++;
+
+ // log_word(((adcval & 0x3FC) << 6) | pwmval);
+
+ if (!led_is_on)
+ return;
+
+ // ADCSRA &= ~(_BV(ADIE) | _BV(ADIF));
+
+ if (led_mode_changed) {
+ led_mode_changed = 0;
+ goto set_pwm;
}
- last_pwmval = pwmval;
- pwmval = tmp;
+ log_word(((adcval & 0xFF) << 8) | old_pwm);
- if (pwmval != last_pwmval) {
- TIMSK |= _BV(TOIE1);
-
- discard = 1000;
- } else {
- discard = 0;
+ if (2*adcval > 5*adc_exp) { // >2.5x expected, lower significantly
+ new_pwm = 2*old_pwm/3;
+ } else if (3*adcval > 4*adc_exp) { // >1.33x expected, lower a bit
+ new_pwm = old_pwm - 1;
+ } else if (4*adcval < 3*adc_exp) { // 0.75x expected, raise a bit
+ new_pwm = old_pwm + 1;
}
-out:
- //TIMSK |= _BV(TOIE1);
- ADCSRA |= _BV(ADIE) | _BV(ADSC);
-#endif
+ if (new_pwm > 0x60) { // odpojeno?
+ new_pwm = 0x60;
+ }
+ if (new_pwm < 2) { // zkrat?
+ new_pwm = 2;
+ }
+
+set_pwm:
+ if (new_pwm != old_pwm) {
+ led_modes[led_mode].pwmval = new_pwm;
+ OCR1D = new_pwm;
+ }
+ // ADCSRA |= _BV(ADSC);
}
ISR(ADC_vect)
adc_handler();
}
-#if 0
- if (--pcount == 0) {
- ppos++;
- pcount = pattern[ppos].length;
- if (!pcount) {
- ppos = 0;
- pcount = pattern[ppos].length;
- }
- if (pattern[ppos].intensity) {
- PORTA |= _BV(PA0);
- } else {
- PORTA &= ~_BV(PA0);
- }
- }
-#endif
-
int main(void)
{
- char seen = 0;
- char pcount, ppos;
- unsigned char adcidx = 0;
- uint16_t adcvals[16];
-
+ _delay_ms(1500);
init_log();
init_pwm();
init_adc();
init_tmr();
- debug_setstate(2);
+ led_on();
+ debug_setstate(3);
sei();
while (1)
- ; //sleep_mode();
+ ; // sleep_mode();
+
#if 0
- if (!seen) {
- seen = 1;
- eeprom_write_byte(&debug, 2);
- }
+ while (1) {
+ PORTA |= _BV( PA0 );
+ _delay_ms(200);
+ PORTA &=~ _BV( PA0 );
+ _delay_ms(200);
+ }
#endif
-
- DDRA |= _BV( PA0 );
- while( 1 ) {
- PORTA |= _BV( PA0 );
- _delay_ms(200);
- PORTA &=~ _BV( PA0 );
- }
}