#ifndef PRE_HEAT_H
#define PRE_HEAT_H

#define DIMM_FSC_VERSION "V0.1"
#define FAN_TABLE_PATH "/usr/bin/pre_heat.json"

//define for thermal oem command
#define DIMM_SETPOINT_PATH  "/tmp/dimm_setpoint"
#define COVER_SETPOINT_PATH  "/tmp/cover_setpoint"
#define COVER_STATUS_PATH  "/tmp/cover_status"
#define FSC_CONTROL_MODE  "/tmp/fsc_control_mode"
#define FSC_ENABLE_STATUS_PATH  "/tmp/fsc_enable"

#define SETPOINT_CONSTANT   "constant"
#define SETPOINT_VARIABLE   "variable"

#define MAX_FSC_PWM_CHANNEL 29
#define MAX_DIMM_SLOT 24
#define MAX_DIMM_POWER_SLOT 4
#define MAX_MB_PWM_CHANNEL 5
#define MAX_JSON_CHARACTER_SIZE 128
#define MAX_SENSOR_NAME_LENGTH 16
#define MAX_KEY_LENGTH 32
#define PWM_POWER_ON_IN_SHORT_TIME 80
#define MAX_PWM_THERMAL_DEFINE 100
#define MIN_PWM_THERMAL_DEFINE 1
#define MAX_OL_SENSOR   10
#define MAX_OL_SENSOR_STEPS     50
#define MAX_CL_SENSOR   50
#define MAX_FAN_COUNT  20
#define MAX_SETPOINT_CASE   10
#define MAX_SENSOR_E_SECTION    12
#define MAX_SENSOR_EC_SECTION   9
#define MAX_ABNORMAL_SENSOR     50
#define MAX_FAN_AVERAGE_COUNT   10
#define PID_INIT_PWM    50
#define SENSOR_REAL_VALUE_INITIAL   127 /*init sensor reading to 127, sign value */
#define POWERON_FSC_DELAY   10
#define INLET_SENSOR_VALUE_ABNORMAL_STATE   35 /*if inlet sensor is can't read, need use 35 do fsc control */

#define SENSOR_UPPER_NON_CRITICAL_PWM   80
#define SENSOR_UPPER_CRITICAL_PWM  90
#define SENSOR_UPPER_NON_RECOVERABLE_PWM    100

#define MAX_READING_CACHE       10
#define READING_INVALID         0
#define READING_VALID           1

#define FCB_I2C_BUS     7
#define FCB_CPLD_SLAVE_ADDR     0x7c
#define FCB_TMP468_ADDR     0x90

#define DIMM_HEAT_TURN_OFF   0
#define DIMM_HEAT_TURN_ON   1

#define PTC_PRE_HEAT_MAX_PWM    100
#define PTC_PRE_HEAT_MIN_PWM    1
#define PTC_PRE_HEAT_PWM    30

#define DIMM_FAN_MIN_PWM 37
#define CPU_FAN_MIN_PWM 80
#define FCB_6056_LOWER_TEMP_MIN_PWM 75
#define FCB_6056_HIGH_TEMP_MAX_PWM 40
#define FCB_6056_HIGH_TEMP_MIN_PWM 0

#define FCB_6056_FAN_NUM    4
#define FCB_6056_PRE_HEAT_PWM 10

typedef struct
{
    INT8U u8ControlMode;
    INT8U u8PWM[MAX_FSC_PWM_CHANNEL];
}__attribute__ ((packed))SFscControlMode;

typedef struct
{
    INT8U u8DIMMIndex;
    INT8U u16Reg;
}__attribute__ ((packed))SFscFanReg;

typedef struct
{
    INT8U u8DIMMIndex;
    char acDbusPath[256];
}__attribute__ ((packed))SDIMMDbus;

typedef struct
{
    INT8U u8CPUIndex;
    char acDbusPath[256];
}__attribute__ ((packed))SCPUDbus;

typedef struct
{
    INT8U u8DIMMPowerIndex;
    char acDbusPath[256];
}__attribute__ ((packed))SDIMMPowerDbus;

typedef struct
{
    INT8U u8DIMMIndex;
    INT8U u16Reg;
}__attribute__ ((packed))SFscHeatReg;

typedef struct
{
    INT8U u8DIMMIndex;
    INT8U u16Reg;
}__attribute__ ((packed))SFsc6056FanReg;


typedef enum
{
    REG_FCB_CPLD_FAN_QUANTITY                                        = 0x0006,
    REG_FCB_GET_HEAT_COVER_STATUS                                    = 0x0037,
    REG_FCB_DIMM_INITIAL_PWM                                         = 0x0051,
    REG_FCB_DIMM23_SET_PWM                                            = 0x0052,
    REG_FCB_DIMM22_SET_PWM                                            = 0x0053,
    REG_FCB_DIMM21_SET_PWM                                            = 0x0054,
    REG_FCB_DIMM20_SET_PWM                                            = 0x0055,
    REG_FCB_DIMM19_SET_PWM                                            = 0x0056,
    REG_FCB_DIMM18_SET_PWM                                            = 0x0057,
    REG_FCB_DIMM17_SET_PWM                                            = 0x0058,
    REG_FCB_DIMM16_SET_PWM                                            = 0x0059,
    REG_FCB_DIMM15_SET_PWM                                            = 0x005a,
    REG_FCB_DIMM14_SET_PWM                                            = 0x005b,
    REG_FCB_DIMM13_SET_PWM                                            = 0x005c,
    REG_FCB_DIMM12_SET_PWM                                            = 0x005d,
    REG_FCB_DIMM11_SET_PWM                                            = 0x005e,
    REG_FCB_DIMM10_SET_PWM                                            = 0x005f,
    REG_FCB_DIMM9_SET_PWM                                            = 0x0060,
    REG_FCB_DIMM8_SET_PWM                                            = 0x0061,
    REG_FCB_DIMM7_SET_PWM                                            = 0x0062,
    REG_FCB_DIMM6_SET_PWM                                            = 0x0063,
    REG_FCB_DIMM5_SET_PWM                                            = 0x0064,
    REG_FCB_DIMM4_SET_PWM                                            = 0x0065,
    REG_FCB_DIMM3_SET_PWM                                            = 0x0066,
    REG_FCB_DIMM2_SET_PWM                                            = 0x0067,
    REG_FCB_DIMM1_SET_PWM                                            = 0x0068,
    REG_FCB_DIMM0_SET_PWM                                            = 0x0069,
    REG_FCB_PTC_INITIAL_PWM                                          = 0x0075,
    REG_FCB_PTC_DIMM23_SET_PWM                                        = 0x0076,
    REG_FCB_PTC_DIMM22_SET_PWM                                        = 0x0077,
    REG_FCB_PTC_DIMM21_SET_PWM                                        = 0x0078,
    REG_FCB_PTC_DIMM20_SET_PWM                                        = 0x0079,
    REG_FCB_PTC_DIMM19_SET_PWM                                        = 0x007a,
    REG_FCB_PTC_DIMM18_SET_PWM                                        = 0x007b,
    REG_FCB_PTC_DIMM17_SET_PWM                                        = 0x007c,
    REG_FCB_PTC_DIMM16_SET_PWM                                        = 0x007d,
    REG_FCB_PTC_DIMM15_SET_PWM                                        = 0x007e,
    REG_FCB_PTC_DIMM14_SET_PWM                                        = 0x007f,
    REG_FCB_PTC_DIMM13_SET_PWM                                       = 0x0080,
    REG_FCB_PTC_DIMM12_SET_PWM                                       = 0x0081,
    REG_FCB_PTC_DIMM11_SET_PWM                                       = 0x0082,
    REG_FCB_PTC_DIMM10_SET_PWM                                       = 0x0083,
    REG_FCB_PTC_DIMM9_SET_PWM                                       = 0x0084,
    REG_FCB_PTC_DIMM8_SET_PWM                                       = 0x0085,
    REG_FCB_PTC_DIMM7_SET_PWM                                       = 0x0086,
    REG_FCB_PTC_DIMM6_SET_PWM                                       = 0x0087,
    REG_FCB_PTC_DIMM5_SET_PWM                                       = 0x0088,
    REG_FCB_PTC_DIMM4_SET_PWM                                       = 0x0089,
    REG_FCB_PTC_DIMM3_SET_PWM                                       = 0x008a,
    REG_FCB_PTC_DIMM2_SET_PWM                                       = 0x008b,
    REG_FCB_PTC_DIMM1_SET_PWM                                       = 0x008c,
    REG_FCB_PTC_DIMM0_SET_PWM                                       = 0x008d,
    REG_FCB_SET_HEAT_COVER_STATUS                                    = 0x008e,


}EUbbPriCPLDReg;


typedef enum
{
    /*Power good status*/
    PS_GOOD_FAIL=0,
    PS_GOOD_OK,

    /*Update flag */
    FSC_FAN_TABLE_NORMAL = 0,
    FSC_FAN_TABLE_UPDATE = 1,

    /*Fan table load status flag */
    FSC_FAN_TABLE_LOAD_FAIL = 0,
    FSC_FAN_TABLE_LOAD_SUCCESS = 1,

    /*Control mode*/
    FSC_FAN_TABLE_AUTO = 0,
    FSC_FAN_TABLE_MANUAL = 1,

    /*Sensor present */
    FSC_SENSOR_NOT_PRESENT = 0,
    FSC_SENSOR_PRESENT = 1,

    /*Sensor present */
    FSC_SENSOR_NORMAL = 0,
    FSC_SENSOR_ABNORMAL = 1,

    /*Fan type */
    FSC_FAN_TYPE_SINGLE = 0,
    FSC_FAN_TYPE_TWIN = 1,

    /*Fan status */
    FSC_FAN_NORMAL = 0,
    FSC_FAN_FAIL = 1,

    /*Fsc work when dc off */
    FSC_WORK_DC_ON_ONLY = 0,
    FSC_WORK_DC_OFF = 1,

    /*Fan fail handle type */
    FSC_ABNORMAL_POLICY_UNUSED = 0,
    FSC_ABNORMAL_POLICY_INCREASE = 1,
    FSC_ABNORMAL_POLICY_CONSTANT = 2,

    /*FSC normal or abnormal */
    FSC_NORMAL = 0,
    FSC_ABNORMAL = 1,

    /*Thermal debug */
    FSC_NO_THERMAL_DEBUG = 0,
    FSC_OPEN_THERMAL_DEBUG = 1,

}EFscFlag;


typedef struct
{
    char acProject[MAX_KEY_LENGTH];
    char acCustomer[MAX_KEY_LENGTH];
    char acVersion[MAX_KEY_LENGTH];
    char acPlatform[MAX_KEY_LENGTH];
}__attribute__ ((packed))SFscHeader;

typedef struct
{
    INT8U u8MaxReadingCache;
    INT16U u16Elevation;
    char acFanType[MAX_KEY_LENGTH];
    char acWorkDCOff[MAX_KEY_LENGTH];
}__attribute__ ((packed))SFscGlobalConfig;

typedef struct
{
    INT8U u8MaxPwmNum;
    INT8U u8MaxFanNum;
    INT8U u8FanSensorNumPWMMatch[MAX_FAN_COUNT];
    INT8U u8MaxFanDuty;
    INT8U u8MinFanDuty;
}__attribute__ ((packed))SFscFanConfig;

typedef struct
{
    char acCLSensorType[MAX_KEY_LENGTH];
    char acCLSensorStatus[MAX_KEY_LENGTH];
    INT8U u8DT;
    char acSensorName[MAX_SENSOR_NAME_LENGTH + 1];
    INT8S s8VendorSpec;
    INT8S s8CustomerSpec;
    char acSetpointType[MAX_KEY_LENGTH];
    INT8S s8SetpointDefault;
    char acSetpointCase[MAX_SETPOINT_CASE][MAX_KEY_LENGTH];
    INT8S as8SetpointValue[MAX_SETPOINT_CASE];
    char acSetpointCaseUse[MAX_KEY_LENGTH];
    INT8U au8FanWeight[MAX_FSC_PWM_CHANNEL];
    INT8U u8Hysteresis;
    INT8S as8EValue[MAX_SENSOR_E_SECTION-1];
    INT8S as8ECValue[MAX_SENSOR_EC_SECTION-1];
    float afPValue[MAX_SENSOR_EC_SECTION][MAX_SENSOR_E_SECTION];
    float afIValue[MAX_SENSOR_EC_SECTION][MAX_SENSOR_E_SECTION];
    float afDValue[MAX_SENSOR_EC_SECTION][MAX_SENSOR_E_SECTION];

    INT8U u8SensorNumber;
    INT8S s8Setpoint;
    INT8S as8RealValue[MAX_READING_CACHE];
    float fP;
    float fI;
    float fD;
    INT8U u8SensorSDRPresent; /*sensor sdr present flag, 1 - present, 0 - not present*/
    INT8U u8Present;    /*sensor present flag, 1 - present, 0 - not present*/
    INT8U u8Abnormal;    /*sensor health flag, 1 - abnormal, 0 - normal*/
    INT8U u8Health;     /*sensor reading value status*/
    INT8U u8NoReadingTries;
    INT8U u8SensorStatus;
                            /* Event Flags description           */
                            /* Bit 0 -  Initialization Done      */
                            /* Bit 1 -  Update in Progress       */
                            /* Bit 2 -  reserved                 */
                            /* Bit 3 -  reserved                 */
                            /* Bit 4 -  reserved                 */
                            /* Bit 5 -  Unable to read           */
                            /* Bit 6 -  Sensor Scanning disabled */
                            /* Bit 7 -  Event Message Disabled   */

    INT32U u32CalculateTick;
    INT8U u8PwmPIDCalculate;
    INT16S s16LastPwmPIDCalculate;
    float fPIncrement;
    float fIIncrement;
    float fDIncrement;
    INT8U u8PwmAfterWeighting[MAX_FSC_PWM_CHANNEL];
    INT8U u8PwmAfterWeightingCache[MAX_FSC_PWM_CHANNEL][MAX_FAN_AVERAGE_COUNT];
    INT8U u8PwmAfterHysteresis[MAX_FSC_PWM_CHANNEL];
}__attribute__ ((packed))SFscCLSensorInfo;

typedef struct
{
    INT8U u8MaxCLSensor;
    INT8U u8TotalCLSensor;
    char acPIDAdjustMethod[MAX_KEY_LENGTH];
    INT8U u8CLSensorESection;
    INT8U u8CLSensorECSection;
    INT8U u8CLSensorSetpointMaxCase;
    SFscCLSensorInfo asFscCLSensorInfo[MAX_CL_SENSOR];
}__attribute__ ((packed))SFscCLSensor;

typedef struct
{
    INT8U u8FanSensorNumberStart;
    char acFanFailSingle[MAX_KEY_LENGTH];
    INT8U u8FanFailTwin1;
    INT8U u8FanFailTwin2Diff;
    char acFanFailTwin2Same[MAX_KEY_LENGTH];

    /*fan status: 0 - normal, 1 - abnormal */
    INT8U au8FanStatus[MAX_FAN_COUNT];
    INT8U au8FanFailPwm[MAX_FSC_PWM_CHANNEL];
    INT8U au8FanFailConstantPwm;
    INT8U u8FanFailHandleType;
}__attribute__ ((packed))SFscFanFail;

typedef struct
{
    char acSensorName[MAX_SENSOR_NAME_LENGTH];
    char acFailPolicy[MAX_KEY_LENGTH];
    INT8U u8FailValue;

    INT8U u8SensorFailHandleType;
    INT8U u8SensorFailPwmOut;
}__attribute__ ((packed))SFscSensorFailInfo;


typedef struct
{
    INT8U u8MaxAbnormalSensor;
    INT8U u8TotalAbnormalSensor;
    SFscFanFail sFscFanFail;
    SFscSensorFailInfo asFscSensorFailInfo[MAX_ABNORMAL_SENSOR];
}__attribute__ ((packed))SFscAbnormalEvent;

typedef struct
{
    INT8U u8UpdateFlag; /*1 - update, 0 - normal */
    INT8U u8FanTableLoadStatus; /*1 - success, 0 - fail */
    INT8U u8ControlMode; /*1 - manual, 0 - auto */
    INT8U u8ThermalDebug; /*thermal debug falg, 0 - no debug, 1 - debuging */
    INT8U u8WorkDCOff; /*1 - work when dc off, 0 - no work when dc off */
    INT8U u8LoadTableTries;
    INT32U u32Tick;
    INT8U u8SKUID;
    INT8U u8MaxOLPwm;
    INT8U au8CLPwm[MAX_FSC_PWM_CHANNEL];
    INT8U au8MaxAbnormalPwm;
    INT8U au8MaxAbnormalIncreasePwm;
    char acFactorSensorName[16];
    INT8U u8FactorPwm;
    INT8U u8FscStatus;  /*0 - normal fsc, 1 - abnormal fsc */
    INT8U au8PwmOut[MAX_FSC_PWM_CHANNEL];
    INT8U au8ManualPwmOut[MAX_FSC_PWM_CHANNEL];
    INT8U u8MaxCoverTemp;
}__attribute__ ((packed))SFscRunningInfo;



typedef struct
{
    SFscHeader sFSCHeader;
    SFscGlobalConfig sFscGlobalConfig;
    SFscFanConfig sFscFanConfig;
    SFscCLSensor sFscCLSensor;
    SFscAbnormalEvent sFscAbnormalEvent;
    SFscRunningInfo sFscRunningInfo;
}__attribute__ ((packed))SFscInfo;

#endif
