/* * Copyright 2009 Ettus Research LLC */ #include "config.h" #include #include #include #include #include #include #include #include "global.h" #include "power.h" #include "debug.h" #include "error.h" #include "ltc3675.h" #ifdef CHARGER_TI #include "bq24190.h" #else #include "ltc4155.h" #endif // CHARGER_TI #define AUTO_POWER_ON #define INITIAL_DELAY 250 // ms FUSES = { // FIXME: & FUSE_CKSEL1 for low power 128 kHz clock .low = (FUSE_CKSEL0 & FUSE_SUT0 & FUSE_CKDIV8), // Internal 8MHz Oscillator, Slowly rising power (start-up time), Divide Clock by 8 .high = (FUSE_EESAVE & FUSE_SPIEN), // Save EEPROM between flashes // FIXME: Leave SPIEN for programming enabled? }; // Not using watchdog as it runs during sleep and consumes power volatile STATE _state; /* - Main/shared variables must be volatile - Port pins are tri-stated on reset * AVR_IRQ PD(5) - Enable pull-ups on all O.D. outputs from regulator chip * PS_POR/SRST should be driven HIGH by ATTiny? - AVR_RESET -> RESET pin - don't configure fuse (this would disable this functionality and prohibit serial programming) * Ship-and-store mode for charge controller? * cli before I2C calls * PS_TX - en5-clk, en2-data * Instruction following SEI is executed before interrupts * LTC3675 real-time status doesn't contain UV/OT * LTC3675 PGOOD -> power down (no point in checking blink state) * On WALL, use TX, on battery use OTG switcher * PRR - Power Reduction Register (p40) - 100% -> 50% battery charge limit * Check latched status for UV/OT in 3675 * If blink error reset, get latest charge status from 4155 * Fix UV status check from 3675/4155 as they currently share the same error * Use charger termination at 8hr or Vc/x * Check PGood on all regs after power on before setting powered=true * Re-init 4155 on soft-power on - Re-set 3A limit in 4155 after external power connection - Removing power when running on battery, 4155GO 0xA0 - but WALL has been removed - Why is charger reporting Constant Current when power is removed * ltc3675_is_power_button_depressed: check if any reg is on, otherwise value will be invalid * When e.g. 3.3V doesn't come up, blink code is correctly 4 but there's a very short blink before re-starting the sequence - Vprog _state.blink_error*/!= BlinkError_None)) // [Prioritise] Always keep first sequence running return; else if (_state.blink_error == count) // Don't restart if the same return; if (count == BlinkError_None) { debug_log("BLNK-"); _state.blink_stop = true; return; } //char msg[25]; //sprintf(msg, "Blink code = %i\n", count); //debug_log(msg); debug_log_ex("BLNK ", false); debug_log_byte(count); _state.blink_error = count; _state.blink_loops = 0; _state.blink_last_loop = 0; _state.blinker_state = 0; _state.blink_stop = false; charge_set_led(false); TCNT0 = 0; if ((TCCR0A & 0x07) == 0x00) // Might already be active with existing error _state.active_timers++; TCCR0A |= 0x05; // Start with 1024 prescale } ISR(TIMER0_COMPA_vect) // Blink the sequence, and leave one slot at the beginning and end where the LED is off so one can get a sense of how many blinks occurred { pmc_mask_irqs(true); if (_state.blinker_state < (2 * _state.blink_error + 1)) charge_set_led((_state.blinker_state % 2) == 1); _state.blinker_state++; if (_state.blinker_state == (2 * _state.blink_error + 1 + 1)) { _state.blinker_state = 0; if (_state.blink_stop) { if ((TCCR0A & 0x07) != 0x00) _state.active_timers--; TCCR0A &= ~0x07; _state.blink_error = BlinkError_None; debug_log("BLNK."); } else { _state.blink_loops++; } } pmc_mask_irqs(false); }