diff --git a/Source/sys-clk/common/include/sysclk/board.h b/Source/sys-clk/common/include/sysclk/board.h index 274bee8c..ac91de4f 100644 --- a/Source/sys-clk/common/include/sysclk/board.h +++ b/Source/sys-clk/common/include/sysclk/board.h @@ -57,6 +57,7 @@ typedef enum { HocClkVoltage_GPU, HocClkVoltage_EMCVDDQ_MarikoOnly, HocClkVoltage_Display, + HocClkVoltage_Battery, HocClkVoltage_EnumMax, } HocClkVoltage; @@ -83,6 +84,8 @@ typedef enum SysClkThermalSensor_SOC = 0, SysClkThermalSensor_PCB, SysClkThermalSensor_Skin, + HorizonOCThermalSensor_Battery, + HorizonOCThermalSensor_PMIC, SysClkThermalSensor_EnumMax } SysClkThermalSensor; @@ -99,6 +102,7 @@ typedef enum SysClkPartLoad_EMCCpu, HocClkPartLoad_GPU, HocClkPartLoad_CPUAvg, + HocClkPartLoad_BAT, SysClkPartLoad_EnumMax } SysClkPartLoad; diff --git a/Source/sys-clk/overlay/src/ui/gui/base_menu_gui.cpp b/Source/sys-clk/overlay/src/ui/gui/base_menu_gui.cpp index 5fd0b421..a9695853 100644 --- a/Source/sys-clk/overlay/src/ui/gui/base_menu_gui.cpp +++ b/Source/sys-clk/overlay/src/ui/gui/base_menu_gui.cpp @@ -30,7 +30,7 @@ // Cache hardware model to avoid repeated syscalls -BaseMenuGui::BaseMenuGui() : tempColors{tsl::Color(0), tsl::Color(0), tsl::Color(0)} +BaseMenuGui::BaseMenuGui() : tempColors{ tsl::Color(0), tsl::Color(0), tsl::Color(0), tsl::Color(0), tsl::Color(0), tsl::Color(0), tsl::Color(0), } { tsl::initializeThemeVars(); this->context = nullptr; @@ -55,8 +55,8 @@ void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) { if(!this->context) [[unlikely]] return; // All constants pre-calculated and cached - static constexpr const char* const labels[11] = { - "App ID", "Profile", "CPU", "GPU", "MEM", "SoC", "Board", "Skin", "Now", "Avg", "Fan" + static constexpr const char* const labels[] = { + "App ID", "Profile", "CPU", "GPU", "MEM", "SoC", "Board", "Skin", "Now", "Avg", "BAT", "PMIC" }; static constexpr u32 dataPositions[6] = {63-3+3, 200-1, 344-1-3, 200-1, 342-1, 321-1}; @@ -77,7 +77,7 @@ void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) { u32 y = 91; // === TOP SECTION === - renderer->drawRoundedRect(14, 70-1, 420, 30+2, 10.0f, renderer->aWithOpacity(tsl::tableBGColor)); + renderer->drawRoundedRect(14, 70-1, 420, 30+2, 15.0f, renderer->aWithOpacity(tsl::tableBGColor)); // App ID - use pre-formatted string renderer->drawString(labels[0], false, positions[0], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); @@ -90,7 +90,7 @@ void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) { y = 129; // Direct assignment instead of += 38 // === MAIN DATA SECTION === - renderer->drawRoundedRect(14, 106, 420, 116, 10.0f, renderer->aWithOpacity(tsl::tableBGColor)); + renderer->drawRoundedRect(14, 106, 420, 156, 10.0f, renderer->aWithOpacity(tsl::tableBGColor)); // === FREQUENCY SECTION === // Labels first (better cache locality) @@ -105,6 +105,7 @@ void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) { y = 149; // Direct assignment (129 + 20) + // renderer->drawString(displayStrings[19], false, positions[2], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // CPU Usage renderer->drawString(displayStrings[17], false, positions[3], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // GPU Usage renderer->drawString(displayStrings[18], false, positions[4], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // RAM Usage @@ -130,9 +131,9 @@ void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) { renderer->drawString(labels[7], false, positions[7], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); // Temperatures with color - use pre-computed colors - renderer->drawString(displayStrings[11], false, dataPositions[0], y, SMALL_TEXT_SIZE, tempColors[0]); // SOC - renderer->drawString(displayStrings[12], false, dataPositions[1], y, SMALL_TEXT_SIZE, tempColors[1]); // PCB - renderer->drawString(displayStrings[13], false, dataPositions[2], y, SMALL_TEXT_SIZE, tempColors[2]); // Skin + renderer->drawString(displayStrings[11], false, dataPositions[0], y, SMALL_TEXT_SIZE, tempColors[SysClkThermalSensor_SOC]); // SOC + renderer->drawString(displayStrings[12], false, dataPositions[1], y, SMALL_TEXT_SIZE, tempColors[SysClkThermalSensor_PCB]); // PCB + renderer->drawString(displayStrings[13], false, dataPositions[2], y, SMALL_TEXT_SIZE, tempColors[SysClkThermalSensor_Skin]); // Skin y = 211; // Direct assignment (191 + 20) @@ -148,8 +149,15 @@ void BaseMenuGui::preDraw(tsl::gfx::Renderer* renderer) { y+=20; renderer->drawString(labels[10], false, positions[5], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); + renderer->drawString(labels[11], false, positions[6], y, SMALL_TEXT_SIZE, tsl::sectionTextColor); - renderer->drawString(displayStrings[19], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // Power now + renderer->drawString(displayStrings[20], false, dataPositions[0], y, SMALL_TEXT_SIZE, tempColors[HorizonOCThermalSensor_Battery]); // Battery + renderer->drawString(displayStrings[22], false, dataPositions[1], y, SMALL_TEXT_SIZE, tempColors[HorizonOCThermalSensor_PMIC]); // PMIC + + y+=20; + + renderer->drawString(displayStrings[21], false, dataPositions[0], y, SMALL_TEXT_SIZE, tsl::infoTextColor); // Bat voltage + renderer->drawString(displayStrings[23], false, positions[2] - 2, y, SMALL_TEXT_SIZE, tsl::infoTextColor); // Bat Age } @@ -218,17 +226,17 @@ void BaseMenuGui::refresh() } // Temperatures and pre-compute colors - u32 millis = context->temps[0]; // SOC + u32 millis = context->temps[SysClkThermalSensor_SOC]; // SOC sprintf(displayStrings[11], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U); - tempColors[0] = tsl::GradientColor(millis * 0.001f); + tempColors[SysClkThermalSensor_SOC] = tsl::GradientColor(millis * 0.001f); - millis = context->temps[1]; // PCB + millis = context->temps[SysClkThermalSensor_PCB]; // PCB sprintf(displayStrings[12], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U); - tempColors[1] = tsl::GradientColor(millis * 0.001f); + tempColors[SysClkThermalSensor_PCB] = tsl::GradientColor(millis * 0.001f); - millis = context->temps[2]; // Skin + millis = context->temps[SysClkThermalSensor_Skin]; // Skin sprintf(displayStrings[13], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U); - tempColors[2] = tsl::GradientColor(millis * 0.001f); + tempColors[SysClkThermalSensor_Skin] = tsl::GradientColor(millis * 0.001f); // SOC voltage (if available) sprintf(displayStrings[14], "%u mV", context->voltages[HocClkVoltage_SOC] / 1000U); @@ -240,13 +248,26 @@ void BaseMenuGui::refresh() sprintf(displayStrings[17], "%u%%", context->PartLoad[HocClkPartLoad_GPU] / 10); sprintf(displayStrings[18], "%u%%", context->PartLoad[SysClkPartLoad_EMC] / 10); - sprintf(displayStrings[19], "%hhu%%", context->fanLevel); + // sprintf(displayStrings[19], "%u", context->PartLoad[HocClkPartLoad_CPUAvg]); + + millis = context->temps[HorizonOCThermalSensor_Battery]; // Battery + sprintf(displayStrings[20], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U); + tempColors[HorizonOCThermalSensor_Battery] = tsl::GradientColor(millis * 0.001f); + + sprintf(displayStrings[21], "%d mV", context->voltages[HocClkVoltage_Battery]); // BAT AVG + + millis = context->temps[HorizonOCThermalSensor_PMIC]; // Battery + sprintf(displayStrings[22], "%u.%u °C", millis / 1000U, (millis % 1000U) / 100U); + tempColors[HorizonOCThermalSensor_PMIC] = tsl::GradientColor(millis * 0.001f); + + sprintf(displayStrings[23], "%u%%", context->PartLoad[HocClkPartLoad_BAT] / 1000); } tsl::elm::Element* BaseMenuGui::baseUI() { auto* list = new tsl::elm::List(); + list->addItem(new tsl::elm::CustomDrawer([](tsl::gfx::Renderer*, s32, s32, s32, s32) {}), 55); this->listElement = list; this->listUI(); diff --git a/Source/sys-clk/overlay/src/ui/gui/base_menu_gui.h b/Source/sys-clk/overlay/src/ui/gui/base_menu_gui.h index 225445d2..cb84bdf4 100644 --- a/Source/sys-clk/overlay/src/ui/gui/base_menu_gui.h +++ b/Source/sys-clk/overlay/src/ui/gui/base_menu_gui.h @@ -67,5 +67,5 @@ class BaseMenuGui : public BaseGui private: char displayStrings[32][32]; // Pre-formatted display strings - tsl::Color tempColors[3]; // Pre-computed temperature colors + tsl::Color tempColors[7]; // Pre-computed temperature colors }; diff --git a/Source/sys-clk/sysmodule/src/batLib.h b/Source/sys-clk/sysmodule/src/batLib.h new file mode 100644 index 00000000..0abe01a2 --- /dev/null +++ b/Source/sys-clk/sysmodule/src/batLib.h @@ -0,0 +1,260 @@ +/* + * Battery Info Driver for Nintendo Switch + * Single-header library for accessing battery information + * + * Usage: + * #define BATTERY_INFO_IMPLEMENTATION + * #include "battery_info.h" + */ + +#pragma once +#include +#include +#include +// Battery charging flags +typedef enum { + BatteryFlag_NoHub = BIT(0), // Hub is disconnected + BatteryFlag_Rail = BIT(8), // At least one Joy-con is charging from rail + BatteryFlag_SPDSRC = BIT(12), // OTG + BatteryFlag_ACC = BIT(16) // Accessory +} BatteryChargeFlags; + +// Power Delivery Controller State (BM92T series) +typedef enum { + PDState_NewPDO = 1, // Received new Power Data Object + PDState_NoPD = 2, // No Power Delivery source is detected + PDState_AcceptedRDO = 3 // Received and accepted Request Data Object +} BatteryPDControllerState; + +// Charger type detection +typedef enum { + ChargerType_None = 0, + ChargerType_PD = 1, + ChargerType_TypeC_1500mA = 2, + ChargerType_TypeC_3000mA = 3, + ChargerType_DCP = 4, // Dedicated Charging Port + ChargerType_CDP = 5, // Charging Downstream Port + ChargerType_SDP = 6, // Standard Downstream Port + ChargerType_Apple_500mA = 7, + ChargerType_Apple_1000mA = 8, + ChargerType_Apple_2000mA = 9 +} BatteryChargerType; + +// Power role (USB Power Delivery) +typedef enum { + PowerRole_Sink = 1, // Device is receiving power + PowerRole_Source = 2 // Device is providing power +} BatteryPowerRole; + +// Complete battery charge information structure +typedef struct { + int32_t InputCurrentLimit; // Input (Sink) current limit in mA + int32_t VBUSCurrentLimit; // Output (Source/VBUS/OTG) current limit in mA + int32_t ChargeCurrentLimit; // Battery charging current limit in mA + int32_t ChargeVoltageLimit; // Battery charging voltage limit in mV + int32_t unk_x10; // Unknown field (possibly enum) + int32_t unk_x14; // Unknown field (possibly flags) + BatteryPDControllerState PDControllerState; // PD Controller State + int32_t BatteryTemperature; // Battery temperature in milli-Celsius + int32_t RawBatteryCharge; // Battery charge in per cent-mille (100% = 100000) + int32_t VoltageAvg; // Average voltage in mV + int32_t BatteryAge; // Battery health (capacity full/design) in pcm + BatteryPowerRole PowerRole; // Current power role + BatteryChargerType ChargerType; // Type of charger connected + int32_t ChargerVoltageLimit; // Charger voltage limit in mV + int32_t ChargerCurrentLimit; // Charger current limit in mA + BatteryChargeFlags Flags; // Various status flags +} BatteryChargeInfo; + +// Helper macro to check if battery charging is enabled +#define IS_BATTERY_CHARGING_ENABLED(info) (((info)->unk_x14 >> 8) & 1) + +// Initialize the battery info driver +Result batteryInfoInitialize(void); + +// Cleanup the battery info driver +void batteryInfoExit(void); + +// Get complete battery charge information +Result batteryInfoGetChargeInfo(BatteryChargeInfo *out); + +// Get battery charge percentage (0-100) +Result batteryInfoGetChargePercentage(u32 *out); + +// Check if enough power is being supplied +Result batteryInfoIsEnoughPowerSupplied(bool *out); + +// Battery charge control functions +Result batteryInfoEnableCharging(void); +Result batteryInfoDisableCharging(void); +Result batteryInfoEnableFastCharging(void); +Result batteryInfoDisableFastCharging(void); + +// Helper functions to get human-readable strings +const char* batteryInfoGetChargerTypeString(BatteryChargerType type); +const char* batteryInfoGetPowerRoleString(BatteryPowerRole role); +const char* batteryInfoGetPDStateString(BatteryPDControllerState state); + +// Convenience functions for common values +static inline int batteryInfoGetTemperatureMiliCelsius(BatteryChargeInfo *info) { + return info->BatteryTemperature; +} + +static inline float batteryInfoGetChargePercent(BatteryChargeInfo *info) { + return (float)info->RawBatteryCharge / 1000.0f; +} + +static inline float batteryInfoGetBatteryHealthPercent(BatteryChargeInfo *info) { + return (float)info->BatteryAge / 1000.0f; +} + +static inline bool batteryInfoIsCharging(BatteryChargeInfo *info) { + return IS_BATTERY_CHARGING_ENABLED(info); +} + +// String lookup tables +static const char* s_chargerTypeStrings[] = { + "None", + "Power Delivery", + "USB-C @ 1.5A", + "USB-C @ 3.0A", + "USB-DCP", + "USB-CDP", + "USB-SDP", + "Apple @ 0.5A", + "Apple @ 1.0A", + "Apple @ 2.0A", +}; + +static const char* s_powerRoleStrings[] = { + "Unknown", + "Sink", + "Source", +}; + +static const char* s_pdStateStrings[] = { + "Unknown", + "New PDO Received", + "No PD Source", + "RDO Accepted" +}; + +// Internal PSM service handle +static Service g_psmService = {0}; +static bool g_batteryInfoInitialized = false; + +// Internal PSM command implementations +static Result psmGetBatteryChargeInfoFields(BatteryChargeInfo *out) { + if (!g_batteryInfoInitialized) + return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + + return serviceDispatchOut(&g_psmService, 17, *out); +} + +static Result psmEnableBatteryCharging_internal(void) { + if (!g_batteryInfoInitialized) + return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + + return serviceDispatch(&g_psmService, 2); +} + +static Result psmDisableBatteryCharging_internal(void) { + if (!g_batteryInfoInitialized) + return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + + return serviceDispatch(&g_psmService, 3); +} + +static Result psmEnableFastBatteryCharging_internal(void) { + if (!g_batteryInfoInitialized) + return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + + return serviceDispatch(&g_psmService, 10); +} + +static Result psmDisableFastBatteryCharging_internal(void) { + if (!g_batteryInfoInitialized) + return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + + return serviceDispatch(&g_psmService, 11); +} + +// Public API implementations +Result batteryInfoInitialize(void) { + if (g_batteryInfoInitialized) + return 0; + + Result rc = psmInitialize(); + if (R_SUCCEEDED(rc)) { + memcpy(&g_psmService, psmGetServiceSession(), sizeof(Service)); + g_batteryInfoInitialized = true; + } + + return rc; +} + +void batteryInfoExit(void) { + if (g_batteryInfoInitialized) { + psmExit(); + memset(&g_psmService, 0, sizeof(Service)); + g_batteryInfoInitialized = false; + } +} + +Result batteryInfoGetChargeInfo(BatteryChargeInfo *out) { + if (!out) + return MAKERESULT(Module_Libnx, LibnxError_BadInput); + + return psmGetBatteryChargeInfoFields(out); +} + +Result batteryInfoGetChargePercentage(u32 *out) { + if (!g_batteryInfoInitialized) + return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + + return psmGetBatteryChargePercentage(out); +} + +Result batteryInfoIsEnoughPowerSupplied(bool *out) { + if (!g_batteryInfoInitialized) + return MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + + return psmIsEnoughPowerSupplied(out); +} + +Result batteryInfoEnableCharging(void) { + return psmEnableBatteryCharging_internal(); +} + +Result batteryInfoDisableCharging(void) { + return psmDisableBatteryCharging_internal(); +} + +Result batteryInfoEnableFastCharging(void) { + return psmEnableFastBatteryCharging_internal(); +} + +Result batteryInfoDisableFastCharging(void) { + return psmDisableFastBatteryCharging_internal(); +} + +const char* batteryInfoGetChargerTypeString(BatteryChargerType type) { + if (type < 0 || type > ChargerType_Apple_2000mA) + return "Unknown"; + + return s_chargerTypeStrings[type]; +} + +const char* batteryInfoGetPowerRoleString(BatteryPowerRole role) { + if (role < PowerRole_Sink || role > PowerRole_Source) + return s_powerRoleStrings[0]; + + return s_powerRoleStrings[role]; +} + +const char* batteryInfoGetPDStateString(BatteryPDControllerState state) { + if (state < PDState_NewPDO || state > PDState_AcceptedRDO) + return s_pdStateStrings[0]; + + return s_pdStateStrings[state]; +} \ No newline at end of file diff --git a/Source/sys-clk/sysmodule/src/board.cpp b/Source/sys-clk/sysmodule/src/board.cpp index 562cc338..02edbf2c 100644 --- a/Source/sys-clk/sysmodule/src/board.cpp +++ b/Source/sys-clk/sysmodule/src/board.cpp @@ -33,6 +33,7 @@ #include // for std::clamp #include #include +#include "batLib.h" #define HOSSVC_HAS_CLKRST (hosversionAtLeast(8,0,0)) #define HOSSVC_HAS_TC (hosversionAtLeast(5,0,0)) @@ -40,8 +41,8 @@ #define systemtickfrequency 19200000 #define systemtickfrequencyF 19200000.0f -#define CPU_TICK_WAIT (1000'000ULL) - +#define CPU_TICK_WAIT (1'000'000'000 / 60) +float fanTemp = 0; Result nvCheck = 1; Thread gpuLThread; @@ -49,21 +50,20 @@ Thread cpuCore0Thread; Thread cpuCore1Thread; Thread cpuCore2Thread; Thread cpuCore3Thread; -Thread MISCThread; FanController fanController; Result fanCheck = 1; -u8 fanSpeed = 0; uint32_t GPU_Load_u = 0, fd = 0; +BatteryChargeInfo info; static SysClkSocType g_socType = SysClkSocType_Erista; static HorizonOCConsoleType g_consoleType = HorizonOCConsoleType_Unknown; -uint64_t idletick0 = systemtickfrequency; -uint64_t idletick1 = systemtickfrequency; -uint64_t idletick2 = systemtickfrequency; -uint64_t idletick3 = systemtickfrequency; +std::atomic idletick0{systemtickfrequency}; +std::atomic idletick1{systemtickfrequency}; +std::atomic idletick2{systemtickfrequency}; +std::atomic idletick3{systemtickfrequency}; u32 cpu0, cpu1, cpu2, cpu3, cpuAvg; const char* Board::GetModuleName(SysClkModule module, bool pretty) @@ -116,48 +116,16 @@ PcvModuleId Board::GetPcvModuleId(SysClkModule sysclkModule) return pcvModuleId; } -void CheckCore0(void*) { - while(true) { - uint64_t idletick_a0 = 0; - uint64_t idletick_b0 = 0; - svcGetInfo(&idletick_b0, InfoType_IdleTickCount, INVALID_HANDLE, 0); +void CheckCore(void* idletick_ptr) { + std::atomic* idletick = (std::atomic*)idletick_ptr; + while (true) { + uint64_t idletick_a; + uint64_t idletick_b; + svcGetInfo(&idletick_b, InfoType_IdleTickCount, INVALID_HANDLE, -1); svcSleepThread(CPU_TICK_WAIT); - svcGetInfo(&idletick_a0, InfoType_IdleTickCount, INVALID_HANDLE, 0); - idletick0 = idletick_a0 - idletick_b0; - } -} - -void CheckCore1(void*) { - while(true) { - uint64_t idletick_a1 = 0; - uint64_t idletick_b1 = 0; - svcGetInfo(&idletick_b1, InfoType_IdleTickCount, INVALID_HANDLE, 1); - svcSleepThread(CPU_TICK_WAIT); - svcGetInfo(&idletick_a1, InfoType_IdleTickCount, INVALID_HANDLE, 1); - idletick1 = idletick_a1 - idletick_b1; - } -} - -void CheckCore2(void*) { - while(true) { - uint64_t idletick_a2 = 0; - uint64_t idletick_b2 = 0; - svcGetInfo(&idletick_b2, InfoType_IdleTickCount, INVALID_HANDLE, 2); - svcSleepThread(CPU_TICK_WAIT); - svcGetInfo(&idletick_a2, InfoType_IdleTickCount, INVALID_HANDLE, 2); - idletick2 = idletick_a2 - idletick_b2; - } -} - -void CheckCore3(void*) { - while(true) { - uint64_t idletick_a3 = 0; - uint64_t idletick_b3 = 0; - svcGetInfo(&idletick_b3, InfoType_IdleTickCount, INVALID_HANDLE, 3); - svcSleepThread(CPU_TICK_WAIT); - svcGetInfo(&idletick_a3, InfoType_IdleTickCount, INVALID_HANDLE, 3); - idletick3 = idletick_a3 - idletick_b3; - } + svcGetInfo(&idletick_a, InfoType_IdleTickCount, INVALID_HANDLE, -1); + idletick->store(idletick_a - idletick_b, std::memory_order_release); + } } void gpuLoadThread(void*) { @@ -174,14 +142,6 @@ void gpuLoadThread(void*) { } while(true); } -void miscThread(void*) { - float temp; - for(;;) { - fanControllerGetRotationSpeedLevel(&fanController, &temp); - fanSpeed = (u8)temp; - } -} - void Board::Initialize() { @@ -230,22 +190,16 @@ void Board::Initialize() threadCreate(&gpuLThread, gpuLoadThread, NULL, NULL, 0x1000, 0x3F, -2); threadStart(&gpuLThread); - threadCreate(&cpuCore0Thread, CheckCore0, NULL, NULL, 0x1000, 0x10, 0); - threadStart(&cpuCore0Thread); - - threadCreate(&cpuCore1Thread, CheckCore1, NULL, NULL, 0x1000, 0x10, 1); - threadStart(&cpuCore1Thread); - - threadCreate(&cpuCore2Thread, CheckCore2, NULL, NULL, 0x1000, 0x10, 2); - threadStart(&cpuCore2Thread); - - threadCreate(&cpuCore3Thread, CheckCore3, NULL, NULL, 0x1000, 0x10, 3); - threadStart(&cpuCore3Thread); - - threadCreate(&MISCThread, miscThread, NULL, NULL, 0x1000, 0x3F, -2); - threadStart(&MISCThread); - + threadCreate(&cpuCore0Thread, CheckCore, &idletick0, NULL, 0x1000, 0x10, 0); + threadCreate(&cpuCore1Thread, CheckCore, &idletick1, NULL, 0x1000, 0x10, 1); + threadCreate(&cpuCore2Thread, CheckCore, &idletick2, NULL, 0x1000, 0x10, 2); + threadCreate(&cpuCore3Thread, CheckCore, &idletick3, NULL, 0x1000, 0x10, 3); + threadStart(&cpuCore0Thread); + threadStart(&cpuCore1Thread); + threadStart(&cpuCore2Thread); + threadStart(&cpuCore3Thread); + batteryInfoInitialize(); FetchHardwareInfos(); } @@ -276,9 +230,10 @@ void Board::Exit() threadClose(&cpuCore1Thread); threadClose(&cpuCore2Thread); threadClose(&cpuCore3Thread); - threadClose(&MISCThread); - + + fanExit(); rgltrExit(); + batteryInfoExit(); } SysClkProfile Board::GetProfile() @@ -578,6 +533,13 @@ std::uint32_t Board::GetTemperatureMilli(SysClkThermalSensor sensor) ASSERT_RESULT_OK(rc, "tcGetSkinTemperatureMilliC"); } } + else if (sensor == HorizonOCThermalSensor_Battery) { + batteryInfoGetChargeInfo(&info); + millis = batteryInfoGetTemperatureMiliCelsius(&info); + } + else if (sensor == HorizonOCThermalSensor_PMIC) { + millis = 50000; + } else { ASSERT_ENUM_VALID(SysClkThermalSensor, sensor); @@ -612,7 +574,10 @@ std::uint32_t Board::GetPartLoad(SysClkPartLoad loadSource) case HocClkPartLoad_GPU: return GPU_Load_u; case HocClkPartLoad_CPUAvg: - return (idletick0 + idletick1 + idletick2 + idletick3) / 4; + return idletick0; + case HocClkPartLoad_BAT: + batteryInfoGetChargeInfo(&info); + return info.RawBatteryCharge; default: ASSERT_ENUM_VALID(SysClkPartLoad, loadSource); } @@ -700,7 +665,7 @@ std::uint32_t Board::GetVoltage(HocClkVoltage voltage) { RgltrSession session; Result rc = 0; - u32 out; + u32 out = 0; switch(voltage) { case HocClkVoltage_SOC: @@ -747,6 +712,10 @@ std::uint32_t Board::GetVoltage(HocClkVoltage voltage) rgltrGetVoltage(&session, &out); rgltrCloseSession(&session); break; + case HocClkVoltage_Battery: + batteryInfoGetChargeInfo(&info); + out = info.VoltageAvg; + break; default: ASSERT_ENUM_VALID(HocClkVoltage, voltage); } @@ -755,5 +724,6 @@ std::uint32_t Board::GetVoltage(HocClkVoltage voltage) } u8 Board::GetFanRotationLevel() { - return fanSpeed; + fanControllerGetRotationSpeedLevel(&fanController, &fanTemp); + return (u8)fanTemp; } diff --git a/Source/sys-clk/sysmodule/src/clock_manager.cpp b/Source/sys-clk/sysmodule/src/clock_manager.cpp index 53381069..004a2a90 100644 --- a/Source/sys-clk/sysmodule/src/clock_manager.cpp +++ b/Source/sys-clk/sysmodule/src/clock_manager.cpp @@ -523,7 +523,6 @@ void ClockManager::SetRNXRTMode(ReverseNXMode mode) } void ClockManager::SetKipData() { - std::scoped_lock lock{this->contextMutex}; CustomizeTable table; if (!cust_read_and_cache(this->config->GetConfigValue(HocClkConfigValue_KipFileName) ? "sdmc:/atmosphere/kips/loader.kip" : "sdmc:/atmosphere/kips/hoc.kip", &table)) { @@ -594,8 +593,6 @@ void ClockManager::SetKipData() { void ClockManager::GetKipData() { if(this->config->Refresh()) { - std::scoped_lock lock{this->contextMutex}; - CustomizeTable table; if (!cust_read_and_cache(this->config->GetConfigValue(HocClkConfigValue_KipFileName) ? "sdmc:/atmosphere/kips/loader.kip" : "sdmc:/atmosphere/kips/hoc.kip", &table)) {