X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?p=heater.git;a=blobdiff_plain;f=firmware%2Fmain.c;h=fcb74261d6df2df28c1034c95da4a85053fb0eba;hp=9a041500be8aefd19088472b2aa1ae2d8e50ca9d;hb=4c4fe8554a4c770d68dba4b45df716c4d0308a2f;hpb=36f60161fac194572a272bdb0239a01fcf2b801b diff --git a/firmware/main.c b/firmware/main.c index 9a04150..fcb7426 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -7,7 +7,9 @@ #include "logging.h" -static unsigned char pwm = 1; +#define N_STEPS 5 +static unsigned char steps[] = { 60, 85, 121, 171, 242 }; +static unsigned char intensity = 0; static void timer_init() { @@ -15,10 +17,32 @@ static void timer_init() DDRB |= _BV(PB4); - TCCR1 = _BV(CS10); // clk/1 = 1 MHz - // TCCR1 = _BV(CS11) | _BV(CS13); // clk/512 = 2 kHz + // TCCR1 = _BV(CS10); // clk/1 = 1 MHz + TCCR1 = _BV(CS11) | _BV(CS13); // clk/512 = 2 kHz GTCCR = _BV(COM1B1) | _BV(PWM1B); OCR1C = 255; + OCR1B = steps[0]; + TIMSK = _BV(OCIE1B) | _BV(TOIE1); +} + +volatile unsigned char adc_type, adc_drop; + +ISR(TIM1_OVF_vect) +{ + adc_drop = 2; + adc_type = 1; + ADCSRA |= _BV(ADSC); +} + +ISR(TIM1_COMPB_vect) +{ + adc_drop = 2; + adc_type = 0; + ADCSRA |= _BV(ADSC); +} + +static void set_pwm(unsigned char pwm) +{ OCR1B = pwm; } @@ -26,11 +50,38 @@ static void adc_init() { power_adc_enable(); - ADCSRA = _BV(ADEN) | _BV(ADPS1) | _BV(ADPS0); // clk/8 = 125 kHz + ADCSRA = _BV(ADEN) | _BV(ADPS1) | _BV(ADPS0) | _BV(ADIE); // clk/8 = 125 kHz ADMUX = _BV(REFS1) | _BV(MUX1) | _BV(MUX0); // 1.1V ref., PB3 single-ended DIDR0 = _BV(ADC3D); } +volatile uint16_t batt_on, batt_off; + +ISR(ADC_vect) +{ + uint16_t adcw = ADCW; + + if (adc_drop) { + adc_drop--; + ADCSRA |= _BV(ADSC); + return; + } + + if (adc_type == 0) { + if (batt_off) { + batt_off += adcw - (batt_off >> 5); + } else { + batt_off = adcw << 5; + } + } else { + if (batt_on) { + batt_on += adcw - (batt_on >> 5); + } else { + batt_on = adcw << 5; + } + } +} + static void status_led_init() { DDRB |= _BV(PB2); @@ -47,6 +98,11 @@ static void status_led_off() PORTB &= ~_BV(PB2); } +static unsigned char status_led_is_on() +{ + return PORTB & _BV(PB2) ? 1 : 0; +} + static void buttons_init() { DDRB &= ~(_BV(PB0) | _BV(PB1)); // set as input @@ -160,9 +216,8 @@ static void power_down() static void button_one_pressed() { - if (pwm > 1) { - pwm >>= 1; - OCR1B = pwm; + if (intensity > 0) { + set_pwm(steps[--intensity]); } else { power_down(); } @@ -170,9 +225,8 @@ static void button_one_pressed() static void button_two_pressed() { - if (pwm < 0x80) { - pwm <<= 1; - OCR1B = pwm; + if (intensity < N_STEPS-1) { + set_pwm(steps[++intensity]); } } @@ -207,23 +261,39 @@ static void timer_check_buttons() button_state = newstate; } +static unsigned char blink_on_time, blink_off_time, n_blinks; +static unsigned char blink_counter; + +static void timer_blink() +{ + if (blink_counter) { + blink_counter--; + } else if (status_led_is_on()) { + status_led_off(); + blink_counter = blink_off_time; + } else if (n_blinks) { + --n_blinks; + status_led_on(); + blink_counter = blink_on_time; + } else { + n_blinks = intensity + 1; + blink_on_time = 0; + blink_off_time = 2; + blink_counter = 10; +#if 0 + log_byte(0xbb); + log_byte(batt_on >> 7); + log_byte(batt_off >> 7); +#endif + } +} + int main() { log_init(); power_down(); -#if 0 - ADCSRA |= _BV(ADSC); - while (!(ADCSRA & _BV(ADIF))) - ; - log_word(ADCW); - ADCSRA |= _BV(ADSC); - while (!(ADCSRA & _BV(ADIF))) - ; - log_word(ADCW); - log_flush(); -#endif sei(); // we try to be completely IRQ-driven, so just wait for IRQs here @@ -239,6 +309,8 @@ int main() if (wdt_timer_fired) { wdt_timer_fired = 0; timer_check_buttons(); + timer_blink(); + log_flush(); } } }