#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(); DDRB = 0; DDRC = 0; DDRD = 0; PORTB = 0; PORTC = 0; PORTD = 0; 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 HAL_INIT(BUTTON_N, INPUT, ON); // Pull-up for user button MCUCR = (1 << ISC10); // Any-edge interrupt GICR = (1 << INT1); // Turn on button interrupt // Hardware bug after sleep. Need to manually turn off->on I2C transceiver. TWCR &= ~((1 << TWSTO) | (1 << TWEN)); sei(); } static void disable_periphery() { cli(); WDTCR = 0; TWCR = 0; SPCR = 0; ADCSRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; PORTB = 0; PORTC = 0; HAL_INIT(BUTTON_N, INPUT, ON); // Pull-up for user button } void pm_suspend() { disable_periphery(); MCUCR = (1 << SM1) | (1 << SE); sei(); sleep_cpu(); cli(); } 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); }