implemented sleep and power off

This commit is contained in:
Shaun Inman 2023-01-05 22:15:46 -05:00
parent 2cc36b97d5
commit db0042e57e
3 changed files with 102 additions and 33 deletions

View file

@ -12,23 +12,13 @@
#include <SDL/SDL_ttf.h> #include <SDL/SDL_ttf.h>
#include <errno.h> #include <errno.h>
#include <msettings.h>
#include "api.h" #include "api.h"
#include "utils.h"
#include "defines.h" #include "defines.h"
/////////////////////////////// ///////////////////////////////
// TODO: tmp
void powerOff(void) {
system("echo u > /proc/sysrq-trigger");
system("echo s > /proc/sysrq-trigger");
system("echo o > /proc/sysrq-trigger");
}
void fauxSleep(void) { }
int preventAutosleep(void) { return 0; }
int isCharging() { return 0; }
///////////////////////////////
void LOG_note(int level, const char* fmt, ...) { void LOG_note(int level, const char* fmt, ...) {
char buf[1024] = {0}; char buf[1024] = {0};
va_list args; va_list args;
@ -115,11 +105,11 @@ struct owlfb_mem_info {
/////////////////////////////// ///////////////////////////////
// NOTE: even with a buffer vsync blocks without threading
#define GFX_BUFFER_COUNT 3 #define GFX_BUFFER_COUNT 3
#define GFX_ENABLE_VSYNC #define GFX_ENABLE_VSYNC
// #define GFX_ENABLE_BUFFER #define GFX_ENABLE_BUFFER
// NOTE: even with a buffer vsync blocks without threading
/////////////////////////////// ///////////////////////////////
@ -176,7 +166,7 @@ SDL_Surface* GFX_init(void) {
gfx.vinfo.xres_virtual = SCREEN_WIDTH; gfx.vinfo.xres_virtual = SCREEN_WIDTH;
gfx.vinfo.yres_virtual = SCREEN_HEIGHT; gfx.vinfo.yres_virtual = SCREEN_HEIGHT;
#ifdef GFX_ENABLE_BUFFER #ifdef GFX_ENABLE_BUFFER
gfx.vinfo.yres_virtual *= GFX_BUFFER_COUNT gfx.vinfo.yres_virtual *= GFX_BUFFER_COUNT;
#endif #endif
#if defined (GFX_ENABLE_BUFFER) && !defined (GFX_ENABLE_VSYNC) #if defined (GFX_ENABLE_BUFFER) && !defined (GFX_ENABLE_VSYNC)
gfx.vinfo.xoffset = 0; gfx.vinfo.xoffset = 0;
@ -564,3 +554,76 @@ int PAD_anyPressed(void) { return pad.is_pressed!=BTN_NONE; }
int PAD_justPressed(int btn) { return pad.just_pressed & btn; } int PAD_justPressed(int btn) { return pad.just_pressed & btn; }
int PAD_isPressed(int btn) { return pad.is_pressed & btn; } int PAD_isPressed(int btn) { return pad.is_pressed & btn; }
int PAD_justReleased(int btn) { return pad.just_released & btn; } int PAD_justReleased(int btn) { return pad.just_released & btn; }
///////////////////////////////
static int can_poweroff = 1;
void POW_disablePowerOff(void) {
can_poweroff = 0;
}
void POW_powerOff(void) {
if (can_poweroff) {
system("echo u > /proc/sysrq-trigger");
system("echo s > /proc/sysrq-trigger");
system("echo o > /proc/sysrq-trigger");
}
}
#define BACKLIGHT_PATH "/sys/class/backlight/backlight.2/bl_power"
#define GOVERNOR_PATH "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"
static char governor[128];
static void POW_enterSleep(void) {
SetRawVolume(0);
putInt(BACKLIGHT_PATH, FB_BLANK_POWERDOWN);
// save current governor (either ondemand or performance)
getFile(GOVERNOR_PATH, governor, 128);
trimTrailingNewlines(governor);
putFile(GOVERNOR_PATH, "powersave");
sync();
}
static void POW_exitSleep(void) {
putInt(BACKLIGHT_PATH, FB_BLANK_UNBLANK);
SetVolume(GetVolume());
// restore previous governor
putFile(GOVERNOR_PATH, governor);
}
static void POW_waitForWake(void) {
SDL_Event event;
int wake = 0;
unsigned long sleep_ticks = SDL_GetTicks();
while (!wake) {
while (SDL_PollEvent(&event)) {
if (event.type==SDL_KEYUP) {
uint8_t code = event.key.keysym.scancode;
if (code==CODE_POWER) {
wake = 1;
break;
}
}
}
SDL_Delay(200);
if (can_poweroff && SDL_GetTicks()-sleep_ticks>=120000) { // increased to two minutes
if (POW_isCharging()) sleep_ticks += 60000; // check again in a minute
else POW_powerOff(); // TODO: not working...
}
}
return;
}
void POW_fauxSleep(void) {
GFX_clear(gfx.screen);
PAD_reset();
POW_enterSleep();
// TODO: pause keymon
POW_waitForWake();
// TODO: resume keymon
POW_exitSleep();
}
int POW_preventAutosleep(void) {
return POW_isCharging();
}
int POW_isCharging() {
return getInt("/sys/class/power_supply/battery/charger_online");
}

View file

@ -4,11 +4,7 @@
/////////////////////////////// ///////////////////////////////
// TODO: tmp // TODO: tmo
void powerOff(void);
void fauxSleep(void);
int preventAutosleep(void);
int isCharging();
#define PAD_justRepeated PAD_justPressed #define PAD_justRepeated PAD_justPressed
/////////////////////////////// ///////////////////////////////
@ -82,4 +78,12 @@ int PAD_justReleased(int btn);
/////////////////////////////// ///////////////////////////////
void POW_disablePowerOff(void);
void POW_powerOff(void);
void POW_fauxSleep(void);
int POW_preventAutosleep(void);
int POW_isCharging();
///////////////////////////////
#endif #endif

View file

@ -1239,6 +1239,7 @@ int main (int argc, char *argv[]) {
SDL_Surface* screen = GFX_init(); SDL_Surface* screen = GFX_init();
InitSettings(); InitSettings();
PAD_reset();
SDL_Surface* version = NULL; SDL_Surface* version = NULL;
@ -1249,7 +1250,7 @@ int main (int argc, char *argv[]) {
PAD_reset(); PAD_reset();
int dirty = 1; int dirty = 1;
int was_charging = isCharging(); int was_charging = POW_isCharging();
unsigned long charge_start = SDL_GetTicks(); unsigned long charge_start = SDL_GetTicks();
int show_version = 0; int show_version = 0;
int show_setting = 0; // 1=brightness,2=volume int show_setting = 0; // 1=brightness,2=volume
@ -1399,7 +1400,7 @@ int main (int argc, char *argv[]) {
#define CHARGE_DELAY 1000 #define CHARGE_DELAY 1000
if (dirty || now-charge_start>=CHARGE_DELAY) { if (dirty || now-charge_start>=CHARGE_DELAY) {
int is_charging = isCharging(); int is_charging = POW_isCharging();
if (was_charging!=is_charging) { if (was_charging!=is_charging) {
was_charging = is_charging; was_charging = is_charging;
dirty = 1; dirty = 1;
@ -1408,19 +1409,20 @@ int main (int argc, char *argv[]) {
} }
if (power_start && now-power_start>=1000) { if (power_start && now-power_start>=1000) {
powerOff(); POW_powerOff();
// return 0; // we should never reach this point quit = 1;
break;
} }
if (PAD_justPressed(BTN_SLEEP)) { if (PAD_justPressed(BTN_SLEEP)) {
power_start = now; power_start = now;
} }
#define SLEEP_DELAY 30000 #define SLEEP_DELAY 30000
if (now-cancel_start>=SLEEP_DELAY && preventAutosleep()) cancel_start = now; if (now-cancel_start>=SLEEP_DELAY && POW_preventAutosleep()) cancel_start = now;
if (now-cancel_start>=SLEEP_DELAY || PAD_justReleased(BTN_SLEEP)) // || PAD_justPressed(BTN_MENU)) if (now-cancel_start>=SLEEP_DELAY || PAD_justReleased(BTN_SLEEP)) // || PAD_justPressed(BTN_MENU))
{ {
fauxSleep(); POW_fauxSleep();
cancel_start = SDL_GetTicks(); cancel_start = SDL_GetTicks();
power_start = 0; power_start = 0;
dirty = 1; dirty = 1;
@ -1554,10 +1556,10 @@ int main (int argc, char *argv[]) {
GFX_flip(screen); GFX_flip(screen);
dirty = 0; dirty = 0;
} }
// slow down to 60fps // // slow down to 60fps
unsigned long frame_duration = SDL_GetTicks() - frame_start; // unsigned long frame_duration = SDL_GetTicks() - frame_start;
#define TARGET_FRAME_DURATION 17 // #define TARGET_FRAME_DURATION 17
if (frame_duration<TARGET_FRAME_DURATION) SDL_Delay(TARGET_FRAME_DURATION-frame_duration); // if (frame_duration<TARGET_FRAME_DURATION) SDL_Delay(TARGET_FRAME_DURATION-frame_duration);
} }
if (version) SDL_FreeSurface(version); if (version) SDL_FreeSurface(version);