Files
OpenBMC/meta-luxshare/meta-bhs/recipes-oem/oem-fsc/dimm-fsc/dimm_fsc.c
T
2026-04-23 17:07:55 +08:00

2998 lines
94 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 "dimm_fsc.h"
#include <dbus/dbus.h>
#include <stddef.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <time.h>
SFscInfo psFscInfo;
INT8U g_u8FSCPresent = FALSE;
INT8U g_u8FSCEnable = 0;
INT8U g_u8DIMMHighTempProtect = 0;
#if 0
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},
};
#endif
SFscFanReg sSFscFanReg[MAX_DIMM_SLOT] =
{
{0, 0x0064},
{1, 0x0065},
{2, 0x0066},
{3, 0x0067},
{4, 0x0068},
{5, 0x0069},
{6, 0x005e},
{7, 0x005f},
{8, 0x0060},
{9, 0x0061},
{10, 0x0062},
{11, 0x0063},
{12, 0x0058},
{13, 0x0059},
{14, 0x005a},
{15, 0x005b},
{16, 0x005c},
{17, 0x005d},
{18, 0x0052},
{19, 0x0053},
{20, 0x0054},
{21, 0x0055},
{22, 0x0056},
{23, 0x0057},
};
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},
};
#if 0
SFsc6056FanReg sFsc6056FanReg[FCB_6056_FAN_NUM] =
{
{0, 0x008f},
{1, 0x0090},
{2, 0x0091},
{3, 0x0092},
};
#endif
SFsc6056FanReg sFsc6056FanReg[FCB_6056_FAN_NUM] =
{
{0, 0x0092},
{1, 0x0091},
{2, 0x0090},
{3, 0x008f},
};
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"},
};
SDIMMPowerDbus sSDIMMPowerDbus[MAX_DIMM_POWER_SLOT] =
{
{0, "/xyz/openbmc_project/sensors/power/DDR0_Power"},
{1, "/xyz/openbmc_project/sensors/power/DDR1_Power"},
{2, "/xyz/openbmc_project/sensors/power/DDR2_Power"},
{3, "/xyz/openbmc_project/sensors/power/DDR3_Power"},
};
SCPUDbus sSCPUDbus[2] =
{
{0, "/xyz/openbmc_project/sensors/temperature/CPU0_Temp"},
{1, "/xyz/openbmc_project/sensors/temperature/CPU1_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, double* pdValue, 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);
*pdValue = 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 LuxFSCDbusGetCPUValue(char* pcDbusPatch, double* pdValue, INT8U* pu8Present, INT8U* pu8Status)
{
const char *bus_name = "xyz.openbmc_project.IntelCPUSensor";
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);
*pdValue = 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 LuxFSCDbusGetDIMMPowerValue(char* pcDbusPatch, double* pdValue, INT8U* pu8Present, INT8U* pu8Status)
{
const char *bus_name = "xyz.openbmc_project.PSUSensor";
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);
*pdValue = 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 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 LuxFSCGetFSCControlMode(SFscInfo* psFscInfo)
{
SFscControlMode sFscControlMode;
FILE* fp = NULL;
char acCmdbuff[512] = {0};
char acCmdstr[1024] = {0};
INT8U u8Value = 0;
if(0 != LuxAccess(FSC_CONTROL_MODE, F_OK))
{
psFscInfo->sFscRunningInfo.u8ControlMode = FSC_FAN_TABLE_AUTO;
return FUNC_FAILED;
}
/*Read FSC configuration*/
fp = LuxFopen(FSC_CONTROL_MODE, "rb");
if(NULL == fp)
{
LuxPrintf("Error: LuxFopen %s Failed\n", FSC_CONTROL_MODE);
return FUNC_FAILED;
}
if(1 != LuxFread(&sFscControlMode, sizeof(SFscControlMode), 1, fp))
{
LuxPrintf("Error: LuxFread Failed\n");
LuxFclose(fp);
return FUNC_FAILED;
}
psFscInfo->sFscRunningInfo.u8ControlMode = sFscControlMode.u8ControlMode;
LuxMemcpy(psFscInfo->sFscRunningInfo.au8ManualPwmOut, sFscControlMode.u8PWM, MAX_FSC_PWM_CHANNEL);
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 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;
LuxFSCSetSetpointToFile(psFscInfo.sFscCLSensor.asFscCLSensorInfo[0].s8SetpointDefault);
LuxFSCSetSetpointToFile(psFscInfo.sFscCLSensor.asFscCLSensorInfo[0].s8SetpointDefault);
}
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;
double dSensorReading = 0;
INT8U u8Status = 0;
INT8U u8Present = 0;
double dGroupAMaxTemp = 0;
double dGroupAMinTemp = 0;
double dGroupBMaxTemp = 0;
double dGroupBMinTemp = 0;
double dGroupCMaxTemp = 0;
double dGroupCMinTemp = 0;
double dGroupDMaxTemp = 0;
double dGroupDMinTemp = 0;
/*Get closeloop sensor status and reading */
for(u8SensorIndex = 0; u8SensorIndex < psFscInfo->sFscCLSensor.u8TotalCLSensor ; u8SensorIndex++)
{
/*CPU0 DIMM temperature */
dSensorReading = 0;
u8Present = FSC_SENSOR_NOT_PRESENT;
u8Status = FSC_SENSOR_NORMAL;
if(u8SensorIndex < 24)
{
LuxFSCDbusGetDIMMValue(sSDIMMDbus[u8SensorIndex].acDbusPath, &dSensorReading, &u8Present, &u8Status);
if(u8SensorIndex < 6)
{
if(dSensorReading != 0)
{
if(dGroupAMaxTemp < dSensorReading)
{
dGroupAMaxTemp = dSensorReading;
psFscInfo->sFscRunningInfo.u8DIMMGroupMaxTemp[0] = dGroupAMaxTemp;
}
}
}
else if(u8SensorIndex < 12)
{
if(dSensorReading != 0)
{
if(dGroupBMaxTemp < dSensorReading)
{
dGroupBMaxTemp = dSensorReading;
psFscInfo->sFscRunningInfo.u8DIMMGroupMaxTemp[1] = dGroupBMaxTemp;
}
}
}
else if(u8SensorIndex < 18)
{
if(dSensorReading != 0)
{
if(dGroupCMaxTemp < dSensorReading)
{
dGroupCMaxTemp = dSensorReading;
psFscInfo->sFscRunningInfo.u8DIMMGroupMaxTemp[2] = dGroupCMaxTemp;
}
}
}
else if(u8SensorIndex < 24)
{
if(dSensorReading != 0)
{
if(dGroupDMaxTemp < dSensorReading)
{
dGroupDMaxTemp = dSensorReading;
psFscInfo->sFscRunningInfo.u8DIMMGroupMaxTemp[3] = dGroupDMaxTemp;
}
}
}
}
else
{
LuxFSCDbusGetCPUValue(sSCPUDbus[u8SensorIndex - MAX_DIMM_SLOT].acDbusPath, &dSensorReading, &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] = dSensorReading;
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] = dSensorReading;
}
}
}
//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 = 5;
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)
{
INT8U u8SetpointCase = 0;
INT8S s8Setpoint = 0;
/* Search setpoint */
if(0 == LuxStrncmp(psFscCLSensorInfo->acSetpointType, SETPOINT_CONSTANT, LuxStrlen(SETPOINT_CONSTANT)))
{
if(u8SensorIndex < MAX_DIMM_SLOT)
{
if(FUNC_FAILED == LuxFSCGetSetpointFromFile(&s8Setpoint))
{
psFscCLSensorInfo->s8Setpoint = psFscCLSensorInfo->s8SetpointDefault;
}
else
{
psFscCLSensorInfo->s8Setpoint = s8Setpoint;
}
}
else
{
psFscCLSensorInfo->s8Setpoint = psFscCLSensorInfo->s8SetpointDefault;
}
}
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)
{
double dReadingT = 0;
double dReadingT1 = 0;
double dReadingT2 = 0;
double dPIncrement = 0;
double fIIncrement = 0;
double fDIncrement = 0;
INT8U u8Pwm = 0;
INT8U u8FanIndex=0;
INT8U u8HysteresisIndex = 0;
INT16S s16PwmSum = 0;
float fPWMIncrease = 0;
/*get last three sensor readings */
dReadingT = psFscCLSensorInfo->as8RealValue[MAX_READING_CACHE - 3];
dReadingT1 = psFscCLSensorInfo->as8RealValue[MAX_READING_CACHE - 2];
dReadingT2 = psFscCLSensorInfo->as8RealValue[MAX_READING_CACHE - 1];
/*calculate pwm by PID formula */
dPIncrement = (float)(psFscCLSensorInfo->fP * (dReadingT2 - dReadingT1));
fIIncrement = (float)(psFscCLSensorInfo->fI * (dReadingT2 - psFscCLSensorInfo->s8Setpoint));
fDIncrement = (float)(psFscCLSensorInfo->fD * (dReadingT2 + dReadingT - 2*dReadingT1));
fPWMIncrease = dPIncrement + 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);
}
psFscCLSensorInfo->dPIncrement = dPIncrement;
psFscCLSensorInfo->dIIncrement = fIIncrement;
psFscCLSensorInfo->dDIncrement = 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, u8SensorIndex);
/*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 LuxSetCPLDPTCHeatPWM(INT8U u8PwmNumber, INT8U u8PTCPWM)
{
char acCmdbuff[512] = {0};
EFuncRetCode eRet;
LuxSprintf(acCmdbuff, "i2ctransfer -y -a %d w3@0x%x 0x%x 0x00 0x%x",FCB_I2C_BUS, \
FCB_CPLD_SLAVE_ADDR, (REG_FCB_PTC_DIMM0_SET_PWM + u8PwmNumber), u8PTCPWM);
LuxPrintf("LuxSetPTCHeatPWM : %s\n",acCmdbuff);
eRet = LuxSystem(acCmdbuff);
return eRet;
}
EFuncRetCode LuxSetCPLDPWM(INT8U u8PwmNumber, INT8U u8DutycycleValue)
{
INT8U au8WriteData[32] = {0};
INT8U u8WriteLen = 0;
INT8U au8ReadBuf[32] = {0};
INT8U u8ReadLen = 0;
au8WriteData[0] = sSFscFanReg[u8PwmNumber - MAX_MB_PWM_CHANNEL].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("Set DIMM Fan Write FCB data fail\n");
return FUNC_FAILED;
}
else
{
//LuxPrintf("Set DIMM Fan Write CPLD Reg 0x%x Data 0x%x \n",au8WriteData[0], u8DutycycleValue);
}
return FUNC_OK;
}
EFuncRetCode LuxSetCPLD6056FanPWM(INT8U u8PwmNumber, INT8U u8DutycycleValue)
{
INT8U au8WriteData[32] = {0};
INT8U u8WriteLen = 0;
INT8U au8ReadBuf[32] = {0};
INT8U u8ReadLen = 0;
au8WriteData[0] = sFsc6056FanReg[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("Set 6056 Fan Write FCB data fail\n");
return FUNC_FAILED;
}
else
{
//LuxPrintf("Set 6056 Fan Write CPLD Reg 0x%x Data 0x%x \n",au8WriteData[0], u8DutycycleValue);
}
if(0 == u8PwmNumber)
{
/*CPU0 A-F 6056 fan */
LuxSetCPLDPWM(5, u8DutycycleValue);
LuxSetCPLDPWM(6, u8DutycycleValue);
LuxSetCPLDPWM(7, u8DutycycleValue);
LuxSetCPLDPWM(8, u8DutycycleValue);
LuxSetCPLDPWM(9, u8DutycycleValue);
LuxSetCPLDPWM(10, u8DutycycleValue);
}
if(1 == u8PwmNumber)
{
/*CPU0 G-L 6056 fan */
LuxSetCPLDPWM(11, u8DutycycleValue);
LuxSetCPLDPWM(12, u8DutycycleValue);
LuxSetCPLDPWM(13, u8DutycycleValue);
LuxSetCPLDPWM(14, u8DutycycleValue);
LuxSetCPLDPWM(15, u8DutycycleValue);
LuxSetCPLDPWM(16, u8DutycycleValue);
}
if(2 == u8PwmNumber)
{
/*CPU1 A-F 6056 fan */
LuxSetCPLDPWM(17, u8DutycycleValue);
LuxSetCPLDPWM(18, u8DutycycleValue);
LuxSetCPLDPWM(19, u8DutycycleValue);
LuxSetCPLDPWM(20, u8DutycycleValue);
LuxSetCPLDPWM(21, u8DutycycleValue);
LuxSetCPLDPWM(22, u8DutycycleValue);
}
if(3 == u8PwmNumber)
{
/*CPU1 G-L 6056 fan */
LuxSetCPLDPWM(23, u8DutycycleValue);
LuxSetCPLDPWM(24, u8DutycycleValue);
LuxSetCPLDPWM(25, u8DutycycleValue);
LuxSetCPLDPWM(26, u8DutycycleValue);
LuxSetCPLDPWM(27, u8DutycycleValue);
LuxSetCPLDPWM(28, u8DutycycleValue);
}
return FUNC_OK;
}
EFuncRetCode LuxSetMBPWM(INT8U u8PwmNumber, INT8U u8DutycycleValue)
{
char acCmdbuff[512] = {0};
EFuncRetCode eRet;
/*MB pwm need change max 100 to max 255 */
u8DutycycleValue *= 2.55;
LuxSprintf(acCmdbuff, "echo %d > /sys/class/hwmon/hwmon0/pwm%d",u8DutycycleValue,(2 + u8PwmNumber));
eRet = LuxSystem(acCmdbuff);
return eRet;
}
EFuncRetCode LuxFSCOutputPWM(INT8U u8PwmChannel, INT8U u8Pwm)
{
if(u8Pwm >= 100)
{
u8Pwm = 100;
}
if(u8PwmChannel < MAX_MB_PWM_CHANNEL)
{
/*In mobile project, pwm 4 and pwm 5 is for liquid. force set to 100% */
if((3 == u8PwmChannel) || (4 == u8PwmChannel))
{
u8Pwm = 100;
}
else
{
if(u8Pwm < CPU_FAN_MIN_PWM)
{
u8Pwm = CPU_FAN_MIN_PWM;
}
}
if(FUNC_FAILED == LuxSetMBPWM(u8PwmChannel, u8Pwm))
{
LuxPrintf("Set MB pwm %d dutycycle to %d failed\n",u8PwmChannel, u8Pwm);
return FUNC_FAILED;
}
}
else
{
//LuxPrintf("u8MaxCoverTemp = %d\n",psFscInfo.sFscRunningInfo.u8MaxCoverTemp);
//LuxPrintf("u16DIMMTotalPower = %d\n",psFscInfo.sFscRunningInfo.u16DIMMTotalPower);
//LuxPrintf("u8MaxDIMMSensorTemp = %d\n",psFscInfo.sFscRunningInfo.u8MaxDIMMSensorTemp);
//LuxPrintf("psFscInfo.sFscCLSensor.asFscCLSensorInfo[0].s8Setpoint = %d\n",psFscInfo.sFscCLSensor.asFscCLSensorInfo[0].s8Setpoint);
if(60 <= psFscInfo.sFscCLSensor.asFscCLSensorInfo[0].s8Setpoint)
{
#if 0
if((psFscInfo.sFscRunningInfo.u8MaxCoverTemp < 60) && (psFscInfo.sFscRunningInfo.u16DIMMTotalPower < 150) && (psFscInfo.sFscRunningInfo.u8MaxDIMMSensorTemp < 68))
{
//LuxPrintf("Because Cover sensor temperature is very low, set DIMM fan to 0\n");
u8Pwm = 0;
}
else
{
if(u8Pwm < DIMM_FAN_MIN_PWM)
{
u8Pwm = DIMM_FAN_MIN_PWM;
}
}
#endif
if(u8Pwm < DIMM_FAN_MIN_PWM)
{
u8Pwm = DIMM_FAN_MIN_PWM;
}
}
if(0 == g_u8FSCEnable)
{
u8Pwm = 0;
}
#if 0
if(TRUE == g_u8FSCPresent)
{
if(FUNC_FAILED == LuxSetCPLDPWM(u8PwmChannel, u8Pwm))
{
LuxPrintf("Set FCB CPLD pwm %d dutycycle to %d failed\n",u8PwmChannel, u8Pwm);
return FUNC_FAILED;
}
}
#endif
}
return FUNC_OK;
}
EFuncRetCode LuxFSCManualOutputPWM(INT8U u8PwmChannel, INT8U u8Pwm)
{
if(u8PwmChannel < MAX_MB_PWM_CHANNEL)
{
if(FUNC_FAILED == LuxSetMBPWM(u8PwmChannel, u8Pwm))
{
LuxPrintf("Manual set MB pwm %d dutycycle to %d failed\n",u8PwmChannel, u8Pwm);
return FUNC_FAILED;
}
}
else
{
if(TRUE == g_u8FSCPresent)
{
if(FUNC_FAILED == LuxSetCPLDPWM(u8PwmChannel, u8Pwm))
{
LuxPrintf("Manual set FCB CPLD pwm %d dutycycle to %d failed\n",u8PwmChannel, u8Pwm);
return FUNC_FAILED;
}
}
}
return FUNC_OK;
}
EFuncRetCode LuxFSCCoverPreHeat(SFscInfo* psFscInfo)
{
INT8U u8DIMMIndex = 0;
for(u8DIMMIndex = 0; u8DIMMIndex < MAX_DIMM_SLOT; u8DIMMIndex++)
{
LuxSetCPLDPTCHeatPWM(u8DIMMIndex, PTC_PRE_HEAT_PWM);
}
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: %lf,%lf,%lf\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: %lf\n",(u8SensorIndex+1), psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].dPIncrement);
LuxPrintf("\tCloseloop sensor %d fIIncrement: %lf\n",(u8SensorIndex+1), psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].dIIncrement);
LuxPrintf("\tCloseloop sensor %d fDIncrement: %lf\n",(u8SensorIndex+1), psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].dDIncrement);
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 LuxPrintDIMMTemp(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************************ DIMM Temperature Print **********************\n");
for(u8SensorIndex = 0; u8SensorIndex < 24; u8SensorIndex++)
{
LuxPrintf("\tDIMM Temp sensor %d reading: %d\n",(u8SensorIndex+1),psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8SensorIndex].as8RealValue[MAX_READING_CACHE - 1]);
}
}
LuxPrintf("\n\n");
return FUNC_OK;
}
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;
}
EFuncRetCode LuxFSCGetDIMMTotalPower(SFscInfo* psFscInfo)
{
INT8U u8SensorIndex = 0;
double dSensorReading = 0;
INT8U u8Status = 0;
INT8U u8Present = 0;
INT16U u16Power = 0;
for(u8SensorIndex = 0; u8SensorIndex < MAX_DIMM_POWER_SLOT; u8SensorIndex++)
{
LuxFSCDbusGetDIMMPowerValue(sSDIMMPowerDbus[u8SensorIndex].acDbusPath, &dSensorReading, &u8Present, &u8Status);
//LuxPrintf("DIMMPower %d u8Power = %d\n",u8SensorIndex,s8SensorReading);
u16Power += (INT16U)dSensorReading;
}
psFscInfo->sFscRunningInfo.u16DIMMTotalPower = u16Power;
//LuxPrintf("u8Power = %d\n",u16Power);
return FUNC_OK;
}
EFuncRetCode LuxFSCHandle6056Fan(SFscInfo* psFscInfo)
{
INT8U u85056FanIndex = 0;
INT8U u8PwmChannel = 0;
INT8U u8Pwm = 0;
INT8U u8DIMMSensorIndex = 0;
INT8U u8MaxDIMMSensorTemp = 0;
for(u8DIMMSensorIndex = 0; u8DIMMSensorIndex < MAX_DIMM_SLOT; u8DIMMSensorIndex++)
{
if(u8MaxDIMMSensorTemp < psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8DIMMSensorIndex].as8RealValue[MAX_READING_CACHE - 1])
{
u8MaxDIMMSensorTemp = psFscInfo->sFscCLSensor.asFscCLSensorInfo[u8DIMMSensorIndex].as8RealValue[MAX_READING_CACHE - 1];
}
}
//LuxPrintf("u8MaxDIMMSensorTemp = %d\n",u8MaxDIMMSensorTemp);
psFscInfo->sFscRunningInfo.u8MaxDIMMSensorTemp = u8MaxDIMMSensorTemp;
/*if DIMM setpoint if 40, need 6056 fan 100% pwm output */
for(u8PwmChannel = 0; u8PwmChannel < FCB_6056_FAN_NUM; u8PwmChannel++)
{
//LuxPrintf("6056 fan %d DIMMGroup Temp = %d\n",u8PwmChannel, psFscInfo->sFscRunningInfo.u8DIMMGroupMaxTemp[3 - u8PwmChannel]);
if(40 == psFscInfo->sFscCLSensor.asFscCLSensorInfo[0].s8Setpoint)
{
if(psFscInfo->sFscRunningInfo.u8DIMMGroupMaxTemp[u8PwmChannel] >= 45)
{
u8Pwm = 100;
}
else if(psFscInfo->sFscRunningInfo.u8DIMMGroupMaxTemp[u8PwmChannel] >= 44)
{
u8Pwm = 95;
}
else if(psFscInfo->sFscRunningInfo.u8DIMMGroupMaxTemp[u8PwmChannel] >= 43)
{
u8Pwm = 90;
}
else if(psFscInfo->sFscRunningInfo.u8DIMMGroupMaxTemp[u8PwmChannel] >= 42)
{
u8Pwm = 85;
}
else if(psFscInfo->sFscRunningInfo.u8DIMMGroupMaxTemp[u8PwmChannel] >= 41)
{
u8Pwm = 80;
}
else if(psFscInfo->sFscRunningInfo.u8DIMMGroupMaxTemp[u8PwmChannel] >= 36)
{
u8Pwm = 70;
}
else
{
u8Pwm = 60;
}
}
else
{
if(psFscInfo->sFscRunningInfo.u8DIMMGroupMaxTemp[u8PwmChannel] > 78)
{
u8Pwm = 100;
}
else if(psFscInfo->sFscRunningInfo.u8DIMMGroupMaxTemp[u8PwmChannel] > 77)
{
u8Pwm = 90;
}
else if(psFscInfo->sFscRunningInfo.u8DIMMGroupMaxTemp[u8PwmChannel] > 76)
{
u8Pwm = 80;
}
else if(psFscInfo->sFscRunningInfo.u8DIMMGroupMaxTemp[u8PwmChannel] > 75)
{
u8Pwm = 60;
}
else if(psFscInfo->sFscRunningInfo.u8DIMMGroupMaxTemp[u8PwmChannel] > 74)
{
u8Pwm = 30;
}
else
{
u8Pwm = 10;
}
}
if(0 == g_u8FSCEnable)
{
u8Pwm = 0;
}
if(TRUE == g_u8FSCPresent)
{
if(FUNC_FAILED == LuxSetCPLD6056FanPWM(u8PwmChannel, u8Pwm))
{
LuxPrintf("Set FCB 6056 fan pwm %d dutycycle to %d failed\n",u8PwmChannel, u8Pwm);
return FUNC_FAILED;
}
}
}
return FUNC_OK;
}
void get_timestamp(char *buffer, size_t size) {
time_t now = time(NULL);
struct tm *tm_info = localtime(&now);
strftime(buffer, size, "%Y-%m-%d %H:%M:%S", tm_info);
}
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;
FILE* fp = NULL;
char timestamp[64];
get_timestamp(timestamp, sizeof(timestamp));
fp = fopen("/home/root/cover_temp.log", "a");
if(NULL == fp)
{
LuxPrintf("Can't open /home/root/cover_temp.log\n");
}
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);
fclose(fp);
return FUNC_FAILED;
}
else
{
//LuxPrintf("Channel %d read buffer 0x%x 0x%x\n",u8CoverTempSensorIndex+1, au8ReadBuf[0], au8ReadBuf[1]);
if(0 == (au8ReadBuf[0] & 0x80))
{
u8SensorTemp = (INT8U)((((INT16U)((au8ReadBuf[0] << 8) + au8ReadBuf[1])) >> 3) * 0.0625);
fprintf(fp, "%s, Channel %d temp = %d\n",timestamp, u8CoverTempSensorIndex+1, u8SensorTemp);
if(u8CoverMaxTemp < u8SensorTemp)
{
u8CoverMaxTemp = u8SensorTemp;
}
}
}
}
//LuxPrintf("Max temp = %d\n",u8CoverMaxTemp);
fclose(fp);
*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",psFscInfo->sFscRunningInfo.u8MaxCoverTemp);
}
return FUNC_OK;
}
int LuxCoverHighTempProtect(SFscInfo* psFscInfo)
{
if((psFscInfo->sFscRunningInfo.u8DIMMGroupMaxTemp[0] >= DIMM_PROTECT_TEMPERATURE) || (psFscInfo->sFscRunningInfo.u8DIMMGroupMaxTemp[1] >= DIMM_PROTECT_TEMPERATURE) \
|| (psFscInfo->sFscRunningInfo.u8DIMMGroupMaxTemp[2] >= DIMM_PROTECT_TEMPERATURE) || (psFscInfo->sFscRunningInfo.u8DIMMGroupMaxTemp[3] >= DIMM_PROTECT_TEMPERATURE))
{
if(0 == g_u8DIMMHighTempProtect)
{
LuxPrintf("DIMM temperature is over 85 degree, power off system!!!\n");
LuxPrintf("DIMM group 0 temp = %f\n",psFscInfo->sFscRunningInfo.u8DIMMGroupMaxTemp[0]);
LuxPrintf("DIMM group 1 temp = %f\n",psFscInfo->sFscRunningInfo.u8DIMMGroupMaxTemp[1]);
LuxPrintf("DIMM group 2 temp = %f\n",psFscInfo->sFscRunningInfo.u8DIMMGroupMaxTemp[2]);
LuxPrintf("DIMM group 3 temp = %f\n",psFscInfo->sFscRunningInfo.u8DIMMGroupMaxTemp[3]);
system("ipmitool raw 0 2 0");
g_u8DIMMHighTempProtect = 1;
}
}
}
int main(void)
{
INT32U u32Tick = 0;
LuxPrintf("******************************************************************************\n");
LuxPrintf("************************ Luxshare DIMM FSC Task Begin ************************\n");
LuxPrintf("******************************************************************************\n");
INT8U u8TurnOnSystemFlag = 0;
INT8U u8PwmChannel = 0;
EFuncRetCode eRet;
INT8U u8DIMMFSCChannnel = 0;
INT8U u8FSC6056Channnel = 0;
INT8U u8FSCEnableVaule = 0;
LuxFSCInit();
if(FUNC_OK == LuxCheckFCBPresent())
{
g_u8FSCPresent = TRUE;
}
while(1)
{
usleep(100*1000);
/*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 fsc enable status, if not enable by OEM command, don't do dimm fsc logic and turn off 6056*/
eRet = LuxFSCGetEnableStatus(&u8FSCEnableVaule);
if((FUNC_FAILED == eRet) || (0 == u8FSCEnableVaule))
{
g_u8FSCEnable = 0;
}
else
{
g_u8FSCEnable = 1;
}
LuxFSCGetFSCControlMode(&psFscInfo);
/*Check if manual control */
if(FSC_FAN_TABLE_MANUAL == psFscInfo.sFscRunningInfo.u8ControlMode)
{
for(u8PwmChannel = 0; u8PwmChannel < MAX_FSC_PWM_CHANNEL; u8PwmChannel++)
{
LuxFSCManualOutputPWM(u8PwmChannel, psFscInfo.sFscRunningInfo.au8ManualPwmOut[u8PwmChannel]);
}
continue;
}
/*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
{
g_u8DIMMHighTempProtect = 0;
continue;
}
#if 0
if(TRUE == g_u8FSCPresent)
{
if(TRUE == g_u8FSCEnable)
{
if(0 == (psFscInfo.sFscRunningInfo.u32Tick % 600))
{
LuxFSCCoverMaxTemp(&psFscInfo);
}
}
}
#endif
LuxFSCGetDIMMTotalPower(&psFscInfo);
/*Get sensor status and reading every second */
LuxFSCGetSensorStatus(&psFscInfo);
/*Handle closeloop sensor */
LuxFSCHandleCloseloop(&psFscInfo);
/*Handle closeloop sensor */
LuxFSCHandle6056Fan(&psFscInfo);
/*Handle output pwm */
LuxFSCHandlePwmOut(&psFscInfo);
LuxCoverHighTempProtect(&psFscInfo);
/*Handle high-temperature Cover heat */
//LuxFSCHandleCoverHeat(&psFscInfo);
/*Handle thermal debug */
//LuxFSCHandleThermalDebug(&psFscInfo);
//LuxPrintDIMMTemp(&psFscInfo);
}
return 0;
}