#include "pm.h" #include #include #include #include void pm_reset() { DDRB = 0; DDRC = 0; DDRD = 0; PORTB = 0; PORTC = 0; PORTD = 0; GICR = 0; // Reset to bootloader WDTCR = (1 << WDE) | (1 << WDP2); while(1); /* // Reset to application asm("ldi R16,0x00"); asm("push R16"); asm("push R16"); asm("push R16"); asm("push R16"); asm("ret"); while (1); */ } void pm_axl_on() { HAL_ON(AXL_EN); } void pm_axl_off() { HAL_OFF(AXL_EN); } void pm_init() { cli(); HAL_INIT(VBUS_SENSE, INPUT, OFF); // USB connected indicator HAL_INIT(VLED_EN_N, OUTPUT, OFF_N); // VLED DCDC converter enable HAL_INIT(CHG_ACTIVE_N, INPUT, ON); // Battery charging status input HAL_INIT(BAT_SENSE, INPUT, OFF); // No pull-up on Batt sense ADC input HAL_INIT(BAT_SENSE_EN_N, INPUT, OFF); // Disable using High-Z HAL_INIT(AXL_EN, OUTPUT, OFF); // Turn off AXL HAL_INIT(AXL_I2C, INPUT, OFF); // No Pull-ups on I2C // Hardware bug after sleep. Need to manually turn off->on I2C transceiver. TWCR &= ~((1 << TWSTO) | (1 << TWEN)); sei(); } void pm_disable_periphery() { cli(); // Turn off HW TCCR1B = 0; TIMSK = 0; WDTCR = 0; TWCR = 0; SPCR = 0; ADCSRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; PORTB = 0; PORTC = 0; PORTD = 0; } void pm_suspend() { pm_disable_periphery(); // Activate wake from button HAL_INIT(BUTTON_N, INPUT, ON); // Pull-up for user button MCUCR = (1 << SM1) | (1 << SE); sei(); sleep_cpu(); cli(); } void pm_led_on_auto() { if (pm_ac_connected()) pm_led_off(); else pm_led_on(); } void pm_led_on() { HAL_ON_N(VLED_EN_N); } void pm_led_off() { HAL_OFF_N(VLED_EN_N); } int pm_ac_connected() { return HAL_ASSERTED(VBUS_SENSE); } int pm_charging() { return HAL_ASSERTED_N(CHG_ACTIVE_N); }