]> www.fi.muni.cz Git - bike-lights.git/commitdiff
PWM + ADC + code cleanups
authorJan "Yenya" Kasprzak <kas@fi.muni.cz>
Tue, 12 Jun 2012 21:20:15 +0000 (23:20 +0200)
committerJan "Yenya" Kasprzak <kas@fi.muni.cz>
Tue, 12 Jun 2012 21:20:15 +0000 (23:20 +0200)
lights.c

index 6d78e2335d41083f4d6f0704a0d0fe506a00f6df..635b24996f871fcc3fdc64451b1dd212f9806422 100644 (file)
--- a/lights.c
+++ b/lights.c
@@ -4,8 +4,9 @@
 #include <avr/sleep.h>
 #include <avr/interrupt.h>
 
-uint16_t pwmee EEMEM;
 volatile uint16_t adcval;
+unsigned char pwmval = 0x28;
+uint16_t pwmints = 0;
 
 volatile struct
 {
@@ -15,46 +16,127 @@ volatile struct
 }
 intflags;
 
+static void inline led_on()
+{
+        DDRB |= _BV( PB5 );
+}
+
+static void inline led_off()
+{
+        DDRB &= ~_BV( PB5 );
+}
 
-unsigned char debug EEMEM = 1;
+/* ------------ Logging/Debugging ----------- */
 
-ISR(ADC_vect)
+unsigned char debug_state EEMEM;
+
+static void inline debug_setstate(unsigned char val)
 {
-       adcval = ADCW;
-       ADCSRA &= ~_BV(ADIE);         /* disable ADC interrupt */
-       intflags.adc_int = 1;
+       eeprom_write_byte(&debug_state, val);
 }
 
-ISR(TIMER1_OVF_vect)
+#define LOG_BUFFER 192
+uint16_t log_buffer[LOG_BUFFER] EEMEM;
+uint16_t log_buffer_count;
+
+static void inline init_log()
 {
-       TIMSK &= ~_BV(TOIE1);
-       intflags.pwm_int = 1;
+       debug_setstate(1);
+       log_buffer_count = 0;
+}
+
+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);
+       log_buffer_count++;
+}
+
+/* ------------ Timer ----------- */
+
+uint16_t clock = 0;
+
+static void inline init_tmr()
+{
+       TCCR0A = _BV(WGM00);
+       TCCR0B = _BV(CS02) | _BV(CS00); // 1 kHz
+       OCR0A = 10; // 100 Hz
+       TIMSK |= _BV(OCIE0A);
+       DDRA |= _BV( PA0 );
+
+       clock = 0;
+}
+
+static void inline tmr_handler()
+{
+       unsigned char c = clock & 0x7F;
+       ++clock;
+
+       if (c == 10 || c == 30) 
+               led_on();
+
+       if (c == 20 || c == 40)
+               led_off();
+
+       log_word(adcval);
+       if (adcval != 0xFFEE) {
+               adcval = 0xFFEE;
+
+               ADCSRA |= _BV(ADIE) | _BV(ADSC);
+       }
 }
 
 ISR(TIMER0_COMPA_vect)
 {
-       intflags.tmr_int = 1;
+       tmr_handler();
 }
 
-struct {
-       unsigned char intensity :2;
-       unsigned char length :6;
-} pattern[] = { {1, 2}, {0, 4}, { 1, 2 }, {0, 15}, {0, 0} };
-       
+/* ------------ PWM ----------- */
+
 static void inline init_pwm()
 {
+       /* Async clock */
+       PLLCSR = _BV(LSM) | _BV(PLLE);
+       _delay_ms(1);
+       while (PLLCSR & _BV(PLOCK) == 0)
+               ;
+       PLLCSR |= _BV(PCKE);
+
        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;
+       // TCCR1B = 0x80| _BV(CS13) | _BV(CS11);
+       TCCR1B = 0x80 | _BV(CS10);
        OCR1C = 0xFF;
-       OCR1D = OCR1B = OCR1A = 0x40;
+       OCR1D = OCR1B = OCR1A = pwmval;
        TCNT1 = 0;
-       DDRB |= _BV( PB5 ) | _BV( PB1 ) | _BV( PB3 );
+       DDRB |= _BV( PB5 );
        PORTB &= ~(_BV( PB5 ) | _BV( PB1 ) | _BV( PB3 ));
-       TIMSK |= _BV(TOIE1);
+
+       led_off();
+       // TIMSK |= _BV(TOIE1);
 }
 
+#if 0
+static void inline pwm_handler()
+{
+       TCNT1 = 0;
+       OCR1D = pwmval;
+}
+
+ISR(TIMER1_OVF_vect)
+{
+       TIMSK &= ~_BV(TOIE1);
+       pwm_handler();
+}
+#endif
+
+/* ------------ A/D Converter ----------- */
+
 static void inline init_adc()
 {
        ADCSRA = _BV(ADEN) | _BV(ADATE) | _BV(ADPS1) | _BV(ADPS0);
@@ -63,94 +145,118 @@ static void inline init_adc()
        DIDR0 = _BV(ADC1D) | _BV(AREFD);
 }
 
-static void inline init_tmr()
+static void inline adc_handler()
 {
-       TCCR0A = _BV(WGM00);
-       TCCR0B = _BV(CS02); // | _BV(CS00);
-       OCR0A = 0x80;
-       TIMSK |= _BV(OCIE0A);
-       DDRA |= _BV( PA0 );
-}
+       static unsigned char last_pwmval = 0;
+       static unsigned char counter = 0;
+       uint16_t tmp = pwmval;
+       static uint16_t discard = 5;
 
-int main(void)
-{
-       char seen = 0;
-       char pcount, ppos;
-
-       init_pwm();
-       init_adc();
-       init_tmr();
+       adcval = ADCW;
+       ADCSRA &= ~_BV(ADIE);         /* disable ADC interrupt */
+#if 0
+       if (--discard > 0)
+               goto out;
 
-       ppos = 0;
-       pcount = pattern[ppos].length;
-        if (pattern[ppos].intensity) {
-               PORTA |=  _BV( PA0 );
-       }
+       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++;
 
-       while (1) {
-               unsigned char pwmhi, pwmlo;
+       if (tmp > 0xFF)
+               tmp = 0xFF;
+       if (tmp == 0)
+               tmp = 1;
 
-               if (intflags.adc_int) {
-                       intflags.adc_int = 0;
+       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);
+               }
+       }
 
-                       if (adcval > 0x3C0)
-                               adcval = 0x3C0;
-                       if (adcval < 1)
-                               adcval = 1;
-                       pwmhi = adcval >> 8;
-                       pwmlo = adcval & 0xFF;
+       last_pwmval = pwmval;
+       pwmval = tmp;
 
-                       TC1H = pwmhi;
-                       OCR1D = pwmlo;
+       if (pwmval != last_pwmval) {
+               TIMSK |= _BV(TOIE1);
+               
+               discard = 1000;
+       } else {
+               discard = 0;
+       }
 
-                       TC1H = pwmhi;
-                       OCR1B = pwmlo;
+out:
+       //TIMSK |= _BV(TOIE1);
+       ADCSRA |= _BV(ADIE) | _BV(ADSC);
+#endif
+}
 
-                       TC1H = pwmhi;
-                       OCR1A = pwmlo;
+ISR(ADC_vect)
+{
+       adc_handler();
+}
 
-                       TIMSK |= _BV(TOIE1);
+#if 0
+       if (--pcount == 0) {
+               ppos++;
+               pcount = pattern[ppos].length;
+               if (!pcount) {
+                       ppos = 0;
+                       pcount = pattern[ppos].length;
                }
-
-               if (intflags.pwm_int) {
-                       intflags.pwm_int = 0;
-                       ADCSRA |= _BV(ADIE) | _BV(ADSC);
+               if (pattern[ppos].intensity) {
+                       PORTA |= _BV(PA0);
+               } else {
+                       PORTA &= ~_BV(PA0);
                }
+       }
+#endif
 
-               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);
-                               }
-                       }
-               }
+int main(void)
+{
+       char seen = 0;
+       char pcount, ppos;
+       unsigned char adcidx = 0;
+       uint16_t adcvals[16];
 
-               sei();
-               sleep_mode();
-               cli();
+       init_log();
 
+       init_pwm();
+       init_adc();
+       init_tmr();
+
+       debug_setstate(2);
+
+       sei();
+       while (1)
+               ; //sleep_mode();
 #if 0
                if (!seen) {
                        seen = 1;
                        eeprom_write_byte(&debug, 2);
                }
 #endif
-       }
 
     DDRA |= _BV( PA0 );
     while( 1 ) { 
         PORTA |=  _BV( PA0 );
-        _delay_ms(2000);
+        _delay_ms(200);
         PORTA &=~ _BV( PA0 );
-        _delay_ms(2000);
     }
 }