瀏覽代碼

Merge branch 'DO360'

FolusWen 4 年之前
父節點
當前提交
c1249a7f73

+ 1 - 1
EVSE/Projects/DO360/Apps/FactoryConfig.c

@@ -129,7 +129,7 @@ int main(int argc,char *argv[])
 	SysConfig.isRFID = 1;
 	//********** Charging **********//
 	SysConfig.MaxChargingEnergy = 0;
-	SysConfig.MaxChargingCurrent = 200;		// 最大可輸出電流 (整樁)
+	SysConfig.MaxChargingCurrent = 0;		// 最大可輸出電流 (整樁)
 	SysConfig.MaxChargingDuration = 0;
 	SysConfig.AcMaxChargingCurrent = 0;
 	SysConfig.PhaseLossPolicy = 0;

+ 194 - 27
EVSE/Projects/DO360/Apps/Module_EvComm.c

@@ -879,7 +879,7 @@ BOOL IsAvalibleGunType(char name, unsigned char *type)
 	return false;
 }
 
-unsigned char ConnectorQuantityTypeParsing(unsigned char *modelName, unsigned char *type)
+unsigned char ConnectorQuantityTypeParsing(unsigned char *modelName, unsigned char *type, unsigned char *physical)
 {
 	unsigned char quantity = 0;
 
@@ -887,6 +887,7 @@ unsigned char ConnectorQuantityTypeParsing(unsigned char *modelName, unsigned ch
 	{
 		if(IsAvalibleGunType(modelName[7 + i], &type[quantity]))
 		{
+		    physical[quantity] = modelName[7 + i];
 			if(quantity < 2)
 			{
 				quantity++;
@@ -978,6 +979,33 @@ void DispenserStatusResponse(int socket, struct PACKET_STRUCTURE *packet, unsign
 
 struct ChargingCapabilityResponse ConnectorCapability[GENERAL_GUN_QUANTITY];
 
+void GetPhysicalLimitVoltageAndCurrent(byte index, unsigned short *voltage, unsigned short *currrent)
+{
+    if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].RemoteMaxPhysicalVoltage != 0 &&
+        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].RemoteMaxPhysicalVoltage <= *voltage)
+    {
+        *voltage = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].RemoteMaxPhysicalVoltage;
+    }
+
+    if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].RemoteMaxPhysicalCurrent != 0 &&
+        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].RemoteMaxPhysicalCurrent <= *currrent)
+    {
+        *currrent = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].RemoteMaxPhysicalCurrent;
+    }
+}
+
+void GetConfigLimitVoltageAndCurrent(byte index, unsigned short *voltage, unsigned short *currrent)
+{
+    unsigned short limitCurrent = ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX ?
+            (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].MaxTotalChargingCurrent) :
+            (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].MaxTotalChargingCurrent / 2);
+
+    if(limitCurrent != 0 && limitCurrent <= *currrent)
+    {
+        *currrent = limitCurrent;
+    }
+}
+
 void ChargingCapabilityResponse(int socket, struct PACKET_STRUCTURE *packet)
 {
 	struct PACKET_STRUCTURE sendBuffer;
@@ -990,6 +1018,9 @@ void ChargingCapabilityResponse(int socket, struct PACKET_STRUCTURE *packet)
 	current = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.AvailableChargingCurrent;
 	power = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.AvailableChargingPower;
 
+	GetPhysicalLimitVoltageAndCurrent(packet->Header.id - 1, &voltage, &current);
+	GetConfigLimitVoltageAndCurrent(packet->Header.id - 1, &voltage, &current);
+
 	currency = ShmSysConfigAndInfo->SysInfo.DispenserInfo.Currency;
 	price = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].UserPrice;
 	cost = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].TotalCost;
@@ -1062,7 +1093,7 @@ void ChargingTargetResponse(int socket, struct PACKET_STRUCTURE *packet, unsigne
 	send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
 }
 
-void FirmwareUpgradeResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char result)
+void FirmwareUpgradeResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char dispenserIndex, unsigned char result)
 {
     struct PACKET_STRUCTURE sendBuffer;
 
@@ -1070,11 +1101,18 @@ void FirmwareUpgradeResponse(int socket, struct PACKET_STRUCTURE *packet, unsign
     sendBuffer.Header.se = packet->Header.se;
     sendBuffer.Header.id = packet->Header.id;
     sendBuffer.Header.op = _Header_Response;
-    sendBuffer.Header.len = 2;
+    sendBuffer.Header.len = 3;
     sendBuffer.Payload.reg = _Reg_Software_Update;
     sendBuffer.Payload.data[0] = _R_OK;
     sendBuffer.Payload.data[1] = result;
 
+    if(result == _R_NeedUpgrade)
+    {
+        int length = strlen(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].FwFileName);
+        memcpy(&sendBuffer.Payload.data[2], ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].FwFileName, length);
+        sendBuffer.Header.len += length;
+    }
+
     send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
 }
 
@@ -1369,7 +1407,43 @@ BOOL FindConnectorID(unsigned char dispenserIndex, unsigned char id)
 	return find;
 }
 
-void ConnectorTypeBindingHandler(unsigned char dispenserIndex, unsigned char *type)
+void ConnectorPhysicalLimitBindingHandler(unsigned char connectorIndex, unsigned char physical)
+{
+    //char modelList[6] = {'J', 'U', 'E', 'G', 'V', 'F'};
+    //unsigned char typeList[6] = {0, 1, 1, 2, 1, 1};     // 0 : Chademo, 1: CCS, 2: GB
+
+    switch(physical)
+    {
+        case 'J':
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[connectorIndex].RemoteMaxPhysicalVoltage = CHA_MAX_PHYSICAL_VOLTAGE;
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[connectorIndex].RemoteMaxPhysicalCurrent = CHA_NATURAL_MAX_CURRENT;
+            break;
+
+        case 'U':
+        case 'E':
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[connectorIndex].RemoteMaxPhysicalVoltage = CCS_MAX_PHYSICAL_VOLTAGE;
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[connectorIndex].RemoteMaxPhysicalCurrent = CCS_NATURAL_MAX_CURRENT;
+            break;
+
+        case 'G':
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[connectorIndex].RemoteMaxPhysicalVoltage = GBT_MAX_PHYSICAL_VOLTAGE;
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[connectorIndex].RemoteMaxPhysicalCurrent = GBT_NATURAL_MAX_CURRENT;
+            break;
+
+        case 'V':
+        case 'F':
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[connectorIndex].RemoteMaxPhysicalVoltage = CCS_MAX_PHYSICAL_VOLTAGE;
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[connectorIndex].RemoteMaxPhysicalCurrent = CCS_LIQUID_MAX_CURRENT;
+            break;
+
+        default:
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[connectorIndex].RemoteMaxPhysicalVoltage = 0;
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[connectorIndex].RemoteMaxPhysicalCurrent = 0;
+            break;
+    }
+}
+
+void ConnectorTypeBindingHandler(unsigned char dispenserIndex, unsigned char *type, unsigned char *physicalType)
 {
     char *str_gun_type[] = {STR_GUN_TYPE_CHADEMO, STR_GUN_TYPE_CCS, STR_GUN_TYPE_GBT};
 
@@ -1379,8 +1453,12 @@ void ConnectorTypeBindingHandler(unsigned char dispenserIndex, unsigned char *ty
 		ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gunIndex].ParentDispensetIndex = dispenserIndex;
 		ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gunIndex].GeneralChargingData.Index = gunIndex;
 		ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gunIndex].GeneralChargingData.Type = type[i];
+        ConnectorPhysicalLimitBindingHandler(gunIndex, physicalType[i]);
 
-		PRINTF_FUNC("Dispenser id %d Connector %d type %s", dispenserIndex + 1, gunIndex + 1, str_gun_type[type[i]]);
+		PRINTF_FUNC("Dispenser %d Connector %d type %s, MaxVol: %4d, MaxCur: %4d",
+            dispenserIndex + 1, gunIndex + 1, str_gun_type[type[i]],
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gunIndex].RemoteMaxPhysicalVoltage,
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gunIndex].RemoteMaxPhysicalCurrent);
 	}
 }
 
@@ -1468,8 +1546,9 @@ BOOL DispenserIdentificationHandler(struct PACKET_STRUCTURE *packet, unsigned ch
 	unsigned char quantity = 0;
 
 	unsigned char connectorType[2] = {0, 0};
+	unsigned char physicalType[2] = {0, 0};
 
-	quantity = ConnectorQuantityTypeParsing(modelName, connectorType);
+	quantity = ConnectorQuantityTypeParsing(modelName, connectorType, physicalType);
 
 	if(quantity > 0)
 	{
@@ -1488,7 +1567,7 @@ BOOL DispenserIdentificationHandler(struct PACKET_STRUCTURE *packet, unsigned ch
 			SetConnectorID(dispenserIndex, quantity);
 			memcpy(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].ModelName, packet->Payload.data, (packet->Header.len - 2));
 
-			ConnectorTypeBindingHandler(dispenserIndex, connectorType);
+			ConnectorTypeBindingHandler(dispenserIndex, connectorType, physicalType);
 
 			PRINTF_FUNC("Dispenser id %d identified, Connector quantity: %d\n", dispenserIndex + 1, quantity);
 
@@ -1588,23 +1667,60 @@ BOOL ConnectorChargingTargetHandler(struct PACKET_STRUCTURE *packet, unsigned ch
 {
 	BOOL find = FindConnectorID(dispenserIndex, packet->Header.id);
 	BOOL done = false;
-	float voltage = 0, current = 0;
+	unsigned short voltage = 0, current = 0;
 
 	if(find)
 	{
-		voltage = (float)((packet->Payload.data[0] << 8) + packet->Payload.data[1]) / 10;
-		current = (float)((packet->Payload.data[2] << 8) + packet->Payload.data[3]) / 10;
+		voltage = ((packet->Payload.data[0] << 8) + packet->Payload.data[1]);
+		current = ((packet->Payload.data[2] << 8) + packet->Payload.data[3]);
+
+		if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteTargetVoltage != voltage ||
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteTargetCurrent != current)
+		{
+		    ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteTargetVoltage = voltage;
+		    ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteTargetCurrent = current;
+		    if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.OutputLimitEnable)
+		    {
+		        PRINTF_FUNC("Connector %d Remote Voltage: %d, Remote Current: %d", packet->Header.id, voltage, current);
+		    }
+		}
+
+		GetPhysicalLimitVoltageAndCurrent(packet->Header.id - 1, &voltage, &current);
+		GetConfigLimitVoltageAndCurrent(packet->Header.id - 1, &voltage, &current);
+
+		if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteTargetVoltage != voltage ||
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteTargetCurrent != current)
+		{
+		    if(!ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.OutputLimitEnable)
+		    {
+		        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.OutputLimitEnable = true;
+		        PRINTF_FUNC("Connector %d Remote Voltage: %d, Remote Current: %d", packet->Header.id,
+                    ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteTargetVoltage,
+                    ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteTargetCurrent);
+		        PRINTF_FUNC("Connector %d Limit Voltage: %d, Limit Current: %d", packet->Header.id, voltage, current);
+		    }
+		}
+		else
+		{
+		    ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.OutputLimitEnable = false;
+		}
+		ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteLimitVoltage = voltage;
+		ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteLimitCurrent = current;
 
 		if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.SystemStatus == S_CHARGING)
 		{
-			if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.EvBatterytargetVoltage != voltage ||
-				ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.EvBatterytargetCurrent != current)
+		    float targetVol = (float)(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteLimitVoltage / 10);
+		    float targetCur = (float)(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteLimitCurrent / 10);
+
+			if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.EvBatterytargetVoltage != targetVol ||
+				ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.EvBatterytargetCurrent != targetCur)
 			{
-				PRINTF_FUNC("Connector %d Target Voltage: %d, Current: %d", packet->Header.id, (int)(voltage * 10), (int)(current * 10));
+				PRINTF_FUNC("Connector %d Target Voltage: %d, Current: %d",
+                    packet->Header.id, (int)(targetVol * 10), (int)(targetCur * 10));
 			}
 
-			ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.EvBatterytargetVoltage = (float)voltage;
-			ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.EvBatterytargetCurrent = (float)current;
+			ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.EvBatterytargetVoltage = targetVol;
+			ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.EvBatterytargetCurrent = targetCur;
 
 			done = true;
 		}
@@ -1629,7 +1745,43 @@ BOOL ConnectorChargingTargetHandler(struct PACKET_STRUCTURE *packet, unsigned ch
 
 unsigned char FirmwareUpgradeHandler(struct PACKET_STRUCTURE *packet, unsigned char dispenserIndex)
 {
-    return _R_NoUpgrade;
+    unsigned char UpgradeResponse = _R_NoUpgrade;
+
+    if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].ConnectorID[0] == packet->Header.id)
+    {
+        if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.FirmwareUpdateRequest)
+        {
+            if(packet->Payload.data[0] == 0)
+            {
+                UpgradeResponse = _R_NeedUpgrade;
+            }
+            else
+            {
+                if(!ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.FirmwareUpdateConfirm)
+                {
+                    ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.FirmwareUpdateConfirm = true;
+                    ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.FirmwareUpdateRequest = false;
+                    PRINTF_FUNC("Dispenser %d Updating...", dispenserIndex + 1);
+                }
+            }
+        }
+        else
+        {
+            if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.FirmwareUpdateConfirm)
+            {
+                if(packet->Payload.data[0] == 0)
+                {
+                    if(!ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.FirmwareUpdateCompleted)
+                    {
+                        ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.FirmwareUpdateCompleted = true;
+                        PRINTF_FUNC("Dispenser %d Upgrade Completed", dispenserIndex + 1);
+                    }
+                }
+            }
+        }
+    }
+
+    return UpgradeResponse;
 }
 
 BOOL ConnectorPlugInHandler(struct PACKET_STRUCTURE *packet, unsigned char dispenserIndex)
@@ -1741,9 +1893,11 @@ unsigned char ChargingPermissionHandler(struct PACKET_STRUCTURE *packet, unsigne
                 else
                 {
                     permission = _DAS_NotAllowed;
-                    PRINTF_FUNC("Cabinet status idle, not allow dispenser id %d connector id %d charging",
-                                        dispenserIndex + 1, packet->Header.id);
-                    PRINTF_FUNC("RemoteStop or UnlockStop, not allow dispenser index %d connector id %d preparing to charge", dispenserIndex, packet->Header.id);
+                    if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.ChargingPermission != permission)
+                    {
+                        PRINTF_FUNC("Cabinet status idle, not allow dispenser %d connector %d charging",
+                            dispenserIndex + 1, packet->Header.id);
+                    }
                 }
                 break;
 
@@ -1752,7 +1906,10 @@ unsigned char ChargingPermissionHandler(struct PACKET_STRUCTURE *packet, unsigne
                     ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.UnlockStopRequest)
                 {
                     permission = _DAS_NotAllowed;
-                    PRINTF_FUNC("RemoteStop or UnlockStop, not allow dispenser index %d connector id %d preparing to charge", dispenserIndex, packet->Header.id);
+                    if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.ChargingPermission != permission)
+                    {
+                        PRINTF_FUNC("RemoteStop or UnlockStop, not allow dispenser index %d connector id %d preparing to charge", dispenserIndex, packet->Header.id);
+                    }
                 }
                 else if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus >= _CRS_Preparing &&
                     ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus <= _CRS_Charging)
@@ -1780,7 +1937,10 @@ unsigned char ChargingPermissionHandler(struct PACKET_STRUCTURE *packet, unsigne
                     ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.UnlockStopRequest)
                 {
                     permission = _DAS_NotAllowed;
-                    PRINTF_FUNC("RemoteStop or UnlockStop, not allow dispenser index %d connector id %d charging", dispenserIndex, packet->Header.id);
+                    if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.ChargingPermission != permission)
+                    {
+                        PRINTF_FUNC("RemoteStop or UnlockStop, not allow dispenser index %d connector id %d charging", dispenserIndex, packet->Header.id);
+                    }
                 }
                 else if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus == _CRS_Preparing ||
                     ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus == _CRS_Charging)
@@ -1790,7 +1950,10 @@ unsigned char ChargingPermissionHandler(struct PACKET_STRUCTURE *packet, unsigne
                 else
                 {
                     permission = _DAS_NotAllowed;
-                    PRINTF_FUNC("Dispenser index %d connector id %d remote status not in charging mode", dispenserIndex, packet->Header.id);
+                    if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.ChargingPermission != permission)
+                    {
+                        PRINTF_FUNC("Dispenser index %d connector id %d remote status not in charging mode", dispenserIndex, packet->Header.id);
+                    }
                 }
                 break;
 
@@ -1800,9 +1963,12 @@ unsigned char ChargingPermissionHandler(struct PACKET_STRUCTURE *packet, unsigne
             case S_RESERVATION:
             case S_MAINTAIN:
                 permission = _DAS_NotAllowed;
-                PRINTF_FUNC("Cabinet status(%d) not match, not allow dispenser index %d connector id %d charging",
-                    ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.SystemStatus,
-                    dispenserIndex, packet->Header.id);
+                if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.ChargingPermission != permission)
+                {
+                    PRINTF_FUNC("Cabinet status(%d) not match, not allow dispenser index %d connector id %d charging",
+                        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.SystemStatus,
+                        dispenserIndex, packet->Header.id);
+                }
                 break;
 
             default:
@@ -1815,6 +1981,8 @@ unsigned char ChargingPermissionHandler(struct PACKET_STRUCTURE *packet, unsigne
 	    permission = _DAS_NotAllowed;
 	}
 
+	ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.ChargingPermission = permission;
+
 //	PRINTF_FUNC("Dispenser %d Permission %s, Gun Status: %d, Connector Status: %d, Wait Plug: %d, PlugIn: %d, Available: %d, Order: %d", dispenserIndex, permission == true ? "OK" : "NG",
 //		ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.SystemStatus,
 //		ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus,
@@ -2161,8 +2329,7 @@ void DispenserSocketProcess(int socketFd, struct sockaddr_in clientInfo, unsigne
 					if(receiveBuffer.Header.op == _Header_Read && receiveBuffer.Payload.reg == _Reg_Software_Update)
 					{
 					    unsigned char NeedUpgrade = FirmwareUpgradeHandler(&receiveBuffer, dispenserIndex);
-
-                        FirmwareUpgradeResponse(socketFd, &receiveBuffer, NeedUpgrade);
+                        FirmwareUpgradeResponse(socketFd, &receiveBuffer, dispenserIndex, NeedUpgrade);
 					}
 
 					// Reg: 0x08, Plug-in status

+ 10 - 0
EVSE/Projects/DO360/Apps/Module_EvComm.h

@@ -26,6 +26,16 @@
 #define	CONNECTION_LIMIT				5
 #define MAXIMUM_CONNECT_QUANTITY		2
 
+#define CCS_MAX_PHYSICAL_VOLTAGE        9500
+#define CCS_NATURAL_MAX_CURRENT         2000
+#define CCS_LIQUID_MAX_CURRENT          5000
+
+#define CHA_MAX_PHYSICAL_VOLTAGE        5000
+#define CHA_NATURAL_MAX_CURRENT         2000
+
+#define GBT_MAX_PHYSICAL_VOLTAGE        7500
+#define GBT_NATURAL_MAX_CURRENT         2500
+
 struct Message
 {
 	int				size;

+ 218 - 360
EVSE/Projects/DO360/Apps/Module_InternalComm.c

@@ -2423,387 +2423,245 @@ int main(void)
 	//bool printRelayStatus = true;
 	for(;;)
 	{
-		bool isCharging = false;
-		// 程序開始之前~ 必須先確定 FW 版本與硬體版本,確認後!!~ 該模組才算是真正的 Initial Comp.
-		if (ShmRelayModuleData[0]->SelfTest_Comp == NO)
-		{
-		    // clena fw version
-		    memset(ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev, 0x00, 32);
-
-			GetFwAndHwVersion_Relay();
-			SetRtcData_Relay(0);
-			sleep(1);
-
-            if(strlen((char *)ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev))
+	    if(!ShmSysConfigAndInfo->SysInfo.FirmwareUpdate)
+	    {
+            bool isCharging = false;
+            // 程序開始之前~ 必須先確定 FW 版本與硬體版本,確認後!!~ 該模組才算是真正的 Initial Comp.
+            if (ShmRelayModuleData[0]->SelfTest_Comp == NO)
             {
-                ShmRelayModuleData[0]->SelfTest_Comp = YES;
-            }
-		}
-
-		// DO360 RC2
-		if (ShmRelayModuleData[1]->SelfTest_Comp == NO)
-		{
-		    // clena fw version
-		    memset(ShmSysConfigAndInfo->SysInfo.Relay2ModuleFwRev, 0x00, 32);
+                // clena fw version
+                memset(ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev, 0x00, 32);
 
-			GetFwAndHwVersion_Relay2();
-			SetRtcData_Relay(1);
-			sleep(1);
+                GetFwAndHwVersion_Relay();
+                SetRtcData_Relay(0);
+                sleep(1);
 
-            if (strlen((char *)ShmSysConfigAndInfo->SysInfo.Relay2ModuleFwRev) != 0)
-            {
-                ShmRelayModuleData[1]->SelfTest_Comp = YES;
+                if(strlen((char *)ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev))
+                {
+                    ShmRelayModuleData[0]->SelfTest_Comp = YES;
+                }
             }
-		}
 
-		if (ShmFanModuleData->SelfTest_Comp == NO)
-		{
-		    // clena fw version
-		    memset(ShmSysConfigAndInfo->SysInfo.FanModuleFwRev, 0x00, 32);
-
-			GetFwAndHwVersion_Fan();
-			SetModelName_Fan();
-			SetRtcData_Fan();
-			sleep(1);
-			gettimeofday(&_priority_time, NULL);
-
-            if(strlen((char *)ShmSysConfigAndInfo->SysInfo.FanModuleFwRev) != 0)
+            // DO360 RC2
+            if (ShmRelayModuleData[1]->SelfTest_Comp == NO)
             {
-                ShmFanModuleData->SelfTest_Comp = YES;
-            }
-		}
-
-		// 自檢階段處理,自檢階段如果讀不到版號則代表該系統沒有掛燈板
-//		if (ShmLedModuleData->SelfTest_Comp == NO)
-//		{
-			// 自檢階段
-//			if (ShmSysConfigAndInfo->SysInfo.SelfTestSeq <= _STEST_PSU_CAP)
-//			{
-//				GetFwAndHwVersion_Led();
-//				sleep(1);
-//				gettimeofday(&_led_priority_time, NULL);
-//			}
-//			else
-//			{
-				// 自檢階段沒有問到版號
-//				if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.LedboardStestFail == NO)
-//					ShmStatusCodeData->AlarmCode.AlarmEvents.bits.LedboardStestFail = YES;
-//			}
-//		}
-
-		//AcChargeTypeProcess();
-
-		if (ShmRelayModuleData[0]->SelfTest_Comp == YES && ShmRelayModuleData[1]->SelfTest_Comp == YES)
-		{
-			// ==============優先權最高 10 ms ==============
-			// 輸出電壓
-			GetPersentOutputVol();
-
-			// 三相輸入電壓
-			GetPresentInputVol();
-
-			// 讀取當前 AC relay 狀態
-			regRelay[0].relay_event.bits.AC_Contactor = ShmSysConfigAndInfo->SysInfo.AcContactorStatus;
-			regRelay[1].relay_event.bits.AC_Contactor = ShmSysConfigAndInfo->SysInfo.AcContactorStatus;
-			//GetRelayOutputStatus();
-
-			for (int i = 0; i < gunCount; i++)
-			{
-				// Cable check (Set)
-				//CableCheckDetected(i);
-
-				// check k1 k2 relay 狀態
-				CheckK1K2RelayOutput(i);
-
-				// 依據當前各槍的狀態選擇 搭上/放開 Relay
-				SetK1K2RelayStatus(i);
+                // clena fw version
+                memset(ShmSysConfigAndInfo->SysInfo.Relay2ModuleFwRev, 0x00, 32);
 
-				if (ShmSysConfigAndInfo->SysConfig.PhaseLossPolicy == YES)
-					CheckPhaseLossStatus(i);
+                GetFwAndHwVersion_Relay2();
+                SetRtcData_Relay(1);
+                sleep(1);
 
-				CheckAcInputOvpStatus(i);
-
-				if (_chargingData[i]->SystemStatus == S_IDLE)
-				{
-					_chargingData[i]->RelayWeldingCheck = NO;
-					_isRelayWelding[i] = NO;
-				}
-
-				if (_chargingData[i]->SystemStatus == S_BOOTING	||
-					(_chargingData[i]->SystemStatus >= S_REASSIGN_CHECK && _chargingData[i]->SystemStatus <= S_COMPLETE) ||
-					(_chargingData[i]->SystemStatus >= S_CCS_PRECHARGE_ST0 && _chargingData[i]->SystemStatus <= S_CCS_PRECHARGE_ST1) ||
-					ShmSysConfigAndInfo->SysInfo.WaitForPlugit == YES ||
-					(ShmSysConfigAndInfo->SysInfo.PageIndex >= _LCM_AUTHORIZING && ShmSysConfigAndInfo->SysInfo.PageIndex <= _LCM_WAIT_FOR_PLUG))
-				{
-					_chargingData[i]->IsReadyToCharging = YES;
-					isCharging = true;
-
-					// 限定只有在槍類別為 GBT 的時候才做 relay welding 的判斷
-					if (_chargingData[i]->Type == _Type_GB)
-					{
-						if (_chargingData[i]->SystemStatus >= S_PREPARING_FOR_EVSE &&
-							_chargingData[i]->RelayWeldingCheck == NO)
-							CheckRelayWeldingStatus(i);
-					}
-					else
-						_chargingData[i]->RelayWeldingCheck = YES;
-
-					if (_chargingData[i]->SystemStatus == S_CHARGING)
-					{
-					    // DO360 do not check under voltage output & any voltage difference
-						//CheckOutputPowerOverCarReq(i);
-						//CheckOutputVolNoneMatchFire(i);
-					}
-					else
-						_isOutputNoneMatch[i] = NO;
-				}
-				else
-					_chargingData[i]->IsReadyToCharging = NO;
-			}
-
-			// Cable check (Get)
-			//GetGfdAdc();
-
-			// 橋接 relay
-			SetParalleRelayStatus();
+                if (strlen((char *)ShmSysConfigAndInfo->SysInfo.Relay2ModuleFwRev) != 0)
+                {
+                    ShmRelayModuleData[1]->SelfTest_Comp = YES;
+                }
+            }
 
-			// 搭上 AC Contactor
-//			if (isCharging)
-//				outputRelay.relay_event.bits.AC_Contactor = YES;
-//			else
-//				outputRelay.relay_event.bits.AC_Contactor = NO;
+            if (ShmFanModuleData->SelfTest_Comp == NO)
+            {
+                // clena fw version
+                memset(ShmSysConfigAndInfo->SysInfo.FanModuleFwRev, 0x00, 32);
 
-			if (isCharging ||
-				(ShmPsuData->Work_Step >= _TEST_MODE && ShmPsuData->Work_Step <= _TEST_MODE))
-			{
-				isStopChargingCount = false;
-				outputRelay[0].relay_event.bits.AC_Contactor = YES;
-				outputRelay[1].relay_event.bits.AC_Contactor = YES;
-			}
-			else
-			{
-				if (!isStopChargingCount)
-				{
-					gettimeofday(&_close_ac_contactor, NULL);
-					isStopChargingCount = true;
-				}
-				else
-				{
-					if (((outputRelay[0].relay_event.bits.AC_Contactor == YES || outputRelay[1].relay_event.bits.AC_Contactor == YES)&&
-							GetTimeoutValue(_close_ac_contactor) / 1000 >= (TEN_MINUTES * 1000)))
-					{
-						outputRelay[0].relay_event.bits.AC_Contactor = NO;
-						outputRelay[1].relay_event.bits.AC_Contactor = NO;
-					}
-				}
-			}
+                GetFwAndHwVersion_Fan();
+                SetModelName_Fan();
+                SetRtcData_Fan();
+                sleep(1);
+                gettimeofday(&_priority_time, NULL);
 
-			if (ShmPsuData->Work_Step >= _TEST_MODE && ShmPsuData->Work_Step <= _TEST_MODE)
-			{
-				outputRelay[0].relay_event.bits.Gun1_N = outputRelay[0].relay_event.bits.Gun1_P = YES;
-			}
+                if(strlen((char *)ShmSysConfigAndInfo->SysInfo.FanModuleFwRev) != 0)
+                {
+                    ShmFanModuleData->SelfTest_Comp = YES;
+                }
+            }
 
-			// 搭上/鬆開 Relay
-			if(IsNoneMatchRelayStatus(0))
-			{
-				if (Config_Relay_Output(Uart5Fd, Addr.DO360_RC1, &outputRelay[0]))
-				{
-					//regRelay.relay_event.bits.AC_Contactor = ShmSysConfigAndInfo->SysInfo.AcContactorStatus;
-					regRelay[0].relay_event.bits.CCS_Precharge = outputRelay[0].relay_event.bits.CCS_Precharge;
-					regRelay[0].relay_event.bits.Gun1_P = outputRelay[0].relay_event.bits.Gun1_P;
-					regRelay[0].relay_event.bits.Gun1_N = outputRelay[0].relay_event.bits.Gun1_N;
-					regRelay[0].relay_event.bits.Gun2_P = outputRelay[0].relay_event.bits.Gun2_P;
-					regRelay[0].relay_event.bits.Gun2_N = outputRelay[0].relay_event.bits.Gun2_N;
-					regRelay[0].relay_event.bits.Gun1_Parallel_P = outputRelay[0].relay_event.bits.Gun1_Parallel_P;
-					regRelay[0].relay_event.bits.Gun1_Parallel_N = outputRelay[0].relay_event.bits.Gun1_Parallel_N;
-					regRelay[0].relay_event.bits.Gun2_Parallel_P = outputRelay[0].relay_event.bits.Gun2_Parallel_P;
-					regRelay[0].relay_event.bits.Gun2_Parallel_N = outputRelay[0].relay_event.bits.Gun2_Parallel_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, bri2_p = %x, bri2_n = %x \n",
-							regRelay[0].relay_event.bits.AC_Contactor,
-							regRelay[0].relay_event.bits.Gun1_P,
-							regRelay[0].relay_event.bits.Gun1_N,
-							regRelay[0].relay_event.bits.Gun2_P,
-							regRelay[0].relay_event.bits.Gun2_N,
-							regRelay[0].relay_event.bits.CCS_Precharge,
-							regRelay[0].relay_event.bits.Gun1_Parallel_P,
-							regRelay[0].relay_event.bits.Gun1_Parallel_N,
-							regRelay[0].relay_event.bits.Gun2_Parallel_P,
-							regRelay[0].relay_event.bits.Gun2_Parallel_N);
-				}
-			}
+            if (ShmRelayModuleData[0]->SelfTest_Comp == YES && ShmRelayModuleData[1]->SelfTest_Comp == YES)
+            {
+                // ==============優先權最高 10 ms ==============
+                // 輸出電壓
+                GetPersentOutputVol();
 
-			// 搭上/鬆開 Relay
-			if(IsNoneMatchRelayStatus(1))
-			{
-				if (Config_Relay_Output(Uart5Fd, Addr.DO360_RC2, &outputRelay[1]))
-				{
-					//regRelay.relay_event.bits.AC_Contactor = ShmSysConfigAndInfo->SysInfo.AcContactorStatus;
-					regRelay[1].relay_event.bits.CCS_Precharge = outputRelay[1].relay_event.bits.CCS_Precharge;
-					regRelay[1].relay_event.bits.Gun1_P = outputRelay[1].relay_event.bits.Gun1_P;
-					regRelay[1].relay_event.bits.Gun1_N = outputRelay[1].relay_event.bits.Gun1_N;
-					regRelay[1].relay_event.bits.Gun2_P = outputRelay[1].relay_event.bits.Gun2_P;
-					regRelay[1].relay_event.bits.Gun2_N = outputRelay[1].relay_event.bits.Gun2_N;
-					regRelay[1].relay_event.bits.Gun1_Parallel_P = outputRelay[1].relay_event.bits.Gun1_Parallel_P;
-					regRelay[1].relay_event.bits.Gun1_Parallel_N = outputRelay[1].relay_event.bits.Gun1_Parallel_N;
-					regRelay[1].relay_event.bits.Gun2_Parallel_P = outputRelay[1].relay_event.bits.Gun2_Parallel_P;
-					regRelay[1].relay_event.bits.Gun2_Parallel_N = outputRelay[1].relay_event.bits.Gun2_Parallel_N;
-
-					PRINTF_FUNC("Match Relay2, AC = %x, g1_p = %x, g1_n = %x, g2_p = %x, g2_n = %x, pre = %x, bri_p = %x, bri_n = %x, bri2_p = %x, bri2_n = %x \n",
-							regRelay[1].relay_event.bits.AC_Contactor,
-							regRelay[1].relay_event.bits.Gun1_P,
-							regRelay[1].relay_event.bits.Gun1_N,
-							regRelay[1].relay_event.bits.Gun2_P,
-							regRelay[1].relay_event.bits.Gun2_N,
-							regRelay[1].relay_event.bits.CCS_Precharge,
-							regRelay[1].relay_event.bits.Gun1_Parallel_P,
-							regRelay[1].relay_event.bits.Gun1_Parallel_N,
-							regRelay[1].relay_event.bits.Gun2_Parallel_P,
-							regRelay[1].relay_event.bits.Gun2_Parallel_N);
-				}
-			}
+                // 三相輸入電壓
+                GetPresentInputVol();
 
+                // 讀取當前 AC relay 狀態
+                regRelay[0].relay_event.bits.AC_Contactor = ShmSysConfigAndInfo->SysInfo.AcContactorStatus;
+                regRelay[1].relay_event.bits.AC_Contactor = ShmSysConfigAndInfo->SysInfo.AcContactorStatus;
+                //GetRelayOutputStatus();
 
-//			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))
-//				{
-//					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);
-//				}
-//			}
-//			else
-//			{
-//				if (!printRelayStatus)
-//				{
-//					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,
-//							regRelay.relay_event.bits.Gun2_P,
-//							regRelay.relay_event.bits.Gun2_N,
-//							regRelay.relay_event.bits.CCS_Precharge,
-//							regRelay.relay_event.bits.Gun1_Parallel_P,
-//							regRelay.relay_event.bits.Gun1_Parallel_N);
-//				}
-//				printRelayStatus = true;
-//			}
-		}
-
-		if (ShmFanModuleData->SelfTest_Comp == YES ||
-				strlen((char *)ShmSysConfigAndInfo->SysInfo.FanModuleFwRev) != 0 ||
-				ShmSysConfigAndInfo->SysInfo.FanModuleFwRev[0] != '\0')
-		{
-			if (GetTimeoutValue(_priority_time) / 1000 >= 1000)
-			{
-				//GetPsuTempForFanSpeed();
-				GetFanSpeedByFunction();
-				GetFanSpeed();
-				ShmSysConfigAndInfo->SysInfo.SystemFanRotaSpeed = _setFanSpeed;
-				gettimeofday(&_priority_time, NULL);
+                for (int i = 0; i < gunCount; i++)
+                {
+                    // check k1 k2 relay 狀態
+                    CheckK1K2RelayOutput(i);
+
+                    // 依據當前各槍的狀態選擇 搭上/放開 Relay
+                    SetK1K2RelayStatus(i);
+
+                    if (ShmSysConfigAndInfo->SysConfig.PhaseLossPolicy == YES)
+                        CheckPhaseLossStatus(i);
+
+                    CheckAcInputOvpStatus(i);
+
+                    if (_chargingData[i]->SystemStatus == S_IDLE)
+                    {
+                        _chargingData[i]->RelayWeldingCheck = NO;
+                        _isRelayWelding[i] = NO;
+                    }
+
+                    if (_chargingData[i]->SystemStatus == S_BOOTING	||
+                        (_chargingData[i]->SystemStatus >= S_REASSIGN_CHECK && _chargingData[i]->SystemStatus <= S_COMPLETE) ||
+                        (_chargingData[i]->SystemStatus >= S_CCS_PRECHARGE_ST0 && _chargingData[i]->SystemStatus <= S_CCS_PRECHARGE_ST1) ||
+                        ShmSysConfigAndInfo->SysInfo.WaitForPlugit == YES ||
+                        (ShmSysConfigAndInfo->SysInfo.PageIndex >= _LCM_AUTHORIZING && ShmSysConfigAndInfo->SysInfo.PageIndex <= _LCM_WAIT_FOR_PLUG))
+                    {
+                        _chargingData[i]->IsReadyToCharging = YES;
+                        isCharging = true;
+
+                        // 限定只有在槍類別為 GBT 的時候才做 relay welding 的判斷
+                        if (_chargingData[i]->Type == _Type_GB)
+                        {
+                            if (_chargingData[i]->SystemStatus >= S_PREPARING_FOR_EVSE &&
+                                _chargingData[i]->RelayWeldingCheck == NO)
+                                CheckRelayWeldingStatus(i);
+                        }
+                        else
+                            _chargingData[i]->RelayWeldingCheck = YES;
+
+                        if (_chargingData[i]->SystemStatus == S_CHARGING)
+                        {
+                            // DO360 do not check under voltage output & any voltage difference
+                            //CheckOutputPowerOverCarReq(i);
+                            //CheckOutputVolNoneMatchFire(i);
+                        }
+                        else
+                            _isOutputNoneMatch[i] = NO;
+                    }
+                    else
+                        _chargingData[i]->IsReadyToCharging = NO;
+                }
 
-				unsigned short TargetSpeed = ShmFanModuleData->TestFanSpeed;
+                // 橋接 relay
+                SetParalleRelayStatus();
 
-				if(TargetSpeed != 0 && TargetSpeed < MIN_FAN_SPEED)
-				{
-				    TargetSpeed = MIN_FAN_SPEED;
-				}
-				ShmFanModuleData->SetFan1Speed = TargetSpeed;
-				ShmFanModuleData->SetFan2Speed = TargetSpeed;
-				ShmFanModuleData->SetFan3Speed = TargetSpeed;
-				ShmFanModuleData->SetFan4Speed = TargetSpeed;
+                if (isCharging ||
+                    (ShmPsuData->Work_Step >= _TEST_MODE && ShmPsuData->Work_Step <= _TEST_MODE))
+                {
+                    isStopChargingCount = false;
+                    outputRelay[0].relay_event.bits.AC_Contactor = YES;
+                    outputRelay[1].relay_event.bits.AC_Contactor = YES;
+                }
+                else
+                {
+                    if (!isStopChargingCount)
+                    {
+                        gettimeofday(&_close_ac_contactor, NULL);
+                        isStopChargingCount = true;
+                    }
+                    else
+                    {
+                        if (((outputRelay[0].relay_event.bits.AC_Contactor == YES || outputRelay[1].relay_event.bits.AC_Contactor == YES)&&
+                                GetTimeoutValue(_close_ac_contactor) / 1000 >= (TEN_MINUTES * 1000)))
+                        {
+                            outputRelay[0].relay_event.bits.AC_Contactor = NO;
+                            outputRelay[1].relay_event.bits.AC_Contactor = NO;
+                        }
+                    }
+                }
 
-//				if (isCharging)
-//				{
-////					if (ShmFanModuleData->PresentFan1Speed < MAX_FAN_SPEED ||
-////						ShmFanModuleData->PresentFan2Speed < MAX_FAN_SPEED ||
-////						ShmFanModuleData->PresentFan3Speed < MAX_FAN_SPEED ||
-////						ShmFanModuleData->PresentFan4Speed < MAX_FAN_SPEED)
-////					{
-////						ShmFanModuleData->SetFan1Speed = MAX_FAN_SPEED;
-////						ShmFanModuleData->SetFan2Speed = MAX_FAN_SPEED;
-////						ShmFanModuleData->SetFan3Speed = MAX_FAN_SPEED;
-////						ShmFanModuleData->SetFan4Speed = MAX_FAN_SPEED;
-////					}
-//
-//					// 在還沒問到 PSU 溫度~ 還是要有個最小轉速
-//					ShmFanModuleData->SetFan1Speed = MIN_FAN_SPEED;
-//					ShmFanModuleData->SetFan2Speed = MIN_FAN_SPEED;
-//					ShmFanModuleData->SetFan3Speed = MIN_FAN_SPEED;
-//					ShmFanModuleData->SetFan4Speed = MIN_FAN_SPEED;
-//
-//					if (ShmFanModuleData->TestFanSpeed > 0)
-//					{
-//						ShmFanModuleData->SetFan1Speed = ShmFanModuleData->TestFanSpeed;
-//						ShmFanModuleData->SetFan2Speed = ShmFanModuleData->TestFanSpeed;
-//						ShmFanModuleData->SetFan3Speed = ShmFanModuleData->TestFanSpeed;
-//						ShmFanModuleData->SetFan4Speed = ShmFanModuleData->TestFanSpeed;
-//					}
-//				}
-//				else
-//				{
-////					if (ShmFanModuleData->PresentFan1Speed > MIN_FAN_SPEED ||
-////						ShmFanModuleData->PresentFan2Speed > MIN_FAN_SPEED ||
-////						ShmFanModuleData->PresentFan3Speed > MIN_FAN_SPEED ||
-////						ShmFanModuleData->PresentFan4Speed > MIN_FAN_SPEED)
-////					{
-//						ShmFanModuleData->SetFan1Speed = MIN_FAN_SPEED;
-//						ShmFanModuleData->SetFan2Speed = MIN_FAN_SPEED;
-//						ShmFanModuleData->SetFan3Speed = MIN_FAN_SPEED;
-//						ShmFanModuleData->SetFan4Speed = MIN_FAN_SPEED;
-////					}
-//
-//					// 停止時,如溫度還是很高,則需要維持該轉速直到溫度降低
-//					if (ShmFanModuleData->TestFanSpeed >= MAX_FAN_SPEED)
-//					{
-//						ShmFanModuleData->SetFan1Speed = ShmFanModuleData->TestFanSpeed;
-//						ShmFanModuleData->SetFan2Speed = ShmFanModuleData->TestFanSpeed;
-//						ShmFanModuleData->SetFan3Speed = ShmFanModuleData->TestFanSpeed;
-//						ShmFanModuleData->SetFan4Speed = ShmFanModuleData->TestFanSpeed;
-//					}
-//				}
+                if (ShmPsuData->Work_Step >= _TEST_MODE && ShmPsuData->Work_Step <= _TEST_MODE)
+                {
+                    outputRelay[0].relay_event.bits.Gun1_N = outputRelay[0].relay_event.bits.Gun1_P = YES;
+                }
 
-				//PRINTF_FUNC("set fan = %d \n", ShmFanModuleData->SetFan1Speed);
-				SetFanModuleSpeed();
-			}
-		}
+                // 搭上/鬆開 Relay
+                if(IsNoneMatchRelayStatus(0))
+                {
+                    if (Config_Relay_Output(Uart5Fd, Addr.DO360_RC1, &outputRelay[0]))
+                    {
+                        //regRelay.relay_event.bits.AC_Contactor = ShmSysConfigAndInfo->SysInfo.AcContactorStatus;
+                        regRelay[0].relay_event.bits.CCS_Precharge = outputRelay[0].relay_event.bits.CCS_Precharge;
+                        regRelay[0].relay_event.bits.Gun1_P = outputRelay[0].relay_event.bits.Gun1_P;
+                        regRelay[0].relay_event.bits.Gun1_N = outputRelay[0].relay_event.bits.Gun1_N;
+                        regRelay[0].relay_event.bits.Gun2_P = outputRelay[0].relay_event.bits.Gun2_P;
+                        regRelay[0].relay_event.bits.Gun2_N = outputRelay[0].relay_event.bits.Gun2_N;
+                        regRelay[0].relay_event.bits.Gun1_Parallel_P = outputRelay[0].relay_event.bits.Gun1_Parallel_P;
+                        regRelay[0].relay_event.bits.Gun1_Parallel_N = outputRelay[0].relay_event.bits.Gun1_Parallel_N;
+                        regRelay[0].relay_event.bits.Gun2_Parallel_P = outputRelay[0].relay_event.bits.Gun2_Parallel_P;
+                        regRelay[0].relay_event.bits.Gun2_Parallel_N = outputRelay[0].relay_event.bits.Gun2_Parallel_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, bri2_p = %x, bri2_n = %x \n",
+                                regRelay[0].relay_event.bits.AC_Contactor,
+                                regRelay[0].relay_event.bits.Gun1_P,
+                                regRelay[0].relay_event.bits.Gun1_N,
+                                regRelay[0].relay_event.bits.Gun2_P,
+                                regRelay[0].relay_event.bits.Gun2_N,
+                                regRelay[0].relay_event.bits.CCS_Precharge,
+                                regRelay[0].relay_event.bits.Gun1_Parallel_P,
+                                regRelay[0].relay_event.bits.Gun1_Parallel_N,
+                                regRelay[0].relay_event.bits.Gun2_Parallel_P,
+                                regRelay[0].relay_event.bits.Gun2_Parallel_N);
+                    }
+                }
 
-//		if (ShmLedModuleData->SelfTest_Comp == YES)
-//		{
-//			if (GetTimeoutValue(_led_priority_time) / 1000 >= 1000)
-//			{
-//				if(gunCount == 1)
-//				{
-//					SetLedColor(_chargingData[0], _chargingData[0]);
-//				}
-//				else if (gunCount == 2)
-//				{
-//					SetLedColor(_chargingData[0], _chargingData[1]);
-//				}
+                // 搭上/鬆開 Relay
+                if(IsNoneMatchRelayStatus(1))
+                {
+                    if (Config_Relay_Output(Uart5Fd, Addr.DO360_RC2, &outputRelay[1]))
+                    {
+                        //regRelay.relay_event.bits.AC_Contactor = ShmSysConfigAndInfo->SysInfo.AcContactorStatus;
+                        regRelay[1].relay_event.bits.CCS_Precharge = outputRelay[1].relay_event.bits.CCS_Precharge;
+                        regRelay[1].relay_event.bits.Gun1_P = outputRelay[1].relay_event.bits.Gun1_P;
+                        regRelay[1].relay_event.bits.Gun1_N = outputRelay[1].relay_event.bits.Gun1_N;
+                        regRelay[1].relay_event.bits.Gun2_P = outputRelay[1].relay_event.bits.Gun2_P;
+                        regRelay[1].relay_event.bits.Gun2_N = outputRelay[1].relay_event.bits.Gun2_N;
+                        regRelay[1].relay_event.bits.Gun1_Parallel_P = outputRelay[1].relay_event.bits.Gun1_Parallel_P;
+                        regRelay[1].relay_event.bits.Gun1_Parallel_N = outputRelay[1].relay_event.bits.Gun1_Parallel_N;
+                        regRelay[1].relay_event.bits.Gun2_Parallel_P = outputRelay[1].relay_event.bits.Gun2_Parallel_P;
+                        regRelay[1].relay_event.bits.Gun2_Parallel_N = outputRelay[1].relay_event.bits.Gun2_Parallel_N;
+
+                        PRINTF_FUNC("Match Relay2, AC = %x, g1_p = %x, g1_n = %x, g2_p = %x, g2_n = %x, pre = %x, bri_p = %x, bri_n = %x, bri2_p = %x, bri2_n = %x \n",
+                                regRelay[1].relay_event.bits.AC_Contactor,
+                                regRelay[1].relay_event.bits.Gun1_P,
+                                regRelay[1].relay_event.bits.Gun1_N,
+                                regRelay[1].relay_event.bits.Gun2_P,
+                                regRelay[1].relay_event.bits.Gun2_N,
+                                regRelay[1].relay_event.bits.CCS_Precharge,
+                                regRelay[1].relay_event.bits.Gun1_Parallel_P,
+                                regRelay[1].relay_event.bits.Gun1_Parallel_N,
+                                regRelay[1].relay_event.bits.Gun2_Parallel_P,
+                                regRelay[1].relay_event.bits.Gun2_Parallel_N);
+                    }
+                }
+            }
 
-//				gettimeofday(&_led_priority_time, NULL);
-//			}
-//		}
+            if (ShmFanModuleData->SelfTest_Comp == YES ||
+                    strlen((char *)ShmSysConfigAndInfo->SysInfo.FanModuleFwRev) != 0 ||
+                    ShmSysConfigAndInfo->SysInfo.FanModuleFwRev[0] != '\0')
+            {
+                if (GetTimeoutValue(_priority_time) / 1000 >= 1000)
+                {
+                    //GetPsuTempForFanSpeed();
+                    GetFanSpeedByFunction();
+                    GetFanSpeed();
+                    ShmSysConfigAndInfo->SysInfo.SystemFanRotaSpeed = _setFanSpeed;
+                    gettimeofday(&_priority_time, NULL);
+
+                    unsigned short TargetSpeed = ShmFanModuleData->TestFanSpeed;
+
+                    if(TargetSpeed != 0 && TargetSpeed < MIN_FAN_SPEED)
+                    {
+                        TargetSpeed = MIN_FAN_SPEED;
+                    }
+                    ShmFanModuleData->SetFan1Speed = TargetSpeed;
+                    ShmFanModuleData->SetFan2Speed = TargetSpeed;
+                    ShmFanModuleData->SetFan3Speed = TargetSpeed;
+                    ShmFanModuleData->SetFan4Speed = TargetSpeed;
+
+                    //PRINTF_FUNC("set fan = %d \n", ShmFanModuleData->SetFan1Speed);
+                    SetFanModuleSpeed();
+                }
+            }
+	    }
 
 		usleep(10000);
 	}

+ 20 - 42
EVSE/Projects/DO360/Apps/Module_PrimaryComm.c

@@ -462,52 +462,30 @@ int main(void)
 
 	for(;;)
 	{
-//		if (strcmp((char *)ShmSysConfigAndInfo->SysInfo.LcmHwRev, " ") == 0x00)
-//		{
-//			if ((GetTimeoutValue(_flash_time) / 1000) > 1000)
-//			{
-//				if (flash == NO)
-//					flash = YES;
-//				else
-//					flash = NO;
-//				SetOutputGpio(flash);
-//				gettimeofday(&_flash_time, NULL);
-//			}
-//		}
-//		else
-//		{
-//			if ((GetTimeoutValue(_flash_time) / 1000) > 5000)
-//			{
-//				if (flash == NO)
-//					flash = YES;
-
-//				SetOutputGpio(flash);
-//				gettimeofday(&_flash_time, NULL);
-//			}
-//		}
-
-		// 程序開始之前~ 必須先確定 FW 版本與硬體版本,確認後!!~ 該模組才算是真正的 Initial Comp.
-		// 模組更新 FW 後,需重新做
-		if(ShmPrimaryMcuData->SelfTest_Comp != PASS)
-		{
-		    memset(ShmPrimaryMcuData->version, 0x00, 16);
+	    if(!ShmSysConfigAndInfo->SysInfo.FirmwareUpdate)
+	    {
+            // 程序開始之前~ 必須先確定 FW 版本與硬體版本,確認後!!~ 該模組才算是真正的 Initial Comp.
+            // 模組更新 FW 後,需重新做
+            if(ShmPrimaryMcuData->SelfTest_Comp != PASS)
+            {
+                memset(ShmPrimaryMcuData->version, 0x00, 16);
 
-			GetFwAndHwVersion();
-			sleep(1);
+                GetFwAndHwVersion();
+                sleep(1);
 
-            if(strlen((char *)ShmPrimaryMcuData->version) != 0)
-            {
-                ShmPrimaryMcuData->SelfTest_Comp = YES;
+                if(strlen((char *)ShmPrimaryMcuData->version) != 0)
+                {
+                    ShmPrimaryMcuData->SelfTest_Comp = YES;
+                }
             }
-		}
-		else
-		{
-			GetInputGpioStatus();
-			//PRINTF_FUNC("Input Status: %02X %02X", ShmPrimaryMcuData->InputDet.InputDetValue[1], ShmPrimaryMcuData->InputDet.InputDetValue[0]);
-
-			SetOutputGpio(ShmPrimaryMcuData->OutputDrv.OutputDrvValue[0]);
-		}
+            else
+            {
+                GetInputGpioStatus();
+                //PRINTF_FUNC("Input Status: %02X %02X", ShmPrimaryMcuData->InputDet.InputDetValue[1], ShmPrimaryMcuData->InputDet.InputDetValue[0]);
 
+                SetOutputGpio(ShmPrimaryMcuData->OutputDrv.OutputDrvValue[0]);
+            }
+	    }
 		usleep(100000);
 	}
 

+ 11 - 5
EVSE/Projects/DO360/Apps/Module_PsuComm.c

@@ -1574,18 +1574,24 @@ int main(void)
 						if (chargingInfo[groupIndex]->PresentChargingVoltage > 0 &&
 								evseOutVol[groupIndex] != chargingInfo[groupIndex]->PresentChargingVoltage)
 						{
+						    if((int)evseOutVol[groupIndex] != (int)chargingInfo[groupIndex]->PresentChargingVoltage)
+						    {
+	                            PRINTF_FUNC("groupIndex = %d, ev need vol = %.1fV, evse output vol = %.1fV, fire voltage vol = %.1fV \n",
+	                                groupIndex, chargingInfo[groupIndex]->EvBatterytargetVoltage,
+	                                chargingInfo[groupIndex]->PresentChargingVoltage, chargingInfo[groupIndex]->FireChargingVoltage);
+						    }
 							evseOutVol[groupIndex] = chargingInfo[groupIndex]->PresentChargingVoltage;
-							PRINTF_FUNC("groupIndex = %d, ev need vol = %.1fV, evse output vol = %.1fV, fire voltage vol = %.1fV \n",
-                                groupIndex,	chargingInfo[groupIndex]->EvBatterytargetVoltage,
-								chargingInfo[groupIndex]->PresentChargingVoltage, chargingInfo[groupIndex]->FireChargingVoltage);
 						}
 
 						if (chargingInfo[groupIndex]->PresentChargingCurrent > 0 &&
 							evseOutCur[groupIndex] != chargingInfo[groupIndex]->PresentChargingCurrent)
 						{
+							if((int)evseOutCur[groupIndex] != (int)chargingInfo[groupIndex]->PresentChargingCurrent)
+							{
+                                PRINTF_FUNC("groupIndex = %d, ev need cur = %.1fA, evse output cur = %.1fA \n", groupIndex,
+                                    chargingInfo[groupIndex]->EvBatterytargetCurrent, chargingInfo[groupIndex]->PresentChargingCurrent);
+							}
 							evseOutCur[groupIndex] = chargingInfo[groupIndex]->PresentChargingCurrent;
-							PRINTF_FUNC("groupIndex = %d, ev need cur = %.1fA, evse output cur = %.1fA \n", groupIndex,
-								chargingInfo[groupIndex]->EvBatterytargetCurrent, chargingInfo[groupIndex]->PresentChargingCurrent);
 						}
 
 						if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)

+ 330 - 168
EVSE/Projects/DO360/Apps/main.c

@@ -60,6 +60,9 @@
 #define		UPGRADE_PRI			0x04
 #define		UPGRADE_AC			0x05
 #define		UPGRADE_LED			0x06
+#define     UPGRADE_DORC1       0x07
+#define     UPGRADE_DORC2       0x08
+#define     UPGRADE_DDRB        0x09
 #define		SYSTEM_MIN_VOL		150
 #define 	MIN_OUTPUT_CUR		0
 #define		AC_OUTPUT_VOL		220
@@ -89,12 +92,14 @@
 #define     DISPENSER_RECONNECTE_TIME   30
 #define     DISPENSER_AUTH_COMP_TIME    3
 #define     FORCE_BALANCE_TIME          5
+#define     DISPENSER_UPGRADE_TIME      600
 
 char 	*valid_Internet[2] 	  = {"8.8.8.8", "180.76.76.76"};
 unsigned char mask_table[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
 int whileLoopTime = 10000; // 10 ms
 int	wtdFd = -1;
 byte _authorizeIndex = NO_DEFINE;
+BOOL _UpgradeNeedReboot = FALSE;
 
 bool IsAuthorizingMode();
 void ClearAuthorizedFlag();
@@ -158,6 +163,7 @@ struct timeval                  _ConnectorAuthorizing_Time[CONNECTOR_QUANTITY];
 struct timeval                  _ConnectorAuthorizeFail_Time[CONNECTOR_QUANTITY];
 struct timeval                  _DispenserAuthorizing_Time[CONNECTOR_QUANTITY];
 int chargingTime[CONNECTOR_QUANTITY];
+struct timeval                  _DispenserUpgrade_time;
 
 // for initial index to check EV board type is correct
 byte _gunIndex = 0;
@@ -176,7 +182,7 @@ bool isModelNameMatch = true;
 
 //int rfidFd = -1;
 //char* rfidPortName = "/dev/ttyS2";
-char* fwVersion = "D0.07.00.0000.00";
+char* fwVersion = "D0.08.00.0000.00";
 
 sqlite3 *localDb;
 bool isDb_ready;
@@ -1137,11 +1143,11 @@ void InitEthernet()
 				}
 			}
 
-			bool ethResult = YES;
+            bool ethResult = YES;
 
-			if(ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet)
-				ethResult = NO;
-			else
+            if(ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet)
+                ethResult = NO;
+            else
 			{
 				system("/sbin/ifmetric eth0 0");
 
@@ -1348,6 +1354,8 @@ void InitialShareMemoryInfo()
 	char cmd[512];
 	char buf[512];
 
+	_UpgradeNeedReboot = FALSE;
+
 	sprintf((char *)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomApn, "Internet");
 	sprintf((char *)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapId, " ");
 	sprintf((char *)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapPwd, " ");
@@ -3121,15 +3129,19 @@ void PowerCabinetAuthorizingSettingInitial(void)
     ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.BackendAuthorized = false;
 }
 
+void AnnounceAccountBalance(unsigned char index, int balance)
+{
+    ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].Parameter.bits.AnnounceBalance = true;
+    ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].AccountBalance = balance;
+    ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].Parameter.bits.AccountBalanceRequest = true;
+    PRINTF_FUNC("Announce Account Balance %d To Connector %d", balance, index + 1);
+}
+
 void FouceAnnounceAccountBalance(unsigned char index)
 {
     if(!ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].Parameter.bits.AnnounceBalance)
     {
-        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].Parameter.bits.AnnounceBalance = true;
-
-        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].AccountBalance = 0;
-        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].Parameter.bits.AccountBalanceRequest = true;
-        PRINTF_FUNC("Force Announce Account Balance To Connector %d", index + 1);
+        AnnounceAccountBalance(index, 0);
     }
 }
 
@@ -3799,157 +3811,272 @@ void KillTask()
 	system("killall Module_Wifi &");
 }
 
-char CheckUpdateProcess()
+int PutDispenserImage(char *IpAddress, char *SourcePath)
 {
-	DIR *d;
-	struct dirent *dir;
-	d = opendir("/mnt/");
+    int isPass = PASS;
+    unsigned char ftpcmdbuf[256];
 
-	if (d)
-	{
-		long int MaxLen=48*1024*1024, ImageLen = 0;
-		while ((dir = readdir(d)) != NULL)
+    PRINTF_FUNC("Transfer image(%s) to ip: %s ", SourcePath, IpAddress);
+    //Using ftpput command to transfer upgrade image,
+    //User name     : root
+    //User password : y42j/4cj84
+    //Destination   : as same as source path
+    sprintf((char*)ftpcmdbuf,"ftpput -u root -p y42j/4cj84 %s %s %s", IpAddress, SourcePath, SourcePath);
+
+    if(system((char*)ftpcmdbuf) != 0)
+    {
+        isPass = FAIL;
+        PRINTF_FUNC("Transfer Image NG - FTP put upgrade image to fail");
+    }
+    else
+    {
+        PRINTF_FUNC("FTP put Image OK");
+    }
+
+    return isPass;
+}
+
+void TriggerDispenserUpgrade(unsigned char index, char *FileName)
+{
+    memset(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[index].FwFileName, 0x00, 128);
+    memcpy(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[index].FwFileName, FileName, strlen(FileName));
+    ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[index].Setting.bits.FirmwareUpdateRequest = true;
+    PRINTF_FUNC("Trigger dispenser %d to update image %s", index + 1, FileName);
+}
+
+BOOL PutImageToAllDispenser(char *SourcePath, char *FileName)
+{
+    int isPass = FAIL;
+    BOOL transferred = FALSE;
+
+    for(int i = 0; i < GENERAL_GUN_QUANTITY; i++)
+    {
+        if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.ConnectionInfo[i].Status == _CNS_DispenserMatched)
+        {
+            char DispenserIpAddress[16];
+            memset((char*)DispenserIpAddress, 0x00, 16);
+            sprintf((char*)DispenserIpAddress, "%d.%d.%d.%d",
+                ((ShmSysConfigAndInfo->SysInfo.DispenserInfo.ConnectionInfo[i].IpAddress >>  0) & 0xFF),
+                ((ShmSysConfigAndInfo->SysInfo.DispenserInfo.ConnectionInfo[i].IpAddress >>  8) & 0xFF),
+                ((ShmSysConfigAndInfo->SysInfo.DispenserInfo.ConnectionInfo[i].IpAddress >> 16) & 0xFF),
+                ((ShmSysConfigAndInfo->SysInfo.DispenserInfo.ConnectionInfo[i].IpAddress >> 24) & 0xFF));
+
+            isPass = PutDispenserImage(DispenserIpAddress, SourcePath);
+            if(isPass == PASS)
+            {
+                TriggerDispenserUpgrade(ShmSysConfigAndInfo->SysInfo.DispenserInfo.ConnectionInfo[i].DispenserIndex, FileName);
+            }
+            transferred = true;
+        }
+    }
+
+    return transferred;
+}
+
+BOOL WaitAllDispenserUpgradeCompleted(void)
+{
+    BOOL completed = TRUE;
+
+    gettimeofday(&_DispenserUpgrade_time, NULL);
+    do
+    {
+        completed = TRUE;
+        for(int i = 0; i < GENERAL_GUN_QUANTITY; i++)
+        {
+            if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.FirmwareUpdateRequest ||
+                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.FirmwareUpdateConfirm)
+            {
+                if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.FirmwareUpdateCompleted)
+                {
+                    ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.FirmwareUpdateRequest = false;
+                    ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.FirmwareUpdateConfirm = false;
+                    ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.FirmwareUpdateCompleted = false;
+                    PRINTF_FUNC("Dispenser %d Upgrade Success", i + 1);
+                }
+                else
+                {
+                    completed = FALSE;
+                }
+            }
+        }
+
+        if(GetTimeoutValue(_DispenserUpgrade_time) / uSEC_VAL >= DISPENSER_UPGRADE_TIME)
+        {
+            PRINTF_FUNC("Wait Upgrade Timeout");
+            completed = FALSE;
+            break;
+        }
+
+        if(completed == FALSE)
+        {
+            sleep(1);
+        }
+    }while(!completed);
+
+    return completed;
+}
+
+char CheckUpdateProcess()
+{
+    char model[32];
+    bool support = false;
+    bool OneImageOnly = false;
+    int isPass = true;
+    uint8_t retSucc = 0;
+    uint8_t retFail = 0;
+    byte target = 0;
+    char *new_str = NULL;
+    unsigned char *ptr = NULL;
+    int fd = 0;
+    int uartFd = 0;
+    unsigned int Type = 0;
+    long int MaxLen = 48 * 1024 * 1024, ImageLen = 0;
+    DIR *d;
+    struct dirent *dir;
+    char cmdBuf[128];
+
+    d = opendir("/mnt/");
+
+	if(d)
+	{
+		while((dir = readdir(d)) != NULL && !OneImageOnly)
 		{
-			char *new_str;
-			new_str = malloc(strlen("/mnt/")+strlen(dir->d_name)+1);
-			new_str[0] = '\0';
+            if (strcmp(dir->d_name, ".") == 0 || strcmp(dir->d_name, "..") == 0) {
+                continue;
+            }
+
+		    new_str = calloc(strlen("/mnt/") + strlen(dir->d_name) + 1, sizeof(char));
 			strcat(new_str, "/mnt/");
 			strcat(new_str, dir->d_name);
-			int fd = open(new_str, O_RDONLY);
-			if (fd < 0)
+			fd = open(new_str, O_RDONLY);
+			if(fd < 0)
 			{
-				return FAIL;
+	            free(new_str);
+			    continue;
 			}
 
-			unsigned char *ptr = malloc(MaxLen); //-48 is take out the header
-			memset(ptr, 0xFF, MaxLen);  //-48 is take out the header
+			DEBUG_INFO_MSG("%s\n", new_str);
+
+			ptr = calloc(MaxLen, sizeof(char));     //-48 is take out the header
+			memset(ptr, 0xFF, MaxLen);              //-48 is take out the header
 			//get the image length
 			ImageLen = read(fd, ptr, MaxLen);
 
 			if (ImageLen > 20)
 			{
-				unsigned int Type = (((unsigned int)ptr[16])<<24 | ((unsigned int)ptr[17])<<16 | ((unsigned int)ptr[18])<<8 | ((unsigned int)ptr[19]));
-			    PRINTF_FUNC("Typed...%x \r\n", Type);
+			    support = false;
+			    memcpy(model, ptr, 16);
+			    PRINTF_FUNC("Model: %s", model);
+				Type = (((unsigned int)ptr[16]) << 24 | ((unsigned int)ptr[17]) << 16 | ((unsigned int)ptr[18]) << 8 | ((unsigned int)ptr[19]));
+			    PRINTF_FUNC("Typed...%x", Type);
 
-			    switch (Type)
+			    if(strcmp(model, (char *)ShmSysConfigAndInfo->SysConfig.ModelName) == EQUAL)
 			    {
-			    	case 0x10000001:
-			    	case 0x10000002:
-			    	case 0x10000003:
-			    	case 0x10000004:
-			    	case 0x10000005:
-			    	{
-			    		if (Upgrade_Flash(Type, new_str, (char *)ShmSysConfigAndInfo->SysConfig.ModelName) == PASS)
-			    			return PASS;
-			    		else
-			    			return FAIL;
-			    	}
-			    	break;
-					case 0x10000007:
-					case 0x10000008:
-					case 0x10000009:
-					case 0x1000000A:
-					{
-						bool isPass = true;
-						int CanFd = InitCanBus();
+                    switch (Type)
+                    {
+                        case 0x10000001:
+                        case 0x10000002:
+                        case 0x10000003:
+                        case 0x10000004:
+                        case 0x10000005:
+                            support = true;
+                            _UpgradeNeedReboot = TRUE;
+                            isPass = Upgrade_Flash(Type, new_str, (char *)ShmSysConfigAndInfo->SysConfig.ModelName);
+                            break;
+
+                        case 0x10000006:            // primary mcu
+                        case 0x1000000D:            // relay board
+                        case 0x1000000E:            // fan board
+                        case 0x10000014:            // led board
+                            support = true;
+                            target = 0x00;
+
+                            if (Type == 0x10000006)
+                            {
+                                target = UPGRADE_PRI;
+                            }
+                            else if (Type == 0x1000000D)
+                            {
+                                target = UPGRADE_RB;
+                            }
+                            else if (Type == 0x1000000E)
+                            {
+                                target = UPGRADE_FAN;
+                            }
+                            else if (Type == 0x10000014)
+                            {
+                                target = UPGRADE_LED;
+                            }
 
-						if (CanFd > 0)
-						{
-							for(byte index = 0; index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; index++)
-							{
-								if (!isPass)
-						        break;
-
-						        if (chargingInfo[index]->Type == _Type_CCS_2)
-						        {
-						        	if (Upgrade_CCS(CanFd, Type, chargingInfo[index]->Evboard_id, new_str, (char *)ShmSysConfigAndInfo->SysConfig.ModelName) == FAIL)
-						            {
-						            	isPass = false;
-						            }
-						        }
-						    }
-						}
-						else
-						{
-						    printf("Upgrade CCS open CAN FD fail.\n");
-						    isPass = false;
-						}
+                            uartFd = InitComPort(target);
 
-						return isPass;
-					}
-						break;
-			    	case 0x10000006:
-			    	case 0x1000000D:
-			    	case 0x1000000E:
-			    	case 0x20000002:
-			    	case 0x10000014:
-			    	{
-			    		// CSU_PRIMARY_CONTROLLER : 0x10000006
-			    		byte target = 0x00;
-
-			    		if (Type == 0x10000006)
-			    			target = UPGRADE_PRI;
-			    		else if (Type == 0x1000000D)
-			    			target = UPGRADE_RB;
-			    		else if (Type == 0x1000000E)
-			    			target = UPGRADE_FAN;
-			    		else if (Type == 0x20000002)
-			    			target = UPGRADE_AC;
-			    		else if (Type == 0x10000014)
-			    			target = UPGRADE_LED;
-
-			    		int fd = InitComPort(target);
-
-			    		if (Upgrade_UART(fd, Type, target, new_str, (char *)ShmSysConfigAndInfo->SysConfig.ModelName) == PASS)
-			    			return PASS;
-			    		else
-			    			return FAIL;
-
-			    		close(fd);
-			    	}
-			    	break;
-			    	case 0x1000000B:
-			    	case 0x1000000C:
-			    	{
-			    		// CHAdeMO_BOARD : 0x1000000B, GBT : 0x1000000C
-			    		bool isPass = true;
-			    		int CanFd = InitCanBus();
-
-			    		if (CanFd > 0)
-			    		{
-			    			for(byte index = 0; index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; index++)
-			    			{
-			    				if (!isPass)
-			    					break;
-
-			    				if ((Type == 0x1000000B && chargingInfo[index]->Type == _Type_Chademo) ||
-			    						(Type == 0x1000000C && chargingInfo[index]->Type == _Type_GB))
-			    				{
-			    					if (Upgrade_CAN(CanFd, Type, chargingInfo[index]->Evboard_id, new_str, (char *)ShmSysConfigAndInfo->SysConfig.ModelName) == PASS)
-			    						return PASS;
-			    					else
-			    						return FAIL;
-			    				}
-			    			}
-			    		}
-			    		else
-			    		{
-			    			PRINTF_FUNC("Upgrad FD fail. \n");
-			    			isPass = false;
-			    		}
-
-			    		return isPass;
-			    		break;
-			    	}
+                            if(target == UPGRADE_RB)
+                            {
+                                isPass = Upgrade_UART(uartFd, Type, UPGRADE_DORC1, new_str, (char *)ShmSysConfigAndInfo->SysConfig.ModelName);
+                                if(isPass == PASS)
+                                {
+                                    retSucc++;
+                                }
+                                else
+                                {
+                                    retFail++;
+                                }
+                                PRINTF_FUNC("Upgrade %s", isPass == PASS ? "Success" : "Fail");
+                                sleep(3);
+                                isPass = Upgrade_UART(uartFd, Type, UPGRADE_DORC2, new_str, (char *)ShmSysConfigAndInfo->SysConfig.ModelName);
+                            }
+                            else
+                            {
+                                isPass = Upgrade_UART(uartFd, Type, target, new_str, (char *)ShmSysConfigAndInfo->SysConfig.ModelName);
+                            }
+
+                            close(fd);
+                            break;
+                    }
+
+                    if(support)
+                    {
+                        if(isPass == PASS)
+                        {
+                            retSucc++;
+                        }
+                        else
+                        {
+                            retFail++;
+                        }
+                        PRINTF_FUNC("Upgrade %s", isPass == PASS ? "Success" : "Fail");
+                    }
+			    }
+			    else
+			    {
+			        if(model[0] == 'D' && model[1] == 'D')
+			        {
+			            OneImageOnly = true;
+			            _UpgradeNeedReboot = TRUE;
+			            PRINTF_FUNC("Start Put Image To All Dispenser");
+			            PutImageToAllDispenser(new_str, dir->d_name);
+			            WaitAllDispenserUpgradeCompleted();
+			            PRINTF_FUNC("All Dispenser Upgrade Completed");
+			        }
 			    }
 			}
-			free(new_str);
-			free(ptr);
+
+		    sprintf(cmdBuf, "rm -f %s", new_str);
+		    system(cmdBuf);
+
+            free(new_str);
+            free(ptr);
 		}
 	}
 	free(dir);
 	closedir(d);
-	return FAIL;
+
+    if(retFail != 0)
+    {
+        return FAIL;
+    }
+
+    return PASS;
 }
 
 /*
@@ -4333,16 +4460,28 @@ void CheckFwUpdateFunction()
 	//PRINTF_FUNC("ShmSysConfigAndInfo->SysInfo.FirmwareUpdate = %d \n", ShmSysConfigAndInfo->SysInfo.FirmwareUpdate);
 	if (ShmSysConfigAndInfo->SysInfo.FirmwareUpdate == YES)
 	{
-		DEBUG_INFO_MSG("ftp : update start. \n");
-		KillTask();
+		DEBUG_INFO_MSG("ftp : update start.");
+		//KillTask();
+	    ChangeLcmByIndex(_LCM_FIX);
+	    system("killall Module_PrimaryComm");
+	    system("killall Module_InternalComm");
+
 		if (CheckUpdateProcess() == PASS)
-			DEBUG_INFO_MSG("ftp : update complete. \n");
+			DEBUG_INFO_MSG("ftp : update complete.");
 		else
-			DEBUG_INFO_MSG("ftp : update fail. \n");
+			DEBUG_INFO_MSG("ftp : update fail.");
 
 		ShmSysConfigAndInfo->SysInfo.FirmwareUpdate = NO;
 		sleep(5);
-		system("reboot -f");
+		if(_UpgradeNeedReboot)
+		{
+		    system("reboot -f");
+		}
+		else
+		{
+            KillTask();
+            system("/usr/bin/run_evse_restart.sh");
+		}
 	}
 	else if(ShmOCPP16Data->MsMsg.bits.UpdateFirmwareReq == YES)
 	{
@@ -4354,16 +4493,14 @@ void CheckFwUpdateFunction()
 			strcpy((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, "");
 			strcpy((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, "Installing");
 			ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = YES;
-			KillTask();
+			//KillTask();
+	        system("killall Module_PrimaryComm");
+	        system("killall Module_InternalComm");
 
 			for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _index++)
 			{
 				setChargerMode(_index, MODE_UPDATE);
 			}
-			for (byte _index = 0; _index < ShmSysConfigAndInfo->SysConfig.AcConnectorCount; _index++)
-			{
-				ac_chargingInfo[_index]->SystemStatus = MODE_UPDATE;
-			}
 
 			if (CheckUpdateProcess() == PASS)
 			{
@@ -4379,7 +4516,16 @@ void CheckFwUpdateFunction()
 			strcpy((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, "Installed");
 			ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = YES;
 			sleep(5);
-			system("reboot -f");
+
+	        if(_UpgradeNeedReboot)
+	        {
+	            system("reboot -f");
+	        }
+	        else
+	        {
+	            KillTask();
+	            system("/usr/bin/run_evse_restart.sh");
+	        }
 		}
 	}
 }
@@ -4607,12 +4753,9 @@ void UserPriceHandler(char *UserId, char *UserPrice)
             ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].UserPrice = CurrentRate;
             ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].AccountBalance = AccountBalance;
 
-            int DispenserIndex = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].ParentDispensetIndex;
-
-            if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[DispenserIndex].AuthorizeStatus == _AuthorizeStatus_Pass &&
-                ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].Parameter.bits.AuthorizeRequestType == _AuthorizeSrc_Local)
+            if(chargingInfo[i]->SystemStatus == S_AUTHORIZING)
             {
-                ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].Parameter.bits.AccountBalanceRequest = true;
+                AnnounceAccountBalance(i, AccountBalance);
             }
         }
     }
@@ -5687,25 +5830,27 @@ void CheckMiscCommandRequirement(void)
 {
     BOOL NeedAnnouncement = FALSE;
 
-    for(int i = 0; i < CONNECTOR_QUANTITY; i++)
+    if(ShmSysConfigAndInfo->SysInfo.FirmwareUpdate != YES)
     {
-        if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].Parameter.bits.AvailabilityRequest ||
-            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].Parameter.bits.RemoteStartRequest ||
-            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].Parameter.bits.AccountBalanceRequest)
+        for(int i = 0; i < CONNECTOR_QUANTITY; i++)
         {
-            NeedAnnouncement = TRUE;
-        }
+            if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].Parameter.bits.AvailabilityRequest ||
+                ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].Parameter.bits.RemoteStartRequest ||
+                ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].Parameter.bits.AccountBalanceRequest)
+            {
+                NeedAnnouncement = TRUE;
+            }
 
-        if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.ConnectorTimeoutConfigRequest ||
-            ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.DefaultPriceConfigRequest ||
-            ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.CurrencyConfigRequest ||
-            ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.HardwareRebootRequest ||
-            ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.SoftwareResetRequest)
-        {
-            NeedAnnouncement = TRUE;
+            if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.ConnectorTimeoutConfigRequest ||
+                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.DefaultPriceConfigRequest ||
+                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.CurrencyConfigRequest ||
+                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.HardwareRebootRequest ||
+                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[i].Setting.bits.SoftwareResetRequest)
+            {
+                NeedAnnouncement = TRUE;
+            }
         }
     }
-
     ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.MiscNeedAnnouncement = NeedAnnouncement;
 }
 
@@ -6008,6 +6153,12 @@ int main(void)
 
 						ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].Parameter.bits.StartWaitPlug = false;
 						ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].Parameter.bits.NeedCleanAuthorizeInfo = false;
+						ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].Parameter.bits.OutputLimitEnable = false;
+
+						chargingInfo[gun_index]->EvBatterytargetVoltage = 0;
+						chargingInfo[gun_index]->EvBatterytargetCurrent = 0;
+						ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].RemoteTargetVoltage = 0;
+						ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].RemoteTargetCurrent = 0;
 					}
 					else if (chargingInfo[gun_index]->SystemStatus == S_RESERVATION &&
 							isModeChange(gun_index))
@@ -6253,6 +6404,16 @@ int main(void)
 							ShmSysConfigAndInfo->SysInfo.OrderCharging = NO_DEFINE;
 						StopSystemTimeoutDet();
 						ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].Parameter.bits.PsuReleasable = false;
+						ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].MaxTotalChargingCurrent = ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent * 10;
+						ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].MaxTotalChargingPower = ShmSysConfigAndInfo->SysConfig.MaxChargingPower * 10;
+						ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].MaxOutputEnergy = ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy;
+						ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].MaxOutputDuration = ShmSysConfigAndInfo->SysConfig.MaxChargingDuration;
+
+						PRINTF_FUNC("Max Total Current %d, Max Total Power %d, Total Energy %d, Total Duration %d",
+                            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].MaxTotalChargingCurrent,
+                            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].MaxTotalChargingPower,
+                            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].MaxOutputEnergy,
+                            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[gun_index].MaxOutputDuration);
 					}
 
 					bool isRessign = false;
@@ -6333,6 +6494,7 @@ int main(void)
 						PRINTF_FUNC("=============Smart Charging : _REASSIGNED_COMP============= Step 6 \n");
 						ShmSysConfigAndInfo->SysInfo.MainChargingMode = _MAIN_CHARGING_MODE_AVER;
 						ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE;
+						setChargerMode(gun_index, MODE_PRECHARGE);
 					}
 
 					//PRINTF_FUNC("CurGunSelected = %d, gun_index = %d \n", ShmSysConfigAndInfo->SysInfo.CurGunSelected, gun_index);

二進制
EVSE/Projects/DO360/Images/FactoryDefaultConfig.bin


二進制
EVSE/Projects/DO360/Images/ramdisk.gz


+ 29 - 20
EVSE/Projects/define.h

@@ -108,15 +108,6 @@ Storage							0x0A200000-0x7FFFFFFF		1886 MB
     #define GENERAL_GUN_QUANTITY	0
     #define PSU_QUANTITY            2
     #define ONE_CONNECTOR_USE       0
-#elif DD360Audi
-    #define MAX_PSU_QUANTITY        62
-    #define CHAdeMO_QUANTITY        0
-    #define CCS_QUANTITY            2
-    #define GB_QUANTITY             0
-    #define AC_QUANTITY             0
-    #define GENERAL_GUN_QUANTITY	0
-    #define PSU_QUANTITY            2
-    #define ONE_CONNECTOR_USE       
 #elif DO360
     #define MAX_PSU_QUANTITY        62
     #define CHAdeMO_QUANTITY        0
@@ -547,7 +538,10 @@ typedef union
         unsigned int SoftwareResetRequest:1;            // 0: no request,   1: software reset request               (    ocpp   -> cabinet -> dispenser)
         unsigned int SoftwareResetConfirm:1;            // 0: no effect,    1: dispenser confirmed
         unsigned int AuthorizeTargetID:8;               // authorize target connector id
-        unsigned int res:15;
+        unsigned int FirmwareUpdateRequest:1;           // firmware update request
+        unsigned int FirmwareUpdateConfirm:1;           // firmware update start
+        unsigned int FirmwareUpdateCompleted:1;         // firmware update completed
+        unsigned int res:12;
     }bits;
 }DispenserSettingFlag;
 
@@ -587,6 +581,7 @@ struct DispenserModule
                                                 // 0: Authorize idle, 1: Authorize wait,   2: Authorizing
     unsigned char           AuthorizeStatus;    // 3: Authorize ok,   4: Authorizing fail
     DispenserSettingFlag    Setting;
+    char                    FwFileName[128];
 };
 
 struct ConnectionInfoData
@@ -654,7 +649,9 @@ typedef union
         unsigned int  NeedCleanAuthorizeInfo:1;         //
         unsigned int  AuthorizeRequest:1;               // 0: idle,         1: requesting                                       ( dispenser -> cabinet)
         unsigned int  SwipeRfidConfirm:1;
-        unsigned int  res:14;
+        unsigned int  OutputLimitEnable:1;              // 0: disable,      1: enable
+        unsigned int  ChargingPermission:2;             // 0: not allowed,  1: allowed,         2: wait
+        unsigned int  res:11;
     }bits;
 }ConnectorParameter;
 
@@ -675,6 +672,18 @@ struct ConnectorInfoData
     unsigned int            RemoteRemainChargingDuration;   // remain charging duration from connector, unit: 1s
     unsigned char           RemoteSoc;                      // ev battery soc from connector, unit: 1%
 
+    unsigned short          RemoteMaxPhysicalVoltage;       // max physical voltage from connector, unit: 0.1V
+    unsigned short          RemoteMaxPhysicalCurrent;       // max physical current from connector, unit: 0.1A
+    unsigned short          RemoteTargetVoltage;            // target voltage from connector, unit: 0.1V
+    unsigned short          RemoteTargetCurrent;            // target current from connector, unit: 0.1A
+    unsigned short          RemoteLimitVoltage;             // limit voltage to psu voltage command, unit: 0.1V
+    unsigned short          RemoteLimitCurrent;             // limit current to psu current command, unit: 0.1A
+
+    unsigned short          MaxTotalChargingCurrent;        // max total output current, unit: 0.1A
+    unsigned short          MaxTotalChargingPower;          // max total output power, unit: 0.1kw
+    unsigned short          MaxOutputEnergy;                //0: no limit,  1 ~ 65535   kWh
+    unsigned short          MaxOutputDuration;              //0: no limit,  1 ~ 65535   minutes
+
     unsigned int            UserPrice;                      // connector user's user price, unit: 0.01 (dollar / kWh)
     unsigned int            TotalCost;                      // connector user's total cost, unit: 0.01 dollar
     int                     AccountBalance;                 // connector user's account balance, unit: 0.01 dollar
@@ -1065,10 +1074,10 @@ char AlarmStatusCode[128][6]=
 	"012300",	// System AC output OCP L3
 	"012301",	// Circuit Short L2
 	"012302",	// Circuit Short L3
-	"012303",	// CCS liquid chiller water level warning
-	"012304",	// connection disconnected from power cabinet
-	"012305",	// Meter communication timeout
-	"012306",	// The dip switch of the PSU may be incorrect
+	"012303",   // CCS liquid chiller water level warning
+	"012304",   // connection disconnected from power cabinet
+	"012305",   // Meter communication timeout
+	"012306",   // The dip switch of the PSU may be incorrect
 };
 struct AlarmCodeData
 {
@@ -1194,12 +1203,12 @@ struct AlarmCodeData
 			unsigned char SystemAcOutputOCPL3:1;					//bit 4
 			unsigned char CircuitShortL2:1;							//bit 5
 			unsigned char CircuitShortL3:1;							//bit 6
-			unsigned char CcsLiquidChillerWaterLevelWarning:1;		//bit 7
+			unsigned char CcsLiquidChillerWaterLevelWarning:1;      //bit 7
 			//AlarmVal[13]
-			unsigned char DisconnectedFromDo :1;					//bit 0
-			unsigned char MeterCommTimeout:1;						//bit 1
-			unsigned char PsuDipSwitchStestFail:1; 					//bit 1
-			unsigned char Reserved :5;								//bit 3~bit7
+            unsigned char DisconnectedFromDo:1;                     //bit 0
+            unsigned char MeterCommTimeout:1;                       //bit 1
+            unsigned char PsuDipSwitchStestFail:1;                  //bit 2
+            unsigned char Reserved:5;                               //bit 3~bit7
 		}bits;
 	}AlarmEvents;
 };