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=0d45ac93d9a6429bc040486f173f93a2f7d9b0bc;hp=ec582327a3d450d78aa6ae54058354a8862c3e91;hb=e847a9fc0c504419a8e2f93a813312d0be94c7ef;hpb=164f72d29f27faca0a4b2683f73e96a53edeedee diff --git a/firmware/main.c b/firmware/main.c index ec58232..0d45ac9 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -33,9 +33,8 @@ * Status LED: * When powering up by a button press, the LED goes on to provide a visual * feedback, and is switched off after the button is released. - * After a button press, the # of blinks of the LED reflects the - * chosen output power level for some time. Afterwards, it displays - * the battery level. + * It displays the current power level and current battery voltage + * using # of blinks with different blinking lengths. * When the battery is completely exhausted, the output power is switched * off, the LED keeps blinking for some time, and then the whole system is * switched off to avoid deep discharge of the battery. @@ -59,6 +58,16 @@ #define WAKEUP_POLL 50 // msec #define WAKEUP_LIMIT 5 // times WAKEUP_POLL +// #define BUTTONS_REVERSE + +#ifdef BUTTONS_REVERSE +# define BUTTON1 PB0 +# define BUTTON2 PB1 +#else +# define BUTTON1 PB1 +# define BUTTON2 PB0 +#endif /* !BUTTONS_REVERSE */ + /* which state (output on or output off) are we measuring now */ static volatile unsigned char adc_type, adc_drop; #define ADC_RUNAVG_SHIFT 5 // running average shift on batt_on, batt_off @@ -107,9 +116,7 @@ static unsigned char power_levels[] = { #define N_POWER_LEVELS (sizeof(power_levels) / sizeof(power_levels[0])) static unsigned char power_level = 0; // selected power level -static unsigned char power_level_changed; // for visual feedback -#define LED_PWRCHANGE_COUNT 3 #define LED_BATTEMPTY_COUNT 60 /* timing by WDT */ @@ -125,9 +132,8 @@ static void adc_init() { power_adc_enable(); - ADCSRA = _BV(ADEN) // enable - | _BV(ADPS1) | _BV(ADPS0) // clk/8 = 125 kHz - | _BV(ADIE); // enable IRQ + ADCSRA = _BV(ADEN) // enable + | _BV(ADPS1) | _BV(ADPS0); // clk/8 = 125 kHz ADMUX = _BV(REFS1) | _BV(MUX1) | _BV(MUX0); // 1.1V reference, PB3 pin, single-ended DIDR0 |= _BV(ADC3D); // PB3 pin as analog input @@ -135,15 +141,17 @@ static void adc_init() static void adc_susp() { - ADCSRA &= ~_BV(ADEN); // disable ADC + ADCSRA = 0; // disable ADC DIDR0 &= ~_BV(ADC3D); // disable analog input on PB3 power_adc_disable(); } -static void adc_start_measurement() +static void adc_start_measurement(unsigned char on) { - ADCSRA |= _BV(ADSC); + adc_drop = 1; + adc_type = on; + ADCSRA |= _BV(ADSC) | _BV(ADIE); } ISR(ADC_vect) @@ -172,6 +180,7 @@ ISR(ADC_vect) batt_on = adcw << ADC_RUNAVG_SHIFT; } } + ADCSRA &= ~_BV(ADIE); } /* ===================== Timer/Counter1 for PWM ===================== */ @@ -209,16 +218,12 @@ static void pwm_susp() ISR(TIM1_OVF_vect) { - adc_drop = 1; - adc_type = 1; - adc_start_measurement(); + adc_start_measurement(1); } ISR(TIM1_COMPB_vect) { - adc_drop = 1; - adc_type = 0; - adc_start_measurement(); + adc_start_measurement(0); } static void pwm_set(unsigned char pwm) @@ -269,9 +274,9 @@ static void buttons_susp() static unsigned char buttons_pressed() { return ( - (PINB & _BV(PB0) ? 0 : 1) + (PINB & _BV(BUTTON1) ? 0 : 1) | - (PINB & _BV(PB1) ? 0 : 2) + (PINB & _BV(BUTTON2) ? 0 : 2) ); } @@ -381,10 +386,12 @@ static unsigned char battery_level() static void status_led_next_pattern() { static unsigned char battery_exhausted; + static unsigned char display_power_level; - if (power_level_changed) { - power_level_changed--; + if (display_power_level) { n_blinks = power_level + 1; + blink_on_time = 1; + blink_off_time = 2; } else { unsigned char b_level = battery_level(); if (b_level) { @@ -397,11 +404,12 @@ static void status_led_next_pattern() } n_blinks = b_level + 1; + blink_on_time = 3; + blink_off_time = 0; } - blink_on_time = 2; - blink_off_time = 1; blink_counter = 10; + display_power_level = !display_power_level; } static void timer_blink() @@ -424,9 +432,6 @@ static void timer_blink() static void button_pressed(unsigned char button, unsigned char long_press) { // ignore simlultaneous button 1 and 2 press - // Note: we set power_level_changed after each button press, - // even when the power is at maximum, to provide visual feedback - // with status LED. if (long_press) { if (button == 1) { power_down(); @@ -448,7 +453,6 @@ static void button_pressed(unsigned char button, unsigned char long_press) } } } - power_level_changed = LED_PWRCHANGE_COUNT; status_led_next_pattern(); } @@ -489,12 +493,16 @@ static void calculate_power_level() uint32_t pwm; unsigned char batt_on8; - if (battery_level() == 0 || batt_on == 0) { + if (battery_level() == 0) { pwm_set(0); // TODO power_down() after some time return; } + if (!batt_on) { + batt_on = batt_off; + }; + batt_on8 = batt_on >> 8; pwm = (uint32_t)PWM_TOP * power_levels[power_level] @@ -507,9 +515,11 @@ static void calculate_power_level() if (pwm < PWM_MIN) pwm = PWM_MIN; +#if 0 log_byte(0x10 + power_level); log_byte(batt_on8); log_byte(pwm & 0xFF); +#endif pwm_set(pwm); }