#include #include #include #include #include #include #include "lights.h" #if 0 static void hw_setup() { power_all_disable(); // init_battery(); init_pwm(); // init_adc(); // init_wdt(); // // init_buttons(); // init_pwmled(); // init_pattern(); // init_control(); // set_sleep_mode(SLEEP_MODE_IDLE); } static void hw_suspend() { susp_pwm(); susp_adc(); susp_wdt(); susp_buttons(); power_all_disable(); } void power_down() { hw_suspend(); do { // G'night set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_enable(); sleep_bod_disable(); sei(); sleep_cpu(); // G'morning cli(); sleep_disable(); // allow wakeup by long button-press only } while (!buttons_wait_for_release()); // ok, so I will wake up hw_setup(); } #endif uint16_t read_adc_sync() { uint16_t rv; ADCSRA |= _BV(ADSC); // start the conversion // wait for the conversion to finish while((ADCSRA & _BV(ADIF)) == 0) ; rv = ADCW; ADCSRA |= _BV(ADIF); // clear the IRQ flag return rv; } void init_adc() { power_adc_enable(); ACSR |= _BV(ACD); // but disable the analog comparator ADCSRA = _BV(ADEN) // enable // | _BV(ADPS1) | _BV(ADPS0) // CLK/8 = 125 kHz | _BV(ADPS2) // CLK/16 = 62.5 kHz ; // Disable digital input on all bits used by ADC DIDR0 = _BV(ADC3D) | _BV(ADC2D); ADMUX = _BV(REFS1) | _BV(MUX1) | _BV(MUX0); /* Do first conversion and drop the result */ read_adc_sync(); // ADCSRA |= _BV(ADIE); // enable IRQ } int main(void) { uint16_t a, p, c, target; int32_t sum; uint8_t micro; init_log(); log_set_state(3); init_pwm(); init_adc(); // init_pwmled(); pwm_set(1); // setup_mux(0); // pwmled_on_off(1); // pwmled_set_target(1); sum = 0; c = 0; micro = 0; sei(); target = 0xf0; #if 0 while(1) { unsigned char p; for (p = 0xd4; p <= 0xd5; p+= 0x1) { unsigned char i, j; uint16_t sum; pwm_set(p); for (j = 0; j < 12; j++) { sum = 0; for (i = 0; i < 2; i++) { sum += read_adc_sync(); } log_byte(sum); for (i = 0; i < 14; i++) { sum += read_adc_sync(); } } log_flush(); } } #endif while (1) { sum += target - read_adc_sync() - (sum >> 7); micro++; if (micro > 7) micro = 0; p = ((sum >> 4) + micro) >> 3; if (p > 0xd8) p = 0xd8; pwm_set(p); if (++c > 200) { log_byte(p); log_flush(); c = 0; } } p = a = c = 0; while (1) { uint16_t i; for (i = 0; i < 25; i++) { uint16_t val; val = read_adc_sync(); a += val - (a >> 5); } if (a < (42 << 5) && p < 250) { p++; } else if (p > 1 && a > (38 << 5)) { p--; } pwm_set(p); if (++c > 1000) { log_byte(0xbb); // log_word(read_adc_sync()); log_word(a); log_word(p); log_flush(); c = 0; } } while(1) { uint16_t i, t; for (t = 0; t < 3; t++) { pwmled_set_target(t); for (i = 0; i < 1000; i++) { need_pwmled_adc = 1; while (need_pwmled_adc == 1) ; } } } #if 0 hw_setup(); power_down(); #if 1 while (1) { cli(); if (pwm_enabled) { set_sleep_mode(SLEEP_MODE_IDLE); } 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(); sleep_disable(); } #endif #if 0 DDRB |= _BV(PB2); while (1) { PORTB |= _BV( PB2 ); _delay_ms(200); PORTB &=~ _BV( PB2 ); _delay_ms(200); } #endif #endif }