From f6117273f63c0545b45d2a2b6e86a4e4e68cb7c8 Mon Sep 17 00:00:00 2001 From: "Jan \"Yenya\" Kasprzak" Date: Thu, 23 Aug 2012 10:54:50 +0200 Subject: [PATCH] multi-mode light --- lights.c | 117 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 67 insertions(+), 50 deletions(-) diff --git a/lights.c b/lights.c index 78bd2e1..d05fa1c 100644 --- a/lights.c +++ b/lights.c @@ -5,22 +5,25 @@ #include volatile uint16_t adcval; -unsigned char pwmval = 0x10; -volatile uint16_t adc_exp = 0x10; 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; } @@ -28,6 +31,7 @@ static void inline led_off() { led_is_on = 0; DDRB &= ~_BV( PB5 ); + PORTA &=~ _BV( PA0 ); // ADCSRA &= ~(_BV(ADIE) | _BV(ADIF)); } @@ -72,7 +76,7 @@ static void log_word(uint16_t word) { /* ------------ Timer ----------- */ -volatile uint16_t clock = 0; +volatile uint16_t jiffies = 0; static void inline init_tmr() { @@ -82,35 +86,42 @@ static void inline init_tmr() TIMSK |= _BV(OCIE0A); DDRA |= _BV( PA0 ); - clock = 0; + jiffies = 0; } static void inline tmr_handler() { - unsigned char c = clock & 0x1F; - unsigned char c1 = clock & 0xFF; + unsigned char c = jiffies & 0x0F; + unsigned char c1 = jiffies & 0x7F; + + ++jiffies; - ++clock; #if 0 - if (c == 10 || c == 30) + if (c == 1) led_on(); - if (c == 20 || c == 40) + if (c == 9) led_off(); #endif if (c == 0x02 || c == 0x08) led_on(); + if (c == 0x05 || c == 0x0b) led_off(); - if ((clock & 0x7F) == 0x1F) { - if (c1 < 0x80) { - adc_exp = 0x80; - } else { - adc_exp = 0x20; - } +#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) { @@ -144,9 +155,9 @@ static void inline init_pwm() | _BV(CS10) // no clock prescaling ; OCR1C = 0xFF; // TOP value - OCR1D = OCR1B = OCR1A = pwmval; + OCR1D = OCR1B = OCR1A = 0; // OCR1D = 0; - // DDRB |= _BV( PB5 ); + DDRB |= _BV( PB5 ); PORTB &= ~(_BV( PB5 ) | _BV( PB1 ) | _BV( PB3 )); // led_off(); @@ -186,32 +197,35 @@ static void inline init_adc() static void inline adc_handler() { - uint16_t new_pwm = pwmval; - uint16_t old_pwm = pwmval; - uint16_t old_adc = adcval; + 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; adccount++; // log_word(((adcval & 0x3FC) << 6) | pwmval); - log_word(((adcval & 0xFF) << 8) | pwmval); if (!led_is_on) return; - // adcval = (adcval + 3*old_adc)/4; // ADCSRA &= ~(_BV(ADIE) | _BV(ADIF)); - if (adcval < 1) { - adcval = 1; - } else if (adcval > adc_exp) { - new_pwm = old_pwm*adc_exp/adcval; - } else if (adcval < adc_exp && 2 * adcval > adc_exp) { - new_pwm = old_pwm*adc_exp/adcval; - } else if (adcval < adc_exp) { - new_pwm = 2 * old_pwm; + if (led_mode_changed) { + led_mode_changed = 0; + goto set_pwm; + } + + log_word(((adcval & 0xFF) << 8) | old_pwm); + + 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; } - new_pwm = (3*old_pwm + new_pwm) / 4; if (new_pwm > 0x60) { // odpojeno? new_pwm = 0x60; } @@ -219,10 +233,11 @@ static void inline adc_handler() new_pwm = 2; } - // if (new_pwm < 15*old_pwm/16 || new_pwm > 17*old_pwm/16) { - pwmval = new_pwm; - OCR1D = pwmval; - // } +set_pwm: + if (new_pwm != old_pwm) { + led_modes[led_mode].pwmval = new_pwm; + OCR1D = new_pwm; + } // ADCSRA |= _BV(ADSC); } @@ -233,24 +248,26 @@ ISR(ADC_vect) int main(void) { + _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 - DDRA |= _BV( PA0 ); - while( 1 ) { - PORTA |= _BV( PA0 ); - _delay_ms(200); - PORTA &=~ _BV( PA0 ); - } + while (1) { + PORTA |= _BV( PA0 ); + _delay_ms(200); + PORTA &=~ _BV( PA0 ); + _delay_ms(200); + } #endif } -- 2.39.3