2438 lines
76 KiB
C
Executable File
2438 lines
76 KiB
C
Executable File
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <stdbool.h>
|
|
#include <stdarg.h>
|
|
#include <inttypes.h>
|
|
#include <ctype.h>
|
|
#include "lux_json_api.h"
|
|
#include "lux_system_api.h"
|
|
#include "cover_heat.h"
|
|
#include <dbus/dbus.h>
|
|
#include <stddef.h>
|
|
#include <linux/i2c.h>
|
|
#include <linux/i2c-dev.h>
|
|
|
|
SFscInfo psFscInfo;
|
|
INT8U g_u8FSCPresent = FALSE;
|
|
|
|
SFscFanReg sSFscFanReg[MAX_DIMM_SLOT] =
|
|
{
|
|
{0, 0x0069},
|
|
{1, 0x0068},
|
|
{2, 0x0067},
|
|
{3, 0x0066},
|
|
{4, 0x0065},
|
|
{5, 0x0064},
|
|
{6, 0x005e},
|
|
{7, 0x005f},
|
|
{8, 0x0060},
|
|
{9, 0x0061},
|
|
{10, 0x0062},
|
|
{11, 0x0063},
|
|
{12, 0x005d},
|
|
{13, 0x005c},
|
|
{14, 0x005b},
|
|
{15, 0x005a},
|
|
{16, 0x0059},
|
|
{17, 0x0058},
|
|
{18, 0x0052},
|
|
{19, 0x0053},
|
|
{20, 0x0054},
|
|
{21, 0x0055},
|
|
{22, 0x0056},
|
|
{23, 0x0057},
|
|
};
|
|
|
|
#if 0
|
|
SFscHeatReg sSFscHeatReg[MAX_DIMM_SLOT] =
|
|
{
|
|
{0, 0x008d},
|
|
{1, 0x008c},
|
|
{2, 0x008b},
|
|
{3, 0x008a},
|
|
{4, 0x0089},
|
|
{5, 0x0088},
|
|
{6, 0x0082},
|
|
{7, 0x0083},
|
|
{8, 0x0084},
|
|
{9, 0x0085},
|
|
{10, 0x0086},
|
|
{11, 0x0087},
|
|
{12, 0x0081},
|
|
{13, 0x0080},
|
|
{14, 0x007f},
|
|
{15, 0x007e},
|
|
{16, 0x007d},
|
|
{17, 0x007c},
|
|
{18, 0x0076},
|
|
{19, 0x0077},
|
|
{20, 0x0078},
|
|
{21, 0x0079},
|
|
{22, 0x007a},
|
|
{23, 0x007b},
|
|
};
|
|
#endif
|
|
|
|
SFscHeatReg sSFscHeatReg[MAX_DIMM_SLOT] =
|
|
{
|
|
{0, 0x0088},
|
|
{1, 0x0089},
|
|
{2, 0x008a},
|
|
{3, 0x008b},
|
|
{4, 0x008c},
|
|
{5, 0x008d},
|
|
|
|
{6, 0x0087},
|
|
{7, 0x0086},
|
|
{8, 0x0085},
|
|
{9, 0x0084},
|
|
{10, 0x0083},
|
|
{11, 0x0082},
|
|
|
|
|
|
{12, 0x007c},
|
|
{13, 0x007d},
|
|
{14, 0x007e},
|
|
{15, 0x007f},
|
|
{16, 0x0080},
|
|
{17, 0x0081},
|
|
|
|
{18, 0x007b},
|
|
{19, 0x007a},
|
|
{20, 0x0079},
|
|
{21, 0x0078},
|
|
{22, 0x0077},
|
|
{23, 0x0076},
|
|
};
|
|
|
|
|
|
SDIMMDbus sSDIMMDbus[MAX_DIMM_SLOT] =
|
|
{
|
|
{0, "/xyz/openbmc_project/sensors/temperature/DIMM_CPU0_A_Temp"},
|
|
{1, "/xyz/openbmc_project/sensors/temperature/DIMM_CPU0_B_Temp"},
|
|
{2, "/xyz/openbmc_project/sensors/temperature/DIMM_CPU0_C_Temp"},
|
|
{3, "/xyz/openbmc_project/sensors/temperature/DIMM_CPU0_D_Temp"},
|
|
{4, "/xyz/openbmc_project/sensors/temperature/DIMM_CPU0_E_Temp"},
|
|
{5, "/xyz/openbmc_project/sensors/temperature/DIMM_CPU0_F_Temp"},
|
|
{6, "/xyz/openbmc_project/sensors/temperature/DIMM_CPU0_G_Temp"},
|
|
{7, "/xyz/openbmc_project/sensors/temperature/DIMM_CPU0_H_Temp"},
|
|
{8, "/xyz/openbmc_project/sensors/temperature/DIMM_CPU0_I_Temp"},
|
|
{9, "/xyz/openbmc_project/sensors/temperature/DIMM_CPU0_J_Temp"},
|
|
{10, "/xyz/openbmc_project/sensors/temperature/DIMM_CPU0_K_Temp"},
|
|
{11, "/xyz/openbmc_project/sensors/temperature/DIMM_CPU0_L_Temp"},
|
|
{12, "/xyz/openbmc_project/sensors/temperature/DIMM_CPU1_A_Temp"},
|
|
{13, "/xyz/openbmc_project/sensors/temperature/DIMM_CPU1_B_Temp"},
|
|
{14, "/xyz/openbmc_project/sensors/temperature/DIMM_CPU1_C_Temp"},
|
|
{15, "/xyz/openbmc_project/sensors/temperature/DIMM_CPU1_D_Temp"},
|
|
{16, "/xyz/openbmc_project/sensors/temperature/DIMM_CPU1_E_Temp"},
|
|
{17, "/xyz/openbmc_project/sensors/temperature/DIMM_CPU1_F_Temp"},
|
|
{18, "/xyz/openbmc_project/sensors/temperature/DIMM_CPU1_G_Temp"},
|
|
{19, "/xyz/openbmc_project/sensors/temperature/DIMM_CPU1_H_Temp"},
|
|
{20, "/xyz/openbmc_project/sensors/temperature/DIMM_CPU1_I_Temp"},
|
|
{21, "/xyz/openbmc_project/sensors/temperature/DIMM_CPU1_J_Temp"},
|
|
{22, "/xyz/openbmc_project/sensors/temperature/DIMM_CPU1_K_Temp"},
|
|
{23, "/xyz/openbmc_project/sensors/temperature/DIMM_CPU1_L_Temp"},
|
|
};
|
|
|
|
EFuncRetCode check_dbus_error(DBusError *error)
|
|
{
|
|
if (dbus_error_is_set(error))
|
|
{
|
|
//LuxPrintf("D-Bus Error: %s\n", error->message);
|
|
dbus_error_free(error);
|
|
return FUNC_FAILED;
|
|
}
|
|
}
|
|
|
|
EFuncRetCode i2cReadWrite(INT8U bus, INT8U slaveAddr,
|
|
INT8U* writeData, INT8U writelen,
|
|
INT8U* readData, INT8U readlen)
|
|
{
|
|
char busPath[32] = {0};
|
|
struct i2c_msg messages[2];
|
|
struct i2c_rdwr_ioctl_data ioctl_data;
|
|
|
|
LuxSprintf(busPath, "/dev/i2c-%d", bus);
|
|
int fd = open(busPath, O_RDWR);
|
|
if (fd < 0)
|
|
{
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
if (writelen > 0)
|
|
{
|
|
messages[0].addr = slaveAddr;
|
|
messages[0].flags = 0;
|
|
messages[0].len = writelen;
|
|
messages[0].buf = writeData;
|
|
}
|
|
if (readlen > 0)
|
|
{
|
|
messages[1].addr = slaveAddr;
|
|
messages[1].flags = I2C_M_RD;
|
|
messages[1].len = readlen;
|
|
messages[1].buf = readData;
|
|
}
|
|
ioctl_data.msgs = messages;
|
|
ioctl_data.nmsgs = (writelen == 0 ? 0 : 1) + (readlen > 0 ? 1 : 0);
|
|
if (ioctl(fd, I2C_RDWR, &ioctl_data) < 0)
|
|
{
|
|
close(fd);
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
close(fd);
|
|
return FUNC_OK;
|
|
}
|
|
|
|
EFuncRetCode LuxFSCDbusGetDIMMValue(char* pcDbusPatch, INT8S* ps8Value, INT8U* pu8Present, INT8U* pu8Status)
|
|
{
|
|
const char *bus_name = "xyz.openbmc_project.DIMMTempSensor";
|
|
const char *path = pcDbusPatch;
|
|
const char *iface = "org.freedesktop.DBus.Properties";
|
|
const char *method = "Get";
|
|
|
|
const char *intf = "xyz.openbmc_project.Sensor.Value";
|
|
const char *prop = "Value";
|
|
|
|
DBusConnection *conn;
|
|
DBusError err;
|
|
DBusMessage *msg, *reply;
|
|
DBusMessageIter args;
|
|
|
|
dbus_error_init(&err);
|
|
conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
|
|
check_dbus_error(&err);
|
|
if (!conn)
|
|
{
|
|
if(reply)
|
|
dbus_message_unref(reply);
|
|
if(msg)
|
|
dbus_message_unref(msg);
|
|
if(conn)
|
|
dbus_connection_unref(conn);
|
|
return FUNC_FAILED;
|
|
}
|
|
msg = dbus_message_new_method_call(bus_name, path, iface, method);
|
|
if (!msg)
|
|
{
|
|
if(reply)
|
|
dbus_message_unref(reply);
|
|
if(msg)
|
|
dbus_message_unref(msg);
|
|
if(conn)
|
|
dbus_connection_unref(conn);
|
|
|
|
return FUNC_FAILED;
|
|
}
|
|
dbus_message_iter_init_append(msg, &args);
|
|
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &intf))
|
|
{
|
|
if(reply)
|
|
dbus_message_unref(reply);
|
|
if(msg)
|
|
dbus_message_unref(msg);
|
|
if(conn)
|
|
dbus_connection_unref(conn);
|
|
|
|
return FUNC_FAILED;
|
|
}
|
|
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &prop))
|
|
{
|
|
if(reply)
|
|
dbus_message_unref(reply);
|
|
if(msg)
|
|
dbus_message_unref(msg);
|
|
if(conn)
|
|
dbus_connection_unref(conn);
|
|
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
|
|
check_dbus_error(&err);
|
|
if (!reply)
|
|
{
|
|
if(reply)
|
|
dbus_message_unref(reply);
|
|
if(msg)
|
|
dbus_message_unref(msg);
|
|
if(conn)
|
|
dbus_connection_unref(conn);
|
|
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
if (!dbus_message_iter_init(reply, &args))
|
|
{
|
|
//LuxPrintf("Message has no arguments!\n");
|
|
}
|
|
else if (DBUS_TYPE_ARRAY == dbus_message_iter_get_arg_type(&args))
|
|
{
|
|
}
|
|
else if (DBUS_TYPE_VARIANT == dbus_message_iter_get_arg_type(&args))
|
|
{
|
|
DBusMessageIter variant_iter;
|
|
dbus_message_iter_recurse(&args, &variant_iter);
|
|
int type = dbus_message_iter_get_arg_type(&variant_iter);
|
|
switch (type)
|
|
{
|
|
case DBUS_TYPE_STRING:
|
|
{
|
|
const char *str_value;
|
|
dbus_message_iter_get_basic(&variant_iter, &str_value);
|
|
//printf("Parsed string value from variant: %s\n", str_value);
|
|
break;
|
|
}
|
|
case DBUS_TYPE_DOUBLE:
|
|
{
|
|
double double_value;
|
|
dbus_message_iter_get_basic(&variant_iter, &double_value);
|
|
//printf("Parsed double value from variant: %f\n", double_value);
|
|
*ps8Value = (INT8U)double_value;
|
|
*pu8Present = FSC_SENSOR_PRESENT;
|
|
*pu8Status = FSC_SENSOR_NORMAL;
|
|
break;
|
|
}
|
|
case DBUS_TYPE_BOOLEAN:
|
|
{
|
|
dbus_bool_t bool_value;
|
|
dbus_message_iter_get_basic(&variant_iter, &bool_value);
|
|
//printf("Parsed boolean value from variant: %d\n", bool_value);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
dbus_message_unref(reply);
|
|
dbus_message_unref(msg);
|
|
dbus_connection_unref(conn);
|
|
return FUNC_OK;
|
|
}
|
|
|
|
|
|
EFuncRetCode LuxFSCCheckFanTableExist(char* pcName)
|
|
{
|
|
/*check fan table file exist */
|
|
if(LuxAccess(pcName,F_OK) != 0)
|
|
{
|
|
LuxPrintf("Fan table file %s is not exist!!!\n",pcName);
|
|
return FUNC_FAILED;
|
|
}
|
|
return FUNC_OK;
|
|
}
|
|
|
|
EFuncRetCode LuxFSCLoadHeader(cJSON* psCJSONRoot, SFscHeader* psFSCHeader)
|
|
{
|
|
char acTemp[MAX_JSON_CHARACTER_SIZE] = {0};
|
|
|
|
LuxMemset(acTemp, 0, MAX_JSON_CHARACTER_SIZE);
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectStringValue(psCJSONRoot, "Project", acTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table Project fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if(LuxStrlen(acTemp) > MAX_KEY_LENGTH)
|
|
{
|
|
LuxPrintf("Project value error %s\n",acTemp);
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
LuxMemcpy(psFSCHeader->acProject, acTemp, LuxStrlen(acTemp));
|
|
}
|
|
}
|
|
|
|
LuxMemset(acTemp, 0, MAX_JSON_CHARACTER_SIZE);
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectStringValue(psCJSONRoot, "Customer", psFSCHeader->acCustomer)))
|
|
{
|
|
LuxPrintf("Parse fan table Customer fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if(LuxStrlen(acTemp) > MAX_KEY_LENGTH)
|
|
{
|
|
LuxPrintf("Customer value error %s\n",acTemp);
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
LuxMemcpy(psFSCHeader->acCustomer, acTemp, LuxStrlen(acTemp));
|
|
}
|
|
}
|
|
|
|
LuxMemset(acTemp, 0, MAX_JSON_CHARACTER_SIZE);
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectStringValue(psCJSONRoot, "Version", psFSCHeader->acVersion)))
|
|
{
|
|
LuxPrintf("Parse fan table Version fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if(LuxStrlen(acTemp) > MAX_KEY_LENGTH)
|
|
{
|
|
LuxPrintf("Version value error %s\n",acTemp);
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
LuxMemcpy(psFSCHeader->acVersion, acTemp, LuxStrlen(acTemp));
|
|
}
|
|
}
|
|
|
|
LuxMemset(acTemp, 0, MAX_JSON_CHARACTER_SIZE);
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectStringValue(psCJSONRoot, "platform", psFSCHeader->acPlatform)))
|
|
{
|
|
LuxPrintf("Parse fan table platform fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if(LuxStrlen(acTemp) > MAX_KEY_LENGTH)
|
|
{
|
|
LuxPrintf("platform value error %s\n",acTemp);
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
LuxMemcpy(psFSCHeader->acPlatform, acTemp, LuxStrlen(acTemp));
|
|
}
|
|
}
|
|
|
|
return FUNC_OK;
|
|
}
|
|
|
|
EFuncRetCode LuxFSCLoadGlobalConfig(cJSON* psCJSONRoot, SFscGlobalConfig* psFscGlobalConfig)
|
|
{
|
|
cJSON* psCJSONGlobalConfigRoot = NULL;
|
|
int iTemp = 0;
|
|
char acTemp[MAX_JSON_CHARACTER_SIZE] = {0};
|
|
|
|
psCJSONGlobalConfigRoot = LuxcJSONGetObjectItem(psCJSONRoot, "GlobalConfig");
|
|
if(NULL == psCJSONGlobalConfigRoot)
|
|
{
|
|
LuxPrintf("Can't get GlobalConfig cJSONRoot\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntValue(psCJSONGlobalConfigRoot, "MaxSensorReadingCache", &iTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table MaxSensorReadingCache fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
psFscGlobalConfig->u8MaxReadingCache = (INT8U)iTemp;
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntValue(psCJSONGlobalConfigRoot, "Elevation", &iTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table Elevation fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
psFscGlobalConfig->u16Elevation = iTemp;
|
|
}
|
|
|
|
LuxMemset(acTemp, 0, MAX_JSON_CHARACTER_SIZE);
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectStringValue(psCJSONGlobalConfigRoot, "FanType", acTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table FanType fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if(LuxStrlen(acTemp) > MAX_KEY_LENGTH)
|
|
{
|
|
LuxPrintf("FanType value error %s\n",acTemp);
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
LuxMemcpy(psFscGlobalConfig->acFanType, acTemp, LuxStrlen(acTemp));
|
|
}
|
|
}
|
|
|
|
LuxMemset(acTemp, 0, MAX_JSON_CHARACTER_SIZE);
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectStringValue(psCJSONGlobalConfigRoot, "WorkDCOff", acTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table WorkDCOff fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if(LuxStrlen(acTemp) > MAX_KEY_LENGTH)
|
|
{
|
|
LuxPrintf("WorkDCOff value error %s\n",acTemp);
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
LuxMemcpy(psFscGlobalConfig->acWorkDCOff, acTemp, LuxStrlen(acTemp));
|
|
}
|
|
}
|
|
|
|
return FUNC_OK;
|
|
}
|
|
|
|
EFuncRetCode LuxFSCLoadFanConfig(cJSON* psCJSONRoot, SFscFanConfig* psFscFanConfig)
|
|
{
|
|
cJSON* psCJSONFanConfigRoot = NULL;
|
|
int aiTemp[MAX_JSON_CHARACTER_SIZE] = {0};
|
|
int iArraySize = 0;
|
|
int iTemp = 0;
|
|
INT8U u8Index = 0;
|
|
|
|
psCJSONFanConfigRoot = LuxcJSONGetObjectItem(psCJSONRoot, "FanConfig");
|
|
if(NULL == psCJSONFanConfigRoot)
|
|
{
|
|
LuxPrintf("Can't get FanConfig cJSONRoot\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntValue(psCJSONFanConfigRoot, "MaxPWMNumber", &iTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table MaxPWMNumber fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
psFscFanConfig->u8MaxPwmNum = (INT8U)iTemp;
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntValue(psCJSONFanConfigRoot, "MaxFanNumber", &iTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table MaxFanNumber fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
psFscFanConfig->u8MaxFanNum = (INT8U)iTemp;
|
|
}
|
|
|
|
LuxMemset(aiTemp, 0, MAX_JSON_CHARACTER_SIZE);
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntArray(psCJSONFanConfigRoot, "FanSensorNumPWMMatch", aiTemp, &iArraySize)))
|
|
{
|
|
LuxPrintf("Parse fan table FanSensorNumPWMMatch fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if(iArraySize > MAX_FAN_COUNT)
|
|
{
|
|
LuxPrintf("FanSensorNumPWMMatch value error %s\n",aiTemp);
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
for(u8Index = 0; u8Index < iArraySize; u8Index++)
|
|
{
|
|
psFscFanConfig->u8FanSensorNumPWMMatch[u8Index] = (INT8U)aiTemp[u8Index];
|
|
}
|
|
}
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntValue(psCJSONFanConfigRoot, "MaxFanDuty", &iTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table MaxFanDuty fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
psFscFanConfig->u8MaxFanDuty = (INT8U)iTemp;
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntValue(psCJSONFanConfigRoot, "MinFanDuty", &iTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table MinFanDuty fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
psFscFanConfig->u8MinFanDuty = (INT8U)iTemp;
|
|
}
|
|
|
|
return FUNC_OK;
|
|
}
|
|
|
|
EFuncRetCode LuxFSCLoadCloseloopSensor(cJSON* psCJSONRoot, SFscCLSensor* psFscCLSensor)
|
|
{
|
|
INT8U u8CLSensorCount = 0;
|
|
INT8U u8SensorIndex = 0;
|
|
SFscCLSensorInfo sFscCLSensorInfo;
|
|
cJSON* psCJSONCloseloopRoot = NULL;
|
|
cJSON* psCJSONCloseloopSensorRoot = NULL;
|
|
char acKeyName[MAX_KEY_LENGTH] = {0};
|
|
int iArraySize = 0;
|
|
int iRow = 0;
|
|
int iColumn = 0;
|
|
int iTemp = 0;
|
|
char acTemp[MAX_JSON_CHARACTER_SIZE] = {0};
|
|
int aiTemp[MAX_JSON_CHARACTER_SIZE] = {0};
|
|
char asTemp[MAX_SETPOINT_CASE][MAX_JSON_CHARACTER_SIZE] = {0};
|
|
double adTemp[MAX_JSON_CHARACTER_SIZE][MAX_JSON_CHARACTER_SIZE] = {0};
|
|
INT8U u8RowIndex = 0;
|
|
INT8U u8ColumnIndex =0;
|
|
INT8U u8Index = 0;
|
|
|
|
psCJSONCloseloopRoot = LuxcJSONGetObjectItem(psCJSONRoot, "CloseLoop");
|
|
if(NULL == psCJSONCloseloopRoot)
|
|
{
|
|
LuxPrintf("Can't get CloseLoop cJSONRoot\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntValue(psCJSONCloseloopRoot, "MaxCloseloopSensor", &iTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table MaxCloseloopSensor fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
psFscCLSensor->u8MaxCLSensor = (INT8U)iTemp;
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntValue(psCJSONCloseloopRoot, "TotalCloseloopSensor", &iTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table TotalCloseloopSensor fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
psFscCLSensor->u8TotalCLSensor = (INT8U)iTemp;
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectStringValue(psCJSONCloseloopRoot, "PidAdjustMethod", acTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table PidAdjustMethod fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if(LuxStrlen(acTemp) > MAX_KEY_LENGTH)
|
|
{
|
|
LuxPrintf("PidAdjustMethod value error %s\n",acTemp);
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
LuxMemcpy(psFscCLSensor->acPIDAdjustMethod, acTemp, LuxStrlen(acTemp));
|
|
}
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntValue(psCJSONCloseloopRoot, "ESection", &iTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table ESection fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
psFscCLSensor->u8CLSensorESection = (INT8U)iTemp;
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntValue(psCJSONCloseloopRoot, "ECSection", &iTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table ECSection fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
psFscCLSensor->u8CLSensorECSection = (INT8U)iTemp;
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntValue(psCJSONCloseloopRoot, "SensorSetpointMaxCase", &iTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table SensorSetpointMaxCase fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
psFscCLSensor->u8CLSensorSetpointMaxCase = (INT8U)iTemp;
|
|
}
|
|
|
|
u8CLSensorCount = psFscCLSensor->u8TotalCLSensor;
|
|
if(u8CLSensorCount > psFscCLSensor->u8MaxCLSensor)
|
|
{
|
|
LuxPrintf("Wrong closeloop sensor count %d\n",u8CLSensorCount);
|
|
}
|
|
|
|
for(u8SensorIndex = 0; u8SensorIndex < u8CLSensorCount; u8SensorIndex++)
|
|
{
|
|
LuxMemset(&sFscCLSensorInfo, 0 ,sizeof(SFscCLSensorInfo));
|
|
LuxMemset(acKeyName, 0, MAX_KEY_LENGTH);
|
|
LuxSprintf(acKeyName, "CLSensor%d", u8SensorIndex+1); /*In fsc json file, the sensor index count from 1 */
|
|
|
|
psCJSONCloseloopSensorRoot = LuxcJSONGetObjectItem(psCJSONCloseloopRoot, acKeyName);
|
|
if(NULL == psCJSONCloseloopSensorRoot)
|
|
{
|
|
LuxPrintf("Can't get CLSensor%d cJSONRoot\n",u8SensorIndex);
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
LuxMemset(acTemp, 0, MAX_JSON_CHARACTER_SIZE);
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectStringValue(psCJSONCloseloopSensorRoot, "SensorType", acTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if(LuxStrlen(acTemp) > MAX_KEY_LENGTH)
|
|
{
|
|
LuxPrintf("SensorType value error %s\n",acTemp);
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
LuxMemcpy(sFscCLSensorInfo.acCLSensorType, acTemp, LuxStrlen(acTemp));
|
|
}
|
|
}
|
|
|
|
LuxMemset(acTemp, 0, MAX_JSON_CHARACTER_SIZE);
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectStringValue(psCJSONCloseloopSensorRoot, "SensorStatus", acTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table SensorStatusfail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if(LuxStrlen(acTemp) > MAX_KEY_LENGTH)
|
|
{
|
|
LuxPrintf("SensorStatus value error %s\n",acTemp);
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
LuxMemcpy(sFscCLSensorInfo.acCLSensorStatus, acTemp, LuxStrlen(acTemp));
|
|
}
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntValue(psCJSONCloseloopSensorRoot, "DT", &iTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table DT fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
sFscCLSensorInfo.u8DT = (INT8U)iTemp;
|
|
}
|
|
|
|
LuxMemset(acTemp, 0, MAX_JSON_CHARACTER_SIZE);
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectStringValue(psCJSONCloseloopSensorRoot, "SensorName", acTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table SensorName fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if(LuxStrlen(acTemp) > MAX_SENSOR_NAME_LENGTH)
|
|
{
|
|
LuxPrintf("SensorName value error %s\n",acTemp);
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
LuxMemcpy(sFscCLSensorInfo.acSensorName, acTemp, LuxStrlen(acTemp));
|
|
}
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntValue(psCJSONCloseloopSensorRoot, "VendorSpec", &iTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table VendorSpec fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
sFscCLSensorInfo.s8VendorSpec = (INT8U)iTemp;
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntValue(psCJSONCloseloopSensorRoot, "CustomerSpec", &iTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table CustomerSpec fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
sFscCLSensorInfo.s8CustomerSpec = (INT8U)iTemp;
|
|
}
|
|
|
|
LuxMemset(acTemp, 0, MAX_JSON_CHARACTER_SIZE);
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectStringValue(psCJSONCloseloopSensorRoot, "SetpointType", acTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table SetpointType fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if(LuxStrlen(acTemp) > MAX_SENSOR_NAME_LENGTH)
|
|
{
|
|
LuxPrintf("SetpointType value error %s\n",acTemp);
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
LuxMemcpy(sFscCLSensorInfo.acSetpointType, acTemp, LuxStrlen(acTemp));
|
|
}
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntValue(psCJSONCloseloopSensorRoot, "SetpointDefault", &iTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table SetpointDefault fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
sFscCLSensorInfo.s8SetpointDefault = (INT8U)iTemp;
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectStringArray(psCJSONCloseloopSensorRoot, "SetpointCase", asTemp, &iArraySize)))
|
|
{
|
|
LuxPrintf("Parse fan table SetpointCase fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if(iArraySize > MAX_SETPOINT_CASE)
|
|
{
|
|
LuxPrintf("SetpointCase value error %s\n",acTemp);
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
LuxMemcpy(sFscCLSensorInfo.acSetpointCase, (char**)asTemp, sizeof(sFscCLSensorInfo.acSetpointCase));
|
|
}
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntArray(psCJSONCloseloopSensorRoot, "SetpointValue", aiTemp, &iArraySize)))
|
|
{
|
|
LuxPrintf("Parse fan table SetpointValue fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if(iArraySize > MAX_OL_SENSOR_STEPS)
|
|
{
|
|
LuxPrintf("SetpointValue value error %s\n",acTemp);
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
for(u8Index = 0; u8Index < iArraySize; u8Index++)
|
|
{
|
|
sFscCLSensorInfo.as8SetpointValue[u8Index] = (INT8S)aiTemp[u8Index];
|
|
}
|
|
}
|
|
}
|
|
|
|
LuxMemset(acTemp, 0, MAX_JSON_CHARACTER_SIZE);
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectStringValue(psCJSONCloseloopSensorRoot, "SetpointCaseUse", acTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table SetpointCaseUse fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if(LuxStrlen(acTemp) > MAX_SENSOR_NAME_LENGTH)
|
|
{
|
|
LuxPrintf("SetpointCaseUse value error %s\n",acTemp);
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
LuxMemcpy(sFscCLSensorInfo.acSetpointCaseUse, acTemp, LuxStrlen(acTemp));
|
|
}
|
|
}
|
|
|
|
LuxMemset(aiTemp, 0, MAX_JSON_CHARACTER_SIZE);
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntArray(psCJSONCloseloopSensorRoot, "FanWeighting", aiTemp, &iArraySize)))
|
|
{
|
|
LuxPrintf("Parse fan table FanWeighting fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if(iArraySize > MAX_FSC_PWM_CHANNEL)
|
|
{
|
|
LuxPrintf("FanWeighting value error %s\n",acTemp);
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
for(u8Index = 0; u8Index < iArraySize; u8Index++)
|
|
{
|
|
sFscCLSensorInfo.au8FanWeight[u8Index] = (INT8U)aiTemp[u8Index];
|
|
}
|
|
}
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntValue(psCJSONCloseloopSensorRoot, "Hysteresis", &iTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table Hysteresis fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
sFscCLSensorInfo.u8Hysteresis = (INT8U)iTemp;
|
|
}
|
|
|
|
LuxMemset(aiTemp, 0, MAX_JSON_CHARACTER_SIZE);
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntArray(psCJSONCloseloopSensorRoot, "E", aiTemp, &iArraySize)))
|
|
{
|
|
LuxPrintf("Parse fan table E fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if(iArraySize > MAX_SENSOR_E_SECTION-1)
|
|
{
|
|
LuxPrintf("E value error %s\n",acTemp);
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
for(u8Index = 0; u8Index < iArraySize; u8Index++)
|
|
{
|
|
sFscCLSensorInfo.as8EValue[u8Index] = (INT8S)aiTemp[u8Index];
|
|
}
|
|
}
|
|
}
|
|
|
|
LuxMemset(aiTemp, 0, MAX_JSON_CHARACTER_SIZE);
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntArray(psCJSONCloseloopSensorRoot, "EC", aiTemp, &iArraySize)))
|
|
{
|
|
LuxPrintf("Parse fan table EC fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if(iArraySize > MAX_SENSOR_EC_SECTION-1)
|
|
{
|
|
LuxPrintf("EC value error %s\n",acTemp);
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
for(u8Index = 0; u8Index < iArraySize; u8Index++)
|
|
{
|
|
sFscCLSensorInfo.as8ECValue[u8Index] = (INT8S)aiTemp[u8Index];
|
|
}
|
|
}
|
|
}
|
|
|
|
LuxMemset(adTemp, 0, sizeof(adTemp));
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectDoubleArray2(psCJSONCloseloopSensorRoot, "P", adTemp, &iRow, &iColumn)))
|
|
{
|
|
LuxPrintf("Parse fan table P fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if((iRow > MAX_SENSOR_EC_SECTION) || (iColumn > MAX_SENSOR_E_SECTION))
|
|
{
|
|
LuxPrintf("P value error \n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
for(u8RowIndex = 0; u8RowIndex < MAX_SENSOR_EC_SECTION; u8RowIndex++)
|
|
{
|
|
for(u8ColumnIndex = 0; u8ColumnIndex < MAX_SENSOR_E_SECTION; u8ColumnIndex++)
|
|
{
|
|
sFscCLSensorInfo.afPValue[u8RowIndex][u8ColumnIndex] = adTemp[u8RowIndex][u8ColumnIndex];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
LuxMemset(adTemp, 0, sizeof(adTemp));
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectDoubleArray2(psCJSONCloseloopSensorRoot, "I", adTemp, &iRow, &iColumn)))
|
|
{
|
|
LuxPrintf("Parse fan table I fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if((iRow > MAX_SENSOR_EC_SECTION) || (iColumn > MAX_SENSOR_E_SECTION))
|
|
{
|
|
LuxPrintf("I value error \n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
for(u8RowIndex = 0; u8RowIndex < MAX_SENSOR_EC_SECTION; u8RowIndex++)
|
|
{
|
|
for(u8ColumnIndex = 0; u8ColumnIndex < MAX_SENSOR_E_SECTION; u8ColumnIndex++)
|
|
{
|
|
sFscCLSensorInfo.afIValue[u8RowIndex][u8ColumnIndex] = adTemp[u8RowIndex][u8ColumnIndex];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
LuxMemset(adTemp, 0, sizeof(adTemp));
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectDoubleArray2(psCJSONCloseloopSensorRoot, "D", adTemp, &iRow, &iColumn)))
|
|
{
|
|
LuxPrintf("Parse fan table D fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if((iRow > MAX_SENSOR_EC_SECTION) || (iColumn > MAX_SENSOR_E_SECTION))
|
|
{
|
|
LuxPrintf("D value error \n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
for(u8RowIndex = 0; u8RowIndex < MAX_SENSOR_EC_SECTION; u8RowIndex++)
|
|
{
|
|
for(u8ColumnIndex = 0; u8ColumnIndex < MAX_SENSOR_E_SECTION; u8ColumnIndex++)
|
|
{
|
|
sFscCLSensorInfo.afDValue[u8RowIndex][u8ColumnIndex] = adTemp[u8RowIndex][u8ColumnIndex];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
LuxMemcpy(&psFscCLSensor->asFscCLSensorInfo[u8SensorIndex], &sFscCLSensorInfo, sizeof(SFscCLSensorInfo));
|
|
}
|
|
return FUNC_OK;
|
|
}
|
|
|
|
EFuncRetCode LuxFSCLoadAbnormalConfig(cJSON* psCJSONRoot, SFscAbnormalEvent* psFscAbnormalEvent)
|
|
{
|
|
INT8U u8AbnormalSensorCount = 0;
|
|
INT8U u8SensorIndex = 0;
|
|
SFscSensorFailInfo sFscSensorFailInfo;
|
|
cJSON* psCJSONAbnormalEventRoot = NULL;
|
|
cJSON* psCJSONAbnormalSensorRoot = NULL;
|
|
char acKeyName[MAX_KEY_LENGTH] = {0};
|
|
int iTemp = 0;
|
|
char acTemp[MAX_JSON_CHARACTER_SIZE] = {0};
|
|
|
|
psCJSONAbnormalEventRoot = LuxcJSONGetObjectItem(psCJSONRoot, "AbnormalEvent");
|
|
if(NULL == psCJSONAbnormalEventRoot)
|
|
{
|
|
LuxPrintf("Can't get AbnormalEvent cJSONRoot\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntValue(psCJSONAbnormalEventRoot, "MaxFailSensor", &iTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table MaxFailSensor fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
psFscAbnormalEvent->u8MaxAbnormalSensor = (INT8U)iTemp;
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntValue(psCJSONAbnormalEventRoot, "TotalFailSensor", &iTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table TotalFailSensor fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
psFscAbnormalEvent->u8TotalAbnormalSensor = (INT8U)iTemp;
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntValue(psCJSONAbnormalEventRoot, "FanSensorNumberStart", &iTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table FanSensorNumberStart fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
psFscAbnormalEvent->sFscFanFail.u8FanSensorNumberStart = (INT8U)iTemp;
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectStringValue(psCJSONAbnormalEventRoot, "FanFailSingle", acTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table FanFailSingle fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if(LuxStrlen(acTemp) > MAX_KEY_LENGTH)
|
|
{
|
|
LuxPrintf("FanFailSingle value error %s\n",acTemp);
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
LuxMemcpy(psFscAbnormalEvent->sFscFanFail.acFanFailSingle, acTemp, LuxStrlen(acTemp));
|
|
}
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntValue(psCJSONAbnormalEventRoot, "FanFailTwin_1", &iTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table FanFailTwin_1 fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
psFscAbnormalEvent->sFscFanFail.u8FanFailTwin1 = (INT8U)iTemp;
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntValue(psCJSONAbnormalEventRoot, "FanFailTwin_2_Diff", &iTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table FanFailTwin_2_Diff fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
psFscAbnormalEvent->sFscFanFail.u8FanFailTwin2Diff = (INT8U)iTemp;
|
|
}
|
|
|
|
LuxMemset(acTemp, 0, MAX_JSON_CHARACTER_SIZE);
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectStringValue(psCJSONAbnormalEventRoot, "FanFailTwin_2_Same", acTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table FanFailTwin_2_Same fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if(LuxStrlen(acTemp) > MAX_KEY_LENGTH)
|
|
{
|
|
LuxPrintf("FanFailTwin_2_Same value error %s\n",acTemp);
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
LuxMemcpy(psFscAbnormalEvent->sFscFanFail.acFanFailTwin2Same, acTemp, LuxStrlen(acTemp));
|
|
}
|
|
}
|
|
|
|
u8AbnormalSensorCount = psFscAbnormalEvent->u8TotalAbnormalSensor;
|
|
if(u8AbnormalSensorCount > psFscAbnormalEvent->u8MaxAbnormalSensor)
|
|
{
|
|
LuxPrintf("Wrong abnormal sensor count %d\n",u8AbnormalSensorCount);
|
|
}
|
|
|
|
for(u8SensorIndex = 0; u8SensorIndex < u8AbnormalSensorCount; u8SensorIndex++)
|
|
{
|
|
LuxMemset(&sFscSensorFailInfo, 0 ,sizeof(SFscSensorFailInfo));
|
|
LuxMemset(acKeyName, 0, MAX_KEY_LENGTH);
|
|
LuxSprintf(acKeyName, "AbnormalSensor%d", u8SensorIndex+1); /*In fsc json file, the sensor index count from 1 */
|
|
|
|
psCJSONAbnormalSensorRoot = LuxcJSONGetObjectItem(psCJSONAbnormalEventRoot, acKeyName);
|
|
if(NULL == psCJSONAbnormalSensorRoot)
|
|
{
|
|
LuxPrintf("Can't get AbnormalSensor%d cJSONRoot\n",u8SensorIndex);
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
LuxMemset(acTemp, 0, MAX_JSON_CHARACTER_SIZE);
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectStringValue(psCJSONAbnormalSensorRoot, "SensorName", acTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table SensorName fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if(LuxStrlen(acTemp) > MAX_KEY_LENGTH)
|
|
{
|
|
LuxPrintf("SensorName value error %s\n",acTemp);
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
LuxMemcpy(sFscSensorFailInfo.acSensorName, acTemp, LuxStrlen(acTemp));
|
|
}
|
|
}
|
|
|
|
LuxMemset(acTemp, 0, MAX_JSON_CHARACTER_SIZE);
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectStringValue(psCJSONAbnormalSensorRoot, "Policy", acTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table Policy fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if(LuxStrlen(acTemp) > MAX_KEY_LENGTH)
|
|
{
|
|
LuxPrintf("Policy value error %s\n",acTemp);
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
LuxMemcpy(sFscSensorFailInfo.acFailPolicy, acTemp, LuxStrlen(acTemp));
|
|
}
|
|
}
|
|
|
|
if(FUNC_FAILED == (LuxcJSONGetObjectIntValue(psCJSONAbnormalSensorRoot, "FailValue", &iTemp)))
|
|
{
|
|
LuxPrintf("Parse fan table FailValue fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
sFscSensorFailInfo.u8FailValue = (INT8U)iTemp;
|
|
}
|
|
|
|
LuxMemcpy(&psFscAbnormalEvent->asFscSensorFailInfo[u8SensorIndex], &sFscSensorFailInfo, sizeof(SFscSensorFailInfo));
|
|
}
|
|
return FUNC_OK;
|
|
}
|
|
|
|
|
|
EFuncRetCode LuxFSCLoadFanTable(cJSON* psCJSONRoot, SFscInfo* psFscInfo)
|
|
{
|
|
EFuncRetCode eRetn = FUNC_FAILED;
|
|
|
|
/*Load fan table header */
|
|
eRetn = LuxFSCLoadHeader(psCJSONRoot, &psFscInfo->sFSCHeader);
|
|
if(FUNC_FAILED == eRetn)
|
|
{
|
|
LuxPrintf("Load fan table header fail !!!\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
/*Load fan table global configuration */
|
|
eRetn = LuxFSCLoadGlobalConfig(psCJSONRoot, &psFscInfo->sFscGlobalConfig);
|
|
if(FUNC_FAILED == eRetn)
|
|
{
|
|
LuxPrintf("Load fan table global config fail !!!\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
/*Load fan table fan configuration */
|
|
eRetn = LuxFSCLoadFanConfig(psCJSONRoot, &psFscInfo->sFscFanConfig);
|
|
if(FUNC_FAILED == eRetn)
|
|
{
|
|
LuxPrintf("Load fan table fan config fail !!!\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
/*Load fan table closeloop sensor information */
|
|
eRetn = LuxFSCLoadCloseloopSensor(psCJSONRoot, &psFscInfo->sFscCLSensor);
|
|
if(FUNC_FAILED == eRetn)
|
|
{
|
|
LuxPrintf("Load fan table fan config fail !!!\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
return FUNC_OK;
|
|
}
|
|
|
|
EFuncRetCode LuxFSCGetSetpointFromFile(INT8S* ps8Setpoint)
|
|
{
|
|
FILE* fp = NULL;
|
|
char acCmdbuff[512] = {0};
|
|
char acCmdstr[1024] = {0};
|
|
INT8U u8Value = 0;
|
|
|
|
if(0 != LuxAccess(DIMM_SETPOINT_PATH, F_OK))
|
|
{
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
LuxSprintf(acCmdstr, "cat %s",DIMM_SETPOINT_PATH);
|
|
if ((fp = LuxPopen(acCmdstr, "r")) != NULL)
|
|
{
|
|
fgets(acCmdbuff, sizeof(acCmdbuff), fp);
|
|
u8Value = strtoul(acCmdbuff, NULL, 10);
|
|
LuxPclose(fp);
|
|
if (u8Value > 120)
|
|
{
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
*ps8Setpoint = (INT8S)u8Value;
|
|
return FUNC_OK;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
return FUNC_OK;
|
|
}
|
|
|
|
EFuncRetCode LuxFSCSetSetpointToFile(INT8S s8Setpoint)
|
|
{
|
|
FILE *fp = NULL;
|
|
char buffer[32] = {0};
|
|
|
|
fp = LuxFopen(DIMM_SETPOINT_PATH, "wb");
|
|
if(NULL == fp)
|
|
{
|
|
LuxPrintf("Error: LuxFopen %s Failed\n",DIMM_SETPOINT_PATH);
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
snprintf(buffer, sizeof(buffer), "%d", s8Setpoint);
|
|
if (fputs(buffer, fp) == EOF)
|
|
{
|
|
LuxPrintf("Error: fputs Failed\n");
|
|
LuxFclose(fp);
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
LuxFclose(fp);
|
|
return FUNC_OK;
|
|
}
|
|
|
|
EFuncRetCode LuxFSCSetPreHeatTempToFile(INT8S s8Setpoint)
|
|
{
|
|
FILE *fp = NULL;
|
|
char buffer[32] = {0};
|
|
|
|
fp = LuxFopen(COVER_SETPOINT_PATH, "wb");
|
|
if(NULL == fp)
|
|
{
|
|
LuxPrintf("Error: LuxFopen %s Failed\n",COVER_SETPOINT_PATH);
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
snprintf(buffer, sizeof(buffer), "%d", s8Setpoint);
|
|
if (fputs(buffer, fp) == EOF)
|
|
{
|
|
LuxPrintf("Error: fputs Failed\n");
|
|
LuxFclose(fp);
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
LuxFclose(fp);
|
|
return FUNC_OK;
|
|
}
|
|
|
|
EFuncRetCode LuxFSCGetPreHeatTempFromFile(INT8S* ps8Setpoint)
|
|
{
|
|
FILE* fp = NULL;
|
|
char acCmdbuff[512] = {0};
|
|
char acCmdstr[1024] = {0};
|
|
INT8U u8Value = 0;
|
|
|
|
if(0 != LuxAccess(COVER_SETPOINT_PATH, F_OK))
|
|
{
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
LuxSprintf(acCmdstr, "cat %s",COVER_SETPOINT_PATH);
|
|
if ((fp = LuxPopen(acCmdstr, "r")) != NULL)
|
|
{
|
|
fgets(acCmdbuff, sizeof(acCmdbuff), fp);
|
|
u8Value = strtoul(acCmdbuff, NULL, 10);
|
|
LuxPclose(fp);
|
|
if (u8Value > 120)
|
|
{
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
*ps8Setpoint = (INT8S)u8Value;
|
|
return FUNC_OK;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
return FUNC_OK;
|
|
}
|
|
|
|
|
|
EFuncRetCode LuxFSCInit()
|
|
{
|
|
char acFscFileName[64] = {0};
|
|
cJSON* psCJSONRoot = NULL;
|
|
LuxMemset(&psFscInfo, 0, sizeof(SFscInfo));
|
|
|
|
LuxSprintf(acFscFileName,"%s",FAN_TABLE_PATH);
|
|
|
|
LuxPrintf("Load fan table %s\n",acFscFileName);
|
|
|
|
/*Check fan table exist*/
|
|
if(FUNC_FAILED == LuxFSCCheckFanTableExist(acFscFileName))
|
|
{
|
|
LuxPrintf("Fan table is not exist !!!\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
/* Load fan table */
|
|
psCJSONRoot = LuxcJSONParseJsonFile(acFscFileName);
|
|
if(NULL == psCJSONRoot)
|
|
{
|
|
LuxPrintf("Can't open fan table file %s !!!\n",acFscFileName);
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
if(LuxFSCLoadFanTable(psCJSONRoot, &psFscInfo) != FUNC_OK)
|
|
{
|
|
psFscInfo.sFscRunningInfo.u8FanTableLoadStatus = FSC_FAN_TABLE_LOAD_FAIL;
|
|
}
|
|
else
|
|
{
|
|
psFscInfo.sFscRunningInfo.u8FanTableLoadStatus = FSC_FAN_TABLE_LOAD_SUCCESS;
|
|
LuxFSCSetPreHeatTempToFile(COVER_PRE_HEAT_TEMP);
|
|
}
|
|
|
|
if(NULL != psCJSONRoot)
|
|
{
|
|
LuxcJSONDelete(psCJSONRoot);
|
|
}
|
|
|
|
return FUNC_OK;
|
|
}
|
|
|
|
EFuncRetCode LuxFSCFanTableUpdate(SFscInfo* psFscInfo)
|
|
{
|
|
if(FSC_FAN_TABLE_UPDATE == psFscInfo->sFscRunningInfo.u8UpdateFlag)
|
|
{
|
|
LuxPrintf("Fan table need update. re-load fan table.\n");
|
|
if(FUNC_OK != LuxFSCInit())
|
|
{
|
|
LuxPrintf("Reload fan table fail!!!\n");
|
|
if(psFscInfo->sFscRunningInfo.u8LoadTableTries < 3)
|
|
{
|
|
LuxPrintf("Retry !!!\n");
|
|
psFscInfo->sFscRunningInfo.u8LoadTableTries ++;
|
|
return FUNC_OK;
|
|
}
|
|
else
|
|
{
|
|
psFscInfo->sFscRunningInfo.u8UpdateFlag = FSC_FAN_TABLE_NORMAL;
|
|
psFscInfo->sFscRunningInfo.u8FanTableLoadStatus = FSC_FAN_TABLE_LOAD_FAIL;
|
|
psFscInfo->sFscRunningInfo.u8LoadTableTries = 0;
|
|
return FUNC_FAILED;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
psFscInfo->sFscRunningInfo.u8UpdateFlag = FSC_FAN_TABLE_NORMAL;
|
|
psFscInfo->sFscRunningInfo.u8FanTableLoadStatus = FSC_FAN_TABLE_LOAD_SUCCESS;
|
|
return FUNC_OK;
|
|
}
|
|
}
|
|
|
|
return FUNC_OK;
|
|
}
|
|
|
|
EFuncRetCode LuxPDKGetPSGood()
|
|
{
|
|
FILE* fp = NULL;
|
|
char acCmdbuff[512] = {0};
|
|
char acCmdstr[1024] = {0};
|
|
unsigned long value = 0;
|
|
|
|
LuxSprintf(acCmdstr, "devmem 0x1e780088");
|
|
|
|
if ((fp = LuxPopen(acCmdstr, "r")) != NULL)
|
|
{
|
|
fgets(acCmdbuff, sizeof(acCmdbuff), fp);
|
|
value = strtoul(acCmdbuff, NULL, 16);
|
|
LuxPclose(fp);
|
|
if ((value & 0x2000) > 0)
|
|
{
|
|
return PS_GOOD_OK;
|
|
}
|
|
else
|
|
{
|
|
return PS_GOOD_FAIL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return FUNC_FAILED;
|
|
}
|
|
}
|
|
|
|
EFuncRetCode LuxFSCGetDIMMValue(INT8U u8CPUIndex, INT8U u8DIMMIndex, INT8S* ps8Value, INT8U* pu8Present, INT8U* pu8Status)
|
|
{
|
|
FILE* fp = NULL;
|
|
char acCmdbuff[512] = {0};
|
|
char acCmdstr[1024] = {0};
|
|
INT8U u8DIMMValue = 0;
|
|
|
|
LuxSprintf(acCmdstr, "peci_cmds raw 0x%x 0x05 0x05 0xa1 0x00 0x0e 0x%x 0x00",(0x30 + u8CPUIndex), u8DIMMIndex);
|
|
|
|
if ((fp = LuxPopen(acCmdstr, "r")) != NULL)
|
|
{
|
|
fgets(acCmdbuff, sizeof(acCmdbuff), fp);
|
|
LuxPclose(fp);
|
|
unsigned int byteValue = 0;
|
|
int count = 0;
|
|
char *token = strtok(acCmdbuff, " ");
|
|
|
|
while (token != NULL)
|
|
{
|
|
if (count == 0)
|
|
{
|
|
sscanf(token, "%x", &byteValue);
|
|
*pu8Status = (INT8U)byteValue;
|
|
}
|
|
|
|
if (count == 2)
|
|
{
|
|
sscanf(token, "%x", &byteValue);
|
|
u8DIMMValue = (INT8U)byteValue;
|
|
if(u8DIMMValue != 0)
|
|
{
|
|
*pu8Present = FSC_SENSOR_PRESENT;
|
|
}
|
|
else
|
|
{
|
|
*pu8Present = FSC_SENSOR_NOT_PRESENT;
|
|
}
|
|
break;
|
|
}
|
|
count++;
|
|
token = strtok(NULL, " ");
|
|
}
|
|
*ps8Value = u8DIMMValue;
|
|
}
|
|
else
|
|
{
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
EFuncRetCode LuxFSCGetCPUValue(INT8U u8CPUIndex, INT8S* ps8Value, INT8U* pu8Present, INT8U* pu8Status)
|
|
{
|
|
FILE *fp = NULL;
|
|
char command[256];
|
|
char output[256];
|
|
float temperature = 0;
|
|
char tempStr[255] = {0};
|
|
|
|
sprintf(command, "peci_cmds -a 0x%x GetTemp", (0x30 + u8CPUIndex));
|
|
if ((fp = popen(command, "r")) != NULL)
|
|
{
|
|
if (fgets(output, sizeof(output), fp) != NULL)
|
|
{
|
|
if (sscanf(output, "%*s (%fC)", &temperature) == 1)
|
|
{
|
|
// change temperature to int
|
|
if (temperature < -128 || temperature > 127)
|
|
{
|
|
LuxPrintf("Temperature out of range for INT8U.\n");
|
|
pclose(fp);
|
|
return FUNC_FAILED;
|
|
}
|
|
pclose(fp);
|
|
*ps8Value = (INT8S)temperature;
|
|
*pu8Present = FSC_SENSOR_PRESENT;
|
|
return FUNC_OK;
|
|
}
|
|
else
|
|
{
|
|
LuxPrintf("Failed to parse temperature.\n");
|
|
pclose(fp);
|
|
return FUNC_FAILED;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pclose(fp);
|
|
return FUNC_FAILED;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LuxPrintf("Failed to execute command.\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EFuncRetCode LuxFSCGetSensorStatus(SFscInfo* psFscInfo)
|
|
{
|
|
INT8U u8SensorIndex = 0;
|
|
INT8U u8SensorNumber = 0;
|
|
INT8U u8ReadingIndex = 0;
|
|
INT8S s8SensorReading = 0;
|
|
INT8U u8Status = 0;
|
|
INT8U u8Present = 0;
|
|
|
|
/*Get closeloop sensor status and reading */
|
|
for(u8SensorIndex = 0; u8SensorIndex < psFscInfo->sFscCLSensor.u8TotalCLSensor ; u8SensorIndex++)
|
|
{
|
|
/*CPU0 DIMM temperature */
|
|
if(u8SensorIndex < 24)
|
|
{
|
|
LuxFSCDbusGetDIMMValue(sSDIMMDbus[u8SensorIndex].acDbusPath, &s8SensorReading, &u8Present, &u8Status);
|
|
}
|
|
|
|
/*Closeloop sensor need save the all real value. */
|
|
for(u8ReadingIndex = 0; u8ReadingIndex < MAX_READING_CACHE; u8ReadingIndex++)
|
|
{
|
|
if(SENSOR_REAL_VALUE_INITIAL == psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].as8RealValue[u8ReadingIndex])
|
|
{
|
|
psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].as8RealValue[u8ReadingIndex] = s8SensorReading;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(MAX_READING_CACHE == u8ReadingIndex)
|
|
{
|
|
for(u8ReadingIndex = 0; u8ReadingIndex < MAX_READING_CACHE; u8ReadingIndex++)
|
|
{
|
|
if(u8ReadingIndex < (MAX_READING_CACHE - 1))
|
|
{
|
|
psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].as8RealValue[u8ReadingIndex] = psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].as8RealValue[u8ReadingIndex + 1];
|
|
}
|
|
else
|
|
{
|
|
psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].as8RealValue[MAX_READING_CACHE-1] = s8SensorReading;
|
|
}
|
|
}
|
|
}
|
|
//psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].u8SensorStatus = psVolatileSensorZone->asLuxSensorInfo[u8SensorNumber].SensorInfo.EventFlags;
|
|
//psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].u8Health = psVolatileSensorZone->asLuxSensorInfo[u8SensorNumber].SensorInfo.HealthLevel;
|
|
psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].u8Present = u8Present;
|
|
|
|
}
|
|
|
|
return FUNC_OK;
|
|
}
|
|
|
|
EFuncRetCode LuxFSCGetTruePID(SFscCLSensorInfo* psFscCLSensorInfo, INT8U u8CLSensorESection, INT8U u8CLSensorECSection)
|
|
{
|
|
INT8U u8EIndex = 0;
|
|
INT8U u8ECIndex = 0;
|
|
INT8S s8E = 0;
|
|
INT8S s8EC = 0;
|
|
|
|
/*E = current_reading - setpoint */
|
|
s8E = psFscCLSensorInfo->as8RealValue[MAX_READING_CACHE-1] - psFscCLSensorInfo->s8Setpoint;
|
|
|
|
/*EC = current_reading - last_reading */
|
|
s8EC = psFscCLSensorInfo->as8RealValue[MAX_READING_CACHE-1] - psFscCLSensorInfo->as8RealValue[MAX_READING_CACHE-2];
|
|
|
|
/*get true pid parameter by query e and ec value */
|
|
for(u8ECIndex = 0; u8ECIndex < (u8CLSensorECSection - 1); u8ECIndex++)
|
|
{
|
|
if(psFscCLSensorInfo->as8ECValue[u8ECIndex] < s8EC)
|
|
{
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
/*LuxPrintf("find the EC section, u8ECIndex = %d\n",u8ECIndex);*/
|
|
break;
|
|
}
|
|
}
|
|
if((u8CLSensorECSection - 1) == u8ECIndex)
|
|
{
|
|
/*LuxPrintf("EC chose the max\n");*/
|
|
u8ECIndex = (u8CLSensorECSection - 1);
|
|
}
|
|
|
|
for(u8EIndex = 0; u8EIndex < (u8CLSensorESection - 1); u8EIndex++)
|
|
{
|
|
if(psFscCLSensorInfo->as8EValue[u8EIndex] < s8E)
|
|
{
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
/*LuxPrintf("find the E section, u8EIndex = %d\n",u8EIndex);*/
|
|
break;
|
|
}
|
|
}
|
|
if((u8CLSensorESection - 1) == u8EIndex)
|
|
{
|
|
/*LuxPrintf("E chose the max\n");*/
|
|
u8EIndex = (u8CLSensorESection - 1);
|
|
}
|
|
|
|
psFscCLSensorInfo->fP = psFscCLSensorInfo->afPValue[u8ECIndex][u8EIndex];
|
|
psFscCLSensorInfo->fI = psFscCLSensorInfo->afIValue[u8ECIndex][u8EIndex];
|
|
psFscCLSensorInfo->fI = -10;
|
|
psFscCLSensorInfo->fD = psFscCLSensorInfo->afDValue[u8ECIndex][u8EIndex];
|
|
|
|
return FUNC_OK;
|
|
}
|
|
|
|
EFuncRetCode LuxFSCGetSetpointCase(SFscCLSensorInfo* psFscCLSensorInfo)
|
|
{
|
|
/*TBD */
|
|
if(0)
|
|
{
|
|
psFscCLSensorInfo = psFscCLSensorInfo;
|
|
}
|
|
return FUNC_OK;
|
|
}
|
|
|
|
EFuncRetCode LuxFSCGetTureSetpoint(SFscCLSensorInfo* psFscCLSensorInfo)
|
|
{
|
|
INT8U u8SensorIndex = 0;
|
|
INT8U u8SetpointCase = 0;
|
|
INT8S s8Setpoint = 0;
|
|
|
|
/* Search setpoint */
|
|
if(0 == LuxStrncmp(psFscCLSensorInfo->acSetpointType, SETPOINT_CONSTANT, LuxStrlen(SETPOINT_CONSTANT)))
|
|
{
|
|
if(FUNC_FAILED == LuxFSCGetSetpointFromFile(&s8Setpoint))
|
|
{
|
|
psFscCLSensorInfo->s8Setpoint = psFscCLSensorInfo->s8SetpointDefault;
|
|
}
|
|
else
|
|
{
|
|
psFscCLSensorInfo->s8Setpoint = s8Setpoint;
|
|
}
|
|
}
|
|
else if(0 == LuxStrncmp(psFscCLSensorInfo->acSetpointType, SETPOINT_VARIABLE, LuxStrlen(SETPOINT_VARIABLE)))
|
|
{
|
|
/*get variable setpoint sensor's case use*/
|
|
LuxFSCGetSetpointCase(psFscCLSensorInfo);
|
|
|
|
for(u8SetpointCase = 0; u8SetpointCase < MAX_SETPOINT_CASE; u8SetpointCase++)
|
|
{
|
|
if(0 == LuxStrncmp(psFscCLSensorInfo->acSetpointCaseUse, psFscCLSensorInfo->acSetpointCase[u8SetpointCase], LuxStrlen(psFscCLSensorInfo->acSetpointCaseUse)))
|
|
{
|
|
/*find the setpoint define*/
|
|
psFscCLSensorInfo->s8Setpoint = psFscCLSensorInfo->as8SetpointValue[u8SetpointCase];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(u8SetpointCase == MAX_SETPOINT_CASE)
|
|
{
|
|
/*Can't find setpoint define, use default setpoint*/
|
|
psFscCLSensorInfo->s8Setpoint = psFscCLSensorInfo->s8SetpointDefault;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/*setpoint type is not correct, use default setpoint*/
|
|
psFscCLSensorInfo->s8Setpoint = psFscCLSensorInfo->s8SetpointDefault;
|
|
}
|
|
|
|
return FUNC_OK;
|
|
}
|
|
|
|
EFuncRetCode LuxFSCCloseloopCalculateDuty(SFscCLSensorInfo* psFscCLSensorInfo, INT8U u8MaxPwm, INT8U u8MinPwm)
|
|
{
|
|
INT8S s8ReadingT = 0;
|
|
INT8S s8ReadingT1 = 0;
|
|
INT8S s8ReadingT2 = 0;
|
|
float fPIncrement = 0;
|
|
float fIIncrement = 0;
|
|
float fDIncrement = 0;
|
|
INT8U u8Pwm = 0;
|
|
INT8U u8FanIndex=0;
|
|
INT8U u8HysteresisIndex = 0;
|
|
INT16S s16PwmSum = 0;
|
|
float fPWMIncrease = 0;
|
|
|
|
/*get last three sensor readings */
|
|
s8ReadingT = psFscCLSensorInfo->as8RealValue[MAX_READING_CACHE - 3];
|
|
s8ReadingT1 = psFscCLSensorInfo->as8RealValue[MAX_READING_CACHE - 2];
|
|
s8ReadingT2 = psFscCLSensorInfo->as8RealValue[MAX_READING_CACHE - 1];
|
|
|
|
/*calculate pwm by PID formula */
|
|
fPIncrement = (float)(psFscCLSensorInfo->fP * (s8ReadingT2 - s8ReadingT1));
|
|
fIIncrement = (float)(psFscCLSensorInfo->fI * (s8ReadingT2 - psFscCLSensorInfo->s8Setpoint));
|
|
fDIncrement = (float)(psFscCLSensorInfo->fD * (s8ReadingT2 + s8ReadingT - 2*s8ReadingT1));
|
|
fPWMIncrease = fPIncrement + fIIncrement + fDIncrement;
|
|
|
|
if((psFscCLSensorInfo->s16LastPwmPIDCalculate + fPWMIncrease) < 0)
|
|
{
|
|
u8Pwm = 0;
|
|
}
|
|
else if((psFscCLSensorInfo->s16LastPwmPIDCalculate + fPWMIncrease) > 100)
|
|
{
|
|
u8Pwm = 100;
|
|
}
|
|
else
|
|
{
|
|
u8Pwm = (INT8U)(psFscCLSensorInfo->s16LastPwmPIDCalculate + fPWMIncrease + 0.5);
|
|
}
|
|
|
|
if(0 == s8ReadingT2)
|
|
{
|
|
psFscCLSensorInfo->u8SensorNoReading = 1;
|
|
}
|
|
else
|
|
{
|
|
psFscCLSensorInfo->u8SensorNoReading = 0;
|
|
}
|
|
|
|
psFscCLSensorInfo->fPIncrement = fPIncrement;
|
|
psFscCLSensorInfo->fIIncrement = fIIncrement;
|
|
psFscCLSensorInfo->fDIncrement = fDIncrement;
|
|
|
|
/*judge if greater than max pwm */
|
|
if(u8Pwm >= u8MaxPwm)
|
|
{
|
|
u8Pwm = u8MaxPwm;
|
|
}
|
|
|
|
/*judge if less than max pwm */
|
|
if(u8Pwm <= u8MinPwm)
|
|
{
|
|
u8Pwm = u8MinPwm;
|
|
}
|
|
|
|
psFscCLSensorInfo->u8PwmPIDCalculate = u8Pwm;
|
|
psFscCLSensorInfo->s16LastPwmPIDCalculate = (INT16S)u8Pwm;
|
|
|
|
/*Calculate pwm after weighting*/
|
|
for(u8FanIndex = 0; u8FanIndex < MAX_FSC_PWM_CHANNEL; u8FanIndex++)
|
|
{
|
|
psFscCLSensorInfo->u8PwmAfterWeighting[u8FanIndex] = (INT8U)((float)u8Pwm * ((float)psFscCLSensorInfo->au8FanWeight[u8FanIndex] / 100));
|
|
}
|
|
|
|
/*Calculate pwm after hysteresis*/
|
|
for(u8FanIndex = 0; u8FanIndex < MAX_FSC_PWM_CHANNEL; u8FanIndex++)
|
|
{
|
|
if(psFscCLSensorInfo->u32CalculateTick < (MAX_FAN_AVERAGE_COUNT-1))
|
|
{
|
|
psFscCLSensorInfo->u8PwmAfterWeightingCache[u8FanIndex][psFscCLSensorInfo->u32CalculateTick] = psFscCLSensorInfo->u8PwmAfterWeighting[u8FanIndex];
|
|
}
|
|
else
|
|
{
|
|
if(MAX_FAN_AVERAGE_COUNT == psFscCLSensorInfo->u32CalculateTick)
|
|
{
|
|
psFscCLSensorInfo->u8PwmAfterWeightingCache[u8FanIndex][MAX_FAN_AVERAGE_COUNT-1] = psFscCLSensorInfo->u8PwmAfterWeighting[u8FanIndex];
|
|
}
|
|
else
|
|
{
|
|
for(u8HysteresisIndex = 0; u8HysteresisIndex < (MAX_FAN_AVERAGE_COUNT - 1); u8HysteresisIndex++)
|
|
{
|
|
psFscCLSensorInfo->u8PwmAfterWeightingCache[u8FanIndex][u8HysteresisIndex] = psFscCLSensorInfo->u8PwmAfterWeightingCache[u8FanIndex][u8HysteresisIndex+1];
|
|
}
|
|
psFscCLSensorInfo->u8PwmAfterWeightingCache[u8FanIndex][MAX_FAN_AVERAGE_COUNT-1] = psFscCLSensorInfo->u8PwmAfterWeighting[u8FanIndex];
|
|
|
|
}
|
|
|
|
s16PwmSum = 0;
|
|
if(psFscCLSensorInfo->u8Hysteresis != 0)
|
|
{
|
|
for(u8HysteresisIndex = 0; u8HysteresisIndex < psFscCLSensorInfo->u8Hysteresis; u8HysteresisIndex++)
|
|
{
|
|
s16PwmSum += psFscCLSensorInfo->u8PwmAfterWeightingCache[u8FanIndex][MAX_FAN_AVERAGE_COUNT-1-u8HysteresisIndex];
|
|
}
|
|
|
|
psFscCLSensorInfo->u8PwmAfterHysteresis[u8FanIndex] = s16PwmSum / psFscCLSensorInfo->u8Hysteresis;
|
|
}
|
|
else
|
|
{
|
|
psFscCLSensorInfo->u8PwmAfterHysteresis[u8FanIndex] = psFscCLSensorInfo->u8PwmAfterWeightingCache[u8FanIndex][(MAX_FAN_AVERAGE_COUNT - 1)];
|
|
}
|
|
}
|
|
}
|
|
|
|
psFscCLSensorInfo->u32CalculateTick ++;
|
|
return FUNC_OK;
|
|
}
|
|
|
|
|
|
EFuncRetCode LuxFSCHandleCloseloop(SFscInfo* psFscInfo)
|
|
{
|
|
INT8U u8SensorIndex = 0;
|
|
SFscCLSensorInfo* psFscCLSensorInfo = NULL;
|
|
INT32U u32Tick = 0;
|
|
|
|
u32Tick = psFscInfo->sFscRunningInfo.u32Tick;
|
|
for(u8SensorIndex = 0; u8SensorIndex < psFscInfo->sFscCLSensor.u8TotalCLSensor; u8SensorIndex++)
|
|
{
|
|
psFscCLSensorInfo = &psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex];
|
|
|
|
if(0 != LuxStrncmp(psFscCLSensorInfo->acCLSensorStatus, "Enable", LuxStrlen("Enable")))
|
|
{
|
|
/*LuxPrintf("Closeloop sensor %s is not enable, skip\n",psFscCLSensorInfo->acSensorName);*/
|
|
psFscCLSensorInfo->u8PwmPIDCalculate = 0;
|
|
continue;
|
|
}
|
|
|
|
/*every sensor has it's polling cycles */
|
|
if(0 == (u32Tick % psFscCLSensorInfo->u8DT))
|
|
{
|
|
if(FSC_SENSOR_NOT_PRESENT == psFscCLSensorInfo->u8Present)
|
|
{
|
|
/*no need to do fsc control if sensor is not present */
|
|
/*LuxPrintf("Sensor %s no need to do fsc control because sensor is not preset\n",psFscCLSensorInfo->acSensorName);*/
|
|
psFscCLSensorInfo->u8PwmPIDCalculate=0;
|
|
continue;
|
|
}
|
|
|
|
/*if sensor status is abnormal, skip calculate pwm. Abnormal event handle it. */
|
|
if(FSC_SENSOR_ABNORMAL == psFscCLSensorInfo->u8Abnormal)
|
|
{
|
|
/*LuxPrintf("Sensor %s is abnormal, skip.\n",psFscCLSensorInfo->acSensorName);*/
|
|
psFscCLSensorInfo->u8PwmPIDCalculate = 0;
|
|
continue;
|
|
}
|
|
|
|
/*Closeloop sensor cache reading need >= 3, because PID need sensor reading at t-2, t-1, t. if buffer is not full, skip*/
|
|
if(SENSOR_REAL_VALUE_INITIAL == psFscCLSensorInfo->as8RealValue[MAX_READING_CACHE - 1])
|
|
{
|
|
/*LuxPrintf("Sensor %s reading cache is less than 3, skip.\n",psFscCLSensorInfo->acSensorName);*/
|
|
psFscCLSensorInfo->u8PwmPIDCalculate = 0;
|
|
continue;
|
|
}
|
|
|
|
/*lookup true setpoint */
|
|
LuxFSCGetTureSetpoint(psFscCLSensorInfo);
|
|
|
|
/*lookup true PID parameter from e and ec array */
|
|
LuxFSCGetTruePID(psFscCLSensorInfo, psFscInfo->sFscCLSensor.u8CLSensorESection, psFscInfo->sFscCLSensor.u8CLSensorECSection);
|
|
|
|
/*do openloop sensor pwm calculate */
|
|
LuxFSCCloseloopCalculateDuty(psFscCLSensorInfo, psFscInfo->sFscFanConfig.u8MaxFanDuty, psFscInfo->sFscFanConfig.u8MinFanDuty);
|
|
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
return FUNC_OK;
|
|
}
|
|
|
|
EFuncRetCode LuxSetCPLDHeatPWM(INT8U u8PwmNumber, INT8U u8DutycycleValue)
|
|
{
|
|
INT8U au8WriteData[32] = {0};
|
|
INT8U u8WriteLen = 0;
|
|
INT8U au8ReadBuf[32] = {0};
|
|
INT8U u8ReadLen = 0;
|
|
|
|
/*if setpoint is 40, turn off heat pwm */
|
|
if(40 == psFscInfo.sFscCLSensor.asFscCLSensorInfo[0].s8Setpoint)
|
|
{
|
|
u8DutycycleValue = 0;
|
|
}
|
|
au8WriteData[0] = sSFscHeatReg[u8PwmNumber].u16Reg;
|
|
au8WriteData[1] = 0x00;
|
|
au8WriteData[2] = u8DutycycleValue;
|
|
u8WriteLen = 3;
|
|
if(FUNC_FAILED == i2cReadWrite(FCB_I2C_BUS, FCB_CPLD_SLAVE_ADDR, au8WriteData, u8WriteLen, au8ReadBuf, u8ReadLen))
|
|
{
|
|
LuxPrintf("Write FCB data fail\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
//LuxPrintf("Write CPLD Reg 0x%x Data 0x%x \n",au8WriteData[0], u8DutycycleValue);
|
|
}
|
|
return FUNC_OK;
|
|
}
|
|
|
|
EFuncRetCode LuxSetCPLDFanPWM(INT8U u8PwmNumber, INT8U u8DutycycleValue)
|
|
{
|
|
char acCmdbuff[512] = {0};
|
|
EFuncRetCode eRet;
|
|
INT8U u8Reg = 0x00;
|
|
u8Reg = sSFscFanReg[u8PwmNumber].u16Reg;
|
|
|
|
LuxSprintf(acCmdbuff, "i2ctransfer -y -a %d w3@0x%x 0x%x 0x00 0x%x",FCB_I2C_BUS, \
|
|
FCB_CPLD_SLAVE_ADDR, u8Reg, u8DutycycleValue);
|
|
|
|
//LuxPrintf("LuxSetFCBPWM : %s\n",acCmdbuff);
|
|
eRet = LuxSystem(acCmdbuff);
|
|
return FUNC_OK;
|
|
}
|
|
|
|
int LuxCoverHighTempProtect(INT8U u8PwmChannel)
|
|
{
|
|
INT8U u8DIMMIndex = 0;
|
|
static INT8U u8OverTempDelay[MAX_DIMM_SLOT] = {0};
|
|
|
|
if(psFscInfo.sFscRunningInfo.u8MaxCoverTemp > 120)
|
|
{
|
|
u8OverTempDelay[u8PwmChannel] ++;
|
|
if(u8OverTempDelay[u8PwmChannel] >= 10)
|
|
{
|
|
//LuxPrintf("Cover temperature is over 100, turn off all PTC heat, u8OverTempDelay = %d!!!\n",u8OverTempDelay[u8PwmChannel]);
|
|
return TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
u8OverTempDelay[u8PwmChannel] = 0;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
EFuncRetCode LuxFSCOutputPWM(INT8U u8PwmChannel, INT8U u8Pwm)
|
|
{
|
|
if(u8Pwm >= PTC_HEAT_MAX_PWM)
|
|
{
|
|
u8Pwm = PTC_HEAT_MAX_PWM;
|
|
}
|
|
|
|
if(60 <= psFscInfo.sFscCLSensor.asFscCLSensorInfo[0].s8Setpoint)
|
|
{
|
|
if(u8Pwm <= PTC_PRE_HEAT_MIN_PWM)
|
|
{
|
|
u8Pwm = PTC_PRE_HEAT_MIN_PWM;
|
|
}
|
|
|
|
/*CPU0 DIMM-A, CPU0 DIMM-F, CPU0 DIMM-L, CPU1 DIMM-F, CPU1 DIMM-G, CPU1 DIMM-L minumum heat pwm set to 50% */
|
|
if((0 == u8PwmChannel) || (5 == u8PwmChannel) || (11 == u8PwmChannel) \
|
|
|| (17 == u8PwmChannel) || (18 == u8PwmChannel) || (23 == u8PwmChannel))
|
|
{
|
|
if(u8Pwm <= 100)
|
|
{
|
|
u8Pwm = 100;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(TRUE == LuxCoverHighTempProtect(u8PwmChannel))
|
|
{
|
|
u8Pwm = 0;
|
|
}
|
|
|
|
if(1 == psFscInfo.sFscCLSensor.asFscCLSensorInfo[u8PwmChannel].u8SensorNoReading)
|
|
{
|
|
u8Pwm = 0;
|
|
}
|
|
|
|
if(TRUE == g_u8FSCPresent)
|
|
{
|
|
if(FUNC_FAILED == LuxSetCPLDHeatPWM(u8PwmChannel, u8Pwm))
|
|
{
|
|
LuxPrintf("Set FCB CPLD cover heat pwm %d dutycycle to %d failed\n",u8PwmChannel, u8Pwm);
|
|
return FUNC_FAILED;
|
|
}
|
|
}
|
|
return FUNC_OK;
|
|
}
|
|
|
|
EFuncRetCode LuxFSCGetCoverTemp(INT8U* pu8Value, INT8U* pu8Present, INT8U* pu8Status)
|
|
{
|
|
INT8U au8WriteData[32] = {0};
|
|
INT8U u8WriteLen = 0;
|
|
INT8U au8ReadBuf[32] = {0};
|
|
INT8U u8ReadLen = 0;
|
|
INT8U u8CoverTempSensorIndex = 0;
|
|
INT8U u8SensorTemp = 0;
|
|
INT8U u8CoverMaxTemp = 0;
|
|
|
|
for(u8CoverTempSensorIndex = 0; u8CoverTempSensorIndex < 4; u8CoverTempSensorIndex++)
|
|
{
|
|
u8SensorTemp = 0;
|
|
au8WriteData[0] = (u8CoverTempSensorIndex + 1); //TMP468 sensor channel count from 1
|
|
u8WriteLen = 1;
|
|
u8ReadLen = 2;
|
|
if(FUNC_FAILED == i2cReadWrite(FCB_I2C_BUS, FCB_TMP468_ADDR >> 1, au8WriteData, u8WriteLen, au8ReadBuf, u8ReadLen))
|
|
{
|
|
LuxPrintf("Read Cover TMP468 channel %d fail\n",u8CoverTempSensorIndex);
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if(0 == (au8ReadBuf[0] & 0x80))
|
|
{
|
|
u8SensorTemp = (INT8U)((((INT16U)((au8ReadBuf[0] << 8) + au8ReadBuf[1])) >> 3) * 0.0625);
|
|
//LuxPrintf("Channel %d temp = %d\n",u8CoverTempSensorIndex+1, u8SensorTemp);
|
|
if(u8CoverMaxTemp < u8SensorTemp)
|
|
{
|
|
u8CoverMaxTemp = u8SensorTemp;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
*pu8Value = u8CoverMaxTemp;
|
|
*pu8Present = TRUE;
|
|
return FUNC_OK;
|
|
}
|
|
|
|
EFuncRetCode LuxFSCCoverMaxTemp(SFscInfo* psFscInfo)
|
|
{
|
|
INT8U u8DIMMIndex = 0;
|
|
INT8U u8Status = 0;
|
|
INT8U u8Present = 0;
|
|
INT8S s8Temp = 0;
|
|
|
|
if(FUNC_FAILED != LuxFSCGetCoverTemp(&psFscInfo->sFscRunningInfo.u8MaxCoverTemp, &u8Present, &u8Status))
|
|
{
|
|
//LuxPrintf("Cover max temp = %d\n",u8CoverTemp);
|
|
}
|
|
|
|
return FUNC_OK;
|
|
}
|
|
|
|
EFuncRetCode LuxFSCCoverPreHeat(SFscInfo* psFscInfo)
|
|
{
|
|
INT8U u8DIMMIndex = 0;
|
|
INT8U u8CoverTemp = 0;
|
|
INT8U u8Status = 0;
|
|
INT8U u8Present = 0;
|
|
INT8S s8Temp = 0;
|
|
|
|
if(FUNC_FAILED == LuxFSCGetPreHeatTempFromFile(&s8Temp))
|
|
{
|
|
s8Temp = COVER_PRE_HEAT_TEMP;
|
|
}
|
|
|
|
if(FUNC_FAILED != LuxFSCGetCoverTemp(&u8CoverTemp, &u8Present, &u8Status))
|
|
{
|
|
//LuxPrintf("Cover max temp = %d\n",u8CoverTemp);
|
|
if(u8CoverTemp < s8Temp)
|
|
{
|
|
/*when set pwm to heat, need set dimm fan to keep air flowing,so set dimm fan to 37% pwm */
|
|
for(u8DIMMIndex = 0; u8DIMMIndex < MAX_DIMM_SLOT; u8DIMMIndex++)
|
|
{
|
|
LuxSetCPLDHeatPWM(u8DIMMIndex, PTC_PRE_HEAT_PWM);
|
|
LuxSetCPLDFanPWM(u8DIMMIndex, DIMM_FAN_MIN_PWM);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LuxSetCPLDHeatPWM(u8DIMMIndex, 0);
|
|
LuxSetCPLDFanPWM(u8DIMMIndex, 0);
|
|
}
|
|
}
|
|
|
|
return FUNC_OK;
|
|
}
|
|
|
|
|
|
EFuncRetCode LuxFSCHandlePwmOut(SFscInfo* psFscInfo)
|
|
{
|
|
INT8U u8SensorIndex = 0;
|
|
INT8U u8PwmIndex = 0;
|
|
INT8U u8OLPwm = 0;
|
|
INT8U u8AbnormalPwm = 0;
|
|
INT8U u8AbnormalSensorIncreasePwm = 0;
|
|
INT8U u8IncreasePwm[MAX_FSC_PWM_CHANNEL] = {0};
|
|
INT8U au8CLPwm[MAX_FSC_PWM_CHANNEL] = {0};
|
|
INT8U au8PwmTemp[MAX_FSC_PWM_CHANNEL] = {0};
|
|
char acOLMaxPwmSensorName[MAX_SENSOR_NAME_LENGTH] = {0};
|
|
char acCLMaxPwmSensorName[MAX_SENSOR_NAME_LENGTH] = {0};
|
|
char acMaxAbnormalPwmSensorName[MAX_SENSOR_NAME_LENGTH] = {0};
|
|
|
|
/*step 1, get closeloop sensor pwm output */
|
|
for(u8PwmIndex = 0; u8PwmIndex < MAX_FSC_PWM_CHANNEL; u8PwmIndex++)
|
|
{
|
|
for(u8SensorIndex = 0; u8SensorIndex < psFscInfo->sFscCLSensor.u8TotalCLSensor; u8SensorIndex++)
|
|
{
|
|
if(psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].u8PwmAfterHysteresis[u8PwmIndex] > au8CLPwm[u8PwmIndex])
|
|
{
|
|
au8CLPwm[u8PwmIndex] = psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].u8PwmAfterHysteresis[u8PwmIndex];
|
|
LuxMemset(acCLMaxPwmSensorName, 0, MAX_SENSOR_NAME_LENGTH);
|
|
memcpy(acCLMaxPwmSensorName, psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].acSensorName, \
|
|
LuxStrlen(psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].acSensorName));
|
|
}
|
|
}
|
|
}
|
|
LuxMemcpy(psFscInfo->sFscRunningInfo.au8CLPwm,au8CLPwm, MAX_FSC_PWM_CHANNEL);
|
|
|
|
/*step 2, output auto pwm */
|
|
for(u8PwmIndex = 0; u8PwmIndex < MAX_FSC_PWM_CHANNEL; u8PwmIndex++)
|
|
{
|
|
psFscInfo->sFscRunningInfo.au8PwmOut[u8PwmIndex] = psFscInfo->sFscRunningInfo.au8CLPwm[u8PwmIndex];
|
|
if(psFscInfo->sFscRunningInfo.au8PwmOut[u8PwmIndex] > psFscInfo->sFscFanConfig.u8MaxFanDuty)
|
|
{
|
|
psFscInfo->sFscRunningInfo.au8PwmOut[u8PwmIndex] = psFscInfo->sFscFanConfig.u8MaxFanDuty;
|
|
}
|
|
if(psFscInfo->sFscRunningInfo.au8PwmOut[u8PwmIndex] < psFscInfo->sFscFanConfig.u8MinFanDuty)
|
|
{
|
|
psFscInfo->sFscRunningInfo.au8PwmOut[u8PwmIndex] = psFscInfo->sFscFanConfig.u8MinFanDuty;
|
|
}
|
|
|
|
LuxFSCOutputPWM(u8PwmIndex, psFscInfo->sFscRunningInfo.au8PwmOut[u8PwmIndex]);
|
|
}
|
|
return FUNC_OK;
|
|
}
|
|
|
|
EFuncRetCode LuxFSCHandleCoverHeat(SFscInfo* psFscInfo)
|
|
{
|
|
#if 0
|
|
INT8U u8DIMMIndex = 0;
|
|
SFscCLSensorInfo* psFscCLSensorInfo = NULL;
|
|
|
|
for(u8DIMMIndex = 0; u8DIMMIndex < MAX_DIMM_SLOT; u8DIMMIndex++)
|
|
{
|
|
psFscCLSensorInfo = &psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8DIMMIndex];
|
|
|
|
/*if DIMM temperature lower than setpoint, need turn on heat*/
|
|
if(psFscCLSensorInfo->as8RealValue[MAX_READING_CACHE-1] < psFscCLSensorInfo->s8Setpoint)
|
|
{
|
|
LuxSetCPLDPTCHeatPWM(u8DIMMIndex, PTC_PRE_HEAT_MAX_PWM);
|
|
}
|
|
else
|
|
{
|
|
LuxSetCPLDPTCHeatPWM(u8DIMMIndex, PTC_PRE_HEAT_MIN_PWM);
|
|
}
|
|
|
|
}
|
|
#endif
|
|
return FUNC_OK;
|
|
}
|
|
|
|
|
|
EFuncRetCode LuxFSCHandleThermalDebug(SFscInfo* psFscInfo)
|
|
{
|
|
INT8U u8PwmIndex = 0;
|
|
INT8U u8SensorIndex = 0;
|
|
|
|
/*check if thermal debug message opened */
|
|
psFscInfo->sFscRunningInfo.u8ThermalDebug = FSC_OPEN_THERMAL_DEBUG;
|
|
if(FSC_OPEN_THERMAL_DEBUG == psFscInfo->sFscRunningInfo.u8ThermalDebug)
|
|
{
|
|
LuxPrintf("\t************************ Thermal Debug **********************\n");
|
|
LuxPrintf("\tpsFscInfo->sFscRunningInfo.u8ControlMode = %d\n",psFscInfo->sFscRunningInfo.u8ControlMode);
|
|
|
|
LuxPrintf("\tCloseloop:\n");
|
|
for(u8SensorIndex = 0; u8SensorIndex < psFscInfo->sFscCLSensor.u8TotalCLSensor; u8SensorIndex++)
|
|
{
|
|
LuxPrintf("\tCloseloop sensor %d name: %s\n",(u8SensorIndex+1), psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].acSensorName);
|
|
LuxPrintf("\tCloseloop sensor %d number: 0x%x\n",(u8SensorIndex+1), psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].u8SensorNumber);
|
|
LuxPrintf("\tCloseloop sensor %d u8Present: %d\n",(u8SensorIndex+1), psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].u8Present);
|
|
LuxPrintf("\tCloseloop sensor %d u8Abnormal: %d\n",(u8SensorIndex+1), psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].u8Abnormal);
|
|
LuxPrintf("\tCloseloop sensor %d u8Health: %d\n",(u8SensorIndex+1), psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].u8Health);
|
|
LuxPrintf("\tCloseloop sensor %d s8Setpoint: %d\n",(u8SensorIndex+1), psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].s8Setpoint);
|
|
LuxPrintf("\tCloseloop sensor %d p: %f\n",(u8SensorIndex+1), psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].fP);
|
|
LuxPrintf("\tCloseloop sensor %d i: %f\n",(u8SensorIndex+1), psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].fI);
|
|
LuxPrintf("\tCloseloop sensor %d d: %f\n",(u8SensorIndex+1), psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].fD);
|
|
LuxPrintf("\tCloseloop sensor %d reading: %d,%d,%d\n",(u8SensorIndex+1), psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].as8RealValue[MAX_READING_CACHE - 3],\
|
|
psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].as8RealValue[MAX_READING_CACHE - 2],\
|
|
psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].as8RealValue[MAX_READING_CACHE - 1]);
|
|
LuxPrintf("\tCloseloop sensor %d s16LastPwmPIDCalculate: %d\n\n",(u8SensorIndex+1), psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].s16LastPwmPIDCalculate);
|
|
LuxPrintf("\tCloseloop sensor %d fPIncrement: %f\n",(u8SensorIndex+1), psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].fPIncrement);
|
|
LuxPrintf("\tCloseloop sensor %d fIIncrement: %f\n",(u8SensorIndex+1), psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].fIIncrement);
|
|
LuxPrintf("\tCloseloop sensor %d fDIncrement: %f\n",(u8SensorIndex+1), psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].fDIncrement);
|
|
LuxPrintf("\tCloseloop sensor %d u8PwmPIDCalculate: %d\n",(u8SensorIndex+1), psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].u8PwmPIDCalculate);
|
|
LuxPrintf("\tCloseloop sensor %d u8PwmAfterWeighting:",(u8SensorIndex+1));
|
|
for(u8PwmIndex = 0; u8PwmIndex < MAX_FSC_PWM_CHANNEL; u8PwmIndex++)
|
|
{
|
|
LuxPrintf("%d ",psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].u8PwmAfterWeighting[u8PwmIndex]);
|
|
}
|
|
LuxPrintf("\n");
|
|
|
|
LuxPrintf("\tCloseloop sensor %d u8PwmAfterHysteresis:",(u8SensorIndex+1));
|
|
for(u8PwmIndex = 0; u8PwmIndex < MAX_FSC_PWM_CHANNEL; u8PwmIndex++)
|
|
{
|
|
LuxPrintf("%d ",psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].u8PwmAfterHysteresis[u8PwmIndex]);
|
|
}
|
|
LuxPrintf("\n");
|
|
|
|
LuxPrintf("\tCloseloop sensor %d u8PwmAfterHysteresis:",(u8SensorIndex+1));
|
|
for(u8PwmIndex = 0; u8PwmIndex < MAX_FSC_PWM_CHANNEL; u8PwmIndex++)
|
|
{
|
|
LuxPrintf("%d ",psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].u8PwmAfterHysteresis[u8PwmIndex]);
|
|
}
|
|
LuxPrintf("\n\n");
|
|
}
|
|
|
|
LuxPrintf("\tFinally output:\n");
|
|
for(u8PwmIndex = 0; u8PwmIndex < MAX_FSC_PWM_CHANNEL; u8PwmIndex++)
|
|
{
|
|
LuxPrintf("\tpwm channel %d output: %d\n",u8PwmIndex,psFscInfo->sFscRunningInfo.au8PwmOut[u8PwmIndex]);
|
|
}
|
|
for(u8PwmIndex = 0; u8PwmIndex < MAX_FSC_PWM_CHANNEL; u8PwmIndex++)
|
|
{
|
|
LuxPrintf("\tManual output: %d\n",psFscInfo->sFscRunningInfo.au8ManualPwmOut[u8PwmIndex]);
|
|
}
|
|
}
|
|
|
|
return FUNC_OK;
|
|
}
|
|
|
|
EFuncRetCode LuxFSCGetManualValue(INT8U* pu8Value)
|
|
{
|
|
FILE* fp = NULL;
|
|
char acCmdbuff[512] = {0};
|
|
char acCmdstr[1024] = {0};
|
|
INT8U u8ManualValue = 0;
|
|
|
|
LuxSprintf(acCmdstr, "cat %s",COVER_MANUAL_CONTROL_VALUE);
|
|
|
|
if ((fp = LuxPopen(acCmdstr, "r")) != NULL)
|
|
{
|
|
fgets(acCmdbuff, sizeof(acCmdbuff), fp);
|
|
LuxPclose(fp);
|
|
acCmdbuff[strcspn(acCmdbuff, "\n")] = 0;
|
|
if (acCmdbuff[0] == '0' && acCmdbuff[1] == 'x')
|
|
{
|
|
u8ManualValue = (INT8U)strtol(acCmdbuff, NULL, 10);
|
|
printf("u8ManualValue= %d\n",u8ManualValue);
|
|
}
|
|
else
|
|
{
|
|
printf("LuxFSCGetCoverTemp get error : %s\n", acCmdbuff);
|
|
}
|
|
*pu8Value = u8ManualValue;
|
|
return FUNC_OK;
|
|
}
|
|
else
|
|
{
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
}
|
|
|
|
EFuncRetCode LuxFSCGetEnableStatus(INT8U* pu8Value)
|
|
{
|
|
FILE* fp = NULL;
|
|
char acCmdbuff[512] = {0};
|
|
char acCmdstr[1024] = {0};
|
|
INT8U u8Value = 0;
|
|
|
|
if(0 != LuxAccess(FSC_ENABLE_STATUS_PATH, F_OK))
|
|
{
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
LuxSprintf(acCmdstr, "cat %s",FSC_ENABLE_STATUS_PATH);
|
|
if ((fp = LuxPopen(acCmdstr, "r")) != NULL)
|
|
{
|
|
fgets(acCmdbuff, sizeof(acCmdbuff), fp);
|
|
u8Value = strtoul(acCmdbuff, NULL, 10);
|
|
LuxPclose(fp);
|
|
if (u8Value > 1)
|
|
{
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
*pu8Value = (INT8U)u8Value;
|
|
return FUNC_OK;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
return FUNC_OK;
|
|
}
|
|
|
|
EFuncRetCode LuxCheckFCBPresent()
|
|
{
|
|
INT8U au8WriteData[32] = {0};
|
|
INT8U u8WriteLen = 0;
|
|
INT8U au8ReadBuf[32] = {0};
|
|
INT8U u8ReadLen = 0;
|
|
|
|
au8WriteData[0] = 0x05;
|
|
au8WriteData[1] = 0x00;
|
|
u8WriteLen = 2;
|
|
u8ReadLen = 1;
|
|
if(FUNC_FAILED == i2cReadWrite(FCB_I2C_BUS, FCB_CPLD_SLAVE_ADDR, au8WriteData, u8WriteLen, au8ReadBuf, u8ReadLen))
|
|
{
|
|
LuxPrintf("FCB is not present!!!\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
else
|
|
{
|
|
LuxPrintf("FCB is present.\n");
|
|
}
|
|
return FUNC_OK;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
INT32U u32Tick = 0;
|
|
|
|
LuxPrintf("******************************************************************************\n");
|
|
LuxPrintf("************************ Luxshare Cover FSC Task Begin ***********************\n");
|
|
LuxPrintf("******************************************************************************\n");
|
|
LuxFSCInit();
|
|
INT8U u8ManualValue = 0;
|
|
INT8U u8FSCEnable = 0;
|
|
INT8U u8DIMMFSCChannnel = 0;
|
|
EFuncRetCode eRet;
|
|
|
|
if(FUNC_OK == LuxCheckFCBPresent())
|
|
{
|
|
g_u8FSCPresent = TRUE;
|
|
}
|
|
|
|
while(1)
|
|
{
|
|
usleep(200*1000);
|
|
INT8U u8PwmChannel = 0;
|
|
|
|
/*Check fan table update flag. */
|
|
LuxFSCFanTableUpdate(&psFscInfo);
|
|
|
|
/*if fan table load fail, return error */
|
|
if(FSC_FAN_TABLE_LOAD_FAIL == psFscInfo.sFscRunningInfo.u8FanTableLoadStatus)
|
|
{
|
|
LuxPrintf("Fan table load fail, return error.\n");
|
|
return FUNC_FAILED;
|
|
}
|
|
|
|
/*Check cover heat enable status, if not enable by OEM command, don't do all cover heat logic and turn off heat*/
|
|
eRet = LuxFSCGetEnableStatus(&u8FSCEnable);
|
|
if((FUNC_FAILED == eRet) || (0 == u8FSCEnable))
|
|
{
|
|
if(TRUE == g_u8FSCPresent)
|
|
{
|
|
for(u8DIMMFSCChannnel = 0; u8DIMMFSCChannnel < 24; u8DIMMFSCChannnel++)
|
|
{
|
|
if(FUNC_FAILED == LuxSetCPLDHeatPWM(u8DIMMFSCChannnel, 0))
|
|
{
|
|
LuxPrintf("Set FCB CPLD cover heat pwm %d dutycycle to %d failed\n",u8DIMMFSCChannnel, 0);
|
|
return FUNC_FAILED;
|
|
}
|
|
}
|
|
}
|
|
continue;
|
|
}
|
|
|
|
/*Check if manual control */
|
|
if(0 == LuxAccess(COVER_MANUAL_CONTROL_FLAG, F_OK))
|
|
{
|
|
if(FUNC_OK == LuxFSCGetManualValue(&u8ManualValue))
|
|
{
|
|
for(u8PwmChannel = 0; u8PwmChannel < MAX_FSC_PWM_CHANNEL; u8PwmChannel++)
|
|
{
|
|
LuxFSCOutputPWM(u8PwmChannel, u8ManualValue);
|
|
}
|
|
}
|
|
return FUNC_OK;
|
|
}
|
|
|
|
/*check if power on in 120 seconds */
|
|
if(PS_GOOD_OK == LuxPDKGetPSGood())
|
|
{
|
|
//LuxPrintf("PSGood is on\n");
|
|
psFscInfo.sFscRunningInfo.u32Tick ++;
|
|
if(psFscInfo.sFscRunningInfo.u32Tick < POWERON_FSC_DELAY)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if(TRUE == g_u8FSCPresent)
|
|
{
|
|
LuxFSCCoverMaxTemp(&psFscInfo);
|
|
}
|
|
|
|
/*Get sensor status and reading every second */
|
|
LuxFSCGetSensorStatus(&psFscInfo);
|
|
|
|
/*Handle closeloop sensor */
|
|
LuxFSCHandleCloseloop(&psFscInfo);
|
|
|
|
/*Handle output pwm */
|
|
LuxFSCHandlePwmOut(&psFscInfo);
|
|
|
|
/*Handle high-temperature Cover heat */
|
|
LuxFSCHandleCoverHeat(&psFscInfo);
|
|
|
|
/*Handle thermal debug */
|
|
//LuxFSCHandleThermalDebug(&psFscInfo);
|
|
}
|
|
return 0;
|
|
}
|