From b68134504b36a8a4999e105c286517bd599d09c9 Mon Sep 17 00:00:00 2001 From: cathery Date: Mon, 2 Mar 2020 18:18:12 +0300 Subject: [PATCH] Implement PSC module --- source/Sysmodule/source/main.cpp | 3 ++ source/Sysmodule/source/psc_module.cpp | 71 ++++++++++++++++++++++++++ source/Sysmodule/source/psc_module.h | 8 +++ source/Sysmodule/source/usb_module.cpp | 25 ++++++--- source/Sysmodule/source/usb_module.h | 3 ++ 5 files changed, 102 insertions(+), 8 deletions(-) create mode 100644 source/Sysmodule/source/psc_module.cpp create mode 100644 source/Sysmodule/source/psc_module.h diff --git a/source/Sysmodule/source/main.cpp b/source/Sysmodule/source/main.cpp index 6e1ad98..e5c6505 100644 --- a/source/Sysmodule/source/main.cpp +++ b/source/Sysmodule/source/main.cpp @@ -5,6 +5,7 @@ #include "usb_module.h" #include "controller_handler.h" #include "config_handler.h" +#include "psc_module.h" #define APP_VERSION "0.6.0" @@ -80,12 +81,14 @@ int main(int argc, char *argv[]) config::Initialize(); handler::Initialize(); usb::Initialize(); + psc::Initialize(); while (true) { svcSleepThread(1e+8L); } + psc::Exit(); usb::Exit(); handler::Exit(); config::Exit(); diff --git a/source/Sysmodule/source/psc_module.cpp b/source/Sysmodule/source/psc_module.cpp new file mode 100644 index 0000000..0bda58a --- /dev/null +++ b/source/Sysmodule/source/psc_module.cpp @@ -0,0 +1,71 @@ +#include "psc_module.h" +#include +#include "usb_module.h" +#include "config_handler.h" +#include "controller_handler.h" +#include "log.h" + +namespace syscon::psc +{ + namespace + { + PscPmModule pscModule; + Waiter pscModuleWaiter; + const uint16_t dependencies[] = {PscPmModuleId_Usb}; + + void PscThreadFunc(void *arg); + + ams::os::StaticThread<0x2'000> g_psc_thread(&PscThreadFunc, nullptr, 0x2C); + + bool is_psc_thread_running = false; + + void PscThreadFunc(void *arg) + { + WriteToLog("Starting PSC thread!"); + do { + if (R_SUCCEEDED(waitSingle(pscModuleWaiter, U64_MAX))) + { + PscPmState pscState; + u32 out_flags; + if (R_SUCCEEDED(pscPmModuleGetRequest(&pscModule, &pscState, &out_flags))) + { + switch (pscState) + { + case PscPmState_ReadyAwaken: + WriteToLog("Switch is awake! Enabling usb events..."); + usb::CreateUsbEvents(); + break; + case PscPmState_ReadySleep: + case PscPmState_ReadyShutdown: + WriteToLog("Ready to sleep! Disabling usb events..."); + usb::DestroyUsbEvents(); + break; + default: + break; + } + pscPmModuleAcknowledge(&pscModule, pscState); + } + } + } while (is_psc_thread_running); + } + } + Result Initialize() + { + R_TRY(pscmGetPmModule(&pscModule, static_cast(126), dependencies, sizeof(dependencies) / sizeof(uint16_t), true)); + pscModuleWaiter = waiterForEvent(&pscModule.event); + is_psc_thread_running = true; + return g_psc_thread.Start().GetValue(); + } + + void Exit() + { + is_psc_thread_running = false; + + pscPmModuleFinalize(&pscModule); + pscPmModuleClose(&pscModule); + eventClose(&pscModule.event); + + g_psc_thread.CancelSynchronization(); + g_psc_thread.Join(); + } +}; \ No newline at end of file diff --git a/source/Sysmodule/source/psc_module.h b/source/Sysmodule/source/psc_module.h new file mode 100644 index 0000000..851133c --- /dev/null +++ b/source/Sysmodule/source/psc_module.h @@ -0,0 +1,8 @@ +#pragma once +#include "switch.h" + +namespace syscon::psc +{ + Result Initialize(); + void Exit(); +}; \ No newline at end of file diff --git a/source/Sysmodule/source/usb_module.cpp b/source/Sysmodule/source/usb_module.cpp index c2c5c5e..533d2a9 100644 --- a/source/Sysmodule/source/usb_module.cpp +++ b/source/Sysmodule/source/usb_module.cpp @@ -180,24 +180,18 @@ namespace syscon::usb Result Enable() { - R_TRY(CreateCatchAllAvailableEvent()); - R_TRY(CreateDualshock3AvailableEvent()); - R_TRY(CreateDualshock4AvailableEvent()); + CreateUsbEvents(); is_usb_event_thread_running = true; R_TRY(g_usb_event_thread.Start().GetValue()); - is_usb_interface_change_thread_running = true; R_TRY(g_usb_interface_change_thread.Start().GetValue()); - return 0; } void Disable() { - usbHsDestroyInterfaceAvailableEvent(&g_usbCatchAllEvent, CatchAllEventIndex); - usbHsDestroyInterfaceAvailableEvent(&g_usbDualshock3Event, Dualshock3EventIndex); - usbHsDestroyInterfaceAvailableEvent(&g_usbDualshock4Event, Dualshock4EventIndex); + DestroyUsbEvents(); is_usb_event_thread_running = false; is_usb_interface_change_thread_running = false; @@ -212,6 +206,21 @@ namespace syscon::usb handler::Reset(); } + Result CreateUsbEvents() + { + R_TRY(CreateCatchAllAvailableEvent()); + R_TRY(CreateDualshock3AvailableEvent()); + R_TRY(CreateDualshock4AvailableEvent()); + return 0; + } + + void DestroyUsbEvents() + { + usbHsDestroyInterfaceAvailableEvent(&g_usbCatchAllEvent, CatchAllEventIndex); + usbHsDestroyInterfaceAvailableEvent(&g_usbDualshock3Event, Dualshock3EventIndex); + usbHsDestroyInterfaceAvailableEvent(&g_usbDualshock4Event, Dualshock4EventIndex); + } + Result ReloadDualshock4Event() { usbHsDestroyInterfaceAvailableEvent(&g_usbDualshock4Event, Dualshock4EventIndex); diff --git a/source/Sysmodule/source/usb_module.h b/source/Sysmodule/source/usb_module.h index e85b9cd..1e7f9b8 100644 --- a/source/Sysmodule/source/usb_module.h +++ b/source/Sysmodule/source/usb_module.h @@ -9,5 +9,8 @@ namespace syscon::usb { Result Enable(); void Disable(); + Result CreateUsbEvents(); + void DestroyUsbEvents(); + Result ReloadDualshock4Event(); } \ No newline at end of file