소스 검색

2022-06-22 / Alston Lin
Actions
1. Add support for UU power lib.
2. Modify Infy power lib

Files
1. As follow commit history

root 2 년 전
부모
커밋
51695b4520

+ 35 - 51
EVSE/Modularization/Infypwr_PsuCommObj.c

@@ -8,8 +8,9 @@
 #include "Infypwr_PsuCommObj.h"
 
 #define ARRAY_SIZE(A)		(sizeof(A) / sizeof(A[0]))
-#define NO		0
-#define YES		1
+#define NO					0
+#define YES					1
+#define MODULE_MAX_VOL		1000
 
 #define DEBUG_LIB						1
 
@@ -150,7 +151,7 @@ int InitCanBus()
 	struct timeval			tv;
 	struct ifreq 			ifr0;
 	struct sockaddr_can		addr0;
-	//struct can_filter 		rfilter[2];
+	struct can_filter 		rfilter[2];
 
 	system("/sbin/ip link set can1 down");
 	system("/sbin/ip link set can1 type can bitrate 500000 restart-ms 100");
@@ -181,17 +182,22 @@ int InitCanBus()
 		#endif
 	}
 	nbytes=40960;
-//	rfilter[0].can_id = 0x0757F803 | CAN_EFF_FLAG;
-//	rfilter[0].can_mask = (CAN_EFF_FLAG | CAN_RTR_FLAG | CAN_EFF_MASK);
-//	rfilter[1].can_id = 0x0757F80B | CAN_EFF_FLAG;
-//	rfilter[1].can_mask = (CAN_EFF_FLAG | CAN_RTR_FLAG | CAN_EFF_MASK);
-//
-//	if (setsockopt(s0, CAN_INV_FILTER, CAN_RAW_FILTER_MAX, &rfilter, sizeof(rfilter)) < 0)
-//	{
-//		#ifdef SystemLogMessage
-//		printf("*********************************Set SOL_CAN_RAW NG");
-//		#endif
-//	}
+
+	//===================================CAN Filter===================================
+	//Filter only allowed: Destination CSU 0xF0
+	rfilter[0].can_id = 0xF000;
+	rfilter[0].can_mask = 0xF000;
+
+	//Filter only allowed: Destination Nexton 0xFF
+	rfilter[1].can_id = 0xFF00;
+	rfilter[1].can_mask = 0xFF00;
+
+	if (setsockopt(s0, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter)) < 0)
+	{
+		#ifdef SystemLogMessage
+		PRINTF_LIB_FUNC("Set SOL_CAN_RAW NG");
+		#endif
+	}
 
    	strcpy(ifr0.ifr_name, "can1" );
 	ioctl(s0, SIOCGIFINDEX, &ifr0); /* ifr.ifr_ifindex gets filled with that device's index */
@@ -296,7 +302,7 @@ void ReceiveDataFromCanBus()
                         byte SN = address;
                         bool isfind = false;
 
-                        if (group < 2 && !colFinished)
+                        if (group < 4 && !colFinished)
                         {
                             for(byte _index = 0; _index < infy_pow_info[group].psuCount; _index++)
                             {
@@ -315,7 +321,7 @@ void ReceiveDataFromCanBus()
                             }
 
                             byte subPcount = 0;
-                            for (byte i = 0; i < 2; i++)
+                            for (byte i = 0; i < 4; i++)
                             {
                                 subPcount += infy_pow_info[i].psuCount;
                             }
@@ -326,7 +332,7 @@ void ReceiveDataFromCanBus()
 
                         short temp = frame.data[4];
                         int status = (frame.data[5] << 16) + (frame.data[6] << 8) + frame.data[7];
-                        return_status(group, SN, temp, status);
+                        return_status(group, SN, temp, status, PSU_PROTOCOL_TYPE, LIB_NO_USE, LIB_NO_USE, LIB_NO_USE, LIB_NO_USE);
                         //PRINTF_LIB_FUNC("group = %d, address = %d, temp = %d \n", group, address, temp);
                     }
                         break;
@@ -343,7 +349,6 @@ void ReceiveDataFromCanBus()
                         }
 
                         return_module_count(group, count);
-                        //PRINTF_LIB_FUNC("group = %d, count = %d \n", group, count);
                     }
                         break;
 
@@ -352,15 +357,14 @@ void ReceiveDataFromCanBus()
                         if (!colFinished)
                             break;
 
-                        // 回傳輸出能力 : 最大電壓、最小電壓、最大電流、額定功率
-                        //address = frame.can_id & 0x000000FF;
-//                        if(!GetRealIndexByGroup(&address))
-//                            break;
+                        // 回傳輸出能力 : 最大電壓,最小電壓,最大電流,額定功率
                         short maxVol = ((frame.data[0] << 8) + frame.data[1]) * 10;
                         short minVol = ((frame.data[2] << 8) + frame.data[3]) * 10;
                         short maxCur = (frame.data[4] << 8) + frame.data[5];
                         short totalPow = ((frame.data[6] << 8) + frame.data[7]) / 10;
 
+                        if (maxCur > MODULE_MAX_VOL)
+                        	maxCur = MODULE_MAX_VOL;
                         return_available_cap(address, maxVol, minVol, maxCur, totalPow);
     //					PRINTF_LIB_FUNC("address = %d, maxVol = %d, minVol = %d, maxCur = %d, totalPow = %d \n",
     //							address, maxVol, minVol, maxCur, totalPow);
@@ -370,8 +374,6 @@ void ReceiveDataFromCanBus()
                     case PSU_RCmd_SysOutputVolCur:
                     {
                         // 回傳當前輸出電壓電流
-                        //address = frame.can_id & 0x000000FF;
-
                         int outputVol = ((frame.data[0] << 24) + (frame.data[1] << 16) + (frame.data[2] << 8) + frame.data[3]) / 100;
                         int outputCur = ((frame.data[4] << 24) + (frame.data[5] << 16) + (frame.data[6] << 8) + frame.data[7]) / 100;
 
@@ -390,7 +392,7 @@ void ReceiveDataFromCanBus()
                         float _Vol = IEEE_754_to_float(vol);
                         float _Cur = IEEE_754_to_float(cur);
 
-                        return_get_output_float(group, _Vol, _Cur);
+                        return_get_output_float(group, _Vol, _Cur, PSU_PROTOCOL_TYPE);
                     }
                         break;
                     case PSU_RCmd_ModuleIAvailable:
@@ -400,8 +402,6 @@ void ReceiveDataFromCanBus()
 
                         // 回傳降載後的電流
                         address = frame.can_id & 0x000000FF;
-//                        if(!GetRealIndexByGroup(&address))
-//                            break;
 
                         unsigned short vextVol = ((frame.data[0] << 8) + frame.data[1]);
                         unsigned short iAvailCur = ((frame.data[2] << 8) + frame.data[3]);
@@ -421,28 +421,22 @@ void ReceiveDataFromCanBus()
                         byte value[4];
                         byte type;
 
-//                        if(!GetRealIndexByGroup(&address))
-//                            break;
-
                         memcpy(value, frame.data + 4, sizeof(value));
                         ReturnValue = IEEE_754_to_float(value);
                         if (frame.data[0] == ((FAN_SPEED_CMD >> 8) & 0xFF) && frame.data[1] == (FAN_SPEED_CMD & 0xFF))
                         {
                             type = 1;
                             return_mis_info(address, ReturnValue, type);
-                            //PRINTF_LIB_FUNC("address = %d, FanSpeed = %f \n", address, FanSpeed);
                         }
                         else if (frame.data[0] == ((TEMP_DC_CMD >> 8) & 0xFF) && frame.data[1] == (TEMP_DC_CMD & 0xFF))
                         {
                             type = 2;
                             return_mis_info(address, ReturnValue, type);
-                            //PRINTF_LIB_FUNC("address = %d, FanSpeed = %f \n", address, FanSpeed);
                         }
                         else if (frame.data[0] == ((TEMP_DC_CMD >> 8) & 0xFF) && frame.data[1] == (TEMP_DC_CMD & 0xFF))
                         {
                             type = 3;
                             return_mis_info(address, ReturnValue, type);
-                            //PRINTF_LIB_FUNC("address = %d, FanSpeed = %f \n", address, FanSpeed);
                         }
                     }
                         break;
@@ -454,14 +448,12 @@ void ReceiveDataFromCanBus()
 
                         // 回傳版號 : 無系統回覆功能
                         address = frame.can_id & 0x000000FF;
-//                        if(!GetRealIndexByGroup(&address))
-//                            break;
 
                         short dcSwVer = ((frame.data[0] << 8) + frame.data[1]);
                         short pfcSwVer = ((frame.data[2] << 8) + frame.data[3]);
                         short hwVer = ((frame.data[4] << 8) + frame.data[5]);
 
-                        return_fw_version(address, dcSwVer, pfcSwVer, hwVer);
+                        return_fw_version(address, dcSwVer, pfcSwVer, hwVer, PSU_PROTOCOL_TYPE);
                         //PRINTF_LIB_FUNC("address = %d, DC %d, PFC %d, HW %d \n", address, dcSwVer, pfcSwVer, hwVer);
                     }
                         break;
@@ -479,8 +471,6 @@ void ReceiveDataFromCanBus()
 
                         // 回傳三向輸入電壓
                         address = frame.can_id & 0x000000FF;
-//                        if(!GetRealIndexByGroup(&address))
-//                            break;
 
                         short abVol = ((frame.data[0] << 8) + frame.data[1]) / 10;
                         short bcVol = ((frame.data[2] << 8) + frame.data[3]) / 10;
@@ -500,9 +490,6 @@ void ReceiveDataFromCanBus()
 						memcpy(vol, frame.data, 4);
 						memcpy(cur, frame.data + 4, 4);
 
-//						if (!GetRealIndexByGroup(&address))
-//							break;
-
 						float _Vol = IEEE_754_to_float(vol);
 						float _Cur = IEEE_754_to_float(cur);
 
@@ -525,16 +512,14 @@ void ReceiveDataFromCanBus()
                         /*Test mode used*/
                         // 回傳輸出值與入風口溫度
                         address = frame.can_id & 0x000000FF;
-//                        if(!GetRealIndexByGroup(&address))
-//                            break;
 
                         short outputVol = ((frame.data[0] << 8) + frame.data[1]);
                         short outputCur = ((frame.data[2] << 8) + frame.data[3]);
                         short outputPow = ((frame.data[4] << 8) + frame.data[5]);
                         byte temp = frame.data[6];
 
-                        return_output_temp(address, outputVol, outputCur, outputPow, temp);
-                        //PRINTF_LIB_FUNC("address = %d, abVol = %d, bcVol = %d, caVol = %d \n", address, abVol, bcVol, caVol);
+                        return_output_temp(address, outputVol, outputCur, outputPow, temp, PSU_PROTOCOL_TYPE);
+                        //printf("address = %d, outputVol = %d \n", address, outputVol);
                     }
                         break;
                     case Nexton_PSU_StatusEvent:
@@ -545,8 +530,6 @@ void ReceiveDataFromCanBus()
                         /*Test mode used*/
                         // 回傳輸出值與入風口溫度
                         address = frame.can_id & 0x000000FF;
-//                        if(!GetRealIndexByGroup(&address))
-//                            break;
 
                         byte isErr =  (frame.data[0] >> 0) & 0x01;
                         byte status = (frame.data[0] >> 1) & 0x01;
@@ -567,8 +550,6 @@ void ReceiveDataFromCanBus()
                         /*Test mode used*/
                         // 回傳輸出值與入風口溫度
                         address = frame.can_id & 0x000000FF;
-//                        if(!GetRealIndexByGroup(&address))
-//                            break;
 
                         short vR = ((frame.data[0] << 8) + frame.data[1]);
                         short vS = ((frame.data[2] << 8) + frame.data[3]);
@@ -709,7 +690,7 @@ void FlashLed(byte group, byte value)
 	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
 }
 
-void PresentOutputVol(byte group, int voltage, int current)
+void PresentOutputVol(byte group, int voltage, int current, byte psuCount)
 {
 	byte data[8];
     PwrFrame PwrFrameMsg;
@@ -940,8 +921,11 @@ void GetSingleModuleOutputF(byte moduleIndex)
 /***                                   Get                                      ***/
 /***                                                                            ***/
 /**********************************************************************************/
-void GetStatus(byte group)
+void GetStatus(byte group, byte param)
 {
+	if (param == LIB_NO_USE)
+		return;
+
 	byte data[8];
     PwrFrame PwrFrameMsg;
     PwrFrameMsg.PwrMessage = 0;

+ 14 - 7
EVSE/Modularization/Infypwr_PsuCommObj.h

@@ -19,6 +19,7 @@
 #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>
@@ -39,6 +40,9 @@
 #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
@@ -58,6 +62,8 @@
 #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;
@@ -222,7 +228,7 @@ struct INFY_POW_MODULE_INFO
 	byte psuCount;
 };
 
-struct INFY_POW_MODULE_INFO infy_pow_info[2];
+struct INFY_POW_MODULE_INFO infy_pow_info[4];
 
 /*Initialization*/
 bool InitialCommunication();
@@ -231,7 +237,7 @@ bool InitialCommunication();
 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);
+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();
@@ -245,7 +251,7 @@ 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);
+void GetStatus(byte group, byte param);
 void GetFanSpeed(byte group);
 void GetDcTemperature(byte group);
 void GetPfcTemperature(byte group);
@@ -264,7 +270,8 @@ void ChangePsuBaudrate(short baudrate);
 
 /* Callback Function */
 void RefreshStatus(void *func);
-void (*return_status)(byte group, byte address, byte temp, int status);
+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);
@@ -273,7 +280,7 @@ 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);
+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);
@@ -282,7 +289,7 @@ 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);
+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);
@@ -293,7 +300,7 @@ void (*return_iavail_info)(byte address, unsigned short Iavail, unsigned short V
 /*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);
+		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,

+ 8 - 1
EVSE/Modularization/Makefile

@@ -10,7 +10,7 @@ Lib_Openssl = "-L../GPL/openssl-1.1.1n/release/lib" -lssl
 all: clean Module_RFIDLib Module_SystexLib Infypwr_PsuCommObj Phihong_PsuCommObj Module_RatedCurrentLib Module_UpgradeLib \
      Module_Wifi Module_4g WebServiceLib Module_EventLogging Module_ProduceUtils Module_DcMeter Module_PowerSharing_Task \
      Ocpp16 Ocpp20 Ocppph \
-     Module_Payment Module_Payment_Bazel8
+     Module_Payment Module_Payment_Bazel8 UUpwr_PsuCommObj
 
 clean:
 	rm -f libModule_RFID.a
@@ -23,6 +23,7 @@ clean:
 	rm -f libPhihong_PsuCommObj.a
 	rm -f libModule_Upgrade.a
 	rm -f libInfypwr_PsuCommObj.a
+	rm -f libUUpwr_PsuCommObj.a
 	rm -f Module_ProduceUtils
 	rm -f Module_PhBackend
 	rm -f OcppBackend20
@@ -118,6 +119,12 @@ Infypwr_PsuCommObj:
 	$(AR) -r libInfypwr_PsuCommObj.a Infypwr_PsuCommObj.o
 	rm -f Infypwr_PsuCommObj.o
 
+UUpwr_PsuCommObj:
+	rm -f libUUpwr_PsuCommObj.a
+	$(CC) -D $(Project) -O0  -Wall -c -fmessage-length=0 -o UUpwr_PsuCommObj.o UUpwr_PsuCommObj.c
+	$(AR) -r libUUpwr_PsuCommObj.a UUpwr_PsuCommObj.o
+	rm -f UUpwr_PsuCommObj.o
+
 Module_UpgradeLib:
 	@echo "===== Module_UpgradeLib =========================================="
 	rm -f libModule_Upgrade.a

+ 1303 - 0
EVSE/Modularization/UUpwr_PsuCommObj.c

@@ -0,0 +1,1303 @@
+/*
+ * UUpwr_PsuCommObj.c
+ *
+ *  Created on: 2022年3月30日
+ *      Author: 7564
+ */
+
+#include "UUpwr_PsuCommObj.h"
+
+//================================================
+// Callback function
+//================================================
+void RefreshStatus(void *func)
+{
+	return_status = func;
+}
+
+void RefreshModuleCount(void *func)
+{
+	return_module_count = func;
+}
+
+void RefreshAvailableCap(void *func)
+{
+	return_available_cap = func;
+}
+
+void RefreshFwVersion(void *func)
+{
+	return_fw_version = func;
+}
+
+void RefreshInputVol(void *func)
+{
+	return_input_vol = func;
+}
+
+void RefreshGetOutput(void *func)
+{
+	return_get_output = func;
+}
+
+void RefreshGetOutputF(void *func)
+{
+	return_get_output_float = func;
+}
+
+void RefreshMisInfo(void *func)
+{
+	return_mis_info = func;
+}
+
+void RefreshIavailable(void *func)
+{
+	return_iavail_info = func;
+}
+
+void AutoMode_RefreshOutputAndTemp(void *func)
+{
+	return_output_temp = func;
+}
+
+void AutoMode_RefreshModuleStatus(void *func)
+{
+	return_module_status = func;
+}
+
+void AutoMode_RefreshModuleInput(void *func)
+{
+	return_module_input = func;
+}
+
+//================================================
+// Private Function
+//================================================
+int UU_GetTimeoutValue(struct timespec *startTime)
+{
+	struct timespec endTime;
+
+	clock_gettime(CLOCK_MONOTONIC_COARSE, &endTime);
+	return (endTime.tv_nsec - startTime->tv_nsec) / 1000000;
+}
+
+void UU_GetTimespecFunc(struct timespec *time)
+{
+	clock_gettime(CLOCK_MONOTONIC_COARSE, time);
+}
+
+void SendCmdToPsu(int cmd, byte *data, byte dataLen)
+{
+    PwrFrame PwrFrameMsg;
+    struct can_frame frame;
+
+    //設定 CANBSU 2.0B 長封包
+    PwrFrameMsg.PwrMessage = cmd | 0x80000000;
+
+    frame.can_id = PwrFrameMsg.PwrMessage;
+    frame.can_dlc = dataLen;
+    memcpy(frame.data, data, dataLen);
+
+    write(CanFd, &frame, sizeof(struct can_frame));
+}
+
+int InitCanBus()
+{
+	int 					s0,nbytes;
+	struct timeval			tv;
+	struct ifreq 			ifr0;
+	struct sockaddr_can		addr0;
+	//struct can_filter 		rfilter[2];
+
+	system("/sbin/ip link set can1 down");
+	system("/sbin/ip link set can1 type can bitrate 500000 restart-ms 100");
+	system("/sbin/ip link set can1 up");
+
+	s0 = socket(PF_CAN, SOCK_RAW, CAN_RAW);
+
+	tv.tv_sec = 0;
+	tv.tv_usec = 10000;
+   	if (setsockopt(s0, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct	timeval)) < 0)
+	{
+		#ifdef SystemLogMessage
+   		PRINTF_LIB_FUNC("Set SO_RCVTIMEO NG");
+		#endif
+	}
+	nbytes=40960;
+	if (setsockopt(s0, SOL_SOCKET,  SO_RCVBUF, &nbytes, sizeof(int)) < 0)
+	{
+		#ifdef SystemLogMessage
+		PRINTF_LIB_FUNC("Set SO_RCVBUF NG");
+		#endif
+	}
+	nbytes=40960;
+	if (setsockopt(s0, SOL_SOCKET, SO_SNDBUF, &nbytes, sizeof(int)) < 0)
+	{
+		#ifdef SystemLogMessage
+		PRINTF_LIB_FUNC("Set SO_SNDBUF NG");
+		#endif
+	}
+	nbytes=40960;
+
+   	strcpy(ifr0.ifr_name, "can1" );
+	ioctl(s0, SIOCGIFINDEX, &ifr0); /* ifr.ifr_ifindex gets filled with that device's index */
+	addr0.can_family = AF_CAN;
+	addr0.can_ifindex = ifr0.ifr_ifindex;
+	bind(s0, (struct sockaddr *)&addr0, sizeof(addr0));
+	return s0;
+}
+
+void SetOutputVoltage(byte group, int voltage)
+{
+	byte data[8];
+	PwrFrame PwrFrameMsg;
+	PwrFrameMsg.PwrMessage = 0;
+
+	PwrFrameMsg.UUBits.Protocol = 0x01;
+	PwrFrameMsg.UUBits.MonitorAddress = PSU_MONITOR_DEFAULT;
+	// module id
+	if (group == SYSTEM_CMD)
+		PwrFrameMsg.UUBits.ModuleAddress = PSU_MODULE_BROADCAST;
+	else
+		PwrFrameMsg.UUBits.ModuleAddress = group;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	// Group
+	if (group == SYSTEM_CMD)
+		data[0] = 0x00;
+	else
+		data[0] = group + 1;
+	// Message Type
+	data[0] = data[0] << 4;
+	data[0] |= PSU_MSG_CMD_SET_PARAM;
+	// Command Type
+	data[1] = PSU_W_OUTPUT_VOL;
+	// Command Data
+	data[4] = (voltage >> 24) & 0xFF;
+	data[5] = (voltage >> 16) & 0xFF;
+	data[6] = (voltage >> 8) & 0xFF;
+	data[7] = voltage & 0xFF;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void SetOutputCurrent(byte group, int current)
+{
+	byte data[8];
+	PwrFrame PwrFrameMsg;
+	PwrFrameMsg.PwrMessage = 0;
+
+	PwrFrameMsg.UUBits.Protocol = 0x01;
+	PwrFrameMsg.UUBits.MonitorAddress = PSU_MONITOR_DEFAULT;
+	// module id
+	if (group == SYSTEM_CMD)
+		PwrFrameMsg.UUBits.ModuleAddress = PSU_MODULE_BROADCAST;
+	else
+		PwrFrameMsg.UUBits.ModuleAddress = group;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	// Group
+	if (group == SYSTEM_CMD)
+		data[0] = 0x00;
+	else
+		data[0] = group + 1;
+	// Message Type
+	data[0] = data[0] << 4;
+	data[0] |= PSU_MSG_CMD_SET_PARAM;
+	// Command Type
+	data[1] = PSU_W_OUTPUT_CUR;
+	// Command Data
+	data[4] = (current >> 24) & 0xFF;
+	data[5] = (current >> 16) & 0xFF;
+	data[6] = (current >> 8) & 0xFF;
+	data[7] = current & 0xFF;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void GetFastOutputVol(byte group)
+{
+	byte data[8];
+	PwrFrame PwrFrameMsg;
+	PwrFrameMsg.PwrMessage = 0;
+	PwrFrameMsg.UUBits.Protocol = 0x01;
+	PwrFrameMsg.UUBits.MonitorAddress = PSU_MONITOR_DEFAULT;
+	// module id
+	//if (group == SYSTEM_CMD)
+		PwrFrameMsg.UUBits.ModuleAddress = PSU_MODULE_BROADCAST;
+	//else
+	//	PwrFrameMsg.UUBits.ModuleAddress = group;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	// Group
+	if (group == SYSTEM_CMD)
+		data[0] = 0x00;
+	else
+		data[0] = group + 1;
+	// Message Type
+	data[0] = data[0] << 4;
+	data[0] |= PSU_MSG_CMD_READ_MSG;
+	// Command Type
+	data[1] = PSU_R_FAST_OUTPUT_VOL;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void GetFastOutputCur(byte group)
+{
+	byte data[8];
+	PwrFrame PwrFrameMsg;
+	PwrFrameMsg.PwrMessage = 0;
+	PwrFrameMsg.UUBits.Protocol = 0x01;
+	PwrFrameMsg.UUBits.MonitorAddress = PSU_MONITOR_DEFAULT;
+	// module id
+	//if (group == SYSTEM_CMD)
+		PwrFrameMsg.UUBits.ModuleAddress = PSU_MODULE_BROADCAST;
+	//else
+	//	PwrFrameMsg.UUBits.ModuleAddress = group;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	// Group
+	if (group == SYSTEM_CMD)
+		data[0] = 0x00;
+	else
+		data[0] = group + 1;
+	// Message Type
+	data[0] = data[0] << 4;
+	data[0] |= PSU_MSG_CMD_READ_MSG;
+	// Command Type
+	data[1] = PSU_R_FAST_OUTPUT_CUR;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void GetOutputPowCap(byte group)
+{
+	byte data[8];
+	PwrFrame PwrFrameMsg;
+	PwrFrameMsg.PwrMessage = 0;
+
+	PwrFrameMsg.UUBits.Protocol = 0x01;
+	PwrFrameMsg.UUBits.MonitorAddress = PSU_MONITOR_DEFAULT;
+	// module id
+	//if (group == SYSTEM_CMD)
+		PwrFrameMsg.UUBits.ModuleAddress = PSU_MODULE_BROADCAST;
+	//else
+	//	PwrFrameMsg.UUBits.ModuleAddress = group;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	// Group
+	if (group == SYSTEM_CMD)
+		data[0] = 0x00;
+	else
+		data[0] = group + 1;
+	// Message Type
+	data[0] = data[0] << 4;
+	data[0] |= PSU_MSG_CMD_READ_MSG;
+	// Command Type
+	data[1] = PSU_R_OUTPUT_POW_CAP;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void GetOutputCurCap(byte group)
+{
+	byte data[8];
+	PwrFrame PwrFrameMsg;
+	PwrFrameMsg.PwrMessage = 0;
+
+	PwrFrameMsg.UUBits.Protocol = 0x01;
+	PwrFrameMsg.UUBits.MonitorAddress = PSU_MONITOR_DEFAULT;
+	// module id
+	if (group == SYSTEM_CMD)
+		PwrFrameMsg.UUBits.ModuleAddress = PSU_MODULE_BROADCAST;
+	else
+		PwrFrameMsg.UUBits.ModuleAddress = group;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	// Group
+	if (group == SYSTEM_CMD)
+		data[0] = 0x00;
+	else
+		data[0] = group + 1;
+	// Message Type
+	data[0] = data[0] << 4;
+	data[0] |= PSU_MSG_CMD_READ_MSG;
+	// Command Type
+	data[1] = PSU_R_OUTPUT_CUR_CAP;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void GetPsuMaxVoltage(byte group)
+{
+	byte data[8];
+	PwrFrame PwrFrameMsg;
+	PwrFrameMsg.PwrMessage = 0;
+	PwrFrameMsg.UUBits.Protocol = 0x01;
+	PwrFrameMsg.UUBits.MonitorAddress = PSU_MONITOR_DEFAULT;
+	// module id
+	//if (group == SYSTEM_CMD)
+	PwrFrameMsg.UUBits.ModuleAddress = PSU_MODULE_BROADCAST;
+	//else
+	//	PwrFrameMsg.UUBits.ModuleAddress = group;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	// Group
+	if (group == SYSTEM_CMD)
+		data[0] = 0x00;
+	else
+		data[0] = group + 1;
+	// Message Type
+	data[0] = data[0] << 4;
+	data[0] |= PSU_MSG_CMD_READ_MSG;
+	// Command Type
+	data[1] = PSU_R_MAX_VOL;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void GetTemperature(byte group)
+{
+	byte data[8];
+	PwrFrame PwrFrameMsg;
+	PwrFrameMsg.PwrMessage = 0;
+
+	PwrFrameMsg.UUBits.Protocol = 0x01;
+	PwrFrameMsg.UUBits.MonitorAddress = PSU_MONITOR_DEFAULT;
+	// module id
+	if (group == SYSTEM_CMD)
+		PwrFrameMsg.UUBits.ModuleAddress = PSU_MODULE_BROADCAST;
+	else
+		PwrFrameMsg.UUBits.ModuleAddress = group;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	// Group
+	if (group == SYSTEM_CMD)
+		data[0] = 0x00;
+	else
+		data[0] = group + 1;
+	// Message Type
+	data[0] = data[0] << 4;
+	data[0] |= PSU_MSG_CMD_READ_MSG;
+	// Command Type
+	data[1] = PSU_R_TEMP;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void GetInputVoltageL12(byte group)
+{
+	byte data[8];
+	PwrFrame PwrFrameMsg;
+	PwrFrameMsg.PwrMessage = 0;
+
+	PwrFrameMsg.UUBits.Protocol = 0x01;
+	PwrFrameMsg.UUBits.MonitorAddress = PSU_MONITOR_DEFAULT;
+	// module id
+	if (group == SYSTEM_CMD)
+		PwrFrameMsg.UUBits.ModuleAddress = PSU_MODULE_BROADCAST;
+	else
+		PwrFrameMsg.UUBits.ModuleAddress = group;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	// Group
+	if (group == SYSTEM_CMD)
+		data[0] = 0x00;
+	else
+		data[0] = group + 1;
+	// Message Type
+	data[0] = data[0] << 4;
+	data[0] |= PSU_MSG_CMD_READ_MSG;
+	// Command Type
+	data[1] = PSU_R_VIN_L12;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void GetInputVoltageL23(byte group)
+{
+	byte data [8];
+	PwrFrame PwrFrameMsg;
+	PwrFrameMsg.PwrMessage = 0;
+
+	PwrFrameMsg.UUBits.Protocol = 0x01;
+	PwrFrameMsg.UUBits.MonitorAddress = PSU_MONITOR_DEFAULT;
+	// module id
+	if (group == SYSTEM_CMD)
+		PwrFrameMsg.UUBits.ModuleAddress = PSU_MODULE_BROADCAST;
+	else
+		PwrFrameMsg.UUBits.ModuleAddress = group;
+
+	memset ( data, 0x00, ARRAY_SIZE( data ) );
+	// Group
+	if (group == SYSTEM_CMD)
+		data [0] = 0x00;
+	else
+		data [0] = group + 1;
+	// Message Type
+	data [0] = data [0] << 4;
+	data [0] |= PSU_MSG_CMD_READ_MSG;
+	// Command Type
+	data [1] = PSU_R_VIN_L23;
+
+	SendCmdToPsu ( PwrFrameMsg.PwrMessage, data, sizeof(data) );
+}
+
+void GetInputVoltageL31(byte group)
+{
+	byte data [8];
+	PwrFrame PwrFrameMsg;
+	PwrFrameMsg.PwrMessage = 0;
+
+	PwrFrameMsg.UUBits.Protocol = 0x01;
+	PwrFrameMsg.UUBits.MonitorAddress = PSU_MONITOR_DEFAULT;
+	// module id
+	if (group == SYSTEM_CMD)
+		PwrFrameMsg.UUBits.ModuleAddress = PSU_MODULE_BROADCAST;
+	else
+		PwrFrameMsg.UUBits.ModuleAddress = group;
+
+	memset ( data, 0x00, ARRAY_SIZE( data ) );
+	// Group
+	if (group == SYSTEM_CMD)
+		data [0] = 0x00;
+	else
+		data [0] = group + 1;
+	// Message Type
+	data [0] = data [0] << 4;
+	data [0] |= PSU_MSG_CMD_READ_MSG;
+	// Command Type
+	data [1] = PSU_R_VIN_L31;
+
+	SendCmdToPsu ( PwrFrameMsg.PwrMessage, data, sizeof(data) );
+}
+
+void GetDc2DcVersion(byte group)
+{
+	byte data[8];
+	PwrFrame PwrFrameMsg;
+	PwrFrameMsg.PwrMessage = 0;
+	PwrFrameMsg.UUBits.Protocol = 0x01;
+	PwrFrameMsg.UUBits.MonitorAddress = PSU_MONITOR_DEFAULT;
+	// module id
+	//if (group == SYSTEM_CMD)
+	PwrFrameMsg.UUBits.ModuleAddress = PSU_MODULE_BROADCAST;
+	//else
+	//	PwrFrameMsg.UUBits.ModuleAddress = group;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	// Group
+	if (group == SYSTEM_CMD)
+		data[0] = 0x00;
+	else
+		data[0] = group + 1;
+	// Message Type
+	data[0] = data[0] << 4;
+	data[0] |= PSU_MSG_CMD_READ_MSG;
+	// Command Type
+	data[1] = PSU_R_DD_VERSION;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void GetPfcVersion(byte group)
+{
+	byte data[8];
+	PwrFrame PwrFrameMsg;
+	PwrFrameMsg.PwrMessage = 0;
+	PwrFrameMsg.UUBits.Protocol = 0x01;
+	PwrFrameMsg.UUBits.MonitorAddress = PSU_MONITOR_DEFAULT;
+	// module id
+	//if (group == SYSTEM_CMD)
+	PwrFrameMsg.UUBits.ModuleAddress = PSU_MODULE_BROADCAST;
+	//else
+	//	PwrFrameMsg.UUBits.ModuleAddress = group;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	// Group
+	if (group == SYSTEM_CMD)
+		data[0] = 0x00;
+	else
+		data[0] = group + 1;
+	// Message Type
+	data[0] = data[0] << 4;
+	data[0] |= PSU_MSG_CMD_READ_MSG;
+	// Command Type
+	data[1] = PSU_R_PFC_VERSION;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+//================================================
+// Receive data from CANBUS Function
+//================================================
+void SendCallback()
+{
+	int _passTime = UU_GetTimeoutValue ( & ShmTimelineData._getCount_time );
+	if (_passTime < 0)
+		UU_GetTimespecFunc(&ShmTimelineData._getCount_time);
+	else if (ShmTimelineData._getCountChk && _passTime > 200)
+	{
+		ShmUuPowerData.totalPsuCount = 0;
+		for (byte i = 0; i < 2; i ++)
+		{
+			if (ShmUuPowerData.uu_pow_info [i].psuCount > 0)
+			{
+				return_module_count ( i, ShmUuPowerData.uu_pow_info [i].psuCount );
+				ShmUuPowerData.totalPsuCount += ShmUuPowerData.uu_pow_info [i].psuCount;
+			}
+		}
+
+		return_module_count (SYSTEM_CMD, ShmUuPowerData.totalPsuCount);
+		ShmTimelineData._getCountChk = LIB_STOP;
+		ShmUuPowerData._getCountIndexComp = LIB_START;
+	}
+}
+
+void ReceiveDataFromCanBus()
+{
+	int nbytes;
+	struct can_frame frame;
+	PwrFrame *PwrFrameMsg;
+	byte group;
+
+	memset(&ShmUuPowerData, 0, sizeof(struct UuPowerInformation));
+	memset(&ShmTimelineData, 0, sizeof(struct TimelineInfor));
+
+	while(1)
+	{
+		SendCallback();
+
+		memset(&frame, 0, sizeof(struct can_frame));
+		nbytes = read(CanFd, &frame, sizeof(struct can_frame));
+
+		if (nbytes > 0)
+		{
+            PwrFrameMsg = (PwrFrame *)&frame.can_id;
+            //byte protocol = PwrFrameMsg->UUBits.Protocol;
+            byte moduleAddr = PwrFrameMsg->UUBits.ModuleAddress;
+            //byte monitorAddr = PwrFrameMsg->UUBits.MonitorAddress;
+
+            // Group 從0開始~ 但 UU 從 1 開始~
+            group = ((frame.data[0] & 0xF0) >> 4) - 1;
+			//printf("group = %d \n", group);
+			//printf("moduleAddr = %d \n", moduleAddr);
+			//printf("monitorAddr = %d \n", monitorAddr);
+//			printf("data[0] = %d, data[1] = %d, data[2] = %d, data[3] = %d, data[4] = %d, data[5] = %d, data[6] = %d, data[7] = %d \n",
+//					frame.data[0], frame.data[1], frame.data[2], frame.data[3],
+//					frame.data[4], frame.data[5], frame.data[6], frame.data[7]);
+
+            switch (frame.data[1])
+            {
+            	case PSU_R_MODULE_COUNT:
+            	{
+            		//printf("----------PSU_R_GET_COUNT---------- \n");
+            	    bool isFind = false;
+            	    for (byte i = 0; i < ShmUuPowerData.uu_pow_info[group].psuCount; i++)
+            	    {
+            	    	if (ShmUuPowerData.uu_pow_info[group].psuInfo[i].targetNumber == moduleAddr)
+            	    		isFind = true;
+            	    }
+
+            	    if (!isFind)
+            	    {
+            	    	ShmUuPowerData.uu_pow_info[group].psuInfo[ShmUuPowerData.uu_pow_info[group].psuCount].targetNumber = moduleAddr;
+            	        ShmUuPowerData.uu_pow_info[group].psuCount++;
+            	    }
+
+            	    if (ShmTimelineData._getCountChk == LIB_STOP)
+            	    {
+            	    	ShmTimelineData._getCountChk = LIB_START;
+            	    	UU_GetTimespecFunc(&ShmTimelineData._getCount_time);
+            	    }
+            	}
+            	break;
+            }
+
+            if (ShmUuPowerData._getCountIndexComp)
+            {
+				switch (frame.data[1])
+				{
+					case PSU_R_FAST_OUTPUT_VOL:
+					{
+						//printf("----------PSU_R_FAST_OUTPUT_VOL---------- \n");
+						float _vol = 0, _cur = 0;
+						for(byte count = 0; count < ShmUuPowerData.uu_pow_info[group].psuCount; count++)
+						{
+							if (ShmUuPowerData.uu_pow_info[group].psuInfo[count].targetNumber == moduleAddr)
+							{
+								ShmUuPowerData.uu_pow_info[group].psuInfo[count].outputVol =
+										((frame.data[4] << 24 | frame.data[5] << 16 | frame.data[6] << 8 | frame.data[7])) / 100;
+							}
+
+							if (ShmUuPowerData.uu_pow_info[group].psuInfo[count].outputVol > 0)
+							{
+								if (_vol == 0 || ShmUuPowerData.uu_pow_info[group].psuInfo[count].outputVol < _vol)
+									_vol = ShmUuPowerData.uu_pow_info[group].psuInfo[count].outputVol;
+							}
+
+							_cur += ShmUuPowerData.uu_pow_info[group].psuInfo[count].outputCur;
+						}
+
+						ShmUuPowerData.uu_pow_info[group].presentVol = _vol;
+						ShmUuPowerData.uu_pow_info[group].presentCur = _cur;
+
+						return_get_output_float(group,
+								ShmUuPowerData.uu_pow_info [group].presentVol,
+								ShmUuPowerData.uu_pow_info [group].presentCur,
+								PSU_PROTOCOL_TYPE );
+					}
+						break;
+					case PSU_R_FAST_OUTPUT_CUR:
+					{
+						//printf("----------PSU_R_OUTPUT_CUR---------- \n");
+						for(byte count = 0; count < ShmUuPowerData.uu_pow_info[group].psuCount; count++)
+						{
+							if (ShmUuPowerData.uu_pow_info[group].psuInfo[count].targetNumber == moduleAddr)
+							{
+								ShmUuPowerData.uu_pow_info[group].psuInfo[count].outputCur =
+										((frame.data[4] << 24 | frame.data[5] << 16 | frame.data[6] << 8 | frame.data[7])) / 100;
+								break;
+							}
+						}
+	//
+	//					ShmUuPowerData.uu_pow_info[group].presentCur = ((frame.data[4] << 24 | frame.data[5] << 16 | frame.data[6] << 8 | frame.data[7])) / 100;
+	//					return_get_output_float(group,
+	//					    ShmUuPowerData.uu_pow_info[group].presentVol,
+	//						ShmUuPowerData.uu_pow_info[group].presentCur,
+	//						PSU_PROTOCOL_TYPE);
+					}
+						break;
+					case PSU_R_DD_VERSION:
+					{
+						//printf("----------PSU_R_DD_VERSION---------- \n");
+						for(byte count = 0; count < ShmUuPowerData.uu_pow_info[group].psuCount; count++)
+						{
+							if (ShmUuPowerData.uu_pow_info[group].psuInfo[count].targetNumber == moduleAddr)
+							{
+								ShmUuPowerData.uu_pow_info[group].psuInfo[count].dc2dcVersion =
+										((frame.data[6] << 8) + frame.data[7]);
+
+								byte psuIndexAddr = moduleAddr;
+								if (group > 0)
+								{
+									psuIndexAddr = moduleAddr + ShmUuPowerData.uu_pow_info[group - 1].psuCount;
+								}
+								return_fw_version(psuIndexAddr,
+										ShmUuPowerData.uu_pow_info[group].psuInfo[count].dc2dcVersion,
+										ShmUuPowerData.uu_pow_info[group].psuInfo[count].pfcVersion,
+										LIB_UU_HW_VERSIION,
+										PSU_PROTOCOL_TYPE);
+								break;
+							}
+						}
+					}
+						break;
+					case PSU_R_PFC_VERSION:
+					{
+						//printf("----------PSU_R_PFC_VERSION---------- \n");
+						for(byte count = 0; count < ShmUuPowerData.uu_pow_info[group].psuCount; count++)
+						{
+							if (ShmUuPowerData.uu_pow_info[group].psuInfo[count].targetNumber == moduleAddr)
+							{
+								ShmUuPowerData.uu_pow_info[group].psuInfo[count].pfcVersion =
+										((frame.data[6] << 8) + frame.data[7]);
+
+								byte psuIndexAddr = moduleAddr;
+								if (group > 0)
+								{
+									psuIndexAddr = moduleAddr + ShmUuPowerData.uu_pow_info[group - 1].psuCount;
+								}
+								return_fw_version(psuIndexAddr,
+										ShmUuPowerData.uu_pow_info[group].psuInfo[count].dc2dcVersion,
+										ShmUuPowerData.uu_pow_info[group].psuInfo[count].pfcVersion,
+										LIB_UU_HW_VERSIION,
+										PSU_PROTOCOL_TYPE);
+								break;
+							}
+						}
+					}
+						break;
+					case PSU_R_IAVAILABLE:
+					{
+						//printf("----------PSU_R_IAVAILABLE---------- \n");
+	//					printf("Group = %d, moduleAddr = %d, data[4] = %d, data[5] = %d, data[6] = %d, data[7] = %d \n",
+	//							group, moduleAddr,
+	//							frame.data[4], frame.data[5], frame.data[6], frame.data[7]);
+						for(byte count = 0; count < ShmUuPowerData.uu_pow_info[group].psuCount; count++)
+						{
+							if (ShmUuPowerData.uu_pow_info[group].psuInfo[count].targetNumber == moduleAddr)
+							{
+								byte psuIndexAddr = moduleAddr;
+								if (group > 0)
+								{
+									psuIndexAddr = moduleAddr + ShmUuPowerData.uu_pow_info[group - 1].psuCount;
+								}
+
+								return_iavail_info(psuIndexAddr, ((frame.data[6] << 8) + frame.data[7]) / 1, LIB_NO_USE);
+								break;
+							}
+						}
+					}
+						break;
+					case PSU_W_OUTPUT_VOL:
+					{
+						printf("----------PSU_W_OUTPUT_VOL_CAP---------- \n");
+					}
+						break;
+					case PSU_W_OUTPUT_CUR:
+					{
+						printf("----------PSU_W_OUTPUT_CUR_CAP---------- \n");
+					}
+						break;
+					case PSU_R_SERIAL_NUM:
+					{
+						printf("----------PSU_R_SERIAL_NUM---------- \n");
+					}
+						break;
+					case PSU_R_STATUS:
+					{
+						//printf("----------PSU_R_STATUS---------- \n");
+						byte psuIndexAddr = moduleAddr;
+						if (group > 0)
+						{
+							psuIndexAddr = moduleAddr + ShmUuPowerData.uu_pow_info[group - 1].psuCount;
+						}
+
+						return_status(group, psuIndexAddr, LIB_NO_USE, LIB_NO_USE, PSU_PROTOCOL_TYPE,
+								frame.data[4], frame.data[5], frame.data[6], frame.data[7]);
+					}
+						break;
+					case PSU_R_OUTPUT_POW_CAP:
+					{
+						int pow = (frame.data[4] << 24 | frame.data[5] << 16 | frame.data[6] << 8 | frame.data[7]) / 10000;
+
+						if ((pow += 5) > 180)
+							pow = 180;
+
+						for(byte count = 0; count < ShmUuPowerData.uu_pow_info[group].psuCount; count++)
+						{
+							if (ShmUuPowerData.uu_pow_info[group].psuInfo[count].targetNumber == moduleAddr)
+							{
+								ShmUuPowerData.uu_pow_info[group].psuInfo[count].powerCap = pow;
+
+								byte psuIndexAddr = moduleAddr;
+								if (group > 0)
+								{
+									 psuIndexAddr = moduleAddr + ShmUuPowerData.uu_pow_info[group - 1].psuCount;
+								}
+
+								return_available_cap(psuIndexAddr,
+										LIB_PSU_MAX_VOL,
+										LIB_PSU_MIN_VOL,
+										LIB_PSU_MAX_CUR,
+										ShmUuPowerData.uu_pow_info[group].psuInfo[count].powerCap);
+								break;
+							}
+						}
+					}
+						break;
+					case PSU_R_OUTPUT_CUR_CAP:
+					{
+						// 因為高低壓設定的問題~該指令無法正常指令
+						int cur = (frame.data[4] << 24 | frame.data[5] << 16 | frame.data[6] << 8 | frame.data[7]) / 1000;
+
+						for(byte count = 0; count < ShmUuPowerData.uu_pow_info[group].psuCount; count++)
+						{
+							if (ShmUuPowerData.uu_pow_info[group].psuInfo[count].targetNumber == moduleAddr)
+							{
+								ShmUuPowerData.uu_pow_info[group].psuInfo[count].currentCap = cur;
+								break;
+							}
+						}
+					}
+						break;
+					case PSU_R_MAX_VOL:
+					{
+						// 因為高低壓設定的問題~該指令無法正常指令
+						int maxVol = ((frame.data[4] << 24 | frame.data[5] << 16 | frame.data[6] << 8 | frame.data[7]) / 100000) * 1000;
+
+						for(byte count = 0; count < ShmUuPowerData.uu_pow_info[group].psuCount; count++)
+						{
+							if (ShmUuPowerData.uu_pow_info[group].psuInfo[count].targetNumber == moduleAddr)
+							{
+								ShmUuPowerData.uu_pow_info[group].psuInfo[count].maxVoltage = maxVol;
+								break;
+							}
+						}
+					}
+						break;
+					case PSU_R_VIN_L12:
+					{
+						//printf("----------PSU_R_VIN_L12---------- \n");
+						for(byte count = 0; count < ShmUuPowerData.uu_pow_info[group].psuCount; count++)
+						{
+							if (ShmUuPowerData.uu_pow_info[group].psuInfo[count].targetNumber == moduleAddr)
+							{
+								ShmUuPowerData.uu_pow_info[group].psuInfo[count].inputVolL12 =
+										((frame.data[4] << 24 | frame.data[5] << 16 | frame.data[6] << 8 | frame.data[7])) / 1000;
+								break;
+							}
+						}
+					}
+						break;
+					case PSU_R_VIN_L23:
+					{
+						//printf("----------PSU_R_VIN_L23---------- \n");
+						for(byte count = 0; count < ShmUuPowerData.uu_pow_info[group].psuCount; count++)
+						{
+							if (ShmUuPowerData.uu_pow_info[group].psuInfo[count].targetNumber == moduleAddr)
+							{
+								ShmUuPowerData.uu_pow_info[group].psuInfo[count].inputVolL23 =
+										((frame.data[4] << 24 | frame.data[5] << 16 | frame.data[6] << 8 | frame.data[7])) / 1000;
+								break;
+							 }
+						 }
+					}
+						break;
+					case PSU_R_VIN_L31:
+					{
+						//printf("----------PSU_R_VIN_L31---------- \n");
+						for(byte count = 0; count < ShmUuPowerData.uu_pow_info[group].psuCount; count++)
+						{
+							if (ShmUuPowerData.uu_pow_info[group].psuInfo[count].targetNumber == moduleAddr)
+							{
+								ShmUuPowerData.uu_pow_info[group].psuInfo[count].inputVolL31 =
+										((frame.data[4] << 24 | frame.data[5] << 16 | frame.data[6] << 8 | frame.data[7])) / 1000;
+
+								byte psuIndexAddr = moduleAddr;
+								if (group > 0)
+								{
+									psuIndexAddr = moduleAddr + ShmUuPowerData.uu_pow_info[group - 1].psuCount;
+								}
+
+								return_input_vol(psuIndexAddr,
+										ShmUuPowerData.uu_pow_info[group].psuInfo[count].inputVolL12,
+										ShmUuPowerData.uu_pow_info[group].psuInfo[count].inputVolL23,
+										ShmUuPowerData.uu_pow_info[group].psuInfo[count].inputVolL31);
+								break;
+							}
+						}
+					}
+						break;
+					case PSU_R_TEMP:
+					{
+						//printf("----------PSU_R_TEMP---------- \n");
+						byte psuIndexAddr = moduleAddr;
+						if (group > 0)
+						{
+							psuIndexAddr = moduleAddr + ShmUuPowerData.uu_pow_info[group - 1].psuCount;
+						}
+
+						return_output_temp(psuIndexAddr, LIB_NO_USE, LIB_NO_USE, LIB_NO_USE, ((frame.data[6] << 8 | frame.data[7])) / 1000, PSU_PROTOCOL_TYPE);
+						//printf("temp = %02d \n", ((frame.data[6] << 8 | frame.data[7])) / 1000);
+					}
+						break;
+					case PSU_RW_GROUP:
+					{
+						printf("PSU_RW_GROUP : address = %d, group = %d \n",  moduleAddr, group);
+					}
+						break;
+					case PSU_W_HIGH_LOW_VOL_MODE:
+					{
+						//printf("----------PSU_W_HIGH_LOW_VOL_MODE---------- \n");
+					}
+						break;
+					case PSU_R_HIGH_LOW_VOL_MODE:
+					{
+						//printf("----------PSU_R_HIGH_LOW_VOL_MODE---------- \n");
+						printf("PSU_R_HIGH_LOW_VOL_MODE : G : %d, value : %d \n", group, frame.data[7]);
+					}
+						break;
+				}
+            }
+		}
+		else
+			usleep(10000);
+	}
+}
+
+//================================================
+// Public Function
+//================================================
+bool InitialCommunication()
+{
+	CanFd = InitCanBus();
+
+	if(CanFd < 0)
+	{
+		printf("Init can bus fail.... \n");
+		return false;
+	}
+
+    recFork = fork();
+    if(recFork == 0)
+    {
+    	ReceiveDataFromCanBus();
+	}
+
+//  callbackFunc = fork();
+//	if (callbackFunc == 0)
+//	{
+//		SendCallback();
+//	}
+
+    return true;
+}
+
+/*
+ * Data :
+ * byte 0 =>
+ 	0 ~ 3 bit : MessageType
+ 	4 ~ 7 bit : Group Address (1 ~ 15)
+ * byte 1 =>
+ 	Command Type
+ * byte 2、3 =>
+ 	Reserved
+ * byte 4 ~ 7 =>
+	Command Data
+ */
+/**********************************************************************************/
+/***                                                                            ***/
+/***                                   Get                                      ***/
+/***                                                                            ***/
+/**********************************************************************************/
+void GetGroup(byte address)
+{
+	byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+
+    PwrFrameMsg.UUBits.Protocol = 0x01;
+	PwrFrameMsg.UUBits.MonitorAddress = PSU_MONITOR_DEFAULT;
+	// module id
+    PwrFrameMsg.UUBits.ModuleAddress = 0x04;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	// Group
+	data[0] = 0x01;
+	// Message Type
+	data[0] = data[0] << 4;
+	data[0] |= PSU_MSG_CMD_READ_MSG;
+	// Command Type
+	data[1] = PSU_RW_GROUP;
+	// Reserved
+	data[2] = 0x00;
+	data[3] = 0x00;
+	// Command Data
+	data[4] = 0x00;
+	data[5] = 0x00;
+	data[6] = 0x00;
+	data[7] = 0x00;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void GetStatus(byte group, byte param)
+{
+	if (param == LIB_NO_USE)
+		return;
+
+	byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+
+    PwrFrameMsg.UUBits.Protocol = 0x01;
+	PwrFrameMsg.UUBits.MonitorAddress = PSU_MONITOR_DEFAULT;
+	// module id - 不管哪一群~ 都是對該群做群發動做
+	PwrFrameMsg.UUBits.ModuleAddress = PSU_MODULE_BROADCAST;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	// Group
+	if (group == SYSTEM_CMD)
+		data[0] = 0x00;
+	else
+		data[0] = group + 1;
+	// Message Type
+	data[0] = data[0] << 4;
+	data[0] |= PSU_MSG_CMD_READ_MSG;
+	// Command Type
+	data[1] = PSU_R_STATUS;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void GetModuleVoltageMode(byte group)
+{
+	byte data[8];
+	PwrFrame PwrFrameMsg;
+	PwrFrameMsg.PwrMessage = 0;
+
+	PwrFrameMsg.UUBits.Protocol = 0x01;
+	PwrFrameMsg.UUBits.MonitorAddress = PSU_MONITOR_DEFAULT;
+	// module id - 群發
+	if (group == SYSTEM_CMD)
+		PwrFrameMsg.UUBits.ModuleAddress = PSU_MODULE_BROADCAST;
+	else
+		PwrFrameMsg.UUBits.ModuleAddress = group;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	// Group
+	if (group == SYSTEM_CMD)
+		data[0] = 0x00;
+	else
+		data[0] = group + 1;
+	// Message Type
+	data[0] = data[0] << 4;
+	data[0] |= PSU_MSG_CMD_READ_MSG;
+	// Command Type
+	data[1] = PSU_R_HIGH_LOW_VOL_MODE;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+/**********************************************************************************/
+/***                                                                            ***/
+/***                                   Set                                      ***/
+/***                                                                            ***/
+/**********************************************************************************/
+void SetGroup(byte group, byte sourceAddr, byte targetAddr)
+{
+	byte data[8];
+	PwrFrame PwrFrameMsg;
+	PwrFrameMsg.PwrMessage = 0;
+
+	PwrFrameMsg.UUBits.Protocol = 0x01;
+	PwrFrameMsg.UUBits.MonitorAddress = PSU_MONITOR_DEFAULT;
+	// module id
+	PwrFrameMsg.UUBits.ModuleAddress = sourceAddr;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	// Group
+	data[0] = group + 1;
+	// Message Type
+	data[0] = data[0] << 4;
+	data[0] |= PSU_MSG_CMD_SET_PARAM;
+	// Command Type
+	data[1] = PSU_RW_GROUP;
+	// Reserved
+	data[2] = 0x00;
+	data[3] = 0x00;
+	// Command Data
+	data[7] = targetAddr;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void SetModuleVoltageMode(byte group, byte value)
+{
+	byte data[8];
+	PwrFrame PwrFrameMsg;
+	PwrFrameMsg.PwrMessage = 0;
+
+	PwrFrameMsg.UUBits.Protocol = 0x01;
+	PwrFrameMsg.UUBits.MonitorAddress = PSU_MONITOR_DEFAULT;
+	// module id
+	if (group == SYSTEM_CMD)
+		PwrFrameMsg.UUBits.ModuleAddress = PSU_MODULE_BROADCAST;
+	else
+		PwrFrameMsg.UUBits.ModuleAddress = group;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	// Group
+	if (group == SYSTEM_CMD)
+		data[0] = 0x00;
+	else
+		data[0] = group + 1;
+	// Message Type
+	data[0] = data[0] << 4;
+	data[0] |= PSU_MSG_CMD_SET_PARAM;
+	// Command Type
+	data[1] = PSU_W_HIGH_LOW_VOL_MODE;
+	// Command Data
+	data[4] = 0x00;
+	data[5] = 0x00;
+	data[6] = 0x00;
+	data[7] = value;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+
+
+
+
+
+/**********************************************************************************/
+/***                                                                            ***/
+/***                                   sdlu                                     ***/
+/***                                                                            ***/
+/**********************************************************************************/
+void SwitchPower(byte group, byte value)
+{
+	byte data[8];
+	PwrFrame PwrFrameMsg;
+	PwrFrameMsg.PwrMessage = 0;
+
+	PwrFrameMsg.UUBits.Protocol = 0x01;
+	PwrFrameMsg.UUBits.MonitorAddress = PSU_MONITOR_DEFAULT;
+	// module id
+	if (group == SYSTEM_CMD)
+		PwrFrameMsg.UUBits.ModuleAddress = PSU_MODULE_BROADCAST;
+	else
+		PwrFrameMsg.UUBits.ModuleAddress = group;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	// 1 : 關機
+	// 0 : 開機
+	// Group
+	if (group == SYSTEM_CMD)
+		data[0] = 0x00;
+	else
+		data[0] = group + 1;
+	// Message Type
+	data[0] = data[0] << 4;
+	data[0] |= PSU_MSG_CMD_SET_PARAM;
+	// Command Type
+	data[1] = PSU_W_SWITCH_POW;
+	// Command Data
+	data[4] = 0x00;
+	data[5] = 0x00;
+	data[6] = 0x00;
+	data[7] = value;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void GetModuleCount(byte group)
+{
+	byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.UUBits.Protocol = 0x01;
+    PwrFrameMsg.UUBits.MonitorAddress = PSU_MONITOR_DEFAULT;
+    // module id - 群發
+    if (group == SYSTEM_CMD)
+    	PwrFrameMsg.UUBits.ModuleAddress = PSU_MODULE_BROADCAST;
+    else
+    {
+    	PwrFrameMsg.UUBits.ModuleAddress = group;
+    }
+
+    memset(data, 0x00, ARRAY_SIZE(data));
+	if (group == SYSTEM_CMD)
+	{
+		// Group
+		data[0] = 0x01;
+		// Message Type
+		data[0] = data[0] << 4;
+		data[0] |= PSU_MSG_CMD_READ_MSG;
+		// Command Type
+		data[1] = PSU_R_MODULE_COUNT;
+
+		SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+
+		// Group
+		data[0] = 0x02;
+		SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+	}
+	else
+	{
+		// Group
+		data[0] = group + 1;
+		// Message Type
+		data[0] = data[0] << 4;
+		data[0] |= PSU_MSG_CMD_READ_MSG;
+		// Command Type
+		data[1] = PSU_R_MODULE_COUNT;
+
+		SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+	}
+}
+
+void GetModuleCap(byte group)
+{
+	GetOutputPowCap(group);
+	//GetOutputCurCap(group);
+	//GetPsuMaxVoltage(group);
+}
+
+void GetModuleIavailable(byte group)
+{
+	byte data[8];
+	PwrFrame PwrFrameMsg;
+	PwrFrameMsg.PwrMessage = 0;
+
+	PwrFrameMsg.UUBits.Protocol = 0x01;
+	PwrFrameMsg.UUBits.MonitorAddress = PSU_MONITOR_DEFAULT;
+	// module id
+	//if (group == SYSTEM_CMD)
+		PwrFrameMsg.UUBits.ModuleAddress = PSU_MODULE_BROADCAST;
+	//else
+	//	PwrFrameMsg.UUBits.ModuleAddress = group;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	// Group
+	if (group == SYSTEM_CMD)
+		data[0] = 0x00;
+	else
+		data[0] = group + 1;
+	// Message Type
+	data[0] = data[0] << 4;
+	data[0] |= PSU_MSG_CMD_READ_MSG;
+	// Command Type
+	data[1] = PSU_R_IAVAILABLE;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void GetModuleOutputF(byte group)
+{
+	GetFastOutputVol(group);
+	GetFastOutputCur(group);
+}
+
+void GetDcTemperature(byte group)
+{
+	GetTemperature(group);
+	GetInputVoltageL12(group);
+	GetInputVoltageL23(group);
+	GetInputVoltageL31(group);
+}
+
+void PresentOutputVol(byte group, int voltage, int current, byte psuCount)
+{
+	voltage *= 100;
+	SetOutputVoltage ( group, voltage );
+
+	current *= 100;
+	if (psuCount > 0)
+		current /= psuCount;
+	else
+		current = LIB_PSU_MIN_CUR;
+	SetOutputCurrent ( group, current );
+	if (current == 0 && voltage == 0)
+		SwitchPower(group, PSU_POWER_OFF);
+}
+
+void GetModuleVer(byte group)
+{
+	GetDc2DcVersion(group);
+	GetPfcVersion(group);
+}
+
+void SetWalkInConfig(byte group, byte enable, byte sec)
+{
+	// 這階段可以做模塊高低壓設定、初始化一些設定
+	ShmUuPowerData._getCountIndexComp = LIB_STOP;
+	SetModuleVoltageMode(group, PSU_VOLTAGE_AUTO);
+}
+
+void FlashLed(byte group, byte value)
+{
+	// none use
+}
+
+void SetDirModulePresentOutput(byte group, int voltage, int current, byte _switch, byte _interRelay)
+{
+	// none use
+}
+
+
+

+ 261 - 0
EVSE/Modularization/UUpwr_PsuCommObj.h

@@ -0,0 +1,261 @@
+/*
+ * UUpwr_PsuCommObj.h
+ *
+ *  Created on: 2022年3月30日
+ *      Author: 7564
+ */
+
+#ifndef UUPWR_PSUCOMMOBJ_H_
+#define UUPWR_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 <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 ARRAY_SIZE(A)		(sizeof(A) / sizeof(A[0]))
+#define	PSU_PROTOCOL_TYPE	1
+#define SYSTEM_CMD          0x3F
+#define LIB_START			1
+#define LIB_STOP			0
+#define LIB_IN_USE			1
+#define LIB_NO_USE			0
+#define LIB_PSU_MIN_CUR		10			// 1A
+#define LIB_PSU_MAX_CUR		1000		// 100A
+#define LIB_PSU_MAX_VOL		10000		// 1000V
+#define LIB_PSU_MIN_VOL		1500		// 150V
+#define LIB_UU_HW_VERSIION	0
+
+typedef unsigned char       byte;
+typedef unsigned short      word;
+typedef unsigned int        unit;
+
+struct UuPowerInformation	ShmUuPowerData;
+struct TimelineInfor		ShmTimelineData;
+
+int CanFd;
+pid_t recFork;
+pid_t callbackFunc;
+
+typedef union
+{
+    unsigned int PwrMessage;
+    struct
+    {
+    	unsigned int SerialNumberLowPart:9;        // SerialNumber Low Part
+    	unsigned int ProductionDay:5;              // Production Day
+    	unsigned int ModuleAddress:7;              // Module Address
+    	unsigned int MonitorAddress:4;             // Monitor Address
+        unsigned int Protocol:4;                   // Protocol
+        unsigned int res:3;						   // reserved
+    }UUBits;
+}PwrFrame;
+
+struct UU_PSU_INFO
+{
+	byte targetNumber;
+
+	unsigned short dc2dcVersion;
+	unsigned short pfcVersion;
+
+	float maxVoltage;
+	unsigned short powerCap;
+	unsigned short currentCap;
+
+	float outputVol;
+	float outputCur;
+
+	unsigned short inputVolL12;
+	unsigned short inputVolL23;
+	unsigned short inputVolL31;
+};
+
+struct UU_POW_MODULE_INFO
+{
+	struct UU_PSU_INFO psuInfo[12];
+	byte psuCount;
+
+	float presentVol;
+	float presentCur;
+};
+
+struct TimelineInfor
+{
+	bool _getCountChk;
+	struct timespec _getCount_time;
+};
+
+struct UuPowerInformation
+{
+	bool _getCountIndexComp;
+	// 2 Group
+	struct UU_POW_MODULE_INFO uu_pow_info[2];
+	byte totalPsuCount;
+};
+
+enum PSU_VOLTAGE_MODE
+{
+	PSU_VOLTAGE_HIGH = 			0x01,
+	PSU_VOLTAGE_LOW = 			0x02,
+	PSU_VOLTAGE_AUTO = 			0x03
+};
+
+enum PSU_POWER_CMD
+{
+	PSU_POWER_ON = 		0,
+	PSU_POWER_OFF = 			1,
+};
+
+enum PSU_MONITOR_ID
+{
+	PSU_MONITOR_BROADCAST = 0x00,
+	PSU_MONITOR_DEFAULT = 	0x01,
+};
+
+enum PSU_MODULE_ID
+{
+	PSU_MODULE_BROADCAST = 0x00
+};
+
+enum PSU_MSG_CMD
+{
+	PSU_MSG_CMD_SET_PARAM = 		0x00,		// Send
+	PSU_MSG_CMD_SET_RES = 			0x01,		// Response
+	PSU_MSG_CMD_READ_MSG = 			0x02,		// Send
+	PSU_MSG_CMD_READ_RES = 			0x03,		// Response
+	PSU_MSG_CMD_READ_SERIAL_RES = 	0x04,
+};
+
+enum PSU_CTRL_CMD
+{
+	PSU_R_MODULE_COUNT = 			0x00,	// Get module count ( Get output voltage )
+	PSU_R_OUTPUT_CUR = 				0x01,	// Get output current
+	PSU_W_OUTPUT_VOL = 				0x02,	// Set output voltage
+	PSU_W_OUTPUT_CUR = 				0x03,	// Set output current
+	PSU_W_SWITCH_POW =				0x04,	// Set PSU power - on/off
+	PSU_R_SERIAL_NUM = 				0x05,	// Get PSU serial number
+	PSU_R_STATUS = 					0x08,	// Get status
+	PSU_R_OUTPUT_POW_CAP = 			0x0A,	// Get Output power Cap
+	PSU_R_MAX_VOL = 				0x0C,	// Get max voltage
+	PSU_R_VIN_L12 = 				0x14,	// Get L12 of Vin
+	PSU_R_VIN_L23 = 				0x15,	// Get L23 of Vin
+	PSU_R_VIN_L31 = 				0x16,	// Get L31 of Vin
+	PSU_R_TEMP = 					0x1E,	// Get PSU temperature
+	PSU_R_FAST_OUTPUT_CUR = 		0x2F,	// Get output current (Fast)
+	PSU_RW_GROUP = 					0x59,	// Get/Set PSU group
+	PSU_W_HIGH_LOW_VOL_MODE =		0x5F,	// Set PSU high/low voltage mode
+	PSU_R_HIGH_LOW_VOL_MODE = 		0x60,	// Get PSU high/low voltage mode
+	PSU_R_FAST_OUTPUT_VOL = 		0x62,	// Get output voltage (Fast)
+	PSU_R_DD_VERSION = 				0x63, 	// Get DC to DC version
+	PSU_R_PFC_VERSION = 			0x64,	// Get PFC version
+	PSU_R_OUTPUT_CUR_CAP = 			0x68,	// Get output current cap.
+	PSU_R_IAVAILABLE = 				0x72,	// Get iavailable current
+};
+
+enum PSU_INFORMATION_TARGET
+{
+	PSU_INFORMATION_OUTPUT_POW = 	0x01,
+	PSU_INFORMATION_OUTPUT_CUR = 	0x02,
+};
+
+enum PSU_FLASH_CMD
+{
+	PSU_FLASH_NORMAL = 		0,
+	PSU_FLASH_ON = 			1,
+};
+
+/*Initialization*/
+bool InitialCommunication();
+
+void GetStatus(byte group, byte param);
+void GetGroup(byte address);
+void GetModuleVoltageMode(byte group);
+
+void SetGroup(byte group, byte sourceAddr, byte targetAddr);
+void SetModuleVoltageMode(byte group, byte value);
+
+void SwitchPower(byte group, byte value);
+void SetWalkInConfig(byte group, byte enable, byte sec);
+void GetModuleCount(byte group);
+void GetModuleCap(byte group);
+void GetModuleVer(byte group);
+void GetModuleOutputF(byte group);
+void GetModuleIavailable(byte group);
+void GetDcTemperature(byte group);
+void PresentOutputVol(byte group, int voltage, int current, byte psuCount);
+void FlashLed(byte group, byte value);
+
+// none used
+void SetDirModulePresentOutput(byte group, int voltage, int current, byte _switch, byte _interRelay);
+
+/* 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);
+
+#endif /* UUPWR_PSUCOMMOBJ_H_ */
+
+

+ 3 - 3
EVSE/Projects/define.h

@@ -910,7 +910,7 @@ typedef union
     }bits;
 }CabinetSettingFlag;
 
-typedef struct DC_METER_INFO
+struct DC_METER_INFO
 {
     double presetVoltage;                       // resolution: 1.000v
     double presentCurrent;                      // resolution: 1.000a
@@ -918,7 +918,7 @@ typedef struct DC_METER_INFO
     double totlizeImportEnergy;                 // resolution: 1.000kwh
     double totlizeExportEnergy;                 // resolution: 1.000kwh
     unsigned char LinkStatus;                   // 0 = unknow ,1 = link , 2 miss link
-}DC_Meter_Info;
+};
 
 typedef struct Bazel8Command
 {
@@ -1044,7 +1044,7 @@ struct SysInfoData
     unsigned char           AuthorizedStatus;           // cabinet authorized status
     CabinetSettingFlag      CabinetSetting;
     struct LocalSharingInfo localSharingInfo;           // Local power sharing info structure
-    DC_Meter_Info           DcMeterInfo[4];
+    struct DC_METER_INFO 	DcMeterInfo[4];
     unsigned char           OTPTemp;                    // OTP Temperature
     unsigned char           OTPTempR;                   // OTP Recovery Temperature
     struct LCD_OVERRIDE     LcdOveride;                 // LCD override info (no use anymore)