]> www.fi.muni.cz Git - bike-lights.git/blobdiff - lights.c
pattern flashing
[bike-lights.git] / lights.c
index 0bedc53e2e059f070a82bdcee6e00381adeca255..6d78e2335d41083f4d6f0704a0d0fe506a00f6df 100644 (file)
--- a/lights.c
+++ b/lights.c
 #include <avr/io.h>
 #include <avr/eeprom.h>
 #include <util/delay.h>
+#include <avr/sleep.h>
+#include <avr/interrupt.h>
 
-char dbg[5] __attribute__((section(".eeprom")));
+uint16_t pwmee EEMEM;
+volatile uint16_t adcval;
 
-int main(void)
+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(PWM1A) | _BV(PWM1B);
-       TCCR1B = 0x80 | _BV(CS13) | _BV(CS12);
+       TCCR1A = _BV(COM1A0) | _BV(COM1A1) | _BV(COM1B0) | _BV(COM1B1) | _BV(PWM1A) | _BV(PWM1B);
+       TCCR1B = 0x80| _BV(CS13) | _BV(CS11);
+       TC1H  = 0x03;
        OCR1C = 0xFF;
-       OCR1D = 0x20;
-       TCNT1 = 3;
-       DDRB |= _BV( PB5 );
-       PORTB &= ~_BV( PB5 );
-
-       _delay_ms(1000);
-       eeprom_write_byte(&dbg[0], TCNT1);
-       eeprom_write_byte(&dbg[1], OCR1C);
-       eeprom_write_byte(&dbg[2], OCR1D);
-       eeprom_write_byte(&dbg[3], TIFR);
-       eeprom_write_byte(&dbg[4], TCCR1B);
+       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 );