2998 lines
94 KiB
C
Executable File
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;
|
|
}
|