X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=lights.c;h=d05fa1cf45c06f17b19306624cabd99ead2c004b;hb=1647725c8e3e1297a330e5ab18ad6033fec807dd;hp=635b24996f871fcc3fdc64451b1dd212f9806422;hpb=a16af64fe34410052a668c2e0ee87c9eb6876e43;p=bike-lights.git diff --git a/lights.c b/lights.c index 635b249..d05fa1c 100644 --- a/lights.c +++ b/lights.c @@ -5,25 +5,34 @@ #include 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 ----------- */ @@ -35,9 +44,11 @@ static void inline debug_setstate(unsigned char val) 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() { @@ -46,49 +57,79 @@ 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) @@ -110,27 +151,28 @@ 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); - 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 @@ -139,72 +181,64 @@ ISR(TIMER1_OVF_vect) 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) @@ -212,51 +246,28 @@ 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 ); - } }