1
0
mirror of https://github.com/cathery/sys-con.git synced 2024-10-06 06:19:43 +00:00

Implement PSC module for cleaning up resources before going to sleep

This commit is contained in:
cathery 2019-11-24 05:25:14 +03:00
parent 1f8a8bc500
commit e889c6e00c
2 changed files with 228 additions and 141 deletions

View File

@ -62,6 +62,10 @@ extern "C"
if (R_FAILED(rc)) if (R_FAILED(rc))
fatalThrow(rc); fatalThrow(rc);
rc = pscmInitialize();
if (R_FAILED(rc))
fatalThrow(rc);
#ifndef __APPLET__ #ifndef __APPLET__
rc = hidInitialize(); rc = hidInitialize();
if (R_FAILED(rc)) if (R_FAILED(rc))
@ -74,6 +78,7 @@ extern "C"
#ifndef __APPLET__ #ifndef __APPLET__
hidExit(); hidExit();
#endif #endif
pscmExit();
usbHsExit(); usbHsExit();
hiddbgReleaseHdlsWorkBuffer(); hiddbgReleaseHdlsWorkBuffer();
hiddbgExit(); hiddbgExit();

View File

@ -58,10 +58,6 @@ Result CreateDualshck3AvailableEvent(Event &out)
filter.idVendor = VENDOR_SONY; filter.idVendor = VENDOR_SONY;
filter.idProduct = PRODUCT_DUALSHOCK3; filter.idProduct = PRODUCT_DUALSHOCK3;
Result rc = usbHsCreateInterfaceAvailableEvent(&out, true, DS3EVENT_INDEX, &filter); Result rc = usbHsCreateInterfaceAvailableEvent(&out, true, DS3EVENT_INDEX, &filter);
if (R_FAILED(rc))
WriteToLog("Failed to open event for Dualshock 3");
else
WriteToLog("Successfully created event for Dualshock 3");
return rc; return rc;
} }
@ -72,10 +68,6 @@ Result CreateDualshock4AvailableEvent(Event &out)
filter.idVendor = VENDOR_SONY; filter.idVendor = VENDOR_SONY;
filter.idProduct = _globalConfig.dualshock4_productID; filter.idProduct = _globalConfig.dualshock4_productID;
Result rc = usbHsCreateInterfaceAvailableEvent(&out, true, DS4EVENT_INDEX, &filter); Result rc = usbHsCreateInterfaceAvailableEvent(&out, true, DS4EVENT_INDEX, &filter);
if (R_FAILED(rc))
WriteToLog("Failed to open event for Dualshock 4 0x", std::hex, _globalConfig.dualshock4_productID);
else
WriteToLog("Successfully created event for Dualshock 4 0x", std::hex, _globalConfig.dualshock4_productID);
return rc; return rc;
} }
@ -85,10 +77,6 @@ Result CreateAllAvailableEvent(Event &out)
filter.Flags = UsbHsInterfaceFilterFlags_bcdDevice_Min; filter.Flags = UsbHsInterfaceFilterFlags_bcdDevice_Min;
filter.bcdDevice_Min = 0; filter.bcdDevice_Min = 0;
Result rc = usbHsCreateInterfaceAvailableEvent(&out, true, ALLEVENT_INDEX, &filter); Result rc = usbHsCreateInterfaceAvailableEvent(&out, true, ALLEVENT_INDEX, &filter);
if (R_FAILED(rc))
WriteToLog("Failed to open catch-all event");
else
WriteToLog("Successfully created catch-all event");
return rc; return rc;
} }
@ -119,6 +107,75 @@ Result QueryVendorProduct(UsbHsInterface *interfaces, size_t interfaces_size, s3
return 1; return 1;
} }
Event catchAllEvent;
Event ds3Event;
Event ds4Event;
Result inline OpenEvents()
{
Result rc = CreateAllAvailableEvent(catchAllEvent);
if (R_FAILED(rc))
return 3;
rc = CreateDualshck3AvailableEvent(ds3Event);
if (R_FAILED(rc))
return 1;
rc = CreateDualshock4AvailableEvent(ds4Event);
if (R_FAILED(rc))
return 2;
return 0;
}
void inline CloseEvents()
{
usbHsDestroyInterfaceAvailableEvent(&ds3Event, DS3EVENT_INDEX);
usbHsDestroyInterfaceAvailableEvent(&ds4Event, DS4EVENT_INDEX);
usbHsDestroyInterfaceAvailableEvent(&catchAllEvent, ALLEVENT_INDEX);
}
struct PSCLoopBuffer
{
PscPmModule &pscModule;
bool &pscLoopRunning;
bool &shouldSleep;
};
void pscLoop(void *buffer)
{
Waiter pscModuleWaiter = waiterForEvent(&static_cast<PSCLoopBuffer *>(buffer)->pscModule.event);
PscPmState pscState;
u32 out_flags;
while (static_cast<PSCLoopBuffer *>(buffer)->pscLoopRunning)
{
Result rc = waitSingle(pscModuleWaiter, U64_MAX);
if (R_SUCCEEDED(rc))
{
rc = pscPmModuleGetRequest(&static_cast<PSCLoopBuffer *>(buffer)->pscModule, &pscState, &out_flags);
if (R_SUCCEEDED(rc))
{
switch (pscState)
{
case PscPmState_ReadyAwaken:
OpenEvents();
static_cast<PSCLoopBuffer *>(buffer)->shouldSleep = false;
break;
case PscPmState_ReadySleep:
case PscPmState_ReadyShutdown:
CloseEvents();
static_cast<PSCLoopBuffer *>(buffer)->shouldSleep = true;
//controllerInterfaces.clear();
break;
default:
break;
}
pscPmModuleAcknowledge(&static_cast<PSCLoopBuffer *>(buffer)->pscModule, pscState);
}
}
}
};
Result mainLoop() Result mainLoop()
{ {
WriteToLog("\n\nNew sysmodule session started on version " APP_VERSION); WriteToLog("\n\nNew sysmodule session started on version " APP_VERSION);
@ -131,21 +188,36 @@ Result mainLoop()
utimerCreate(&filecheckTimer, 1e+9L, TimerType_Repeating); utimerCreate(&filecheckTimer, 1e+9L, TimerType_Repeating);
utimerStart(&filecheckTimer); utimerStart(&filecheckTimer);
PscPmModule pscModule;
const uint16_t dependencies[] = {PscPmModuleId_Usb};
rc = pscmGetPmModule(&pscModule, static_cast<PscPmModuleId>(126), dependencies, sizeof(dependencies) / sizeof(uint16_t), true);
WriteToLog("Get module result: 0x", std::hex, rc);
//Waiter pscModuleWaiter = waiterForEvent(&pscModule.event);
bool pscLoopRunning = true;
bool shouldSleep = false;
Thread pscThread;
PSCLoopBuffer loopBuffer{pscModule, pscLoopRunning, shouldSleep};
threadCreate(&pscThread, pscLoop, &loopBuffer, NULL, 0x2000, 0x3B, -2);
rc = threadStart(&pscThread);
WriteToLog("PSC thread start: 0x", std::hex, rc);
CheckForFileChanges(); CheckForFileChanges();
LoadAllConfigs(); LoadAllConfigs();
Event catchAllEvent; rc = OpenEvents();
Event ds3Event; if (R_FAILED(rc))
Event ds4Event; WriteToLog("Failed to open events: ", rc);
CreateDualshck3AvailableEvent(ds3Event);
CreateAllAvailableEvent(catchAllEvent);
CreateDualshock4AvailableEvent(ds4Event);
controllerInterfaces.reserve(10); controllerInterfaces.reserve(10);
while (appletMainLoop()) while (appletMainLoop())
{ {
if (!shouldSleep)
{
#ifdef __APPLET__ #ifdef __APPLET__
hidScanInput(); hidScanInput();
@ -298,7 +370,12 @@ Result mainLoop()
CreateDualshock4AvailableEvent(ds4Event); CreateDualshock4AvailableEvent(ds4Event);
} }
} }
}
else if (controllerInterfaces.size() != 0)
{
WriteToLog("Clearing interfaces before going to sleep");
controllerInterfaces.clear();
}
#ifdef __APPLET__ #ifdef __APPLET__
consoleUpdate(nullptr); consoleUpdate(nullptr);
#else #else
@ -308,9 +385,14 @@ Result mainLoop()
//After we break out of the loop, close all events and exit //After we break out of the loop, close all events and exit
WriteToLog("Destroying events"); WriteToLog("Destroying events");
usbHsDestroyInterfaceAvailableEvent(&ds3Event, DS3EVENT_INDEX); CloseEvents();
usbHsDestroyInterfaceAvailableEvent(&ds4Event, DS4EVENT_INDEX);
usbHsDestroyInterfaceAvailableEvent(&catchAllEvent, ALLEVENT_INDEX); pscPmModuleFinalize(&pscModule);
pscPmModuleClose(&pscModule);
pscLoopRunning = false;
threadWaitForExit(&pscThread);
threadClose(&pscThread);
controllerInterfaces.clear(); controllerInterfaces.clear();
return rc; return rc;