Browse Source

2020-02-05 / Alston Lin

Actions
1. Remove cardnumber item from define.h
2. Update DS-60-120 Project

Files
1. As follow commit history
Alston 5 years ago
parent
commit
402a00f167

+ 295 - 129
EVSE/Modularization/Infypwr_PsuCommObj.c

@@ -40,6 +40,24 @@ struct Current_cmd_Proc Psu_cmd={
 		0x0E001C00,
 };
 
+#define DEBUG						1
+
+void PRINTF_FUNC(char *string, ...);
+
+void PRINTF_FUNC(char *string, ...)
+{
+	if (DEBUG)
+	{
+		va_list args;
+		char buffer[4096];
+
+		va_start(args, string);
+		vsnprintf(buffer, sizeof(buffer), string, args);
+		va_end(args);
+		printf("%s \n", buffer);
+	}
+}
+
 //================================================
 // Callback function
 //================================================
@@ -48,6 +66,21 @@ void GetPsuAddressReq(void *func)
 	get_psu_addr_req = func;
 }
 
+void RefreshSerialNumber(void *func)
+{
+	return_serial_number = func;
+}
+
+void RefreshVextAndIavail(void *func)
+{
+	return_vext_and_iavail = func;
+}
+
+void RefreshMiscInfo(void *func)
+{
+	return_misc_info = func;
+}
+
 void RefreshStatus(void *func)
 {
 	return_status = func;
@@ -73,7 +106,6 @@ void RefreshAvailableCap(void *func)
 	return_available_cap = func;
 }
 
-
 void RefreshOutputPowerSwitch(void *func)
 {
 	return_output_pow_switch = func;
@@ -99,21 +131,21 @@ int InitCanBus()
    	if (setsockopt(s0, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct	timeval)) < 0)
 	{
 		#ifdef SystemLogMessage
-		printf("Set SO_RCVTIMEO NG");
+   		PRINTF_FUNC("Set SO_RCVTIMEO NG");
 		#endif
 	}
 	nbytes=40960;
 	if (setsockopt(s0, SOL_SOCKET,  SO_RCVBUF, &nbytes, sizeof(int)) < 0)
 	{
 		#ifdef SystemLogMessage
-		printf("Set SO_RCVBUF NG");
+		PRINTF_FUNC("Set SO_RCVBUF NG");
 		#endif
 	}
 	nbytes=40960;
 	if (setsockopt(s0, SOL_SOCKET, SO_SNDBUF, &nbytes, sizeof(int)) < 0)
 	{
 		#ifdef SystemLogMessage
-		printf("Set SO_SNDBUF NG");
+		PRINTF_FUNC("Set SO_SNDBUF NG");
 		#endif
 	}
 
@@ -152,8 +184,8 @@ void ReceiveDataFromCanBus()
             //if master id
             if(target == 0xF0)
             {
-                //printf("Get-INFYPWR-Msg : %08x - %02x%02x%02x%02x%02x%02x%02x%02x\n", frame.can_id,frame.data[0], frame.data[1], frame.data[2], frame.data[3],frame.data[4], frame.data[5], frame.data[6], frame.data[7]);
-                //printf("Get-INFYPWR-Msg : %08x cmd:%08x target:%02x group:%02x address:%02x\n", frame.can_id, intCmd, target, group, address);
+                //PRINTF_FUNC("Get-INFYPWR-Msg : %08x - %02x%02x%02x%02x%02x%02x%02x%02x\n", frame.can_id,frame.data[0], frame.data[1], frame.data[2], frame.data[3],frame.data[4], frame.data[5], frame.data[6], frame.data[7]);
+                //PRINTF_FUNC("Get-INFYPWR-Msg : %08x cmd:%08x target:%02x group:%02x address:%02x\n", frame.can_id, intCmd, target, group, address);
 
     			switch (intCmd)
     			{
@@ -163,12 +195,12 @@ void ReceiveDataFromCanBus()
     					char sn[7];
 
                         Quantity = frame.data[2];
-
+                        //get_psu_count_first(Quantity);
+//
                         for (byte index = 0; index < Quantity; index++)
                         {
-                            memcpy(sn, (char *)"INFY00", 6);
-                            sn[7] = index + 48;     //sacii
-                            get_psu_addr_req((index), sn);
+                        	sn[0] = sn[1] = sn[2] = sn[3] = sn[4] = sn[5] = sn[6] = index;
+                        	get_psu_addr_req(index, sn);
                         }
     				}
     					break;
@@ -177,17 +209,49 @@ void ReceiveDataFromCanBus()
     					break;
     				case INFYPWR_GET_STATUS_MSG:
     				{
+    				    //英飛源狀態 (如果是使用 Group 命令發問模組會使用 Group 命令回覆)
+    					//data[2] = group
+						//data[4] = temp
+						//data[5,6,7] = alarm
+						//if (statusPassID == FEEDBACK_ID)
+						return_status(frame.data[2], address, frame.data[4],
+								(((int) frame.data[5] << 16) + ((int) frame.data[6] << 8) + (int) frame.data[7]) & 0x00ffffff);
+    				}
+    					break;
+
+                    case INFYPWR_GET_BARCODE_MSG:
+                    {
     				    //英飛源狀態 (如果是使用 Group 命令發問模組會使用 Group 命令回覆)
     				    if(group == 0x0B)
     				    {
-    				        //data[2] = group
-    				        //data[4] = temp
-    				        //data[5,6,7] = alarm
-    					    return_status(frame.data[2], address,frame.data[4],
-    					    (((int) frame.data[5] << 16) + ((int) frame.data[6] << 8) + (int) frame.data[7])  & 0x00ffffff);
+    				        char sn[6];
+
+    				        memcpy(sn, &frame.data[0], 6);
+    					    return_serial_number(address, sn , ((word) frame.data[6] * 256 ) + (word) frame.data[7]);
     					}
-    				}
-    					break;
+                    }
+                        break;
+
+
+                    case INFYPWR_GET_VEXT_IAVAIL_MSG:
+                    {
+        			    return_vext_and_iavail(address,
+        			        ((word) frame.data[0] * 256 ) + (word) frame.data[1],
+        			        ((word) frame.data[2] * 256 ) + (word) frame.data[3]);
+                    }
+                    //PRINTF_FUNC("INFYPWR_GET_VEXT_IAVAIL_MSG \n");
+                        break;
+
+                    case INFYPWR_GET_MISC_INFO_MSG:
+                    {
+                        //0,1 = type
+                        //5,6,7,8 = msg
+                    	return_misc_info(address,
+        			        ((word) frame.data[0] * 256 ) + (word) frame.data[1],
+        			        (((int) frame.data[4] << 24) + ((int) frame.data[5] << 16) + ((int) frame.data[6] << 8) + (int) frame.data[7])  & 0x00ffffff);
+                    }
+                    //PRINTF_FUNC("INFYPWR_GET_MISC_INFO_MSG \n");
+                        break;
 
 
     				case INFYPWR_GET_PRESENT_INPUT_VOLTAGE_MSG:
@@ -286,7 +350,7 @@ bool InitialCommunication()
 
 	if(CanFd < 0)
 	{
-		printf("Init can bus fail.\n");
+		PRINTF_FUNC("Init can bus fail.\n");
 		return false;
 	}
 
@@ -297,7 +361,7 @@ bool InitialCommunication()
 	}
     else if(recFork > 0)
     {
-    	printf("fork fail\n");
+    	PRINTF_FUNC("fork fail\n");
     }
 
     return true;
@@ -316,6 +380,7 @@ void RequestModuleTotalMumbert(void)
 //void PsuAddressAssignment(byte phy_addr, char *serial_number, byte real_addr, byte group)
 void PsuAddressAssignment(byte phy_addr, byte group)
 {
+	PRINTF_FUNC("phy_addr = %d, group = %d \n", phy_addr, group);
 	uint cmd = INFYPWR_MODULE_CMD | INFYPWR_SET_GROUP_ASSINGMENT_MSG | (phy_addr << 8) | INFYPWR_MASTER_TXID;
 
 	byte data[8];
@@ -328,57 +393,141 @@ void PsuAddressAssignment(byte phy_addr, byte group)
 void GetStatus(byte group, byte address)
 {
 	//如果用 group 發送 (該 group 內的模組會自動依序回應)
-	//printf("PSU_C_DLL : GetStatus. group = %x, address = %x \n", group, address);
+	//PRINTF_FUNC("PSU_C_DLL : GetStatus. group = %x, address = %x \n", group, address);
+	uint cmd;
+	byte data[8];
+
+	cmd = INFYPWR_GROUP_CMD | INFYPWR_GET_STATUS_MSG | (group << 8) | INFYPWR_MASTER_TXID;
+//    if(group == SET_GROUP_CMD)
+//    {
+//        cmd = INFYPWR_GROUP_CMD | INFYPWR_GET_STATUS_MSG | (group << 8) | INFYPWR_MASTER_TXID;
+//    }
+//    //如果是模組命令則找出模組對應到 (英飛源的ID)
+//    else
+//    {
+//        cmd = INFYPWR_MODULE_CMD | INFYPWR_GET_STATUS_MSG | (address << 8) | INFYPWR_MASTER_TXID;
+//    }
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	SendCmdToPsu(cmd, data, sizeof(data));
+}
+
+void GetFwVersion(byte group, byte address, byte type)
+{
+}
+
+void GetSerialNumber(byte group, byte address)
+{
+    	//如果用 group 發送 (該 group 內的模組會自動依序回應)
 	uint cmd;
 	byte data[8];
 
     //如果是群組命令
     if(group == SET_GROUP_CMD)
     {
-        cmd = INFYPWR_GROUP_CMD | INFYPWR_GET_STATUS_MSG | (address << 8) | INFYPWR_MASTER_TXID;
+        cmd = INFYPWR_GROUP_CMD | INFYPWR_GET_BARCODE_MSG | (address << 8) | INFYPWR_MASTER_TXID;
     }
     //如果是模組命令則找出模組對應到 (英飛源的ID)
     else
     {
-        cmd = INFYPWR_MODULE_CMD | INFYPWR_GET_STATUS_MSG | (address << 8) | INFYPWR_MASTER_TXID;
+        cmd = INFYPWR_MODULE_CMD | INFYPWR_GET_BARCODE_MSG | (address << 8) | INFYPWR_MASTER_TXID;
     }
 
 	memset(data, 0x00, ARRAY_SIZE(data));
 	SendCmdToPsu(cmd, data, sizeof(data));
 }
 
-void GetFwVersion(byte group, byte address, byte type)
+
+void GetVextAndIavail(byte group, byte address)
 {
+    	//如果用 group 發送 (該 group 內的模組會自動依序回應)
+	uint cmd;
+	byte data[8];
+
+    //如果是群組命令
+    if(group == SET_GROUP_CMD)
+    {
+        cmd = INFYPWR_GROUP_CMD | INFYPWR_GET_VEXT_IAVAIL_MSG | (address << 8) | INFYPWR_MASTER_TXID;
+    }
+    //如果是模組命令則找出模組對應到 (英飛源的ID)
+    else
+    {
+        cmd = INFYPWR_MODULE_CMD | INFYPWR_GET_VEXT_IAVAIL_MSG | (address << 8) | INFYPWR_MASTER_TXID;
+    }
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	SendCmdToPsu(cmd, data, sizeof(data));
 }
 
-void GetSerialNumber(byte group, byte address)
+
+void GetMiscInfo(byte group, byte address, unsigned short CmdType)
 {
+    	//如果用 group 發送 (該 group 內的模組會自動依序回應)
+	uint cmd;
+	byte data[8];
+
+	cmd = INFYPWR_GROUP_CMD | INFYPWR_GET_MISC_INFO_MSG | (group << 8) | INFYPWR_MASTER_TXID;
+    //如果是群組命令
+//    if(group == SET_GROUP_CMD)
+//    {
+//        cmd = INFYPWR_GROUP_CMD | INFYPWR_GET_MISC_INFO_MSG | (address << 8) | INFYPWR_MASTER_TXID;
+//    }
+//    //如果是模組命令則找出模組對應到 (英飛源的ID)
+//    else
+//    {
+//        cmd = INFYPWR_MODULE_CMD | INFYPWR_GET_MISC_INFO_MSG | (address << 8) | INFYPWR_MASTER_TXID;
+//    }
+
+
+    memset(data, 0x00, ARRAY_SIZE(data));
+    data[0] = (CmdType >> 8) & 0xFF;
+    data[1] = (CmdType) & 0xFF;
+
+	SendCmdToPsu(cmd, data, sizeof(data));
 }
 
-void GetAvailableCap(byte group, byte address, short _outputVol)
+void SetMiscInfo(byte group, byte address, unsigned short CmdType, unsigned int value)
 {
-	//如果用 group 發送 (該 group 內的模組會自動依序回應)
-	uint cmd;
+	int cmd;
 	byte data[8];
 
+	//PRINTF_FUNC("cmd = %x \n", cmd);
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+
+
+    data[0] = (CmdType >> 8) & 0xFF;
+    data[1] = (CmdType) & 0xFF;
+
+	if(CmdType == MISC_SETCMD_FAN_DENOISE_MODE){
+
+        data[7] = (byte)value;
+	}else{
+	    data[4] = (value >> 24) & 0xff;
+	    data[5] = (value >> 16) & 0xff;
+	    data[6] = (value >> 8) & 0xff;
+	    data[7] = value & 0xff;
+	}
+
     //如果是群組命令
     if(group == SET_GROUP_CMD)
     {
-        cmd = INFYPWR_GROUP_CMD | INFYPWR_GET_AVAILABLE_CAP_MSG | (address << 8) | INFYPWR_MASTER_TXID;
+        cmd = INFYPWR_GROUP_CMD | INFYPWR_SET_MISC_INFO_MSG | (address << 8) | INFYPWR_MASTER_TXID;
+        //PRINTF_FUNC("Module-onoff(g) :%08x - %d - %d \n",cmd, data[0],address);
     }
     //如果是模組命令則找出模組對應到 (英飛源的ID)
     else
     {
-        cmd = INFYPWR_MODULE_CMD | INFYPWR_GET_AVAILABLE_CAP_MSG | (address << 8) | INFYPWR_MASTER_TXID;
+        cmd = INFYPWR_MODULE_CMD | INFYPWR_SET_MISC_INFO_MSG | (address << 8) | INFYPWR_MASTER_TXID;
+        // PRINTF_FUNC("Modele-onoff(M) :%08x - %d - %d \n",cmd, data[0],address);
     }
 
-	memset(data, 0x00, ARRAY_SIZE(data));
 	SendCmdToPsu(cmd, data, sizeof(data));
 }
 
 void GetPresentInputVol(byte group, byte address)
 {
-	//printf("PSU_C_DLL : GetPresentInputVol. group = %x, address = %x \n", group, address);
+	//PRINTF_FUNC("PSU_C_DLL : GetPresentInputVol. group = %x, address = %x \n", group, address);
 	//如果用 group 發送 (該 group 內的模組會自動依序回應)
 	uint cmd;
 	byte data[8];
@@ -398,22 +547,43 @@ void GetPresentInputVol(byte group, byte address)
 	SendCmdToPsu(cmd, data, sizeof(data));
 }
 
+void GetAvailableCap(byte group, byte address, short _outputVol)
+{
+	//如果用 group 發送 (該 group 內的模組會自動依序回應)
+	uint cmd;
+	byte data[8];
+
+	cmd = INFYPWR_GROUP_CMD | INFYPWR_GET_AVAILABLE_CAP_MSG | (group << 8) | INFYPWR_MASTER_TXID;
+//    if(group == SET_GROUP_CMD)
+//    {
+//        cmd = INFYPWR_GROUP_CMD | INFYPWR_GET_AVAILABLE_CAP_MSG | (address << 8) | INFYPWR_MASTER_TXID;
+//    }
+//    //如果是模組命令則找出模組對應到 (英飛源的ID)
+//    else
+//    {
+//        cmd = INFYPWR_MODULE_CMD | INFYPWR_GET_AVAILABLE_CAP_MSG | (address << 8) | INFYPWR_MASTER_TXID;
+//    }
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	SendCmdToPsu(cmd, data, sizeof(data));
+}
+
 void GetPresentOutput(byte group, byte address)
 {
-	//printf("PSU_C_DLL : GetPresentOutput. group = %x, address = %x \n", group, address);
+	//PRINTF_FUNC("PSU_C_DLL : GetPresentOutput. group = %x, address = %x \n", group, address);
 	int cmd;
 	byte data[8];
 
-    //如果是群組命令
-    if(group == SET_GROUP_CMD)
-    {
-        cmd = INFYPWR_GROUP_CMD | INFYPWR_GET_PRESENT_OUTPUT_MSG | (address << 8) | INFYPWR_MASTER_TXID;
-    }
-    //如果是模組命令則找出模組對應到 (英飛源的ID)
-    else
-    {
-        cmd = INFYPWR_MODULE_CMD | INFYPWR_GET_PRESENT_OUTPUT_MSG | (address << 8) | INFYPWR_MASTER_TXID;
-    }
+	cmd = INFYPWR_GROUP_CMD | INFYPWR_GET_PRESENT_OUTPUT_MSG | (group << 8) | INFYPWR_MASTER_TXID;
+//    if(group == SET_GROUP_CMD)
+//    {
+//        cmd = INFYPWR_GROUP_CMD | INFYPWR_GET_PRESENT_OUTPUT_MSG | (address << 8) | INFYPWR_MASTER_TXID;
+//    }
+//    //如果是模組命令則找出模組對應到 (英飛源的ID)
+//    else
+//    {
+//        cmd = INFYPWR_MODULE_CMD | INFYPWR_GET_PRESENT_OUTPUT_MSG | (address << 8) | INFYPWR_MASTER_TXID;
+//    }
 
 	memset(data, 0x00, ARRAY_SIZE(data));
 	SendCmdToPsu(cmd, data, sizeof(data));
@@ -424,17 +594,16 @@ void SetPresentOutput(byte group, byte address, float vol, float cur, float Avai
     uint cmd;
     byte data[8];
     //bool isSearch = false;
-
     //if (cur >= AvailableCur)
 	//cur = AvailableCur;
 
-	//if(vol == 0 && cur == 0)printf("output v=0 a =0 \n");
-    printf("group = %d, address = %d, vol = %f, cur = %f \n", group, address, vol, cur);
+	//if(vol == 0 && cur == 0)PRINTF_FUNC("output v=0 a =0 \n");
+    //PRINTF_FUNC("group = %d, address = %d, vol = %f, cur = %f \n", group, address, vol, cur);
     //英飛源使用 0.001 精度
     uint vol2 =  vol * 100;
     uint cur2 =  cur * 100;
 
-    printf("vol = %f, cur = %f, vol2 = %d, cur2 = %d \n", vol, cur, vol2, cur2);
+    //PRINTF_FUNC("vol = %f, cur = %f, vol2 = %d, cur2 = %d \n", vol, cur, vol2, cur2);
 
  	// 電壓
 	data[0] = (vol2 >> 24) & 0xff;
@@ -448,39 +617,40 @@ void SetPresentOutput(byte group, byte address, float vol, float cur, float Avai
 	data[6] = (cur2 >> 8) & 0xff;
 	data[7] = cur2 & 0xff;
 
-    //如果是群組命令
-    if(group == SET_GROUP_CMD)
-    {
-        cmd = INFYPWR_GROUP_CMD | INFYPWR_SET_GROUP_PERSENT_OUTPUT_MSG | (address << 8) | INFYPWR_MASTER_TXID;
-        //printf("setout(G) :%08x /n",cmd);
-    }
-    //如果是模組命令則找出模組對應到 (英飛源的ID)
-    else
-    {
-
-    	//search group
-    	/*
-        for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
-        {
-        	for (byte index = 0; index < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; index++)
-        	{
-        	    //search id
-        		if (ShmPsuData->PsuGroup[groupIndex].PsuModule[index].Address == address)
-        		{
-        		    //修改英飛為 id
-                    address = ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PhysicalID;
-        			isSearch = true;
-        			break;
-        		}
-        	}
-        	if(isSearch) break;
-        }
-        */
-        cmd = INFYPWR_MODULE_CMD | INFYPWR_SET_MODULE_PERSENT_OUTPUT_MSG | (address << 8) | INFYPWR_MASTER_TXID;
-        //printf("setout(M) :%08x /n",cmd);
-    }
-
-	printf("typecmd = %02x, addr = %02x ,vol = %d, tot_Amp = %f, need_cur = %d, \n", group, address, vol2, AvailableCur, cur2);
+	cmd = INFYPWR_GROUP_CMD | INFYPWR_SET_GROUP_PERSENT_OUTPUT_MSG | (group << 8) | INFYPWR_MASTER_TXID;
+//    if(group == SET_GROUP_CMD)
+//    {
+//        cmd = INFYPWR_GROUP_CMD | INFYPWR_SET_GROUP_PERSENT_OUTPUT_MSG | (address << 8) | INFYPWR_MASTER_TXID;
+//        //PRINTF_FUNC("setout(G) :%08x /n",cmd);
+//    }
+//    //如果是模組命令則找出模組對應到 (英飛源的ID)
+//    else
+//    {
+//
+//    	//search group
+//    	/*
+//        for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
+//        {
+//        	for (byte index = 0; index < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; index++)
+//        	{
+//        	    //search id
+//        		if (ShmPsuData->PsuGroup[groupIndex].PsuModule[index].Address == address)
+//        		{
+//        		    //修改英飛為 id
+//                    address = ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PhysicalID;
+//        			isSearch = true;
+//        			break;
+//        		}
+//        	}
+//        	if(isSearch) break;
+//        }
+//        */
+//        cmd = INFYPWR_MODULE_CMD | INFYPWR_SET_MODULE_PERSENT_OUTPUT_MSG | (address << 8) | INFYPWR_MASTER_TXID;
+//        //PRINTF_FUNC("setout(M) :%08x /n",cmd);
+//    }
+
+	PRINTF_FUNC("typecmd = %02x, addr = %02x ,vol = %d, tot_Amp = %f, need_cur = %d, \n",
+			group, address, vol2, AvailableCur, cur2);
 	SendCmdToPsu(cmd, data, sizeof(data));
 }
 
@@ -497,18 +667,18 @@ void EnableGreenLedFlash(byte group, byte address, byte value)
 	    data[0] = 0x00;
 	}
 
-    //如果是群組命令
-    if(group == SET_GROUP_CMD)
-    {
-        cmd = INFYPWR_GROUP_CMD | INFYPWR_SET_GREEN_KED_FLASH_MSG | (address << 8) | INFYPWR_MASTER_TXID;
-        //printf("Green Led Flash(g) :%08x - %d - %d \n",cmd, data[0],address);
-    }
-    //如果是模組命令則找出模組對應到 (英飛源的ID)
-    else
-    {
-        cmd = INFYPWR_MODULE_CMD | INFYPWR_SET_GREEN_KED_FLASH_MSG | (address << 8) | INFYPWR_MASTER_TXID;
-        //printf("Green Led Flash(M) :%08x - %d - %d \n",cmd, data[0],address);
-    }
+	cmd = INFYPWR_GROUP_CMD | INFYPWR_SET_GREEN_KED_FLASH_MSG | (group << 8) | INFYPWR_MASTER_TXID;
+//    if(group == SET_GROUP_CMD)
+//    {
+//        cmd = INFYPWR_GROUP_CMD | INFYPWR_SET_GREEN_KED_FLASH_MSG | (address << 8) | INFYPWR_MASTER_TXID;
+//        //PRINTF_FUNC("Green Led Flash(g) :%08x - %d - %d \n",cmd, data[0],address);
+//    }
+//    //如果是模組命令則找出模組對應到 (英飛源的ID)
+//    else
+//    {
+//        cmd = INFYPWR_MODULE_CMD | INFYPWR_SET_GREEN_KED_FLASH_MSG | (address << 8) | INFYPWR_MASTER_TXID;
+//        //PRINTF_FUNC("Green Led Flash(M) :%08x - %d - %d \n",cmd, data[0],address);
+//    }
 
 	SendCmdToPsu(cmd, data, sizeof(data));
 }
@@ -530,13 +700,13 @@ void EnableWalkInMode(byte group, byte address, byte value)
     if(group == SET_GROUP_CMD)
     {
         cmd = INFYPWR_GROUP_CMD | INFYPWR_SET_WALKIN_MODE_MSG | (address << 8) | INFYPWR_MASTER_TXID;
-        //printf("WalkIn(g) :%08x - %d - %d \n",cmd, data[0],address);
+        //PRINTF_FUNC("WalkIn(g) :%08x - %d - %d \n",cmd, data[0],address);
     }
     //如果是模組命令則找出模組對應到 (英飛源的ID)
     else
     {
         cmd = INFYPWR_MODULE_CMD | INFYPWR_SET_WALKIN_MODE_MSG | (address << 8) | INFYPWR_MASTER_TXID;
-        // printf("WalkIn(M) :%08x - %d - %d \n",cmd, data[0],address);
+        // PRINTF_FUNC("WalkIn(M) :%08x - %d - %d \n",cmd, data[0],address);
     }
 
 	SendCmdToPsu(cmd, data, sizeof(data));
@@ -559,45 +729,40 @@ void EnableSleepMode(byte group, byte address, byte value)
     if(group == SET_GROUP_CMD)
     {
         cmd = INFYPWR_GROUP_CMD | INFYPWR_SET_SLEEP_MODE_MSG | (address << 8) | INFYPWR_MASTER_TXID;
-        //printf("SleepMode(g) :%08x - %d - %d \n",cmd, data[0],address);
+        //PRINTF_FUNC("SleepMode(g) :%08x - %d - %d \n",cmd, data[0],address);
     }
     //如果是模組命令則找出模組對應到 (英飛源的ID)
     else
     {
         cmd = INFYPWR_MODULE_CMD | INFYPWR_SET_SLEEP_MODE_MSG | (address << 8) | INFYPWR_MASTER_TXID;
-         //printf("SleepMode(M) :%08x - %d - %d \n",cmd, data[0],address);
+         //PRINTF_FUNC("SleepMode(M) :%08x - %d - %d \n",cmd, data[0],address);
     }
 
 	SendCmdToPsu(cmd, data, sizeof(data));
 }
 
-void EnableDipAddrMode(byte group, byte address, byte value)
+void EnableDipAddrMode(void)
 {
-	int cmd;
+	uint cmd = INFYPWR_MODULE_CMD | INFYPWR_SET_ADDRESS_MODE_MSG | (INFYPWR_BROADCAST_ID << 8) | INFYPWR_MASTER_TXID;
+
 	byte data[8];
+	memset(data, 0x00, ARRAY_SIZE(data));
 
-	if(value){
-	    //pwr off
-	    data[0] = 0x01;
-	}else{
-	    //pwr on
-	    data[0] = 0x00;
-	}
+	data[0] = 0x01;
+	SendCmdToPsu(cmd, data, sizeof(data));
 
-    //如果是群組命令
-    if(group == SET_GROUP_CMD)
-    {
-        cmd = INFYPWR_GROUP_CMD | INFYPWR_SET_ADDRESS_MODE_MSG | (address << 8) | INFYPWR_MASTER_TXID;
-        //printf("DipAddrMode(g) :%08x - %d - %d \n",cmd, data[0],address);
-    }
-    //如果是模組命令則找出模組對應到 (英飛源的ID)
-    else
-    {
-        cmd = INFYPWR_MODULE_CMD | INFYPWR_SET_ADDRESS_MODE_MSG | (address << 8) | INFYPWR_MASTER_TXID;
-        // printf("DipAddrMode(M) :%08x - %d - %d \n",cmd, data[0],address);
-    }
+}
+
+void DisableDipAddrMode(void)
+{
+	uint cmd = INFYPWR_MODULE_CMD | INFYPWR_SET_ADDRESS_MODE_MSG | (INFYPWR_BROADCAST_ID << 8) | INFYPWR_MASTER_TXID;
 
+	byte data[8];
+	memset(data, 0x00, ARRAY_SIZE(data));
+
+	data[0] = 0x00;
 	SendCmdToPsu(cmd, data, sizeof(data));
+
 }
 
 void EnableOutputPower(byte group, byte address, byte value)
@@ -605,7 +770,7 @@ void EnableOutputPower(byte group, byte address, byte value)
 	int cmd;
 	byte data[8];
 
-	//printf("cmd = %x \n", cmd);
+	//PRINTF_FUNC("cmd = %x \n", cmd);
 
 	memset(data, 0x00, ARRAY_SIZE(data));
 
@@ -617,18 +782,19 @@ void EnableOutputPower(byte group, byte address, byte value)
 	    data[0] = 0x00;
 	}
 
-    //如果是群組命令
-    if(group == SET_GROUP_CMD)
-    {
-        cmd = INFYPWR_GROUP_CMD | INFYPWR_SET_POWER_SWITCH_MSG | (address << 8) | INFYPWR_MASTER_TXID;
-        //printf("Module-onoff(g) :%08x - %d - %d \n",cmd, data[0],address);
-    }
-    //如果是模組命令則找出模組對應到 (英飛源的ID)
-    else
-    {
-        cmd = INFYPWR_MODULE_CMD | INFYPWR_SET_POWER_SWITCH_MSG | (address << 8) | INFYPWR_MASTER_TXID;
-        // printf("Modele-onoff(M) :%08x - %d - %d \n",cmd, data[0],address);
-    }
+	cmd = INFYPWR_GROUP_CMD | INFYPWR_SET_POWER_SWITCH_MSG | (group << 8) | INFYPWR_MASTER_TXID;
+//    if(group == SET_GROUP_CMD)
+//    {
+//        cmd = INFYPWR_GROUP_CMD | INFYPWR_SET_POWER_SWITCH_MSG | (address << 8) | INFYPWR_MASTER_TXID;
+//        //PRINTF_FUNC("Module-onoff(g) :%08x - %d - %d \n",cmd, data[0],address);
+//    }
+//    //如果是模組命令則找出模組對應到 (英飛源的ID)
+//    else
+//    {
+//        cmd = INFYPWR_MODULE_CMD | INFYPWR_SET_POWER_SWITCH_MSG | (address << 8) | INFYPWR_MASTER_TXID;
+//        // PRINTF_FUNC("Modele-onoff(M) :%08x - %d - %d \n",cmd, data[0],address);
+//    }
 
 	SendCmdToPsu(cmd, data, sizeof(data));
 }
+

+ 51 - 7
EVSE/Modularization/Infypwr_PsuCommObj.h

@@ -49,7 +49,10 @@ typedef unsigned int 		unit;
 #define INFYPWR_MASTER_TXID				0xF0  //
 #define INFYPWR_BROADCAST_ID			0x3F  //
 
-#define SET_MODULE_CMD              0
+#define UNFEEDBACK_ID        0
+#define FEEDBACK_ID          1
+
+#define SET_MODULE_CMD             0
 #define SET_GROUP_CMD              1
 
 
@@ -126,6 +129,10 @@ enum Receieve_INFYPWR_msg
     INFYPWR_GET_PRESENT_INPUT_VOLTAGE_MSG =              		0x00060000,
     INFYPWR_GET_PRESENT_OUTPUT_MSG =            				0x00090000,
     INFYPWR_GET_AVAILABLE_CAP_MSG = 	            			0x000A0000,
+    INFYPWR_GET_BARCODE_MSG = 	            			        0x000B0000,
+    INFYPWR_GET_VEXT_IAVAIL_MSG = 	            			    0x000C0000,
+    INFYPWR_GET_MISC_INFO_MSG = 	            			    0x000E0000,
+    INFYPWR_SET_MISC_INFO_MSG = 	            			    0x000F0000,
     INFYPWR_SET_WALKIN_MODE_MSG = 	            			    0x00130000,
     INFYPWR_SET_GREEN_KED_FLASH_MSG = 	            			0x00140000,
     INFYPWR_SET_GROUP_ASSINGMENT_MSG = 	            			0x00160000,
@@ -136,6 +143,15 @@ enum Receieve_INFYPWR_msg
     INFYPWR_SET_ADDRESS_MODE_MSG = 	            			    0x001F0000,
 };
 
+
+#define MISC_REQCMD_DC_BOARD_TMP            0x1107
+#define MISC_REQCMD_PFC_BOARD_TMP           0x1108
+#define MISC_REQCMD_FAN_SPEED               0x1201
+
+#define MISC_SETCMD_FAN_DENOISE_MODE        0x1113
+#define MISC_SETCMD_FAN_SPEED               0x1201
+#define MISC_SETCMD_AC_INPUT_LIMIT          0x1205
+
 #define 	ARRAY_SIZE(A)		(sizeof(A) / sizeof(A[0]))
 
 int 						CanFd;
@@ -147,44 +163,72 @@ bool InitialCommunication();
 void PsuAddressAssignment(byte phy_addr, byte group);
 void GetStatus(byte group, byte address);
 void GetFwVersion(byte group, byte address, byte type);
-void GetSerialNumber(byte group, byte address);
-void GetFanSpeed(byte group, byte address);
-void GetTemperature(byte group, byte address);
+void GetSerialNumber(byte group, byte address);     //barcode
+void GetVextAndIavail(byte group, byte address);
+//void GetFanSpeed(byte group, byte address);
+void GetMiscInfo(byte group, byte address, unsigned short CmdType);
+//void GetTemperature(byte group, byte address);
 void GetPresentInputVol(byte group, byte address);
 void GetPresentOutput(byte group, byte address);
 void GetPresentInputCurrent(byte group, byte address);
 void GetAvailableCap(byte group, byte address, short _outputVol);
 
 void SetPresentOutput(byte group, byte address, float vol, float cur, float AvailableCur);
-
-void EnableOutputPower(byte group, byte address, byte value);
+void SetMiscInfo(byte group, byte address, unsigned short CmdType, unsigned int value);
 
 void EnableGreenLedFlash(byte group, byte address, byte value);
 void EnableSleepMode(byte group, byte address, byte value);
-void EnableDipAddrMode(byte group, byte address, byte value);
+void EnableDipAddrMode(void);
+
 void EnableWalkInMode(byte group, byte address, byte value);
 void RequestModuleTotalMumbert(void);
 /* API Function end */
 
 /* Callback Function */
+
+
 void GetPsuAddressReq(void *func);
+//void GetPsuRequestCallback(byte phy_id, char *serial_number)
 void (*get_psu_addr_req)(byte phy_id, char *serial_number);
 
+//ver 1.8 & 1.9
+void RefreshSerialNumber(void *func);
+//void GetBarCodeCallback(byte address, char *serial_number , unsigned short module_ver)
+void (*return_serial_number)(byte address, char *serial_number , unsigned short module_ver);
+
+//ver 1.9
+void RefreshVextAndIavail(void *func);
+//void SavePresentModeleVextIavailCallback(byte address, unsigned short Vext, unsigned short Iavail)
+void (*return_vext_and_iavail)(byte address, unsigned short Vext, unsigned short Iavail);
+
+void RefreshMiscInfo(void *func);
+//void GetMiscInfoCallback(byte address, unsigned short CmdType , unsigned int value)
+void (*return_misc_info)(byte address, unsigned short CmdType , unsigned int value);
+
 void RefreshStatus(void *func);
+//void SaveStatusCallback(byte group, byte address, char cri_temp1, int alarm)
 void (*return_status)(byte group, byte address, int alarm, int fault);
 
 void RefreshInputVol(void *func);
+//void SavePresentInputVoltageCallback(byte address, unsigned short vol1, unsigned short vol2, unsigned short vol3)
 void (*return_input_vol)(byte address, unsigned short vol1, unsigned short vol2, unsigned short vol3);
 
 void RefreshGetOutput(void *func);
+//void SavePresentOutputCallback(byte address, unsigned short out_vol, unsigned short out_cur)
 void (*return_get_output)(byte address, unsigned short out_vol, unsigned short out_cur);
 
 void RefreshAvailableCap(void *func);
+//void SaveAvailableCapCallback(byte address, unsigned short maxv,unsigned short minv, unsigned short able_cur, unsigned short able_power)
 void (*return_available_cap)(byte address, unsigned short maxv,unsigned short minv , unsigned short able_cur,unsigned short able_power);
 
 void RefreshOutputPowerSwitch(void *func);
+//void GetOutputPowerSwitchStatusCallback(byte address, unsigned char value)
 void (*return_output_pow_switch)(byte address, int result);
 
 /* Callback Function end */
 
+
+
+void DisableDipAddrMode(void);
+void EnableOutputPower(byte group, byte address, byte value);
 #endif /* INFYPWR_PSUCOMMOBJ_H_ */

+ 28 - 10
EVSE/Projects/DS60-120/Apps/Config.h

@@ -4,13 +4,14 @@
  *  Created on: 2019年4月23日
  *      Author: foluswen
  */
-
 #ifndef CONFIG_H_
 #define CONFIG_H_
 
 typedef unsigned char			byte;
 
 #define TOTAL_QUANTITY_GUN			4				//Max Count
+#define DEBUG						1
+
 #define MODE_BOOT					0
 #define MODE_IDLE					1
 #define MODE_AUTHORIZING			2
@@ -23,13 +24,14 @@ typedef unsigned char			byte;
 #define MODE_TERMINATING			9
 #define MODE_COMPLETE				10
 #define MODE_ALARM					11
-#define MODE_RESERVATION			12
-#define MODE_BOOKING				13
-#define MODE_MAINTAIN				14
-#define MODE_DEBUG					15
-#define MODE_CCS_PRECHARGE_STEP0	16 	// ready for ccs precharge processing, For D+ relay to precharge relay
-#define MODE_CCS_PRECHARGE_STEP1	17	// waitting for ev board inform to enter to charging, For precharge relay to D+ relay
-#define MODE_SINGLE_RUN				18
+#define MODE_FAULT					12
+#define MODE_RESERVATION			13
+#define MODE_BOOKING				14
+#define MODE_MAINTAIN				15
+#define MODE_DEBUG					16
+#define MODE_CCS_PRECHARGE_STEP0	17 	// ready for ccs precharge processing, For D+ relay to precharge relay
+#define MODE_CCS_PRECHARGE_STEP1	18	// waitting for ev board inform to enter to charging, For precharge relay to D+ relay
+#define MODE_SINGLE_RUN				19
 
 #define GFD_WAIT			0
 #define GFD_PASS			1
@@ -66,15 +68,15 @@ enum _SYSTEM_STATUS
 	S_CCS_PRECHARGE_ST0,
 	S_CCS_PRECHARGE_ST1,
 	S_SINGLE_RUN,
-	S_SP_MODE,
 	S_NONE,
 };
 
 enum _GUN_TYPE
 {
 	_Type_Chademo = 		0,
-	_Type_CCS,
+	_Type_CCS_2,
 	_Type_GB,
+
 };
 
 enum _LCM_INDEX
@@ -114,6 +116,7 @@ enum _MODULE_PSU_WORK_STEP
 	_WORK_CHARGING 	= 			10,
 
 	_NO_WORKING			= 		254,
+	_INIT_PSU_STATUS	= 		255
 };
 
 enum _OFFLINE_POLICY
@@ -124,6 +127,12 @@ enum _OFFLINE_POLICY
 	_OFFLINE_POLICY_NO_CHARGING = 0x03,
 };
 
+enum _SYS_AUTHORIZE_MODE
+{
+	_SYS_AUTHORIZE_OCPP = 0x00,
+	_SYS_AUTHORIZE_FREE = 0x01
+};
+
 enum _REASSIGNED_RESOURCE_STEP
 {
 	_REASSIGNED_NONE = 			0,	//
@@ -133,6 +142,15 @@ enum _REASSIGNED_RESOURCE_STEP
 	_REASSIGNED_ADJUST = 		4,	// 模塊重新分配完成
 	_REASSIGNED_RELAY = 		5,	// 切斷橋接的 Relay
 	_REASSIGNED_COMP = 			6,	// 完成
+	_REASSIGNED_M_RELAY = 		7,	// 搭接橋接的 Relay
+	_REASSIGNED_M_MAIN = 		8,	// 重新分配 PSU (最大充)
+	_REASSIGNED_M_GET_NEW_CAP = 9	// 取得新的 CAP 並通知車端
+};
+
+enum _MAIN_CHARGING_MODE
+{
+	_MAIN_CHARGING_MODE_MAX = 0,
+	_MAIN_CHARGING_MODE_AVER = 1,
 };
 
 #endif /* CONFIG_H_ */

+ 33 - 24
EVSE/Projects/DS60-120/Apps/FactoryConfig.c

@@ -29,6 +29,7 @@
 #include	<ctype.h>
 #include 	<ifaddrs.h>
 #include	"../../define.h"
+#include 	"Config.h"
 
 #define Debug
 #define ARRAY_SIZE(A)		(sizeof(A) / sizeof(A[0]))
@@ -81,13 +82,13 @@ void helpOutput(void)
 /**************************************************************************************/
 int main(int argc,char *argv[])
 {
-	unsigned char outType = 0;
-	unsigned int i,Chk, MtdBlockSize = 0x600000;
+	unsigned char outType=0;
+	unsigned int i,Chk, MtdBlockSize=0x600000;
 	unsigned char *ptr;
-	int fd, wrd;
+	int fd,wrd;
 
-	ptr = malloc(MtdBlockSize);
-	if(ptr == NULL)
+	ptr=malloc(MtdBlockSize);
+	if(ptr==NULL)
 	{
 		#ifdef SystemLogMessage
 		StoreLogMsg("[FactoryConfig]main: malloc for SysConfigData NG");
@@ -100,12 +101,19 @@ int main(int argc,char *argv[])
 	/*
 	 * TODO: Set factory default configuration
 	*/
-	//********** System **********//
-	strcpy((char *)SysConfig.ModelName, "DSYE122J0ET2PH");
+	//********** System **********// udhcpc -i eth1 -s ./dhcp_script/eth1.script
+	strcpy((char *)SysConfig.ModelName, "DSYE601J0ET2PH");
 	strcpy((char *)SysConfig.SerialNumber, "");
-	strcpy((char *)SysConfig.SystemId, "");
+
+	memset(SysConfig.SystemId, 0x00, sizeof(SysConfig.SystemId));
+	char Dash = '-';
+
+	strcat((char *)SysConfig.SystemId, (char *)SysConfig.ModelName);
+	strncat((char *)SysConfig.SystemId, &Dash, 1);
+	strcat((char *)SysConfig.SystemId, (char *)SysConfig.SerialNumber);
+
 	strcpy((char *)SysConfig.SystemDateTime, "");
-	SysConfig.AuthorisationMode = 0;
+	SysConfig.AuthorisationMode = _SYS_AUTHORIZE_OCPP;
 	SysConfig.DefaultLanguage = 0;
 	SysConfig.RfidCardNumEndian = 0;
 	SysConfig.AcPlugInTimes = 0;
@@ -126,12 +134,12 @@ int main(int argc,char *argv[])
 	//********** Network **********//
 	strcpy((char *)SysConfig.FtpServer, "");
 	SysConfig.Eth0Interface.EthDhcpClient = 0;
-	strcpy((char *) SysConfig.Eth0Interface.EthMacAddress, "");
+	strcpy((char *) SysConfig.Eth0Interface.EthMacAddress, "AA:BB:CC:DD:EE:FF");
 	strcpy((char *) SysConfig.Eth0Interface.EthIpAddress, "192.168.1.10");
 	strcpy((char *) SysConfig.Eth0Interface.EthSubmaskAddress, "255.255.255.0");
 	strcpy((char *) SysConfig.Eth0Interface.EthGatewayAddress, "192.168.1.254");
 	SysConfig.Eth1Interface.EthDhcpClient = 0;
-	strcpy((char *) SysConfig.Eth1Interface.EthMacAddress, "");
+	strcpy((char *) SysConfig.Eth1Interface.EthMacAddress, "AA:BB:CC:DD:EE:FF");
 	strcpy((char *) SysConfig.Eth1Interface.EthIpAddress, "192.168.0.10");
 	strcpy((char *) SysConfig.Eth1Interface.EthSubmaskAddress, "255.255.255.0");
 	strcpy((char *) SysConfig.Eth1Interface.EthGatewayAddress, "192.168.0.254");
@@ -150,8 +158,8 @@ int main(int argc,char *argv[])
 	strcpy((char *) SysConfig.TelecomInterface.TelcomSoftwareVer, "");
 	strcpy((char *) SysConfig.TelecomInterface.TelcomApn, "Internet");
 	SysConfig.TelecomInterface.TelcomRssi = 0;
-	strcpy((char *) SysConfig.TelecomInterface.TelcomChapPapId, "");
-	strcpy((char *) SysConfig.TelecomInterface.TelcomChapPapPwd, "");
+	strcpy((char *) SysConfig.TelecomInterface.TelcomChapPapId, " ");
+	strcpy((char *) SysConfig.TelecomInterface.TelcomChapPapPwd, " ");
 	strcpy((char *) SysConfig.TelecomInterface.TelcomModemImei, "");
 	strcpy((char *) SysConfig.TelecomInterface.TelcomSimImsi, "");
 	strcpy((char *) SysConfig.TelecomInterface.TelcomSimIccid, "");
@@ -159,24 +167,25 @@ int main(int argc,char *argv[])
 	SysConfig.TelecomInterface.TelcomModemMode = 0;
 	strcpy((char *) SysConfig.TelecomInterface.TelcomIpAddress, "");
 	SysConfig.TelecomInterface.TelcomNetworkConn = 0;
+	strcpy((char *)SysConfig.chargePointVendor, "Phihong Technology");
 	//********** Backend **********//
 	SysConfig.BackendConnTimeout=300; //300 seconds
 	SysConfig.OfflinePolicy = 0;
 	SysConfig.OfflineMaxChargeEnergy = 0;
 	SysConfig.OfflineMaxChargeDuration = 0;
-	strcpy((char *) SysConfig.OcppServerURL, "ws://127.0.0.1");
-	strcpy((char *) SysConfig.ChargeBoxId, "");
+	strcpy((char *) SysConfig.OcppServerURL, "ws://test.evsocket.phihong.com.cn:2012/ocpp/");
+	strcpy((char *) SysConfig.ChargeBoxId, "DemoDC");
 
 	//copy default configuration to pointer
-	memcpy(ptr, &SysConfig, sizeof(struct SysConfigData));
+	memcpy(ptr,&SysConfig,sizeof(struct SysConfigData));
 
 	//calculate CRC
 	Chk=0;
 	for(i=0;i<(MtdBlockSize-4);i++)
 	{
-		Chk += *(ptr+i);
+		Chk+=*(ptr+i);
 	}
-	memcpy(	ptr + MtdBlockSize-4, &Chk, 4);
+	memcpy(	ptr+MtdBlockSize-4,&Chk,4);
 
 	/*
 	* Parameter process
@@ -217,7 +226,7 @@ int main(int argc,char *argv[])
 	/*
 	 * Configuration bin file generate
 	*/
-	if((outType&OUTPUT_FILE) > 0)
+	if((outType&OUTPUT_FILE)>0)
 	{
 		fd = open("/mnt/FactoryDefaultConfig.bin", O_RDWR | O_CREAT);
 		if (fd < 0)
@@ -228,7 +237,7 @@ int main(int argc,char *argv[])
 		}
 		wrd=write(fd, ptr, MtdBlockSize);
 		close(fd);
-		if(wrd < MtdBlockSize)
+		if(wrd<MtdBlockSize)
 		{
 			StoreLogMsg("write /mnt/FactoryDefaultConfig.bin NG\r\n");
 			free(ptr);
@@ -240,7 +249,7 @@ int main(int argc,char *argv[])
 	/*
 	* Flash memory write
 	*/
-	if((outType&OUTPUT_FLASH) > 0)
+	if((outType&OUTPUT_FLASH)>0)
 	{
 		// Save factory default setting value to flash factory default setting block
 		fd = open("/dev/mtdblock12", O_RDWR);
@@ -252,7 +261,7 @@ int main(int argc,char *argv[])
 		}
 		wrd=write(fd, ptr, MtdBlockSize);
 		close(fd);
-		if(wrd < MtdBlockSize)
+		if(wrd<MtdBlockSize)
 		{
 			StoreLogMsg("write /dev/mtdblock12 NG\r\n");
 			free(ptr);
@@ -269,7 +278,7 @@ int main(int argc,char *argv[])
 		}
 		wrd=write(fd, ptr, MtdBlockSize);
 		close(fd);
-		if(wrd < MtdBlockSize)
+		if(wrd<MtdBlockSize)
 		{
 			StoreLogMsg("write /dev/mtdblock11 NG\r\n");
 			free(ptr);
@@ -286,7 +295,7 @@ int main(int argc,char *argv[])
 		}
 		wrd=write(fd, ptr, MtdBlockSize);
 		close(fd);
-		if(wrd < MtdBlockSize)
+		if(wrd<MtdBlockSize)
 		{
 			StoreLogMsg("write /dev/mtdblock10 NG\r\n");
 			free(ptr);

+ 5 - 5
EVSE/Projects/DS60-120/Apps/Makefile

@@ -13,8 +13,8 @@ apps: MainTask EvCommTask EventLoggingTask InternalCommTask LcmControlTask Prima
 MainTask:
 	rm -f *.o
 	rm -f main;
-	$(CC) -O0 -g3 -Wall -c -fmessage-length=0 -o timeout.o timeout.c
-	$(CC) -O0 -g3 -Wall -c -fmessage-length=0 -o main.o main.c
+	$(CC) -include../../../Modularization/Module_RFID.h -O0 -g3 -Wall -c -fmessage-length=0 -o main.o main.c
+	$(CC) -include../../../Modularization/Module_RFID.h -O0 -g3 -Wall -c -fmessage-length=0 -o timeout.o timeout.c
 	$(CC) -o main main.o timeout.o ../../../Modularization/libModule_RFID.a ../../../Modularization/libModule_Upgrade.a	
 	cp -f main ../Images/root
 
@@ -53,13 +53,13 @@ PrimaryCommTask:
 
 PsuCommTask:
 	rm -f Module_PsuComm; 
-	$(CC) -include../../../Modularization/Phihong_PsuCommObj.h -includeConfig.h -O0 -g3 -Wall -c -fmessage-length=0 -o Module_PsuComm.o Module_PsuComm.c
-	$(CC) -o Module_PsuComm Module_PsuComm.o ../../../Modularization/libPhihong_PsuCommObj.a
+	$(CC) -include../../../Modularization/Infypwr_PsuCommObj.h -includeConfig.h -O0 -g3 -Wall -c -fmessage-length=0 -o Module_PsuComm.o Module_PsuComm.c
+	$(CC) -o Module_PsuComm Module_PsuComm.o ../../../Modularization/libInfypwr_PsuCommObj.a
 	cp -f Module_PsuComm ../Images/root	
 	
 ReadCmdlineTask:
 	rm -f ReadCmdline; 
-	$(CC) -O0 -g3 -Wall -c -fmessage-length=0 -o ReadCmdline.o ReadCmdline.c
+	$(CC) -includeConfig.h -O0 -g3 -Wall -c -fmessage-length=0 -o ReadCmdline.o ReadCmdline.c
 	$(CC) -o ReadCmdline ReadCmdline.o
 	cp -f ReadCmdline ../Images/root
 

+ 96 - 57
EVSE/Projects/DS60-120/Apps/Module_EvComm.c

@@ -31,7 +31,6 @@
 #include	"../../define.h"
 #include 	"Module_EvComm.h"
 
-#define Debug
 #define ARRAY_SIZE(A)		(sizeof(A) / sizeof(A[0]))
 #define PASS				1
 #define FAIL				-1
@@ -50,8 +49,12 @@ struct CcsData					*ShmCcsData;
 byte gun_count = CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY;
 int chargingTime[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 
-float maxChargingVol = 6000;			// 限制最大充電電壓,如依照模塊則填上 0
-float maxChargingCur = 1200;				// 限制最大充電電流,如依照模塊則填上 0
+// 限制最大充電電壓,因應不同 type 槍線來限制
+// Chademo : 500V, CCS : 950V
+float maxChargingVol[2] = { 5000, 9500 };			// 限制最大充電電壓,如依照模塊則填上 0
+// 限制最大充電電流與能量透過 Web
+float maxChargingCur[2] = { 0, 0 };					// 限制最大充電電流,如依照模塊則填上 0
+float maxChargingPow = 0;							// 限制最大充電能量,如依照模塊則填上 0
 
 // 槍資訊
 struct ChargingInfoData *_chargingData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
@@ -80,7 +83,10 @@ struct Ev_Board_Cmd Ev_Cmd={
 
 unsigned char mask_table[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
 
+void PRINTF_FUNC(char *string, ...);
+
 void GetMaxVolAndCurMethod(byte index, float *vol, float *cur);
+void GetMaxPowerMethod(float *pow);
 unsigned long GetTimeoutValue(struct timeval _sour_time);
 
 #define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
@@ -129,6 +135,20 @@ int DiffTimeb(struct timeb ST, struct timeb ET)
 	return (StopTime-StartTime)*1000+ET.millitm-ST.millitm;
 }
 
+void PRINTF_FUNC(char *string, ...)
+{
+	if (DEBUG)
+	{
+		va_list args;
+		char buffer[4096];
+
+		va_start(args, string);
+		vsnprintf(buffer, sizeof(buffer), string, args);
+		va_end(args);
+		printf("%s \n", buffer);
+	}
+}
+
 //=================================
 // Common routine
 //=================================
@@ -347,14 +367,14 @@ void AddrAssignment(byte *data)
 
 	if (CheckUniqNumber(index))
 	{
-		printf("EV board id = %x \n", index);
-//		printf("target_number[0] = %x \n", target_number[0]);
-//		printf("target_number[1] = %x \n", target_number[1]);
-//		printf("target_number[2] = %x \n", target_number[2]);
-//		printf("target_number[3] = %x \n", target_number[3]);
-//		printf("target_number[4] = %x \n", target_number[4]);
-
-		printf("SetTargetAddr = %d \n", index);
+		PRINTF_FUNC("EV board id = %x \n", index);
+//		PRINTF_FUNC("target_number[0] = %x \n", target_number[0]);
+//		PRINTF_FUNC("target_number[1] = %x \n", target_number[1]);
+//		PRINTF_FUNC("target_number[2] = %x \n", target_number[2]);
+//		PRINTF_FUNC("target_number[3] = %x \n", target_number[3]);
+//		PRINTF_FUNC("target_number[4] = %x \n", target_number[4]);
+
+		PRINTF_FUNC("SetTargetAddr = %d, type = %d \n", index, _chargingData[index - 1]->Type);
 		SetTargetAddr(target_number, index);
 	}
 }
@@ -574,7 +594,7 @@ void AbnormalStopAnalysis(byte gun_index, byte *errCode)
 			ShmSysConfigAndInfo->SysStopChargingAlarmCode.Level = 0x00;
 		}
 	}
-	printf("NOTIFICATION_EV_STOP : Err Code = %s \n", string);
+	PRINTF_FUNC("NOTIFICATION_EV_STOP : Err Code = %s \n", string);
 
 	if (strcmp(string, "023700") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ChademoEvCommFail = 0x01;
 	if (strcmp(string, "023701") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsEvCommFail = 0x01;
@@ -791,7 +811,7 @@ void CANReceiver()
 				if (GetTimeoutValue(_cmd_ack_timeout[_index]) >= 5000000)
 				{
 					// ACK timeout
-					//printf("gun = %x, ack timeout \n", _index);
+					//PRINTF_FUNC("gun = %x, ack timeout \n", _index);
 				}
 			}
 
@@ -821,7 +841,7 @@ void CANReceiver()
 
 				if(targetGun < 0 || targetGun >= CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY)
 				{
-					printf("EvComm (CANReceiver) : Target index = %x is < 0 or > QUANTITY \n", targetGun);
+					PRINTF_FUNC("EvComm (CANReceiver) : Target index = %x is < 0 or > QUANTITY \n", targetGun);
 					continue;
 				}
 				if(intCmd == 256)
@@ -837,8 +857,8 @@ void CANReceiver()
 						_chargingData[targetGun]->ConnectorPlugIn = frame.data[0];
 						_chargingData[targetGun]->PilotVoltage = frame.data[1];
 
-						//printf("index = %d, ConnectorPlugIn = %x, data[0] = %x \n", targetGun, _chargingData[targetGun]->ConnectorPlugIn, frame.data[0]);
-						//printf("ConnectorPlugIn = %x \n", (-120 + frame.data[1]) / 10);
+						//PRINTF_FUNC("index = %d, ConnectorPlugIn = %x, data[0] = %x \n", targetGun, _chargingData[targetGun]->ConnectorPlugIn, frame.data[0]);
+						//PRINTF_FUNC("ConnectorPlugIn = %x \n", (-120 + frame.data[1]) / 10);
 					}
 						break;
 					case ACK_EV_FW_VERSION:
@@ -847,22 +867,22 @@ void CANReceiver()
 						{
 							memcpy(ShmCHAdeMOData->evse[_chargingData[targetGun]->type_index].version, frame.data, ARRAY_SIZE(frame.data));
 							ShmCHAdeMOData->evse[_chargingData[targetGun]->type_index].SelfTest_Comp = PASS;
-							//printf("chademo ver. : %s\n", ShmCHAdeMOData->evse[_chargingData[targetGun]->type_index].version);
+							//PRINTF_FUNC("chademo ver. : %s\n", ShmCHAdeMOData->evse[_chargingData[targetGun]->type_index].version);
 						}
-						else if (_chargingData[targetGun]->Type == _Type_CCS)
+						else if (_chargingData[targetGun]->Type == _Type_CCS_2)
 						{
-							printf("Get FW HW = %s \n", frame.data);
 							if (ShmCcsData->CommProtocol == 0x01)
 							{
 								memcpy(&ShmCcsData->V2GMessage_DIN70121[_chargingData[targetGun]->type_index].version, frame.data, ARRAY_SIZE(frame.data));
 								ShmCcsData->V2GMessage_DIN70121[_chargingData[targetGun]->type_index].SelfTest_Comp = PASS;
+								//PRINTF_FUNC("CCS FW = %s \n", ShmCcsData->V2GMessage_DIN70121[_chargingData[targetGun]->type_index].version);
 							}
 						}
 					}
 						break;
 					case ACK_EV_HW_VERSION:
 					{
-						//printf("Get EV HW = %s \n", frame.data);
+						//PRINTF_FUNC("Get EV HW = %s \n", frame.data);
 					}
 						break;
 					case ACK_GET_OUTPUT_REQ:
@@ -884,7 +904,7 @@ void CANReceiver()
 							ShmCHAdeMOData->ev[_chargingData[targetGun]->type_index].TargetBatteryVoltage = _chargingData[targetGun]->EvBatterytargetVoltage;
 							ShmCHAdeMOData->ev[_chargingData[targetGun]->type_index].ChargingCurrentRequest = _chargingData[targetGun]->EvBatterytargetCurrent;
 						}
-						else if (_chargingData[targetGun]->Type == _Type_CCS)
+						else if (_chargingData[targetGun]->Type == _Type_CCS_2)
 						{
 							if(ShmCcsData->CommProtocol == 0x01)
 							{
@@ -892,10 +912,10 @@ void CANReceiver()
 							}
 						}
 
-						//printf("EvBatterytargetVoltage = %f \n", _chargingData[targetGun]->EvBatterytargetVoltage);
-						//printf("EvBatterytargetCurrent = %f \n", _chargingData[targetGun]->EvBatterytargetCurrent);
-						//printf("BatteryVoltage = %d \n", ShmCHAdeMOData->ev[_chargingData[target]->type_index].TargetBatteryVoltage);
-						//printf("CurrentRequest = %d \n", ShmCHAdeMOData->ev[_chargingData[target]->type_index].ChargingCurrentRequest);
+						//PRINTF_FUNC("EvBatterytargetVoltage = %f \n", _chargingData[targetGun]->EvBatterytargetVoltage);
+						//PRINTF_FUNC("EvBatterytargetCurrent = %f \n", _chargingData[targetGun]->EvBatterytargetCurrent);
+						//PRINTF_FUNC("BatteryVoltage = %d \n", ShmCHAdeMOData->ev[_chargingData[target]->type_index].TargetBatteryVoltage);
+						//PRINTF_FUNC("CurrentRequest = %d \n", ShmCHAdeMOData->ev[_chargingData[target]->type_index].ChargingCurrentRequest);
 					}
 						break;
 					case ACK_GET_EV_BATTERY_INFO:
@@ -910,11 +930,11 @@ void CANReceiver()
 							ShmCHAdeMOData->ev[_chargingData[targetGun]->type_index].TotalBatteryCapacity = ((short) frame.data[2] << 8) + (short) frame.data[1];
 							ShmCHAdeMOData->ev[_chargingData[targetGun]->type_index].MaxiBatteryVoltage = _chargingData[targetGun]->EvBatteryMaxVoltage;
 
-							//printf("EvBatteryMaxVoltage = %f \n", _chargingData[target]->EvBatteryMaxVoltage);
-							//printf("TotalBatteryCapacity = %d \n", ShmCHAdeMOData->ev[_chargingData[target]->type_index].TotalBatteryCapacity);
-							//printf("MaxiBatteryVoltage = %d \n", ShmCHAdeMOData->ev[_chargingData[target]->type_index].MaxiBatteryVoltage);
+							//PRINTF_FUNC("EvBatteryMaxVoltage = %f \n", _chargingData[target]->EvBatteryMaxVoltage);
+							//PRINTF_FUNC("TotalBatteryCapacity = %d \n", ShmCHAdeMOData->ev[_chargingData[target]->type_index].TotalBatteryCapacity);
+							//PRINTF_FUNC("MaxiBatteryVoltage = %d \n", ShmCHAdeMOData->ev[_chargingData[target]->type_index].MaxiBatteryVoltage);
 						}
-						else if (_chargingData[targetGun]->Type == _Type_CCS)
+						else if (_chargingData[targetGun]->Type == _Type_CCS_2)
 						{
 
 						}
@@ -930,7 +950,7 @@ void CANReceiver()
 							_chargingData[targetGun]->PilotVoltage = (float)(-120 + frame.data[3]) / 10;
 							ShmCHAdeMOData->evse[_chargingData[targetGun]->type_index].EvboardStatus = frame.data[7];
 						}
-						else if (_chargingData[targetGun]->Type == _Type_CCS)
+						else if (_chargingData[targetGun]->Type == _Type_CCS_2)
 						{
 							if (ShmCcsData->CommProtocol == 0x01)
 							{
@@ -941,11 +961,11 @@ void CANReceiver()
 							}
 						}
 
-						//printf("EvboardStatus = %x \n", ShmCHAdeMOData->evse[_chargingData[target]->type_index].EvboardStatus);
-						//printf("ConnectorPlug locked = %x \n", frame.data[0]);
-						//printf("ConnectorTemp 0= %d \n", ShmCHAdeMOData->evse[_chargingData[target]->type_index].ConnectorTemperatureP);
-						//printf("ConnectorTemp 1= %d \n", ShmCHAdeMOData->evse[_chargingData[target]->type_index].ConnectorTemperatureN);
-						//printf("PilotVoltage = %x \n", (-120 + frame.data[3]) / 10);
+						//PRINTF_FUNC("EvboardStatus = %x \n", ShmCHAdeMOData->evse[_chargingData[target]->type_index].EvboardStatus);
+						//PRINTF_FUNC("ConnectorPlug locked = %x \n", frame.data[0]);
+						//PRINTF_FUNC("ConnectorTemp 0= %d \n", ShmCHAdeMOData->evse[_chargingData[target]->type_index].ConnectorTemperatureP);
+						//PRINTF_FUNC("ConnectorTemp 1= %d \n", ShmCHAdeMOData->evse[_chargingData[target]->type_index].ConnectorTemperatureN);
+						//PRINTF_FUNC("PilotVoltage = %x \n", (-120 + frame.data[3]) / 10);
 					}
 						break;
 					case ACK_EVSE_ISOLATION_STATUS:	{}
@@ -959,7 +979,7 @@ void CANReceiver()
 					{
 						// 車端要求停止
 						// frame.data[0] : 0x01 => normal stop, 0x02 => ev emergency stop
-						printf("NOTIFICATION_EV_STOP -----------------------------\n");
+						PRINTF_FUNC("NOTIFICATION_EV_STOP -----------------------------\n");
 						if (frame.data[0] == 0x02)
 						{
 							AbnormalStopAnalysis(targetGun, frame.data + 1);
@@ -968,7 +988,7 @@ void CANReceiver()
 					}
 						break;
 					default:
-						printf("EV board = %d, Ack none defined. intCmd = %d  \n", targetGun, intCmd);
+						PRINTF_FUNC("EV board = %d, Ack none defined. intCmd = %d  \n", targetGun, intCmd);
 						break;
 				}
 			}
@@ -998,10 +1018,10 @@ void SetPresentChargingOutputPower(struct ChargingInfoData *chargingData_1, stru
 	float vol1 = 0, cur1 = 0;
 	float vol2 = 0, cur2 = 0;
 
-	//printf("f vol - 0 = %f \n", chargingData_1->FireChargingVoltage);
-	//printf("f cur - 0 = %f \n", chargingData_1->PresentChargingCurrent);
-	//printf("***********************f vol - 1 = %f \n", chargingData_2->FireChargingVoltage);
-	//printf("***********************f cur - 1 = %f \n", chargingData_2->PresentChargingCurrent);
+	//PRINTF_FUNC("f vol - 0 = %f \n", chargingData_1->FireChargingVoltage);
+	//PRINTF_FUNC("f cur - 0 = %f \n", chargingData_1->PresentChargingCurrent);
+	//PRINTF_FUNC("***********************f vol - 1 = %f \n", chargingData_2->FireChargingVoltage);
+	//PRINTF_FUNC("***********************f cur - 1 = %f \n", chargingData_2->PresentChargingCurrent);
 
 	vol1 = chargingData_1->FireChargingVoltage;
 	cur1 = chargingData_1->PresentChargingCurrent;
@@ -1018,6 +1038,12 @@ void SetPresentChargingOutputCap(struct ChargingInfoData *chargingData_1, struct
 	float pow2 = 0, cur2 = 0;
 	float vol = 0;
 
+	chargingData_1->AvailableChargingPower = 300;
+	chargingData_2->AvailableChargingPower = 300;
+
+	chargingData_1->AvailableChargingCurrent = 500;
+	chargingData_2->AvailableChargingCurrent = 600;
+
 	if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag != _REASSIGNED_NONE)
 	{
 		pow1 = chargingData_1->DeratingChargingPower;
@@ -1030,6 +1056,7 @@ void SetPresentChargingOutputCap(struct ChargingInfoData *chargingData_1, struct
 	}
 	vol = chargingData_1->MaximumChargingVoltage;
 	GetMaxVolAndCurMethod(chargingData_1->Index, &vol, &cur1);
+	GetMaxPowerMethod(&pow1);
 
 	if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag != _REASSIGNED_NONE)
 	{
@@ -1043,8 +1070,9 @@ void SetPresentChargingOutputCap(struct ChargingInfoData *chargingData_1, struct
 	}
 	vol = chargingData_2->MaximumChargingVoltage;
 	GetMaxVolAndCurMethod(chargingData_2->Index, &vol, &cur2);
+	GetMaxPowerMethod(&pow2);
 
-	printf("To EV Power_1 = %f, Cur_1 = %f, Power_2 = %f, Cur_2 = %f \n", pow1, cur1, pow2, cur2);
+	PRINTF_FUNC("To EV Power_1 = %f, Cur_1 = %f, Power_2 = %f, Cur_2 = %f \n", pow1, cur1, pow2, cur2);
 	SetPresentOutputCapacity(pow1, cur1, pow2, cur2);
 }
 
@@ -1068,11 +1096,17 @@ void Initialization()
 
 void GetMaxVolAndCurMethod(byte index, float *vol, float *cur)
 {
-	if (maxChargingVol != 0 && maxChargingVol <= *vol)
-		*vol = maxChargingVol;
+	if (maxChargingVol[index] != 0 && maxChargingVol[index] <= *vol)
+		*vol = maxChargingVol[index];
+
+	if (maxChargingCur[index] != 0 && maxChargingCur[index] <= *cur)
+		*cur = maxChargingCur[index];
+}
 
-	if (maxChargingCur != 0 && maxChargingCur <= *cur)
-		*cur = maxChargingCur;
+void GetMaxPowerMethod(float *pow)
+{
+	if (maxChargingPow != 0 && maxChargingPow <= *pow)
+		*pow = maxChargingPow;
 }
 
 void GetStopChargingReasonByEvse(byte gunIndex, byte *reason)
@@ -1098,7 +1132,7 @@ void GetStopChargingReasonByEvse(byte gunIndex, byte *reason)
 		*(reason + 1) = 1;
 		*(reason + 0) = 2;
 	}
-	else if (_chargingData[gunIndex]->Type == _Type_CCS &&
+	else if (_chargingData[gunIndex]->Type == _Type_CCS_2 &&
 			ShmStatusCodeData->FaultCode.FaultEvents.bits.CcsOutputRelayDrivingFault == 0x01)
 	{
 		// 011014
@@ -1145,7 +1179,7 @@ int main(int argc, char *argv[])
 					GetFirmwareVersion(_index, _chargingData[_index]->Evboard_id);
 					GetHardwareVersion(_index, _chargingData[_index]->Evboard_id);
 				}
-				else if (_chargingData[_index]->Type == _Type_CCS)
+				else if (_chargingData[_index]->Type == _Type_CCS_2)
 				{
 					if (ShmCcsData->CommProtocol == 0x01 &&
 						ShmCcsData->V2GMessage_DIN70121[_chargingData[_index]->type_index].SelfTest_Comp != PASS)
@@ -1156,7 +1190,7 @@ int main(int argc, char *argv[])
 				}
 
 				// 固定要取得的資訊 : 1.槍鎖狀態, 2."Connector 1" 溫度, 3."Connector 2" 溫度, 4.Pilot Voltage
-				//printf("GetMiscellaneousInfo. index = %d, Eid = %d \n", _index, _chargingData[_index]->Evboard_id);
+				//PRINTF_FUNC("GetMiscellaneousInfo. index = %d, Eid = %d \n", _index, _chargingData[_index]->Evboard_id);
 				GetMiscellaneousInfo(_index, _chargingData[_index]->Evboard_id);
 			}
 
@@ -1172,21 +1206,26 @@ int main(int argc, char *argv[])
 					{
 						ClearAbnormalStatus_Chademo(_index);
 					}
-					else if (_chargingData[_index]->Type == _Type_CCS)
+					else if (_chargingData[_index]->Type == _Type_CCS_2)
 					{
 						ClearAbnormalStatus_CCS(_index);
 					}
+
+					if (priorityLow == 1)
+					{
+						maxChargingCur[_index] = ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent;
+					}
 					break;
 				case S_PREPARING_FOR_EV:
 				{
 					// 開始確認車端是否同意開始充電 : 1.SOC, 2.Target Vol, 3.Target Cur, 4.Charging remaining time
 					GetOutputReq(_index, _chargingData[_index]->Evboard_id);
 
-					//printf("PresentChargingVoltage = %f \n", _chargingData[_index]->PresentChargingVoltage);
-					//printf("PresentChargingCurrent = %f \n", _chargingData[_index]->PresentChargingCurrent);
-					//printf("AvailableChargingPower = %f \n", _chargingData[_index]->AvailableChargingPower);
-					//printf("AvailableChargingCurrent = %f \n", _chargingData[_index]->AvailableChargingCurrent);
-					//printf("MaximumChargingVoltage = %f \n", _chargingData[_index]->MaximumChargingVoltage);
+					//PRINTF_FUNC("PresentChargingVoltage = %f \n", _chargingData[_index]->PresentChargingVoltage);
+					//PRINTF_FUNC("PresentChargingCurrent = %f \n", _chargingData[_index]->PresentChargingCurrent);
+					//PRINTF_FUNC("AvailableChargingPower = %f \n", _chargingData[_index]->AvailableChargingPower);
+					//PRINTF_FUNC("AvailableChargingCurrent = %f \n", _chargingData[_index]->AvailableChargingCurrent);
+					//PRINTF_FUNC("MaximumChargingVoltage = %f \n", _chargingData[_index]->MaximumChargingVoltage);
 
 					// 設定當前輸出
 					if (gun_count == 1)
@@ -1210,7 +1249,7 @@ int main(int argc, char *argv[])
 						}
 						GetMaxVolAndCurMethod(_index, &maxVol, &maxCur);
 
-						printf("To EV Max_Vol = %f, Cap_Cur = %f \n", maxVol, maxCur);
+						PRINTF_FUNC("To EV Max_Vol = %f, Cap_Cur = %f \n", maxVol, maxCur);
 						SetChargingPermission(_index, START,
 						_chargingData[_index]->AvailableChargingPower,
 								maxCur,
@@ -1308,7 +1347,7 @@ int main(int argc, char *argv[])
 							SetIsolationStatus(_index, _chargingData[_index]->GroundFaultStatus, _chargingData[_index]->Evboard_id);
 						}
 
-						if(_chargingData[_index]->Type == _Type_CCS &&
+						if(_chargingData[_index]->Type == _Type_CCS_2 &&
 							_chargingData[_index]->PrechargeStatus == PRECHARGE_READY)
 						{
 							SetEvsePrechargeInfo(_index, PRECHARGE_CHARELAY_PASS, _chargingData[_index]->Evboard_id);

+ 17 - 2
EVSE/Projects/DS60-120/Apps/Module_EventLogging.c

@@ -28,7 +28,6 @@
 #include 	<ifaddrs.h>
 #include	"../../define.h"
 
-#define Debug
 #define ARRAY_SIZE(A)		(sizeof(A) / sizeof(A[0]))
 #define PASS				1
 #define FAIL				-1
@@ -36,6 +35,8 @@
 struct SysConfigAndInfo			*ShmSysConfigAndInfo;
 struct StatusCodeData 			*ShmStatusCodeData;
 
+void PRINTF_FUNC(char *string, ...);
+
 int StoreLogMsg(const char *fmt, ...);
 #define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
 #define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
@@ -75,6 +76,20 @@ int DiffTimeb(struct timeb ST, struct timeb ET)
 	return (StopTime-StartTime)*1000+ET.millitm-ST.millitm;
 }
 
+void PRINTF_FUNC(char *string, ...)
+{
+	if (DEBUG)
+	{
+		va_list args;
+		char buffer[4096];
+
+		va_start(args, string);
+		vsnprintf(buffer, sizeof(buffer), string, args);
+		va_end(args);
+		printf("%s \n", buffer);
+	}
+}
+
 //=================================
 // Common routine
 //=================================
@@ -233,7 +248,7 @@ int main(void)
 		}
 
 		//check Alarm Status
-		for(ByteCount=0;ByteCount<8;ByteCount++)
+		for(ByteCount=0;ByteCount<11;ByteCount++)
 		{
 			if(ShmStatusCodeData->AlarmCode.AlarmEvents.AlarmVal[ByteCount] != ShmStatusCodeData->AlarmCode.PreviousAlarmVal[ByteCount])
 			{

+ 205 - 67
EVSE/Projects/DS60-120/Apps/Module_InternalComm.c

@@ -31,7 +31,6 @@
 #include	"internalComm.h"
 #include 	<stdbool.h>
 
-#define Debug
 #define ARRAY_SIZE(A)		(sizeof(A) / sizeof(A[0]))
 #define PASS				1
 #define FAIL				-1
@@ -53,8 +52,8 @@ struct CcsData					*ShmCcsData;
 #define VOUT_MIN_VOLTAGE	150
 #define IOUT_MAX_CURRENT	50
 
-#define MAX_FAN_SPEED		6000
-#define MIN_FAN_SPEED		300
+#define MAX_FAN_SPEED		13500
+#define MIN_FAN_SPEED		2800
 
 // GFD Status
 #define GFD_IDLE			0
@@ -81,7 +80,7 @@ bool FindChargingInfoData(byte target, struct ChargingInfoData **chargingData);
 
 int Uart5Fd;
 char *relayRs485PortName = "/dev/ttyS5";
-unsigned short fanSpeedSmoothValue = 100;
+unsigned short fanSpeedSmoothValue = 1000;
 
 struct timeval _priority_time;
 
@@ -97,6 +96,9 @@ Gpio_in gpio_in;
 Gpio_out gpio_out;
 Relay outputRelay;
 Relay regRelay;
+Rtc rtc;
+
+void PRINTF_FUNC(char *string, ...);
 
 int StoreLogMsg(const char *fmt, ...);
 unsigned long GetTimeoutValue(struct timeval _sour_time);
@@ -152,6 +154,20 @@ unsigned short MaxValue(unsigned short value1, unsigned short value2)
 	return value1 >= value2 ? value1 : value2;
 }
 
+void PRINTF_FUNC(char *string, ...)
+{
+	if (DEBUG)
+	{
+		va_list args;
+		char buffer[4096];
+
+		va_start(args, string);
+		vsnprintf(buffer, sizeof(buffer), string, args);
+		va_end(args);
+		printf("%s \n", buffer);
+	}
+}
+
 //==========================================
 // Communication Function
 //==========================================
@@ -163,14 +179,14 @@ void GetFwAndHwVersion_Fan()
 		strcpy((char *) ShmFanModuleData->version, ver.Version_FW);
 		// SystemInfo
 		strcpy((char *) ShmSysConfigAndInfo->SysInfo.FanModuleFwRev, ver.Version_FW);
-		printf("GetFwAndHwVersion_Fan s1 = %s \n", ver.Version_FW);
+		//PRINTF_FUNC("GetFwAndHwVersion_Fan s1 = %s \n", ver.Version_FW);
 	}
 
 	if (Query_HW_Ver(Uart5Fd, Addr.Fan, &ver) == PASS)
 	{
 		// SystemInfo
 		strcpy((char *) ShmSysConfigAndInfo->SysInfo.FanModuleHwRev, ver.Version_FW);
-		printf("GetFwAndHwVersion_Fan s2 = %s \n", ver.Version_HW);
+		//PRINTF_FUNC("GetFwAndHwVersion_Fan s2 = %s \n", ver.Version_HW);
 	}
 }
 
@@ -182,22 +198,96 @@ void GetFwAndHwVersion_Relay()
 		strcpy((char *) ShmRelayModuleData->version, ver.Version_FW);
 		// SystemInfo
 		strcpy((char *) ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev, ver.Version_FW);
-		printf("GetFwAndHwVersion_Relay s1 = %s \n", ver.Version_FW);
+		//PRINTF_FUNC("GetFwAndHwVersion_Relay s1 = %s \n", ver.Version_FW);
 	}
 
 	if (Query_HW_Ver(Uart5Fd, Addr.Relay, &ver) == PASS)
 	{
 		// SystemInfo
 		strcpy((char *) ShmSysConfigAndInfo->SysInfo.RelayModuleHwRev, ver.Version_FW);
-		printf("GetFwAndHwVersion_Relay s2 = %s \n", ver.Version_HW);
+		//PRINTF_FUNC("GetFwAndHwVersion_Relay s2 = %s \n", ver.Version_HW);
 	}
 }
 
+void SetRtcData_Relay()
+{
+	struct timeb csuTime;
+	struct tm *tmCSU;
+
+	ftime(&csuTime);
+	tmCSU = localtime(&csuTime.time);
+	//	PRINTF_FUNC("Time : %04d-%02d-%02d %02d:%02d:%02d \n", tmCSU->tm_year + 1900,
+	//			tmCSU->tm_mon + 1, tmCSU->tm_mday, tmCSU->tm_hour, tmCSU->tm_min,
+	//			tmCSU->tm_sec);
+
+	rtc.RtcData[0] = '0' + (tmCSU->tm_year + 1900) / 1000 % 10;
+	rtc.RtcData[1] = '0' + (tmCSU->tm_year + 1900) / 100 % 10;
+	rtc.RtcData[2] = '0' + (tmCSU->tm_year + 1900) / 10 % 10;
+	rtc.RtcData[3] = '0' + (tmCSU->tm_year + 1900) / 1 % 10;
+
+	rtc.RtcData[4] = '0' + (tmCSU->tm_mon + 1) / 10 % 10;
+	rtc.RtcData[5] = '0' + (tmCSU->tm_mon + 1) / 1 % 10;
+
+	rtc.RtcData[6] = '0' + (tmCSU->tm_mday) / 10 % 10;
+	rtc.RtcData[7] = '0' + (tmCSU->tm_mday) / 1 % 10;
+
+	rtc.RtcData[8] = '0' + (tmCSU->tm_hour) / 10 % 10;
+	rtc.RtcData[9] = '0' + (tmCSU->tm_hour) / 1 % 10;
+
+	rtc.RtcData[10] = '0' + (tmCSU->tm_min) / 10 % 10;
+	rtc.RtcData[11] = '0' + (tmCSU->tm_min) / 1 % 10;
+
+	rtc.RtcData[12] = '0' + (tmCSU->tm_sec) / 10 % 10;
+	rtc.RtcData[13] = '0' + (tmCSU->tm_sec) / 1 % 10;
+
+	if (Config_Rtc_Data(Uart5Fd, Addr.Relay, &rtc) == PASS)
+		PRINTF_FUNC("SetRtc (RB) sucessfully. \n");
+	else
+		PRINTF_FUNC("SetRtc (RB) fail. \n");
+}
+
+void SetRtcData_Fan()
+{
+	struct timeb csuTime;
+	struct tm *tmCSU;
+
+	ftime(&csuTime);
+	tmCSU = localtime(&csuTime.time);
+	//	PRINTF_FUNC("Time : %04d-%02d-%02d %02d:%02d:%02d \n", tmCSU->tm_year + 1900,
+	//			tmCSU->tm_mon + 1, tmCSU->tm_mday, tmCSU->tm_hour, tmCSU->tm_min,
+	//			tmCSU->tm_sec);
+
+	rtc.RtcData[0] = '0' + (tmCSU->tm_year + 1900) / 1000 % 10;
+	rtc.RtcData[1] = '0' + (tmCSU->tm_year + 1900) / 100 % 10;
+	rtc.RtcData[2] = '0' + (tmCSU->tm_year + 1900) / 10 % 10;
+	rtc.RtcData[3] = '0' + (tmCSU->tm_year + 1900) / 1 % 10;
+
+	rtc.RtcData[4] = '0' + (tmCSU->tm_mon + 1) / 10 % 10;
+	rtc.RtcData[5] = '0' + (tmCSU->tm_mon + 1) / 1 % 10;
+
+	rtc.RtcData[6] = '0' + (tmCSU->tm_mday) / 10 % 10;
+	rtc.RtcData[7] = '0' + (tmCSU->tm_mday) / 1 % 10;
+
+	rtc.RtcData[8] = '0' + (tmCSU->tm_hour) / 10 % 10;
+	rtc.RtcData[9] = '0' + (tmCSU->tm_hour) / 1 % 10;
+
+	rtc.RtcData[10] = '0' + (tmCSU->tm_min) / 10 % 10;
+	rtc.RtcData[11] = '0' + (tmCSU->tm_min) / 1 % 10;
+
+	rtc.RtcData[12] = '0' + (tmCSU->tm_sec) / 10 % 10;
+	rtc.RtcData[13] = '0' + (tmCSU->tm_sec) / 1 % 10;
+
+	if (Config_Rtc_Data(Uart5Fd, Addr.Fan, &rtc) == PASS)
+		PRINTF_FUNC("SetRtc (FB) sucessfully. \n");
+	else
+		PRINTF_FUNC("SetRtc (FB) fail. \n");
+}
+
 void SetModelName_Fan()
 {
 	if (Config_Model_Name(Uart5Fd, Addr.Fan, ShmSysConfigAndInfo->SysConfig.ModelName) == PASS)
 	{
-		printf("Set Model name PASS \n");
+		PRINTF_FUNC("Set Model name PASS = %s \n", ShmSysConfigAndInfo->SysConfig.ModelName);
 	}
 }
 
@@ -207,9 +297,9 @@ void GetPresentInputVol()
 	if (Query_Present_InputVoltage(Uart5Fd, Addr.Relay, &inputVoltage) == PASS)
 	{
 		// resolution : 0.1
-		//printf("InputVoltageR = %f \n", inputVoltage.L1N_L12);
-		//printf("InputVoltageS = %f \n", inputVoltage.L2N_L23);
-		//printf("InputVoltageT = %f \n", inputVoltage.L3N_L31);
+		//PRINTF_FUNC("InputVoltageR = %f \n", inputVoltage.L1N_L12);
+		//PRINTF_FUNC("InputVoltageS = %f \n", inputVoltage.L2N_L23);
+		//PRINTF_FUNC("InputVoltageT = %f \n", inputVoltage.L3N_L31);
 
 		ShmRelayModuleData->InputL1Volt = inputVoltage.L1N_L12;
 		ShmRelayModuleData->InputL2Volt = inputVoltage.L2N_L23;
@@ -287,13 +377,13 @@ void GetPersentOutputVol()
 {
 	if (Query_Present_OutputVoltage(Uart5Fd, Addr.Relay, &outputVoltage) == PASS)
 	{
-//		printf("Conn1 fuse 1 = %f \n", outputVoltage.behindFuse_Voltage_C1);
-//		printf("Conn1 relay 1 = %f \n", outputVoltage.behindRelay_Voltage_C1);
-//		printf("Conn2 fuse 2 = %f \n", outputVoltage.behindFuse_Voltage_C2);
-//		printf("Conn2 relay 2 = %f \n", outputVoltage.behindRelay_Voltage_C2);
+//		PRINTF_FUNC("Conn1 fuse 1 = %f \n", outputVoltage.behindFuse_Voltage_C1);
+//		PRINTF_FUNC("Conn1 relay 1 = %f \n", outputVoltage.behindRelay_Voltage_C1);
+//		PRINTF_FUNC("Conn2 fuse 2 = %f \n", outputVoltage.behindFuse_Voltage_C2);
+//		PRINTF_FUNC("Conn2 relay 2 = %f \n", outputVoltage.behindRelay_Voltage_C2);
 
-		//printf("outputVoltage.behindFuse_Voltage_C1 = %f \n", outputVoltage.behindFuse_Voltage_C1);
-		//printf("outputVoltage.behindFuse_Voltage_C2 = %f \n", outputVoltage.behindFuse_Voltage_C2);
+		//PRINTF_FUNC("outputVoltage.behindFuse_Voltage_C1 = %f \n", outputVoltage.behindFuse_Voltage_C1);
+		//PRINTF_FUNC("outputVoltage.behindFuse_Voltage_C2 = %f \n", outputVoltage.behindFuse_Voltage_C2);
 
 		ShmRelayModuleData->Gun1FuseOutputVolt = outputVoltage.behindFuse_Voltage_C1;
 		ShmRelayModuleData->Gun1RelayOutputVolt = outputVoltage.behindRelay_Voltage_C1;
@@ -338,7 +428,7 @@ void GetPersentOutputVol()
 					//ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemChademoOutputOCP = 0x01;
 				}
 			}
-			else if (_chargingData[index]->Type == _Type_CCS)
+			else if (_chargingData[index]->Type == _Type_CCS_2)
 			{
 
 			}
@@ -349,17 +439,17 @@ void GetPersentOutputVol()
 // 風扇速度
 void GetFanSpeed()
 {
-	printf("Get fan board speed \n");
+	//PRINTF_FUNC("Get fan board speed \n");
 	if (Query_Fan_Speed(Uart5Fd, Addr.Fan, &fanSpeed) == PASS)
 	{
 		ShmFanModuleData->PresentFan1Speed = fanSpeed.speed[0];
 		ShmFanModuleData->PresentFan2Speed = fanSpeed.speed[1];
 		ShmFanModuleData->PresentFan3Speed = fanSpeed.speed[2];
 		ShmFanModuleData->PresentFan4Speed = fanSpeed.speed[3];
-		printf("SystemFanRotaSpeed_1 = %d \n", fanSpeed.speed[0]);
-		printf("SystemFanRotaSpeed_2 = %d \n", fanSpeed.speed[1]);
-		printf("SystemFanRotaSpeed_3 = %d \n", fanSpeed.speed[2]);
-		printf("SystemFanRotaSpeed_4 = %d \n", fanSpeed.speed[3]);
+//		PRINTF_FUNC("SystemFanRotaSpeed_1 = %d \n", fanSpeed.speed[0]);
+//		PRINTF_FUNC("SystemFanRotaSpeed_2 = %d \n", fanSpeed.speed[1]);
+//		PRINTF_FUNC("SystemFanRotaSpeed_3 = %d \n", fanSpeed.speed[2]);
+//		PRINTF_FUNC("SystemFanRotaSpeed_4 = %d \n", fanSpeed.speed[3]);
 		// Config_Fan_Speed(Uart5Fd, Addr.Fan, &fanSpeed[0]);
 		//SysInfoData (SystemFanRotaSpeed)
 	}
@@ -386,7 +476,7 @@ void CheckK1K2RelayOutput(byte index)
 			else
 				_chargingData[index]->RelayK1K2Status = NO;
 
-			if(_chargingData[index]->Type == _Type_CCS)
+			if(_chargingData[index]->Type == _Type_CCS_2)
 			{
 				if (regRelay.relay_event.bits.Gun1_N == YES	&& regRelay.relay_event.bits.CCS_Precharge == YES)
 					_chargingData[index]->RelayKPK2Status = YES;
@@ -401,7 +491,7 @@ void CheckK1K2RelayOutput(byte index)
 			else
 				_chargingData[index]->RelayK1K2Status = NO;
 
-			if(_chargingData[index]->Type == _Type_CCS)
+			if(_chargingData[index]->Type == _Type_CCS_2)
 			{
 				if (regRelay.relay_event.bits.Gun2_N == YES	&& regRelay.relay_event.bits.CCS_Precharge == YES)
 					_chargingData[index]->RelayKPK2Status = YES;
@@ -418,7 +508,7 @@ void CheckK1K2RelayOutput(byte index)
 		else
 			_chargingData[index]->RelayK1K2Status = NO;
 
-		if(_chargingData[index]->Type == _Type_CCS)
+		if(_chargingData[index]->Type == _Type_CCS_2)
 		{
 			if (regRelay.relay_event.bits.Gun2_N == YES && regRelay.relay_event.bits.CCS_Precharge == YES)
 				_chargingData[index]->RelayKPK2Status = YES;
@@ -464,7 +554,7 @@ void GetGfdAdc()
 
 		//if (gfd_adc.result_conn1 != 0)
 		{
-//			printf("******************Resister_conn1 = %d, voltage_conn1 = %d, result_conn1 = %d, step = %d \n",
+//			PRINTF_FUNC("******************Resister_conn1 = %d, voltage_conn1 = %d, result_conn1 = %d, step = %d \n",
 //				gfd_adc.Resister_conn1,
 //				gfd_adc.voltage_conn1,
 //				gfd_adc.result_conn1,
@@ -481,19 +571,19 @@ void GetGpioInput()
 		if (gpio_in.AC_MainBreaker == 1)
 		{
 			// AC Main Breaker ON
-			printf("RB AC Main Breaker. \n");
+			PRINTF_FUNC("RB AC Main Breaker. \n");
 		}
 
 		if (gpio_in.SPD == 1)
 		{
 			// SPD (雷擊保護) ON
-			printf("RB SPD. \n");
+			PRINTF_FUNC("RB SPD. \n");
 		}
 
 		if (gpio_in.Door_Open == 1)
 		{
 			// Door Open
-			printf("RB Door Open. \n");
+			PRINTF_FUNC("RB Door Open. \n");
 		}
 
 		if (gpio_in.GFD[0] == 1)
@@ -509,13 +599,13 @@ void GetGpioInput()
 		if (gpio_in.AC_Drop == 1)
 		{
 			// AC Drop
-			printf("RB AC Drop. \n");
+			PRINTF_FUNC("RB AC Drop. \n");
 		}
 
 		if (gpio_in.Emergency_IO == 1)
 		{
 			// Emergency IO ON
-			printf("RB Emergency IO ON. \n");
+			PRINTF_FUNC("RB Emergency IO ON. \n");
 		}
 
 		if (gpio_in.Button_Emergency_Press == 1)
@@ -565,8 +655,8 @@ void GetAuxPower()
 		//ShmSysConfigAndInfo->SysInfo.AuxPower12V = auxPower.voltage[4];
 		//ShmSysConfigAndInfo->SysInfo.AuxPower5V = auxPower.voltage[6];
 		// aux power voltage
-		//printf("aux1 = %x, \n", auxPower.voltage[0]);
-		//printf("aux2 = %x, \n", auxPower.voltage[1]);
+		//PRINTF_FUNC("aux1 = %x, \n", auxPower.voltage[0]);
+		//PRINTF_FUNC("aux2 = %x, \n", auxPower.voltage[1]);
 	}
 }
 
@@ -583,30 +673,26 @@ void SetFanModuleSpeed()
 		unsigned short speed = ShmFanModuleData->PresentFan1Speed + fanSpeedSmoothValue;
 		if (speed >= ShmFanModuleData->SetFan1Speed)
 			speed = ShmFanModuleData->SetFan1Speed;
-		_fanSpeed.speed[0] = speed & 0xff;
-		_fanSpeed.speed[1] = (speed >> 8) & 0xff;
+		_fanSpeed.speed[0] = speed;
 
 		speed = ShmFanModuleData->PresentFan2Speed + fanSpeedSmoothValue;
 		if (speed >= ShmFanModuleData->SetFan2Speed)
 			speed = ShmFanModuleData->SetFan2Speed;
-		_fanSpeed.speed[2] = speed & 0xff;
-		_fanSpeed.speed[3] = (speed >> 8) & 0xff;
+		_fanSpeed.speed[1] = speed;
 
 		speed = ShmFanModuleData->PresentFan3Speed + fanSpeedSmoothValue;
 		if (speed >= ShmFanModuleData->SetFan3Speed)
 			speed = ShmFanModuleData->SetFan3Speed;
-		_fanSpeed.speed[4] = speed & 0xff;
-		_fanSpeed.speed[5] = (speed >> 8) & 0xff;
+		_fanSpeed.speed[2] = speed;
 
 		speed = ShmFanModuleData->PresentFan4Speed + fanSpeedSmoothValue;
 		if (speed >= ShmFanModuleData->SetFan4Speed)
 			speed = ShmFanModuleData->SetFan4Speed;
-		_fanSpeed.speed[6] = speed & 0xff;
-		_fanSpeed.speed[7] = (speed >> 8) & 0xff;
+		_fanSpeed.speed[3] = speed;
 
 		if (Config_Fan_Speed(Uart5Fd, Addr.Fan, &_fanSpeed) == PASS)
 		{
-			printf("successfully Fan\n");
+			//PRINTF_FUNC("successfully Fan\n");
 		}
 	}
 }
@@ -642,11 +728,11 @@ void SetRelayModuleFanSpeed()
 
 void GetRelayModuleFanSpeed()
 {
-	printf("Get fan board speed \n");
+	PRINTF_FUNC("Get fan board speed \n");
 	if (Query_Fan_Speed(Uart5Fd, Addr.Relay, &fanSpeed) == PASS)
 	{
 		ShmFanModuleData->PresentFan1Speed = fanSpeed.speed[0] + (fanSpeed.speed[1] >> 8);
-		printf("SystemFanRotaSpeed_1 = %d \n", fanSpeed.speed[0]);
+		PRINTF_FUNC("SystemFanRotaSpeed_1 = %d \n", fanSpeed.speed[0]);
 	}
 }
 
@@ -664,7 +750,7 @@ void SetK1K2RelayStatus(byte index)
 			else if (regRelay.relay_event.bits.Gun1_N == YES)
 				outputRelay.relay_event.bits.Gun1_N = NO;
 
-			if (_chargingData[index]->Type == _Type_CCS)
+			if (_chargingData[index]->Type == _Type_CCS_2)
 			{
 				if(regRelay.relay_event.bits.CCS_Precharge == YES)
 					outputRelay.relay_event.bits.CCS_Precharge = NO;
@@ -677,7 +763,7 @@ void SetK1K2RelayStatus(byte index)
 			else if (regRelay.relay_event.bits.Gun2_N == YES)
 				outputRelay.relay_event.bits.Gun2_N = NO;
 
-			if (_chargingData[index]->Type == _Type_CCS)
+			if (_chargingData[index]->Type == _Type_CCS_2)
 			{
 				if(regRelay.relay_event.bits.CCS_Precharge == YES)
 					outputRelay.relay_event.bits.CCS_Precharge = NO;
@@ -725,7 +811,7 @@ void SetK1K2RelayStatus(byte index)
 	{
 		if (_chargingData[index]->Evboard_id == 0x01)
 		{
-			if (_chargingData[index]->Type == _Type_CCS)
+			if (_chargingData[index]->Type == _Type_CCS_2)
 			{
 				if (regRelay.relay_event.bits.CCS_Precharge == NO)
 					outputRelay.relay_event.bits.CCS_Precharge = YES;
@@ -735,7 +821,7 @@ void SetK1K2RelayStatus(byte index)
 		}
 		else if (_chargingData[index]->Evboard_id == 0x02)
 		{
-			if (_chargingData[index]->Type == _Type_CCS)
+			if (_chargingData[index]->Type == _Type_CCS_2)
 			{
 				if (regRelay.relay_event.bits.CCS_Precharge == NO)
 					outputRelay.relay_event.bits.CCS_Precharge = YES;
@@ -748,7 +834,7 @@ void SetK1K2RelayStatus(byte index)
 	{
 		if (_chargingData[index]->Evboard_id == 0x01)
 		{
-			if (_chargingData[index]->Type == _Type_CCS)
+			if (_chargingData[index]->Type == _Type_CCS_2)
 			{
 				if (regRelay.relay_event.bits.Gun1_P == NO)
 					outputRelay.relay_event.bits.Gun1_P = YES;
@@ -758,7 +844,7 @@ void SetK1K2RelayStatus(byte index)
 		}
 		else if (_chargingData[index]->Evboard_id == 0x02)
 		{
-			if (_chargingData[index]->Type == _Type_CCS)
+			if (_chargingData[index]->Type == _Type_CCS_2)
 			{
 				if (regRelay.relay_event.bits.Gun2_P == NO)
 					outputRelay.relay_event.bits.Gun2_P = YES;
@@ -771,7 +857,7 @@ void SetK1K2RelayStatus(byte index)
 
 void SetParalleRelayStatus()
 {
-	if (gunCount >= 2)
+	if (gunCount >= 2 && ONE_CONNECTOR_USE == 0)
 	{
 		if (_chargingData[0]->SystemStatus == S_BOOTING || _chargingData[1]->SystemStatus == S_BOOTING)
 		{
@@ -1019,7 +1105,7 @@ bool IsNoneMatchRelayStatus()
 {
 	bool result = false;
 
-//	printf("Real Relay, AC = %x, g1_p = %x, g1_n = %x, g2_p = %x, g2_n = %x, pre = %x, bri_p = %x, bri_n = %x \n",
+//	PRINTF_FUNC("Real Relay, AC = %x, g1_p = %x, g1_n = %x, g2_p = %x, g2_n = %x, pre = %x, bri_p = %x, bri_n = %x \n",
 //			regRelay.relay_event.bits.AC_Contactor,
 //			regRelay.relay_event.bits.Gun1_P,
 //			regRelay.relay_event.bits.Gun1_N,
@@ -1084,10 +1170,10 @@ void SetGfdConfig(byte index, byte resister)
 	gfd_config.index = index;
 	gfd_config.state = resister;
 
-	//printf("************************GFD Vol = %d, GFD Res = %d \n", gfd_config.reqVol, gfd_config.resister);
+	//PRINTF_FUNC("************************GFD Vol = %d, GFD Res = %d \n", gfd_config.reqVol, gfd_config.resister);
 	if (Config_Gfd_Value(Uart5Fd, Addr.Relay, &gfd_config) == PASS)
 	{
-//		printf("Set reqVol = %f, resister = %d \n",
+//		PRINTF_FUNC("Set reqVol = %f, resister = %d \n",
 //				gfd_config.reqVol,
 //				gfd_config.resister);
 	}
@@ -1131,10 +1217,33 @@ void CheckOutputPowerOverCarReq(byte index)
 	float fireV = _chargingData[index]->FireChargingVoltage;
 	float carV = _chargingData[index]->EvBatterytargetVoltage;
 
-	if (fireV >= (carV + (carV * 0.1)))
+	if (_chargingData[index]->EvBatterytargetVoltage > 1500 &&
+			(_chargingData[index]->Type == _Type_Chademo || _chargingData[index]->Type == _Type_CCS_2 || _chargingData[index]->Type == _Type_GB))
 	{
-		printf("[Module_InternalComm]CheckOutputPowerOverCarReq NG \n");
-		_chargingData[index]->StopChargeFlag = YES;
+		if (fireV >= (carV + (carV * 0.1)))
+		{
+			PRINTF_FUNC("[Module_InternalComm]CheckOutputPowerOverCarReq NG : fire = %f, battery = %f \n",
+					_chargingData[index]->FireChargingVoltage, _chargingData[index]->EvBatterytargetVoltage);
+			DEBUG_ERROR("[Module_InternalComm]CheckOutputPowerOverCarReq NG : fire = %f, battery = %f \n",
+					_chargingData[index]->FireChargingVoltage, _chargingData[index]->EvBatterytargetVoltage);
+			_chargingData[index]->StopChargeFlag = YES;
+		}
+	}
+}
+
+void CheckOutputVolNoneMatchFire(byte index)
+{
+	if (_chargingData[index]->EvBatterytargetVoltage > 1500)
+	{
+		if ((_chargingData[index]->PresentChargingVoltage < _chargingData[index]->FireChargingVoltage - 300) ||
+				(_chargingData[index]->PresentChargingVoltage > _chargingData[index]->FireChargingVoltage + 300))
+		{
+			PRINTF_FUNC("[Module_InternalComm]CheckOutputPowerOverCarReq NG : fire = %f, battery = %f \n",
+					_chargingData[index]->FireChargingVoltage, _chargingData[index]->EvBatterytargetVoltage);
+			DEBUG_ERROR("[Module_InternalComm]CheckOutputPowerOverCarReq NG : fire = %f, battery = %f \n",
+					_chargingData[index]->FireChargingVoltage, _chargingData[index]->EvBatterytargetVoltage);
+			_chargingData[index]->StopChargeFlag = YES;
+		}
 	}
 }
 
@@ -1167,13 +1276,15 @@ int main(void)
 	//outputRelay.relay_event.bits.CCS_Precharge = 0x00;
 	//outputRelay.relay_event.bits.Gun1_Parallel_P = 0x01;
 	//outputRelay.relay_event.bits.Gun1_Parallel_N = 0x01;
+	//outputRelay.relay_event.bits.Gun1_P = 0x01;
 	//outputRelay.relay_event.bits.Gun1_N = 0x01;
 	//outputRelay.relay_event.bits.Gun2_N = 0x01;
 	//outputRelay.relay_event.bits.Gun2_P = 0x01;
-	Config_Relay_Output(Uart5Fd, Addr.Relay, &outputRelay);
+	if(Config_Relay_Output(Uart5Fd, Addr.Relay, &outputRelay) != PASS)
+		PRINTF_FUNC("Config_Relay_Output fail \n");
 
-	gettimeofday(&_priority_time, NULL);
 	bool printRelayStatus = false;
+	//return 0;
 	for(;;)
 	{
 		bool isCharging = false;
@@ -1181,14 +1292,17 @@ int main(void)
 		if (ShmRelayModuleData->SelfTest_Comp == NO)
 		{
 			GetFwAndHwVersion_Relay();
+			//SetRtcData_Relay();
 			sleep(1);
 		}
 
 		if (ShmFanModuleData->SelfTest_Comp == NO)
 		{
-			//GetFwAndHwVersion_Fan();
+			GetFwAndHwVersion_Fan();
 			SetModelName_Fan();
+			//SetRtcData_Fan();
 			sleep(1);
+			gettimeofday(&_priority_time, NULL);
 		}
 
 		if (ShmRelayModuleData->SelfTest_Comp == YES)
@@ -1226,6 +1340,8 @@ int main(void)
 
 					if (_chargingData[i]->SystemStatus == S_CHARGING)
 						CheckOutputPowerOverCarReq(i);
+
+					CheckOutputVolNoneMatchFire(i);
 				}
 				else
 					_chargingData[i]->IsReadyToCharging = NO;
@@ -1233,7 +1349,9 @@ int main(void)
 			// Cable check (Get)
 			GetGfdAdc();
 
-			SetParalleRelayStatus();
+			// 橋接 relay
+			if (gunCount > 1 && ONE_CONNECTOR_USE == NO)
+				SetParalleRelayStatus();
 
 			// 搭上 AC Contactor
 			if (isCharging)
@@ -1245,6 +1363,18 @@ int main(void)
 			// 放開 Relay 之前要先確認輸出的電壓電流是否已經降到某個值
 			if(IsNoneMatchRelayStatus())
 			{
+				if (!printRelayStatus)
+				{
+					PRINTF_FUNC("Match Relay Target, AC = %x, g1_p = %x, g1_n = %x, g2_p = %x, g2_n = %x, pre = %x, bri_p = %x, bri_n = %x \n",
+							outputRelay.relay_event.bits.AC_Contactor,
+							outputRelay.relay_event.bits.Gun1_P,
+							outputRelay.relay_event.bits.Gun1_N,
+							outputRelay.relay_event.bits.Gun2_P,
+							outputRelay.relay_event.bits.Gun2_N,
+							outputRelay.relay_event.bits.CCS_Precharge,
+							outputRelay.relay_event.bits.Gun1_Parallel_P,
+							outputRelay.relay_event.bits.Gun1_Parallel_N);
+				}
 				printRelayStatus = false;
 				if (Config_Relay_Output(Uart5Fd, Addr.Relay, &outputRelay))
 				{}
@@ -1253,7 +1383,7 @@ int main(void)
 			{
 				if (!printRelayStatus)
 				{
-					printf("Match Relay, AC = %x, g1_p = %x, g1_n = %x, g2_p = %x, g2_n = %x, pre = %x, bri_p = %x, bri_n = %x \n",
+					PRINTF_FUNC("Match Relay, AC = %x, g1_p = %x, g1_n = %x, g2_p = %x, g2_n = %x, pre = %x, bri_p = %x, bri_n = %x \n",
 							regRelay.relay_event.bits.AC_Contactor,
 							regRelay.relay_event.bits.Gun1_P,
 							regRelay.relay_event.bits.Gun1_N,
@@ -1269,10 +1399,9 @@ int main(void)
 
 		if (ShmFanModuleData->SelfTest_Comp == YES)
 		{
-			//GetFanSpeed();
-
 			if (GetTimeoutValue(_priority_time) / 1000 >= 1000)
 			{
+				GetFanSpeed();
 				gettimeofday(&_priority_time, NULL);
 				if (isCharging)
 				{
@@ -1300,7 +1429,16 @@ int main(void)
 						ShmFanModuleData->SetFan4Speed = MIN_FAN_SPEED;
 					}
 				}
-				//SetFanModuleSpeed();
+
+				if (ShmFanModuleData->TestFanSpeed > 0)
+				{
+					ShmFanModuleData->SetFan1Speed = ShmFanModuleData->TestFanSpeed;
+					ShmFanModuleData->SetFan2Speed = ShmFanModuleData->TestFanSpeed;
+					ShmFanModuleData->SetFan3Speed = ShmFanModuleData->TestFanSpeed;
+					ShmFanModuleData->SetFan4Speed = ShmFanModuleData->TestFanSpeed;
+				}
+				//PRINTF_FUNC("set fan = %d \n", ShmFanModuleData->SetFan1Speed);
+				SetFanModuleSpeed();
 			}
 		}
 

+ 1 - 1
EVSE/Projects/DS60-120/Apps/Module_LcmContro.h

@@ -29,7 +29,6 @@
 #include 	<stdbool.h>
 #include	"../../define.h"
 
-#define Debug
 #define ARRAY_SIZE(A)		(sizeof(A) / sizeof(A[0]))
 #define PASS				1
 #define FAIL				-1
@@ -73,6 +72,7 @@ short __wifi_status = 0x003C;
 
 short __sel_gun_btn = 0x0040;
 short __ret_home_btn = 0x0042;
+short __stop_method_btn = 0x0044;
 
 short __qr_code = 0x0050;
 

+ 45 - 18
EVSE/Projects/DS60-120/Apps/Module_LcmControl.c

@@ -1,5 +1,7 @@
 #include "Module_LcmContro.h"
 
+void PRINTF_FUNC(char *string, ...);
+
 int StoreLogMsg(const char *fmt, ...);
 #define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
 #define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
@@ -47,6 +49,20 @@ char* getTimeString(void)
 	return result;
 }
 
+void PRINTF_FUNC(char *string, ...)
+{
+	if (DEBUG)
+	{
+		va_list args;
+		char buffer[4096];
+
+		va_start(args, string);
+		vsnprintf(buffer, sizeof(buffer), string, args);
+		va_end(args);
+		printf("%s \n", buffer);
+	}
+}
+
 //==========================================
 // Init all share memory
 //==========================================
@@ -133,7 +149,7 @@ void WriteCmdToLcm(byte *cmd, byte cmdLen)
 	int len = write(_port, cmd, cmdLen);
 	if(len >= sizeof(cmd))
 	{
-		//printf("Write cmd to LCM successfully. \n");
+		//PRINTF_FUNC("Write cmd to LCM successfully. \n");
 	}
 }
 
@@ -170,7 +186,7 @@ void ReadMsgFromLcm(byte *msg, byte readLen)
 	}
 
 //	for (byte idx = 0; idx < len; idx++)
-//		printf("[system_command]-RX: %X\n", *(msg + idx));
+//		PRINTF_FUNC("[system_command]-RX: %X\n", *(msg + idx));
 }
 
 //================================================
@@ -305,10 +321,10 @@ void ChangeWarningFunc()
 {
 	byte cmd[7];
 	byte i = 0;
-	//printf("ChangeWarningFunc \n");
+	//PRINTF_FUNC("ChangeWarningFunc \n");
 	// 最多一次五筆
-	//printf("LCM PageIndex = %d \n", ShmSysConfigAndInfo->SysWarningInfo.PageIndex);
-	//printf("WarningCount = %d \n", ShmSysConfigAndInfo->SysWarningInfo.WarningCount);
+	//PRINTF_FUNC("LCM PageIndex = %d \n", ShmSysConfigAndInfo->SysWarningInfo.PageIndex);
+	//PRINTF_FUNC("WarningCount = %d \n", ShmSysConfigAndInfo->SysWarningInfo.WarningCount);
 	for(i = 0; (i + ShmSysConfigAndInfo->SysWarningInfo.PageIndex * 5) < ShmSysConfigAndInfo->SysWarningInfo.WarningCount; i++)
 	{
 		memset(cmd, 0x00, sizeof(cmd));
@@ -375,7 +391,7 @@ void ChangeQrCode_Charge(char *input)
 //================================================
 void ChangeCurPage()
 {
-	//printf("cur = %d, new = %d \n", _currentPage, ShmSysConfigAndInfo->SysInfo.PageIndex);
+	//PRINTF_FUNC("cur = %d, new = %d \n", _currentPage, ShmSysConfigAndInfo->SysInfo.PageIndex);
 	if (_currentPage != ShmSysConfigAndInfo->SysInfo.PageIndex)
 	{
 		_currentPage = ShmSysConfigAndInfo->SysInfo.PageIndex;
@@ -536,6 +552,11 @@ void ChangeChargingPowerValue(float pow)
 	DisplayValueToLcm(__output_eng_tx, cmd, sizeof(cmd));
 }
 
+void ChangeStopMap(byte value)
+{
+
+}
+
 void RefreshPageAnimation(byte value)
 {
 	switch(_currentPage)
@@ -602,9 +623,9 @@ void RefreshPageAnimation(byte value)
 					}
 				}
 
+				ChangeDisplay2Value(__sel_gun_btn, _sel_gun_btn);
 				if (_chargingInfoData[index]->SystemStatus == S_IDLE)
 				{
-					ChangeDisplay2Value(__sel_gun_btn, _disappear);
 					if(value == 0)
 					{
 						ChangeDisplay2Value(__side_top, _side_rfid_1);
@@ -623,7 +644,6 @@ void RefreshPageAnimation(byte value)
 				}
 				else
 				{
-					ChangeDisplay2Value(__sel_gun_btn, _sel_gun_btn);
 					ChangeDisplay2Value(__side_top, _disappear);
 					ChangeDisplay2Value(__side_down, _disappear);
 					ChangeDisplay2Value(__qr_code_pre, _disappear);
@@ -685,7 +705,10 @@ void RefreshConnStatus()
 	}
 
 	// 連線到後台
-
+	if (ShmSysConfigAndInfo->SysInfo.OcppConnStatus == 0x01)
+		ChangeDisplay2Value(__conn_status, _connect);
+	else
+		ChangeDisplay2Value(__conn_status, _disconnect);
 }
 
 void ProcessPageInfo()
@@ -719,7 +742,7 @@ void ProcessPageInfo()
 						}
 					}
 						break;
-					case _Type_CCS:
+					case _Type_CCS_2:
 					{
 						if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == i)
 						{
@@ -738,9 +761,14 @@ void ProcessPageInfo()
 					if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == i)
 					{
 						ChangeBattMapAndValue(_LCM_CHARGING, _chargingInfoData[i]->EvBatterySoc);
-						if (_chargingInfoData[i]->RemainChargingDuration < 0)
+						if (_chargingInfoData[i]->RemainChargingDuration > 0)
 							ChangeRemainTime(_chargingInfoData[i]->RemainChargingDuration);
 						ChangeChargingPowerValue(_chargingInfoData[i]->PresentChargingPower);
+
+						if (strcmp((char *)_chargingInfoData[i]->StartUserId, "") == 0)
+							ChangeDisplay2Value(__stop_method_btn, _stop_charging_btn);
+						else
+							ChangeDisplay2Value(__stop_method_btn, _stop_charging_btn_scan);
 					}
 				}
 				else if (_currentPage == _LCM_COMPLETE)
@@ -748,7 +776,7 @@ void ProcessPageInfo()
 					if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == i)
 					{
 						ChangeBattMapAndValue(_LCM_COMPLETE, _chargingInfoData[i]->EvBatterySoc);
-						if (_chargingInfoData[i]->RemainChargingDuration < 0)
+						if (_chargingInfoData[i]->RemainChargingDuration > 0)
 							ChangeRemainTime(_chargingInfoData[i]->RemainChargingDuration);
 						ChangeChargingPowerValue(_chargingInfoData[i]->PresentChargingPower);
 					}
@@ -767,15 +795,12 @@ void ProcessPageInfo()
 					}
 				}
 
-				if (_chargingInfoData[index]->SystemStatus == S_IDLE || _chargingInfoData[index]->SystemStatus == S_BOOTING)
+				if (_chargingInfoData[index]->SystemStatus == S_IDLE ||
+						_chargingInfoData[index]->SystemStatus == S_BOOTING)
 				{
 					// QR Code 處理
 					ChangeQrCode_Charge("http://google.com.tw");
 				}
-				else
-				{
-					ChangeDisplay2Value(__sel_gun_btn, _disappear);
-				}
 			}
 		}
 			break;
@@ -804,7 +829,7 @@ void Initialization()
 	}
 
 	if (count == 0)
-		printf("LCM Initialization Gun Fail.............\n");
+		PRINTF_FUNC("LCM Initialization Gun Fail.............\n");
 }
 
 int main(void)
@@ -828,6 +853,8 @@ int main(void)
 	//ChangeBackLight(true);
 	Initialization();
 
+//	ChangeToOtherPage(_LCM_FIX);
+//	return 0;
 	while(_port != -1)
 	{
 		//DemoFunction();

+ 65 - 11
EVSE/Projects/DS60-120/Apps/Module_PrimaryComm.c

@@ -31,7 +31,6 @@
 #include	"PrimaryComm.h"
 #include 	<stdbool.h>
 
-#define Debug
 #define ARRAY_SIZE(A)		(sizeof(A) / sizeof(A[0]))
 #define PASS				1
 #define FAIL				-1
@@ -53,6 +52,9 @@ int Uart1Fd;
 char *priPortName = "/dev/ttyS1";
 Ver ver;
 Gpio_in gpio_in;
+Rtc rtc;
+
+void PRINTF_FUNC(char *string, ...);
 
 int StoreLogMsg(const char *fmt, ...);
 #define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
@@ -93,6 +95,19 @@ int DiffTimeb(struct timeb ST, struct timeb ET)
 	return (StopTime-StartTime)*1000+ET.millitm-ST.millitm;
 }
 
+void PRINTF_FUNC(char *string, ...)
+{
+	if (DEBUG)
+	{
+		va_list args;
+		char buffer[4096];
+
+		va_start(args, string);
+		vsnprintf(buffer, sizeof(buffer), string, args);
+		va_end(args);
+		printf("%s \n", buffer);
+	}
+}
 //=================================
 // Common routine
 //=================================
@@ -226,17 +241,18 @@ void GetFwAndHwVersion()
 {
 	if(Query_FW_Ver(Uart1Fd, Addr.IoExtend, &ver) == PASS)
 	{
-		printf("s1 = %s \n", ver.Version_FW);
+		PRINTF_FUNC("s1 = %s \n", ver.Version_FW);
 		strcpy((char *)ShmPrimaryMcuData->version, ver.Version_FW);
+		strcpy((char *) ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev, ver.Version_FW);
 	}
 
 	if (Query_HW_Ver(Uart1Fd, Addr.IoExtend, &ver) == PASS)
-		printf("s2 = %s \n", ver.Version_HW);
+		PRINTF_FUNC("s2 = %s \n", ver.Version_HW);
 }
 
 void GetInputGpioStatus()
 {
-	//printf("GetInputGpioStatus \n");
+	//PRINTF_FUNC("GetInputGpioStatus \n");
 	if (Query_Gpio_Input(Uart1Fd, Addr.IoExtend, &gpio_in) == PASS)
 	{
 		ShmSysConfigAndInfo->SysInfo.AcContactorStatus = ShmPrimaryMcuData->InputDet.bits.AcContactorDetec = gpio_in.AC_Connector;
@@ -248,9 +264,9 @@ void GetInputGpioStatus()
 		ShmPrimaryMcuData->InputDet.bits.Button2 = gpio_in.Button[1];
 		ShmPrimaryMcuData->InputDet.bits.EmergencyButton = gpio_in.Emergency_Btn;
 
-		//printf("left = %d \n", ShmPrimaryMcuData->InputDet.bits.Button1);
-		//printf("right = %d \n", ShmPrimaryMcuData->InputDet.bits.Button2);
-		//printf("ShmSysConfigAndInfo->SysInfo.AcContactorStatus = %d \n", ShmSysConfigAndInfo->SysInfo.AcContactorStatus);
+		//PRINTF_FUNC("left = %d \n", ShmPrimaryMcuData->InputDet.bits.Button1);
+		//PRINTF_FUNC("right = %d \n", ShmPrimaryMcuData->InputDet.bits.Button2);
+		//PRINTF_FUNC("ShmSysConfigAndInfo->SysInfo.AcContactorStatus = %d \n", ShmSysConfigAndInfo->SysInfo.AcContactorStatus);
 		if (ShmPrimaryMcuData->InputDet.bits.AcMainBreakerDetec == YES)
 			DEBUG_ERROR("AC Mainbreaker occur. \n");
 	}
@@ -271,9 +287,46 @@ void SetOutputGpio()
 	gpio.AC_Breaker = 0x00;
 
 	if (Config_Gpio_Output(Uart1Fd, Addr.IoExtend, &gpio) == PASS)
-		printf("SetOutputGpio sucessfully. \n");
+		PRINTF_FUNC("SetOutputGpio sucessfully. \n");
+	else
+		PRINTF_FUNC("SetOutputGpio fail. \n");
+}
+
+void SetRtcData()
+{
+	struct timeb csuTime;
+	struct tm *tmCSU;
+
+	ftime(&csuTime);
+	tmCSU = localtime(&csuTime.time);
+//	PRINTF_FUNC("Time : %04d-%02d-%02d %02d:%02d:%02d \n", tmCSU->tm_year + 1900,
+//			tmCSU->tm_mon + 1, tmCSU->tm_mday, tmCSU->tm_hour, tmCSU->tm_min,
+//			tmCSU->tm_sec);
+
+	rtc.RtcData[0] = '0' + (tmCSU->tm_year + 1900) / 1000 % 10;
+	rtc.RtcData[1] = '0' + (tmCSU->tm_year + 1900) / 100 % 10;
+	rtc.RtcData[2] = '0' + (tmCSU->tm_year + 1900) / 10 % 10;
+	rtc.RtcData[3] = '0' + (tmCSU->tm_year + 1900) / 1 % 10;
+
+	rtc.RtcData[4] = '0' + (tmCSU->tm_mon + 1) / 10 % 10;
+	rtc.RtcData[5] = '0' + (tmCSU->tm_mon + 1) / 1 % 10;
+
+	rtc.RtcData[6] = '0' + (tmCSU->tm_mday) / 10 % 10;
+	rtc.RtcData[7] = '0' + (tmCSU->tm_mday) / 1 % 10;
+
+	rtc.RtcData[8] = '0' + (tmCSU->tm_hour) / 10 % 10;
+	rtc.RtcData[9] = '0' + (tmCSU->tm_hour) / 1 % 10;
+
+	rtc.RtcData[10] = '0' + (tmCSU->tm_min) / 10 % 10;
+	rtc.RtcData[11] = '0' + (tmCSU->tm_min) / 1 % 10;
+
+	rtc.RtcData[12] = '0' + (tmCSU->tm_sec) / 10 % 10;
+	rtc.RtcData[13] = '0' + (tmCSU->tm_sec) / 1 % 10;
+
+	if (Config_Rtc_Data(Uart1Fd, Addr.IoExtend, &rtc) == PASS)
+		PRINTF_FUNC("SetRtc sucessfully. \n");
 	else
-		printf("SetOutputGpio fail. \n");
+		PRINTF_FUNC("SetRtc fail. \n");
 }
 
 //================================================
@@ -321,7 +374,7 @@ int main(void)
 		return 0;
 	}
 	Uart1Fd = InitComPort();
-	printf("407 Port id = %d \n", Uart1Fd);
+	PRINTF_FUNC("407 Port id = %d \n", Uart1Fd);
 
 	if(Uart1Fd < 0)
 	{
@@ -338,13 +391,14 @@ int main(void)
 	}
 
 	SetOutputGpio();
+	SetRtcData();
 	for(;;)
 	{
 		// 程序開始之前~ 必須先確定 FW 版本與硬體版本,確認後!!~ 該模組才算是真正的 Initial Comp.
 		// 模組更新 FW 後,需重新做
 		if(ShmPrimaryMcuData->SelfTest_Comp != PASS)
 		{
-			printf("(407) Get Fw and Hw Ver. \n");
+			PRINTF_FUNC("(407) Get Fw and Hw Ver. \n");
 			GetFwAndHwVersion();
 			usleep(1000000);
 			ShmPrimaryMcuData->SelfTest_Comp = PASS;

+ 1239 - 1225
EVSE/Projects/DS60-120/Apps/Module_PsuComm.c

@@ -1,1225 +1,1239 @@
-
-#include 	"Module_PsuComm.h"
-
-#define Debug
-#define ARRAY_SIZE(A)		(sizeof(A) / sizeof(A[0]))
-#define PASS				1
-#define FAIL				-1
-#define YES					1
-#define NO					0
-#define DERATING			10
-
-#define SELF_TEST			0
-
-float maxChargingVol = 5000;			// 限制最大充電電壓,如依照模塊則填上 0
-
-struct SysConfigAndInfo			*ShmSysConfigAndInfo;
-struct StatusCodeData 			*ShmStatusCodeData;
-struct PsuData 					*ShmPsuData;
-
-void trim(char *s);
-int mystrcmp(char *p1,char *p2);
-void substr(char *dest, const char* src, unsigned int start, unsigned int cnt);
-void split(char **arr, char *str, const char *del);
-
-bool libInitialize = false;
-byte getAvailableCapOffset = 5;
-byte deratingKeepCount = 0;
-
-float carReqVol = 0;
-float carReqCur = 0;
-float evseOutVol = 0;
-float evseOutCur = 0;
-
-int cmdDelayTime = 60000;
-
-int StoreLogMsg(const char *fmt, ...);
-unsigned long GetTimeoutValue(struct timeval _sour_time);
-#define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
-#define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
-#define DEBUG_ERROR(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
-
-unsigned long GetTimeoutValue(struct timeval _sour_time)
-{
-	struct timeval _end_time;
-	gettimeofday(&_end_time, NULL);
-
-	return 1000000 * (_end_time.tv_sec - _sour_time.tv_sec) + _end_time.tv_usec - _sour_time.tv_usec;
-}
-
-int StoreLogMsg(const char *fmt, ...)
-{
-	char Buf[4096+256];
-	char buffer[4096];
-	time_t CurrentTime;
-	struct tm *tm;
-	va_list args;
-
-	va_start(args, fmt);
-	int rc = vsnprintf(buffer, sizeof(buffer), fmt, args);
-	va_end(args);
-
-	memset(Buf,0,sizeof(Buf));
-	CurrentTime = time(NULL);
-	tm=localtime(&CurrentTime);
-	sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog",
-			tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,
-			buffer,
-			tm->tm_year+1900,tm->tm_mon+1);
-	system(Buf);
-
-	return rc;
-}
-
-int DiffTimeb(struct timeb ST, struct timeb ET)
-{
-	//return milli-second
-	unsigned int StartTime,StopTime;
-
-	StartTime=(unsigned int)ST.time;
-	StopTime=(unsigned int)ET.time;
-	return (StopTime-StartTime)*1000+ET.millitm-ST.millitm;
-}
-
-//=================================
-// Common routine
-//=================================
-char* getTimeString(void)
-{
-	char *result=malloc(21);
-	time_t timep;
-	struct tm *p;
-	time(&timep);
-	p=gmtime(&timep);
-
-	sprintf(result, "[%04d-%02d-%02d %02d:%02d:%02d]", (1900+p->tm_year), (1+p->tm_mon), p->tm_mday, p->tm_hour, p->tm_hour, p->tm_sec);
-
-	return result;
-}
-
-void trim(char *s)
-{
-    int i=0, j, k, l=0;
-
-    while((s[i]==' ')||(s[i]=='\t')||(s[i]=='\n'))
-        i++;
-
-    j = strlen(s)-1;
-    while((s[j]==' ')||(s[j]=='\t')||(s[j]=='\n'))
-        j--;
-
-    if(i==0 && j==strlen(s)-1) { }
-    else if(i==0) s[j+1] = '\0';
-    else {
-        for(k=i; k<=j; k++) s[l++] = s[k];
-        s[l] = '\0';
-    }
-}
-
-int mystrcmp(char *p1,char *p2)
-{
-    while(*p1==*p2)
-    {
-        if(*p1=='\0' || *p2=='\0')
-            break;
-        p1++;
-        p2++;
-    }
-    if(*p1=='\0' && *p2=='\0')
-        return(PASS);
-    else
-        return(FAIL);
-}
-
-void substr(char *dest, const char* src, unsigned int start, unsigned int cnt)
-{
-	strncpy(dest, src + start, cnt);
-	dest[cnt] = 0;
-}
-
-void split(char **arr, char *str, const char *del)
-{
-	char *s = strtok(str, del);
-
-	while(s != NULL)
-	{
-		*arr++ = s;
-		s = strtok(NULL, del);
-	}
-}
-
-//=================================
-// Alarm code mapping to share memory Function
-//=================================
-void AbnormalStopAnalysis(byte gun_index, byte *errCode)
-{
-	char string[7];
-	sprintf(string, "%d%d%d%d%d%d", *(errCode + 5), *(errCode + 4), *(errCode + 3), *(errCode + 2), *(errCode + 1), *(errCode + 0));
-
-//	if (gun_index < _gunCount)
-//	{
-//		if (strlen((char *)ShmSysConfigAndInfo->SysStopChargingAlarmCode.StopCode[gun_index]) <= 0)
-//		{
-//			memcpy(&ShmSysConfigAndInfo->SysStopChargingAlarmCode.StopCode[gun_index][0], string, 7);
-//			ShmSysConfigAndInfo->SysStopChargingAlarmCode.Level = 0x00;
-//		}
-//	}
-	printf("PSU Alarm code = %s \n", errCode);
-}
-//=================================
-// ReAssigned PSU Function
-//=================================
-void ReAssignedResource()
-{
-	int index = 0;
-	struct PsuModuleData PsuModule[ShmPsuData->SystemPresentPsuQuantity];
-
-	for (byte i = 0; i < 4; i++)
-	{
-		for(byte psuCount = 0; psuCount < ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity; psuCount++)
-		{
-			memcpy(&PsuModule[index], &ShmPsuData->PsuGroup[i].PsuModule[psuCount], sizeof(struct PsuModuleData));
-			index++;
-		}
-		ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity = 0;
-	}
-
-	for(int i = 0; i < ShmPsuData->SystemPresentPsuQuantity; i++)
-	{
-		byte group = PsuModule[i].FireWireIndex;
-
-		memcpy(&ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity],
-				&PsuModule[i], sizeof(struct PsuModuleData));
-
-		printf("ReAssignedResource : PhysicalID = %d, Address = %d, group = %d \n",
-				ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].PhysicalID,
-				ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].Address,
-				group);
-
-		PsuAddressAssignment(ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].PhysicalID,
-				(char *)ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].SerialNumber,
-				ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].Address,
-				group);
-		ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity++;
-	}
-}
-
-//=================================
-// Save data to share memory Function
-//=================================
-bool FindChargingInfoData(byte target, struct ChargingInfoData **chargingData)
-{
-	for (byte index = 0; index < CHAdeMO_QUANTITY; index++)
-	{
-		if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == target)
-		{
-			chargingData[target] = &ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index];
-			return true;
-		}
-	}
-
-	for (byte index = 0; index < CCS_QUANTITY; index++)
-	{
-		if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == target)
-		{
-			chargingData[target] = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[index];
-			return true;
-		}
-	}
-
-	for (byte index = 0; index < GB_QUANTITY; index++)
-	{
-		if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == target)
-		{
-			chargingData[target] = &ShmSysConfigAndInfo->SysInfo.GbChargingData[index];
-			return true;
-		}
-	}
-
-	return false;
-}
-
-void GetPsuRequestCallback(byte phy_id, char *serial_number)
-{
-	if (ShmSysConfigAndInfo->SysInfo.AcContactorStatus == NO)
-		return;
-
-	// ********************** 每次送電後,需判斷要把所有的模塊分配到哪個 Group **********************
-	byte group = 0;
-	if(ShmSysConfigAndInfo->SysInfo.BootingStatus == BOOTTING || _gunCount == 1)
-	{
-		// 初始化狀態,則直接先分配到同個群
-		group = 0;
-	}
-	else
-	{
-		group = ShmSysConfigAndInfo->SysInfo.CurGunSelected;
-	}
-
-	bool isNewPsu = true;
-
-	for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
-	{
-		if (ShmPsuData->PsuGroup[group].PsuModule[index].PhysicalID == phy_id &&
-			strncmp((char *)ShmPsuData->PsuGroup[group].PsuModule[index].SerialNumber, serial_number, 7) == 0)
-		{
-			isNewPsu = false;
-		}
-	}
-
-	if (isNewPsu)
-	{
-		ShmPsuData->SystemPresentPsuQuantity++;
-		printf("get psu********id = %d, group = %d \n", ShmPsuData->SystemPresentPsuQuantity, group);
-
-		if (ShmPsuData->Work_Step >= _TEST_LINE_STEP && ShmPsuData->Work_Step <= _TEST_COMPLETE)
-		{
-			// 已經進入火線上的驗證動作
-			ShmPsuData->NeedBackTest = YES;
-		}
-		else if (ShmPsuData->Work_Step == _WORK_CHARGING)
-		{
-			// 一旦進入火線,分配一個不會用到的給該模塊
-			group = 0x03;
-		}
-
-		ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].Address = ShmPsuData->SystemPresentPsuQuantity;
-		ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].PhysicalID = phy_id;
-		ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].AssignID = (group >> 6) + ShmPsuData->SystemPresentPsuQuantity;
-		strcpy((char *)ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].SerialNumber, serial_number);
-
-		byte isFind = false;
-		for (byte index = 0; index < conn_1_count; index++)
-		{
-			printf("connector_1[%d] = %d, phy_id = %d \n", index, connector_1[index], phy_id);
-			if (connector_1[index] == phy_id)
-			{
-				isFind = true;
-				ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].FireWireIndex = 0;
-				break;
-			}
-		}
-
-		if (!isFind)
-		{
-			for (byte index = 0; index < conn_2_count; index++)
-			{
-				printf("connector_2[%d] = %d, phy_id = %d \n", index, connector_2[index], phy_id);
-				if (connector_2[index] == phy_id)
-				{
-					isFind = true;
-					ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].FireWireIndex = 1;
-					break;
-				}
-			}
-		}
-
-		ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity++;
-		PsuAddressAssignment(phy_id, serial_number, ShmPsuData->SystemPresentPsuQuantity, group);
-		ShmPsuData->GroupCount = CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY;
-	}
-}
-
-void SaveStatusCallback(byte group, byte address, int alarm, int fault)
-{
-	//EVSE
-	for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
-	{
-		if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
-		{
-			ShmPsuData->PsuGroup[group].PsuModule[index].AlarmCode = alarm;
-			ShmPsuData->PsuGroup[group].PsuModule[index].FaultCode = fault;
-			//printf("index = %d, alarm = %d, fault = %d \n", index, alarm, fault);
-			break;
-		}
-	}
-}
-
-void SaveAlarmNotifyCallback(byte group, byte address, unsigned char *alarm)
-{
-	//EVSE
-	for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
-	{
-		if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
-		{
-			AbnormalStopAnalysis(group, alarm);
-			break;
-		}
-	}
-}
-
-void SaveFaultNotifyCallback(byte group, byte address, int fault)
-{
-	//EVSE
-	for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
-	{
-		if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
-		{
-			ShmPsuData->PsuGroup[group].PsuModule[index].FaultCode = fault;
-			break;
-		}
-	}
-}
-
-void SaveFirmwareVersion(byte group, byte address, unsigned char packageIndex, unsigned char type , unsigned char *data)
-{
-	for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
-	{
-		if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
-		{
-			if (packageIndex == 0 || packageIndex == 1)
-				strncpy((char *)ShmPsuData->PsuGroup[group].PsuModule[index].FwVersion + (packageIndex * 6), (char *)data, 6);
-			else
-				strncpy((char *)ShmPsuData->PsuGroup[group].PsuModule[index].FwVersion + (packageIndex * 6), (char *)data, 4);
-		}
-	}
-
-	if (packageIndex == 1)
-	{
-		char string[3];
-
-		memcpy(string, (data + 2), 2);
-		string[2] = '\0';
-
-		for (byte i = 0; i < _gunCount; i++)
-		{
-			if (maxChargingVol != 0)
-			{
-				chargingInfo[i]->MaximumChargingVoltage = maxChargingVol;
-			}
-			else
-			{
-				if (strcmp(string, "50") == 0)
-					chargingInfo[i]->MaximumChargingVoltage = 5000;
-				else if (strcmp(string, "70") == 0)
-					chargingInfo[i]->MaximumChargingVoltage = 7000;
-				else if (strcmp(string, "75") == 0)
-					chargingInfo[i]->MaximumChargingVoltage = 7500;
-				else if (strcmp(string, "80") == 0)
-					chargingInfo[i]->MaximumChargingVoltage = 8000;
-				else if (strcmp(string, "95") == 0)
-					chargingInfo[i]->MaximumChargingVoltage = 9500;
-				else if (strcmp(string, "A0") == 0)
-					chargingInfo[i]->MaximumChargingVoltage = 10000;
-				else if (strcmp(string, "C0") == 0)
-					chargingInfo[i]->MaximumChargingVoltage = 12000;
-				else if (strcmp(string, "F0") == 0)
-					chargingInfo[i]->MaximumChargingVoltage = 15000;
-			}
-			printf("index = %d, max vol = %f \n", i, chargingInfo[i]->MaximumChargingVoltage);
-		}
-	}
-}
-
-void SaveFanSpeedCallback(byte group, byte address, byte fan1, byte fan2, byte fan3, byte fan4)
-{
-	//EVSE
-	for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
-	{
-		if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
-		{
-			ShmPsuData->PsuGroup[group].PsuModule[index].FanSpeed_1 = fan1;
-			ShmPsuData->PsuGroup[group].PsuModule[index].FanSpeed_2 = fan2;
-			ShmPsuData->PsuGroup[group].PsuModule[index].FanSpeed_3 = fan3;
-			ShmPsuData->PsuGroup[group].PsuModule[index].FanSpeed_4 = fan4;
-			break;
-		}
-	}
-}
-
-void SaveTemperatureCallback(byte group, byte address, char cri_temp1, char cri_temp2, char cri_temp3, char ex_temp, char in_temp1, char in_temp2, char out_temp)
-{
-	//EVSE
-	for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
-	{
-		if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
-		{
-			ShmPsuData->PsuGroup[group].PsuModule[index].CriticalTemp1 = cri_temp1;
-			ShmPsuData->PsuGroup[group].PsuModule[index].CriticalTemp2 = cri_temp2;
-			ShmPsuData->PsuGroup[group].PsuModule[index].CriticalTemp3 = cri_temp3;
-			ShmPsuData->PsuGroup[group].PsuModule[index].ExletTemp = ex_temp;
-			ShmPsuData->PsuGroup[group].PsuModule[index].InletTemp_1 = in_temp1;
-			ShmPsuData->PsuGroup[group].PsuModule[index].InletTemp_2 = in_temp2;
-			ShmPsuData->PsuGroup[group].PsuModule[index].OutletTemp = out_temp;
-			break;
-		}
-	}
-}
-
-void SavePresentInputVoltageCallback(byte group, byte address, byte vol_type, unsigned short vol1, unsigned short vol2, unsigned short vol3)
-{
-	//EVSE
-	for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
-	{
-		if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
-		{
-			ShmPsuData->PsuGroup[group].PsuModule[index].InputVoltage_Type = vol_type;
-			ShmPsuData->PsuGroup[group].PsuModule[index].InputVoltageL1 = vol1;
-			ShmPsuData->PsuGroup[group].PsuModule[index].InputVoltageL2 = vol2;
-			ShmPsuData->PsuGroup[group].PsuModule[index].InputVoltageL3 = vol3;
-			break;
-		}
-	}
-}
-
-// 模塊輸出的電壓電流
-void SavePresentOutputCallback(byte group, byte address, unsigned short out_vol, unsigned short out_cur)
-{
-	unsigned short outputVol = 0;
-	unsigned short outputCur = 0;
-	bool isChange = false;
-
-	// PSU
-	for (int index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
-	{
-		if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
-		{
-			ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputVoltage = out_vol;
-			ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputCurrent = out_cur;
-			isChange = true;
-		}
-
-		if (ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputVoltage > outputVol)
-			outputVol = ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputVoltage;
-
-		outputCur += ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputCurrent;
-	}
-
-	if (isChange)
-	{
-		// PSU Group
-		// 電壓
-		ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage = outputVol;
-		// 電流
-		ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent = outputCur;
-
-		//EVSE - 槍端的輸出電壓
-		chargingInfo[group]->PresentChargingVoltage = ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage;
-		//EVSE - 槍端的輸出電流
-		chargingInfo[group]->PresentChargingCurrent = ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent;
-	}
-
-	printf("group = %d, GroupPresentOutputVoltage = %d \n", group, ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage);
-	printf("group = %d, GroupPresentOutputCurrent = %d \n", group, ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent);
-}
-
-void SaveAvailableCapCallback(byte group, byte address, unsigned short able_power, unsigned short able_cur)
-{
-	unsigned int power = 0;
-	unsigned int current = 0;
-	unsigned int power_derating = 0;
-	unsigned int current_derating = 0;
-	bool isChange = false;
-
-	for (int index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
-	{
-		if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
-		{
-			ShmPsuData->PsuGroup[group].PsuModule[index].AvailablePower = able_power;
-			ShmPsuData->PsuGroup[group].PsuModule[index].AvailableCurrent =	able_cur;
-			isChange = true;
-		}
-
-		// 降載
-		if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_GET_NEW_CAP)
-		{
-			if (ShmPsuData->PsuGroup[group].PsuModule[index].FireWireIndex == group)
-			{
-				power_derating += ShmPsuData->PsuGroup[group].PsuModule[index].AvailablePower;
-				current_derating += ShmPsuData->PsuGroup[group].PsuModule[index].AvailableCurrent;
-			}
-		}
-
-		power += ShmPsuData->PsuGroup[group].PsuModule[index].AvailablePower;
-		current += ShmPsuData->PsuGroup[group].PsuModule[index].AvailableCurrent;
-	}
-
-	if (current_derating == 0)
-		current_derating = current;
-	if (power_derating == 0)
-		power_derating = power;
-
-	if (isChange)
-	{
-		// PSU Group
-		// Available Power
-		ShmPsuData->PsuGroup[group].GroupAvailablePower = power;
-		// Available Current
-		ShmPsuData->PsuGroup[group].GroupAvailableCurrent = current;
-
-		chargingInfo[group]->AvailableChargingCurrent =	ShmPsuData->PsuGroup[group].GroupAvailableCurrent;
-		chargingInfo[group]->AvailableChargingPower = ShmPsuData->PsuGroup[group].GroupAvailablePower;
-		chargingInfo[group]->DeratingChargingCurrent = current_derating;
-		chargingInfo[group]->DeratingChargingPower = power_derating;
-
-		printf("group = %d, AvailableChargingCurrent = %f, GroupAvailablePower = %f, DeratingChargingCurrent = %f, DeratingChargingPower = %f \n",
-					group, chargingInfo[group]->AvailableChargingCurrent, chargingInfo[group]->AvailableChargingPower,
-					chargingInfo[group]->DeratingChargingCurrent, chargingInfo[group]->DeratingChargingPower);
-	}
-}
-
-void SavePresentInputCurrentCallback(byte group, byte address, unsigned short in_cur1, unsigned short in_cur2, unsigned short in_cur3)
-{
-	//EVSE
-	for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
-	{
-		if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
-		{
-			ShmPsuData->PsuGroup[group].PsuModule[index].InputCurrentL1 = in_cur1;
-			ShmPsuData->PsuGroup[group].PsuModule[index].InputCurrentL2 = in_cur2;
-			ShmPsuData->PsuGroup[group].PsuModule[index].InputCurrentL3 = in_cur3;
-			break;
-		}
-	}
-}
-
-void SaveHardwareVersion(byte group, byte address, int hw_ver)
-{
-	//EVSE
-	for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
-	{
-		if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
-		{
-			ShmPsuData->PsuGroup[group].PsuModule[index].FwVersion[0] = (hw_ver >> 24) & 0xFF;
-			ShmPsuData->PsuGroup[group].PsuModule[index].FwVersion[1] = (hw_ver >> 16) & 0xFF;
-			ShmPsuData->PsuGroup[group].PsuModule[index].FwVersion[2] = (hw_ver >> 8) & 0xFF;
-			ShmPsuData->PsuGroup[group].PsuModule[index].FwVersion[3] = hw_ver & 0xFF;
-			break;
-		}
-	}
-}
-
-void SaveStatusNotifyCallback(byte group, byte address, byte st_machine, unsigned short out_vol, unsigned short out_cur)
-{
-	//EVSE
-	for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
-	{
-		if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
-		{
-			ShmPsuData->PsuGroup[group].PsuModule[index].StateMachine = st_machine;
-			//ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputVoltage = out_vol;
-			//ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputCurrent = out_cur;
-			//printf("psu state = %d, vol = %d, cur = %d \n", st_machine, out_vol, out_cur);
-			break;
-		}
-	}
-}
-
-void GetSerialNumberCallback(byte group, byte address, unsigned char packageIndex, unsigned char *data)
-{
-	for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
-	{
-		if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
-		{
-			strcpy((char *)ShmPsuData->PsuGroup[group].PsuModule[index].SerialNumber + (packageIndex * 7), (char *)data);
-			break;
-		}
-	}
-}
-
-void GetOutputPowerSwitchStatusCallback(byte group, byte address, unsigned char value)
-{
-	for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
-	{
-		if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
-		{
-			//printf("PowerSwitch = %d, group = %d, address = %d \n", value, group, address);
-			ShmPsuData->PsuGroup[group].PsuModule[index].OutputPowerSwitch = value;
-			break;
-		}
-	}
-}
-
-//==========================================
-// Init all share memory
-//==========================================
-int InitShareMemory()
-{
-	int result = PASS;
-	int MeterSMId;
-
-	//creat ShmSysConfigAndInfo
-	if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo),  0777)) < 0)
-    {
-		#ifdef SystemLogMessage
-		DEBUG_ERROR("shmget ShmSysConfigAndInfo NG %d \n");
-		#endif
-		result = FAIL;
-	}
-    else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
-    {
-    	#ifdef SystemLogMessage
-    	DEBUG_ERROR("shmat ShmSysConfigAndInfo NG \n");
-		#endif
-    	result = FAIL;
-   	 }
-    else
-    {}
-
-   	//creat ShmStatusCodeData
-   	if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData),  0777)) < 0)
-    {
-		#ifdef SystemLogMessage
-   		DEBUG_ERROR("shmget ShmStatusCodeData NG \n");
-		#endif
-   		result = FAIL;
-	}
-    else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
-    {
-    	#ifdef SystemLogMessage
-    	DEBUG_ERROR("shmat ShmStatusCodeData NG \n");
-		#endif
-    	result = FAIL;
-   	}
-    else
-    {}
-
-   	//creat ShmPsuData
-	if ((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData),  0777)) < 0)
-	{
-		#ifdef SystemLogMessage
-		DEBUG_ERROR("shmget ShmPsuData NG \n");
-		#endif
-		result = FAIL;
-	}
-	else if ((ShmPsuData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
-	{
-		#ifdef SystemLogMessage
-		DEBUG_ERROR("shmat ShmPsuData NG \n");
-		#endif
-		result = FAIL;
-	 }
-	memset(ShmPsuData,0,sizeof(struct PsuData));
-
-    return result;
-}
-
-//================================================
-// Main process
-//================================================
-void InitialPsuData()
-{
-	ShmPsuData->SystemPresentPsuQuantity = 0;
-
-	for (byte _groupCount = 0; _groupCount < ARRAY_SIZE(ShmPsuData->PsuGroup);	_groupCount++)
-	{
-		ShmPsuData->PsuGroup[_groupCount].GroupPresentPsuQuantity = 0;
-		ShmPsuData->PsuGroup[_groupCount].GroupAvailablePower = 0;
-		ShmPsuData->PsuGroup[_groupCount].GroupAvailableCurrent = 0;
-	}
-}
-
-void Initialization()
-{
-	bool isPass = false;
-	while(!isPass)
-	{
-		isPass = true;
-		for (byte _index = 0; _index < _gunCount; _index++)
-		{
-			if (!FindChargingInfoData(_index, &chargingInfo[0]))
-			{
-				DEBUG_ERROR("EvComm (main) : FindChargingInfoData false \n");
-				isPass = false;
-				break;
-			}
-		}
-	}
-	conn_1_count = sizeof(connector_1)/sizeof(connector_1[0]);
-	conn_2_count = sizeof(connector_2)/sizeof(connector_2[0]);
-}
-
-int main(void)
-{
-	printf("Psu Task boot .... \n");
-	if(InitShareMemory() == FAIL)
-	{
-		#ifdef SystemLogMessage
-		DEBUG_ERROR("InitShareMemory NG\n");
-		#endif
-		if(ShmStatusCodeData != NULL)
-		{
-			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory = 1;
-		}
-		sleep(5);
-		return 0;
-	}
-
-	printf("InitShareMemory OK\n");
-
-	// register callback function
-	GetPsuAddressReq(&GetPsuRequestCallback);
-	RefreshStatus(&SaveStatusCallback);
-	RefreshFanSpeed(&SaveFanSpeedCallback);
-	RefreshTemp(&SaveTemperatureCallback);
-	RefreshInputVol(&SavePresentInputVoltageCallback);
-	RefreshGetOutput(&SavePresentOutputCallback);
-	RefreshAvailableCap(&SaveAvailableCapCallback);
-	RefreshInputCur(&SavePresentInputCurrentCallback);
-
-	RefreshAlarmNotify(&SaveAlarmNotifyCallback);
-	RefreshFaultNotify(&SaveFaultNotifyCallback);
-	RefreshStatusNotify(&SaveStatusNotifyCallback);
-
-	RefreshSerialNumber(&GetSerialNumberCallback);
-	RefreshOutputPowerSwitch(&GetOutputPowerSwitchStatusCallback);
-	RefreshFWVersion(&SaveFirmwareVersion);
-	//RefreshHWVersion(&SaveHardwareVersion);
-
-	// initial object
-	InitialPsuData();
-	Initialization();
-	libInitialize = InitialCommunication();
-
-	byte priorityLow = 1;
-	//main loop
-	while (libInitialize)
-	{
-		// 斷電狀態
-		if (ShmSysConfigAndInfo->SysInfo.AcContactorStatus == NO)
-		{
-			InitialPsuData();
-			sleep(1);
-			ShmPsuData->Work_Step = ASSIGN_START;
-			continue;
-		}
-
-		// update psu fw req
-//		if(psu update req ?)
-//		{
-//
-//			continue;
-//		}
-
-		// 自檢失敗
-		if (ShmPsuData->Work_Step == _NO_WORKING)
-		{
-			DEBUG_ERROR("(PSU) self test fail. \n");
-			printf("(PSU) self test fail. \n");
-			sleep(5);
-		}
-
-		switch(ShmPsuData->Work_Step)
-		{
-			case ASSIGN_START:
-			{
-				printf("PSU ASSIGN_START........ \n");
-				gettimeofday(&_id_assign_time, NULL);
-				ShmPsuData->Work_Step = ASSIGN_COMP;
-			}
-				break;
-			case ASSIGN_COMP:
-			{
-				if (priorityLow == 1)
-				{
-					byte targetGp = 0;
-					if (ShmSysConfigAndInfo->SysInfo.BootingStatus != BOOTTING)
-						targetGp = ShmSysConfigAndInfo->SysInfo.CurGunSelected;
-
-					for (byte psuIndex = 0;	psuIndex < ShmPsuData->PsuGroup[targetGp].GroupPresentPsuQuantity;	psuIndex++)
-					{
-						if (ShmPsuData->PsuGroup[targetGp].PsuModule[psuIndex].Address == NONE_CARE_ADDRESS)
-							continue;
-
-						GetStatus(targetGp, ShmPsuData->PsuGroup[targetGp].PsuModule[psuIndex].Address);
-						usleep(cmdDelayTime);
-						if (strlen((char *)ShmPsuData->PsuGroup[targetGp].PsuModule[psuIndex].FwVersion) == 0 &&
-							ShmPsuData->PsuGroup[targetGp].PsuModule[psuIndex].FwVersion[0] == '\0')
-						{
-							GetFwVersion(targetGp, ShmPsuData->PsuGroup[targetGp].PsuModule[psuIndex].Address, 0x02);
-							usleep(cmdDelayTime);
-						}
-
-						if (strlen((char *)ShmPsuData->PsuGroup[targetGp].PsuModule[psuIndex].SerialNumber) == 0 &&
-								ShmPsuData->PsuGroup[targetGp].PsuModule[psuIndex].SerialNumber[0] == '\0')
-						{
-							GetSerialNumber(targetGp, ShmPsuData->PsuGroup[targetGp].PsuModule[psuIndex].Address);
-							usleep(cmdDelayTime);
-						}
-					}
-				}
-
-				priorityLow >= 20 ? priorityLow = 1 : priorityLow++;
-				// 等待十秒
-				if (GetTimeoutValue(_id_assign_time) >= 15000000)
-				{
-					ShmPsuData->Work_Step = ENABLE_POW;
-				}
-			}
-				break;
-			case ENABLE_POW:
-			{
-				if (ShmSysConfigAndInfo->SysInfo.BootingStatus == BOOTTING)
-				{
-					// 電樁在 Booting 的狀態 - 自檢
-					ShmPsuData->Work_Step = _TEST_LINE_STEP;
-				}
-				else
-				{
-					ShmPsuData->Work_Step = _WORK_CHARGING;
-					gettimeofday(&_workModePriority_time, NULL);
-				}
-			}
-				break;
-			case _TEST_LINE_STEP:
-			{
-				printf("cur total psu count = %d \n", ShmPsuData->SystemPresentPsuQuantity);
-				if (ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity <= 0)
-				{
-					sleep(1);
-					continue;
-				}
-
-#if (SELF_TEST)
-				// 對整個 Group 保持通訊
-				bool isFind = false;
-				while(ShmPsuData->Work_Step != _NO_WORKING &&
-						_curCheckPsuIndexForFireLine < ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity)
-				{
-					GetStatus(0, NONE_CARE_ADDRESS);
-					usleep(cmdDelayTime);
-					GetAvailableCap(0, NONE_CARE_ADDRESS, getAvailableCapOffset);
-					usleep(cmdDelayTime);
-					EnableOutputPower(0, NONE_CARE_ADDRESS, OUTPUT_POWER_SWITCH_ON);
-					usleep(cmdDelayTime);
-
-					if (ShmPsuData->NeedBackTest == YES)
-					{
-						ShmPsuData->NeedBackTest = NO;
-						_curCheckPsuIndexForFireLine = 0x00;
-					}
-
-					if (isFind)
-					{
-						GetPresentOutput(0, ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].Address);
-						usleep(cmdDelayTime);
-						//printf("stop vor = %d \n", ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PresentOutputVoltage);
-						if (ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PresentOutputVoltage <= 200)
-						{
-							// 檢查下一個
-							_curCheckPsuIndexForFireLine++;
-							isFind = false;
-						}
-						SetPresentOutput(0, ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].Address,
-								ZERO_VOL, ZERO_CUR, chargingInfo[0]->AvailableChargingCurrent, 0x00);
-						usleep(cmdDelayTime);
-					}
-					else
-					{
-						printf("AvailableCurrent = %d \n", ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].AvailableCurrent);
-						if (ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].AvailableCurrent > 0)
-						{
-							if (ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PresentOutputVoltage == 0)
-							{
-								//printf("set output vol = %d, cur = %d \n", SELF_TEST_VOL, SELF_TEST_CUR);
-								SetPresentOutput(0, ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].Address,
-									SELF_TEST_VOL, SELF_TEST_CUR, chargingInfo[0]->AvailableChargingCurrent, 0x00);
-								usleep(cmdDelayTime);
-							}
-
-							if(!isCheckOutputTimeStart)
-							{
-								gettimeofday(&_chk_output_time, NULL);
-								isCheckOutputTimeStart = true;
-							}
-							else
-							{
-								// 如果五秒內火線上都沒有偵測到電壓,則代表異常
-								if (GetTimeoutValue(_chk_output_time) >= 10000000)
-								{
-									// 自檢失敗
-									printf("self test timeout \n");
-									EnableOutputPower(0, NONE_CARE_ADDRESS, OUTPUT_POWER_SWITCH_OFF);
-									usleep(cmdDelayTime);
-									ShmPsuData->Work_Step = _NO_WORKING;
-									continue;
-								}
-							}
-
-							for (byte gunIndex = 0; gunIndex < _gunCount; gunIndex ++)
-							{
-								GetPresentOutput(0, ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].Address);
-								usleep(cmdDelayTime);
-								printf("Cur psu output voltage = %d \n", ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PresentOutputVoltage);
-								printf("Fire voltage = %f \n", chargingInfo[gunIndex]->FuseChargingVoltage);
-								// 該模組的輸出電壓與火線上的電壓一致
-								if (chargingInfo[gunIndex]->FuseChargingVoltage >= 50 &&
-									((chargingInfo[gunIndex]->FuseChargingVoltage >= ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PresentOutputVoltage - 300) &&
-									(chargingInfo[gunIndex]->FuseChargingVoltage <= ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PresentOutputVoltage + 300)))
-								{
-									// 找到火線上的電壓了,這邊紀錄火線是紀錄屬於哪一把槍的火線
-									if (_curCheckPsuIndexForFireLine < ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity)
-									{
-										// 紀錄當前 PSU 是哪個火線上的
-										ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].FireWireIndex = gunIndex;
-
-										//recordPsuData[_curCheckPsuIndexForFireLine]._fire_index = gunIndex;
-										//recordPsuData[_curCheckPsuIndexForFireLine]._phy_addr = ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].PhysicalID;
-										//strcpy(recordPsuData[_curCheckPsuIndexForFireLine]._serial_num, (char *)ShmPsuData->PsuGroup[0].PsuModule[_curCheckPsuIndexForFireLine].SerialNumber);
-										printf("Find Fire Line Number end~~~~~~~~~~~~~~~ = %d \n", gunIndex);
-										usleep(100000);
-										isCheckOutputTimeStart = false;
-										isFind = true;
-										break;
-									}
-								}
-							}
-						}
-					}
-
-					usleep(100000);
-				}
-
-				if (ShmPsuData->Work_Step != _NO_WORKING)
-					ShmPsuData->Work_Step = _TEST_POWER_STEP;
-
-				EnableOutputPower(0, NONE_CARE_ADDRESS, OUTPUT_POWER_SWITCH_OFF);
-				usleep(cmdDelayTime);
-#else
-				ShmPsuData->Work_Step = _TEST_POWER_STEP;
-#endif
-			}
-				break;
-			case _TEST_POWER_STEP:
-			{
-				if(!_chkTotalCapStart)
-				{
-					_chkTotalCapStart = true;
-					gettimeofday(&_chk_cap_time, NULL);
-				}
-
-				for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
-				{
-					GetStatus(groupIndex, NONE_CARE_ADDRESS);
-					usleep(cmdDelayTime);
-					GetAvailableCap(groupIndex, NONE_CARE_ADDRESS, getAvailableCapOffset);
-					usleep(cmdDelayTime);
-				}
-
-				if (GetTimeoutValue(_chk_cap_time) >= 2000000)
-				{
-					printf("AvailableChargingCurrent = %f, AvailableChargingPower = %f \n",
-							chargingInfo[0]->AvailableChargingCurrent, chargingInfo[0]->AvailableChargingPower);
-					for (byte index = 0; index < ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity; index++)
-					{
-						printf("index = %d, fire index = %d, phy addr = %s \n",
-								index, ShmPsuData->PsuGroup[0].PsuModule[index].FireWireIndex, ShmPsuData->PsuGroup[0].PsuModule[index].SerialNumber);
-					}
-					ShmPsuData->Work_Step = _TEST_COMPLETE;
-				}
-			}
-				break;
-			case _TEST_COMPLETE:
-			{
-				priorityLow = 1;
-				sleep(1);
-			}
-				break;
-			case _WORK_CHARGING:
-			{
-				int time = GetTimeoutValue(_workModePriority_time) / 1000;
-				// 智能分配 : 檢查該槍是否有模塊有用,有則無須重新分配直接進入充電
-				if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_PREPARE)
-				{
-					if (ShmPsuData->PsuGroup[ShmSysConfigAndInfo->SysInfo.CurGunSelected].GroupPresentPsuQuantity > 0)
-					{
-						printf("=============Smart Charging : _REASSIGNED_NONE============= Step 0 \n");
-						ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE;
-					}
-					else
-					{
-						printf("=============Smart Charging : _REASSIGNED_GET_NEW_CAP============= Step 2 \n");
-						ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_GET_NEW_CAP;
-					}
-				}
-
-				//printf("cur total psu count = %d \n", ShmPsuData->SystemPresentPsuQuantity);
-				for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
-				{
-					// 每秒
-					if (time > 1000)
-					{
-						GetStatus(groupIndex, NONE_CARE_ADDRESS);
-						usleep(cmdDelayTime);
-						GetAvailableCap(groupIndex, NONE_CARE_ADDRESS, getAvailableCapOffset);
-						usleep(cmdDelayTime);
-
-						// 智能分配 : 檢查車端需求電流是否有降低至新的輸出值
-						if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_GET_NEW_CAP)
-						{
-							if (groupIndex != ShmSysConfigAndInfo->SysInfo.CurGunSelected)
-							{
-								if (chargingInfo[groupIndex]->SystemStatus >= S_CHARGING &&	chargingInfo[groupIndex]->SystemStatus <= S_COMPLETE)
-								{
-									if (chargingInfo[groupIndex]->DeratingChargingCurrent < chargingInfo[groupIndex]->AvailableChargingCurrent)
-									{
-										// 車端需求電流降低至降載的電流
-										printf("Smart Charging : index = %d, EvBatterytargetCurrent = %f, DeratingChargingCurrent = %f \n",
-											groupIndex, chargingInfo[groupIndex]->EvBatterytargetCurrent, chargingInfo[groupIndex]->DeratingChargingCurrent);
-
-										if ((chargingInfo[groupIndex]->EvBatterytargetCurrent <= chargingInfo[groupIndex]->DeratingChargingCurrent) ||
-											deratingKeepCount >= DERATING)
-										{
-											// 車端降載完成
-											printf("=============Smart Charging : _REASSIGNED_MAIN============= Step 3 \n");
-											ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_MAIN;
-										}
-										else
-										{
-											deratingKeepCount++;
-										}
-									}
-
-								}
-							}
-						}
-						else
-							deratingKeepCount = 0;
-
-						if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_MAIN)
-						{
-							printf("=============Smart Charging : _REASSIGNED_ADJUST============= Step 4 \n");
-							//重新分配模組
-							ReAssignedResource();
-							gettimeofday(&_derating_time, NULL);
-							ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_ADJUST;
-						}
-
-						gettimeofday(&_workModePriority_time, NULL);
-					}
-
-					GetPresentOutput(groupIndex, NONE_CARE_ADDRESS);
-					usleep(cmdDelayTime);
-					if (carReqVol != chargingInfo[groupIndex]->EvBatterytargetVoltage)
-					{
-						carReqVol = chargingInfo[groupIndex]->EvBatterytargetVoltage;
-						DEBUG_INFO("ev need vol = %f \n", chargingInfo[groupIndex]->EvBatterytargetVoltage);
-					}
-
-					if (carReqCur != chargingInfo[groupIndex]->EvBatterytargetCurrent)
-					{
-						carReqCur = chargingInfo[groupIndex]->EvBatterytargetCurrent;
-						DEBUG_INFO("ev need cur = %f \n", chargingInfo[groupIndex]->EvBatterytargetCurrent);
-					}
-
-					if (evseOutVol != chargingInfo[groupIndex]->FireChargingVoltage)
-					{
-						evseOutVol = chargingInfo[groupIndex]->FireChargingVoltage;
-						printf("evse output v index = %d, vol = %f \n",	groupIndex, chargingInfo[groupIndex]->FireChargingVoltage);
-					}
-
-					if (evseOutCur != chargingInfo[groupIndex]->PresentChargingCurrent)
-					{
-						evseOutCur = chargingInfo[groupIndex]->PresentChargingCurrent;
-						printf("evse output c index = %d, cur = %f \n", groupIndex, chargingInfo[groupIndex]->PresentChargingCurrent);
-					}
-
-					if (chargingInfo[groupIndex]->AvailableChargingCurrent <= 0)
-						continue;
-
-					// 針對各槍當前狀態,傳送需要回傳的資料指令
-					if (((chargingInfo[groupIndex]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[groupIndex]->SystemStatus <= S_CHARGING) && chargingInfo[groupIndex]->RelayK1K2Status) ||
-							chargingInfo[groupIndex]->SystemStatus == S_REASSIGN ||
-							(chargingInfo[groupIndex]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[groupIndex]->SystemStatus <= S_CCS_PRECHARGE_ST1)
-						)
-					{
-						EnableOutputPower(groupIndex, NONE_CARE_ADDRESS, OUTPUT_POWER_SWITCH_ON);
-						usleep(cmdDelayTime);
-						if (ShmPsuData->PsuGroup[groupIndex].GroupAvailableCurrent > 0)
-						{
-							if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_ADJUST)
-							{
-								// 如果車端要求的電流超過降載,則以降載電流為主
-								if (chargingInfo[groupIndex]->EvBatterytargetCurrent >= chargingInfo[groupIndex]->DeratingChargingCurrent)
-								{
-									chargingInfo[groupIndex]->EvBatterytargetCurrent = chargingInfo[groupIndex]->DeratingChargingCurrent;
-								}
-
-								if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_ADJUST)
-								{
-									deratingTime = GetTimeoutValue(_derating_time) / 1000;
-									if (deratingTime > 3000)
-									{
-										deratingTime = 0;
-										printf("=============Smart Charging : _REASSIGNED_RELAY============= Step 5 \n");
-										ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_RELAY;
-									}
-								}
-
-								if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_ADJUST)
-								{
-									for(int i = 0; i < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; i++)
-									{
-										printf("*********_REASSIGNED_ADJUST : groupIndex = %d, outputCur = %d, outputVol = %d \n",
-												groupIndex,
-												ShmPsuData->PsuGroup[groupIndex].PsuModule[i].PresentOutputCurrent,
-												ShmPsuData->PsuGroup[groupIndex].PsuModule[i].PresentOutputVoltage);
-									}
-								}
-
-								float targetVol = chargingInfo[groupIndex]->EvBatterytargetVoltage;
-								float targetCur = chargingInfo[groupIndex]->EvBatterytargetCurrent;
-
-								if (targetVol != 0)
-								{
-									if (targetCur <= 10)
-										targetCur = 10;
-								}
-								else
-								{
-									targetVol = 0;
-									targetCur = 0;
-								}
-
-								// 該充電槍的目標電壓與目標電流
-								SetPresentOutput(groupIndex, NONE_CARE_ADDRESS,
-									targetVol, targetCur,
-									chargingInfo[groupIndex]->DeratingChargingCurrent,
-									0x00);
-							}
-							else
-							{
-								printf("Set Present Output index = %d, V = %f, C = %f \n", groupIndex,
-										chargingInfo[groupIndex]->EvBatterytargetVoltage, chargingInfo[groupIndex]->EvBatterytargetCurrent);
-
-								float targetVol = chargingInfo[groupIndex]->EvBatterytargetVoltage;
-								float targetCur = chargingInfo[groupIndex]->EvBatterytargetCurrent;
-
-								if (targetVol != 0)
-								{
-									if (targetCur <= 10)
-										targetCur = 10;
-								}
-								else
-								{
-									targetVol = 0;
-									targetCur = 0;
-								}
-
-								// 該充電槍的目標電壓與目標電流
-								SetPresentOutput(groupIndex, NONE_CARE_ADDRESS,
-									targetVol,
-									targetCur,
-									chargingInfo[groupIndex]->AvailableChargingCurrent,
-									0x00);
-							}
-
-							usleep(cmdDelayTime);
-						}
-					}
-					else if (chargingInfo[groupIndex]->SystemStatus >= S_TERMINATING &&
-							chargingInfo[groupIndex]->SystemStatus <= S_COMPLETE)
-					{
-						SetPresentOutput(groupIndex, NONE_CARE_ADDRESS, ZERO_VOL, ZERO_CUR,
-								chargingInfo[groupIndex]->AvailableChargingCurrent, 0x00);
-						usleep(cmdDelayTime);
-					}
-				}
-				priorityLow >= 200 ? priorityLow = 1 : priorityLow++;
-				break;
-			}
-		}
-		usleep(45000);
-	}
-	return FAIL;
-}
+
+#include 	"Module_PsuComm.h"
+
+#define ARRAY_SIZE(A)		(sizeof(A) / sizeof(A[0]))
+#define PASS				1
+#define FAIL				-1
+#define YES					1
+#define NO					0
+#define DERATING			10
+
+#define SELF_TEST			0
+
+struct SysConfigAndInfo			*ShmSysConfigAndInfo;
+struct StatusCodeData 			*ShmStatusCodeData;
+struct PsuData 					*ShmPsuData;
+
+void trim(char *s);
+int mystrcmp(char *p1,char *p2);
+void substr(char *dest, const char* src, unsigned int start, unsigned int cnt);
+void split(char **arr, char *str, const char *del);
+
+bool libInitialize = false;
+byte gun_count = CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY;
+byte getAvailableCapOffset = 5;
+byte deratingKeepCount = 0;
+
+float carReqVol = 0;
+float carReqCur = 0;
+float evseOutVol = 0;
+float evseOutCur = 0;
+
+int cmdDelayTime = 20000;
+
+void PRINTF_FUNC(char *string, ...);
+
+int StoreLogMsg(const char *fmt, ...);
+#define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
+#define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
+#define DEBUG_ERROR(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
+
+unsigned long GetTimeoutValue(struct timeval _sour_time);
+
+unsigned long GetTimeoutValue(struct timeval _sour_time)
+{
+	struct timeval _end_time;
+	gettimeofday(&_end_time, NULL);
+
+	return 1000000 * (_end_time.tv_sec - _sour_time.tv_sec) + _end_time.tv_usec - _sour_time.tv_usec;
+}
+
+int StoreLogMsg(const char *fmt, ...)
+{
+	char Buf[4096+256];
+	char buffer[4096];
+	time_t CurrentTime;
+	struct tm *tm;
+	va_list args;
+
+	va_start(args, fmt);
+	int rc = vsnprintf(buffer, sizeof(buffer), fmt, args);
+	va_end(args);
+
+	memset(Buf,0,sizeof(Buf));
+	CurrentTime = time(NULL);
+	tm=localtime(&CurrentTime);
+	sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog",
+			tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,
+			buffer,
+			tm->tm_year+1900,tm->tm_mon+1);
+	system(Buf);
+
+	return rc;
+}
+
+int DiffTimeb(struct timeb ST, struct timeb ET)
+{
+	//return milli-second
+	unsigned int StartTime,StopTime;
+
+	StartTime=(unsigned int)ST.time;
+	StopTime=(unsigned int)ET.time;
+	return (StopTime-StartTime)*1000+ET.millitm-ST.millitm;
+}
+
+void PRINTF_FUNC(char *string, ...)
+{
+	if (DEBUG)
+	{
+		va_list args;
+		char buffer[4096];
+
+		va_start(args, string);
+		vsnprintf(buffer, sizeof(buffer), string, args);
+		va_end(args);
+		printf("%s \n", buffer);
+	}
+}
+//=================================
+// Common routine
+//=================================
+char* getTimeString(void)
+{
+	char *result=malloc(21);
+	time_t timep;
+	struct tm *p;
+	time(&timep);
+	p=gmtime(&timep);
+
+	sprintf(result, "[%04d-%02d-%02d %02d:%02d:%02d]", (1900+p->tm_year), (1+p->tm_mon), p->tm_mday, p->tm_hour, p->tm_hour, p->tm_sec);
+
+	return result;
+}
+
+void trim(char *s)
+{
+    int i=0, j, k, l=0;
+
+    while((s[i]==' ')||(s[i]=='\t')||(s[i]=='\n'))
+        i++;
+
+    j = strlen(s)-1;
+    while((s[j]==' ')||(s[j]=='\t')||(s[j]=='\n'))
+        j--;
+
+    if(i==0 && j==strlen(s)-1) { }
+    else if(i==0) s[j+1] = '\0';
+    else {
+        for(k=i; k<=j; k++) s[l++] = s[k];
+        s[l] = '\0';
+    }
+}
+
+int mystrcmp(char *p1,char *p2)
+{
+    while(*p1==*p2)
+    {
+        if(*p1=='\0' || *p2=='\0')
+            break;
+        p1++;
+        p2++;
+    }
+    if(*p1=='\0' && *p2=='\0')
+        return(PASS);
+    else
+        return(FAIL);
+}
+
+void substr(char *dest, const char* src, unsigned int start, unsigned int cnt)
+{
+	strncpy(dest, src + start, cnt);
+	dest[cnt] = 0;
+}
+
+void split(char **arr, char *str, const char *del)
+{
+	char *s = strtok(str, del);
+
+	while(s != NULL)
+	{
+		*arr++ = s;
+		s = strtok(NULL, del);
+	}
+}
+
+//=================================
+// ReAssigned PSU Function
+//=================================
+void ReAssignedResource()
+{
+	int index = 0;
+	struct PsuModuleData PsuModule[ShmPsuData->SystemPresentPsuQuantity];
+
+	for (byte i = 0; i < 4; i++)
+	{
+		for(byte psuCount = 0; psuCount < ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity; psuCount++)
+		{
+			memcpy(&PsuModule[index], &ShmPsuData->PsuGroup[i].PsuModule[psuCount], sizeof(struct PsuModuleData));
+			index++;
+		}
+		ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity = 0;
+	}
+
+	for(int i = 0; i < ShmPsuData->SystemPresentPsuQuantity; i++)
+	{
+		byte group = PsuModule[i].FireWireIndex;
+
+		memcpy(&ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity],
+				&PsuModule[i], sizeof(struct PsuModuleData));
+
+		PRINTF_FUNC("ReAssignedResource : PhysicalID = %d, Address = %d, group = %d \n",
+				ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].PhysicalID,
+				ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].Address,
+				group);
+//		printf("ReAssignedResource : PhysicalID = %d, Address = %d, group = %d \n",
+//				ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].PhysicalID,
+//				ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].Address,
+//				group);
+
+		PsuAddressAssignment(ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].PhysicalID,
+				group);
+		ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity++;
+	}
+}
+
+//=================================
+// Save data to share memory Function
+//=================================
+bool FindChargingInfoData(byte target, struct ChargingInfoData **chargingData)
+{
+	for (byte index = 0; index < CHAdeMO_QUANTITY; index++)
+	{
+		if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == target)
+		{
+			chargingData[target] = &ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index];
+			return true;
+		}
+	}
+
+	for (byte index = 0; index < CCS_QUANTITY; index++)
+	{
+		if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == target)
+		{
+			chargingData[target] = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[index];
+			return true;
+		}
+	}
+
+	for (byte index = 0; index < GB_QUANTITY; index++)
+	{
+		if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == target)
+		{
+			chargingData[target] = &ShmSysConfigAndInfo->SysInfo.GbChargingData[index];
+			return true;
+		}
+	}
+
+	return false;
+}
+
+//=================================
+// Alarm code mapping to share memory Function
+//=================================
+// 檢查 Byte 中某個 Bit 的值
+// _byte : 欲改變的 byte
+// _bit : 該 byte 的第幾個 bit
+unsigned char mask_table[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
+unsigned char DetectBitValue(unsigned char _byte, unsigned char _bit)
+{
+	return ( _byte & mask_table[_bit] ) != 0x00;
+}
+
+void AbnormalStopAnalysis(byte gun_index, int errCode)
+{
+	for (char i = 0; i < 3; i++)
+	{
+		unsigned char byteIndex = (errCode >> (8 * i)) & 0xff;
+
+		for (char bitIndex = 0; bitIndex < 8; bitIndex++)
+		{
+			if(DetectBitValue(byteIndex , bitIndex) == 1)
+			{
+				switch(byteIndex)
+				{
+					case 0:
+					{
+						if (bitIndex == 0)
+							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuOutputShortCircuit = YES;
+						else if (bitIndex == 5)
+							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = YES;
+					}
+						break;
+				case 1:
+					{
+						if (bitIndex == 1)
+							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFailureAlarm = YES;
+						else if (bitIndex == 2)
+							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuProtectionAlarm = YES;
+						else if (bitIndex == 3)
+							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFailureAlarm = YES;
+						else if (bitIndex == 4)
+							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCriticalPointOTP = YES;
+						else if (bitIndex == 5)
+							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = YES;
+					}
+					break;
+				case 2:
+					{
+						if (bitIndex == 1)
+							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDuplicateID = YES;
+						if (bitIndex == 2)
+							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuThreePhaseOnputImbalance = YES;
+						else if (bitIndex == 3)
+							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuThreePhaseInputInadequate = YES;
+						else if (bitIndex == 4)
+							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuThreePhaseInputInadequate = YES;
+						else if (bitIndex == 5)
+							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputUVP = YES;
+						else if (bitIndex == 6)
+							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputOVP = YES;
+					}
+					break;
+				}
+			}
+			else
+			{
+				switch (byteIndex) {
+				case 0: {
+					if (bitIndex == 0)
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuOutputShortCircuit = NO;
+					else if (bitIndex == 5)
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = NO;
+				}
+					break;
+				case 1: {
+					if (bitIndex == 1)
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFailureAlarm = NO;
+					else if (bitIndex == 2)
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuProtectionAlarm = NO;
+					else if (bitIndex == 3)
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFailureAlarm = NO;
+					else if (bitIndex == 4)
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCriticalPointOTP = NO;
+					else if (bitIndex == 5)
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = NO;
+				}
+					break;
+				case 2: {
+					if (bitIndex == 1)
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDuplicateID = NO;
+					if (bitIndex == 2)
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuThreePhaseOnputImbalance = NO;
+					else if (bitIndex == 3)
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuThreePhaseInputInadequate = NO;
+					else if (bitIndex == 4)
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuThreePhaseInputInadequate = NO;
+					else if (bitIndex == 5)
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputUVP = NO;
+					else if (bitIndex == 6)
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputOVP = NO;
+				}
+					break;
+				}
+			}
+		}
+	}
+}
+
+//=================================
+// Callback Function
+//=================================
+void GetPsuRequestCallback(byte phy_id, char *serial_number)
+{
+	if (ShmSysConfigAndInfo->SysInfo.AcContactorStatus == NO)
+		return;
+
+	// ********************** 每次送電後,需判斷要把所有的模塊分配到哪個 Group **********************
+	byte group = 0;
+	if(ShmSysConfigAndInfo->SysInfo.BootingStatus == BOOTTING || gun_count == 1)
+	{
+		// 初始化狀態,則直接先分配到同個群
+		group = 0;
+	}
+	else
+	{
+		group = ShmSysConfigAndInfo->SysInfo.CurGunSelected;
+	}
+
+	bool isNewPsu = true;
+	for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
+	{
+		if (ShmPsuData->PsuGroup[group].PsuModule[index].PhysicalID == phy_id &&
+			strncmp((char *)ShmPsuData->PsuGroup[group].PsuModule[index].SerialNumber, serial_number, 7) == 0)
+		{
+			isNewPsu = false;
+		}
+	}
+
+	if (isNewPsu)
+	{
+		ShmPsuData->SystemPresentPsuQuantity++;
+		PRINTF_FUNC("get psu********Membar = %d, group = %d \n", ShmPsuData->SystemPresentPsuQuantity, group);
+
+		if (ShmPsuData->Work_Step >= _TEST_LINE_STEP && ShmPsuData->Work_Step <= _TEST_COMPLETE)
+		{
+			// 已經進入火線上的驗證動作
+			ShmPsuData->NeedBackTest = YES;
+		}
+		else if (ShmPsuData->Work_Step == _WORK_CHARGING)
+		{
+			// 一旦進入火線,分配一個不會用到的給該模塊
+			group++;
+		}
+
+		ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].Address = ShmPsuData->SystemPresentPsuQuantity;
+		ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].PhysicalID = phy_id;
+		ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].AssignID = (group >> 6) + ShmPsuData->SystemPresentPsuQuantity;
+		strcpy((char *)ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].SerialNumber, serial_number);
+		ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity++;
+
+		byte isFind = false;
+		for (byte index = 0; index < conn_1_count; index++)
+		{
+			PRINTF_FUNC("connector_1[%d] = %d, phy_id = %d \n", index, connector_1[index], phy_id);
+			if (connector_1[index] == phy_id)
+			{
+				isFind = true;
+				ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].FireWireIndex = 0;
+				break;
+			}
+		}
+
+		if (!isFind)
+		{
+			for (byte index = 0; index < conn_2_count; index++)
+			{
+				PRINTF_FUNC("connector_2[%d] = %d, phy_id = %d \n", index, connector_2[index], phy_id);
+				if (connector_2[index] == phy_id)
+				{
+					isFind = true;
+					ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].FireWireIndex = 1;
+					break;
+				}
+			}
+		}
+
+		//PsuAddressAssignment(phy_id, serial_number, ShmPsuData->SystemPresentPsuQuantity, group);
+		PsuAddressAssignment(phy_id, group);
+
+		if (ShmPsuData->Work_Step != _WORK_CHARGING)
+		{
+			ShmPsuData->GroupCount = group + 1;
+		}
+	}
+}
+
+void SaveStatusCallback(byte group, byte address, char cri_temp1, int alarm)
+{
+	//EVSE
+	for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
+	{
+		if (ShmPsuData->PsuGroup[group].PsuModule[index].PhysicalID == address)
+	    {
+			ShmPsuData->PsuGroup[group].PsuModule[index].CriticalTemp1 = cri_temp1;
+	    	ShmPsuData->PsuGroup[group].PsuModule[index].AlarmCode = alarm;
+	    	AbnormalStopAnalysis(group, alarm);
+	    	break;
+	    }
+	}
+}
+
+//模組三向輸入電壓
+void SavePresentInputVoltageCallback(byte address, unsigned short vol1, unsigned short vol2, unsigned short vol3)
+{
+	//EVSE
+	//search group
+    for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
+    { 
+    	for (byte index = 0; index < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; index++)
+    	{
+    	    //search id
+    		if (ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PhysicalID == address)
+    		{
+    		    //update module msg
+    			ShmPsuData->PsuGroup[groupIndex].PsuModule[index].InputVoltageL1 = vol1;
+    			ShmPsuData->PsuGroup[groupIndex].PsuModule[index].InputVoltageL2 = vol2;
+    			ShmPsuData->PsuGroup[groupIndex].PsuModule[index].InputVoltageL3 = vol3;
+    			break;
+    		}
+    	}
+    }
+}
+
+// 模塊輸出的電壓電流
+void SavePresentOutputCallback(byte address, unsigned short out_vol, unsigned short out_cur)
+{
+	unsigned short outputVol = 0;
+	unsigned short outputCur = 0;
+	unsigned short group = 0;
+	bool isChange = false;
+
+	// PSU
+	for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
+    {
+    	for (int index = 0; index < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; index++)
+    	{
+    		if (ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PhysicalID == address)
+    		{
+    		    //如果英飛源模組不是 ver1.09 版使用模組輸出電壓
+    		    /*
+    			if(InfyPwrModelVerIs109 == 0)
+    			{
+    			    ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PresentOutputVoltage = out_vol;
+    			}
+    			*/
+    			ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PresentOutputVoltage = out_vol;
+    			ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PresentOutputCurrent = out_cur;   			
+    			
+    		    for (int loop = 0; loop < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; loop++)
+    		    {
+    		        //update voltage
+   		            if (ShmPsuData->PsuGroup[groupIndex].PsuModule[loop].PresentOutputVoltage > outputVol)
+   		            {
+    			        outputVol = ShmPsuData->PsuGroup[groupIndex].PsuModule[loop].PresentOutputVoltage;
+    			    }
+    			    //update total current
+    			    outputCur += ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PresentOutputCurrent;
+    			    group = groupIndex;
+    			    isChange = true;
+    		    }
+    		}
+
+            /*
+    		if (ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputVoltage > outputVol)
+    			outputVol = ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputVoltage;
+
+    		outputCur += ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputCurrent;
+    		*/
+    	}
+    }
+
+	if (isChange)
+	{
+		// PSU Group
+		// 電壓
+		ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage = outputVol;
+		// 電流
+		ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent = outputCur;
+
+		//EVSE - 槍端的輸出電壓
+		chargingInfo[group]->PresentChargingVoltage = ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage;
+		//EVSE - 槍端的輸出電流
+		chargingInfo[group]->PresentChargingCurrent = ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent;
+	}
+
+	//printf("GroupPresentOutputVoltage = %d \n", ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage);
+	//printf("GroupPresentOutputCurrent = %d \n", ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent);
+}
+
+//PSU able_power = KW (單位 0.1) exp. 300 = 30kw
+//PSU able_cur = A (單位 0.1) exp. 400 = 40A
+void SaveAvailableCapCallback(byte address, unsigned short maxv, unsigned short minv, unsigned short able_cur, unsigned short able_power)
+{
+	unsigned int power = 0;
+	unsigned int current = 0;
+	unsigned int power_derating = 0;
+	unsigned int current_derating = 0;
+	unsigned int group = 0;
+	bool isChange = false;
+	//bool sameGroup = false;
+
+    //search group
+	//printf("GroupCount = %d \n", ShmPsuData->GroupCount);
+    for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
+    {        
+    	//printf("GroupPresentPsuQuantity = %d \n", ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity);
+    	for (int index = 0; index < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; index++)
+    	{
+    	    //search group-id
+    		//printf("PhysicalID = %d, address = %d \n", ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PhysicalID, address);
+    		if (ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PhysicalID == address)
+    		{
+    		    //先更新該模組資訊    
+    			ShmPsuData->PsuGroup[groupIndex].PsuModule[index].AvailablePower = able_power;
+
+    			//電壓在 150V 時使用額定電流
+    			if(ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PresentOutputVoltage < 1500)
+    			{
+    			    ShmPsuData->PsuGroup[groupIndex].PsuModule[index].AvailableCurrent = able_cur;
+    			}
+    			//如果英飛源模組不是 ver1.09 版 或 (如果英飛源模組是 ver1.09 版但回應可輸出電流有誤則使用額定報文可輸出電流)
+    			/*
+    			if(InfyPwrModelVerIs109 == 0 ||
+    			    (InfyPwrModelVerIs109 == 1 && ShmPsuData->PsuGroup[groupIndex].PsuModule[index].AvailableCurrent == 0))
+    			{
+    			        ShmPsuData->PsuGroup[groupIndex].PsuModule[index].AvailableCurrent = able_cur;
+    			}
+    			*/
+    		    //該對應的模組群重新計算總合		    
+    		    for (int loop = 0; loop < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; loop++)
+    		    {
+    		    	// 降載
+    		    	if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_GET_NEW_CAP &&
+    		    			ShmSysConfigAndInfo->SysInfo.ReAssignedFlag < _REASSIGNED_COMP)
+    		    	{
+    		    		if (ShmPsuData->PsuGroup[group].PsuModule[index].FireWireIndex == group)
+    		    		{
+    		    			power_derating += ShmPsuData->PsuGroup[group].PsuModule[index].AvailablePower;
+    		    			current_derating += ShmPsuData->PsuGroup[group].PsuModule[index].AvailableCurrent;
+    		    		}
+    		    	}
+
+    		        power += ShmPsuData->PsuGroup[groupIndex].PsuModule[loop].AvailablePower;
+    			    current += ShmPsuData->PsuGroup[groupIndex].PsuModule[loop].AvailableCurrent;
+    			    group = groupIndex;
+    			    isChange = true;
+    		    }
+    		}
+    	}
+    }
+    
+    if (current_derating == 0)
+    {
+    	current_derating = current;
+    }
+
+    if (power_derating == 0)
+    {
+    	power_derating = power;
+    }
+
+	if (isChange)
+	{
+		// PSU Group
+		// Available Power
+		ShmPsuData->PsuGroup[group].GroupAvailablePower = power;
+		// Available Current
+		ShmPsuData->PsuGroup[group].GroupAvailableCurrent = current;
+
+		chargingInfo[group]->MaximumChargingVoltage = maxv;
+		chargingInfo[group]->AvailableChargingCurrent =	ShmPsuData->PsuGroup[group].GroupAvailableCurrent;
+		chargingInfo[group]->AvailableChargingPower = ShmPsuData->PsuGroup[group].GroupAvailablePower;
+		chargingInfo[group]->DeratingChargingCurrent = current_derating;
+		chargingInfo[group]->DeratingChargingPower = power_derating;
+
+		PRINTF_FUNC("group = %d, AvailableChargingCurrent = %f, GroupAvailablePower = %f, DeratingChargingCurrent = %f, DeratingChargingPower = %f \n",
+							group, chargingInfo[group]->AvailableChargingCurrent, chargingInfo[group]->AvailableChargingPower,
+							chargingInfo[group]->DeratingChargingCurrent, chargingInfo[group]->DeratingChargingPower);
+	}
+}
+
+void GetBarCodeCallback(byte address, char *serial_number , unsigned short module_ver)
+{
+	//EVSE
+	for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
+	{
+    	for (byte index = 0; index < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; index++)
+    	{
+    		if (ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PhysicalID == address)
+    		{
+    		    ShmPsuData->PsuGroup[groupIndex].PsuModule[index].FwVersion[0] = (module_ver >> 8) & 0xFF;
+    			ShmPsuData->PsuGroup[groupIndex].PsuModule[index].FwVersion[1] = (module_ver) & 0xFF;
+    		    //strcpy((char *)ShmPsuData->PsuGroup[groupIndex].PsuModule[ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity].SerialNumber, serial_number);
+    		}
+    	}
+	}
+}
+
+void GetMiscInfoCallback(byte address, unsigned short CmdType , unsigned int value)
+{
+	//EVSE
+	for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
+    {
+    	for (byte index = 0; index < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; index++)
+    	{
+    		if (ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PhysicalID == address)
+    		{
+    		    if(CmdType == MISC_REQCMD_DC_BOARD_TMP){
+    		        //數值未處理
+    		        ShmPsuData->PsuGroup[groupIndex].PsuModule[index].CriticalTemp2 = (byte)value;
+    		    }else if(CmdType == MISC_REQCMD_PFC_BOARD_TMP){
+    		        //數值未處理
+    		        ShmPsuData->PsuGroup[groupIndex].PsuModule[index].CriticalTemp3 = (byte)value;
+    		    }else if(CmdType == MISC_REQCMD_FAN_SPEED){
+    		        //數值未處理
+    		        ShmPsuData->PsuGroup[groupIndex].PsuModule[index].FanSpeed_1 = (unsigned short)value;
+    		    }
+    		}
+    	}
+	}
+
+	//暫定如果有回 misc 就認定英飛源為 1.9 版
+	//InfyPwrModelVerIs109 = 1;
+	//printf("Get Misc : %d \n",InfyPwrModelVerIs109);
+}
+
+void SaveHardwareVersion(byte group, byte address, int hw_ver)
+{
+	//EVSE
+	for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
+	{
+		if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address)
+		{
+			ShmPsuData->PsuGroup[group].PsuModule[index].FwVersion[0] = (hw_ver >> 24) & 0xFF;
+			ShmPsuData->PsuGroup[group].PsuModule[index].FwVersion[1] = (hw_ver >> 16) & 0xFF;
+			ShmPsuData->PsuGroup[group].PsuModule[index].FwVersion[2] = (hw_ver >> 8) & 0xFF;
+			ShmPsuData->PsuGroup[group].PsuModule[index].FwVersion[3] = hw_ver & 0xFF;
+			break;
+		}
+	}
+}
+
+
+//Vext      模組二極體後電壓
+//Iavail    模組目前因環境因素的真實能輸出電流
+void SavePresentModeleVextIavailCallback(byte address, unsigned short Vext, unsigned short Iavail)
+{
+	//EVSE
+	//search group
+    for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
+    {
+    	for (byte index = 0; index < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; index++)
+    	{
+    	    //search id
+    		if (ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PhysicalID == address)
+    		{
+    		    //update module msg
+    		    //ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PresentOutputVoltage = Vext;
+    		    //
+    		    if(ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PresentOutputVoltage >= 1500)
+    		    {
+    			    ShmPsuData->PsuGroup[groupIndex].PsuModule[index].AvailableCurrent = Iavail;
+    			}
+    			//printf("Vext = %d I = %d \n", Vext,Iavail);
+    			break;
+    		}
+    	}
+    }
+}
+
+void GetOutputPowerSwitchStatusCallback(byte address, unsigned char value)
+{
+    for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
+    {
+    	for (byte index = 0; index < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; index++)
+    	{
+    		if (ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PhysicalID == address)
+    		{
+    			//printf("PowerSwitch = %d, group = %d, address = %d \n", value, group, address);
+    			if(value){
+    			    ShmPsuData->PsuGroup[groupIndex].PsuModule[index].OutputPowerSwitch = 0x00;
+    			}else{
+    			    ShmPsuData->PsuGroup[groupIndex].PsuModule[index].OutputPowerSwitch = 0x01;
+    			}
+    			
+    			break;
+    		}
+    	}
+    }
+}
+
+//==========================================
+// Init all share memory
+//==========================================
+int InitShareMemory()
+{
+	int result = PASS;
+	int MeterSMId;
+
+	//creat ShmSysConfigAndInfo
+	if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo),  0777)) < 0)
+    {
+		#ifdef SystemLogMessage
+		DEBUG_ERROR("shmget ShmSysConfigAndInfo NG %d \n");
+		#endif
+		result = FAIL;
+	}
+    else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+    	#ifdef SystemLogMessage
+    	DEBUG_ERROR("shmat ShmSysConfigAndInfo NG \n");
+		#endif
+    	result = FAIL;
+   	 }
+    else
+    {}
+
+   	//creat ShmStatusCodeData
+   	if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData),  0777)) < 0)
+    {
+		#ifdef SystemLogMessage
+   		DEBUG_ERROR("shmget ShmStatusCodeData NG \n");
+		#endif
+   		result = FAIL;
+	}
+    else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+    	#ifdef SystemLogMessage
+    	DEBUG_ERROR("shmat ShmStatusCodeData NG \n");
+		#endif
+    	result = FAIL;
+   	}
+    else
+    {}
+
+   	//creat ShmPsuData
+	if ((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData),  0777)) < 0)
+	{
+		#ifdef SystemLogMessage
+		DEBUG_ERROR("shmget ShmPsuData NG \n");
+		#endif
+		result = FAIL;
+	}
+	else if ((ShmPsuData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+	{
+		#ifdef SystemLogMessage
+		DEBUG_ERROR("shmat ShmPsuData NG \n");
+		#endif
+		result = FAIL;
+	 }
+	memset(ShmPsuData,0,sizeof(struct PsuData));
+
+    return result;
+}
+
+//================================================
+// Main process
+//================================================
+void InitialPsuData()
+{
+	ShmPsuData->SystemPresentPsuQuantity = 0;
+
+	for (byte _groupCount = 0; _groupCount < ARRAY_SIZE(ShmPsuData->PsuGroup);	_groupCount++)
+	{
+		ShmPsuData->PsuGroup[_groupCount].GroupPresentPsuQuantity = 0;
+		ShmPsuData->PsuGroup[_groupCount].GroupAvailablePower = 0;
+		ShmPsuData->PsuGroup[_groupCount].GroupAvailableCurrent = 0;
+	}
+	
+	ShmPsuData->Work_Step = _INIT_PSU_STATUS;
+}
+
+void Initialization()
+{
+	bool isPass = false;
+	while(!isPass)
+	{
+		isPass = true;
+		for (byte _index = 0; _index < _gunCount; _index++)
+		{
+			if (!FindChargingInfoData(_index, &chargingInfo[0]))
+			{
+				DEBUG_ERROR("EvComm (main) : FindChargingInfoData false \n");
+				isPass = false;
+				break;
+			}
+		}
+	}
+	conn_1_count = sizeof(connector_1)/sizeof(connector_1[0]);
+	conn_2_count = sizeof(connector_2)/sizeof(connector_2[0]);
+}
+
+int main(void)
+{
+	PRINTF_FUNC("Psu Task boot .... \n");
+	if(InitShareMemory() == FAIL)
+	{
+		#ifdef SystemLogMessage
+		DEBUG_ERROR("InitShareMemory NG\n");
+		#endif
+		if(ShmStatusCodeData != NULL)
+		{
+			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory = 1;
+		}
+		sleep(5);
+		return 0;
+	}
+
+	PRINTF_FUNC("InitShareMemory OK\n");
+
+	// register callback function
+	GetPsuAddressReq(&GetPsuRequestCallback);
+	RefreshSerialNumber(&GetBarCodeCallback);
+	RefreshVextAndIavail(&SavePresentModeleVextIavailCallback);
+	RefreshMiscInfo(&GetMiscInfoCallback);
+
+	RefreshStatus(&SaveStatusCallback);
+	RefreshInputVol(&SavePresentInputVoltageCallback);
+	RefreshGetOutput(&SavePresentOutputCallback);
+	RefreshAvailableCap(&SaveAvailableCapCallback);
+	RefreshOutputPowerSwitch(&GetOutputPowerSwitchStatusCallback);
+
+	// initial object
+	InitialPsuData();
+	Initialization();
+	libInitialize = InitialCommunication();
+
+    byte priorityLow = 1;
+    byte isInitialComp = NO;
+	//main loop
+	while (libInitialize)
+	{
+		// 斷電狀態
+		if (ShmSysConfigAndInfo->SysInfo.AcContactorStatus == NO)
+		{
+			//一但 AC Off PSU 斷電全部的 PSU Group ID 會全部清 0
+			if (!isInitialComp)
+			{
+				InitialPsuData();
+				ShmPsuData->Work_Step = ASSIGN_START;
+				isInitialComp = YES;
+			}
+			sleep(1);
+			continue;
+		}
+		else
+			isInitialComp = NO;
+
+		// update psu fw req
+//		if(psu update req ?)
+//		{
+//
+//			continue;
+//		}
+
+		// 自檢失敗
+		if (ShmPsuData->Work_Step == _NO_WORKING)
+		{
+			PRINTF_FUNC("== PSU == self test fail. \n");
+			sleep(5);
+		}
+
+		switch(ShmPsuData->Work_Step)
+		{
+			case ASSIGN_START:
+			{
+				PRINTF_FUNC("== PSU == ASSIGN_COMP \n");
+				gettimeofday(&_id_assign_time, NULL);
+				ShmPsuData->Work_Step = ASSIGN_COMP;
+			}
+				break;
+			case ASSIGN_COMP:
+			{
+				if (priorityLow == 1)
+				{
+					//如果還未取得模組數量
+					if(ShmPsuData->SystemPresentPsuQuantity == 0)
+					{
+						EnableDipAddrMode();
+						usleep(cmdDelayTime);
+				        //發送取得目前全部模組數量 (英飛源開機須等待讓模組互相通訊)
+				        RequestModuleTotalMumbert();
+				        usleep(cmdDelayTime);
+					}
+					//己取得模組數量 (目前還未分配群組所以都使用預設 0)
+					else
+					{
+				    	for (byte psuIndex = 0;	psuIndex < ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity;	psuIndex++)
+				    	{
+				            //get status
+				    		GetStatus(0, NONE_CARE_ADDRESS);
+				    		usleep(cmdDelayTime);
+				            //get barcode & ver
+				    		GetSerialNumber(0, NONE_CARE_ADDRESS);
+				    		usleep(cmdDelayTime);
+
+				    		GetMiscInfo(0, NONE_CARE_ADDRESS, MISC_REQCMD_DC_BOARD_TMP);
+				    		usleep(cmdDelayTime);
+				    		GetMiscInfo(0, NONE_CARE_ADDRESS, MISC_REQCMD_PFC_BOARD_TMP);
+				    		usleep(cmdDelayTime);
+				    		GetMiscInfo(0, NONE_CARE_ADDRESS, MISC_REQCMD_PFC_BOARD_TMP);
+				    		usleep(cmdDelayTime);
+				    	}
+					}
+					//printf("Get Misc2 : %d \n",InfyPwrModelVerIs109);
+				}
+
+				priorityLow >= 20 ? priorityLow = 1 : priorityLow++;
+				// 等待 15 秒
+				if (GetTimeoutValue(_id_assign_time) >= 15000000)
+				{
+					ShmPsuData->Work_Step = ENABLE_POW;
+					PRINTF_FUNC("INFYPWR Num = %d \n", ShmPsuData->SystemPresentPsuQuantity);
+					PRINTF_FUNC("== PSU == ENABLE_POW \n");
+				}
+			}
+				break;
+			case ENABLE_POW:
+			{
+				if (ShmSysConfigAndInfo->SysInfo.BootingStatus == BOOTTING)
+				{
+					// 電樁在 Booting 的狀態 - 自檢
+					PRINTF_FUNC("== PSU == _TEST_LINE_STEP \n");
+					ShmPsuData->Work_Step = _TEST_LINE_STEP;
+				}
+				else
+				{
+					PRINTF_FUNC("== PSU == _WORK_CHARGING \n");
+					ShmPsuData->Work_Step = _WORK_CHARGING;
+					gettimeofday(&_workModePriority_time, NULL);
+				}
+			}
+				break;
+			case _TEST_LINE_STEP:
+			{
+				PRINTF_FUNC("cur total psu count = %d \n", ShmPsuData->SystemPresentPsuQuantity);
+				if (ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity <= 0)
+				{
+					sleep(1);
+					continue;
+				}
+
+				ShmPsuData->Work_Step = _TEST_POWER_STEP;
+			}
+				break;
+			case _TEST_POWER_STEP:
+			{
+				if(!_chkTotalCapStart)
+				{
+					_chkTotalCapStart = true;
+					gettimeofday(&_chk_cap_time, NULL);
+				}
+
+				for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
+				{
+					GetStatus(groupIndex, NONE_CARE_ADDRESS);
+					usleep(cmdDelayTime);
+
+					//infypwr v1.9 (如果沒回也沒差)
+					//GetVextAndIavail(SET_MODULE_CMD, NONE_CARE_ADDRESS);
+					//usleep(cmdDelayTime);
+				}
+
+				for (byte psuCount = 0; psuCount < ShmPsuData->SystemPresentPsuQuantity; psuCount++)
+				{
+					GetAvailableCap(psuCount, NONE_CARE_ADDRESS,  0);
+				}
+
+				usleep(cmdDelayTime);
+				if (GetTimeoutValue(_chk_cap_time) >= 2000000)
+				{
+					PRINTF_FUNC("AvailableChargingCurrent = %f, AvailableChargingPower = %f \n",
+							chargingInfo[0]->AvailableChargingCurrent, chargingInfo[0]->AvailableChargingPower);
+					for (byte index = 0; index < ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity; index++)
+					{
+						PRINTF_FUNC("index = %d, fire index = %d, phy addr = %d \n",
+								index, recordPsuData[index]._fire_index, recordPsuData[index]._phy_addr);
+					}
+
+					PRINTF_FUNC("== PSU == TEST_COMPLETE \n");
+					ShmPsuData->Work_Step = _TEST_COMPLETE;
+				}
+			}
+				break;
+			case _TEST_COMPLETE:
+			{
+			    priorityLow = 1;
+				sleep(1);
+			}
+				break;
+			case _WORK_CHARGING:
+			{
+				int time = GetTimeoutValue(_workModePriority_time) / 1000;
+				//printf("GroupCount = %d \n", ShmPsuData->GroupCount);
+				//printf("cur total psu count = %d \n", ShmPsuData->SystemPresentPsuQuantity);
+
+				// 智能分配 : 檢查該槍是否有模塊有用,有則無須重新分配直接進入充電
+				if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_PREPARE)
+				{
+					if (ShmPsuData->PsuGroup[ShmSysConfigAndInfo->SysInfo.CurGunSelected].GroupPresentPsuQuantity > 0)
+					{
+						PRINTF_FUNC("=============Smart Charging : _REASSIGNED_NONE============= Step 0 \n");
+						ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE;
+					}
+					else
+					{
+						PRINTF_FUNC("=============Smart Charging : _REASSIGNED_GET_NEW_CAP============= Step 2 \n");
+						ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_GET_NEW_CAP;
+					}
+				}
+
+				if (time > 1000)
+				{
+					for (byte psuCount = 0; psuCount < ShmPsuData->SystemPresentPsuQuantity; psuCount++)
+					{
+						GetAvailableCap(psuCount, NONE_CARE_ADDRESS,  0);
+					}
+					usleep(cmdDelayTime);
+				}
+
+				for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++)
+				{
+					if (time > 1000)
+					{
+						GetStatus(groupIndex, NONE_CARE_ADDRESS);
+						usleep(cmdDelayTime);
+					    /*
+    					GetMiscInfo(SET_GROUP_CMD, 0, MISC_REQCMD_DC_BOARD_TMP);
+    					usleep(cmdDelayTime);
+    					GetMiscInfo(SET_GROUP_CMD, 0, MISC_REQCMD_PFC_BOARD_TMP);
+    					usleep(cmdDelayTime);
+    					GetMiscInfo(SET_GROUP_CMD, 0, MISC_REQCMD_PFC_BOARD_TMP);
+    					usleep(cmdDelayTime);
+    					*/
+						if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_GET_NEW_CAP)
+						{
+							if (groupIndex != ShmSysConfigAndInfo->SysInfo.CurGunSelected)
+							{
+								if (chargingInfo[groupIndex]->SystemStatus >= S_CHARGING &&	chargingInfo[groupIndex]->SystemStatus <= S_COMPLETE)
+								{
+									if (chargingInfo[groupIndex]->DeratingChargingCurrent < chargingInfo[groupIndex]->AvailableChargingCurrent)
+									{
+										// 車端需求電流降低至降載的電流
+										PRINTF_FUNC("Smart Charging : index = %d, EvBatterytargetCurrent = %f, DeratingChargingCurrent = %f \n",
+										groupIndex, chargingInfo[groupIndex]->EvBatterytargetCurrent, chargingInfo[groupIndex]->DeratingChargingCurrent);
+
+										if ((chargingInfo[groupIndex]->EvBatterytargetCurrent <= chargingInfo[groupIndex]->DeratingChargingCurrent) ||
+											deratingKeepCount >= DERATING)
+										{
+											// 車端降載完成
+											PRINTF_FUNC("=============Smart Charging : _REASSIGNED_MAIN============= Step 3 \n");
+											ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_MAIN;
+										}
+										else
+										{
+											deratingKeepCount++;
+										}
+									}
+								}
+							}
+						}
+						else
+							deratingKeepCount = 0;
+
+						if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_MAIN)
+						{
+							PRINTF_FUNC("=============Smart Charging : _REASSIGNED_ADJUST============= Step 4 \n");
+							//重新分配模組
+							ReAssignedResource();
+							gettimeofday(&_derating_time, NULL);
+							ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_ADJUST;
+						}
+
+						gettimeofday(&_workModePriority_time, NULL);
+					}
+
+					GetPresentOutput(groupIndex, NONE_CARE_ADDRESS);
+					usleep(cmdDelayTime);
+					//GetVextAndIavail(SET_MODULE_CMD, 0);
+
+					if (carReqVol != chargingInfo[groupIndex]->EvBatterytargetVoltage)
+					{
+						carReqVol = chargingInfo[groupIndex]->EvBatterytargetVoltage;
+						DEBUG_INFO("ev need vol = %f \n", chargingInfo[groupIndex]->EvBatterytargetVoltage);
+					}
+
+					if (carReqCur != chargingInfo[groupIndex]->EvBatterytargetCurrent)
+					{
+						carReqCur = chargingInfo[groupIndex]->EvBatterytargetCurrent;
+						DEBUG_INFO("ev need cur = %f \n", chargingInfo[groupIndex]->EvBatterytargetCurrent);
+					}
+
+					if (evseOutVol != chargingInfo[groupIndex]->FireChargingVoltage)
+					{
+						evseOutVol = chargingInfo[groupIndex]->FireChargingVoltage;
+						PRINTF_FUNC("evse output vol = %f \n",	chargingInfo[groupIndex]->FireChargingVoltage);
+					}
+
+					if (evseOutCur != chargingInfo[groupIndex]->PresentChargingCurrent)
+					{
+						evseOutCur = chargingInfo[groupIndex]->PresentChargingCurrent;
+						PRINTF_FUNC("evse output cur = %f \n", chargingInfo[groupIndex]->PresentChargingCurrent);
+					}
+
+					// 針對各槍當前狀態,傳送需要回傳的資料指令
+					if (((chargingInfo[groupIndex]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[groupIndex]->SystemStatus <= S_CHARGING) && chargingInfo[groupIndex]->RelayK1K2Status) ||
+							chargingInfo[groupIndex]->SystemStatus == S_REASSIGN ||
+							(chargingInfo[groupIndex]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[groupIndex]->SystemStatus <= S_CCS_PRECHARGE_ST1))
+					{
+						if (ShmPsuData->PsuGroup[groupIndex].GroupAvailableCurrent > 0)
+						{
+							if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_ADJUST &&
+									ShmSysConfigAndInfo->SysInfo.ReAssignedFlag < _REASSIGNED_COMP )
+							{
+								// 如果車端要求的電流超過降載,則以降載電流為主
+								if (chargingInfo[groupIndex]->EvBatterytargetCurrent >= chargingInfo[groupIndex]->DeratingChargingCurrent)
+								{
+									chargingInfo[groupIndex]->EvBatterytargetCurrent = chargingInfo[groupIndex]->DeratingChargingCurrent;
+								}
+
+								if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_ADJUST)
+								{
+									deratingTime = GetTimeoutValue(_derating_time) / 1000;
+									if (deratingTime > 3000)
+									{
+										deratingTime = 0;
+										PRINTF_FUNC("=============Smart Charging : _REASSIGNED_RELAY============= Step 5 \n");
+										ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_RELAY;
+									}
+
+									for(int i = 0; i < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; i++)
+									{
+										PRINTF_FUNC("*********_REASSIGNED_ADJUST : groupIndex = %d, outputCur = %d, outputVol = %d \n",
+											groupIndex,
+										ShmPsuData->PsuGroup[groupIndex].PsuModule[i].PresentOutputCurrent,
+										ShmPsuData->PsuGroup[groupIndex].PsuModule[i].PresentOutputVoltage);
+									}
+								}
+
+								// 該充電槍的目標電壓與目標電流
+								SetPresentOutput(groupIndex, NONE_CARE_ADDRESS,
+										chargingInfo[groupIndex]->EvBatterytargetVoltage,
+										chargingInfo[groupIndex]->EvBatterytargetCurrent,
+										chargingInfo[groupIndex]->DeratingChargingCurrent);
+								usleep(cmdDelayTime);
+							}
+							else
+							{
+								// 該充電槍的目標電壓與目標電流
+								SetPresentOutput(groupIndex, NONE_CARE_ADDRESS,
+										chargingInfo[groupIndex]->EvBatterytargetVoltage,
+										chargingInfo[groupIndex]->EvBatterytargetCurrent,
+										chargingInfo[groupIndex]->AvailableChargingCurrent);
+								usleep(cmdDelayTime);
+							}
+						}
+
+						if (chargingInfo[groupIndex]->EvBatterytargetVoltage == 0)
+						{
+							EnableOutputPower(groupIndex, NONE_CARE_ADDRESS, SWITCH_OFF);
+							usleep(cmdDelayTime);
+							EnableGreenLedFlash(groupIndex , NONE_CARE_ADDRESS , SWITCH_OFF);
+							usleep(cmdDelayTime);
+						}
+						else
+						{
+							EnableOutputPower(groupIndex, NONE_CARE_ADDRESS, SWITCH_ON);
+							usleep(cmdDelayTime);
+							EnableGreenLedFlash(groupIndex , NONE_CARE_ADDRESS, SWITCH_ON);
+							usleep(cmdDelayTime);
+						}
+					}
+					else if (chargingInfo[groupIndex]->SystemStatus >= S_TERMINATING &&
+							chargingInfo[groupIndex]->SystemStatus <= S_COMPLETE)
+					{
+						SetPresentOutput(groupIndex, NONE_CARE_ADDRESS, ZERO_VOL, ZERO_CUR, chargingInfo[groupIndex]->AvailableChargingCurrent);
+						usleep(cmdDelayTime);
+						EnableGreenLedFlash(groupIndex , NONE_CARE_ADDRESS , SWITCH_OFF);
+						usleep(cmdDelayTime);
+						EnableOutputPower(groupIndex, NONE_CARE_ADDRESS, SWITCH_OFF);
+						usleep(cmdDelayTime);
+					}
+				}
+				priorityLow >= 200 ? priorityLow = 1 : priorityLow++;
+				break;
+			}
+		}
+	}
+	return FAIL;
+}

+ 12 - 4
EVSE/Projects/DS60-120/Apps/Module_PsuComm.h

@@ -32,15 +32,22 @@
 #include	"../../define.h"
 #include 	<stdbool.h>
 
+
 typedef unsigned char 		byte;
+typedef unsigned short 		word;
+typedef unsigned int 		unit;
 
 #define SELF_TEST_VOL				1600
 #define SELF_TEST_CUR				10
 #define ZERO_VOL					0
 #define ZERO_CUR					0
 #define NONE_CARE_ADDRESS			0
-#define OUTPUT_POWER_SWITCH_ON		2
-#define OUTPUT_POWER_SWITCH_OFF		0
+#define SWITCH_ON		2
+#define SWITCH_OFF		0
+
+
+#define SET_MODULE_CMD              0
+#define SET_GROUP_CMD              1
 
 enum _FIRMWARE_TYPE
 {
@@ -67,6 +74,7 @@ struct timeval _chk_output_time;
 bool isCheckOutputTimeStart = false;
 
 byte _curCheckPsuIndexForFireLine = 0x00;
+struct _RecordPsuData recordPsuData[PSU_QUANTITY];
 
 struct timeval _chk_cap_time;
 bool _chkTotalCapStart = false;
@@ -77,7 +85,7 @@ struct timeval _workModePriority_time;
 struct timeval _derating_time;
 int deratingTime = 0;
 
-int connector_1[] = {1, 2};
-int connector_2[] = {3, 4};
+int connector_1[] = {0};
+int connector_2[] = {1};
 int conn_1_count = 0;
 int conn_2_count = 0;

+ 35 - 4
EVSE/Projects/DS60-120/Apps/PrimaryComm.c

@@ -33,7 +33,7 @@
 #define FAIL				-1
 
 struct Address Addr={0x01,0x02,0x03,0x04,0xFF};
-struct Command Cmd={0x01,0x02,0x0a,0x86,0xe0,0xe1,0xe2,0xe3};
+struct Command Cmd={0x01,0x02,0x0a,0x86,0x87,0xe0,0xe1,0xe2,0xe3};
 
 int tranceive(int fd, unsigned char* cmd, unsigned char cmd_len, unsigned char* rx)
 {
@@ -197,6 +197,40 @@ unsigned char Config_Gpio_Output(unsigned char fd, unsigned char targetAddr, Gpi
 	return result;
 }
 
+unsigned char Config_Rtc_Data(unsigned char fd, unsigned char targetAddr, Rtc *Set_Buf)
+{
+	unsigned char result = FAIL;
+	unsigned char tx[21] = { 0xaa, 0x00, targetAddr, Cmd.config_Rtc_Data, 0x0E, 0x00, Set_Buf->RtcData[0], Set_Buf->RtcData[1],
+			Set_Buf->RtcData[2], Set_Buf->RtcData[3], Set_Buf->RtcData[4], Set_Buf->RtcData[5], Set_Buf->RtcData[6], Set_Buf->RtcData[7],
+			Set_Buf->RtcData[8], Set_Buf->RtcData[9], Set_Buf->RtcData[10], Set_Buf->RtcData[11], Set_Buf->RtcData[12], Set_Buf->RtcData[13]};
+	unsigned char rx[512];
+	unsigned char chksum = 0x00;
+
+	for (int idx = 0; idx < (tx[4] | tx[5] << 8); idx++)
+		chksum ^= tx[6 + idx];
+	tx[20] = chksum;
+
+	if (tranceive(fd, tx, sizeof(tx), rx) > 0)
+	{
+		chksum = 0x00;
+		for (int idx = 0; idx < (rx[4] | rx[5] << 8); idx++)
+		{
+			chksum ^= rx[6 + idx];
+		}
+
+		if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
+				(rx[2] == tx[1]) &&
+				(rx[1] == tx[2]) &&
+				(rx[3] == tx[3]) &&
+				(rx[6] == tx[6]))
+		{
+			result = PASS;
+		}
+	}
+
+	return result;
+}
+
 unsigned char Update_Start(unsigned char fd, unsigned char targetAddr, unsigned int crc32)
 {
 	unsigned char result = FAIL;
@@ -211,9 +245,6 @@ unsigned char Update_Start(unsigned char fd, unsigned char targetAddr, unsigned
 
 	if(tranceive(fd, tx, sizeof(tx), rx) > 0)
 	{
-		for(int rr = 0; rr < 8; rr++)
-			printf("rx = %x \n", rx[rr]);
-
 		chksum = 0x00;
 		for(int idx=0;idx<(rx[4] | rx[5]<<8);idx++)
 		{

+ 3 - 4
EVSE/Projects/DS60-120/Apps/PrimaryComm.h

@@ -17,6 +17,7 @@ extern struct Command
 	unsigned char query_Gpio_In;		//0x0a
 
 	unsigned char config_Gpio_Output;	//0x86
+	unsigned char config_Rtc_Data;		//0x87
 
 	unsigned char update_Start;		//0xe0
 	unsigned char update_Abort;		//0xe1
@@ -56,10 +57,7 @@ typedef struct GPIO_OUT
 
 typedef struct RTC
 {
-	unsigned char AC_Connector;
-	unsigned char Button_LED[2];
-	unsigned char System_LED[4];
-	unsigned char AC_Breaker;
+	unsigned char RtcData[14];
 }Rtc;
 
 extern unsigned char Query_FW_Ver(unsigned char fd, unsigned char targetAddr, Ver *Ret_Buf);
@@ -67,6 +65,7 @@ extern unsigned char Query_HW_Ver(unsigned char fd, unsigned char targetAddr, Ve
 extern unsigned char Query_Gpio_Input(unsigned char fd, unsigned char targetAddr, Gpio_in *Ret_Buf);
 
 extern unsigned char Config_Gpio_Output(unsigned char fd, unsigned char targetAddr, Gpio_out *Set_Buf);
+extern unsigned char Config_Rtc_Data(unsigned char fd, unsigned char targetAddr, Rtc *Set_Buf);
 // 13 bytes
 // year : 4, month : 2, day : 2, hour : 2, min : 2, sec : 2
 //extern unsigned char Config_RTC();

+ 316 - 14
EVSE/Projects/DS60-120/Apps/ReadCmdline.c

@@ -43,6 +43,10 @@ typedef unsigned char			byte;
 #define FAIL				-1
 #define ARRAY_SIZE(A)		(sizeof(A) / sizeof(A[0]))
 
+#define TTY_PATH            "/dev/tty"
+#define STTY_US             "stty raw -echo -F "
+#define STTY_DEF            "stty -raw echo -F "
+
 struct SysConfigAndInfo			*ShmSysConfigAndInfo;
 struct StatusCodeData 			*ShmStatusCodeData;
 struct PrimaryMcuData			*ShmPrimaryMcuData;
@@ -188,7 +192,7 @@ void RunStatusProc(char *v1, char *v2)
 	if (strcmp(v2, "-1") == 0 || strcmp(v2, "") == 0)
 	{
 		// get
-		printf ("index = %x, status = %x\n", _index, _chargingData[_index]->SystemStatus);
+		printf ("index = %x, status = %x (%d)\n", _index, _chargingData[_index]->SystemStatus, _chargingData[_index]->IsAvailable);
 	}
 	else
 	{
@@ -337,24 +341,308 @@ void GetGunSelectedNum(char *v1)
 	}
 }
 
-void ChangeToSpMode()
+void SetFanSpeed(char *v1)
 {
-	unsigned char _index = 0;
-	if (gunCount <= 0)
-		return;
+	int speed = atoi(v1);
 
-	for (int i = 0; i < gunCount; i++)
-	{
-		_chargingData[i]->SystemStatus = 20;
-	}
+	ShmFanModuleData->TestFanSpeed = speed;
+}
 
-	if (!FindChargingInfoData(_index, &_chargingData[0]))
+static int get_char()
+{
+    fd_set rfds;
+    struct timeval tv;
+    int ch = 0;
+
+    FD_ZERO(&rfds);
+    FD_SET(0, &rfds);
+    tv.tv_sec = 0;
+    tv.tv_usec = 10; //wait input timout time
+
+    //if input
+    if (select(1, &rfds, NULL, NULL, &tv) > 0)
+    {
+        ch = getchar();
+    }
+
+    return ch;
+}
+
+void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
+{
+	int _GunIndex = atoi(v1);
+	int _Voltage = atoi(v2);
+	int _Current = atoi(v3);
+	unsigned char PreviousSystemStatus = 0xff;
+	int ch = 0;
+
+	if (!FindChargingInfoData(_GunIndex, &_chargingData[0]))
 	{
 		printf ("FindChargingInfoData error\n");
 		return;
 	}
 
-	_chargingData[_index]->SystemStatus = 19;
+    printf ("ReqVoltage = %d, ReqCurrent = %d\n", _Voltage,_Current);
+
+    if(_Voltage > 1000 || _Voltage < 150){
+
+        printf ("Input Voltage over range\n");
+        return;
+    }
+
+//    if(_Current > 100 || _Current < 2){
+//
+//        printf ("Input Current over range\n");
+//        return;
+//    }
+
+    //測試期間先跳過自我測試 _STEST_COMPLETE = 0xfe
+    //ShmSysConfigAndInfo->SysInfo.SelfTestSeq = 0xfe;
+
+    //kill ev task
+    system("killall Module_EvComm");
+
+    _Voltage = (_Voltage * 10);
+    _Current = (_Current * 10);
+
+    //system(STTY_US TTY_PATH);
+
+    while(true)
+    {
+        //fix gun 1
+        ShmSysConfigAndInfo->SysInfo.CurGunSelected = _GunIndex;
+
+    	switch(_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus)
+    	{
+            case S_IDLE:
+    		{
+        	    if(PreviousSystemStatus != _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus)
+        	    {
+        	        PreviousSystemStatus = _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus;
+
+        	        printf ("[UnconditionalCharge - S_IDLE]\n");
+
+        	    }
+
+                _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_PREPARNING;
+    		}
+    		break;
+
+
+    		case S_PREPARNING:
+    		{
+        	    if(PreviousSystemStatus != _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus)
+        	    {
+        	        PreviousSystemStatus = _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus;
+
+        	        printf ("[UnconditionalCharge - S_PREPARNIN]\n");
+
+        	        //等待 AC Relay 搭上且找到模組 (main 在此 statue 其它 task 會去做完)
+        	        printf ("wait find module\n");
+
+        	    }
+    		    //main 會在此階段判斷以下資料跳到下一個 state
+    		    //用來得知 AC 是否有搭上 (搭上模組的資訊才會出來) 因為每次  AC_Contactor
+
+
+    		    //ShmPsuData->SystemPresentPsuQuantity;
+    		    //ShmPsuData->PsuGroup[gun_index].GroupPresentPsuQuantity;
+    		    //ShmPsuData->PsuGroup[gun_index].GroupAvailablePower;
+    		    //_chargingData[gun_index]->AvailableChargingPower;
+
+    		    //等待 AC Relay 搭上且找到模組 (main 在此 statue 其它 task 會去做完)
+    		    //sleep(10);
+
+    		    //清除 main timeout 機制
+    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->TimeoutFlag = 0;
+    		    //不論是什麼 type 的槍都固意設成 Chademo 不跑 Prechage step
+    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->Type = 9;
+
+    		}
+    		break;
+
+    		case S_PREPARING_FOR_EV:
+    		{
+        	    if(PreviousSystemStatus != _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus)
+        	    {
+        	        PreviousSystemStatus = _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus;
+
+        	        printf ("[UnconditionalCharge - S_PREPARING_FOR_EV]\n");
+        	        printf ("ReqVoltage = %d, ReqCurrent = %d\n", _Voltage,_Current);
+
+        	    }
+    		    //清除 main timeout 機制
+    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->TimeoutFlag = 0;
+    		    //不論是什麼 type 的槍都固意設成 Chademo 不跑 Prechage step
+    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->Type = 9;
+
+    		    //充電電壓電流
+    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterySoc = 50;
+   		        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetVoltage = 5000;
+    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetCurrent = 20;
+    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->AvailableChargingCurrent = 1000;
+
+    		    //****** 注意~此行為是防止 K1K2 先開導到無法升壓 ( Relay Board 在此 state 還未搭上 K1K2 )
+    		    //確定模組己升壓完成
+    		    //if(_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingVoltage <=  (3000+500) &&
+    		    //  _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingVoltage >=  (3000-500) )
+    		    {
+    		        printf ("Precharge Done = %f \n", _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingVoltage);
+    		        //EV done
+    		        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_PREPARING_FOR_EVSE;
+    		    }
+
+    		}
+    		break;
+
+
+    		case S_PREPARING_FOR_EVSE:
+    		{
+        	    if(PreviousSystemStatus != _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus)
+        	    {
+        	        PreviousSystemStatus = _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus;
+
+        	        printf ("[UnconditionalCharge - S_PREPARING_FOR_EVSE]\n");
+
+        	    }
+        	    //printf ("tar vol = %d \n", _Voltage);
+        	    //printf ("tar cur = %d \n", _Current);
+
+    		    //清除 main timeout 機制
+    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->TimeoutFlag = 0;
+    		    //不論是什麼 type 的槍都固意設成 Chademo 不跑 Prechage step
+    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->Type = 9;
+
+    		    //充電電壓電流
+    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterySoc = 50;
+    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetVoltage = 5000;
+    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetCurrent = 20;
+    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->AvailableChargingCurrent = 1000;
+
+    		    //printf ("tar vol_ = %d \n", _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetVoltage);
+        	   // printf ("tar cur_ = %d \n", _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetCurrent);
+
+    		    //****** 注意~此行為是防止 K1K2 先開導到無法升壓 ( Relay Board 在此 state 還未搭上 K1K2 )
+    		    //確定模組己升壓完成
+    		    if(_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus == 0x01 ||
+    		        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus == 0x03)
+    		    {
+    		        printf ("First Ground Fault State (%d)\n",_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus);
+    		        printf ("Wait K1K2 = %f \n", _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingVoltage);
+    		        sleep(3);
+    		        //EV done
+    		        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_CHARGING;
+    		    }
+    		    else if (_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus > 0x02)
+    		    {
+    		             printf ("First Ground Fault check Fail (%d)\n",_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus);
+    		            _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_TERMINATING;
+    		    }
+
+    		}
+    		break;
+
+    		case S_CHARGING:
+    		{
+        	    if(PreviousSystemStatus != _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus)
+        	    {
+        	        PreviousSystemStatus = _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus;
+
+        	        printf ("[UnconditionalCharge - S_CHARGING]\n");
+
+        	    }
+    		    //充電電壓電流
+    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterySoc = 50;
+    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetVoltage = _Voltage;
+    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetCurrent = _Current;
+    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->AvailableChargingCurrent = 1000;
+
+    		    //ev task do this
+    		    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingPower = ((float)((_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingVoltage / 10) * (_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingCurrent / 10)) / 1000);
+
+    		    if (_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus == 0x02){
+    		         printf ("Charging Ground Fault check Fail (%d)\n",_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus);
+    		        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_TERMINATING;
+    		    }
+
+    		    if (_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus == 0x03){
+    		         printf ("Charging Ground Fault Warning (%d)\n",_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus);
+    		        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_TERMINATING;
+    		    }
+
+    		}
+    		break;
+
+     		case S_TERMINATING:
+    		{
+        	    if(PreviousSystemStatus != _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus)
+        	    {
+        	        PreviousSystemStatus = _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus;
+        	        system("/root/Module_EvComm &");
+
+        	        printf ("[UnconditionalCharge - S_TERMINATING]\n");
+        	        //無阻塞偵測 keybaord 結束
+        	        system(STTY_DEF TTY_PATH);
+
+        	    }
+
+        	    sleep(3);
+        	    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_COMPLETE;
+        	    return;
+    		}
+    		break;
+
+    		case S_COMPLETE:
+    		{
+        	    if(PreviousSystemStatus != _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus)
+        	    {
+        	        PreviousSystemStatus = _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus;
+
+        	        printf ("[UnconditionalCharge - S_COMPLETE]\n");
+
+        	    }
+        	    sleep(3);
+        	    return;
+    		}
+    		break;
+    	}
+
+    	/*
+    	//使用 Keyboard input 阻塞方法
+        fgets(InputChar, sizeof(InputChar), stdin);
+
+        if (InputChar[0] == 's' && InputChar[1] == 't' && InputChar[2] == 'o' && InputChar[3] == 'p')
+        {
+           printf ("Precharge Done\n");
+           _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_TERMINATING;
+
+        }
+        */
+
+        //使用 keybaord input 非阻塞方法
+        ch = get_char();
+        if (ch)
+        {
+            printf("%c \n\r", ch);
+
+            switch (ch)
+            {
+                //Ctrl + C
+                case 3:
+                    //system(STTY_DEF TTY_PATH);
+                        return;
+                //input c or C
+                case 'c':
+                case 'C':
+                    printf("stop \n\r");
+                    //system(STTY_DEF TTY_PATH);
+                    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_TERMINATING;
+                    break;
+            }
+        }
+
+    }
+
 }
 
 int main(void)
@@ -483,12 +771,26 @@ int main(void)
 			GetGunSelectedNum(newString[1]);
 			continue;
 		}
-		else if(strcmp(newString[0], "spmode") == 0)
+		else if(strcmp(newString[0], "fan") == 0)
 		{
-			// 改變系統模式到特殊測試模式
-			//ChangeToSpMode();
+			// 設定風扇速度
+			SetFanSpeed(newString[1]);
 			continue;
 		}
+		else if(strcmp(newString[0], "strchg") == 0)
+		{
+			//如果連一個參數都沒有 (此命令不理會) 加上判斷第二參數
+			if (strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0 || strcmp(newString[2], "-1") == 0 || strcmp(newString[2], "") == 0)
+			{
+				printf ("Input cmd fail ------  strchg [vol 150-1000] [cru 2-100]\n");
+				continue;
+			}
+
+			// 槍狀態
+			RunUnconditionalChargeIndex1(newString[1], newString[2], newString[3]);
+			continue;
+		}
+
 		printf ("%s\n", msg);
 		usleep(100000);
 	}

+ 1 - 0
EVSE/Projects/DS60-120/Apps/init.sh

@@ -5,6 +5,7 @@ chmod 777 Module_InternalComm
 chmod 777 Module_EventLogging
 chmod 777 Module_EvComm
 chmod 777 Module_PsuComm
+chmod 777 OcppBackend
 chmod 777 kill.sh
 chmod 777 ReadCmdline
 

+ 51 - 9
EVSE/Projects/DS60-120/Apps/internalComm.c

@@ -39,7 +39,7 @@
 #define FAIL				-1
 
 struct Address Addr={0x01,0x02,0x03,0xFF};
-struct Command Cmd={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x81,0x83,0x85,0x86,0x87,0xe0,0xe1,0xe2,0xe3};
+struct Command Cmd={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x81,0x83,0x85,0x86, 0x87,0x8B,0xe0,0xe1,0xe2,0xe3};
 
 int tranceive(int fd, unsigned char* cmd, unsigned char cmd_len, unsigned char* rx)
 {
@@ -205,10 +205,10 @@ unsigned char Query_Fan_Speed(unsigned char fd, unsigned char targetAddr, FanSpe
 	unsigned char chksum = 0x00;
 	unsigned char len = tranceive(fd, tx, sizeof(tx), rx);
 
-		for (int i = 0; i < 7; i++)
-			printf("tx = %x \n", tx[i]);
-		for (int i = 0; i < len; i++)
-			printf("rx = %x \n", rx[i]);
+//		for (int i = 0; i < 7; i++)
+//			printf("tx = %x \n", tx[i]);
+//		for (int i = 0; i < len; i++)
+//			printf("rx = %x \n", rx[i]);
 
 	if(len > 6)
 	{
@@ -361,7 +361,7 @@ unsigned char Query_Gfd_Adc(unsigned char fd, unsigned char targetAddr, Gfd *Ret
 	{
 		if (len < 6+(rx[4] | rx[5]<<8))
 		{
-			printf("Query_Gfd_Adc fail \n");
+			//printf("Query_Gfd_Adc fail \n");
 			return result;
 		}
 
@@ -454,7 +454,12 @@ unsigned char Config_Fan_Speed(unsigned char fd, unsigned char targetAddr, FanSp
 		chksum ^= tx[6+idx];
 	tx[14] = chksum;
 
+//		for(int i = 0; i < 15; i++)
+//			printf ("tx = %x \n", tx[i]);
+
 	unsigned char len = tranceive(fd, tx, sizeof(tx), rx);
+//	for(int i = 0; i < len; i++)
+//				printf ("rx = %x \n", rx[i]);
 	if(len > 6)
 	{
 		if (len < 6+(rx[4] | rx[5]<<8))
@@ -485,8 +490,8 @@ unsigned char Config_Relay_Output(unsigned char fd, unsigned char targetAddr, Re
 	unsigned char rx[512];
 	unsigned char chksum = 0x00;
 
-	for(int idx = 6;idx<8;idx++)
-		chksum ^= tx[idx];
+	for(int idx = 0;idx<(tx[4] | tx[5]<<8);idx++)
+		chksum ^= tx[6 + idx];
 	tx[9] = chksum;
 
 //	for (int i = 0; i < 10; i++)
@@ -620,8 +625,11 @@ unsigned char Config_Model_Name(unsigned char fd, unsigned char targetAddr, unsi
 		chksum ^= tx[6+idx];
 	tx[20] = chksum;
 
+//	for(int i = 0; i < 21; i++)
+//				printf ("tx = %x \n", tx[i]);
 	unsigned char len = tranceive(fd, tx, sizeof(tx), rx);
-
+//	for(int i = 0; i < len; i++)
+//					printf ("rx = %x \n", rx[i]);
 	if(len > 6)
 	{
 		if (len < 6+(rx[4] | rx[5]<<8))
@@ -646,6 +654,40 @@ unsigned char Config_Model_Name(unsigned char fd, unsigned char targetAddr, unsi
 	return result;
 }
 
+unsigned char Config_Rtc_Data(unsigned char fd, unsigned char targetAddr, Rtc *Set_Buf)
+{
+	unsigned char result = FAIL;
+	unsigned char tx[21] = { 0xaa, 0x00, targetAddr, Cmd.config_Rtc_Data, 0x0E, 0x00, Set_Buf->RtcData[0], Set_Buf->RtcData[1],
+			Set_Buf->RtcData[2], Set_Buf->RtcData[3], Set_Buf->RtcData[4], Set_Buf->RtcData[5], Set_Buf->RtcData[6], Set_Buf->RtcData[7],
+			Set_Buf->RtcData[8], Set_Buf->RtcData[9], Set_Buf->RtcData[10], Set_Buf->RtcData[11], Set_Buf->RtcData[12], Set_Buf->RtcData[13]};
+	unsigned char rx[512];
+	unsigned char chksum = 0x00;
+
+	for (int idx = 0; idx < (tx[4] | tx[5] << 8); idx++)
+		chksum ^= tx[6 + idx];
+	tx[20] = chksum;
+
+	if (tranceive(fd, tx, sizeof(tx), rx) > 0)
+	{
+		chksum = 0x00;
+		for (int idx = 0; idx < (rx[4] | rx[5] << 8); idx++)
+		{
+			chksum ^= rx[6 + idx];
+		}
+
+		if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
+				(rx[2] == tx[1]) &&
+				(rx[1] == tx[2]) &&
+				(rx[3] == tx[3]) &&
+				(rx[6] == tx[6]))
+		{
+			result = PASS;
+		}
+	}
+
+	return result;
+}
+
 unsigned char Update_Start(unsigned char fd, unsigned char targetAddr, unsigned int crc32)
 {
 	unsigned char result = FAIL;

+ 8 - 1
EVSE/Projects/DS60-120/Apps/internalComm.h

@@ -33,7 +33,8 @@ extern struct Command
 	unsigned char config_Model_Name;			//0x83
 	unsigned char config_Relay_Output;			//0x85
 	unsigned char config_Gpio_Output;			//0x86
-	unsigned char config_Gfd_Value;			//0x87
+	unsigned char config_Rtc_Data;				//0x87
+	unsigned char config_Gfd_Value;			//0x8B
 
 	unsigned char update_Start;				//0xe0
 	unsigned char update_Abort;				//0xe1
@@ -162,6 +163,11 @@ typedef struct GPIO_OUT
 	unsigned char System_LED[4];
 }Gpio_out;
 
+typedef struct RTC
+{
+	unsigned char RtcData[14];
+}Rtc;
+
 extern unsigned char Query_FW_Ver(unsigned char fd, unsigned char targetAddr, Ver *Ret_Buf);
 extern unsigned char Query_HW_Ver(unsigned char fd, unsigned char targetAddr, Ver *Ret_Buf);
 extern unsigned char Query_Present_InputVoltage(unsigned char fd, unsigned char targetAddr, PresentInputVoltage *Ret_Buf);
@@ -178,6 +184,7 @@ extern unsigned char Config_Relay_Output(unsigned char fd, unsigned char targetA
 extern unsigned char Config_Gpio_Output(unsigned char fd, unsigned char targetAddr, Gpio_out *Set_Buf);
 extern unsigned char Config_Gfd_Value(unsigned char fd, unsigned char targetAddr, Gfd_config *Set_Buf);
 extern unsigned char Config_Model_Name(unsigned char fd, unsigned char targetAddr, unsigned char *modelname);
+extern unsigned char Config_Rtc_Data(unsigned char fd, unsigned char targetAddr, Rtc *Set_Buf);
 
 extern unsigned char Update_Start(unsigned char fd, unsigned char targetAddr, unsigned int crc32);
 extern unsigned char Update_Abord(unsigned char fd, unsigned char targetAddr);

+ 9 - 7
EVSE/Projects/DS60-120/Apps/kill.sh

@@ -1,8 +1,10 @@
-killall Module_CSU
-killall Module_PrimaryComm
-killall Module_LcmControl
-killall Module_InternalComm
-killall Module_EventLogging
-killall Module_EvComm
-killall Module_PsuComm
+pkill Module_CSU
+pkill Module_PrimaryComm
+pkill Module_LcmControl
+pkill Module_InternalComm
+pkill Module_EventLogging
+pkill Module_EvComm
+pkill Module_PsuComm
+pkill OcppBackend
+pkill main
 

File diff suppressed because it is too large
+ 409 - 199
EVSE/Projects/DS60-120/Apps/main.c


+ 12 - 11
EVSE/Projects/DS60-120/Apps/timeout.h

@@ -34,19 +34,20 @@
 
 enum Timeout_flag
 {
-	Timeout_None =					0,
-	Timeout_SelftestChk = 			1,
-	Timeout_Authorizing = 			2,
-	Timeout_VerifyFail = 			3,
-	Timeout_VerifyComp = 			4,
-	Timeout_WaitPlug = 				5,
+	Timeout_None =						0,
+	Timeout_SelftestChk = 				1,
+	Timeout_Authorizing = 				2,
+	Timeout_VerifyFail = 				3,
+	Timeout_VerifyComp = 				4,
+	Timeout_WaitPlug = 					5,
 
-	Timeout_Preparing = 			6,
-	Timeout_EvChargingDet = 		7,
-	Timeout_EvseChargingDet = 		8,
-	Timeout_WaitforCompleteDet = 	9,
+	Timeout_Preparing = 				6,
+	Timeout_EvChargingDet = 			7,
+	Timeout_EvseChargingDet = 			8,
+	Timeout_WaitforCompleteDet = 		9,
 
-	Timeout_ForCcsPrechargeDet = 	10,
+	Timeout_ForCcsPrechargeDet = 		10,
+	Timeout_ReturnToChargingGunDet = 	11
 };
 
 #endif /* TIMEOUT_H_ */

+ 1 - 2
EVSE/Projects/define.h

@@ -40,7 +40,7 @@ Storage							0x0A200000-0x7FFFFFFF		1886 MB
 #define CHAdeMO_QUANTITY	1
 #define CCS_QUANTITY		1
 #define GB_QUANTITY		0
-#define AC_QUANTITY		1	
+#define AC_QUANTITY		0	
 #define PSU_QUANTITY		2
 #define ONE_CONNECTOR_USE	0
 
@@ -254,7 +254,6 @@ struct ChargingInfoData
 	unsigned char		SystemStatus;				//0: Booting, 1: idle, 2: authorizing, 3: preparing, 4: charging, 5: terminating, 6: alarm, 7: fault
 	unsigned char		PreviousSystemStatus;		// 0: Booting, 1: idle, 2: authorizing, 3: preparing, 4: charging, 5: terminating, 6: alarm, 7: fault	
 	int 			ReservationId;
-	unsigned char 		CardNumber[32];
 	unsigned char 		IsAvailable;
 	float MaximumChargingVoltage;	//0~6553.5 volt
 	float AvailableChargingCurrent;	//0~6553.5 amp

Some files were not shown because too many files changed in this diff