Deeper sleep when idle
authorJan "Yenya" Kasprzak <kas@fi.muni.cz>
Fri, 10 May 2013 21:52:55 +0000 (23:52 +0200)
committerJan "Yenya" Kasprzak <kas@fi.muni.cz>
Fri, 10 May 2013 21:52:55 +0000 (23:52 +0200)
projects/step-up/adc.c
projects/step-up/battery.c
projects/step-up/lights.h
projects/step-up/main.c
projects/step-up/pwm.c
projects/step-up/pwmled.c
projects/step-up/wdt.c

index ea30935..55cd861 100644 (file)
@@ -10,8 +10,9 @@
 //#define NUM_ADCS     ZERO_ADC
 #define NUM_ADCS       2
 
-volatile static unsigned char current_adc;;
-volatile unsigned char need_battery_adc;
+volatile static unsigned char current_adc;
+volatile unsigned char adc_enabled;
+volatile unsigned char need_battery_adc, need_pwmled_adc;
 static uint16_t adc_sum, read_zero, drop_count, read_count, n_reads_log;
 volatile uint16_t jiffies;
 
@@ -40,13 +41,23 @@ void start_next_adc()
                drop_count = 1;
                read_count = 1;
                n_reads_log = 0;
-       } else {
+       } else if (need_pwmled_adc) {
                current_adc = 0;
                read_zero = 0;
                drop_count = 1;
                read_count = 1 << PWMLED_ADC_SHIFT;
                n_reads_log = PWMLED_ADC_SHIFT;
+       } else {
+               ADCSRA &= ~_BV(ADEN);
+               power_adc_disable();
+               adc_enabled = 0;
+               return;
+       }
 
+       if (!adc_enabled) {
+               power_adc_enable();
+               ADCSRA |= _BV(ADEN);
+               adc_enabled = 1;
        }
 
        adc_sum = 0;
@@ -95,7 +106,9 @@ static uint16_t read_adc_sync()
 void init_adc()
 {
        need_battery_adc = 0;
+       need_pwmled_adc = 0;
        current_adc = 0;
+       adc_enabled = 1;
 
        power_adc_enable();
        ACSR |= _BV(ACD);       // but disable the analog comparator
@@ -124,6 +137,8 @@ void susp_adc()
 {
        ADCSRA = 0;
        DIDR0 = 0;
+       power_adc_disable();
+       adc_enabled = 0;
 }
 
 ISR(ADC_vect) { // IRQ handler
index ceb53cb..0e51cb1 100644 (file)
@@ -77,8 +77,10 @@ unsigned char battery_gauge()
                rv = 7;
        }
 
+#if 0
        if (rv == 1 && !initial_readings)
                set_error(ERR_BATTERY);
+#endif
 
 #if 0
        log_byte(0xbb);
index 2980cd3..4a0b6b9 100644 (file)
@@ -21,13 +21,14 @@ void inline log_word(uint16_t word) { }
 /* adc.c */
 #define PWMLED_ADC_SHIFT 1 /* 1<<1 measurements per single callback */
 extern volatile unsigned char need_battery_adc;
-extern volatile unsigned char adc_running;
+extern volatile unsigned char need_pwmled_adc;
+extern volatile unsigned char adc_enabled;
 void init_adc();
 void susp_adc();
 
 /* pwm.c */
 #define PWM_MAX 0xFF
-extern volatile unsigned char pwm_running;
+extern volatile unsigned char pwm_enabled;
 void init_pwm();
 void susp_pwm();
 void pwm_off();
index c1ee381..25d80df 100644 (file)
@@ -72,13 +72,15 @@ int main(void)
 #if 1
        while (1) {
                cli();
-               if (pwm_running) {
+               if (pwm_enabled) {
                        set_sleep_mode(SLEEP_MODE_IDLE);
-               } else if (adc_running) {
+               } else if (adc_enabled) {
                        set_sleep_mode(SLEEP_MODE_ADC);
                } else {
                        set_sleep_mode(SLEEP_MODE_PWR_DOWN);
                }
+
+               sleep_enable();
                // keep BOD active, no sleep_bod_disable();
                sei();
                sleep_cpu();
index 42ed777..b93a4fa 100644 (file)
@@ -11,7 +11,7 @@
  * Counts from 0 to 0xFF, without OCR1C compare.
  */
 
-static unsigned char pwm_enabled;
+volatile unsigned char pwm_enabled;
 
 static void inline enable_pll()
 {
@@ -57,6 +57,7 @@ void pwm_off()
        DDRB &= ~_BV(PB4);
 
        PLLCSR &= ~(_BV(PLLE) | _BV(PCKE));
+       power_timer1_disable();
        pwm_enabled = 0;
 }
 
@@ -65,6 +66,7 @@ void pwm_set(uint8_t stride)
        OCR1B = stride;
 
        if (!pwm_enabled) {
+               power_timer1_enable();
                enable_pll();
                DDRB |= _BV(PB4);
                pwm_enabled = 1;
index bc604da..485d024 100644 (file)
@@ -60,9 +60,11 @@ void pwmled_on_off(unsigned char mode)
        if (mode) {
                state = ST_ON;
                mode_changed = 1;
+               need_pwmled_adc = 1;
                pwm_set(pwm_val);
        } else {
                state = ST_OFF;
+               need_pwmled_adc = 0;
                pwm_off();
        }
 }
@@ -113,6 +115,7 @@ void pwmled_adc(uint16_t adcval)
        if (pwm_val >= PWM_MAX
                || (pwm_val > (2*PWM_MAX/3) && adcval < 0x08)) {
                pwmled_err();
+               need_pwmled_adc = 0;
                return;
        }
 
index 15bfbbb..cb94ec8 100644 (file)
@@ -17,10 +17,16 @@ void susp_wdt()
 ISR(WDT_vect) {
        ++jiffies;
 
+       if (pwm_enabled) {
+               need_pwmled_adc = 1;
+       }
+
        if (jiffies & 0x000F) {
                need_battery_adc = 1; // about every 1s
        }
 
        patterns_next_tick();
        timer_check_buttons();
+       if (!adc_enabled)
+               start_next_adc(); // only if not running
 }