Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions workspace/all/common/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ static struct PWR_Context

pthread_t battery_pt;
SDL_atomic_t is_charging;
SDL_atomic_t is_usb_connected;
SDL_atomic_t charge;

SDL_atomic_t is_online;
Expand Down Expand Up @@ -3967,6 +3968,7 @@ static void PWR_updateBatteryStatus(void)
PLAT_getBatteryStatusFine(&is_charging, &charge);
SDL_AtomicSet(&pwr.is_charging, is_charging);
SDL_AtomicSet(&pwr.charge, charge);
SDL_AtomicSet(&pwr.is_usb_connected, PLAT_isUSBConnected());

// this is technically redundant, but PWR_update() might not always be called to conserve battery and cycles
LEDS_applyRules();
Expand Down Expand Up @@ -4315,7 +4317,8 @@ static void PWR_waitForWake(void)
SDL_Delay(200);
if (SDL_GetTicks() - sleep_ticks >= sleepDelay)
{ // increased to two minutes
if (SDL_AtomicGet(&pwr.is_charging))
if (SDL_AtomicGet(&pwr.is_charging) ||
(CFG_getKeepAwakeWhenUSB() && SDL_AtomicGet(&pwr.is_usb_connected)))
{
sleep_ticks += 60000; // check again in a minute
continue;
Expand Down Expand Up @@ -4396,14 +4399,19 @@ void PWR_enableAutosleep(void)
}
int PWR_preventAutosleep(void)
{
return SDL_AtomicGet(&pwr.is_charging) || !pwr.can_autosleep || GetHDMI();
return SDL_AtomicGet(&pwr.is_charging) || !pwr.can_autosleep || GetHDMI() ||
(CFG_getKeepAwakeWhenUSB() && SDL_AtomicGet(&pwr.is_usb_connected));
}

// updated by PWR_updateBatteryStatus()
int PWR_isCharging(void)
{
return SDL_AtomicGet(&pwr.is_charging);
}
int PWR_isUSBConnected(void)
{
return SDL_AtomicGet(&pwr.is_usb_connected);
}
int PWR_getBattery(void)
{ // 10-100 in 10-20% fragments
return SDL_AtomicGet(&pwr.charge);
Expand Down
2 changes: 2 additions & 0 deletions workspace/all/common/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,7 @@ void PWR_enableAutosleep(void);
int PWR_preventAutosleep(void);

int PWR_isCharging(void);
int PWR_isUSBConnected(void);
int PWR_getBattery(void);

int PWR_isOnline(void);
Expand Down Expand Up @@ -732,6 +733,7 @@ int PLAT_supportsOverscan(void);
#define PWR_LOW_CHARGE 10
void PLAT_getBatteryStatus(int* is_charging, int* charge); // 0,1 and 0,10,20,40,60,80,100
void PLAT_getBatteryStatusFine(int* is_charging, int* charge); // 0,1 and 0-100
int PLAT_isUSBConnected(void); // 1 if the device is configured as a USB gadget on a host, else 0
void PLAT_enableBacklight(int enable);
int PLAT_supportsDeepSleep(void);
int PLAT_deepSleep(void);
Expand Down
23 changes: 23 additions & 0 deletions workspace/all/common/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ void CFG_defaults(NextUISettings *cfg)
.screenTimeoutSecs = CFG_DEFAULT_SCREENTIMEOUTSECS,
.suspendTimeoutSecs = CFG_DEFAULT_SUSPENDTIMEOUTSECS,
.powerOffProtection = CFG_DEFAULT_POWEROFFPROTECTION,
.keepAwakeWhenUSB = CFG_DEFAULT_KEEPAWAKEWHENUSB,

.haptics = CFG_DEFAULT_HAPTICS,
.romsUseFolderBackground = CFG_DEFAULT_ROMSUSEFOLDERBACKGROUND,
Expand Down Expand Up @@ -302,6 +303,11 @@ void CFG_init(FontLoad_callback_t cb, ColorSet_callback_t ccb)
CFG_setPowerOffProtection((bool)temp_value);
continue;
}
if (sscanf(line, "keepAwakeWhenUSB=%i", &temp_value) == 1)
{
CFG_setKeepAwakeWhenUSB((bool)temp_value);
continue;
}
if (sscanf(line, "switcherscale=%i", &temp_value) == 1)
{
CFG_setGameSwitcherScaling(temp_value);
Expand Down Expand Up @@ -703,6 +709,17 @@ void CFG_setPowerOffProtection(bool enable)
CFG_sync();
}

bool CFG_getKeepAwakeWhenUSB(void)
{
return settings.keepAwakeWhenUSB;
}

void CFG_setKeepAwakeWhenUSB(bool enable)
{
settings.keepAwakeWhenUSB = enable;
CFG_sync();
}

bool CFG_getShowClock(void)
{
return settings.showClock;
Expand Down Expand Up @@ -1355,6 +1372,10 @@ void CFG_get(const char *key, char *value)
{
sprintf(value, "%i", CFG_getPowerOffProtection());
}
else if (strcmp(key, "keepAwakeWhenUSB") == 0)
{
sprintf(value, "%i", CFG_getKeepAwakeWhenUSB());
}
else if (strcmp(key, "switcherscale") == 0)
{
sprintf(value, "%i", CFG_getGameSwitcherScaling());
Expand Down Expand Up @@ -1552,6 +1573,7 @@ void CFG_sync(void)
fprintf(file, "screentimeout=%i\n", settings.screenTimeoutSecs);
fprintf(file, "suspendTimeout=%i\n", settings.suspendTimeoutSecs);
fprintf(file, "powerOffProtection=%i\n", settings.powerOffProtection);
fprintf(file, "keepAwakeWhenUSB=%i\n", settings.keepAwakeWhenUSB);
fprintf(file, "switcherscale=%i\n", settings.gameSwitcherScaling);
fprintf(file, "haptics=%i\n", settings.haptics);
fprintf(file, "romfolderbg=%i\n", settings.romsUseFolderBackground);
Expand Down Expand Up @@ -1622,6 +1644,7 @@ void CFG_print(void)
printf("\t\"screentimeout\": %i,\n", settings.screenTimeoutSecs);
printf("\t\"suspendTimeout\": %i,\n", settings.suspendTimeoutSecs);
printf("\t\"powerOffProtection\": %i,\n", settings.powerOffProtection);
printf("\t\"keepAwakeWhenUSB\": %i,\n", settings.keepAwakeWhenUSB);
printf("\t\"switcherscale\": %i,\n", settings.gameSwitcherScaling);
printf("\t\"haptics\": %i,\n", settings.haptics);
printf("\t\"romfolderbg\": %i,\n", settings.romsUseFolderBackground);
Expand Down
5 changes: 5 additions & 0 deletions workspace/all/common/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ typedef struct
uint32_t screenTimeoutSecs;
uint32_t suspendTimeoutSecs;
bool powerOffProtection;
bool keepAwakeWhenUSB;

// Emulator
int saveFormat;
Expand Down Expand Up @@ -215,6 +216,7 @@ typedef struct
#define CFG_DEFAULT_SCREENTIMEOUTSECS 60
#define CFG_DEFAULT_SUSPENDTIMEOUTSECS 30
#define CFG_DEFAULT_POWEROFFPROTECTION true
#define CFG_DEFAULT_KEEPAWAKEWHENUSB false
#define CFG_DEFAULT_HAPTICS false
#define CFG_DEFAULT_ROMSUSEFOLDERBACKGROUND true
#define CFG_DEFAULT_SAVEFORMAT SAVE_FORMAT_SAV
Expand Down Expand Up @@ -310,6 +312,9 @@ void CFG_setSuspendTimeoutSecs(uint32_t secs);
// Enable/disable PMIC power-off protection mode.
bool CFG_getPowerOffProtection(void);
void CFG_setPowerOffProtection(bool enable);
// Keep the device awake while it is connected to a host as a USB device.
bool CFG_getKeepAwakeWhenUSB(void);
void CFG_setKeepAwakeWhenUSB(bool enable);
// Show/hide clock in the status pill.
bool CFG_getShowClock(void);
void CFG_setShowClock(bool show);
Expand Down
7 changes: 7 additions & 0 deletions workspace/all/settings/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,13 @@ int main(int argc, char *argv[])
[](const std::any &value) { CFG_setPowerOffProtection(std::any_cast<bool>(value)); },
[]() { CFG_setPowerOffProtection(CFG_DEFAULT_POWEROFFPROTECTION); }}
);

systemItems.push_back(
new MenuItem{ListItemType::Generic, "Keep awake over USB", "Prevent screen-off and sleep while connected to a\ncomputer as a USB device (not just charging).", {false, true}, on_off,
[]() -> std::any { return CFG_getKeepAwakeWhenUSB(); },
[](const std::any &value) { CFG_setKeepAwakeWhenUSB(std::any_cast<bool>(value)); },
[]() { CFG_setKeepAwakeWhenUSB(CFG_DEFAULT_KEEPAWAKEWHENUSB); }}
);
}

if(deviceInfo.hasActiveCooling())
Expand Down
5 changes: 5 additions & 0 deletions workspace/desktop/platform/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ void PLAT_getBatteryStatusFine(int* is_charging, int* charge)
*charge = 100;
}

int PLAT_isUSBConnected(void)
{
return 0;
}

void PLAT_enableBacklight(int enable) {
// buh
}
Expand Down
33 changes: 33 additions & 0 deletions workspace/tg5040/platform/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,39 @@ void PLAT_getBatteryStatusFine(int *is_charging, int *charge)
}
}

int PLAT_isUSBConnected(void)
{
// The UDC (USB Device Controller) reports "configured" once a host has
// enumerated us as a USB gadget. This is independent of merely being
// plugged into a charger, so it lets us tell "connected to a computer"
// apart from "connected to power".
DIR *dir = opendir("/sys/class/udc");
if (!dir)
return 0;

int connected = 0;
struct dirent *entry;
while ((entry = readdir(dir)) != NULL)
{
if (entry->d_name[0] == '.')
continue;

char path[512];
snprintf(path, sizeof(path), "/sys/class/udc/%s/state", entry->d_name);

char state[32] = {0};
getFile(path, state, sizeof(state));
if (strncmp(state, "configured", 10) == 0)
{
connected = 1;
break;
}
}

closedir(dir);
return connected;
}

void PLAT_enableBacklight(int enable) {
if (enable) {
if (is_brick || is_brickpro) SetRawBrightness(8);
Expand Down
6 changes: 6 additions & 0 deletions workspace/tg5050/platform/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,12 @@ void PLAT_getBatteryStatusFine(int *is_charging, int *charge)
}
}

int PLAT_isUSBConnected(void)
{
// Not implemented for this platform yet.
return 0;
}

void PLAT_enableBacklight(int enable) {
if (enable) {
SetBrightness(GetBrightness());
Expand Down
Loading