#include #include #include #include #include uint16_t pwmee EEMEM; volatile uint16_t adcval; volatile struct { uint8_t pwm_int: 1; uint8_t adc_int: 1; uint8_t tmr_int: 1; } intflags; unsigned char debug EEMEM = 1; ISR(ADC_vect) { adcval = ADCW; ADCSRA &= ~_BV(ADIE); /* disable ADC interrupt */ intflags.adc_int = 1; } ISR(TIMER1_OVF_vect) { TIMSK &= ~_BV(TOIE1); intflags.pwm_int = 1; } ISR(TIMER0_COMPA_vect) { intflags.tmr_int = 1; } struct { unsigned char intensity :2; unsigned char length :6; } pattern[] = { {1, 2}, {0, 4}, { 1, 2 }, {0, 15}, {0, 0} }; static void inline init_pwm() { 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); TC1H = 0x03; OCR1C = 0xFF; OCR1D = OCR1B = OCR1A = 0x40; TCNT1 = 0; DDRB |= _BV( PB5 ) | _BV( PB1 ) | _BV( PB3 ); PORTB &= ~(_BV( PB5 ) | _BV( PB1 ) | _BV( PB3 )); TIMSK |= _BV(TOIE1); } static void inline init_adc() { ADCSRA = _BV(ADEN) | _BV(ADATE) | _BV(ADPS1) | _BV(ADPS0); ADMUX = _BV(REFS1) | _BV(MUX0); // ADCSRB = _BV(REFS2); DIDR0 = _BV(ADC1D) | _BV(AREFD); } static void inline init_tmr() { TCCR0A = _BV(WGM00); TCCR0B = _BV(CS02); // | _BV(CS00); OCR0A = 0x80; TIMSK |= _BV(OCIE0A); DDRA |= _BV( PA0 ); } int main(void) { char seen = 0; char pcount, ppos; init_pwm(); init_adc(); init_tmr(); ppos = 0; pcount = pattern[ppos].length; if (pattern[ppos].intensity) { PORTA |= _BV( PA0 ); } while (1) { unsigned char pwmhi, pwmlo; if (intflags.adc_int) { intflags.adc_int = 0; if (adcval > 0x3C0) adcval = 0x3C0; if (adcval < 1) adcval = 1; pwmhi = adcval >> 8; pwmlo = adcval & 0xFF; TC1H = pwmhi; OCR1D = pwmlo; TC1H = pwmhi; OCR1B = pwmlo; TC1H = pwmhi; OCR1A = pwmlo; TIMSK |= _BV(TOIE1); } if (intflags.pwm_int) { intflags.pwm_int = 0; ADCSRA |= _BV(ADIE) | _BV(ADSC); } if (intflags.tmr_int) { intflags.tmr_int = 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); } } } sei(); sleep_mode(); cli(); #if 0 if (!seen) { seen = 1; eeprom_write_byte(&debug, 2); } #endif } DDRA |= _BV( PA0 ); while( 1 ) { PORTA |= _BV( PA0 ); _delay_ms(2000); PORTA &=~ _BV( PA0 ); _delay_ms(2000); } }