Files
2024-12-27 21:39:30 -07:00

155 lines
3.1 KiB
C++

#include "temperatureManager.h"
#include "utils.h"
#include "xboxInternals.h"
#include "xboxConfig.h"
namespace
{
bool mInitialized = false;
int32_t mCounter = 0;
int32_t mTargetTemp = 55;
int32_t mLastTemp = 0;
double mCpuFreq = 733;
int32_t mMinFanSpeed = 10;
int32_t mSystemFanSpeed = 0;
int32_t mCurrentFanSpeed = 0;
int32_t mTooHotCount = 0;
int32_t mTooColdCount = 0;
xboxConfig::xboxVersionEnum mXboxVer = xboxConfig::xboxVersionUnknown;
}
void temperatureManager::init()
{
if (mInitialized == true)
{
return;
}
mXboxVer = xboxConfig::getXboxVersion();
mSystemFanSpeed = getFanSpeed();
mCurrentFanSpeed = mSystemFanSpeed;
mLastTemp = max(getCpuTemp(), getMbTemp());
mCpuFreq = xboxConfig::getCPUFreq();
mMinFanSpeed = mCpuFreq > 760 ? 30 : 10;
}
int32_t temperatureManager::getCpuTemp()
{
if(mXboxVer != xboxConfig::xboxVersion16 && mXboxVer != xboxConfig::xboxVersion16b)
{
DWORD cpu = 0;
HalReadSMBusByte(0x4C << 1, 0x01, &cpu);
DWORD cpudec = 0;
HalReadSMBusByte(0x4C << 1, 0x10, &cpudec);
return (uint8_t)(cpu + cpudec / 256);
}
uint32_t cpuTemp = 0;
HalReadSMBusByte(PIC_ADDRESS, CPU_TEMP, &cpuTemp);
return cpuTemp;
}
int32_t temperatureManager::getMbTemp()
{
uint32_t tempMb = 0;
HalReadSMBusByte(PIC_ADDRESS, MB_TEMP, &tempMb);
return mXboxVer == xboxConfig::xboxVersion16 || mXboxVer == xboxConfig::xboxVersion16b
? (int32_t)(tempMb * 0.8f)
: (int32_t)tempMb;
}
int32_t temperatureManager::getFanSpeed()
{
uint32_t fanSpeed = 0;
HalReadSMBusByte(PIC_ADDRESS, FAN_READBACK, &fanSpeed);
return (int32_t)fanSpeed;
}
void temperatureManager::setFanSpeed(uint32_t fanspeed)
{
if (fanspeed > 50)
{
return;
}
if (mCurrentFanSpeed == fanspeed)
{
return;
}
mCurrentFanSpeed = fanspeed;
for (uint32_t i = 0; i < 2; i++)
{
HalWriteSMBusByte(PIC_ADDRESS, FAN_MODE, 1);
Sleep(10);
HalWriteSMBusByte(PIC_ADDRESS, FAN_REGISTER, fanspeed);
Sleep(10);
}
}
void temperatureManager::refresh()
{
// We dont want to refresh every frame as this will lock up the smbus
if (mCounter != 50)
{
mCounter++;
return;
}
mCounter = 0;
mMinFanSpeed = mCpuFreq > 760 ? 30 : 10;
int32_t temp = max(getCpuTemp(), getMbTemp());
float targetTempFloor = mTargetTemp - 0.75f;
float targetTempCeiling = mTargetTemp + 0.75f;
int calculatedFanSpeed = mCurrentFanSpeed;
if ((temp >= targetTempFloor) && (temp <= targetTempCeiling))
{
mTooHotCount = 0;
mTooColdCount = 0;
if (temp > mLastTemp)
{
calculatedFanSpeed++;
}
else if (temp < mLastTemp)
{
calculatedFanSpeed--;
}
}
else if (temp < targetTempFloor)
{
if (temp == mLastTemp)
{
mTooColdCount++;
}
else if (temp > mLastTemp)
{
mTooColdCount--;
}
if ((temp < mLastTemp) || (mTooColdCount == 12))
{
calculatedFanSpeed--;
mTooColdCount = 0;
}
}
else if (temp > targetTempCeiling)
{
if (temp == mLastTemp)
{
mTooHotCount++;
}
else if (temp < mLastTemp)
{
mTooHotCount--;
}
if ((temp > mLastTemp) || (mTooHotCount == 12))
{
calculatedFanSpeed++;
mTooHotCount = 0;
}
}
calculatedFanSpeed = min(max(calculatedFanSpeed, mMinFanSpeed), 50);
setFanSpeed(calculatedFanSpeed);
mLastTemp = temp;
}