📄 fanstuff.cpp
字号:
}*/
// protocol, address, command, len, data
status = this->ECSMBusRead(this->ECSMBusBaseOffsetInERAM, PRTC_Read_Block, BATTERY_ADDRESS_IN_EC_SMBUS, 0x21, &ReturnLen, ReturnData);
if( ReturnLen <= 32)
{
for( i=0;i< ReturnLen;i++)
sprintf(templist+strlen(templist), "%c", *(ReturnData+i));
}
else
sprintf(templist+strlen(templist), "%s %x ", "error",status);
templist[strlen(templist)-1]= '\0';
sprintf(this->CurrentStatus, "(%s)", templist);
::SetDlgItemText(this->hwndDialog, 8113, this->CurrentStatus);
this->HasReadDeviceName = TRUE;
}
strcpy(templist, "");
// protocol, address, command, len, data
this->ECSMBusRead(this->ECSMBusBaseOffsetInERAM, PRTC_Read_Word, BATTERY_ADDRESS_IN_EC_SMBUS, CMD_Voltage, &ReturnLen, ReturnData);
sprintf(templist+strlen(templist), " v:%dmV ", *(unsigned short*)ReturnData);
// protocol, address, command, len, data
this->ECSMBusRead(this->ECSMBusBaseOffsetInERAM, PRTC_Read_Word, BATTERY_ADDRESS_IN_EC_SMBUS, CMD_Current, &ReturnLen, ReturnData);
sprintf(templist+strlen(templist), "I:%dmA ", *(short*)ReturnData);
// protocol, address, command, len, data
this->ECSMBusRead(this->ECSMBusBaseOffsetInERAM, PRTC_Read_Word, BATTERY_ADDRESS_IN_EC_SMBUS, CMD_RemainingCapacity, &ReturnLen, ReturnData);
sprintf(templist+strlen(templist), "C:%dmAh ", *(unsigned short*)ReturnData);
// protocol, address, command, len, data
this->ECSMBusRead(this->ECSMBusBaseOffsetInERAM, PRTC_Read_Word, BATTERY_ADDRESS_IN_EC_SMBUS, CMD_FullChargeCapacity, &ReturnLen, ReturnData);
sprintf(templist+strlen(templist), "FC:%dmAh ", *(unsigned short*)ReturnData);
templist[strlen(templist)-1]= '\0';
sprintf(this->CurrentStatus, "(%s)", templist);
::SetDlgItemText(this->hwndDialog, 8112, this->CurrentStatus);
}
//
// handle fan control according to mode
//
/*
this->CurrentModeFromDialog();
switch (this->CurrentMode) {
case 1: // Bios Auto
if (this->State.FanCtrl!=0x080)
ok= this->SetFan("Mode switch", 0x80);
break;
case 2: // Smart
this->SmartControl();
break;
case 3: // fixed manual
::GetDlgItemText(this->hwndDialog, 8310, manlevel, sizeof(manlevel));
if (isdigit(manlevel[0]) && atoi(manlevel)>=0 && atoi(manlevel)<=255) {
if (this->State.FanCtrl!=atoi(manlevel)) {
ok= this->SetFan("Manual", atoi(manlevel));
}
else
ok= true;
}
break;
}
this->PreviousMode= this->CurrentMode;
*/
return ok;
}
//-------------------------------------------------------------------------
// smart fan control depending on temperature
//-------------------------------------------------------------------------
int
FANCONTROL::SmartControl(void)
{
int ok= 0, i,
newfanctrl= -1,
fanctrl= this->State.FanCtrl;
// if currently auto force initial fan speed according to rules
if ((fanctrl & 0x80)!=0 && this->PreviousMode==1) {
fanctrl= -1;
newfanctrl= 0;
}
// check for fan-up
for (i= 0; this->SmartLevels[i].temp!=-1; i++) {
if (this->MaxTemp>=this->SmartLevels[i].temp && this->SmartLevels[i].fan>fanctrl)
newfanctrl= this->SmartLevels[i].fan;
}
// not uptriggered check for downtrigger (previous level hit)
if (newfanctrl==-1) {
for (i= 0; this->SmartLevels[i].temp!=-1; i++) {
if (this->MaxTemp<=this->SmartLevels[i].temp && this->SmartLevels[i].fan<fanctrl) {
newfanctrl= this->SmartLevels[i].fan;
break;
}
}
}
// fan speed needs change?
if (newfanctrl!=-1 && newfanctrl!=fanctrl) {
if (newfanctrl==0x80) { // switch to BIOS-auto mode
// this->ModeToDialog(1); // bios
}
ok= this->SetFan("Smart", newfanctrl);
}
return ok;
}
//-------------------------------------------------------------------------
// set fan state via EC
//-------------------------------------------------------------------------
int
FANCONTROL::SetFan(const char *source, int fanctrl, BOOL final)
{
int ok= 0;
char obuf[256]= "", obuf2[256], datebuf[128];
if (this->FanBeepFreq && this->FanBeepDura)
::Beep(this->FanBeepFreq, this->FanBeepDura);
this->CurrentDateTimeLocalized(datebuf, sizeof(datebuf));
sprintf(obuf+strlen(obuf), "%s: Set fan control to 0x%02x, ", source, fanctrl);
sprintf(obuf+strlen(obuf), "Result: ");
if (this->ActiveMode && !this->FinalSeen) {
this->EcAccess.Lock();
// set new fan level
ok= this->WriteByteToEC(TP_ECOFFSET_FAN, fanctrl);
// verify completion
ok= this->ReadByteFromEC(TP_ECOFFSET_FAN, &this->State.FanCtrl);
if (ok && final)
this->FinalSeen= true; // prevent further changes when setting final mode
this->EcAccess.Unlock();
if (this->State.FanCtrl==fanctrl) {
sprintf(obuf+strlen(obuf), "OK");
ok= true;
}
else {
sprintf(obuf+strlen(obuf), "COULD NOT SET FAN STATE!!!!");
::Beep(880, 300);
::Sleep(200);
::Beep(880, 300);
::Sleep(200);
::Beep(880, 300);
ok= false;
}
}
else {
sprintf(obuf+strlen(obuf), "CMD IGNORED (PASSIVE MODE)");
}
// display result
sprintf(obuf2, "%s (%s)", obuf, datebuf);
::SetDlgItemText(this->hwndDialog, 8113, obuf2);
this->Trace(this->CurrentStatus);
this->Trace(obuf);
if (!final)
::PostMessage(this->hwndDialog, WM__GETDATA, 0, 0);
return ok;
}
//-------------------------------------------------------------------------
// read fan and temperatures from embedded controller
//-------------------------------------------------------------------------
int
FANCONTROL::ReadEcStatus(FCSTATE *pfcstate)
{
DWORD i, ok, rc= 0;
FCSTATE sample= { 0, },
sample2= { 0, };
setzero(pfcstate, sizeof(*pfcstate));
// reading from the EC seems to yield erratic results at times (probably
// due to collision with other drivers reading from the port). So try
// up to three times to read two samples which look oka and have matching
// value
this->EcAccess.Lock();
for (i= 0; i<3; i++) {
ok= this->ReadEcRaw(&sample);
if (ok) {
ok= this->ReadEcRaw(&sample2);
if (ok) {
// match for identical fanctrl settings and temperature differences
// of no more than 1癈
BOOL match= sample.FanCtrl==sample2.FanCtrl;
for (int j= 0; j<12 && match; j++) {
if (sample.Sensors[j]>128 || sample2.Sensors[j]>128 ||
abs(sample.Sensors[j]-sample2.Sensors[j])>1) {
match= false;
}
}
if (match) { // looks good
ok= true;
break;
}
else { // try again after short delay
ok= false;
::Sleep(200);
}
}
}
}
this->EcAccess.Unlock();
if (ok) {
memcpy(pfcstate, &sample, sizeof(*pfcstate));
}
return ok;
}
//-------------------------------------------------------------------------
// read fan and temperatures from embedded controller
//-------------------------------------------------------------------------
int
FANCONTROL::ReadEcRaw(FCSTATE *pfcstate)
{
int i, idxtemp, ok;
pfcstate->FanSpeedLo= 0;
pfcstate->FanSpeedHi= 0;
pfcstate->FanCtrl= -1;
memset(pfcstate->Sensors, 0, sizeof(pfcstate->Sensors));
ok= ReadByteFromEC(TP_ECOFFSET_FAN, &pfcstate->FanCtrl);
if (ok)
ok= ReadByteFromEC(TP_ECOFFSET_FANSPEED, &pfcstate->FanSpeedLo);
if (ok)
ok= ReadByteFromEC(TP_ECOFFSET_FANSPEED+1, &pfcstate->FanSpeedHi);
idxtemp= 0;
for (i= 0; i<8 && ok; i++) { // temp sensors 0x78 - 0x7f
ok= ReadByteFromEC(TP_ECOFFSET_TEMP0+i, &pfcstate->Sensors[idxtemp]);
pfcstate->SensorAddr[idxtemp]= TP_ECOFFSET_TEMP0+i;
pfcstate->SensorName[idxtemp]= gSensorNames[idxtemp];
idxtemp++;
}
for (i= 0; i<4 && ok; i++) { // temp sensors 0xC0 - 0xC4
ok= ReadByteFromEC(TP_ECOFFSET_TEMP1+i, &pfcstate->Sensors[idxtemp]);
pfcstate->SensorAddr[idxtemp]= TP_ECOFFSET_TEMP1+i;
pfcstate->SensorName[idxtemp]= gSensorNames[idxtemp];
idxtemp++;
}
return ok;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -