blob: 4367e002af7ba6dad9f5ec78b40d1eb945fb52aa [file] [log] [blame] [edit]
#include "power.hpp"
#include "stm32h7xx_hal.h"
#include "32blit.h"
#include "32blit/battery.hpp"
#include "i2c.h"
#include "i2c-bq24295.h"
namespace power {
// power state we're changing to
enum class Target {
IDLE,
SLEEP,
OFF
};
static uint32_t last_input_time = 0, sleep_fade_start = 0;
float sleep_fade = 1.0f;
const int sleep_inactivity_time = 120000; // ms before sleeping
const int fade_out_time = 1000, auto_sleep_fade_out_time = 3000, fade_in_time = 500;
static Target target = Target::IDLE;
void update() {
if(target == Target::IDLE) {
// inactivity timeout
if(HAL_GetTick() - last_input_time > sleep_inactivity_time) {
target = Target::SLEEP;
sleep_fade_start = HAL_GetTick();
}
} else if(target == Target::OFF && sleep_fade == 0.0f) {
// fade to off complete
// TODO: disable almost everything (need HOME button interrupt, battery status, etc.)
// we're not charging, enter shipping mode to save battery
// (and shut down entirely if not connected to USB)
auto charge_status = battery::get_charge_status();
if(charge_status == battery::BatteryChargeStatus::NotCharging || charge_status == battery::BatteryChargeStatus::ChargingComplete)
bq24295_enable_shipping_mode(&hi2c4);
}
if(target != Target::IDLE) {
// fade out (slower for auto-sleep)
auto fade_time = target == Target::SLEEP ? auto_sleep_fade_out_time : fade_out_time;
sleep_fade = std::max(0.0f, 1.0f - float(HAL_GetTick() - sleep_fade_start) / fade_time);
blit_update_volume();
} else if(sleep_fade < 1.0f) {
// fade in
sleep_fade = std::min(1.0f, float(HAL_GetTick() - sleep_fade_start) / fade_in_time);
blit_update_volume();
}
}
void update_active() {
// fading out or done fading, fade back in
if(target == Target::SLEEP) {
target = Target::IDLE;
sleep_fade_start = HAL_GetTick() - sleep_fade * fade_in_time;
}
last_input_time = HAL_GetTick();
}
void power_off() {
target = Target::OFF;
sleep_fade_start = HAL_GetTick();
}
bool is_off() {
return target == Target::OFF && sleep_fade == 0.0f;
}
}