leddie/firmware/lib/pm.c

103 lines
1.5 KiB
C

#include "pm.h"
#include "hal.h"
#include <avr/io.h>
#include <util/delay.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
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(VLED_EN_N, OUTPUT, OFF_N); // VLED DCDC converter enable
HAL_INIT(CHG_ACTIVE_N, INPUT, OFF); // 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
GICR = (1 << INT1);
// 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();
//EICRA = 0;
//EIMSK = (1 << INT1);
//SMCR = (1 << SM1) | (1 << SE);
sei();
sleep_cpu();
cli();
}