Browse Source

2020-12-25 / Wendell
Actions
1. dispenser firmware upgrade function
2. power cabinet rc2 firmware upgrade function
3. connector maximum output current is determined by model name
4. fix account balance will be clean to 0 affter reveived user price
5. modify default MaxChargingCurrent = 0

Files
1. As follow commit history

Image version : D0.08.XX.XXXX.XX

Wendell 4 năm trước cách đây
mục cha
commit
82a7d69b58

+ 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)

+ 325 - 164
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;
@@ -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;

BIN
EVSE/Projects/DO360/Images/FactoryDefaultConfig.bin


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;
 };

BIN
EVSE/rootfs/root/OcppBackend20