/*
 * Infypwr_PsuCommObj.h
 *
 *  Created on: 2019年11月26日
 *      Author: 7564
 */

#ifndef INFYPWR_PSUCOMMOBJ_H_
#define INFYPWR_PSUCOMMOBJ_H_

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <signal.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/wireless.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/time.h>

#include 	<stdbool.h>
#include 	<unistd.h>
#include 	<stdarg.h>
#include    <stdio.h>      /*標準輸入輸出定義*/
#include    <stdlib.h>     /*標準函數庫定義*/
#include    <unistd.h>     /*Unix 標準函數定義*/
#include    <fcntl.h>      /*檔控制定義*/
#include    <termios.h>    /*PPSIX 終端控制定義*/
#include    <errno.h>      /*錯誤號定義*/
#include 	<errno.h>
#include 	<string.h>
#include	<time.h>
#include	<ctype.h>
#include 	<ifaddrs.h>
#include 	<math.h>

#define LIB_IN_USE				1
#define LIB_NO_USE				0

#define INFYPWR_CMD				0x02000000
#define INFYPWR_BROADCAST		0x00003F00
#define INFYPWR_DEFAULT			0x000000F0

#define INFYPWR_GROUP_SHIFT		0x00400000

#define SYSTEM_CMD                  0x3F
#define DEVICE_NO_SINGLE_MODULE     0x0A
#define DEVICE_NO_GROUP_MODULE      0x0B
#define INFY_ADD_BROADCAST          0x3F
#define INFY_ADD_CSU                0xF0
#define NEXTON_ADD                  0xFF

#define ARRAY_SIZE(A)		(sizeof(A) / sizeof(A[0]))
#define CMD_DELAY_TIME 		25000
#define FAN_SPEED_CMD		0x1201
#define TEMP_DC_CMD			0x1107
#define TEMP_PFC_CMD		0x1108

#define	PSU_PROTOCOL_TYPE	0

typedef unsigned char       byte;
typedef unsigned short      word;
typedef unsigned int        unit;

int 						CanFd;
pid_t 						recFork;

typedef union
{
    unsigned int PwrMessage;
    struct
    {
        unsigned int SourceAddress:8;                   // source address
        unsigned int DestinationAddress:8;              // destination address
        unsigned int CmdValue:6;                        // command value
        unsigned int DeviceValue:4;                     // 0x0A: for module command, 0x0B group command
        unsigned int Error:3;                           // error code
        unsigned int res:3;
    }InfyBits;
    struct
    {
        unsigned int SourceAddress:8;                   // source address
        unsigned int DestinationAddress:8;              // destination address
        unsigned int CmdValue:13;                       // command value
        unsigned int res:3;
    }NextonBits;
}PwrFrame;

enum PSU_POWER_CMD
{
	PSU_POWER_ON = 		0,
	PSU_POWER_OFF = 			1,
};

enum PSU_SLEEP_MODE_CMD
{
	PSU_SLEEP_MODE_WAKE_UP = 	0,
	PSU_SLEEP_MODE_SLEEP = 		1,
};

enum PSU_FLASH_CMD
{
	PSU_FLASH_NORMAL = 		0,
	PSU_FLASH_ON = 			1,
};

enum PSU_FAN_NOISE_CMD
{
    PSU_FAN_NOISE_BY_POWER =        0xA0,       // power poriority mode
    PSU_FAN_NOISE_BY_DENOISE =      0xA1,       // denoise mode
    PSU_FAN_NOISE_BY_QUIET =        0xA2,       // quiet mode
};

enum PSU_SET_CMD
{
    MIS_INFO =                  0x008F0000,     // 現在只能改變降噪模式
    FLASH_LED =                 0x00940000,
    WALK_IN_MODE =              0x00930000,
    SLEEP_MODE =                0x00990000,     // 當 SWITCH POWER 打開時,可透過該指令讓模塊休眠 (風扇會停)
    SWITCH_POWER =              0x009A0000,     // 打開,則模塊依照設定的輸出功率輸出
    PRESENT_OUT_VOL =           0x009B0000,
    DIP_SWITCH_MODE =           0x009F0000,     // 設定所有模塊的地址為撥碼方式
    /*Ver : 9.06 used*/
    TEST_PRESENT_OUT =          0x180100E5,
    /*Upgrade*/
    CHANGE_BAUDRATE =           0x028F0000
};

enum PSU_GET_CMD
{
    MODULE_OUTPUT_VOL_CUR_FLOAT =   0x00810000,     // 取得當前輸出電壓電流 (float)
    MODULE_COUNT =                  0x00820000,     // 取得模塊數量
    STATUS =                        0x00840000,     // 取得溫度、狀態
    MODULE_INPUT =                  0x00860000,     // 取得三向輸入電壓
    MODULE_VER =                    0x00870000,     // 取得版號
    MODULE_OUTPUT_VOL_CUR =         0x00880000,     // 取得當前輸出電壓電流
    MODULE_CAP =                    0x008A0000,     // 取得當前 Group 的最大電壓、最大電流、最小電壓、額定功率
    MODULE_BARCODE =                0x008B0000,     // 取得 BarCode
    MODULE_IAVAILABLE =             0x008C0000,     // 取得實際模塊可輸出的電流能力 (降載)
    MODULE_MIS_INFO =               0x008E0000,     // 取得模塊資訊 (Tdc、Tpfc、風扇速度)
    /*Ver : 9.06 used*/
    AUTO_OUTPUT_TEMP =              0x00010000,
    AUTO_MODULE_STATUS =            0x00020000,
    AUTO_MODULE_INPUT =             0x00030000,
};

typedef enum
{
    Infy_MsgErr_Normal          = 0x00,
    Infy_MsgErr_Reserved1       = 0x01,
    Infy_MsgErr_CmdInvalid      = 0x02,
    Infy_MsgErr_DataInvalid     = 0x03,
    Infy_MsgErr_InvalidAdd      = 0x04,
    Infy_MsgErr_Reserved2       = 0x05,
    Infy_MsgErr_Reserved3       = 0x06,
    Infy_MsgErr_StartProcess    = 0x07,
}InfyMessageError;

typedef enum
{
    PSU_RCmd_SysOutputVolCur_F      = 0x01,
    PSU_RCmd_SysModuleCount         = 0x02,
    PSU_RCmd_ModuleOutputVolCur_F   = 0x03,     // no use
    PSU_RCmd_ModuleStatus           = 0x04,
    PSU_RCmd_ModuleInputVoltage     = 0x06,
    PSU_RCmd_ModuleVersion          = 0x07,
    PSU_RCmd_SysOutputVolCur        = 0x08,
    PSU_RCmd_ModuleOutputVolCur     = 0x09,     // no use
    PSU_RCmd_ModuleCapability       = 0x0A,
    PSU_RCmd_ModuleBarcode          = 0x0B,
    PSU_RCmd_ModuleIAvailable       = 0x0C,
    PSU_RCmd_ModuleMiscInfo         = 0x0E,
    PSU_WCmd_ModuleSetMiscInfo      = 0x0F,
    PSU_WCmd_ModuleWalkIn           = 0x13,
    PSU_WCmd_ModuleFlashLed         = 0x14,
    PSU_WCmd_ModuleSetGroup         = 0x16,
    PSU_WCmd_ModuleSleepMode        = 0x19,
    PSU_WCmd_ModulePowerOnOff       = 0x1A,
    PSU_WCmd_SetOutput              = 0x1B,
    PSU_WCmd_ModuleSetOutput        = 0x1C,
    PSU_WCmd_DipSwitchMode          = 0x1F,
}InfyPwrCommand;

typedef enum
{
    Nexton_PSU_ChargingRequest      = 0x1801,
    Nexton_PSU_DcOutputValue        = 0x1901,
    Nexton_PSU_StatusEvent          = 0x1902,
    Nexton_PSU_AcInputValue         = 0x1903,
}NextonPwrCommand;

typedef enum
{
    GetMiscInfo_DcTemperature       = 0x1107,
    GetMiscInfo_PfcTemperature      = 0x1108,
    GetMiscInfo_FanSpeed            = 0x1201,
}GetMiscInfoCommand;

typedef enum
{
    SetMiscInfo_FanMode             = 0x1113,
    SetMiscInfo_FanSpeed            = 0x1201,
    SetMiscInfo_CurrentLimit        = 0x1205,
    SetMiscInfo_SendTemperature     = 0x1301,
}SetMiscInfoCommand;

union FloatingPointIEEE754
{
	struct
	{
		unsigned int mantissa : 23;
		unsigned int exponent : 8;
		unsigned int sign : 1;
	} raw;
	float f;
} number;

struct INFY_POW_MODULE_INFO
{
	byte serialNumber[12];
	byte targetNumber[12];
	byte psuCount;
};

struct INFY_POW_MODULE_INFO infy_pow_info[4];

/*Initialization*/
bool InitialCommunication();

/*Set Cmd*/
void SwitchPower(byte group, byte value);
void SleepMode(byte group, byte value);
void FlashLed(byte group, byte value);
void PresentOutputVol(byte group, int voltage, int current, byte psuCount);
void FanNoiseInfo(byte group, byte value);
void SetWalkInConfig(byte group, byte enable, byte sec);
void SetDipSwitchMode();

// set only one powermodule to output
void PresentSingleOutput(byte moduleIndex, int voltage, int current);
void SwitchSinglePower(byte moduleIndex, byte value);
void FlashSingleLed(byte moduleIndex, byte value);
void GetSingleModuleOutputF(byte moduleIndex);

/*Ver : 9.06 used*/
void SetDirModulePresentOutput(byte group, int voltage, int current, byte _switch, byte _interRelay);
/*Get Cmd*/
void GetStatus(byte group, byte param);
void GetFanSpeed(byte group);
void GetDcTemperature(byte group);
void GetPfcTemperature(byte group);
void GetFanSpeed(byte group);
void GetModuleCount(byte group);
void GetModuleVer(byte group);
void GetModuleCap(byte group);
void GetModuleBarCode(byte group);
void GetModuleInput(byte group);
void GetModuleIavailable(byte group);
void GetModuleOutput(byte group);
void GetModuleOutputF(byte group);

/*Upgrade*/
void ChangePsuBaudrate(short baudrate);

/* Callback Function */
void RefreshStatus(void *func);
void (*return_status)(byte group, byte address, byte temp, int status, byte type,
		unsigned char err1, unsigned char err2, unsigned char err3, unsigned char err4);

void RefreshModuleCount(void *func);
void (*return_module_count)(byte group, byte count);

void RefreshAvailableCap(void *func);
void (*return_available_cap)(byte address, short maxVol, short minVol, short maxCur, short totalPow);

void RefreshFwVersion(void *func);
void (*return_fw_version)(byte address, short dcSwVer, short pfcSwVer, short hwVer, byte type);

void RefreshInputVol(void *func);
void (*return_input_vol)(byte address, unsigned short vol1, unsigned short vol2, unsigned short vol3);

void RefreshGetOutput(void *func);
void (*return_get_output)(byte address, float outVol, float outCur);

void RefreshGetOutputF(void *func);
void (*return_get_output_float)(byte group, float outVol, float outCur, byte type);

void RefreshMisInfo(void *func);
void (*return_mis_info)(byte address, unsigned int fanSpeed, byte type);

void RefreshIavailable(void *func);
void (*return_iavail_info)(byte address, unsigned short Iavail, unsigned short Vext);

/*Test mode used*/
void AutoMode_RefreshOutputAndTemp(void *func);
void (*return_output_temp)(byte address, unsigned short outputVol,
		unsigned short outputCur, unsigned short outputPower, unsigned char Temperature, byte type);

void AutoMode_RefreshModuleStatus(void *func);
void (*return_module_status)(byte address, unsigned char isErr, unsigned char status,
		unsigned char err1, unsigned char err2, unsigned char err3, unsigned char err4);

void AutoMode_RefreshModuleInput(void *func);
void (*return_module_input)(byte address, unsigned short inputR,
		unsigned short inputS, unsigned short inputT);
/* Callback Function end */
#endif /* INFYPWR_PSUCOMMOBJ_H_ */