瀏覽代碼

Merge branch 'master' into DO360

Wendell 3 年之前
父節點
當前提交
3c679653d8
共有 100 個文件被更改,包括 4529 次插入1854 次删除
  1. 104 0
      EVSE/Modularization/Infypwr_PsuCommObj.c
  2. 7 1
      EVSE/Modularization/Infypwr_PsuCommObj.h
  3. 3 3
      EVSE/Modularization/Makefile
  4. 5 5
      EVSE/Modularization/WebService.c
  5. 279 207
      EVSE/Modularization/ocpp20/MessageHandler.c
  6. 13 5
      EVSE/Modularization/ocpp20/Module_OcppBackend20.c
  7. 3 1
      EVSE/Modularization/ocpp20/Module_OcppBackend20.h
  8. 397 187
      EVSE/Modularization/ocppfiles/MessageHandler.c
  9. 1 0
      EVSE/Modularization/ocppfiles/MessageHandler.h
  10. 17 9
      EVSE/Modularization/ocppfiles/Module_OcppBackend.c
  11. 3 1
      EVSE/Modularization/ocppfiles/Module_OcppBackend.h
  12. 340 217
      EVSE/Modularization/ocppph/MessageHandler.c
  13. 1 0
      EVSE/Modularization/ocppph/MessageHandler.h
  14. 17 9
      EVSE/Modularization/ocppph/Module_OcppBackend.c
  15. 3 1
      EVSE/Modularization/ocppph/Module_OcppBackend.h
  16. 147 241
      EVSE/Projects/AW-CCS/Apps/CCS/Module_CCS.c
  17. 1 0
      EVSE/Projects/AW-CCS/Apps/CCS/Module_CCS.h
  18. 184 151
      EVSE/Projects/AW-CCS/Apps/CCS/v2g/api/api.c
  19. 6 4
      EVSE/Projects/AW-CCS/Apps/CCS/v2g/api/api.h
  20. 332 112
      EVSE/Projects/AW-CCS/Apps/LCM/Module_LcmControl.c
  21. 1 2
      EVSE/Projects/AW-CCS/Apps/LCM/lcmComm_dgus.c
  22. 23 4
      EVSE/Projects/AW-CCS/Apps/LCM/lcmComm_dgus.h
  23. 161 58
      EVSE/Projects/AW-CCS/Apps/Module_AlarmDetect.c
  24. 23 0
      EVSE/Projects/AW-CCS/Apps/Module_ConfigTools.c
  25. 2 165
      EVSE/Projects/AW-CCS/Apps/Module_InternalComm.c
  26. 18 6
      EVSE/Projects/AW-CCS/Apps/Module_PowerSharing.c
  27. 2 0
      EVSE/Projects/AW-CCS/Apps/Module_PowerSharing.h
  28. 161 40
      EVSE/Projects/AW-CCS/Apps/main.c
  29. 14 9
      EVSE/Projects/AW-CCS/Apps/main.h
  30. 二進制
      EVSE/Projects/AW-CCS/Images/FactoryDefaultConfig.bin
  31. 二進制
      EVSE/Projects/AW-CCS/Images/ramdisk.gz
  32. 198 84
      EVSE/Projects/AW-Regular/Apps/Module_ConfigTools.c
  33. 184 0
      EVSE/Projects/DD360/Apps/CSU/CheckSystemTask.c
  34. 60 0
      EVSE/Projects/DD360/Apps/CSU/CheckSystemTask.h
  35. 12 0
      EVSE/Projects/DD360/Apps/CSU/Primary.c
  36. 15 0
      EVSE/Projects/DD360/Apps/CSU/SelfTest.c
  37. 8 0
      EVSE/Projects/DD360/Apps/CSU/UpgradeFW.c
  38. 39 17
      EVSE/Projects/DD360/Apps/CSU/WatchDog.c
  39. 48 0
      EVSE/Projects/DD360/Apps/CSU/WatchDog.c.old
  40. 145 20
      EVSE/Projects/DD360/Apps/CSU/main.c
  41. 106 82
      EVSE/Projects/DD360/Apps/Define/define.h
  42. 4 2
      EVSE/Projects/DD360/Apps/Makefile
  43. 74 6
      EVSE/Projects/DD360/Apps/ModuleDoComm/DoComm.c
  44. 5 0
      EVSE/Projects/DD360/Apps/ModuleDoComm/DoComm.h
  45. 4 2
      EVSE/Projects/DD360/Apps/ModuleEvComm/AbnormalState.c
  46. 14 9
      EVSE/Projects/DD360/Apps/ModuleEvComm/Module_EvTxComm.c
  47. 4 1
      EVSE/Projects/DD360/Apps/ModuleInternalComm/Module_InternalComm.c
  48. 41 4
      EVSE/Projects/DD360/Apps/ModuleInternalComm/RelayBoard.c
  49. 39 0
      EVSE/Projects/DD360/Apps/ModuleLcmCtrl/Module_LcmControl.c
  50. 54 6
      EVSE/Projects/DD360/Apps/ModulePrimary/Module_PrimaryComm.c
  51. 1 0
      EVSE/Projects/DD360/Apps/ModulePrimary/Module_PrimaryComm.h
  52. 4 0
      EVSE/Projects/DD360/Apps/Script/kill.sh
  53. 35 17
      EVSE/Projects/DD360/Apps/ShareMemory/shmMem.c
  54. 二進制
      EVSE/Projects/DD360/Apps/UnsafetyOutputTask
  55. 二進制
      EVSE/Projects/DD360/Images/ramdisk.gz
  56. 二進制
      EVSE/Projects/DD360/output/FactoryConfig
  57. 二進制
      EVSE/Projects/DD360/output/Module_DoComm
  58. 二進制
      EVSE/Projects/DD360/output/Module_EvComm
  59. 二進制
      EVSE/Projects/DD360/output/Module_EventLogging
  60. 二進制
      EVSE/Projects/DD360/output/Module_InternalComm
  61. 二進制
      EVSE/Projects/DD360/output/Module_LcmControl
  62. 二進制
      EVSE/Projects/DD360/output/Module_PrimaryComm
  63. 二進制
      EVSE/Projects/DD360/output/ReadCmdline
  64. 二進制
      EVSE/Projects/DD360/output/main
  65. 184 0
      EVSE/Projects/DD360Audi/Apps/CSU/CheckSystemTask.c
  66. 60 0
      EVSE/Projects/DD360Audi/Apps/CSU/CheckSystemTask.h
  67. 12 0
      EVSE/Projects/DD360Audi/Apps/CSU/Primary.c
  68. 15 0
      EVSE/Projects/DD360Audi/Apps/CSU/SelfTest.c
  69. 8 0
      EVSE/Projects/DD360Audi/Apps/CSU/UpgradeFW.c
  70. 39 17
      EVSE/Projects/DD360Audi/Apps/CSU/WatchDog.c
  71. 48 0
      EVSE/Projects/DD360Audi/Apps/CSU/WatchDog.c.old
  72. 145 20
      EVSE/Projects/DD360Audi/Apps/CSU/main.c
  73. 106 82
      EVSE/Projects/DD360Audi/Apps/Define/define.h
  74. 4 2
      EVSE/Projects/DD360Audi/Apps/Makefile
  75. 74 6
      EVSE/Projects/DD360Audi/Apps/ModuleDoComm/DoComm.c
  76. 5 0
      EVSE/Projects/DD360Audi/Apps/ModuleDoComm/DoComm.h
  77. 4 2
      EVSE/Projects/DD360Audi/Apps/ModuleEvComm/AbnormalState.c
  78. 14 9
      EVSE/Projects/DD360Audi/Apps/ModuleEvComm/Module_EvTxComm.c
  79. 4 1
      EVSE/Projects/DD360Audi/Apps/ModuleInternalComm/Module_InternalComm.c
  80. 41 4
      EVSE/Projects/DD360Audi/Apps/ModuleInternalComm/RelayBoard.c
  81. 39 0
      EVSE/Projects/DD360Audi/Apps/ModuleLcmCtrl/Module_LcmControl.c
  82. 54 6
      EVSE/Projects/DD360Audi/Apps/ModulePrimary/Module_PrimaryComm.c
  83. 1 0
      EVSE/Projects/DD360Audi/Apps/ModulePrimary/Module_PrimaryComm.h
  84. 4 0
      EVSE/Projects/DD360Audi/Apps/Script/kill.sh
  85. 35 17
      EVSE/Projects/DD360Audi/Apps/ShareMemory/shmMem.c
  86. 二進制
      EVSE/Projects/DD360Audi/Images/ramdisk.gz
  87. 二進制
      EVSE/Projects/DD360Audi/output/FactoryConfig
  88. 二進制
      EVSE/Projects/DD360Audi/output/Module_DoComm
  89. 二進制
      EVSE/Projects/DD360Audi/output/Module_EvComm
  90. 二進制
      EVSE/Projects/DD360Audi/output/Module_EventLogging
  91. 二進制
      EVSE/Projects/DD360Audi/output/Module_InternalComm
  92. 二進制
      EVSE/Projects/DD360Audi/output/Module_LcmControl
  93. 二進制
      EVSE/Projects/DD360Audi/output/Module_PrimaryComm
  94. 二進制
      EVSE/Projects/DD360Audi/output/ReadCmdline
  95. 二進制
      EVSE/Projects/DD360Audi/output/main
  96. 0 0
      EVSE/Projects/DD360ComBox/Apps/.metadata/.lock
  97. 184 0
      EVSE/Projects/DD360ComBox/Apps/CSU/CheckSystemTask.c
  98. 60 0
      EVSE/Projects/DD360ComBox/Apps/CSU/CheckSystemTask.h
  99. 12 0
      EVSE/Projects/DD360ComBox/Apps/CSU/Primary.c
  100. 15 0
      EVSE/Projects/DD360ComBox/Apps/CSU/SelfTest.c

+ 104 - 0
EVSE/Modularization/Infypwr_PsuCommObj.c

@@ -492,6 +492,25 @@ void ReceiveDataFromCanBus()
                         //PRINTF_LIB_FUNC("address = %d, abVol = %d, bcVol = %d, caVol = %d \n", address, abVol, bcVol, caVol);
                     }
                         break;
+                    case PSU_RCmd_ModuleOutputVolCur_F:
+                    {
+                    	if (!colFinished)
+							break;
+
+						byte vol[4], cur[4];
+
+						memcpy(vol, frame.data, 4);
+						memcpy(cur, frame.data + 4, 4);
+
+						if (!GetRealIndexByGroup(&address))
+							break;
+
+						float _Vol = IEEE_754_to_float(vol);
+						float _Cur = IEEE_754_to_float(cur);
+
+                    	return_get_output(address, _Vol, _Cur);
+                    }
+                    	break;
                     default:
                         break;
                 }
@@ -833,6 +852,91 @@ void SetDipSwitchMode()
 
     SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
 }
+
+void PresentSingleOutput(byte moduleIndex, int voltage, int current)
+{
+	byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_WCmd_ModuleSetOutput;
+
+	int Vol = voltage * 100;
+	int Cur = current * 100;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+
+	// 輸出電壓
+	data[0] = (Vol >> 24) & 0xFF;
+	data[1] = (Vol >> 16) & 0xFF;
+	data[2] = (Vol >> 8) & 0xFF;
+	data[3] = Vol & 0xFF;
+	// 輸出電流
+	data[4] = (Cur >> 24) & 0xFF;
+	data[5] = (Cur >> 16) & 0xFF;
+	data[6] = (Cur >> 8) & 0xFF;
+	data[7] = Cur & 0xFF;
+
+	PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    PwrFrameMsg.InfyBits.DestinationAddress = moduleIndex;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void SwitchSinglePower(byte moduleIndex, byte value)
+{
+	byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_WCmd_ModulePowerOnOff;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	// 1 : 關機
+	// 0 : 開機
+	data[0] = value;
+
+	PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    PwrFrameMsg.InfyBits.DestinationAddress = moduleIndex;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void FlashSingleLed(byte moduleIndex, byte value)
+{
+	byte data[8];
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_WCmd_ModuleFlashLed;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	// 1 : 閃爍
+	// 0 : 正常
+	data[0] = value;
+
+	PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    PwrFrameMsg.InfyBits.DestinationAddress = moduleIndex;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
+void GetSingleModuleOutputF(byte moduleIndex)
+{
+	byte data[8];
+	PwrFrame PwrFrameMsg;
+	PwrFrameMsg.PwrMessage = 0;
+	PwrFrameMsg.InfyBits.CmdValue = PSU_RCmd_ModuleOutputVolCur_F;
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+
+	PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+	PwrFrameMsg.InfyBits.DestinationAddress = moduleIndex;
+	PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
+
 /**********************************************************************************/
 /***                                                                            ***/
 /***                                   Get                                      ***/

+ 7 - 1
EVSE/Modularization/Infypwr_PsuCommObj.h

@@ -236,6 +236,12 @@ void FanNoiseInfo(byte group, byte value);
 void SetWalkInConfig(byte group, byte enable, byte sec);
 void SetDipSwitchMode();
 
+// set only one powermodule to output
+void PresentSingleOutput(byte moduleIndex, int voltage, int current);
+void SwitchSinglePower(byte moduleIndex, byte value);
+void FlashSingleLed(byte moduleIndex, byte value);
+void GetSingleModuleOutputF(byte moduleIndex);
+
 /*Ver : 9.06 used*/
 void SetDirModulePresentOutput(byte group, int voltage, int current, byte _switch, byte _interRelay);
 /*Get Cmd*/
@@ -273,7 +279,7 @@ void RefreshInputVol(void *func);
 void (*return_input_vol)(byte address, unsigned short vol1, unsigned short vol2, unsigned short vol3);
 
 void RefreshGetOutput(void *func);
-void (*return_get_output)(byte address, unsigned short outVol, unsigned short outCur);
+void (*return_get_output)(byte address, float outVol, float outCur);
 
 void RefreshGetOutputF(void *func);
 void (*return_get_output_float)(byte group, float outVol, float outCur);

+ 3 - 3
EVSE/Modularization/Makefile

@@ -72,17 +72,17 @@ WebServiceLib:
 
 Ocppph:
 	rm -f OcppBackendPH;
-	$(CC) -D $(TLS_EXPIRED) -D $(Project) -D__USE_XOPEN -D_GNU_SOURCE ./ocppph/Module_OcppBackend.c ./ocppph/MessageHandler.c ./ocppph/JsonParser.c ./ocppph/SystemLogMessage.c ./ocppph/hashmap.c ./ocppph/common.c -I ../Projects -I ../GPL/libwebsockets-2.2.2-stable/release/include -I ../GPL/json-c-json-c-0.13.1-20180305/release/include -L ../GPL/libwebsockets-2.2.2-stable/release/lib -L ../GPL/openssl-1.0.2g/release/lib -L ../GPL/json-c-json-c-0.13.1-20180305/release/lib -lwebsockets -luuid -lpthread -lc -lsqlite3 -ljson-c -o OcppBackendPH
+	$(CC) -D $(TLS_EXPIRED) -D $(Project) -D__USE_XOPEN -D_GNU_SOURCE ./ocppph/Module_OcppBackend.c ./ocppph/MessageHandler.c ./ocppph/JsonParser.c ./ocppph/SystemLogMessage.c ./ocppph/hashmap.c ./ocppph/common.c -I ../Projects -I ../GPL/libwebsockets-2.2.2-stable/release/include -I ../GPL/json-c-json-c-0.13.1-20180305/release/include -include ./Module_RatedCurrent.h  -L ../GPL/libwebsockets-2.2.2-stable/release/lib -L ../GPL/openssl-1.0.2g/release/lib -L ../GPL/json-c-json-c-0.13.1-20180305/release/lib -L ./ -lwebsockets -luuid -lpthread -lc -lsqlite3 -ljson-c -lModule_RatedCurrent -o OcppBackendPH
 	mv -f OcppBackendPH ../rootfs/root/
 
 Ocpp16:
 	rm -f OcppBackend;
-	$(CC) -D $(TLS_EXPIRED) -D $(Project) -D__USE_XOPEN -D_GNU_SOURCE ./ocppfiles/Module_OcppBackend.c ./ocppfiles/MessageHandler.c ./ocppfiles/JsonParser.c ./ocppfiles/SystemLogMessage.c ./ocppfiles/hashmap.c ./ocppfiles/common.c -I ../Projects -I ../GPL/libwebsockets-2.2.2-stable/release/include -I ../GPL/json-c-json-c-0.13.1-20180305/release/include -L ../GPL/libwebsockets-2.2.2-stable/release/lib -L ../GPL/openssl-1.0.2g/release/lib -L ../GPL/json-c-json-c-0.13.1-20180305/release/lib -lwebsockets -luuid -lpthread -lc -lsqlite3 -ljson-c -o OcppBackend
+	$(CC) -D $(TLS_EXPIRED) -D $(Project) -D__USE_XOPEN -D_GNU_SOURCE ./ocppfiles/Module_OcppBackend.c ./ocppfiles/MessageHandler.c ./ocppfiles/JsonParser.c ./ocppfiles/SystemLogMessage.c ./ocppfiles/hashmap.c ./ocppfiles/common.c -I ../Projects -I ../GPL/libwebsockets-2.2.2-stable/release/include -I ../GPL/json-c-json-c-0.13.1-20180305/release/include -include ./Module_RatedCurrent.h -L ../GPL/libwebsockets-2.2.2-stable/release/lib -L ../GPL/openssl-1.0.2g/release/lib -L ../GPL/json-c-json-c-0.13.1-20180305/release/lib -L ./ -lwebsockets -luuid -lpthread -lc -lsqlite3 -ljson-c -lModule_RatedCurrent -o OcppBackend
 	mv -f OcppBackend ../rootfs/root/
 
 Ocpp20:
 	rm -f OcppBackend20;
-	$(CC) -D $(TLS_EXPIRED) -D $(Project) -D__USE_XOPEN -D_GNU_SOURCE ./ocpp20/Module_OcppBackend20.c ./ocpp20/MessageHandler.c ./ocpp20/JsonParser.c ./ocpp20/SystemLogMessage.c ./ocpp20/hashmap.c ./ocpp20/common.c -I ../Projects -I ../GPL/libwebsockets-2.2.2-stable/release/include -I ../GPL/json-c-json-c-0.13.1-20180305/release/include -L ../GPL/libwebsockets-2.2.2-stable/release/lib -L ../GPL/openssl-1.0.2g/release/lib -L ../GPL/json-c-json-c-0.13.1-20180305/release/lib -lwebsockets -luuid -lpthread -lc -lsqlite3 -ljson-c -o OcppBackend20
+	$(CC) -D $(TLS_EXPIRED) -D $(Project) -D__USE_XOPEN -D_GNU_SOURCE ./ocpp20/Module_OcppBackend20.c ./ocpp20/MessageHandler.c ./ocpp20/JsonParser.c ./ocpp20/SystemLogMessage.c ./ocpp20/hashmap.c ./ocpp20/common.c -I ../Projects -I ../GPL/libwebsockets-2.2.2-stable/release/include -I ../GPL/json-c-json-c-0.13.1-20180305/release/include -include ./Module_RatedCurrent.h  -L ../GPL/libwebsockets-2.2.2-stable/release/lib -L ../GPL/openssl-1.0.2g/release/lib -L ../GPL/json-c-json-c-0.13.1-20180305/release/lib -L ./ -lwebsockets -luuid -lpthread -lc -lsqlite3 -ljson-c -lModule_RatedCurrent -o OcppBackend20
 	mv -f OcppBackend20 ../rootfs/root/
 
 

+ 5 - 5
EVSE/Modularization/WebService.c

@@ -1399,7 +1399,7 @@ int main(int argc, char *argv[]) {
 				PsuQuantity = RatedPower/30;
 			}
 		}
-		if(strcmp(IsDO, "DO") == 0 || strcmp(IsDO, "DK") == 0){
+		if(strcmp(IsDO, "DO") == 0 || strcmp(IsDO, "DK") == 0 || strcmp(IsDO, "DB") == 0){
 		}
 		
 		struct json_object *jobj1;
@@ -1726,7 +1726,7 @@ int main(int argc, char *argv[]) {
 				json_object_array_add(FwSecondVersionArr,FwSecondVersion[i]);
 			}
 		}
-		if(strcmp(IsDO, "DO") == 0 || strcmp(IsDO, "DK") == 0){
+		if(strcmp(IsDO, "DO") == 0 || strcmp(IsDO, "DK") == 0 || strcmp(IsDO, "DB") == 0){
 			if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.DispenserQuantity>4 || ShmSysConfigAndInfo->SysInfo.DispenserInfo.DispenserQuantity<0)ShmSysConfigAndInfo->SysInfo.DispenserInfo.DispenserQuantity=0;
 			DispenserQuantity = json_object_new_int(ShmSysConfigAndInfo->SysInfo.DispenserInfo.DispenserQuantity);
 			TotalConnectorQuantity = json_object_new_int(ShmSysConfigAndInfo->SysInfo.DispenserInfo.TotalConnectorQuantity);
@@ -2235,7 +2235,7 @@ int main(int argc, char *argv[]) {
 				AcGunQty++;
 			}
 		}
-		if(strcmp(IsDO, "DO") == 0 || strcmp(IsDO, "DK") == 0){
+		if(strcmp(IsDO, "DO") == 0 || strcmp(IsDO, "DK") == 0 || strcmp(IsDO, "DB") == 0){
 			if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.TotalConnectorQuantity>4 || ShmSysConfigAndInfo->SysInfo.DispenserInfo.TotalConnectorQuantity<0)ShmSysConfigAndInfo->SysInfo.DispenserInfo.TotalConnectorQuantity=0;
 			int DDTotalConnectorQuantity = ShmSysConfigAndInfo->SysInfo.DispenserInfo.TotalConnectorQuantity;
 			for(int i=0;i<DDTotalConnectorQuantity;i++){
@@ -2394,7 +2394,7 @@ int main(int argc, char *argv[]) {
 			json_object_object_add(jobj1,"FwPrimaryVersion",FwPrimaryVersionArr);
 			json_object_object_add(jobj1,"FwSecondVersion",FwSecondVersionArr);
 		}
-		if(strcmp(IsDO, "DO") == 0 || strcmp(IsDO, "DK") == 0){
+		if(strcmp(IsDO, "DO") == 0 || strcmp(IsDO, "DK") == 0 || strcmp(IsDO, "DB") == 0){
 			json_object_object_add(jobj1,"DispenserQuantity",DispenserQuantity);
 			json_object_object_add(jobj1,"TotalConnectorQuantity",TotalConnectorQuantity);
 			json_object_object_add(jobj1,"DDModelName",DDModelNameArr);
@@ -2587,7 +2587,7 @@ int main(int argc, char *argv[]) {
 			}
 			json_object_object_add(jobj2,"ChargingInfo3",ChargingInfo3);
 		}
-		if(strcmp(IsDO, "DO") == 0 || strcmp(IsDO, "DK") == 0){
+		if(strcmp(IsDO, "DO") == 0 || strcmp(IsDO, "DK") == 0 || strcmp(IsDO, "DB") == 0){
 			if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.TotalConnectorQuantity>4|| ShmSysConfigAndInfo->SysInfo.DispenserInfo.TotalConnectorQuantity<0)ShmSysConfigAndInfo->SysInfo.DispenserInfo.TotalConnectorQuantity=0;
 			int DDTotalConnectorQuantity = ShmSysConfigAndInfo->SysInfo.DispenserInfo.TotalConnectorQuantity;
 			DDChargingInfo1=json_object_new_object();

文件差異過大導致無法顯示
+ 279 - 207
EVSE/Modularization/ocpp20/MessageHandler.c


+ 13 - 5
EVSE/Modularization/ocpp20/Module_OcppBackend20.c

@@ -13,6 +13,7 @@ struct StartTime
 {
 	unsigned int connect;
 	unsigned int bootNotification;
+	unsigned int reConnect;
 }startTime;
 
 //==========================================
@@ -1201,11 +1202,18 @@ int main(void)
 
 				if((changeChageWebSocketPingInterval == TRUE) || (GetOcppConnStatus() == 0))
 				{
-					DEBUG_INFO("GetOcppConnStatus() = %d\n", GetOcppConnStatus());
-					changeChageWebSocketPingInterval = FALSE;
-					lws_context_destroy(context);
-					ConnectionEstablished = 0;
-					context = NULL;
+					if(((time((time_t*)NULL)-startTime.reConnect) >= 3) || (((time((time_t*)NULL)-startTime.reConnect) < 0)))
+					{
+						DEBUG_INFO("GetOcppConnStatus() = %d\n", GetOcppConnStatus());
+						changeChageWebSocketPingInterval = FALSE;
+						lws_context_destroy(context);
+						ConnectionEstablished = 0;
+						context = NULL;
+					}
+				}
+				else
+				{
+					startTime.reConnect = time((time_t*)NULL);
 				}
 			}
 		}

+ 3 - 1
EVSE/Modularization/ocpp20/Module_OcppBackend20.h

@@ -17,16 +17,18 @@
 #include 	<sys/ipc.h>
 #include 	<sys/shm.h>
 #include 	<sys/mman.h>
+#include 	<sys/sysinfo.h>
 #include 	<linux/wireless.h>
 #include 	<linux/sockios.h>
 #include 	<linux/socket.h>
+#include 	<linux/unistd.h>
+#include 	<linux/kernel.h>
 #include 	<arpa/inet.h>
 #include 	<netinet/in.h>
 #include 	<unistd.h>
 #include 	<stdarg.h>
 #include    <stdio.h>
 #include    <stdlib.h>
-#include    <unistd.h>
 #include    <fcntl.h>
 #include    <termios.h>
 #include 	<errno.h>

文件差異過大導致無法顯示
+ 397 - 187
EVSE/Modularization/ocppfiles/MessageHandler.c


+ 1 - 0
EVSE/Modularization/ocppfiles/MessageHandler.h

@@ -395,6 +395,7 @@ enum GetConfigurationKey {
 	GetConfiguration_TimeOffset,
 	GetConfiguration_NextTimeOffsetTransitionDateTime,
 	GetConfiguration_TimeOffsetNextTransition,
+	GetConfiguration_SystemUptimeSec,
 	GetConfiguration_LocalAuthListEnabled,
 	GetConfiguration_LocalAuthListMaxLength,
 	GetConfiguration_SendLocalListMaxLength,

+ 17 - 9
EVSE/Modularization/ocppfiles/Module_OcppBackend.c

@@ -13,6 +13,7 @@ struct StartTime
 {
 	unsigned int connect;
 	unsigned int bootNotification;
+	unsigned int reConnect;
 }startTime;
 
 //==========================================
@@ -1542,17 +1543,24 @@ int main(void)
 
 				if((changeChageWebSocketPingInterval == TRUE) || (GetOcppConnStatus() == 0))
 				{
-					DEBUG_INFO("GetOcppConnStatus() = %d\n", GetOcppConnStatus());
-
-					if(changeChageWebSocketPingInterval)
+					if(((time((time_t*)NULL)-startTime.reConnect) >= 3) || ((time((time_t*)NULL)-startTime.reConnect) < 0))
 					{
-						DEBUG_INFO("Websocket ping interval changed request.\n");
-						changeChageWebSocketPingInterval = FALSE;
-					}
+						DEBUG_INFO("GetOcppConnStatus() = %d\n", GetOcppConnStatus());
 
-					lws_context_destroy(context);
-					ConnectionEstablished = 0;
-					context = NULL;
+						if(changeChageWebSocketPingInterval)
+						{
+							DEBUG_INFO("Websocket ping interval changed request.\n");
+							changeChageWebSocketPingInterval = FALSE;
+						}
+
+						lws_context_destroy(context);
+						ConnectionEstablished = 0;
+						context = NULL;
+					}
+				}
+				else
+				{
+					startTime.reConnect = time((time_t*)NULL);
 				}
 			}
 		}

+ 3 - 1
EVSE/Modularization/ocppfiles/Module_OcppBackend.h

@@ -17,16 +17,18 @@
 #include 	<sys/ipc.h>
 #include 	<sys/shm.h>
 #include 	<sys/mman.h>
+#include 	<sys/sysinfo.h>
 #include 	<linux/wireless.h>
 #include 	<linux/sockios.h>
 #include 	<linux/socket.h>
+#include 	<linux/unistd.h>
+#include 	<linux/kernel.h>
 #include 	<arpa/inet.h>
 #include 	<netinet/in.h>
 #include 	<unistd.h>
 #include 	<stdarg.h>
 #include    <stdio.h>
 #include    <stdlib.h>
-#include    <unistd.h>
 #include    <fcntl.h>
 #include    <termios.h>
 #include 	<errno.h>

+ 340 - 217
EVSE/Modularization/ocppph/MessageHandler.c

@@ -1202,15 +1202,6 @@ void checkChargePointMaxProfile(uint32_t durationReq, struct StructChargingProfi
 	{
 		fp = fopen(profileFileName, "r");
 
-		for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.ChargingSchedule.ChargingSchedulePeriod);idxPeriod++)
-		{
-			maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].StartPeriod = -1;
-			maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].Limit = -1;
-			maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].NumberPhases = 3;
-		}
-		maxProfile.ChargingProfileId = -1;
-		maxProfile.StackLevel = -1;
-
 		while(getline(&line, &len, fp) != -1)
 		{
 			json_object *obj = NULL;
@@ -1222,7 +1213,7 @@ void checkChargePointMaxProfile(uint32_t durationReq, struct StructChargingProfi
 			}
 			else
 			{
-				if((json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "ChargingProfileId")) != maxProfile.ChargingProfileId) &&
+				if((json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingProfileId")) != maxProfile.ChargingProfileId) &&
 				   (json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "stackLevel")) >= maxProfile.StackLevel)
 				  )
 				{
@@ -1246,6 +1237,15 @@ void checkChargePointMaxProfile(uint32_t durationReq, struct StructChargingProfi
 
 							if((DiffTimebWithNowSec(tbFrom)>=0) && (DiffTimebWithNowSec(tbTo)<=0))
 							{
+								for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.ChargingSchedule.ChargingSchedulePeriod);idxPeriod++)
+								{
+									maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].StartPeriod = -1;
+									maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].Limit = -1;
+									maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].NumberPhases = 3;
+								}
+								maxProfile.ChargingProfileId = -1;
+								maxProfile.StackLevel = -1;
+
 								if(maxProfile.ChargingProfileId == -1)
 									DEBUG_INFO("MaxProfile found.\n");
 								else
@@ -1303,9 +1303,9 @@ void checkChargePointMaxProfile(uint32_t durationReq, struct StructChargingProfi
 									sprintf((char*)maxProfile.ValidTo, " ");
 								}
 
-								if(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "RecurrencyKind") != NULL)
+								if(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "recurrencyKind") != NULL)
 								{
-									sprintf((char*)maxProfile.RecurrencyKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "RecurrencyKind")));
+									sprintf((char*)maxProfile.RecurrencyKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "recurrencyKind")));
 								}
 								else
 								{
@@ -1352,6 +1352,15 @@ void checkChargePointMaxProfile(uint32_t durationReq, struct StructChargingProfi
 					}
 					else
 					{
+						for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.ChargingSchedule.ChargingSchedulePeriod);idxPeriod++)
+						{
+							maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].StartPeriod = -1;
+							maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].Limit = -1;
+							maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].NumberPhases = 3;
+						}
+						maxProfile.ChargingProfileId = -1;
+						maxProfile.StackLevel = -1;
+
 						if(maxProfile.ChargingProfileId == -1)
 							DEBUG_INFO("MaxProfile found.\n");
 						else
@@ -1408,9 +1417,9 @@ void checkChargePointMaxProfile(uint32_t durationReq, struct StructChargingProfi
 							sprintf((char*)maxProfile.ValidTo, " ");
 						}
 
-						if(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "RecurrencyKind") != NULL)
+						if(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "recurrencyKind") != NULL)
 						{
-							sprintf((char*)maxProfile.RecurrencyKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "RecurrencyKind")));
+							sprintf((char*)maxProfile.RecurrencyKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "recurrencyKind")));
 						}
 						else
 						{
@@ -1467,7 +1476,7 @@ void checkChargePointMaxProfile(uint32_t durationReq, struct StructChargingProfi
 			DEBUG_INFO("Profile valid from: %s\n", maxProfile.ValidFrom);
 			DEBUG_INFO("Profile valid to: %s\n", maxProfile.ValidTo);
 			DEBUG_INFO("Profile ChargingProfileKind: %s\n", maxProfile.ChargingProfileKind);
-			DEBUG_INFO("Profile RecurrencyKind: %s\n", maxProfile.RecurrencyKind);
+			DEBUG_INFO("Profile recurrencyKind: %s\n", maxProfile.RecurrencyKind);
 
 			DEBUG_INFO("Profile start schedule: %s\n", maxProfile.ChargingSchedule.StartSchedule);
 			DEBUG_INFO("Profile schedule duration: %d\n", maxProfile.ChargingSchedule.Duration);
@@ -1606,7 +1615,7 @@ void checkChargePointMaxProfile(uint32_t durationReq, struct StructChargingProfi
 		DEBUG_INFO("Profile valid from: %s\n", maxProfile.ValidFrom);
 		DEBUG_INFO("Profile valid to: %s\n", maxProfile.ValidTo);
 		DEBUG_INFO("Profile ChargingProfileKind: %s\n", maxProfile.ChargingProfileKind);
-		DEBUG_INFO("Profile RecurrencyKind: %s\n", maxProfile.RecurrencyKind);
+		DEBUG_INFO("Profile recurrencyKind: %s\n", maxProfile.RecurrencyKind);
 
 		DEBUG_INFO("Profile start schedule: %s\n", compositeProfile->ChargingSchedule.StartSchedule);
 		DEBUG_INFO("Profile schedule duration: %d\n", maxProfile.ChargingSchedule.Duration);
@@ -1736,15 +1745,6 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 	{
 		fp = fopen(profileFileName, "r");
 
-		for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(txProfile.ChargingSchedule.ChargingSchedulePeriod);idxPeriod++)
-		{
-			txProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].StartPeriod = -1;
-			txProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].Limit = -1;
-			txProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].NumberPhases = 3;
-		}
-		txProfile.ChargingProfileId = -1;
-		txProfile.StackLevel = -1;
-
 		while(getline(&line, &len, fp) != -1)
 		{
 			json_object *obj = NULL;
@@ -1756,7 +1756,7 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 			}
 			else
 			{
-				if((json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "ChargingProfileId")) != txProfile.ChargingProfileId) &&
+				if((json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingProfileId")) != txProfile.ChargingProfileId) &&
 				   (json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "stackLevel")) >= txProfile.StackLevel)
 				  )
 				{
@@ -1780,6 +1780,15 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 
 							if((DiffTimebWithNowSec(tbFrom)>=0) && (DiffTimebWithNowSec(tbTo)<=0))
 							{
+								for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(txProfile.ChargingSchedule.ChargingSchedulePeriod);idxPeriod++)
+								{
+									txProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].StartPeriod = -1;
+									txProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].Limit = -1;
+									txProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].NumberPhases = 3;
+								}
+								txProfile.ChargingProfileId = -1;
+								txProfile.StackLevel = -1;
+
 								if(txProfile.ChargingProfileId == -1)
 									DEBUG_INFO("TxProfile found.\n");
 								else
@@ -1836,9 +1845,9 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 									sprintf((char*)txProfile.ValidTo, " ");
 								}
 
-								if(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "RecurrencyKind") != NULL)
+								if(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "recurrencyKind") != NULL)
 								{
-									sprintf((char*)txProfile.RecurrencyKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "RecurrencyKind")));
+									sprintf((char*)txProfile.RecurrencyKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "recurrencyKind")));
 								}
 								else
 								{
@@ -1885,6 +1894,15 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 					}
 					else
 					{
+						for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(txProfile.ChargingSchedule.ChargingSchedulePeriod);idxPeriod++)
+						{
+							txProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].StartPeriod = -1;
+							txProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].Limit = -1;
+							txProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].NumberPhases = 3;
+						}
+						txProfile.ChargingProfileId = -1;
+						txProfile.StackLevel = -1;
+
 						if(txProfile.ChargingProfileId == -1)
 							DEBUG_INFO("TxProfile found.\n");
 						else
@@ -1941,9 +1959,9 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 							sprintf((char*)txProfile.ValidTo, " ");
 						}
 
-						if(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "RecurrencyKind") != NULL)
+						if(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "recurrencyKind") != NULL)
 						{
-							sprintf((char*)txProfile.RecurrencyKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "RecurrencyKind")));
+							sprintf((char*)txProfile.RecurrencyKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "recurrencyKind")));
 						}
 						else
 						{
@@ -2000,7 +2018,7 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 			DEBUG_INFO("Profile valid from: %s\n", txProfile.ValidFrom);
 			DEBUG_INFO("Profile valid to: %s\n", txProfile.ValidTo);
 			DEBUG_INFO("Profile ChargingProfileKind: %s\n", txProfile.ChargingProfileKind);
-			DEBUG_INFO("Profile RecurrencyKind: %s\n", txProfile.RecurrencyKind);
+			DEBUG_INFO("Profile recurrencyKind: %s\n", txProfile.RecurrencyKind);
 
 			DEBUG_INFO("Profile start schedule: %s\n", txProfile.ChargingSchedule.StartSchedule);
 			DEBUG_INFO("Profile schedule duration: %d\n", txProfile.ChargingSchedule.Duration);
@@ -2030,15 +2048,6 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 	{
 		fp = fopen(profileFileName, "r");
 
-		for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod);idxPeriod++)
-		{
-			defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].StartPeriod = -1;
-			defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].Limit = -1;
-			defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].NumberPhases = 3;
-		}
-		defaultTxProfile.ChargingProfileId = -1;
-		defaultTxProfile.StackLevel = -1;
-
 		while(getline(&line, &len, fp) != -1)
 		{
 			json_object *obj = NULL;
@@ -2050,7 +2059,7 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 			}
 			else
 			{
-				if((json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "ChargingProfileId")) != defaultTxProfile.ChargingProfileId) &&
+				if((json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingProfileId")) != defaultTxProfile.ChargingProfileId) &&
 				   (json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "stackLevel")) >= defaultTxProfile.StackLevel)
 				  )
 				{
@@ -2074,6 +2083,15 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 
 							if((DiffTimebWithNowSec(tbFrom)>=0) && (DiffTimebWithNowSec(tbTo)<=0))
 							{
+								for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod);idxPeriod++)
+								{
+									defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].StartPeriod = -1;
+									defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].Limit = -1;
+									defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].NumberPhases = 3;
+								}
+								defaultTxProfile.ChargingProfileId = -1;
+								defaultTxProfile.StackLevel = -1;
+
 								if(defaultTxProfile.ChargingProfileId == -1)
 									DEBUG_INFO("TxDefaultProfile found.\n");
 								else
@@ -2131,9 +2149,9 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 									sprintf((char*)defaultTxProfile.ValidTo, " ");
 								}
 
-								if(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "RecurrencyKind") != NULL)
+								if(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "recurrencyKind") != NULL)
 								{
-									sprintf((char*)defaultTxProfile.RecurrencyKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "RecurrencyKind")));
+									sprintf((char*)defaultTxProfile.RecurrencyKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "recurrencyKind")));
 								}
 								else
 								{
@@ -2180,6 +2198,15 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 					}
 					else
 					{
+						for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod);idxPeriod++)
+						{
+							defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].StartPeriod = -1;
+							defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].Limit = -1;
+							defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].NumberPhases = 3;
+						}
+						defaultTxProfile.ChargingProfileId = -1;
+						defaultTxProfile.StackLevel = -1;
+
 						if(defaultTxProfile.ChargingProfileId == -1)
 							DEBUG_INFO("TxDefaultProfile found.\n");
 						else
@@ -2236,9 +2263,9 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 							sprintf((char*)defaultTxProfile.ValidTo, " ");
 						}
 
-						if(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "RecurrencyKind") != NULL)
+						if(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "recurrencyKind") != NULL)
 						{
-							sprintf((char*)defaultTxProfile.RecurrencyKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "RecurrencyKind")));
+							sprintf((char*)defaultTxProfile.RecurrencyKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "recurrencyKind")));
 						}
 						else
 						{
@@ -2295,7 +2322,7 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 			DEBUG_INFO("Profile valid from: %s\n", defaultTxProfile.ValidFrom);
 			DEBUG_INFO("Profile valid to: %s\n", defaultTxProfile.ValidTo);
 			DEBUG_INFO("Profile ChargingProfileKind: %s\n", defaultTxProfile.ChargingProfileKind);
-			DEBUG_INFO("Profile RecurrencyKind: %s\n", defaultTxProfile.RecurrencyKind);
+			DEBUG_INFO("Profile recurrencyKind: %s\n", defaultTxProfile.RecurrencyKind);
 
 			DEBUG_INFO("Profile start schedule: %s\n", defaultTxProfile.ChargingSchedule.StartSchedule);
 			DEBUG_INFO("Profile schedule duration: %d\n", defaultTxProfile.ChargingSchedule.Duration);
@@ -2324,15 +2351,6 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 	{
 		fp = fopen(profileFileName, "r");
 
-		for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.ChargingSchedule.ChargingSchedulePeriod);idxPeriod++)
-		{
-			maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].StartPeriod = -1;
-			maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].Limit = -1;
-			maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].NumberPhases = 3;
-		}
-		maxProfile.ChargingProfileId = -1;
-		maxProfile.StackLevel = -1;
-
 		while(getline(&line, &len, fp) != -1)
 		{
 			json_object *obj = NULL;
@@ -2344,7 +2362,7 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 			}
 			else
 			{
-				if((json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "ChargingProfileId")) != maxProfile.ChargingProfileId) &&
+				if((json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "chargingProfileId")) != maxProfile.ChargingProfileId) &&
 				   (json_object_get_int(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "stackLevel")) >= maxProfile.StackLevel)
 				  )
 				{
@@ -2368,6 +2386,15 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 
 							if((DiffTimebWithNowSec(tbFrom)>=0) && (DiffTimebWithNowSec(tbTo)<=0))
 							{
+								for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.ChargingSchedule.ChargingSchedulePeriod);idxPeriod++)
+								{
+									maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].StartPeriod = -1;
+									maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].Limit = -1;
+									maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].NumberPhases = 3;
+								}
+								maxProfile.ChargingProfileId = -1;
+								maxProfile.StackLevel = -1;
+
 								if(maxProfile.ChargingProfileId == -1)
 									DEBUG_INFO("MaxProfile found.\n");
 								else
@@ -2425,9 +2452,9 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 									sprintf((char*)maxProfile.ValidTo, " ");
 								}
 
-								if(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "RecurrencyKind") != NULL)
+								if(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "recurrencyKind") != NULL)
 								{
-									sprintf((char*)maxProfile.RecurrencyKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "RecurrencyKind")));
+									sprintf((char*)maxProfile.RecurrencyKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "recurrencyKind")));
 								}
 								else
 								{
@@ -2474,6 +2501,15 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 					}
 					else
 					{
+						for(int idxPeriod=0;idxPeriod<ARRAY_SIZE(maxProfile.ChargingSchedule.ChargingSchedulePeriod);idxPeriod++)
+						{
+							maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].StartPeriod = -1;
+							maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].Limit = -1;
+							maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxPeriod].NumberPhases = 3;
+						}
+						maxProfile.ChargingProfileId = -1;
+						maxProfile.StackLevel = -1;
+
 						if(maxProfile.ChargingProfileId == -1)
 							DEBUG_INFO("MaxProfile found.\n");
 						else
@@ -2530,9 +2566,9 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 							sprintf((char*)maxProfile.ValidTo, " ");
 						}
 
-						if(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "RecurrencyKind") != NULL)
+						if(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "recurrencyKind") != NULL)
 						{
-							sprintf((char*)maxProfile.RecurrencyKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "RecurrencyKind")));
+							sprintf((char*)maxProfile.RecurrencyKind, "%s", json_object_get_string(json_object_object_get(json_object_object_get(obj, "csChargingProfiles"), "recurrencyKind")));
 						}
 						else
 						{
@@ -2589,7 +2625,7 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 			DEBUG_INFO("Profile valid from: %s\n", maxProfile.ValidFrom);
 			DEBUG_INFO("Profile valid to: %s\n", maxProfile.ValidTo);
 			DEBUG_INFO("Profile ChargingProfileKind: %s\n", maxProfile.ChargingProfileKind);
-			DEBUG_INFO("Profile RecurrencyKind: %s\n", maxProfile.RecurrencyKind);
+			DEBUG_INFO("Profile recurrencyKind: %s\n", maxProfile.RecurrencyKind);
 
 			DEBUG_INFO("Profile start schedule: %s\n", maxProfile.ChargingSchedule.StartSchedule);
 			DEBUG_INFO("Profile schedule duration: %d\n", maxProfile.ChargingSchedule.Duration);
@@ -2743,7 +2779,7 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 		DEBUG_INFO("Profile valid from: %s\n", txProfile.ValidFrom);
 		DEBUG_INFO("Profile valid to: %s\n", txProfile.ValidTo);
 		DEBUG_INFO("Profile ChargingProfileKind: %s\n", txProfile.ChargingProfileKind);
-		DEBUG_INFO("Profile RecurrencyKind: %s\n", txProfile.RecurrencyKind);
+		DEBUG_INFO("Profile recurrencyKind: %s\n", txProfile.RecurrencyKind);
 
 		DEBUG_INFO("Profile start schedule: %s\n", compositeProfile->ChargingSchedule.StartSchedule);
 		DEBUG_INFO("Profile schedule duration: %d\n", txProfile.ChargingSchedule.Duration);
@@ -2902,7 +2938,7 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 		DEBUG_INFO("Profile valid from: %s\n", defaultTxProfile.ValidFrom);
 		DEBUG_INFO("Profile valid to: %s\n", defaultTxProfile.ValidTo);
 		DEBUG_INFO("Profile ChargingProfileKind: %s\n", defaultTxProfile.ChargingProfileKind);
-		DEBUG_INFO("Profile RecurrencyKind: %s\n", defaultTxProfile.RecurrencyKind);
+		DEBUG_INFO("Profile recurrencyKind: %s\n", defaultTxProfile.RecurrencyKind);
 
 		DEBUG_INFO("Profile start schedule: %s\n", compositeProfile->ChargingSchedule.StartSchedule);
 		DEBUG_INFO("Profile schedule duration: %d\n", defaultTxProfile.ChargingSchedule.Duration);
@@ -3042,7 +3078,7 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 		DEBUG_INFO("Profile valid from: %s\n", maxProfile.ValidFrom);
 		DEBUG_INFO("Profile valid to: %s\n", maxProfile.ValidTo);
 		DEBUG_INFO("Profile ChargingProfileKind: %s\n", maxProfile.ChargingProfileKind);
-		DEBUG_INFO("Profile RecurrencyKind: %s\n", maxProfile.RecurrencyKind);
+		DEBUG_INFO("Profile recurrencyKind: %s\n", maxProfile.RecurrencyKind);
 
 		DEBUG_INFO("Profile start schedule: %s\n", compositeProfile->ChargingSchedule.StartSchedule);
 		DEBUG_INFO("Profile schedule duration: %d\n", maxProfile.ChargingSchedule.Duration);
@@ -3087,6 +3123,7 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 	// TxProfile found, composite schedule based on it
 	if(txProfile.ChargingProfileId != -1)
 	{
+		compositeProfile->ChargingSchedule.Duration = txProfile.ChargingSchedule.Duration;
 		for(int idxTxPeriod=0;idxTxPeriod<limitTx;idxTxPeriod++)
 		{
 			if((txProfile.ChargingSchedule.ChargingSchedulePeriod[idxTxPeriod].Limit != -1) &&
@@ -3148,6 +3185,7 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 			{
 				if(defaultTxProfile.ChargingProfileId != -1)
 				{
+					compositeProfile->ChargingSchedule.Duration = (defaultTxProfile.ChargingSchedule.Duration>compositeProfile->ChargingSchedule.Duration)?defaultTxProfile.ChargingSchedule.Duration:compositeProfile->ChargingSchedule.Duration;
 					for(int idxDefPeriod=0;idxDefPeriod<limitDef;idxDefPeriod++)
 					{
 						if((defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxDefPeriod].StartPeriod >= (txProfile.ChargingSchedule.ChargingSchedulePeriod[idxTxPeriod].StartPeriod + (txProfile.ChargingSchedule.Duration-defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxDefPeriod].StartPeriod))) &&
@@ -3198,7 +3236,18 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 										}
 									}
 									else
+									{
+										if(defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxDefPeriod].StartPeriod != compositeProfile->ChargingSchedule.ChargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)].StartPeriod)
+										{
+											memcpy(&compositeProfile->ChargingSchedule.ChargingSchedulePeriod[compositePeriodIdx], &defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxDefPeriod],sizeof(struct StructChargingSchedulePeriod));
+											compositePeriodIdx++;
+										}
+										else
+										{
+											memcpy(&compositeProfile->ChargingSchedule.ChargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)], &defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxDefPeriod],sizeof(struct StructChargingSchedulePeriod));
+										}
 										break;
+									}
 								}
 							}
 							else
@@ -3222,6 +3271,7 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 	// TxProfile not found but defaultTxProfile found, composite schedule based on it
 	else if(defaultTxProfile.ChargingProfileId != -1)
 	{
+		compositeProfile->ChargingSchedule.Duration = defaultTxProfile.ChargingSchedule.Duration;
 		for(int idxDefPeriod=0;idxDefPeriod<limitDef;idxDefPeriod++)
 		{
 			if((defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxDefPeriod].Limit != -1) &&
@@ -3234,16 +3284,14 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 					{
 						if(defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxDefPeriod].StartPeriod >= maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxMaxPeriod].StartPeriod)
 						{
+							tmpPeriod.StartPeriod = defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxDefPeriod].StartPeriod;
+							tmpPeriod.NumberPhases = defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxDefPeriod].NumberPhases;
 							if((maxProfile.ChargingSchedule.Duration > 0))
 							{
-								tmpPeriod.StartPeriod = defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxDefPeriod].StartPeriod;
-								tmpPeriod.NumberPhases = defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxDefPeriod].NumberPhases;
 								tmpPeriod.Limit = (defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxDefPeriod].Limit>maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxMaxPeriod].Limit?maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxMaxPeriod].Limit:defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxDefPeriod].Limit);
 							}
 							else
 							{
-								tmpPeriod.StartPeriod = defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxDefPeriod].StartPeriod;
-								tmpPeriod.NumberPhases = defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxDefPeriod].NumberPhases;
 								tmpPeriod.Limit = defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxDefPeriod].Limit;
 							}
 
@@ -3272,8 +3320,18 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 							}
 						}
 						else
-
+						{
+							if(defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxDefPeriod].StartPeriod != compositeProfile->ChargingSchedule.ChargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)].StartPeriod)
+							{
+								memcpy(&compositeProfile->ChargingSchedule.ChargingSchedulePeriod[compositePeriodIdx], &defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxDefPeriod],sizeof(struct StructChargingSchedulePeriod));
+								compositePeriodIdx++;
+							}
+							else
+							{
+								memcpy(&compositeProfile->ChargingSchedule.ChargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)], &defaultTxProfile.ChargingSchedule.ChargingSchedulePeriod[idxDefPeriod],sizeof(struct StructChargingSchedulePeriod));
+							}
 							break;
+						}
 					}
 				}
 				else
@@ -3295,50 +3353,76 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 	// Fill other period by MaxProfile
 	if(maxProfile.ChargingProfileId != -1)
 	{
-		for(int idxMaxPeriod=0;idxMaxPeriod<limitMax;idxMaxPeriod++)
+		if(compositePeriodIdx==0)
 		{
-			if((maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxMaxPeriod].Limit != -1) &&
-			   (maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxMaxPeriod].StartPeriod < durationReq) &&
-			   (maxProfile.ChargingSchedule.Duration > 0))
+			compositeProfile->ChargingSchedule.Duration = maxProfile.ChargingSchedule.Duration;
+			for(int idxMaxPeriod=0;idxMaxPeriod<limitDef;idxMaxPeriod++)
 			{
-				if((maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxMaxPeriod].StartPeriod >= compositeProfile->ChargingSchedule.ChargingSchedulePeriod[compositePeriodIdx==0?0:compositePeriodIdx-1].StartPeriod) &&
-				   (maxProfile.ChargingSchedule.Duration > compositeProfile->ChargingSchedule.ChargingSchedulePeriod[compositePeriodIdx==0?0:compositePeriodIdx-1].StartPeriod))
+				if((maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxMaxPeriod].Limit != -1) &&
+				   (maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxMaxPeriod].StartPeriod < durationReq) &&
+				   (maxProfile.ChargingSchedule.Duration > 0))
 				{
-					tmpPeriod.StartPeriod = (compositePeriodIdx==0)?0:compositeProfile->ChargingSchedule.ChargingSchedulePeriod[compositePeriodIdx==0?0:compositePeriodIdx-1].StartPeriod;
-					tmpPeriod.NumberPhases = compositeProfile->ChargingSchedule.ChargingSchedulePeriod[compositePeriodIdx==0?0:compositePeriodIdx-1].NumberPhases;
-					tmpPeriod.Limit = maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxMaxPeriod].Limit;
-				}
-
-				if((compositePeriodIdx > 0 ) && (maxProfile.ChargingSchedule.Duration > compositeProfile->ChargingSchedule.ChargingSchedulePeriod[compositePeriodIdx==0?0:compositePeriodIdx-1].StartPeriod))
-				{
-					tmpPeriod.StartPeriod = (maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxMaxPeriod].StartPeriod>compositeProfile->ChargingSchedule.ChargingSchedulePeriod[compositePeriodIdx-1].StartPeriod)?maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxMaxPeriod].StartPeriod:compositeProfile->ChargingSchedule.Duration;
-					tmpPeriod.NumberPhases = maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxMaxPeriod].NumberPhases;
-					tmpPeriod.Limit = maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxMaxPeriod].Limit;
+					if(maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxMaxPeriod].StartPeriod != compositeProfile->ChargingSchedule.ChargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)].StartPeriod)
+					{
+						memcpy(&compositeProfile->ChargingSchedule.ChargingSchedulePeriod[compositePeriodIdx], &maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxMaxPeriod],sizeof(struct StructChargingSchedulePeriod));
+						compositePeriodIdx++;
+					}
+					else
+					{
+						memcpy(&compositeProfile->ChargingSchedule.ChargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)], &maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxMaxPeriod],sizeof(struct StructChargingSchedulePeriod));
+					}
 				}
-
-				if(tmpPeriod.Limit != -1)
+			}
+		}
+		else
+		{
+			int lastCompositePeriodIdx = compositePeriodIdx;
+			for(int idxMaxPeriod=0;idxMaxPeriod<limitMax;idxMaxPeriod++)
+			{
+				if((maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxMaxPeriod].Limit != -1) &&
+				   (maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxMaxPeriod].StartPeriod < durationReq) &&
+				   (maxProfile.ChargingSchedule.Duration > 0))
 				{
-					if(tmpPeriod.Limit != compositeProfile->ChargingSchedule.ChargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)].Limit)
+					if((maxProfile.ChargingSchedule.Duration >= compositeProfile->ChargingSchedule.ChargingSchedulePeriod[compositePeriodIdx-1].StartPeriod))
 					{
-						if(tmpPeriod.StartPeriod != compositeProfile->ChargingSchedule.ChargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)].StartPeriod)
+						if(maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxMaxPeriod].Limit > compositeProfile->ChargingSchedule.ChargingSchedulePeriod[lastCompositePeriodIdx-1].Limit)
 						{
-							memcpy(&compositeProfile->ChargingSchedule.ChargingSchedulePeriod[compositePeriodIdx], &tmpPeriod , sizeof(struct StructChargingSchedulePeriod));
-							compositePeriodIdx++;
+							tmpPeriod.StartPeriod = maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxMaxPeriod].StartPeriod;
+							tmpPeriod.NumberPhases = maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxMaxPeriod].NumberPhases;
+							tmpPeriod.Limit = compositeProfile->ChargingSchedule.ChargingSchedulePeriod[lastCompositePeriodIdx-1].Limit;
 						}
 						else
 						{
-							memcpy(&compositeProfile->ChargingSchedule.ChargingSchedulePeriod[(compositePeriodIdx==0?compositePeriodIdx:compositePeriodIdx-1)], &tmpPeriod , sizeof(struct StructChargingSchedulePeriod));
+							tmpPeriod.StartPeriod = maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxMaxPeriod].StartPeriod;
+							tmpPeriod.NumberPhases = maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxMaxPeriod].NumberPhases;
+							tmpPeriod.Limit = maxProfile.ChargingSchedule.ChargingSchedulePeriod[idxMaxPeriod].Limit;
 						}
 					}
 
-					// Delete duplicate period
-					if(compositePeriodIdx > 1)
+					if(tmpPeriod.Limit != -1)
 					{
-						if(compositeProfile->ChargingSchedule.ChargingSchedulePeriod[compositePeriodIdx-1].Limit == compositeProfile->ChargingSchedule.ChargingSchedulePeriod[compositePeriodIdx-2].Limit)
+						if(tmpPeriod.Limit != compositeProfile->ChargingSchedule.ChargingSchedulePeriod[compositePeriodIdx-1].Limit)
 						{
-							compositeProfile->ChargingSchedule.ChargingSchedulePeriod[compositePeriodIdx-1].StartPeriod = -1;
-							compositeProfile->ChargingSchedule.ChargingSchedulePeriod[compositePeriodIdx-1].Limit = -1;
-							compositePeriodIdx -= 1;
+							if(tmpPeriod.StartPeriod != compositeProfile->ChargingSchedule.ChargingSchedulePeriod[compositePeriodIdx-1].StartPeriod)
+							{
+								memcpy(&compositeProfile->ChargingSchedule.ChargingSchedulePeriod[compositePeriodIdx], &tmpPeriod , sizeof(struct StructChargingSchedulePeriod));
+								compositePeriodIdx++;
+							}
+							else
+							{
+								memcpy(&compositeProfile->ChargingSchedule.ChargingSchedulePeriod[compositePeriodIdx-1], &tmpPeriod , sizeof(struct StructChargingSchedulePeriod));
+							}
+						}
+
+						// Delete duplicate period
+						if(compositePeriodIdx > 1)
+						{
+							if(compositeProfile->ChargingSchedule.ChargingSchedulePeriod[compositePeriodIdx-1].Limit == compositeProfile->ChargingSchedule.ChargingSchedulePeriod[compositePeriodIdx-2].Limit)
+							{
+								compositeProfile->ChargingSchedule.ChargingSchedulePeriod[compositePeriodIdx-1].StartPeriod = -1;
+								compositeProfile->ChargingSchedule.ChargingSchedulePeriod[compositePeriodIdx-1].Limit = -1;
+								compositePeriodIdx -= 1;
+							}
 						}
 					}
 				}
@@ -3346,6 +3430,7 @@ void checkCompositeSchedule(uint8_t connectorId, uint32_t durationReq, struct St
 		}
 	}
 
+	compositeProfile->ChargingSchedule.Duration = durationReq;
 	DEBUG_INFO("Connector-%d composite schedule ready.\n", connectorId);
 	DEBUG_INFO("Schedule start: %s\n", compositeProfile->ChargingSchedule.StartSchedule);
 	DEBUG_INFO("Schedule duration: %d\n", compositeProfile->ChargingSchedule.Duration);
@@ -3470,6 +3555,9 @@ int InitShareMemory()
 
 int ProcessShareMemory()
 {
+	int result = PASS;
+	ParsingRatedCur modelnameInfo={0};
+
 	if(InitShareMemory() == FAIL)
 	{
 		DEBUG_ERROR("InitShareMemory NG\n");
@@ -3478,10 +3566,87 @@ int ProcessShareMemory()
 		{
 			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory=1;
 		}
-		sleep(5);
-		return FAIL;
+
+		result = FAIL;
 	}
-	return PASS;
+
+	// Model name parsing
+	if(RatedCurrentParsing((char*)ShmSysConfigAndInfo->SysConfig.ModelName, &modelnameInfo) != -1)
+	{
+	 	if((ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D') &&
+	 	   ((ShmSysConfigAndInfo->SysConfig.ModelName[1]=='B') ||
+		    (ShmSysConfigAndInfo->SysConfig.ModelName[1]=='K') ||
+			(ShmSysConfigAndInfo->SysConfig.ModelName[1]=='O'))
+		   ) // 'D' means DC
+		{
+			// DO series
+			for(int gun_index=0; gun_index<GENERAL_GUN_QUANTITY ; gun_index++)
+			{
+				SystemInitial += 1;
+				gunTotalNumber += 1;
+				gunType[gun_index] = GUN_TYPE_DO;
+
+ 				switch(modelnameInfo.ParsingInfo[gun_index].GunType)
+ 				{
+ 					case Gun_Type_Chademo:
+ 						DEBUG_INFO("Gun-%02d type: Cabinet CHAdeMO\n", gun_index);
+ 						break;
+ 					case Gun_Type_CCS_2:
+ 						DEBUG_INFO("Gun-%02d type: Cabinet CCS\n", gun_index);
+						break;
+ 					case Gun_Type_GB:
+ 						DEBUG_INFO("Gun-%02d type: Cabinet GBT\n", gun_index);
+						break;
+ 					case Gun_Type_AC:
+ 						DEBUG_INFO("Gun-%02d type: Cabinet AC\n", gun_index);
+						break;
+ 					default:
+ 						DEBUG_WARN("Gun-%02d type: Cabinet unknown\n", gun_index);
+ 						break;
+ 				}
+			}
+		}
+		else
+		{
+ 			for(int gun_index=0;gun_index<modelnameInfo.GetGunCount;gun_index++)
+ 			{
+				SystemInitial += 1;
+				gunTotalNumber += 1;
+
+ 				switch(modelnameInfo.ParsingInfo[gun_index].GunType)
+ 				{
+ 					case Gun_Type_Chademo:
+ 						gunType[gun_index] = GUN_TYPE_CHAdeMO;
+ 						DEBUG_INFO("Gun-%02d type: CHAdeMO\n", gun_index);
+ 						break;
+ 					case Gun_Type_CCS_2:
+ 						gunType[gun_index] = GUN_TYPE_CCS;
+ 						DEBUG_INFO("Gun-%02d type: CCS\n", gun_index);
+						break;
+ 					case Gun_Type_GB:
+ 						gunType[gun_index] = GUN_TYPE_GBT;
+ 						DEBUG_INFO("Gun-%02d type: GBT\n", gun_index);
+						break;
+ 					case Gun_Type_AC:
+ 						gunType[gun_index] = GUN_TYPE_AC;
+ 						DEBUG_INFO("Gun-%02d type: AC\n", gun_index);
+						break;
+ 					default:
+ 						DEBUG_WARN("Gun-%02d type: Unknown\n", gun_index);
+ 						break;
+ 				}
+ 			}
+		}
+	}
+	else
+	{
+		DEBUG_ERROR("Model name parsing fail.\n");
+		result = FAIL;
+	}
+
+	if(result != PASS)sleep(5);
+
+	return result;
 }
 
 void CheckSystemValue(void)
@@ -3827,7 +3992,7 @@ void CheckSystemValue(void)
 					if((SystemInitial > 0) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus != AcPreviousSystemStatus[index]) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState != AcPreviousConnectorPlugIn[index]) )
 					{
 						// Sent unplug message for California pricing logic
-						if(ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_COMPLETE)
+						if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_COMPLETE) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].PilotState == CP_STATE_A))
 						{
 							uint8_t ts[20];
 							getNowDatetime(ts);
@@ -8620,13 +8785,13 @@ int handleChangeConfigurationRequest(char *uuid, char *payload)
 
     sendChangeConfigurationConfirmation(uuid, comfirmstr);
 	ShmOCPP16DataPH->MsMsg.bits.ChangeConfigurationConf = 1;
-	if((strcmp(keystr,"WebSocketPingInterval")==0)&&(strcmp(comfirmstr,"Accepted")==0))
+
+	if((strcmp(keystr,"WebSocketPingInterval")==0) && (strcmp(comfirmstr,"Accepted")==0))
 	{
 		ChageWebSocketPingInterval(atoi(valuestr));
 	}
 
-	if(((strcmp(keystr,"AuthorizationKey")==0) || ((strcmp(keystr,"SecurityProfile")==0))) &&
-	   (strcmp(keystr,"SecurityProfile")==0)&&(strcmp(comfirmstr,"Accepted")==0))
+	if(((strcmp(keystr,"AuthorizationKey")==0) || (strcmp(keystr,"SecurityProfile")==0)) && (strcmp(comfirmstr,"Accepted")==0))
 	{
 		StoreUsrConfigData(&ShmSysConfigAndInfo->SysConfig);
 		SetOcppConnStatus(FALSE);
@@ -11993,8 +12158,7 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex)
 				{
-					if((SYS_MODE_PREPARING <= ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus) &&
-					   (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus <= SYS_MODE_TERMINATING)) // S_CHARGING
+					if((SYS_MODE_PREPARING <= ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus) && (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus <= SYS_MODE_TERMINATING)) // S_CHARGING
 					{
 						if(SetProfileReq.ConnectorId == ShmOCPP16DataPH->StartTransaction[SetProfileReq.ConnectorId -1].ResponseTransactionId)
 						{
@@ -12020,8 +12184,8 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex)
 				{
-					if((SYS_MODE_PREPARING <= ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus) &&
-					   (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus <= SYS_MODE_TERMINATING)) // S_CHARGING
+					if(((SYS_MODE_PREPARING <= ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus) && (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus <= SYS_MODE_TERMINATING)) ||
+					    ((SYS_MODE_CCS_PRECHARGE_STEP0 <= ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus) && (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1))) // S_CHARGING
 					{
 						if(SetProfileReq.ChargingProfile.TransactionId == ShmOCPP16DataPH->StartTransaction[SetProfileReq.ConnectorId -1].ResponseTransactionId)
 						{
@@ -12047,8 +12211,7 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex)
 				{
-					if((SYS_MODE_PREPARING <= ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus) &&
-					   (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus <= SYS_MODE_TERMINATING)) // S_CHARGING
+					if((SYS_MODE_PREPARING <= ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus) && (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus <= SYS_MODE_TERMINATING)) // S_CHARGING
 					{
 						if(SetProfileReq.ChargingProfile.TransactionId == ShmOCPP16DataPH->StartTransaction[SetProfileReq.ConnectorId -1].ResponseTransactionId)
 						{
@@ -12067,8 +12230,8 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex)
 				{
-					if((SYS_MODE_PREPARING <= ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus) &&
-					   (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus <= SYS_MODE_TERMINATING)) // S_CHARGING
+					if(((SYS_MODE_PREPARING <= ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus) && (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus <= SYS_MODE_TERMINATING)) ||
+					   ((SYS_MODE_CCS_PRECHARGE_STEP0 <= ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus) && (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1))) // S_CHARGING
 					{
 						if(SetProfileReq.ChargingProfile.TransactionId == ShmOCPP16DataPH->StartTransaction[SetProfileReq.ConnectorId -1].ResponseTransactionId)
 						{
@@ -12095,8 +12258,7 @@ int handleSetChargingProfileRequest(char *uuid, char *payload)
 			{
 				if (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex)
 				{
-					if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_CHARGING) ||
-					   (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_TERMINATING)) // S_CHARGING
+					if((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_TERMINATING)) // S_CHARGING
 					{
 						if(SetProfileReq.ChargingProfile.TransactionId == ShmOCPP16DataPH->StartTransaction[SetProfileReq.ConnectorId -1].ResponseTransactionId)
 						{
@@ -12562,7 +12724,7 @@ int handleUnlockConnectorRequest(char *uuid, char *payload)
 
 			for (int index = 0; index < CHAdeMO_QUANTITY; index++)
 			{
-				if ((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex ) && ((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].SystemStatus == SYS_MODE_IDLE) ))
+				if ((ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == tempIndex ))
 				{
 					//stop Transaction
 					ShmOCPP16DataPH->CsMsg.bits[connectorIdInt-1].UnlockConnectorReq = 1;
@@ -12583,7 +12745,7 @@ int handleUnlockConnectorRequest(char *uuid, char *payload)
 
 			for (int index = 0; index < CCS_QUANTITY; index++)
 			{
-				if ((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex ) &&  ((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].SystemStatus == SYS_MODE_IDLE) ))
+				if ((ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == tempIndex ))
 				{
 					//stop Transaction
 					ShmOCPP16DataPH->CsMsg.bits[connectorIdInt-1].UnlockConnectorReq = 1;
@@ -12603,7 +12765,7 @@ int handleUnlockConnectorRequest(char *uuid, char *payload)
 
 			for (int index = 0; index < GB_QUANTITY; index++)
 			{
-				if ((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex ) &&((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_CHARGING)||(ShmSysConfigAndInfo->SysInfo.GbChargingData[index].SystemStatus == SYS_MODE_IDLE)))
+				if ((ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == tempIndex ))
 				{
 					//stop Transaction
 					ShmOCPP16DataPH->CsMsg.bits[connectorIdInt-1].UnlockConnectorReq = 1;
@@ -12617,7 +12779,7 @@ int handleUnlockConnectorRequest(char *uuid, char *payload)
 
 			for (int index = 0; index < GENERAL_GUN_QUANTITY; index++)
 			{
-				if ((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex ) &&((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_CHARGING)||(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.SystemStatus == SYS_MODE_IDLE)))
+				if ((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[index].GeneralChargingData.Index == tempIndex ))
 				{
 					//stop Transaction
 					ShmOCPP16DataPH->CsMsg.bits[connectorIdInt-1].UnlockConnectorReq = 1;
@@ -12638,7 +12800,7 @@ int handleUnlockConnectorRequest(char *uuid, char *payload)
 
 			for (int index = 0; index < AC_QUANTITY; index++)
 			{
-				if ((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex ) && ((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_CHARGING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[index].SystemStatus == SYS_MODE_IDLE) ))
+				if ((ShmSysConfigAndInfo->SysInfo.AcChargingData[index].Index == tempIndex ))
 				{
 					ShmOCPP16DataPH->CsMsg.bits[connectorIdInt-1].UnlockConnectorReq = 1;
 
@@ -13587,7 +13749,7 @@ int initialConfigurationTable(void)
 	char sstr[256]={0};
 	int c = 0;
 	char *loc;
-	int	confVersion = 8;
+	int	confVersion = 9;
 
 	DEBUG_INFO("initialConfigurationTable...version: %d\n", confVersion);
 	//start_t = clock();
@@ -13933,6 +14095,13 @@ int initialConfigurationTable(void)
 
 		fprintf(outfile,"{\"key\":\"%s\",\"readonly\":%s,\"value\":\"%s\"}\n","CustomIdleFeeAfterStop", "false", ShmOCPP16DataPH->ConfigurationTable.CoreProfile[CustomIdleFeeAfterStop].ItemData);
 
+		// SystemUptimeSec
+		ShmOCPP16DataPH->ConfigurationTable.CoreProfile[SystemUptimeSec].ItemAccessibility = 1;
+		strcpy((char *)ShmOCPP16DataPH->ConfigurationTable.CoreProfile[SystemUptimeSec].ItemName, "SystemUptimeSec");
+		strcpy((char *)ShmOCPP16DataPH->ConfigurationTable.CoreProfile[SystemUptimeSec].ItemData, "0" );
+
+		fprintf(outfile,"{\"key\":\"%s\",\"readonly\":%s,\"value\":\"%s\"}\n","SystemUptimeSec", "true", ShmOCPP16DataPH->ConfigurationTable.CoreProfile[SystemUptimeSec].ItemData);
+
 		// Configuration Version
 		ShmOCPP16DataPH->ConfigurationTable.CoreProfile[ConfigurationVersion].ItemAccessibility = 0;
 		strcpy((char *)ShmOCPP16DataPH->ConfigurationTable.CoreProfile[ConfigurationVersion].ItemName, "ConfigurationVersion");
@@ -14338,6 +14507,12 @@ int initialConfigurationTable(void)
 					sprintf((char *)ShmOCPP16DataPH->ConfigurationTable.CoreProfile[CustomIdleFeeAfterStop].ItemData, "%s", valuestr);
 				}
 
+				if(strcmp(keystr, "SystemUptimeSec") == 0)
+				{
+					ShmOCPP16DataPH->ConfigurationTable.CoreProfile[SystemUptimeSec].ItemAccessibility = (strcmp(readonlystr, "true")==0) ? 0 : 1;
+					sprintf((char *)ShmOCPP16DataPH->ConfigurationTable.CoreProfile[SystemUptimeSec].ItemData, "%d", atoi(valuestr));
+				}
+
 				if(strcmp(keystr, "ConfigurationVersion") == 0)
 				{
 					ShmOCPP16DataPH->ConfigurationTable.CoreProfile[ConfigurationVersion].ItemAccessibility = (strcmp(readonlystr, "true")==0) ? 0 : 1;
@@ -14797,6 +14972,15 @@ void StoreConfigurationTable(void)
 
 	fprintf(outfile,"{\"key\":\"%s\",\"readonly\":%s,\"value\":\"%s\"}\n","CustomIdleFeeAfterStop", "false", (char *)ShmOCPP16DataPH->ConfigurationTable.CoreProfile[CustomIdleFeeAfterStop].ItemData);
 
+	// SystemUptimeSec
+	/*
+	ShmOCPP16DataPH->ConfigurationTable.CoreProfile[SystemUptimeSec].ItemAccessibility = 1;
+	strcpy((char *)ShmOCPP16DataPH->ConfigurationTable.CoreProfile[SystemUptimeSec].ItemName, "SystemUptimeSec");
+	strcpy((char *)ShmOCPP16DataPH->ConfigurationTable.CoreProfile[SystemUptimeSec].ItemData, "0" );
+	*/
+
+	fprintf(outfile,"{\"key\":\"%s\",\"readonly\":%s,\"value\":\"%s\"}\n","SystemUptimeSec", "true", (char *)ShmOCPP16DataPH->ConfigurationTable.CoreProfile[SystemUptimeSec].ItemData);
+
 	// ConfigurationVersion
 	/*
 	ShmOCPP16DataPH->ConfigurationTable.CoreProfile[ConfigurationVersion].ItemAccessibility = 1;
@@ -15630,6 +15814,36 @@ void getKeyValue(char *keyReq)
 			  isKnowKey = TRUE;
 		  }
 
+	      if(isEmpty ||  strcmp(keyReq, "SystemUptimeSec") == 0 )
+		  {
+	    	  struct sysinfo s_info;
+	    	  int error = sysinfo(&s_info);
+
+			  strcpy((char *)ShmOCPP16DataPH->GetConfiguration.Key[GetConfiguration_SystemUptimeSec].Item, "SystemUptimeSec");
+			  strcpy((char *)ShmOCPP16DataPH->GetConfiguration.ResponseConfigurationKey[GetConfiguration_SystemUptimeSec].Key, "SystemUptimeSec");
+
+			  if(ShmOCPP16DataPH->ConfigurationTable.CoreProfile[SystemUptimeSec].ItemAccessibility == 1)
+			  {
+				  strcpy((char *)ShmOCPP16DataPH->GetConfiguration.ResponseConfigurationKey[GetConfiguration_SystemUptimeSec].ReadOnly, "0"/*"FALSE"*/);
+			  }
+			  else
+			  {
+				  strcpy((char *)ShmOCPP16DataPH->GetConfiguration.ResponseConfigurationKey[GetConfiguration_SystemUptimeSec].ReadOnly, "1"/*"TRUE"*/);
+			  }
+
+			  if(error != 0)
+			  {
+				  DEBUG_WARN("System uptime get error: %d\n", error);
+			  }
+			  else
+			  {
+				  sprintf((char *)ShmOCPP16Data->ConfigurationTable.CoreProfile[SystemUptimeSec].ItemData, "%ld", s_info.uptime);
+				  sprintf((char *)ShmOCPP16Data->GetConfiguration.ResponseConfigurationKey[GetConfiguration_SystemUptimeSec].Value, "%ld", s_info.uptime);
+			  }
+
+			  isKnowKey = TRUE;
+		  }
+
 	      if(isEmpty ||  strcmp(keyReq, "ConfigurationVersion") == 0 )
 		  {
 			  strcpy((char *)ShmOCPP16DataPH->GetConfiguration.Key[GetConfiguration_ConfigurationVersion].Item, "ConfigurationVersion");
@@ -16733,6 +16947,11 @@ int setKeyValue(char *key, char *value)
 	   }
 
     }
+
+    if(strcmp(key, "SystemUptimeSec") == 0)
+    {
+		isSuccess = NotSupported;
+    }
 #if 0
     //For OCPP Test Case
     if(strcmp(key, "LocalAuthorizationListEnabled") == 0)
@@ -18632,11 +18851,7 @@ void refreshProcDogTimer()
 
 void InitialSystemValue(void)
 {
-	int connectorIndex = 0;
-	//int valueASCII = 0;
 	server_cycle_Status = atoi((char*)ShmOCPP16DataPH->ConfigurationTable.CoreProfile[MinimumStatusDuration].ItemData);
-	gunTotalNumber=0;
-	SystemInitial = 0;
 	locallistVersion=0;
 	BootNotificationInterval = 0;
 	authorizeRetryTimes = 0;
@@ -18661,98 +18876,6 @@ void InitialSystemValue(void)
 	memset(CcsPreviousConnectorPlugIn, 0, ARRAY_SIZE(CcsPreviousConnectorPlugIn));
 	memset(GbPreviousConnectorPlugIn, 0, ARRAY_SIZE(GbPreviousConnectorPlugIn));
 	memset(AcPreviousConnectorPlugIn, 0, ARRAY_SIZE(AcPreviousConnectorPlugIn));
-	memset(gunType, 0, ARRAY_SIZE(gunType));
-
- 	if(ShmSysConfigAndInfo->SysConfig.ModelName[0]=='D') // 'D' means DC
-	{
- 		if((ShmSysConfigAndInfo->SysConfig.ModelName[1]=='B') ||
-		   (ShmSysConfigAndInfo->SysConfig.ModelName[1]=='K') ||
-		   (ShmSysConfigAndInfo->SysConfig.ModelName[1]=='O'))
- 		{
- 			// DO series
- 			for(int index=0; index<GENERAL_GUN_QUANTITY ; index++)
- 			{
-				SystemInitial = SystemInitial + 1;
-				gunTotalNumber = gunTotalNumber + 1;
-				gunType[connectorIndex] = GUN_TYPE_DO;
-				connectorIndex = connectorIndex + 1;
- 			}
- 		}
- 		else
- 		{
- 			// DM, DW, DS series
- 			//check connector / socket type (index: 8, 9, 10)
-			for(int index=7; index <10 ; index++)
-			{
-				if(index != 8)
-				{
-					// DC Connector
-					if ((ShmSysConfigAndInfo->SysConfig.ModelName[index] == 'J'))
-					{
-						SystemInitial = SystemInitial + 1;
-						gunTotalNumber = gunTotalNumber + 1;
-						gunType[connectorIndex] = GUN_TYPE_CHAdeMO;
-						connectorIndex = connectorIndex + 1;
-					}
-					else if ((ShmSysConfigAndInfo->SysConfig.ModelName[index] == 'D') ||
-							 (ShmSysConfigAndInfo->SysConfig.ModelName[index] == 'E') ||
-							 (ShmSysConfigAndInfo->SysConfig.ModelName[index] == 'F') ||
-							 (ShmSysConfigAndInfo->SysConfig.ModelName[index] == 'U') ||
-							 (ShmSysConfigAndInfo->SysConfig.ModelName[index] == 'T') ||
-							 (ShmSysConfigAndInfo->SysConfig.ModelName[index] == 'V'))
-					{
-						SystemInitial = SystemInitial + 1;
-						gunTotalNumber = gunTotalNumber + 1;
-						gunType[connectorIndex] = GUN_TYPE_CCS;
-						connectorIndex = connectorIndex + 1;
-					}
-					else if ((ShmSysConfigAndInfo->SysConfig.ModelName[index] == 'G'))
-					{
-						SystemInitial = SystemInitial + 1;
-						gunTotalNumber = gunTotalNumber + 1;
-						gunType[connectorIndex] = GUN_TYPE_GBT;
-						connectorIndex = connectorIndex + 1;
-					}
-					else if ((ShmSysConfigAndInfo->SysConfig.ModelName[index] == 'O'))
-					{
-						SystemInitial = SystemInitial + 1;
-						gunTotalNumber = gunTotalNumber + 1;
-						gunType[connectorIndex] = GUN_TYPE_DO;
-						connectorIndex = connectorIndex + 1;
-					}
-				}
-				else
-				{
-					// AC Connector
-					if ((ShmSysConfigAndInfo->SysConfig.ModelName[index] > '0') && (ShmSysConfigAndInfo->SysConfig.ModelName[index] <= '9'))
-					{
-						SystemInitial = SystemInitial + 1;
-						gunTotalNumber = gunTotalNumber + 1;
-						gunType[connectorIndex] = GUN_TYPE_AC;
-						connectorIndex = connectorIndex + 1;
-					}
-				}
-			}
- 		}
-
-		//DEBUG_INFO("DC ...\n");
-	}
-	else if (ShmSysConfigAndInfo->SysConfig.ModelName[0]=='A') //'A' means AC
-	{
-		//check connector / socket type (index: 8, 9, 10)
-		for(int index=7; index <10 ; index++)
-		{
-			if ((ShmSysConfigAndInfo->SysConfig.ModelName[index] > '0') && (ShmSysConfigAndInfo->SysConfig.ModelName[index] <= '9'))
-			{
-				SystemInitial = SystemInitial + 1;
-				gunTotalNumber = gunTotalNumber + 1;
-				gunType[connectorIndex] = GUN_TYPE_AC;
-				connectorIndex = connectorIndex + 1;
-
-				//DEBUG_INFO("AC: %d, %c\n", index, ShmSysConfigAndInfo->SysConfig.ModelName[index]);
-			}
-		}
-	}
 
 	//Status &&  ConnectorPlugIn Setting
 	for (int index = 0; index < CHAdeMO_QUANTITY; index++)

+ 1 - 0
EVSE/Modularization/ocppph/MessageHandler.h

@@ -392,6 +392,7 @@ enum GetConfigurationKey {
 	GetConfiguration_DefaultPrice,
 	GetConfiguration_CustomDisplayCostAndPrice,
 	GetConfiguration_CustomIdleFeeAfterStop,
+	GetConfiguration_SystemUptimeSec,
 	GetConfiguration_LocalAuthListEnabled,
 	GetConfiguration_LocalAuthListMaxLength,
 	GetConfiguration_SendLocalListMaxLength,

+ 17 - 9
EVSE/Modularization/ocppph/Module_OcppBackend.c

@@ -13,6 +13,7 @@ struct StartTime
 {
 	unsigned int connect;
 	unsigned int bootNotification;
+	unsigned int reConnect;
 }startTime;
 
 //==========================================
@@ -1542,17 +1543,24 @@ int main(void)
 
 				if((changeChageWebSocketPingInterval == TRUE) || (GetOcppConnStatus() == 0))
 				{
-					DEBUG_INFO("GetOcppConnStatus() = %d\n", GetOcppConnStatus());
-
-					if(changeChageWebSocketPingInterval)
+					if(((time((time_t*)NULL)-startTime.reConnect) >= 3) || ((time((time_t*)NULL)-startTime.reConnect) < 0))
 					{
-						DEBUG_INFO("Websocket ping interval changed request.\n");
-						changeChageWebSocketPingInterval = FALSE;
-					}
+						DEBUG_INFO("GetOcppConnStatus() = %d\n", GetOcppConnStatus());
 
-					lws_context_destroy(context);
-					ConnectionEstablished = 0;
-					context = NULL;
+						if(changeChageWebSocketPingInterval)
+						{
+							DEBUG_INFO("Websocket ping interval changed request.\n");
+							changeChageWebSocketPingInterval = FALSE;
+						}
+
+						lws_context_destroy(context);
+						ConnectionEstablished = 0;
+						context = NULL;
+					}
+				}
+				else
+				{
+					startTime.reConnect = time((time_t*)NULL);
 				}
 			}
 		}

+ 3 - 1
EVSE/Modularization/ocppph/Module_OcppBackend.h

@@ -17,16 +17,18 @@
 #include 	<sys/ipc.h>
 #include 	<sys/shm.h>
 #include 	<sys/mman.h>
+#include	<sys/sysinfo.h>
 #include 	<linux/wireless.h>
 #include 	<linux/sockios.h>
 #include 	<linux/socket.h>
+#include	<linux/unistd.h>
+#include	<linux/kernel.h>
 #include 	<arpa/inet.h>
 #include 	<netinet/in.h>
 #include 	<unistd.h>
 #include 	<stdarg.h>
 #include    <stdio.h>
 #include    <stdlib.h>
-#include    <unistd.h>
 #include    <fcntl.h>
 #include    <termios.h>
 #include 	<errno.h>

文件差異過大導致無法顯示
+ 147 - 241
EVSE/Projects/AW-CCS/Apps/CCS/Module_CCS.c


+ 1 - 0
EVSE/Projects/AW-CCS/Apps/CCS/Module_CCS.h

@@ -38,6 +38,7 @@
 #include	"v2g/api/api.h"
 #include	"v2g/transport/v2gtp.h"
 
+//#define TEST_WITH_ETH0
 
 #define SAVE_SYS_LOG_MSG_EVCOMM_SWITCH		ENABLE
 #define DEBUG_PRINTF_EVCOMM_SHOW			ENABLE

文件差異過大導致無法顯示
+ 184 - 151
EVSE/Projects/AW-CCS/Apps/CCS/v2g/api/api.c


+ 6 - 4
EVSE/Projects/AW-CCS/Apps/CCS/v2g/api/api.h

@@ -30,8 +30,8 @@
 #define DEBUG_PRINTF_EXI_ENGINE_DETAIL_SHOW    DISABLE   //ENABLE, DISABLE
 #else   //debug mode
 #define DEBUG_PRINTF_EXI_ENGINE_SHOW           ENABLE   //ENABLE, DISABLE
-#define DEBUG_PRINTF_EXI_ENGINE_BRIEF_SHOW     DISABLE   //ENABLE, DISABLE
-#define DEBUG_PRINTF_EXI_ENGINE_DETAIL_SHOW    DISABLE   //ENABLE, DISABLE
+#define DEBUG_PRINTF_EXI_ENGINE_BRIEF_SHOW     ENABLE   //ENABLE, DISABLE
+#define DEBUG_PRINTF_EXI_ENGINE_DETAIL_SHOW    ENABLE   //ENABLE, DISABLE
 #endif
 
 void SHM_Save_din_supportedAppProtocolReq(struct CcsData *shm_ccs, struct appHandEXIDocument *buf, struct SysConfigAndInfo *shm_sys);
@@ -164,13 +164,13 @@ float ISO151182014PhyValDecode(struct PhysicalValueType_ISO15118_2014 PhysicalDa
 
 #if DEBUG_PRINTF_EXI_ENGINE_SHOW == ENABLE
     #if DEBUG_PRINTF_EXI_ENGINE_BRIEF_SHOW == ENABLE
-        #define DEBUG_PRINTF_EXI_ENGINE_BRIEF      printf
+        #define DEBUG_PRINTF_EXI_ENGINE_BRIEF(format, args...) StoreLogV2GMsg("[%s:%d][%s] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
     #else
         #define DEBUG_PRINTF_EXI_ENGINE_BRIEF(...)
     #endif
 
     #if DEBUG_PRINTF_EXI_ENGINE_DETAIL_SHOW == ENABLE
-        #define DEBUG_PRINTF_EXI_ENGINE_DETAIL     printf
+        #define DEBUG_PRINTF_EXI_ENGINE_DETAIL(format, args...) StoreLogV2GMsg("[%s:%d][%s] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
     #else
         #define DEBUG_PRINTF_EXI_ENGINE_DETAIL(...)
     #endif
@@ -178,3 +178,5 @@ float ISO151182014PhyValDecode(struct PhysicalValueType_ISO15118_2014 PhysicalDa
     #define DEBUG_PRINTF_EXI_ENGINE_BRIEF(...)
     #define DEBUG_PRINTF_EXI_ENGINE_DETAIL(...)
 #endif
+
+int StoreLogV2GMsg(const char *fmt, ...);

+ 332 - 112
EVSE/Projects/AW-CCS/Apps/LCM/Module_LcmControl.c

@@ -46,7 +46,8 @@ void setPresentChargedEnergy(uint8_t gun_index);
 void setPresentChargingPower(uint8_t gun_index);
 void setBatteryPercentageValue(uint8_t gun_index);
 void setPresentChargedDuration(uint8_t gun_index);
-void setQRcodeContent(char *input, uint8_t length);
+void setPresentPowerConsumption(uint8_t gun_index);
+void setQRcodeContent(char *input, uint8_t length, uint8_t mode);
 void setDisplayValue(uint16_t address, uint8_t value);
 void setGunPluginAnimation(uint8_t gun_index);
 void setBatteryAnimation(uint8_t gun_index, uint8_t system_mode);
@@ -68,6 +69,8 @@ void setBackendIcon();
 void setEthernetIcon();
 void setAlarmCodeAndIcon();
 void setBillingFromWebsite();
+void setQRCodeReceipt(uint8_t gun_index);
+void setReceiptIcon(uint8_t gun_index);
 
 //=======================================
 // Declare Timer
@@ -92,7 +95,7 @@ struct timeb					startTime[AC_QUANTITY][10];
 #define TIME_ANIMATION_BATTERY			1000
 #define TIME_ANIMATION_CONNECTION		1000
 #define TIME_ANIMATION_ALARM			5000
-#define TIME_REFRESH_TIME				2000
+#define TIME_REFRESH_TIME				5000
 #define TIME_AUTH_RESULT_TIME			5000
 
 //=======================================
@@ -116,8 +119,7 @@ uint8_t isCharging	= YES;
 //=======================================
 // Record version and date
 //=======================================
-char *FIRMWARE_UPDATE_IMAGE[3] = {"V0.18", "2021-06-23", "REV.01.00"};
-
+char *FIRMWARE_UPDATE_IMAGE[3] = {"V0.19", "2021-09-28", "REV.01.00"};
 
 //=======================================
 // Common routine
@@ -275,23 +277,44 @@ void page_booting()
 
 void page_idle(uint8_t gun_index, uint8_t system_mode)
 {
-	if((getCurrentPage() != SYSTEM_SCREEN_IDLE) && (ShmCharger->gun_info[gun_index].resultAuthorization != VALIDATED_RFID))
+	if(ShmCharger->gun_info[gun_index].isSleepOn == YES)
 	{
-		setCurrentPage(SYSTEM_SCREEN_IDLE);
-		setDefaultValue(gun_index, system_mode);
-		DEBUG_INFO("Setting page to idle.\n");
+		if((getCurrentPage() != SYSTEM_SCREEN_SLEEP))
+		{
+			setCurrentPage(SYSTEM_SCREEN_SLEEP);
+		}
+		else
+		{}
 	}
 	else
 	{
-		setRfidIcon();
-		setQRCodeIcon();
-
-		if(isEmulator == YES)
+		if(ShmCharger->gun_info[gun_index].isCheckPowerConsumption == YES)
 		{
-			//if(isCharging == YES)
-				//PERCENTAGE = 0;
-			//else
-				//PERCENTAGE = 100;
+			setCurrentPage(SYSTEM_SCREEN_POWER_CONSUMPTION);
+			setDisplayValue(ICON_POWER_CONSUMPTION, APPEAR);
+			setPresentPowerConsumption(gun_index);
+		}
+		else
+		{
+			if((getCurrentPage() != SYSTEM_SCREEN_IDLE) && (ShmCharger->gun_info[gun_index].resultAuthorization != VALIDATED_RFID))
+			{
+				setCurrentPage(SYSTEM_SCREEN_IDLE);
+				setDefaultValue(gun_index, system_mode);
+				DEBUG_INFO("Setting page to idle.\n");
+			}
+			else
+			{
+				setRfidIcon();
+				setQRCodeIcon();
+
+				if(isEmulator == YES)
+				{
+					//if(isCharging == YES)
+						//PERCENTAGE = 0;
+					//else
+						//PERCENTAGE = 100;
+				}
+			}
 		}
 	}
 }
@@ -393,9 +416,10 @@ void page_complete(uint8_t gun_index, uint8_t system_mode)
 	}
 	else
 	{
-		setPresentChargedDuration(gun_index);
 		setPresentChargedEnergy(gun_index);
+		setPresentChargedDuration(gun_index);
 		setBatteryAnimation(gun_index, system_mode);
+		setReceiptIcon(gun_index);
 
 		// SHOW FINAL COST AND ACCOUNT BALANCE AFTER THE END OF TRANSACTION
 		if((ShmSysConfigAndInfo->SysInfo.OcppConnStatus == ON))
@@ -451,6 +475,7 @@ void page_terminating(uint8_t gun_index, uint8_t system_mode)
 		setPresentChargedDuration(gun_index);
 		setPresentChargedEnergy(gun_index);
 		setPresentChargingPower(gun_index);
+		setReceiptIcon(gun_index);
 
 		if((ShmSysConfigAndInfo->SysInfo.OcppConnStatus == ON))
 		{
@@ -578,7 +603,7 @@ void page_header(uint8_t gun_index, uint8_t system_mode)
 	}
 	else
 	{
-		// EVERY 2 SECONDS TO UPDATE PRICE
+		// EVERY 5 SECONDS TO UPDATE PRICE
 		if(DiffTimebWithNow(startTime[gun_index][TMR_IDX_PRICE]) > (TIME_REFRESH_TIME))
 		{
 			ftime(&startTime[gun_index][TMR_IDX_PRICE]);
@@ -878,6 +903,7 @@ void setPresentFinalCost(float cost)
 
 	memset(data, 0x00, ARRAY_SIZE(data));
 	memset(finalCost, 0x00, ARRAY_SIZE(finalCost));
+
 	sprintf((char *)finalCost, "%.2f", cost);
 	string2ByteArray(finalCost, data);
 	lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_COST_COMPLETE, data, ARRAY_SIZE(data));
@@ -937,7 +963,7 @@ void setBillingFromBackend(uint8_t gun_index, uint8_t system_mode)
 						{
 							/*
 							 * 1. SEARCHING USER PRICE FOR PRICE TEXT
-							 * 2. SEARCHING USER PRICE FOR URRENCY AND UNIT TO APPEAR
+							 * 2. SEARCHING USER PRICE FOR CURRENCY AND UNIT TO APPEAR
 							 */
 							setUserPrice(CURRENT_RATE);
 							setCurrencyAndUnitFromBackend(SET_USER_PRICE, CURRENT_RATE,gun_index);
@@ -1304,6 +1330,7 @@ void setRTC()
 //=======================================
 void setRfidIcon()
 {
+	/*
 	//=======================================
 	// AX-Series Generation 1
 	//=======================================
@@ -1341,6 +1368,13 @@ void setRfidIcon()
 		else
 			setDisplayValue(ICON_RFID, RFID_DISABLE);
 	}
+	*/
+
+	if(ShmSysConfigAndInfo->SysConfig.isRFID == ON)
+		setDisplayValue(ICON_NEW_RFID, NEW_RFID_ENABLE);
+	else
+		setDisplayValue(ICON_NEW_RFID, NEW_RFID_DISABLE);
+
 }
 
 //=======================================
@@ -1350,6 +1384,7 @@ void setQRCodeIcon()
 {
 	uint8_t length = 0;
 
+	/*
 	// QR CODE ( ENABLE / DISABLE )
 	if(ShmSysConfigAndInfo->SysConfig.isQRCode == ON)
 	{
@@ -1357,12 +1392,12 @@ void setQRCodeIcon()
 		if(ShmSysConfigAndInfo->SysConfig.QRCodeMadeMode == NO)
 		{
 			length = strlen((char *)ShmSysConfigAndInfo->SysConfig.SystemId);
-			setQRcodeContent((char *)ShmSysConfigAndInfo->SysConfig.SystemId, length);
+			setQRcodeContent((char *)ShmSysConfigAndInfo->SysConfig.SystemId, length, QRCODE_FOR_IDLE);
 		}
 		else
 		{
 			length = strlen((char *)ShmSysConfigAndInfo->SysConfig.QRCodeContent);
-			setQRcodeContent((char *)ShmSysConfigAndInfo->SysConfig.QRCodeContent, length);
+			setQRcodeContent((char *)ShmSysConfigAndInfo->SysConfig.QRCodeContent, length, QRCODE_FOR_IDLE);
 		}
 	}
 	else
@@ -1370,12 +1405,71 @@ void setQRCodeIcon()
 		setDisplayValue(TEXT_QRCODE_CONTENT, DISAPPEAR);
 		setDisplayValue(ICON_QRCODE,QRCODE_DISABLE);
 	}
+	*/
+
+	if(ShmSysConfigAndInfo->SysConfig.isQRCode == ON)
+	{
+		setDisplayValue(ICON_NEW_QR_CODE,NEW_QRCODE_ENABLE);
+		if(ShmSysConfigAndInfo->SysConfig.QRCodeMadeMode == NO)
+		{
+			length = strlen((char *)ShmSysConfigAndInfo->SysConfig.SystemId);
+			setQRcodeContent((char *)ShmSysConfigAndInfo->SysConfig.SystemId, length, QRCODE_FOR_IDLE);
+		}
+		else
+		{
+			length = strlen((char *)ShmSysConfigAndInfo->SysConfig.QRCodeContent);
+			setQRcodeContent((char *)ShmSysConfigAndInfo->SysConfig.QRCodeContent, length, QRCODE_FOR_IDLE);
+		}
+	}
+	else
+	{
+		setDisplayValue(TEXT_QRCODE_CONTENT, DISAPPEAR);
+		setDisplayValue(ICON_NEW_QR_CODE,NEW_QRCODE_DISABLE);
+	}
+}
+
+//=======================================
+// Setting QRCODE icon for receipt
+//=======================================
+void setQRCodeReceipt(uint8_t gun_index)
+{
+	uint8_t length = 0;
+	uint8_t data[128];
+	int TransactionId;
+	unsigned char QRCodeContent[128];
+	unsigned char QRCodeReceipt[128];
+
+	memset(QRCodeReceipt, 0x00, ARRAY_SIZE(QRCodeReceipt));
+	memset(QRCodeReceipt, 0x00, ARRAY_SIZE(QRCodeReceipt));
+	memset(data, 0x00, ARRAY_SIZE(data));
+
+	strcpy((char*)QRCodeContent, "https://ocpp.phihong.com.tw/CDFA/");
+
+	if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
+	{
+		TransactionId = ShmOCPP16Data->StopTransaction[gun_index].TransactionId;
+	}
+	else
+	{}
+
+	sprintf((char *)QRCodeReceipt, "%s%d", QRCodeContent,TransactionId);
+	string2ByteArray(QRCodeReceipt, data);
+
+	if(strstr((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL, "phihong") && (ShmSysConfigAndInfo->SysInfo.OcppConnStatus == ON))
+	{
+		length = strlen((char *)data);
+		setQRcodeContent((char *)data, length, QRCODE_FOR_COMPLETE);
+	}
+	else
+	{
+		setDisplayValue(TEXT_QRCODE_RECEIPT, DISAPPEAR);
+	}
 }
 
 //=======================================
 // Setting QR code content
 //=======================================
-void setQRcodeContent(char *input, uint8_t length)
+void setQRcodeContent(char *input, uint8_t length, uint8_t mode)
 {
 	uint8_t output[length];
 	int loop = 0;
@@ -1389,7 +1483,18 @@ void setQRcodeContent(char *input, uint8_t length)
 		loop++;
 	}
 
-	lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_QRCODE_CONTENT, output, ARRAY_SIZE(output)+1);
+	switch(mode)
+	{
+		case QRCODE_FOR_IDLE:
+			lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_QRCODE_CONTENT, output, ARRAY_SIZE(output)+1);
+			break;
+		case QRCODE_FOR_COMPLETE:
+			lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_QRCODE_RECEIPT, output, ARRAY_SIZE(output)+1);
+			break;
+		default:
+			lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_QRCODE_CONTENT, output, ARRAY_SIZE(output)+1);
+			break;
+	}
 }
 
 //=======================================
@@ -1709,7 +1814,6 @@ void setConnectionAnimation(uint8_t gun_index, uint8_t system_mode)
 
 			break;
 		case SYS_MODE_CHARGING:
-
 			if((ShmCharger->gun_info[gun_index].primaryMcuState.relay_state == ON))
 			{
 				if((CONNECTION_LEVEL_STATUS == CONNECTION_LEVEL_0) && (DiffTimebWithNow(startTime[gun_index][TMR_IDX_CONNECTION]) > (TIME_ANIMATION_CONNECTION)))
@@ -1834,6 +1938,22 @@ void setPresentChargedEnergy(uint8_t gun_index)
 	lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_ENERGY_CHARGING, data, ARRAY_SIZE(data));
 }
 
+//=======================================
+// Setting present power consumption
+//=======================================
+void setPresentPowerConsumption(uint8_t gun_index)
+{
+	uint8_t data[32];
+	uint8_t powerConsumption[32];
+
+	memset(data, 0x00, ARRAY_SIZE(data));
+	memset(powerConsumption, 0x00, ARRAY_SIZE(powerConsumption));
+
+	sprintf((char *)powerConsumption, "%.4f kWh", ((float)ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/10000.0));
+	string2ByteArray(powerConsumption, data);
+	lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, TEXT_POWER_CONSUMPTION, data, ARRAY_SIZE(data));
+}
+
 //=======================================
 // Setting present charged duration
 //=======================================
@@ -1965,6 +2085,26 @@ void setDefaultValue(uint8_t gun_index, uint8_t system_mode)
 	}
 }
 
+//=======================================
+// Setting receipt icon
+//=======================================
+void setReceiptIcon(uint8_t gun_index)
+{
+	// DISPLAY FOR QR CODE RECEIPT
+	if(strstr((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL, "phihong") && (ShmSysConfigAndInfo->SysInfo.OcppConnStatus == ON))
+	{
+		setDisplayValue(ICON_THE_CHARGE_COMPLETE, DISAPPEAR);
+		setDisplayValue(ICON_CONNECTION_COMPLETE, APPEAR);
+		setQRCodeReceipt(gun_index);
+	}
+	else
+	{
+		setDisplayValue(ICON_THE_CHARGE_COMPLETE, APPEAR);
+		setDisplayValue(ICON_CONNECTION_COMPLETE, APPEAR);
+		setQRCodeReceipt(gun_index);
+	}
+}
+
 //=======================================
 // Initial all share memory
 //=======================================
@@ -2081,19 +2221,23 @@ int downloadBMP(uint8_t picIdx, char *filename)
 	uint32_t pixelSize;
 	uint32_t transferedByte=0;
 	uint16_t bufferRamAddr = 0x8000;
+	uint32_t dataLen = 0;
+	uint32_t startAddr=0;
 
 	// Reset LCD
 	uint8_t cmd_reset[] = {0x55, 0xaa, 0x5a, 0xa5};
-	if(lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, 0x04, cmd_reset, ARRAY_SIZE(cmd_reset)) == FAIL)
+	while(lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, 0x04, cmd_reset, ARRAY_SIZE(cmd_reset)) != PASS)
 	{
 		DEBUG_INFO("LCD reset fail.\n");
 	}
+	sleep(1);
 
 	// Get image file size
 	stat(filename, &fileSt);
 	bmp = bopen(filename);
 	uint8_t buf[bmp->width*bmp->height*2];
 
+	DEBUG_INFO("Target address: %d\n", picIdx);
 	DEBUG_INFO("Image filename: %s\n", filename);
 	DEBUG_INFO("Image width: %d height: %d\n", bmp->width, bmp->height);
 	DEBUG_INFO("Image data size: %d\n", ARRAY_SIZE(buf));
@@ -2122,38 +2266,39 @@ int downloadBMP(uint8_t picIdx, char *filename)
 		if((idxSrcData+1) != (((pixelSize%pageSize)==0)?(pixelSize/pageSize):(pixelSize/pageSize)+1))
 		{
 			// Data transfer
-			while(lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, bufferRamAddr, &buf[(idxSrcData*pageSize)], pageSize) != PASS)
+			while(lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, (bufferRamAddr+(dataLen>>1)), &buf[(idxSrcData*pageSize)], pageSize) != PASS)
 			{
 				DEBUG_INFO("Transfer data to ram 0x%04X fail.\n", transferedByte);
 			}
 			transferedByte += pageSize;
-
-			display_cmd[3] = ((pageSize>>1) >> 8) & 0xff;							// Data length high byte
-			display_cmd[4] = ((pageSize>>1) >> 0) & 0xff;							// Data length low byte
-			display_cmd[5] = (((idxSrcData*pageSize)>>1) >> 16) & 0xff;				// Screen on ram address 1st byte
-			display_cmd[6] = (((idxSrcData*pageSize)>>1) >> 8) & 0xff;				// Screen on ram address 2nd byte
-			display_cmd[7] = (((idxSrcData*pageSize)>>1) >> 0) & 0xff;				// Screen on ram address 3th byte
+			dataLen += pageSize;
 		}
 		else
 		{
 			// Last data transfer
-			while(lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, bufferRamAddr, &buf[(idxSrcData*pageSize)], (pixelSize-(idxSrcData*pageSize))) != PASS)
+			while(lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, (bufferRamAddr+(dataLen>>1)), &buf[(idxSrcData*pageSize)], (pixelSize-(idxSrcData*pageSize))) != PASS)
 			{
 				DEBUG_INFO("Transfer data to ram 0x%04X fail.\n", transferedByte);
 			}
 			transferedByte += (pixelSize-(idxSrcData*pageSize));
-
-			display_cmd[3] = (((pixelSize-(idxSrcData*pageSize))>>1) >> 8) & 0xff;	// Data length high byte
-			display_cmd[4] = (((pixelSize-(idxSrcData*pageSize))>>1) >> 0) & 0xff;	// Data length low byte
-			display_cmd[5] = (((idxSrcData*pageSize)>>1) >> 16) & 0xff;				// Screen on ram address 1st byte
-			display_cmd[6] = (((idxSrcData*pageSize)>>1) >> 8) & 0xff;				// Screen on ram address 2nd byte
-			display_cmd[7] = (((idxSrcData*pageSize)>>1) >> 0) & 0xff;				// Screen on ram address 3th byte
+			dataLen += (pixelSize-(idxSrcData*pageSize));
 		}
 
 		// Move data from ram to flash
-		while(lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, 0xa2, display_cmd, ARRAY_SIZE(display_cmd)) != PASS)
+		if((dataLen >= (pageSize*10)) || (idxSrcData == (((pixelSize%pageSize)==0)?(pixelSize/pageSize):(pixelSize/pageSize)+1)-1))
 		{
-			DEBUG_INFO("Write data to display buffer 0x%04X fail.\n", transferedByte);
+			display_cmd[3] = ((dataLen>>1) >> 8) & 0xff;							// Data length high byte
+			display_cmd[4] = ((dataLen>>1) >> 0) & 0xff;							// Data length low byte
+			display_cmd[5] = (((startAddr)>>1) >> 16) & 0xff;				// Screen on ram address 1st byte
+			display_cmd[6] = (((startAddr)>>1) >> 8) & 0xff;				// Screen on ram address 2nd byte
+			display_cmd[7] = (((startAddr)>>1) >> 0) & 0xff;				// Screen on ram address 3th byte
+
+			while(lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, 0xa2, display_cmd, ARRAY_SIZE(display_cmd)) != PASS)
+			{
+				DEBUG_INFO("Write data to display buffer 0x%04X fail.\n", transferedByte);
+			}
+			startAddr += dataLen;
+			dataLen = 0;
 		}
 	}
 
@@ -2164,6 +2309,7 @@ int downloadBMP(uint8_t picIdx, char *filename)
 		DEBUG_INFO("Save image fail.\n");
 	}
 	DEBUG_INFO("Save image success.\n");
+	sleep(1);
 
 	return result;
 }
@@ -2183,15 +2329,17 @@ int downloadBIN(uint8_t targetAddr, char *filename)
 
 	// Reset LCD
 	uint8_t cmd_reset[] = {0x55, 0xaa, 0x5a, 0xa5};
-	if(lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, 0x04, cmd_reset, ARRAY_SIZE(cmd_reset)) == FAIL)
+	while(lcdRegisterWrite(Uart1Fd, REG_TYPE_RAM, 0x04, cmd_reset, ARRAY_SIZE(cmd_reset)) != PASS)
 	{
 		DEBUG_INFO("LCD reset fail.\n");
 	}
+	sleep(1);
 
 	// Get image file size
 	stat(filename, &fileSt);
-	uint8_t buf[(fileSt.st_size%32768==0?fileSt.st_size/32768:(fileSt.st_size/32768)+1)*32768];
+	uint8_t buf[(fileSt.st_size%32768==0?(fileSt.st_size/32768)*32768:(fileSt.st_size/32768)+1)*32768];
 
+	DEBUG_INFO("Target address: %d\n", targetAddr);
 	DEBUG_INFO("Bin filename: %s\n", filename);
 	DEBUG_INFO("Bin data size: %d\n", fileSt.st_size);
 
@@ -2203,19 +2351,18 @@ int downloadBIN(uint8_t targetAddr, char *filename)
 	}
 	else
 	{
+		// Read data from bin file
+		memset(buf, 0x00, ARRAY_SIZE(buf));
+		read(fd, buf, ARRAY_SIZE(buf));
+		close(fd);
+
 		for(uint8_t idxBinSrc=0;idxBinSrc<(fileSt.st_size%32768==0?fileSt.st_size/32768:(fileSt.st_size/32768)+1);idxBinSrc++)
 		{
-			// Read data from bin file
-			memset(buf, 0x00, ARRAY_SIZE(buf));
-			read(fd, buf, ARRAY_SIZE(buf));
-			close(fd);
-
 			// Transfer data to ram
 			for(uint16_t idxSrcData=0;idxSrcData<(((blocklSize%pageSize)==0)?(blocklSize/pageSize):(blocklSize/pageSize)+1);idxSrcData++)
 			{
 				//DEBUG_INFO("Buffer start data address: 0x%08X\n", (idxBinSrc*blocklSize)+(idxSrcData*pageSize));
 				//DEBUG_INFO("  Image start ram address: 0x%08X\n", ((idxSrcData*pageSize) >> 1));
-
 				if((idxSrcData+1) != (((blocklSize%pageSize)==0)?(blocklSize/pageSize):(blocklSize/pageSize)+1))
 				{
 					// Data transfer
@@ -2243,7 +2390,72 @@ int downloadBIN(uint8_t targetAddr, char *filename)
 				DEBUG_INFO("Save bin file to 0x%04X fail.\n", ((targetAddr*8)+idxBinSrc));
 			}
 			DEBUG_INFO("Save bin file on 0x%04X success.\n", ((targetAddr*8)+idxBinSrc));
+			sleep(1);
+		}
+	}
+
+	return result;
+}
+
+//=======================================
+// LCD upgrade
+//=======================================
+int lcdUpgrade(char *forlder)
+{
+	int result = PASS;
+	DIR *dir;
+	struct dirent *file;
+	struct stat fileSt;
+
+	if ((dir = opendir (forlder)) != NULL)
+	{
+		/* print all the files and directories within directory */
+		while ((file = readdir (dir)) != NULL)
+		{
+			if((strlen(file->d_name)>2))
+			{
+				int targetAddr;
+				stat(file->d_name, &fileSt);
+
+				if(sscanf(file->d_name, "%d", &targetAddr) == 1)
+				{
+					char targetFile[384];
+
+					sprintf(targetFile, "/mnt/lcd/%s", file->d_name);
+					if(strstr(file->d_name, ".bmp") != NULL)
+					{
+						downloadBMP(targetAddr, targetFile);
+					}
+					else
+					{
+						downloadBIN(targetAddr, targetFile);
+					}
+				}
+				else
+				{
+					DEBUG_WARN("%s can not parse target address.\n", file->d_name);
+				}
+			}
+			else
+			{
+				if(strlen(file->d_name) >= 3)
+				{
+					DEBUG_ERROR("File name error.\n");
+					result = FAIL;
+				}
+				else
+				{
+					DEBUG_INFO("Searching file.\n");
+				}
+			}
+			sleep(1);
 		}
+		closedir (dir);
+	}
+	else
+	{
+		DEBUG_ERROR("%s does not valid.\n", forlder);
+		result = FAIL;
 	}
 
 	return result;
@@ -2292,78 +2504,86 @@ int main(void)
 
 	for(;;)
 	{
-		if(previousMode != ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus)
+		if(ShmCharger->isUpgradeLcmReq)
 		{
-			previousMode = ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus;
-		}
-
-		if(ShmCharger->isAuthrizing || ShmCharger->isGetAuthResult)
-		{
-			if(DiffTimebWithNow(startTime[ShmCharger->gun_selectd][TMR_IDX_SHOW_AUTH_RESULT]) >= TIME_AUTH_RESULT_TIME)
-				ShmCharger->isGetAuthResult = FALSE;
-
-			if(DiffTimebWithNow(startTime[ShmCharger->gun_selectd][TMR_IDX_SHOW_AUTH_RESULT]) < TIME_AUTH_RESULT_TIME)
-				page_authorizing(ShmCharger->gun_selectd);
-			else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus == SYS_MODE_IDLE) && (ShmCharger->gun_info[ShmCharger->gun_selectd].resultAuthorization == VALIDATED_RFID))
-				page_preparing(ShmCharger->gun_selectd, ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus);
+			ShmCharger->isUpgradeLcmSuccess = ((lcdUpgrade("/mnt/lcd") == PASS) ? YES : NO);
+			ShmCharger->isUpgradeLcmReq = OFF;
 		}
 		else
 		{
-			ftime(&startTime[ShmCharger->gun_selectd][TMR_IDX_SHOW_AUTH_RESULT]);
+			if(previousMode != ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus)
+			{
+				previousMode = ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus;
+			}
 
-			switch(ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus)
+			if(ShmCharger->isAuthrizing || ShmCharger->isGetAuthResult)
 			{
-				case SYS_MODE_BOOTING:
-					page_booting();
-					break;
-				case SYS_MODE_IDLE:
-					page_idle(ShmCharger->gun_selectd, ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus);
-					break;
-				case SYS_MODE_AUTHORIZING:
-					//page_authorizing(ShmCharger->gun_selectd);
-					break;
-				case SYS_MODE_PREPARING:
+				if(DiffTimebWithNow(startTime[ShmCharger->gun_selectd][TMR_IDX_SHOW_AUTH_RESULT]) >= TIME_AUTH_RESULT_TIME)
+					ShmCharger->isGetAuthResult = FALSE;
+
+				if(DiffTimebWithNow(startTime[ShmCharger->gun_selectd][TMR_IDX_SHOW_AUTH_RESULT]) < TIME_AUTH_RESULT_TIME)
+					page_authorizing(ShmCharger->gun_selectd);
+				else if((ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus == SYS_MODE_IDLE) && (ShmCharger->gun_info[ShmCharger->gun_selectd].resultAuthorization == VALIDATED_RFID))
 					page_preparing(ShmCharger->gun_selectd, ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus);
-					break;
-				case SYS_MODE_CHARGING:
-					page_charging(ShmCharger->gun_selectd, ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus);
-					break;
-				case SYS_MODE_TERMINATING:
-					page_terminating(ShmCharger->gun_selectd, ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus);
-					break;
-				case SYS_MODE_COMPLETE:
-					page_complete(ShmCharger->gun_selectd, ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus);
-					break;
-				case SYS_MODE_ALARM:
-					page_alarm();
-					break;
-				case SYS_MODE_FAULT:
-					page_fault();
-					break;
-				case SYS_MODE_MAINTAIN:
-					page_maintain();
-					break;
-				case SYS_MODE_UPDATE:
-					page_update();
-					break;
-				case SYS_MODE_RESERVATION:
-					//page_reservation();
-					page_idle(ShmCharger->gun_selectd, ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus);
-					break;
-				case SYS_MODE_BOOKING:
-					page_booking();
-					break;
-				case SYS_MODE_DEBUG:
-					page_debug();
-					break;
-				default:
-					page_unknown();
-					break;
 			}
-		}
+			else
+			{
+				ftime(&startTime[ShmCharger->gun_selectd][TMR_IDX_SHOW_AUTH_RESULT]);
 
-		page_header(ShmCharger->gun_selectd, ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus);
-		page_footer();
+				switch(ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus)
+				{
+					case SYS_MODE_BOOTING:
+						page_booting();
+						break;
+					case SYS_MODE_IDLE:
+						page_idle(ShmCharger->gun_selectd, ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus);
+						break;
+					case SYS_MODE_AUTHORIZING:
+						//page_authorizing(ShmCharger->gun_selectd);
+						break;
+					case SYS_MODE_PREPARING:
+						page_preparing(ShmCharger->gun_selectd, ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus);
+						break;
+					case SYS_MODE_CHARGING:
+						page_charging(ShmCharger->gun_selectd, ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus);
+						break;
+					case SYS_MODE_TERMINATING:
+						page_terminating(ShmCharger->gun_selectd, ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus);
+						break;
+					case SYS_MODE_COMPLETE:
+						page_complete(ShmCharger->gun_selectd, ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus);
+						break;
+					case SYS_MODE_ALARM:
+						page_alarm();
+						break;
+					case SYS_MODE_FAULT:
+						page_fault();
+						break;
+					case SYS_MODE_MAINTAIN:
+						page_maintain();
+						break;
+					case SYS_MODE_UPDATE:
+						page_update();
+						break;
+					case SYS_MODE_RESERVATION:
+						//page_reservation();
+						page_idle(ShmCharger->gun_selectd, ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus);
+						break;
+					case SYS_MODE_BOOKING:
+						page_booking();
+						break;
+					case SYS_MODE_DEBUG:
+						page_debug();
+						break;
+					default:
+						page_unknown();
+						break;
+				}
+			}
+
+			page_header(ShmCharger->gun_selectd, ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus);
+			page_footer();
+		}
 
 		usleep(100000);
 	}

+ 1 - 2
EVSE/Projects/AW-CCS/Apps/LCM/lcmComm_dgus.c

@@ -45,12 +45,11 @@ int transceiverDgus(int32_t fd, uint8_t *tx, uint16_t tx_len, uint8_t *rx, uint1
 	displayMessageDgus(tx, tx_len, NO);
 	#endif
 
-	usleep(10000);
-
 	if(write(fd, tx, tx_len) >= ARRAY_SIZE(tx))
 	{
 		if(tx[3] == CMD_REG_WRITE_DATA)
 		{
+			usleep(100);
 			len = read(fd, rx, rx_len);
 			if(len > 0)
 			{

+ 23 - 4
EVSE/Projects/AW-CCS/Apps/LCM/lcmComm_dgus.h

@@ -97,7 +97,9 @@
 #define SYSTEM_SCREEN_AUTH_UNKNOW			0x09
 #define SYSTEM_SCREEN_TERMINATING			0X0A
 #define SYSTEM_SCREEN_EMERGENCY				0x0B
-#define SYSTEM_SCREEN_THREE_BAR_PATTERN		0x0C
+#define SYSTEM_SCREEN_SLEEP					0x0C
+#define SYSTEM_SCREEN_SLEEP2				0x0D
+#define SYSTEM_SCREEN_POWER_CONSUMPTION		0x0E
 
 //=======================================
 // Parameter to change icon status
@@ -147,6 +149,10 @@
 #define QRCODE_BANDED						0x01
 #define QRCODE_ENABLE 						0x02
 #define QRCODE_DISABLE						0x03
+#define NEW_QRCODE_DISABLE					0x01
+#define NEW_QRCODE_ENABLE					0x02
+#define NEW_RFID_DISABLE					0x01
+#define NEW_RFID_ENABLE						0x02
 
 //=======================================
 // Icon variable address start from 1000
@@ -183,6 +189,11 @@
 #define ICON_BALANCE_WALLET					0x101D
 #define ICON_DEFAULT_START_PRICE			0x101E
 #define ICON_DEFAULT_ENERGY					0x101F
+#define ICON_START_BUTTON					0x1020
+#define ICON_POWER_CONSUMPTION				0x1021
+#define ICON_THE_CHARGE_COMPLETE			0x1022
+#define ICON_NEW_RFID						0x1023
+#define ICON_NEW_QR_CODE					0x1024
 
 #define ICON_LOGO							0x1500
 #define ICON_LOGO_CHARGING					0x1501
@@ -209,13 +220,21 @@
 #define TEXT_CURRENCY_COMPLETE				0x20CE // size 16
 #define TEXT_DEFUALT_START_PRICE			0x20DE // size 16
 #define TEXT_DEFAULT_ENERGY					0x20EE // size 16
+#define TEXT_POWER_CONSUMPTION				0x20FE // size 32
 
 #define TEXT_RTC							0X2500 // size 32
 
 //=======================================
-// QR Code content address start from 5000
+// QR Code content address start from 3000
 //=======================================
-#define TEXT_QRCODE_CONTENT					0x3000
+#define TEXT_QRCODE_CONTENT					0x3000 // size 256
+#define TEXT_QRCODE_RECEIPT					0x3100 // size 256
+
+//=======================================
+// QR Code mode define
+//=======================================
+#define QRCODE_FOR_IDLE						1
+#define QRCODE_FOR_COMPLETE					2
 
 //=======================================
 // 4G + WIFI connection flags (Header)
@@ -237,7 +256,7 @@
 #define BATTERY_LEVEL_5						0x05
 
 //=======================================
-// CConnection level status (Charging)
+// Connection level status (Charging)
 //=======================================
 #define CONNECTION_LEVEL_0					0x00
 #define CONNECTION_LEVEL_1					0x01

+ 161 - 58
EVSE/Projects/AW-CCS/Apps/Module_AlarmDetect.c

@@ -289,7 +289,7 @@ int main(void)
 			//=====================================
 			// Over voltage detection
 			//=====================================
-			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_L1_OVER_VOLTAGE)
+			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.OVP_L1 == ON)
 			{
 				if(Alarm_Counter[gun_index].OV[0] > FILTER_SPEC)
 				{
@@ -305,7 +305,7 @@ int main(void)
 					Alarm_Counter[gun_index].OV[0]++;
 				}
 			}
-			else if((!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_L1_OVER_VOLTAGE)))
+			else
 			{
 				Alarm_Counter[gun_index].OV[0] = 0;
 				if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP == ON)
@@ -318,7 +318,7 @@ int main(void)
 
 			if(ShmSysConfigAndInfo->SysConfig.AcPhaseCount == 3)
 			{
-				if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_L2_OVER_VOLTAGE)
+				if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.OVP_L2 == ON)
 				{
 					if(Alarm_Counter[gun_index].OV[1] > FILTER_SPEC)
 					{
@@ -334,7 +334,7 @@ int main(void)
 						Alarm_Counter[gun_index].OV[1]++;
 					}
 				}
-				else if((!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_L2_OVER_VOLTAGE)))
+				else
 				{
 					Alarm_Counter[gun_index].OV[1] = 0;
 					if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP == ON)
@@ -345,7 +345,7 @@ int main(void)
 					}
 				}
 
-				if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_L3_OVER_VOLTAGE)
+				if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.OVP_L3 == ON)
 				{
 					if(Alarm_Counter[gun_index].OV[2] > FILTER_SPEC)
 					{
@@ -361,7 +361,7 @@ int main(void)
 						Alarm_Counter[gun_index].OV[2]++;
 					}
 				}
-				else if((!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_L3_OVER_VOLTAGE)))
+				else
 				{
 					Alarm_Counter[gun_index].OV[2] = 0;
 					if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP == ON)
@@ -376,7 +376,7 @@ int main(void)
 			//=====================================
 			// Under voltage detection
 			//=====================================
-			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_L1_UNDER_VOLTAGE)
+			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.UVP_L1 == ON)
 			{
 				if(Alarm_Counter[gun_index].UV[0] > FILTER_SPEC)
 				{
@@ -392,7 +392,7 @@ int main(void)
 					Alarm_Counter[gun_index].UV[0]++;
 				}
 			}
-			else if((!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_L1_UNDER_VOLTAGE)))
+			else
 			{
 				Alarm_Counter[gun_index].UV[0] = 0;
 				if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP == ON)
@@ -405,7 +405,7 @@ int main(void)
 
 			if(ShmSysConfigAndInfo->SysConfig.AcPhaseCount == 3)
 			{
-				if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_L2_UNDER_VOLTAGE)
+				if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.UVP_L2 == ON)
 				{
 					if(Alarm_Counter[gun_index].UV[1] > FILTER_SPEC)
 					{
@@ -421,7 +421,7 @@ int main(void)
 						Alarm_Counter[gun_index].UV[1]++;
 					}
 				}
-				else if((!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_L2_UNDER_VOLTAGE)))
+				else
 				{
 					Alarm_Counter[gun_index].UV[1] = 0;
 					if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP == ON)
@@ -432,7 +432,7 @@ int main(void)
 					}
 				}
 
-				if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_L3_UNDER_VOLTAGE)
+				if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.UVP_L3 == ON)
 				{
 					if(Alarm_Counter[gun_index].UV[2] > FILTER_SPEC)
 					{
@@ -448,7 +448,7 @@ int main(void)
 						Alarm_Counter[gun_index].UV[2]++;
 					}
 				}
-				else if((!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_L3_UNDER_VOLTAGE)))
+				else
 				{
 					Alarm_Counter[gun_index].UV[2] = 0;
 					if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP == ON)
@@ -464,7 +464,7 @@ int main(void)
 			//=====================================
 			// Over current detection
 			//=====================================
-			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_L1_OVER_CURRENT)
+			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.OCP_L1 == ON)
 			{
 				if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP == OFF)
 				{
@@ -473,7 +473,7 @@ int main(void)
 					DEBUG_INFO("ALARM_L1_OVER_CURRENT : alarm \n");
 				}
 			}
-			else if ((!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_L1_OVER_CURRENT)))
+			else
 			{
 				if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP == ON)
 				{
@@ -485,7 +485,7 @@ int main(void)
 
 			if(ShmSysConfigAndInfo->SysConfig.AcPhaseCount == 3)
 			{
-				if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_L2_OVER_CURRENT)
+				if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.OCP_L2 == ON)
 				{
 					if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCPL2 == OFF)
 					{
@@ -494,7 +494,7 @@ int main(void)
 						DEBUG_INFO("ALARM_L2_OVER_CURRENT : alarm \n");
 					}
 				}
-				else if ((!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_L2_OVER_CURRENT)))
+				else
 				{
 					if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCPL2 == ON)
 					{
@@ -504,7 +504,7 @@ int main(void)
 					}
 				}
 
-				if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_L3_OVER_CURRENT)
+				if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.OCP_L3 == ON)
 				{
 					if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCPL3 == OFF)
 					{
@@ -513,7 +513,7 @@ int main(void)
 						DEBUG_INFO("ALARM_L3_OVER_CURRENT : alarm \n");
 					}
 				}
-				else if ((!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_L3_OVER_CURRENT)))
+				else
 				{
 					if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCPL3 == ON)
 					{
@@ -527,7 +527,7 @@ int main(void)
 			//=====================================
 			// Over temperature detection
 			//=====================================
-			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_OVER_TEMPERATURE)
+			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.OTP == ON)
 			{
 				if(Alarm_Counter[gun_index].OT_AMB > FILTER_SPEC)
 				{
@@ -543,7 +543,7 @@ int main(void)
 					Alarm_Counter[gun_index].OT_AMB++;
 				}
 			}
-			else if((!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_OVER_TEMPERATURE)))
+			else
 			{
 				Alarm_Counter[gun_index].OT_AMB = 0;
 				if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAmbientOTP == ON)
@@ -557,7 +557,7 @@ int main(void)
 			//=====================================
 			// Ground fault detection
 			//=====================================
-			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_GROUND_FAIL)
+			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.gmi_fault == ON)
 			{
 				if(Alarm_Counter[gun_index].GMI > FILTER_SPEC)
 				{
@@ -573,7 +573,7 @@ int main(void)
 					Alarm_Counter[gun_index].GMI++;
 				}
 			}
-			else if (!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_GROUND_FAIL))
+			else
 			{
 				Alarm_Counter[gun_index].GMI = 0;
 				if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.AcGroundfaultFail == ON)
@@ -587,7 +587,7 @@ int main(void)
 			//=====================================
 			// CP level fail detection
 			//=====================================
-			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_CP_ERROR)
+			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.cp_fault == ON)
 			{
 				if(Alarm_Counter[gun_index].CP_LevelFail > FILTER_SPEC)
 				{
@@ -603,7 +603,7 @@ int main(void)
 					Alarm_Counter[gun_index].CP_LevelFail++;
 				}
 			}
-			else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_CP_ERROR))
+			else
 			{
 				Alarm_Counter[gun_index].CP_LevelFail= 0;
 				if(ShmStatusCodeData->InfoCode.InfoEvents.bits.PilotFault == ON)
@@ -617,21 +617,21 @@ int main(void)
 			//=====================================
 			// Current AC/DC leak detection
 			//=====================================
-			if((ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_CURRENT_LEAK_AC) ||
-			   (ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_CURRENT_LEAK_DC))
+			if((ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.ac_leak == ON) ||
+			   (ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.dc_leak == ON))
 			{
 				if(Alarm_Counter[gun_index].Leakage > FILTER_SPEC)
 				{
 					if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RcdTrip == OFF)
 					{
 						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RcdTrip = ON;
-						if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_CURRENT_LEAK_AC)
+						if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.ac_leak == ON)
 						{
 							ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_CURRENT_LEAK_AC;
 							ShmCharger->gun_info[gun_index].otherAlarmCode.isACLeakage = ON;
 							DEBUG_INFO("ALARM_CURRENT_LEAK_AC : alarm \n");
 						}
-						else if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_CURRENT_LEAK_DC)
+						else if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.dc_leak == ON)
 						{
 							ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_CURRENT_LEAK_DC;
 							ShmCharger->gun_info[gun_index].otherAlarmCode.isDcLeakage = ON;
@@ -644,8 +644,7 @@ int main(void)
 					Alarm_Counter[gun_index].Leakage++;
 				}
 			}
-			else if((!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_CURRENT_LEAK_AC)) ||
-					(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_CURRENT_LEAK_DC)))
+			else
 			{
 				Alarm_Counter[gun_index].Leakage = 0;
 				if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RcdTrip == ON)
@@ -669,7 +668,7 @@ int main(void)
 			//=====================================
 			// MCU self test fail detection
 			//=====================================
-			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_MCU_TESTFAIL)
+			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.mcu_selftest_fail == ON)
 			{
 				if(Alarm_Counter[gun_index].MCU_SelfTestFail > FILTER_SPEC)
 				{
@@ -685,7 +684,7 @@ int main(void)
 					Alarm_Counter[gun_index].MCU_SelfTestFail++;
 				}
 			}
-			else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_MCU_TESTFAIL))
+			else
 			{
 				Alarm_Counter[gun_index].MCU_SelfTestFail = 0;
 				if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.McuSelftestFail == ON)
@@ -699,7 +698,7 @@ int main(void)
 			//=====================================
 			// Hand shaking timeout detection
 			//=====================================
-			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_HANDSHAKE_TIMEOUT)
+			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.handshaking_timeout == ON)
 			{
 				if(ShmCharger->gun_info[gun_index].otherAlarmCode.isHandshakingTimeOut == OFF)
 				{
@@ -709,7 +708,7 @@ int main(void)
 				}
 
 			}
-			else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_HANDSHAKE_TIMEOUT))
+			else
 			{
 				if(ShmCharger->gun_info[gun_index].otherAlarmCode.isHandshakingTimeOut == ON)
 				{
@@ -722,7 +721,7 @@ int main(void)
 			//=====================================
 			// Emergency stop detection
 			//=====================================
-			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_EMERGENCY_STOP)
+			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.emergency_stop == ON)
 			{
 				if(Alarm_Counter[gun_index].EmrgencyBTN > FILTER_SPEC)
 				{
@@ -738,7 +737,7 @@ int main(void)
 					Alarm_Counter[gun_index].EmrgencyBTN++;
 				}
 			}
-			else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_EMERGENCY_STOP))
+			else
 			{
 				Alarm_Counter[gun_index].EmrgencyBTN = 0;
 				if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.EmergencyStopTrip == ON)
@@ -752,7 +751,7 @@ int main(void)
 			//=====================================
 			// Relay welding detection
 			//=====================================
-			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_RELAY_WELDING)
+			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.relay_welding == ON)
 			{
 				if(Alarm_Counter[gun_index].Relay_Welding > FILTER_SPEC)
 				{
@@ -768,7 +767,7 @@ int main(void)
 					Alarm_Counter[gun_index].Relay_Welding++;
 				}
 			}
-			else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_RELAY_WELDING))
+			else
 			{
 				Alarm_Counter[gun_index].Relay_Welding = 0;
 				if(ShmStatusCodeData->FaultCode.FaultEvents.bits.AcOutputRelayWelding == ON)
@@ -782,7 +781,7 @@ int main(void)
 			//=====================================
 			// Relay driving fault detection
 			//=====================================
-			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_RELAY_DRIVE_FAULT)
+			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.relay_drive_fault == ON)
 			{
 				if(Alarm_Counter[gun_index].Relay_DrivingFault > FILTER_SPEC)
 				{
@@ -798,7 +797,7 @@ int main(void)
 					Alarm_Counter[gun_index].Relay_DrivingFault++;
 				}
 			}
-			else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_RELAY_DRIVE_FAULT))
+			else
 			{
 				Alarm_Counter[gun_index].Relay_DrivingFault = 0;
 				if(ShmStatusCodeData->FaultCode.FaultEvents.bits.AcOutputRelayDrivingFault == ON)
@@ -812,7 +811,7 @@ int main(void)
 			//=====================================
 			// Current short detection
 			//=====================================
-			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_L1_CIRCUIT_SHORT)
+			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.short_circuit_L1 == ON)
 			{
 				if(Alarm_Counter[gun_index].Short[0] > FILTER_SPEC)
 				{
@@ -828,7 +827,7 @@ int main(void)
 					Alarm_Counter[gun_index].Short[0]++;
 				}
 			}
-			else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_L1_CIRCUIT_SHORT))
+			else
 			{
 				Alarm_Counter[gun_index].Short[0] = 0;
 				if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CircuitShort == ON)
@@ -841,7 +840,7 @@ int main(void)
 			
 			if(ShmSysConfigAndInfo->SysConfig.AcPhaseCount == 3)
 			{
-				if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_L2_CIRCUIT_SHORT)
+				if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.short_circuit_L2 == ON)
 				{
 					if(Alarm_Counter[gun_index].Short[1] > FILTER_SPEC)
 					{
@@ -857,7 +856,7 @@ int main(void)
 						Alarm_Counter[gun_index].Short[1]++;
 					}
 				}
-				else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_L2_CIRCUIT_SHORT))
+				else
 				{
 					Alarm_Counter[gun_index].Short[1] = 0;
 					if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CircuitShortL2 == ON)
@@ -868,7 +867,7 @@ int main(void)
 					}
 				}
 
-				if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_L3_CIRCUIT_SHORT)
+				if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.short_circuit_L3 == ON)
 				{
 					if(Alarm_Counter[gun_index].Short[2] > FILTER_SPEC)
 					{
@@ -884,7 +883,7 @@ int main(void)
 						Alarm_Counter[gun_index].Short[2]++;
 					}
 				}
-				else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_L3_CIRCUIT_SHORT))
+				else
 				{
 					Alarm_Counter[gun_index].Short[2] = 0;
 					if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CircuitShortL3 == ON)
@@ -899,7 +898,7 @@ int main(void)
 			//=====================================
 			// Rotatory switch detection
 			//=====================================
-			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_ROTATORY_SWITCH_FAULT)
+			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.rotate_switch_fault == ON)
 			{
 				if(ShmStatusCodeData->FaultCode.FaultEvents.bits.RotarySwitchFault == OFF)
 				{
@@ -908,7 +907,7 @@ int main(void)
 					DEBUG_INFO("ALARM_ROTATORY_SWITCH_FAULT : alarm \n");
 				}
 			}
-			else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_ROTATORY_SWITCH_FAULT))
+			else
 			{
 				if(ShmStatusCodeData->FaultCode.FaultEvents.bits.RotarySwitchFault == ON)
 				{
@@ -921,7 +920,7 @@ int main(void)
 			//=====================================
 			// Leakage module detection
 			//=====================================
-			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_LEAK_MODULE_FAIL)
+			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.leak_module_fail == ON)
 			{
 				if(ShmStatusCodeData->FaultCode.FaultEvents.bits.RcdSelfTestFail == OFF)
 				{
@@ -930,7 +929,7 @@ int main(void)
 					DEBUG_INFO("ALARM_LEAK_MODULE_FAIL : alarm \n");
 				}
 			}
-			else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_LEAK_MODULE_FAIL))
+			else
 			{
 				if(ShmStatusCodeData->FaultCode.FaultEvents.bits.RcdSelfTestFail == ON)
 				{
@@ -943,7 +942,7 @@ int main(void)
 			//=====================================
 			// Shutter detection
 			//=====================================
-			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_SHUTTER_FAULT)
+			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.shutter_fault == ON)
 			{
 				if(ShmStatusCodeData->FaultCode.FaultEvents.bits.ShutterFault == OFF)
 				{
@@ -952,7 +951,7 @@ int main(void)
 					DEBUG_INFO("ALARM_SHUTTER_FAULT : alarm \n");
 				}
 			}
-			else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_SHUTTER_FAULT))
+			else
 			{
 				if(ShmStatusCodeData->FaultCode.FaultEvents.bits.ShutterFault == ON)
 				{
@@ -965,7 +964,7 @@ int main(void)
 			//=====================================
 			// Locker detection
 			//=====================================
-			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_LOCKER_FAULT)
+			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.locker_fault == ON)
 			{
 				if(ShmStatusCodeData->FaultCode.FaultEvents.bits.AcConnectorLockFail == OFF)
 				{
@@ -974,7 +973,7 @@ int main(void)
 					DEBUG_INFO("ALARM_LOCKER_FAULT : alarm \n");
 				}
 			}
-			else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_LOCKER_FAULT))
+			else
 			{
 				if(ShmStatusCodeData->FaultCode.FaultEvents.bits.AcConnectorLockFail == ON)
 				{
@@ -987,7 +986,7 @@ int main(void)
 			//=====================================
 			// Power drop detection
 			//=====================================
-			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_POWER_DROP)
+			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.power_drop == ON)
 			{
 				if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputDrop == OFF)
 				{
@@ -996,7 +995,7 @@ int main(void)
 					DEBUG_INFO("ALARM_POWER_DROP : alarm \n");
 				}
 			}
-			else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_POWER_DROP))
+			else
 			{
 				if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputDrop == ON)
 				{
@@ -1009,7 +1008,7 @@ int main(void)
 			//=====================================
 			// Meter communication timeout detection
 			//=====================================
-			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_METER_TIMEOUT)
+			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.meter_comm_timeout == ON)
 			{
 				if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MeterCommTimeout == OFF)
 				{
@@ -1018,7 +1017,7 @@ int main(void)
 					DEBUG_INFO("ALARM_METER_TIMEOUT : alarm \n");
 				}
 			}
-			else if(!(ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode & ALARM_METER_TIMEOUT))
+			else
 			{
 				if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MeterCommTimeout == ON)
 				{
@@ -1028,6 +1027,50 @@ int main(void)
 				}
 			}
 
+			//=====================================
+			// Meter ic communication timeout detection
+			//=====================================
+			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.meter_ic_comm_timeout == ON)
+			{
+				if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MeterIcCommTimeout == OFF)
+				{
+					ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MeterIcCommTimeout = ON;
+					ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_METER_IC_TIMEOUT;
+					DEBUG_INFO("ALARM_METER_IC_TIMEOUT : alarm \n");
+				}
+			}
+			else
+			{
+				if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MeterIcCommTimeout == ON)
+				{
+					ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MeterIcCommTimeout = OFF;
+					ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_METER_IC_TIMEOUT;
+					DEBUG_INFO("ALARM_METER_IC_TIMEOUT : recover \n");
+				}
+			}
+
+			//=====================================
+			// Pilot negative error detection
+			//=====================================
+			if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.pilot_negative_error == ON)
+			{
+				if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PilotNegativeError == OFF)
+				{
+					ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PilotNegativeError = ON;
+					ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode |= ALARM_CP_NEG_ERROR;
+					DEBUG_INFO("ALARM_PILOT_NEGATIVE_ERROR : alarm \n");
+				}
+			}
+			else
+			{
+				if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PilotNegativeError == ON)
+				{
+					ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PilotNegativeError = OFF;
+					ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode &= ~ALARM_CP_NEG_ERROR;
+					DEBUG_INFO("ALARM_PILOT_NEGATIVE_ERROR : recover \n");
+				}
+			}
+
 			//=====================================
 			// OCPP error code message
 			//=====================================
@@ -1185,6 +1228,18 @@ int main(void)
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012305");
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "MeterCommunicationTimeout");
 				}
+				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_METER_IC_TIMEOUT)
+				{
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012344");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "MeterIcCommunicationTimeout");
+				}
+				else if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CP_NEG_ERROR)
+				{
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "OtherError");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].VendorErrorCode , "012345");
+					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].Info , "PilotNegativeError");
+				}
 				else
 				{
 					sprintf((char*)ShmOCPP16Data->StatusNotification[gun_index].ErrorCode , "NoError");
@@ -1882,6 +1937,54 @@ int main(void)
 						previousAlarmCode[gun_index] &= ~ALARM_METER_TIMEOUT;
 				}
 
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_METER_IC_TIMEOUT) != (previousAlarmCode[gun_index] & ALARM_METER_IC_TIMEOUT))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_METER_IC_TIMEOUT)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_METER_IC_TIMEOUT)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+					
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012344");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "Meter ic communication timeout");
+					
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "Meter");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+					
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+					
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_METER_IC_TIMEOUT)
+						previousAlarmCode[gun_index] |= ALARM_METER_IC_TIMEOUT;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_METER_IC_TIMEOUT;
+				}
+
+				if((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CP_NEG_ERROR) != (previousAlarmCode[gun_index] & ALARM_CP_NEG_ERROR))
+				{
+					getNowDatetime(ShmOCPP20Data->NotifyEvent.eventData[idxEvent].timestamp);
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventId = idxEvent;
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].trigger, "Alerting");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].actualValue, ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CP_NEG_ERROR)?"true":"false"));
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].cleared = ((ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CP_NEG_ERROR)?OFF:ON);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].eventNotificationType, "HardWiredNotification");
+					
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techcode, "012345");
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].techInfo, "Pilot negative error");
+					
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.name, "PCBA");
+					ShmOCPP20Data->NotifyEvent.eventData[idxEvent].component.evse.connectorId = (gun_index+1);
+					sprintf((char*)ShmOCPP20Data->NotifyEvent.eventData[idxEvent].variable.name, "Problem");
+					
+					idxEvent += ((idxEvent<ARRAY_SIZE(ShmOCPP20Data->NotifyEvent.eventData)-1)?1:0);
+					
+					if(ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode & ALARM_CP_NEG_ERROR)
+						previousAlarmCode[gun_index] |= ALARM_CP_NEG_ERROR;
+					else
+						previousAlarmCode[gun_index] &= ~ALARM_CP_NEG_ERROR;
+				}
+
 				if(idxEvent > 0)
 					ShmOCPP20Data->SpMsg.bits.NotifyEventReq = ON;
 			}

+ 23 - 0
EVSE/Projects/AW-CCS/Apps/Module_ConfigTools.c

@@ -699,6 +699,7 @@ int main(void)
 			printf("\n  stop: EVSE stop charging request.");
 			printf("\n  auth: Authorize request.");
 			printf("\n  ccs: CCS flow status.");
+			printf("\n  alarm: Simulate alarm status.");
 			printf("\n  cancel: return to main menu.");
 			printf("\n **************************************************");
 			printf("\n  Please input operation item: ");
@@ -792,6 +793,28 @@ int main(void)
 					printf("\n  Invalid input gun_index.");
 				}
 			}
+			else if(strcmp(cmd, "alarm") == 0)
+			{
+				memset(cmd, 0x00, ARRAY_SIZE(cmd));
+				printf("\n  Please input gun index(1~2): ");
+				scanf("%s", &cmd[0]);
+
+				if((0 < atoi(cmd)) && (atoi(cmd) < 3))
+				{
+					DEBUG_INFO("Alarm simulate gun-%d, OVP.\n", atoi(cmd));
+
+					while(1)
+					{
+						ShmCharger->gun_info[atoi(cmd)-1].systemAlarmCode.SystemAlarmCode |= ALARM_L1_OVER_VOLTAGE;
+						ShmCharger->gun_info[atoi(cmd)-1].primaryMcuAlarm.InputAlarmCode |= ALARM_L1_OVER_VOLTAGE;
+					}
+				}
+				else
+				{
+					printf("\n  Invalid input gun_index.");
+					sleep(1);
+				}
+			}
 			else if(strcmp(cmd, "cancel") == 0)
 			{}
 		}

+ 2 - 165
EVSE/Projects/AW-CCS/Apps/Module_InternalComm.c

@@ -847,6 +847,7 @@ unsigned char Query_AC_MCU_Alarm(unsigned char fd, unsigned char targetAddr, Ac_
 			}
 			Ret_Buf->bits.meter_comm_timeout = (((rx[9]>>4)&0x01)?1:0);
 			Ret_Buf->bits.meter_ic_comm_timeout = (((rx[9]>>5)&0x01)?1:0);
+			Ret_Buf->bits.pilot_negative_error = (((rx[9]>>6)&0x01)?1:0);
 
 			result = PASS;
 		}
@@ -2074,172 +2075,7 @@ int main(void)
 				{
 					//DEBUG_INFO("MCU-%d get alarm code success.\n",gun_index);
 
-					//================================================
-					// Byte[6]
-					// Byte[7]
-					// Byte[8] bits 3 Reserved
-					// Byte[9] bits 6 & 7 Reserved
-					//================================================
-
-					//================================================
-					// Byte[6]
-					//================================================
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.OVP_L1 == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<0;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<0);
-
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.UVP_L1 == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<1;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<1);
-
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.OCP_L1 == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<2;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<2);
-
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.OTP == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<3;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<3);
-
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.gmi_fault == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<4;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<4);
-
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.cp_fault == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<5;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<5);
-
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.ac_leak == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<6;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<6);
-
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.dc_leak == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<7;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<7);
-
-					//================================================
-					// Byte[7]
-					//================================================
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.mcu_selftest_fail == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<8;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<8);
-
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.handshaking_timeout == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<9;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<9);
-
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.emergency_stop == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<10;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<10);
-
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.relay_welding == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<11;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<11);
-
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.leak_module_fail == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<12;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<12);
-
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.shutter_fault == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<13;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<13);
-
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.locker_fault == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<14;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<14);
-
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.power_drop == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<15;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<15);
-
-					//================================================
-					// Byte[8]
-					//================================================
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.short_circuit_L1 == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<16;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<16);
-
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.rotate_switch_fault == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<17;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<17);
-
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.relay_drive_fault == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<18;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<18);
-					
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.OVP_L2 == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<20;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<20);
-
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.OVP_L3 == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<21;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<21);
-
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.UVP_L2 == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<22;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<22);
-
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.UVP_L3 == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<23;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<23);					
-
-					//================================================
-					// Byte[9] 
-					//================================================
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.OCP_L2 == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<24;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<24);
-
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.OCP_L3 == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<25;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<25);			
-
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.short_circuit_L2 == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<26;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<26);
-
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.short_circuit_L3 == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<27;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<27);
-
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.meter_comm_timeout == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<28;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<28);
-
-					if(ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.meter_ic_comm_timeout == 0x01)
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode |= 1<<29;
-					else
-						ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode &= ~(1<<29);
-
 					failCount[gun_index] = 0;
-					
 					ShmCharger->gun_info[gun_index].acCcsInfo.CSUAlarmStatusCode = ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode;
 				}
 				else
@@ -2508,6 +2344,7 @@ int main(void)
 							DEBUG_INFO("MCU-%d get relay_drive_fault : %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.relay_drive_fault);
 							DEBUG_INFO("MCU-%d get meter_comm_timeout : %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.meter_comm_timeout);
 							DEBUG_INFO("MCU-%d get meter_ic_comm_timeout : %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.meter_ic_comm_timeout);
+							DEBUG_INFO("MCU-%d get pilot_negative_error : %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuAlarm.bits.pilot_negative_error);
 							DEBUG_INFO("MCU-%d get InputAlarmCode : %x\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode);
 						}
 

+ 18 - 6
EVSE/Projects/AW-CCS/Apps/Module_PowerSharing.c

@@ -555,7 +555,7 @@ int tcpSocketServerStart(void)
 							switch(idxStep)
 							{
 								case 0:
-									if(difftime(time((time_t*)NULL), conn_getStatusStarttime(dupFd)) >= 3)
+									if((difftime(time((time_t*)NULL), conn_getStatusStarttime(dupFd)) >= 3) || (difftime(time((time_t*)NULL), conn_getStatusStarttime(dupFd)) < 0))
 									{
 										create_cmd_getStatus(&output);
 										conn_getStatusStarttimeUpdate(dupFd);
@@ -565,7 +565,7 @@ int tcpSocketServerStart(void)
 									idxStep++;
 									break;
 								default:
-									if((difftime(time((time_t*)NULL), conn_setCapacityStarttime(dupFd)) >= 1))
+									if((difftime(time((time_t*)NULL), conn_setCapacityStarttime(dupFd)) >= 1) || (difftime(time((time_t*)NULL), conn_setCapacityStarttime(dupFd)) < 0))
 									{
 										create_cmd_SetAvailableCurrent(&output, dupFd);
 										conn_setCapacityStarttimeUpdate(dupFd);
@@ -616,6 +616,7 @@ int tcpSocketClientStart(void)
 	struct hostent 		*ghbn;
 	struct timeval 		tv;
 	uint8_t 			socketEnable;
+	uint8_t				cntSocketErr;
 
 	struct Message		input;
 	struct Message		output;
@@ -648,6 +649,7 @@ int tcpSocketClientStart(void)
 		tv.tv_usec = 500000;
 		setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
 		socketEnable = ON;
+		cntSocketErr = 0;
 		ShmSysConfigAndInfo->SysInfo.localSharingInfo.isConnectedSharingServer = ON;
 	}
 
@@ -722,7 +724,17 @@ int tcpSocketClientStart(void)
 			ShmSysConfigAndInfo->SysInfo.localSharingInfo.isConnectedSharingServer = OFF;
 		}
 		else if(input.size == -1)
-		{}
+		{
+			if(cntSocketErr > 5)
+			{
+				socketEnable = OFF;
+				DEBUG_ERROR("Socket error occur\n");
+			}
+			else
+			{
+				cntSocketErr++;
+			}
+		}
 		usleep(1000000);
 	}
 	close(sockfd);
@@ -741,9 +753,9 @@ int balance_check_loop(void)
 		for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
 		{
 			if(ShmPowerSharing->Connection_Info[idx].isSocketConnected &&
-			   (difftime(time((time_t*)NULL), ShmPowerSharing->Connection_Info[idx].lastHeartBeatTime) > 300))
+			   ((difftime(time((time_t*)NULL), ShmPowerSharing->Connection_Info[idx].lastHeartBeatTime) > TIMEOUT_SPEC_HEARTBEAT) || (difftime(time((time_t*)NULL), ShmPowerSharing->Connection_Info[idx].lastHeartBeatTime) < 0)))
 			{
-				DEBUG_INFO("SocketFd-%d heart beat is over 300 seconds.\n", ShmPowerSharing->Connection_Info[idx].socketFd);
+				DEBUG_INFO("SocketFd-%d heart beat is over %d seconds.\n", ShmPowerSharing->Connection_Info[idx].socketFd, TIMEOUT_SPEC_HEARTBEAT);
 				ShmPowerSharing->Connection_Info[idx].isGunConnected = FALSE;
 				ShmPowerSharing->Connection_Info[idx].isSocketConnected = FALSE;
 			}
@@ -775,7 +787,7 @@ int balance_check_loop(void)
 			if(ShmPowerSharing->Connection_Info[idx].isSocketConnected &&
 			   ShmPowerSharing->Connection_Info[idx].isGunConnected)
 			{
-				if((difftime(time((time_t*)NULL), ShmPowerSharing->Connection_Info[idx].lastCheckCapacityTime) > 10))
+				if((difftime(time((time_t*)NULL), ShmPowerSharing->Connection_Info[idx].lastCheckCapacityTime) > TIMEOUT_SPEC_CHECK_CAPACITY) || (difftime(time((time_t*)NULL), ShmPowerSharing->Connection_Info[idx].lastCheckCapacityTime) < 0))
 				{
 					if(ShmPowerSharing->Connection_Info[idx].availableSharingCurrent >= (ShmPowerSharing->Connection_Info[idx].presentOutputCurrent+2))
 					{

+ 2 - 0
EVSE/Projects/AW-CCS/Apps/Module_PowerSharing.h

@@ -59,6 +59,8 @@
 
 #define LISTEN_PORT_TCP				118
 #define	CONNECTION_LIMIT			5
+#define TIMEOUT_SPEC_HEARTBEAT		180
+#define TIMEOUT_SPEC_CHECK_CAPACITY	10
 
 #define ShmPowerShargingKey			LISTEN_PORT_TCP+8000
 

+ 161 - 40
EVSE/Projects/AW-CCS/Apps/main.c

@@ -33,6 +33,7 @@
 #define TIMEOUT_SPEC_POWERSAVING_RFID			120000
 #define TIMEOUT_SPEC_POWERSAVING_METER			120000
 #define TIMEOUT_SPEC_POWERSAVING_LED_STATUS		120000
+#define TIMEOUT_SPEC_CEHCK_POWER_CONSUMPTION	15000
 
 //==========================
 // GPIO constant define
@@ -2955,7 +2956,7 @@ int upgrade_check()
 	DIR *dir;
 	struct dirent *file;
 	char cmd[512];
-	long int MaxLen=48*1024*1024;
+	long int MaxLen=48*1024*1024, ImageLen=0, wrd;
 
 	if ((dir = opendir ("/mnt")) != NULL)
 	{
@@ -2967,6 +2968,9 @@ int upgrade_check()
 				// Wait for MCU upgrade finish.
 				while(ShmCharger->gun_info[0].mcuFlag.isMcuUpgradeReq || (AC_QUANTITY>1?ShmCharger->gun_info[1].mcuFlag.isMcuUpgradeReq:FALSE))sleep(1);
 
+				// Wait for LCM upgrade finish.
+				while(ShmCharger->isUpgradeLcmReq)sleep(1);
+
 				memset(&ShmCharger->fwUpgradeInfo, 0xFF, sizeof(Fw_Upgrade_Info));
 				DEBUG_INFO("New firmware file: %s\n", file->d_name);
 				sprintf(ShmCharger->fwUpgradeInfo.location, "/mnt/%s", file->d_name);
@@ -2975,7 +2979,7 @@ int upgrade_check()
 				{
 					unsigned char *ptr = malloc(MaxLen); //-48 is take out the header
 					memset(ptr, 0xFF, MaxLen);  //-48 is take out the header
-					read(fd, ptr, MaxLen);
+					ImageLen = read(fd, ptr, MaxLen);
 					close(fd);
 
 					ShmCharger->fwUpgradeInfo.fwType = ((ptr[0x13]<<0) | (ptr[0x12]<<8) | (ptr[0x11]<<16) | (ptr[0x10]<<24));
@@ -3039,6 +3043,39 @@ int upgrade_check()
 							case AC_WALLMOUNT_CONTROLLER:
 								for(int gun_index = 0;gun_index<AC_QUANTITY;gun_index++)
 									ShmCharger->gun_info[gun_index].mcuFlag.isMcuUpgradeReq = ON;
+								sleep(10);
+								break;
+							case LCM:
+								fd = open("/mnt/lcm.zip", O_RDWR | O_CREAT | O_EXCL);
+								if (fd < 0)
+								{
+									DEBUG_ERROR("Can not create lcm.zip file.\n");
+									result = FAIL;
+								}
+								else
+								{
+									// Write image to flash
+									DEBUG_INFO("Writing data to lcm.zip file...\n");
+									wrd=write(fd, ptr+48, ImageLen-48);
+									close(fd);
+									DEBUG_INFO(">> lcm.zip Written length: 0x%x\n", wrd);
+									if(wrd != (ImageLen-48))
+									{
+										result = FAIL;
+									}
+									else
+									{
+										runShellCmd("mkdir -p /mnt/lcd");
+										runShellCmd("unzip /mnt/lcm.zip -d /mnt/lcd");
+										sprintf(cmd, "yes|rm %s", ShmCharger->fwUpgradeInfo.location);
+										system(cmd);
+										system("rm -f /mnt/lcm.zip");
+										result = PASS;
+									}
+								}
+
+								ShmCharger->isUpgradeLcmReq = ON;
+								sleep(10);
 								break;
 							default:
 								result = FAIL;
@@ -3055,7 +3092,6 @@ int upgrade_check()
 						sprintf(cmd, "yes|rm %s", ShmCharger->fwUpgradeInfo.location);
 						system(cmd);
 					}
-
 					free(ptr);
 				}
 				else
@@ -3987,13 +4023,14 @@ void checkReservation(uint8_t gun_index)
 		if(ShmOCPP16Data->CsMsg.bits[gun_index].ReserveNowReq)
 		{
 			ShmOCPP16Data->CsMsg.bits[gun_index].ReserveNowReq = OFF;
+			ShmOCPP16Data->CsMsg.bits[gun_index].ReserveNowConf = ON;
 			if(isMode(gun_index, SYS_MODE_IDLE) && !isReservationExpired(gun_index))
 			{
+				sleep(5);
 				ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId = ShmOCPP16Data->ReserveNow[gun_index].ReservationId;
 				setChargerMode(gun_index, SYS_MODE_RESERVATION);
 			}
-			DEBUG_INFO("Reservation request on connector-%d.\n", gun_index);
-			ShmOCPP16Data->CsMsg.bits[gun_index].ReserveNowConf = ON;
+			DEBUG_INFO("Reservation request on gun-%d.\n", gun_index);
 		}
 	}
 	else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
@@ -4001,13 +4038,13 @@ void checkReservation(uint8_t gun_index)
 		if(ShmOCPP20Data->CsMsg.bits[gun_index].ReserveNowReq)
 		{
 			ShmOCPP20Data->CsMsg.bits[gun_index].ReserveNowReq = OFF;
+			ShmOCPP20Data->CsMsg.bits[gun_index].ReserveNowConf = ON;
 			if(isMode(gun_index, SYS_MODE_IDLE) && !isReservationExpired(gun_index))
 			{
 				ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId = ShmOCPP20Data->ReserveNow[gun_index].id;
 				setChargerMode(gun_index, SYS_MODE_RESERVATION);
 			}
-			DEBUG_INFO("Reservation request on connector-%d.\n", gun_index);
-			ShmOCPP20Data->CsMsg.bits[gun_index].ReserveNowConf = ON;
+			DEBUG_INFO("Reservation request on gun-%d.\n", gun_index);
 		}
 	}
 }
@@ -4237,7 +4274,7 @@ void checkStopReason(uint8_t gun_index)
 		{
 			sprintf((char*)ShmOCPP16Data->StopTransaction[gun_index].StopReason, "Other");
 		}
-		DEBUG_INFO("Gun-%d : StopReason [ %s ]...\n.",gun_index,ShmOCPP16Data->StopTransaction[gun_index].StopReason);
+		DEBUG_INFO("Gun-%d : StopReason [ %s ]...\n",gun_index,ShmOCPP16Data->StopTransaction[gun_index].StopReason);
 
 		ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/10000.0);
 		presentChargedEnergyUpdate(gun_index);
@@ -4304,7 +4341,7 @@ void checkStopReason(uint8_t gun_index)
 		{
 			sprintf((char*)ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason, "Other");
 		}
-		DEBUG_INFO("Gun-%d : StopReason [ %s ]...\n.", gun_index, ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason);
+		DEBUG_INFO("Gun-%d : StopReason [ %s ]...\n", gun_index, ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason);
 
 		ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/10000.0);
 		presentChargedEnergyUpdate(gun_index);
@@ -4328,6 +4365,7 @@ void checkRemoteUpgradeStatus()
 		{
 			DEBUG_INFO("Firmware remote upgrading...\n");
 			sprintf((char*)ShmOCPP16Data->FirmwareStatusNotification.Status, "Installing");
+			sleep(1);
 			ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = ON;
 			ShmOCPP16Data->MsMsg.bits.UpdateFirmwareReq = OFF;
 			int result = upgrade_check();
@@ -4762,7 +4800,8 @@ int main(void)
 			   (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_UPDATE) ||
 			   (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_MAINTAIN) ||
 			   (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_CHARGING) ||
-			   (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_TERMINATING))
+			   (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_TERMINATING) || 
+			   (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_COMPLETE))
 			{
 				ftime(&startTime[gun_index][TMR_IDX_POWERSAVING_LCD]);
 				ftime(&startTime[gun_index][TMR_IDX_POWERSAVING_RFID]);
@@ -4774,7 +4813,7 @@ int main(void)
 				if((gpio_get_value(GPIO_IN_WAKEUP) == OFF) ||
 				   (ShmCharger->gun_info[gun_index].GPIO_Input.Button_Mode_Switch == ON) ||
 				   (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus != ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus) ||
-				   (((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_IDLE) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_PREPARING)) &&
+				   (((ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_IDLE) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_PREPARING) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_RESERVATION)) &&
 					(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_B) &&
 					(DiffTimebWithNow(startTime[gun_index][TMR_IDX_POWERSAVING_STATE_B]) < 10000)))
 				{
@@ -4782,6 +4821,22 @@ int main(void)
 					ftime(&startTime[gun_index][TMR_IDX_POWERSAVING_RFID]);
 					ftime(&startTime[gun_index][TMR_IDX_POWERSAVING_METER]);
 					ftime(&startTime[gun_index][TMR_IDX_POWERSAVING_LED_STATUS]);
+
+					if(((gpio_get_value(GPIO_IN_WAKEUP) == OFF) || (ShmCharger->gun_info[gun_index].GPIO_Input.Button_Mode_Switch == ON)) &&
+					   (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_IDLE) &&
+					   (DiffTimebWithNow(startTime[ShmCharger->gun_selectd][TMR_IDX_CHECK_POWER_CONSUMPTION]) > TIMEOUT_SPEC_CEHCK_POWER_CONSUMPTION))
+					{
+						ShmCharger->gun_info[gun_index].isCheckPowerConsumption = YES;
+						ftime(&startTime[gun_index][TMR_IDX_LCM_POWER_CONSUMPTION]);
+					}
+				}
+				else
+				{
+					ftime(&startTime[gun_index][TMR_IDX_CHECK_POWER_CONSUMPTION]);
+					if((DiffTimebWithNow(startTime[ShmCharger->gun_selectd][TMR_IDX_LCM_POWER_CONSUMPTION]) > TIMEOUT_SPEC_CEHCK_POWER_CONSUMPTION))
+					{
+						ShmCharger->gun_info[gun_index].isCheckPowerConsumption = NO;
+					}
 				}
 			}
 
@@ -4837,21 +4892,21 @@ int main(void)
 					ShmCharger->gun_info[gun_index].isMeterOn = ON;
 				}
 			}
-			
+
 			if(DiffTimebWithNow(startTime[gun_index][TMR_IDX_POWERSAVING_LED_STATUS]) > TIMEOUT_SPEC_POWERSAVING_LED_STATUS)
 			{
-				if(ShmCharger->gun_info[gun_index].isSleepOn == OFF)
+				if(ShmCharger->gun_info[gun_index].isSleepOn == NO)
 				{
 					DEBUG_INFO("LED status into power saving...%d\n", DiffTimebWithNow(startTime[gun_index][TMR_IDX_POWERSAVING_LED_STATUS]));
-					ShmCharger->gun_info[gun_index].isSleepOn = ON;
+					ShmCharger->gun_info[gun_index].isSleepOn = YES;
 				}
 			}
 			else
 			{
-				if(ShmCharger->gun_info[gun_index].isSleepOn == ON)
+				if(ShmCharger->gun_info[gun_index].isSleepOn == YES)
 				{
 					DEBUG_INFO("LED status exit power saving...%d\n", DiffTimebWithNow(startTime[gun_index][TMR_IDX_POWERSAVING_LED_STATUS]));
-					ShmCharger->gun_info[gun_index].isSleepOn = OFF;
+					ShmCharger->gun_info[gun_index].isSleepOn = NO;
 				}
 			}
 
@@ -4959,6 +5014,7 @@ int main(void)
 						ftime(&startTime[gun_index][TMR_IDX_POWERSAVING_METER]);
 						ftime(&startTime[gun_index][TMR_IDX_POWERSAVING_STATE_B]);
 						ftime(&startTime[gun_index][TMR_IDX_POWERSAVING_LED_STATUS]);
+						ftime(&startTime[gun_index][TMR_IDX_LCM_POWER_CONSUMPTION]);
 					}
 
 					if(ShmCharger->gun_info[gun_index].mcuFlag.isReadFwVerPass &&
@@ -5021,9 +5077,9 @@ int main(void)
 
 						// Default LCM brightness to 100
 						ShmCharger->isLcdOn = ON;
-						
+
 						// Defaule led status to not sleep mode
-						ShmCharger->gun_info[gun_index].isSleepOn = OFF;
+						ShmCharger->gun_info[gun_index].isSleepOn = NO;
 
 						// If Web Server OPCC URL is empty kill Module_OcppBackend
 						if((strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0) || ShmSysConfigAndInfo->SysConfig.isEnableLocalPowerSharging)
@@ -5083,23 +5139,29 @@ int main(void)
 						if(ShmCharger->isCcsEnable)system("pkill Module_CCS");
 						DB_Check_Record_Buf(localDb, gun_index);
 					}
-					
+
 					// LED status in Idle mode
-					if(!ShmCharger->isAuthrizing && (strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") == 0))
+					if(!ShmCharger->isAuthrizing)
 					{
 						if(ShmSysConfigAndInfo->SysInfo.OcppConnStatus == ON)
 						{
-							if(ShmCharger->gun_info[gun_index].isSleepOn == OFF)
-								setLedMotion(gun_index,LED_ACTION_IDLE_BACKEND_CONNECTED);
-							else
-								setLedMotion(gun_index,LED_ACTION_IDLE_BACKEND_CONNECTED_SLEEP);
+							if(ShmCharger->gun_info[gun_index].rfidReq == OFF)
+							{
+								if(ShmCharger->gun_info[gun_index].isSleepOn == NO)
+									setLedMotion(gun_index,LED_ACTION_IDLE_BACKEND_CONNECTED);
+								else
+									setLedMotion(gun_index,LED_ACTION_IDLE_BACKEND_CONNECTED_SLEEP);
+							}
 						}
 						else
 						{
-							if(ShmCharger->gun_info[gun_index].isSleepOn == OFF)
-								setLedMotion(gun_index,LED_ACTION_IDLE_BACKEND_DISCONNECTED);
-							else
-								setLedMotion(gun_index,LED_ACTION_IDLE_BACKEND_DISCONNECTED_SLEEP);
+							if(ShmCharger->gun_info[gun_index].rfidReq == OFF)
+							{
+								if(ShmCharger->gun_info[gun_index].isSleepOn == NO)
+									setLedMotion(gun_index,LED_ACTION_IDLE_BACKEND_DISCONNECTED);
+								else
+									setLedMotion(gun_index,LED_ACTION_IDLE_BACKEND_DISCONNECTED_SLEEP);
+							}
 						}
 					}
 
@@ -5157,18 +5219,48 @@ int main(void)
 							ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmCharger->gun_info[gun_index].primaryMcuState.rating_current)?ShmCharger->gun_info[gun_index].primaryMcuState.rating_current:ShmCharger->gun_info[gun_index].targetCurrent);
 
 							if(ShmCharger->isCcsEnable)
+							{
 								ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_5;
+							}
 							else
-								ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmCharger->gun_info[gun_index].primaryMcuState.rating_current)?ShmCharger->gun_info[gun_index].primaryMcuState.rating_current:ShmCharger->gun_info[gun_index].targetCurrent);
+							{
+								if((6 <= ShmCharger->gun_info[gun_index].targetCurrent))
+								{
+									ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmCharger->gun_info[gun_index].primaryMcuState.rating_current)?ShmCharger->gun_info[gun_index].primaryMcuState.rating_current:ShmCharger->gun_info[gun_index].targetCurrent);
+								}
+								else if((1 <= ShmCharger->gun_info[gun_index].targetCurrent) && (ShmCharger->gun_info[gun_index].targetCurrent < 6))
+								{
+									ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = 6;
+								}
+								else
+								{
+									ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = 100;
+								}
+							}
 						}
 						else
 						{
 							ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent)?ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent:ShmCharger->gun_info[gun_index].targetCurrent);
 
 							if(ShmCharger->isCcsEnable)
+							{
 								ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_5;
+							}
 							else
-								ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent)?ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent:ShmCharger->gun_info[gun_index].targetCurrent);
+							{
+								if((6 <= ShmCharger->gun_info[gun_index].targetCurrent))
+								{
+									ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent)?ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent:ShmCharger->gun_info[gun_index].targetCurrent);
+								}
+								else if((1 <= ShmCharger->gun_info[gun_index].targetCurrent) && (ShmCharger->gun_info[gun_index].targetCurrent < 6))
+								{
+									ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = 6;
+								}
+								else
+								{
+									ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = 100;
+								}
+							}
 						}
 						ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = YES;
 
@@ -5214,8 +5306,18 @@ int main(void)
 											DEBUG_INFO("Authorize pass.\n");
 											setSpeaker(ON,SPEAKER_SHORT);
 											setLedMotion(gun_index,LED_ACTION_RFID_PASS);
-											sleep(3);
-											if(ShmCharger->isCcsEnable)system("/root/Module_CCS &");
+											if(ShmCharger->isCcsEnable)
+											{
+												ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_CP_STATE_F;
+												ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON;
+												sleep(4);
+												ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_100;
+												ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON;
+												system("/root/Module_CCS &");
+											}
+											else
+												sleep(4);
+
 											setChargerMode(gun_index, SYS_MODE_PREPARING);
 										}
 										else
@@ -5232,7 +5334,16 @@ int main(void)
 								}
 								else
 								{
-									if(ShmCharger->isCcsEnable)system("/root/Module_CCS &");
+									if(ShmCharger->isCcsEnable)
+									{
+										ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_CP_STATE_F;
+										ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON;
+										sleep(4);
+										ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_100;
+										ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON;
+										system("/root/Module_CCS &");
+									}
+
 									setChargerMode(gun_index, SYS_MODE_PREPARING);
 								}
 								break;
@@ -5240,7 +5351,15 @@ int main(void)
 							case START_METHOD_BLE:
 							case START_METHOD_FREE:
 							default:
-								if(ShmCharger->isCcsEnable)system("/root/Module_CCS &");
+								if(ShmCharger->isCcsEnable)
+								{
+									ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_CP_STATE_F;
+									ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON;
+									sleep(4);
+									ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_100;
+									ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON;
+									system("/root/Module_CCS &");
+								}
 								setChargerMode(gun_index, SYS_MODE_PREPARING);
 								break;
 						}
@@ -5255,7 +5374,9 @@ int main(void)
 						ShmCharger->gun_info[gun_index].resultAuthorization = DEFAULT_RFID;												 
 
 						if(ShmCharger->isCcsEnable)
+						{
 							ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_DUTY_5;
+						}
 						else
 						{
 							ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_CP_STATE_E;
@@ -5930,8 +6051,8 @@ int main(void)
 						{
 							ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_100;
 							ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON;
+							sleep(1);
 							checkStopReason(gun_index);
-							sleep(6);
 							setChargerMode(gun_index, SYS_MODE_COMPLETE);
 						}
 						else if(ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_HLC)
@@ -5955,7 +6076,7 @@ int main(void)
 						{
 							setLedMotion(gun_index, LED_ACTION_STOP);
 						}
-						
+
 						// Charging profile preparation
 						if((DiffTimebWithNow(startTime[gun_index][TMR_IDX_PROFILE_PREPARE]) > TIMEOUT_SPEC_PROFILE_PREPARE) || (DiffTimebWithNow(startTime[gun_index][TMR_IDX_PROFILE_PREPARE]) < 0))
 						{
@@ -5972,7 +6093,7 @@ int main(void)
 
 						// Checking profile id > 0 and current time is between charging profile validFrom & validTo
 						checkChargingProfileLimit(gun_index);
-						
+
 						// Determine max charging current to MCU
 						if(ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent == 0)
 						{
@@ -6082,7 +6203,7 @@ int main(void)
 						ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_100;
 						ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON;
 						ShmCharger->gun_info[gun_index].isCCSWaitChangeDuty = OFF;
-
+						sleep(1);
 						checkStopReason(gun_index);
 						setChargerMode(gun_index, SYS_MODE_COMPLETE);
 					}
@@ -6092,7 +6213,7 @@ int main(void)
 					if(isModeChange(gun_index))
 					{
 						setLedMotion(gun_index, LED_ACTION_STOP);
-						sleep(2);
+						sleep(6);
 						setRelay(gun_index, OFF);
 						setRequest(gun_index, OFF);
 						sleep(13);
@@ -6187,7 +6308,7 @@ int main(void)
 						//======================================
 						// Upgrade complete reboot system
 						//======================================
-						if(!ShmCharger->gun_info[gun_index].mcuFlag.isMcuUpgradeReq && ((AC_QUANTITY>1)?!ShmCharger->gun_info[gun_index^1].mcuFlag.isMcuUpgradeReq:YES))
+						if(!ShmCharger->gun_info[gun_index].mcuFlag.isMcuUpgradeReq && ((AC_QUANTITY>1)?!ShmCharger->gun_info[gun_index^1].mcuFlag.isMcuUpgradeReq:YES) && !ShmCharger->isUpgradeLcmReq)
 						{
 							if(ShmCharger->isUpdateSuccess == YES)
 							{

+ 14 - 9
EVSE/Projects/AW-CCS/Apps/main.h

@@ -77,6 +77,7 @@
 #define ALARM_L3_CIRCUIT_SHORT                  0x08000000
 #define ALARM_METER_TIMEOUT						0x10000000
 #define ALARM_METER_IC_TIMEOUT					0x20000000
+#define ALARM_CP_NEG_ERROR 						0x40000000
 
 //=================================
 //CCS related define
@@ -229,8 +230,8 @@ enum TIMER_IDX
 	TMR_IDX_POWERSAVING_STATE_B,
 	TMR_IDX_CHECK_TASK,
 	TMR_IDX_POWERSAVING_LED_STATUS,
-	TMR_IDX_13,
-	TMR_IDX_14,
+	TMR_IDX_CHECK_POWER_CONSUMPTION,
+	TMR_IDX_LCM_POWER_CONSUMPTION,
 	TMR_IDX_15,
 	TMR_IDX_16,
 	TMR_IDX_17,
@@ -426,6 +427,7 @@ typedef struct AC_PRIMARY_MCU_ALARM
 			unsigned long short_circuit_L3:1;
 			unsigned long meter_comm_timeout:1;
 			unsigned long meter_ic_comm_timeout:1;
+			unsigned long pilot_negative_error:1;
 		}bits;
 	};
 }Ac_Primary_Mcu_Alarm;
@@ -753,7 +755,8 @@ typedef struct GUN_INFO
 	uint16_t										isChargerStopByCondition:1;
 	uint16_t										isMeterOn:1;
 	uint16_t										isSleepOn:1;
-	uint16_t										:2;
+	uint16_t										isCheckPowerConsumption:1;
+	uint16_t										:1;
 }Gun_Info;
 
 struct Charger
@@ -766,12 +769,14 @@ struct Charger
 
 	uint8_t					gun_selectd;
 	uint8_t	 				speaker_type;
-	uint8_t					isSpeakerOn:1;
-	uint8_t		 			isUpdateSuccess:1;
-	uint8_t		 			isCcsEnable:1;
-	uint8_t					isLcdOn:1;
-	uint8_t					isAuthrizing:1;
-	uint8_t					isGetAuthResult:1;
+	uint16_t				isSpeakerOn:1;
+	uint16_t		 		isUpdateSuccess:1;
+	uint16_t		 		isCcsEnable:1;
+	uint16_t				isLcdOn:1;
+	uint16_t				isAuthrizing:1;
+	uint16_t				isGetAuthResult:1;
+	uint16_t				isUpgradeLcmReq:1;
+	uint16_t				isUpgradeLcmSuccess:1;
 };
 
 #endif /* CONFIG_MAIN_H_ */

二進制
EVSE/Projects/AW-CCS/Images/FactoryDefaultConfig.bin


二進制
EVSE/Projects/AW-CCS/Images/ramdisk.gz


+ 198 - 84
EVSE/Projects/AW-Regular/Apps/Module_ConfigTools.c

@@ -22,12 +22,12 @@
 
 #include 	<unistd.h>
 #include 	<stdarg.h>
-#include    <stdio.h>      /*標準輸入輸出定義*/
-#include    <stdlib.h>     /*標準函數庫定義*/
-#include    <unistd.h>     /*Unix 標準函數定義*/
-#include    <fcntl.h>      /*檔控制定義*/
-#include    <termios.h>    /*PPSIX 終端控制定義*/
-#include    <errno.h>      /*錯誤號定義*/
+#include    <stdio.h>
+#include    <stdlib.h>
+#include    <unistd.h>
+#include    <fcntl.h>
+#include    <termios.h>
+#include    <errno.h>
 #include 	<errno.h>
 #include 	<string.h>
 #include	<time.h>
@@ -37,14 +37,11 @@
 #include	<stddef.h>
 #include	<stdint.h>
 #include 	"define.h"
+#include 	"main.h"
 
 //=================================
 // System basic sample constant
 //=================================
-#define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
-#define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
-#define DEBUG_ERROR(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
-
 #define ARRAY_SIZE(A)					(sizeof(A) / sizeof(A[0]))
 #define PASS							1
 #define FAIL							-1
@@ -56,6 +53,8 @@
 
 struct SysConfigAndInfo			*ShmSysConfigAndInfo;
 struct StatusCodeData			*ShmStatusCodeData;
+struct OCPP16Data 				*ShmOCPP16Data;
+struct Charger					*ShmCharger;
 
 int StoreLogMsg(const char *fmt, ...)
 {
@@ -152,12 +151,12 @@ int StoreUsrConfigData(struct SysConfigData *UsrData)
 
 
 		DEBUG_INFO("Erase /dev/mtd10.\n");
-		runShellCmd("flash_erase /dev/mtd10 0 12");
+		runShellCmd("flash_erase /dev/mtd10 0 0");
 		DEBUG_INFO("Write /dev/mtd10.\n");
 		runShellCmd("nandwrite -p /dev/mtd10 /mnt/EvseConfig.bin");
 
 		DEBUG_INFO("Erase /dev/mtd11.\n");
-		runShellCmd("flash_erase /dev/mtd11 0 12");
+		runShellCmd("flash_erase /dev/mtd11 0 0");
 		DEBUG_INFO("Write /dev/mtd11.\n");
 		runShellCmd("nandwrite -p /dev/mtd11 /mnt/EvseConfig.bin");
 
@@ -185,36 +184,60 @@ int InitShareMemory()
 	//Initial ShmSysConfigAndInfo
 	if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), 0777)) < 0)
 	{
-		#ifdef SystemLogMessage
 		DEBUG_ERROR("shmget ShmSysConfigAndInfo NG\n");
-		#endif
 		result = FAIL;
 	}
 	else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
 	{
-		#ifdef SystemLogMessage
 		DEBUG_ERROR("[shmat ShmSysConfigAndInfo NG\n");
-		#endif
 		result = FAIL;
 	}
+	else
+	{}
 
 	//Initial ShmStatusCodeData
 	if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), 0777)) < 0)
 	{
-		#ifdef SystemLogMessage
 		DEBUG_ERROR("shmget ShmStatusCodeData NG\n");
-		#endif
 		result = FAIL;
 	}
 	else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
 	{
-		#ifdef SystemLogMessage
 		DEBUG_ERROR("shmat ShmStatusCodeData NG\n");
-		#endif
 		result = FAIL;
 	}
+	else
+	{}
 
-	return result;
+	//Initial ShmOCPP16Data
+   	if ((MeterSMId = shmget(ShmOcppModuleKey, sizeof(struct OCPP16Data), 0777)) < 0)
+	{
+		DEBUG_ERROR("shmget ShmOCPP16Data NG\n");
+		result = FAIL;
+	}
+	else if ((ShmOCPP16Data = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+	{
+		DEBUG_ERROR("shmat ShmOCPP16Data NG\n");
+		result = FAIL;
+	}
+	else
+	{}
+
+	//Initial ShmCharger
+   	if ((MeterSMId = shmget(ShmChargerKey, sizeof(struct Charger), 0777)) < 0)
+    {
+   		DEBUG_ERROR("shmget ShmCharger NG\n");
+   		result = FAIL;
+	}
+    else if ((ShmCharger = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+    	DEBUG_ERROR("shmat ShmCharger NG\n");
+    	result = FAIL;
+   	}
+    else
+    {}
+
+   	return result;
 }
 
 int main(void)
@@ -235,7 +258,7 @@ int main(void)
 	}
 	else
 	{
-		DEBUG_INFO("InitShareMemory OK.\r\n");
+		DEBUG_INFO("InitShareMemory OK.\n");
 	}
 
 
@@ -243,7 +266,7 @@ int main(void)
 	{
 		system("clear");
 		memset(cmd, 0x00, ARRAY_SIZE(cmd));
-		printf("\n ===== main menu ===================================");
+		printf("\n ===== main menu ==================================");
 		printf("\n  system: system configuration menu.");
 		printf("\n  ocpp: ocpp configuration menu.");
 		printf("\n  network: netwok configuration menu.");
@@ -251,7 +274,7 @@ int main(void)
 		printf("\n  upgrade: trigger firmware upgrade.");
 		printf("\n  save: Save config.");
 		printf("\n  exit: Exit config tools.");
-		printf("\n =================================================");
+		printf("\n ==================================================");
 		printf("\n  Please input item name to config: ");
 		scanf("%s", &cmd[0]);
 
@@ -264,18 +287,18 @@ int main(void)
 			printf("\n  serialnumber: EVSE serial number.");
 			printf("\n  authentication: Authentication function.");
 			printf("\n  rfidendian: RFID read endian.");
-			printf("\n *************************************************");
+			printf("\n **************************************************");
 			printf("\n  Please input operation item: ");
 			scanf("%s", &cmd[0]);
 
 			if(strcmp(cmd, "modelname") == 0)
 			{
 				memset(cmd, 0x00, ARRAY_SIZE(cmd));
-				printf("\n *************************************************");
+				printf("\n ***** modelname **********************************");
 				printf("\n  Current model name: %s", ShmSysConfigAndInfo->SysConfig.ModelName);
 				printf("\n  0: Keep current config.");
 				printf("\n  1: Input new model name.");
-				printf("\n *************************************************");
+				printf("\n **************************************************");
 				printf("\n  Please input operation item: ");
 				scanf("%s", &cmd[0]);
 
@@ -286,16 +309,17 @@ int main(void)
 
 					memset(&ShmSysConfigAndInfo->SysConfig.ModelName[0], 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.ModelName));
 					strcpy((char*)&ShmSysConfigAndInfo->SysConfig.ModelName[0], (char*)&cmd[0]);
+					DEBUG_INFO("Input model name: %s\n", ShmSysConfigAndInfo->SysConfig.ModelName);
 				}
 			}
 			else if(strcmp(cmd, "serialnumber") == 0)
 			{
 				memset(cmd, 0x00, ARRAY_SIZE(cmd));
-				printf("\n *************************************************");
+				printf("\n ***** serialnumber *******************************");
 				printf("\n  Current serial number: %s", ShmSysConfigAndInfo->SysConfig.SerialNumber);
 				printf("\n  0: Keep current config.");
 				printf("\n  1: Input new serial number.");
-				printf("\n *************************************************");
+				printf("\n **************************************************");
 				printf("\n  Please input operation item: ");
 				scanf("%s", &cmd[0]);
 
@@ -306,58 +330,65 @@ int main(void)
 
 					memset(&ShmSysConfigAndInfo->SysConfig.SerialNumber[0], 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SerialNumber));
 					strcpy((char*)&ShmSysConfigAndInfo->SysConfig.SerialNumber[0], (char*)&cmd[0]);
+					DEBUG_INFO("Input serial number: %s\n", ShmSysConfigAndInfo->SysConfig.SerialNumber);
 				}
 			}
 			else if(strcmp(cmd, "authentication") == 0)
 			{
 				memset(cmd, 0x00, ARRAY_SIZE(cmd));
-				printf("\n *************************************************");
+				printf("\n ***** authentication *****************************");
+				printf("\n  Current mode: %d", ShmSysConfigAndInfo->SysConfig.AuthorisationMode);
 				printf("\n  0: Enable.");
 				printf("\n  1: Disable.");
-				printf("\n *************************************************");
-
-				printf("\n  Current mode: %d", ShmSysConfigAndInfo->SysConfig.AuthorisationMode);
+				printf("\n **************************************************");
 				printf("\n  Please input authentication mode: ");
 				scanf("%s", &cmd[0]);
 
 				ShmSysConfigAndInfo->SysConfig.AuthorisationMode = ((0<=atoi(cmd))&&(atoi(cmd)<=1)?atoi(cmd):0);
+				if(ShmSysConfigAndInfo->SysConfig.AuthorisationMode)
+					DEBUG_INFO("Authentication: Disable\n");
+				else
+					DEBUG_INFO("Authentication: Enable\n");
 			}
 			else if(strcmp(cmd, "rfidendian") == 0)
 			{
 				memset(cmd, 0x00, ARRAY_SIZE(cmd));
-				printf("\n *************************************************");
+				printf("\n ***** rfidendian *********************************");
+				printf("\n  Current mode: %d", ShmSysConfigAndInfo->SysConfig.RfidCardNumEndian);
 				printf("\n  0: Little endian.");
 				printf("\n  1: Big endian.");
-				printf("\n *************************************************");
-
-				printf("\n  Current mode: %d", ShmSysConfigAndInfo->SysConfig.RfidCardNumEndian);
+				printf("\n **************************************************");
 				printf("\n  Please input rfid endian mode: ");
 				scanf("%s", &cmd[0]);
 
 				ShmSysConfigAndInfo->SysConfig.RfidCardNumEndian = ((0<=atoi(cmd))&&(atoi(cmd)<=1)?atoi(cmd):0);
+				if(ShmSysConfigAndInfo->SysConfig.RfidCardNumEndian)
+					DEBUG_INFO("Authentication: Little endian\n");
+				else
+					DEBUG_INFO("Authentication: Big endian\n");
 			}
 		}
 		else if(strcmp(cmd, "ocpp") == 0)
 		{
 			memset(cmd, 0x00, ARRAY_SIZE(cmd));
-			printf("\n *************************************************");
+			printf("\n ***** ocpp ***************************************");
 			printf("\n  ocppurl: OCPP backend server url.");
 			printf("\n  cboxid: Charger box id.");
 			printf("\n  vender: Charger point vender.");
 			printf("\n  offlinepolicy: Charger off line policy.");
 			printf("\n  localloadbalance: Charger local load balance.");
-			printf("\n *************************************************");
+			printf("\n **************************************************");
 			printf("\n  Please input operation item: ");
 			scanf("%s", &cmd[0]);
 
 			if(strcmp(cmd, "ocppurl") == 0)
 			{
 				memset(cmd, 0x00, ARRAY_SIZE(cmd));
-				printf("\n *************************************************");
+				printf("\n ***** ocppurl ************************************");
 				printf("\n  Current OCPP url: %s", ShmSysConfigAndInfo->SysConfig.OcppServerURL);
 				printf("\n  0: Keep current config.");
 				printf("\n  1: Input new ocpp url.");
-				printf("\n *************************************************");
+				printf("\n **************************************************");
 				printf("\n  Please input operation item: ");
 				scanf("%s", &cmd[0]);
 
@@ -368,16 +399,17 @@ int main(void)
 
 					memset(&ShmSysConfigAndInfo->SysConfig.OcppServerURL[0], 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.OcppServerURL));
 					strcpy((char*)&ShmSysConfigAndInfo->SysConfig.OcppServerURL[0], (char*)&cmd[0]);
+					DEBUG_INFO("Input ocpp url: %s\n", ShmSysConfigAndInfo->SysConfig.OcppServerURL);
 				}
 			}
 			else if(strcmp(cmd, "cboxid") == 0)
 			{
 				memset(cmd, 0x00, ARRAY_SIZE(cmd));
-				printf("\n *************************************************");
+				printf("\n ***** cboxid *************************************");
 				printf("\n  Current OCPP charger box id: %s", ShmSysConfigAndInfo->SysConfig.ChargeBoxId);
 				printf("\n  0: Keep current config.");
 				printf("\n  1: Input new charger box id.");
-				printf("\n *************************************************");
+				printf("\n **************************************************");
 				printf("\n  Please input operation item: ");
 				scanf("%s", &cmd[0]);
 
@@ -388,16 +420,17 @@ int main(void)
 
 					memset(&ShmSysConfigAndInfo->SysConfig.ChargeBoxId[0], 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.ChargeBoxId));
 					strcpy((char*)&ShmSysConfigAndInfo->SysConfig.ChargeBoxId[0], (char*)&cmd[0]);
+					DEBUG_INFO("Input ocpp charger box id: %s\n", ShmSysConfigAndInfo->SysConfig.ChargeBoxId);
 				}
 			}
 			else if(strcmp(cmd, "vender") == 0)
 			{
 				memset(cmd, 0x00, ARRAY_SIZE(cmd));
-				printf("\n *************************************************");
+				printf("\n ***** vender *************************************");
 				printf("\n  Current OCPP vender: %s", ShmSysConfigAndInfo->SysConfig.chargePointVendor);
 				printf("\n  0: Keep current config.");
 				printf("\n  1: Input new charger box id.");
-				printf("\n *************************************************");
+				printf("\n **************************************************");
 				printf("\n  Please input operation item: ");
 				scanf("%s", &cmd[0]);
 
@@ -408,42 +441,58 @@ int main(void)
 
 					memset(&ShmSysConfigAndInfo->SysConfig.chargePointVendor[0], 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.chargePointVendor));
 					strcpy((char*)&ShmSysConfigAndInfo->SysConfig.chargePointVendor[0], (char*)&cmd[0]);
+					DEBUG_INFO("Input ocpp vender: %s\n", ShmSysConfigAndInfo->SysConfig.chargePointVendor);
 				}
 			}
 			else if(strcmp(cmd, "offlinepolicy") == 0)
 			{
 				memset(cmd, 0x00, ARRAY_SIZE(cmd));
-				printf("\n *************************************************");
+				printf("\n ***** offlinepolicy ******************************");
+				printf("\n  Current off line policy: %d", ShmSysConfigAndInfo->SysConfig.OfflinePolicy);
 				printf("\n  0: Local list.");
 				printf("\n  2: Free charging.");
 				printf("\n  3: Deny charging.");
-				printf("\n *************************************************");
-
-				printf("\n  Current mode: %d", ShmSysConfigAndInfo->SysConfig.OfflinePolicy);
+				printf("\n **************************************************");
 				printf("\n  Please input off line policy mode: ");
 				scanf("%s", &cmd[0]);
 
 				ShmSysConfigAndInfo->SysConfig.OfflinePolicy = ((0<=atoi(cmd))&&(atoi(cmd)<=3)&&(atoi(cmd)!=1)?atoi(cmd):0);
+
+				switch(ShmSysConfigAndInfo->SysConfig.OfflinePolicy)
+				{
+					case 0:
+						DEBUG_INFO("Off line policy: Local list.\n");
+						break;
+					case 2:
+						DEBUG_INFO("Off line policy: Free charging.\n");
+						break;
+					case 3:
+						DEBUG_INFO("Off line policy: Deny charging.\n");
+						break;
+				}
 			}
 			else if(strcmp(cmd, "localloadbalance") == 0)
 			{
 				memset(cmd, 0x00, ARRAY_SIZE(cmd));
-				printf("\n *************************************************");
+				printf("\n ***** localloadbalance ***************************");
+				printf("\n  Current local loading balance: %d", ShmSysConfigAndInfo->SysConfig.isEnableLocalPowerSharging);
 				printf("\n  0: Disable.");
 				printf("\n  1: Enable.");
-				printf("\n *************************************************");
-
-				printf("\n  Current mode: %d", ShmSysConfigAndInfo->SysConfig.isEnableLocalPowerSharging);
+				printf("\n **************************************************");
 				printf("\n  Please input local load balance mode: ");
 				scanf("%s", &cmd[0]);
 
 				ShmSysConfigAndInfo->SysConfig.isEnableLocalPowerSharging = ((0<=atoi(cmd))&&(atoi(cmd)<=1)?atoi(cmd):0);
+				if(ShmSysConfigAndInfo->SysConfig.RfidCardNumEndian)
+					DEBUG_INFO("Local loading balance: Enable\n");
+				else
+					DEBUG_INFO("Local loading balance: Disable\n");
 			}
-		}
+}
 		else if(strcmp(cmd, "network") == 0)
 		{
 			memset(cmd, 0x00, ARRAY_SIZE(cmd));
-			printf("\n *************************************************");
+			printf("\n ***** network *************************************");
 			printf("\n  ethdhcp: Ethernet DHCP client.");
 			printf("\n  wifimode: WiFi mode.");
 			printf("\n  wifidhcp: WiFi DHCP client.");
@@ -453,61 +502,79 @@ int main(void)
 			printf("\n  teleapn: Telecomm APN.");
 			printf("\n  teleid: Telecomm login id.");
 			printf("\n  telepwd: Telecomm login password.");
-			printf("\n *************************************************");
+			printf("\n **************************************************");
 			printf("\n  Please input operation item: ");
 			scanf("%s", &cmd[0]);
 
 			if(strcmp(cmd, "ethdhcp") == 0)
 			{
 				memset(cmd, 0x00, ARRAY_SIZE(cmd));
-				printf("\n *************************************************");
+				printf("\n ***** ethdhcp ************************************");
+				printf("\n  Current ethernet dhcp mode: %d", ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthDhcpClient^1);
 				printf("\n  0: Disable.");
 				printf("\n  1: Enable.");
-				printf("\n *************************************************");
-
-				printf("\n  Current ethernet dhcp mode: %d", ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthDhcpClient^1);
+				printf("\n **************************************************");
 				printf("\n  Please input dhcp mode: ");
 				scanf("%s", &cmd[0]);
 
 				ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthDhcpClient = ((0<=atoi(cmd))&&(atoi(cmd)<=1)?atoi(cmd)^1:0);
+				if(ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthDhcpClient)
+					DEBUG_INFO("Ethernet dhcp client: Disable\n");
+				else
+					DEBUG_INFO("Ethernet dhcp client: Enable\n");
+
 			}
 			else if(strcmp(cmd, "wifimode") == 0)
 			{
 				memset(cmd, 0x00, ARRAY_SIZE(cmd));
-				printf("\n *************************************************");
+				printf("\n ***** wifimode ***********************************");
+				printf("\n  Current WiFi mode: %d", ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode);
 				printf("\n  0: Disable.");
 				printf("\n  1: Station.");
 				printf("\n  2: Access point.");
-				printf("\n *************************************************");
-
-				printf("\n  Current WiFi mode: %d", ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode);
+				printf("\n **************************************************");
 				printf("\n  Please input WiFi mode: ");
 				scanf("%s", &cmd[0]);
 
 				ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode = ((0<=atoi(cmd))&&(atoi(cmd)<=2)?atoi(cmd):0);
+				switch(ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode)
+				{
+					case 0:
+						DEBUG_INFO("Wifi mode: Disable.\n");
+						break;
+					case 1:
+						DEBUG_INFO("Wifi mode: Station.\n");
+						break;
+					case 2:
+						DEBUG_INFO("Wifi mode: AP.\n");
+						break;
+				}
 			}
 			else if(strcmp(cmd, "wifidhcp") == 0)
 			{
 				memset(cmd, 0x00, ARRAY_SIZE(cmd));
-				printf("\n *************************************************");
+				printf("\n ***** wifidhcp ***********************************");
+				printf("\n  Current WiFi dhcp client mode: %d", ShmSysConfigAndInfo->SysConfig.AthInterface.WifiDhcpClient^1);
 				printf("\n  0: Disable.");
 				printf("\n  1: Enable.");
-				printf("\n *************************************************");
-
-				printf("\n  Current WiFi dhcp client mode: %d", ShmSysConfigAndInfo->SysConfig.AthInterface.WifiDhcpClient^1);
+				printf("\n **************************************************");
 				printf("\n  Please input WiFi mode: ");
 				scanf("%s", &cmd[0]);
 
 				ShmSysConfigAndInfo->SysConfig.AthInterface.WifiDhcpClient = ((0<=atoi(cmd))&&(atoi(cmd)<=1)?atoi(cmd)^1:0);
+				if(ShmSysConfigAndInfo->SysConfig.AthInterface.WifiDhcpClient)
+					DEBUG_INFO("Wifi dhcp client: Disable\n");
+				else
+					DEBUG_INFO("Wifi dhcp client: Enable\n");
 			}
 			else if(strcmp(cmd, "wificssid") == 0)
 			{
 				memset(cmd, 0x00, ARRAY_SIZE(cmd));
-				printf("\n *************************************************");
+				printf("\n ***** wificssid **********************************");
 				printf("\n  Current WiFi client SSID: %s", ShmSysConfigAndInfo->SysConfig.AthInterface.WifiSsid);
 				printf("\n  0: Keep current config.");
 				printf("\n  1: Input new WiFi client SSID.");
-				printf("\n *************************************************");
+				printf("\n **************************************************");
 				printf("\n  Please input operation item: ");
 				scanf("%s", &cmd[0]);
 
@@ -518,16 +585,17 @@ int main(void)
 
 					memset(&ShmSysConfigAndInfo->SysConfig.AthInterface.WifiSsid[0], 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.AthInterface.WifiSsid));
 					strcpy((char*)&ShmSysConfigAndInfo->SysConfig.AthInterface.WifiSsid[0], (char*)&cmd[0]);
+					DEBUG_INFO("Wifi client SSID: %s\n", ShmSysConfigAndInfo->SysConfig.AthInterface.WifiSsid);
 				}
 			}
 			else if(strcmp(cmd, "wificpasswd") == 0)
 			{
 				memset(cmd, 0x00, ARRAY_SIZE(cmd));
-				printf("\n *************************************************");
+				printf("\n ***** wificpasswd ********************************");
 				printf("\n  Current WiFi client password: %s", ShmSysConfigAndInfo->SysConfig.AthInterface.WifiPassword);
 				printf("\n  0: Keep current config.");
 				printf("\n  1: Input new WiFi client password.");
-				printf("\n *************************************************");
+				printf("\n **************************************************");
 				printf("\n  Please input operation item: ");
 				scanf("%s", &cmd[0]);
 
@@ -538,30 +606,35 @@ int main(void)
 
 					memset(&ShmSysConfigAndInfo->SysConfig.AthInterface.WifiPassword[0], 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.AthInterface.WifiPassword));
 					strcpy((char*)&ShmSysConfigAndInfo->SysConfig.AthInterface.WifiPassword[0], (char*)&cmd[0]);
+					DEBUG_INFO("Wifi client password: %s\n", ShmSysConfigAndInfo->SysConfig.AthInterface.WifiPassword);
 				}
 			}
 			else if(strcmp(cmd, "telemode") == 0)
 			{
 				memset(cmd, 0x00, ARRAY_SIZE(cmd));
-				printf("\n *************************************************");
+				printf("\n ***** telemode ***********************************");
 				printf("\n  0: Disable.");
 				printf("\n  1: Enable.");
-				printf("\n *************************************************");
+				printf("\n **************************************************");
 
 				printf("\n  Current telecomm mode: %d", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemMode^1);
 				printf("\n  Please input telecomm mode: ");
 				scanf("%s", &cmd[0]);
 
 				ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemMode = ((0<=atoi(cmd))&&(atoi(cmd)<=1)?atoi(cmd)^1:0);
+				if(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemMode)
+					DEBUG_INFO("Wifi dhcp client: Disable\n");
+				else
+					DEBUG_INFO("Wifi dhcp client: Enable\n");
 			}
 			else if(strcmp(cmd, "teleapn") == 0)
 			{
 				memset(cmd, 0x00, ARRAY_SIZE(cmd));
-				printf("\n *************************************************");
+				printf("\n ***** teleapn ************************************");
 				printf("\n  Current telecomm APN: %s", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomApn);
 				printf("\n  0: Keep current config.");
 				printf("\n  1: Input new telecomm APN.");
-				printf("\n *************************************************");
+				printf("\n **************************************************");
 				printf("\n  Please input operation item: ");
 				scanf("%s", &cmd[0]);
 
@@ -572,16 +645,17 @@ int main(void)
 
 					memset(&ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomApn[0], 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomApn));
 					strcpy((char*)&ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomApn[0], (char*)&cmd[0]);
+					DEBUG_INFO("Telecomm APN: %s\n", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomApn);
 				}
 			}
 			else if(strcmp(cmd, "teleid") == 0)
 			{
 				memset(cmd, 0x00, ARRAY_SIZE(cmd));
-				printf("\n *************************************************");
+				printf("\n ***** teleid *************************************");
 				printf("\n  Current telecomm login id: %s", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapId);
 				printf("\n  0: Keep current config.");
 				printf("\n  1: Input new telecomm login id.");
-				printf("\n *************************************************");
+				printf("\n **************************************************");
 				printf("\n  Please input operation item: ");
 				scanf("%s", &cmd[0]);
 
@@ -592,16 +666,17 @@ int main(void)
 
 					memset(&ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapId[0], 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapId));
 					strcpy((char*)&ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapId[0], (char*)&cmd[0]);
+					DEBUG_INFO("Telecomm CHAP id: %s\n", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapId);
 				}
 			}
 			else if(strcmp(cmd, "telepwd") == 0)
 			{
 				memset(cmd, 0x00, ARRAY_SIZE(cmd));
-				printf("\n *************************************************");
+				printf("\n ***** telepwd ************************************");
 				printf("\n  Current telecomm login password: %s", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapPwd);
 				printf("\n  0: Keep current config.");
 				printf("\n  1: Input new telecomm login password.");
-				printf("\n *************************************************");
+				printf("\n **************************************************");
 				printf("\n  Please input operation item: ");
 				scanf("%s", &cmd[0]);
 
@@ -612,17 +687,20 @@ int main(void)
 
 					memset(&ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapPwd[0], 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapPwd));
 					strcpy((char*)&ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapPwd[0], (char*)&cmd[0]);
+					DEBUG_INFO("Telecomm CHAP password: %s\n", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapPwd);
 				}
 			}
 		}
 		else if(strcmp(cmd, "test") == 0)
 		{
 			memset(cmd, 0x00, ARRAY_SIZE(cmd));
-			printf("\n ***** test menu ******************");
+			printf("\n ***** test menu **********************************");
 			printf("\n  start: EVSE start charging request.");
 			printf("\n  stop: EVSE stop charging request.");
+			printf("\n  auth: Authorize request.");
+			printf("\n  alarm: Simulate alarm status.");
 			printf("\n  cancel: return to main menu.");
-			printf("\n *************************************************");
+			printf("\n **************************************************");
 			printf("\n  Please input operation item: ");
 			scanf("%s", &cmd[0]);
 
@@ -635,6 +713,7 @@ int main(void)
 				if((0 < atoi(cmd)) && (atoi(cmd) < 3))
 				{
 					ShmSysConfigAndInfo->SysInfo.AcChargingData[atoi(cmd)-1].schedule.isTriggerStart = ON;
+					DEBUG_INFO("Test start gun-%d, start charging session.\n", atoi(cmd));
 				}
 				else
 				{
@@ -650,12 +729,44 @@ int main(void)
 				if((0 < atoi(cmd)) && (atoi(cmd) < 3))
 				{
 					ShmSysConfigAndInfo->SysInfo.AcChargingData[atoi(cmd)-1].schedule.isTriggerStop = ON;
+					DEBUG_INFO("Test start gun-%d, stop charging session.\n", atoi(cmd));
 				}
 				else
 				{
 					printf("\n  Invalid input gun_index.");
 				}
 			}
+			else if(strcmp(cmd, "auth") == 0)
+			{
+				memset(cmd, 0x00, ARRAY_SIZE(cmd));
+				printf("\n  Please input idtag: ");
+				scanf("%s", &cmd[0]);
+
+				sprintf((char*)ShmSysConfigAndInfo->SysConfig.UserId, "%s", cmd);
+				ShmOCPP16Data->SpMsg.bits.AuthorizeReq = ON;
+				DEBUG_INFO("Test authentication by %s.\n", ShmSysConfigAndInfo->SysConfig.UserId);
+			}
+			else if(strcmp(cmd, "alarm") == 0)
+			{
+				memset(cmd, 0x00, ARRAY_SIZE(cmd));
+				printf("\n  Please input gun index(1~2): ");
+				scanf("%s", &cmd[0]);
+
+				if((0 < atoi(cmd)) && (atoi(cmd) < 3))
+				{					
+					DEBUG_INFO("Alarm simulate gun-%d, OVP.\n", atoi(cmd));
+					while(1)
+					{
+						ShmCharger->gun_info[atoi(cmd)-1].systemAlarmCode.SystemAlarmCode |= ALARM_OVER_VOLTAGE;
+						ShmCharger->gun_info[atoi(cmd)-1].primaryMcuAlarm.InputAlarmCode |= ALARM_OVER_VOLTAGE;
+					}
+				}
+				else
+				{
+					printf("\n  Invalid input gun_index.");
+					sleep(1);
+				}				
+			}
 			else if(strcmp(cmd, "cancel") == 0)
 			{}
 		}
@@ -664,7 +775,7 @@ int main(void)
 			printf("\n  Firmware upgrade trigger.");
 
 			ShmSysConfigAndInfo->SysInfo.FirmwareUpdate = ON;
-
+			DEBUG_INFO("Trigger firmware upgrade.\n");
 			sleep(2);
 		}
 		else if(strcmp(cmd, "save") == 0)
@@ -674,13 +785,16 @@ int main(void)
 				printf("\n  Write configuration fail.\r\n");
 			}
 			else
+			{
 				printf("\n  Write configuration OK.\r\n");
-
+				DEBUG_INFO("Save configuration.\n");
+			}
 			sleep(2);
 		}
 		else if(strcmp(cmd, "exit") == 0)
 		{
 			printf("\n  exit program.\n\n");
+			DEBUG_INFO("Exit configuration tools.\n");
 			return FAIL;
 		}
 	}

+ 184 - 0
EVSE/Projects/DD360/Apps/CSU/CheckSystemTask.c

@@ -0,0 +1,184 @@
+/*
+ * CheckTask.c
+ *
+ *  Created on: 2021年9月22日
+ *      Author: 8513
+ */
+
+#include "CheckSystemTask.h"
+
+bool Taskconutstring(char *src, char *taskname)
+{
+    bool result = false;
+
+    if (src == NULL || strlen(src) == 0)
+        return result;
+
+    if (strstr(src, taskname) != NULL &&
+        strstr(src, "grep") == NULL &&
+        strstr(src, "[") == NULL)
+    {
+        result = true;
+    }
+
+    return result;
+}
+
+int GetProcessCount(char *procName)
+{
+	int result = 0;
+	FILE *fp;
+	char cmd[256];
+	char buf[256];
+
+	sprintf(cmd, "ps -ef |grep %s", procName);
+	fp = popen(cmd, "r");
+	if(fp != NULL)
+	{
+		while(fgets(buf, sizeof(buf), fp) != NULL)
+		{
+			if (Taskconutstring(buf, procName))
+				result++;
+		}
+	}
+
+	pclose(fp);
+
+	return result;
+}
+
+unsigned char CheckSystemTask(unsigned char systemPage)
+{
+	unsigned char result = 0;
+	unsigned char count_main 		= GetProcessCount("main");
+	unsigned char count_evComm 		= GetProcessCount("Module_EvComm");
+	unsigned char count_interComm	= GetProcessCount("Module_InternalComm");
+	unsigned char count_eventComm	= GetProcessCount("Module_EventLogging");
+	unsigned char count_primaryComm	= GetProcessCount("Module_PrimaryComm");
+	unsigned char count_lcmComm	    = GetProcessCount("Module_LcmControl");
+	unsigned char count_doComm	    = GetProcessCount("Module_DoComm");
+	unsigned char count_produceComm	= GetProcessCount("Module_ProduceUtils");
+//	unsigned char count_psuComm 	= GetProcessCount("Module_PsuComm");
+
+//	printf("*************************** \n");
+//	printf("count_main = %d \n", count_main);
+//	printf("count_eventLog = %d \n", count_eventLog);
+//	printf("count_primary = %d \n", count_primary);
+//	printf("count_evComm = %d \n", count_evComm);
+//	printf("count_lcmCtrl = %d \n", count_lcmCtrl);
+//	printf("count_interComm = %d \n", count_interComm);
+//	printf("count_psuComm = %d \n", count_psuComm);
+//	printf("*************************** \n");
+
+//	if (systemPage == 0x09 || systemPage == 0x0A)
+	{
+		if (count_main < _SYSTEM_TASK_COUNT_MAIN )
+		{
+			system("killall Module_EventLogging");
+			system("killall Module_PrimaryComm");
+			system("killall Module_EvComm");
+			system("killall Module_LcmControl");
+			system("killall Module_InternalComm");
+			system("killall Module_DoComm");
+//			system("killall Module_PsuComm");
+//			system("killall OcppBackend &");
+//			system("killall Module_4g &");
+//			system("killall Module_Wifi &");
+			system("killall Module_ProduceUtils &");
+			sleep(3);
+			system("/usr/bin/run_evse_restart.sh");
+		}
+		else
+		{
+			/*
+			if(system("pidof -s Module_EventLogging > /dev/null") != 0)
+				system("/root/Module_EventLogging &");
+
+			if(system("pidof -s Module_PrimaryComm > /dev/null") != 0)
+				system("/root/Module_PrimaryComm &");
+
+			if(system("pidof -s Module_LcmControl > /dev/null") != 0)
+				system("/root/Module_LcmControl &");
+
+            if(system("pidof -s Module_DoComm > /dev/null") != 0)
+                system("/root/Module_DoComm &");
+
+            if(system("pidof -s Module_ProduceUtils > /dev/null") != 0)
+                system("/root/Module_ProduceUtils &");
+
+			*/
+			if (count_evComm < _SYSTEM_TASK_COUNT_EVCOMM )
+			{
+				system("killall Module_EvComm");
+				sleep(3);
+				system("/root/Module_EvComm &");
+			}
+        	if (count_interComm < _SYSTEM_TASK_COUNT_INTERNALCOMM )
+			{
+				system("killall Module_InternalComm");
+				sleep(3);
+				system("/root/Module_InternalComm &");
+			}
+			if (count_eventComm < _SYSTEM_TASK_COUNT_EVENTLOGGING )
+			{
+				system("killall Module_EventLogging");
+				sleep(3);
+				system("/root/Module_EventLogging &");
+			}
+			if (count_primaryComm < _SYSTEM_TASK_COUNT_PRIMARYCOMM )
+			{
+				system("killall Module_PrimaryComm");
+				sleep(3);
+				system("/root/Module_PrimaryComm &");
+			}
+			if (count_lcmComm < _SYSTEM_TASK_COUNT_LCM )
+			{
+				system("killall Module_LcmControl");
+				sleep(3);
+				system("/root/Module_LcmControl &");
+			}
+			if (count_doComm < _SYSTEM_TASK_COUNT_DOCOMM )
+			{
+				system("killall Module_DoComm");
+				sleep(3);
+				system("/root/Module_DoComm &");
+			}
+			if (count_produceComm < _SYSTEM_TASK_COUNT_PRODUCEUTILS )
+			{
+				system("killall Module_ProduceUtils");
+				sleep(3);
+				system("/root/Module_ProduceUtils &");
+			}
+			/*
+			if (count_psuComm < 2)
+			{
+				system("killall Module_PsuComm");
+				sleep(3);
+				system("/root/Module_PsuComm &");
+			}*/
+		}
+
+		sleep(2);
+	}
+
+	if (count_main < _SYSTEM_TASK_COUNT_MAIN)
+		result = _SYSTEM_TASK_LOST_ITEM_MAIN;
+	else if (count_evComm < _SYSTEM_TASK_COUNT_EVCOMM)
+		result = _SYSTEM_TASK_LOST_ITEM_EVCOMM;
+/*	else if (count_psuComm < 2)
+		result = 3; */
+    else if (count_eventComm < _SYSTEM_TASK_COUNT_EVENTLOGGING )
+        result = _SYSTEM_TASK_LOST_ITEM_EVENTLOG;
+    else if (count_primaryComm < _SYSTEM_TASK_COUNT_PRIMARYCOMM)
+        result = _SYSTEM_TASK_LOST_ITEM_PRIMARYCOMM;
+    else if (count_lcmComm < _SYSTEM_TASK_COUNT_LCM)
+        result = _SYSTEM_TASK_LOST_ITEM_LCMCONTROL;
+    else if (count_interComm < 2 )
+        result = _SYSTEM_TASK_LOST_ITEM_INTERCOMM;
+    else if (count_doComm < _SYSTEM_TASK_COUNT_DOCOMM)
+        result = _SYSTEM_TASK_LOST_ITEM_DOCOMM;
+    else if (count_produceComm < _SYSTEM_TASK_COUNT_PRODUCEUTILS)
+        result = _SYSTEM_TASK_LOST_ITEM_PRODUCTUTILS;
+
+	return result;
+}

+ 60 - 0
EVSE/Projects/DD360/Apps/CSU/CheckSystemTask.h

@@ -0,0 +1,60 @@
+/*
+ * CheckTask.h
+ *
+ *  Created on: 2021年9月2日
+ *      Author: 7564
+ */
+
+#ifndef CHECKTASK_H_
+#define CHECKTASK_H_
+
+#include 	<sys/timeb.h>
+#include 	<sys/types.h>
+#include 	<sys/ioctl.h>
+#include 	<sys/socket.h>
+#include 	<sys/ipc.h>
+#include 	<sys/shm.h>
+#include 	<sys/mman.h>
+#include 	<linux/wireless.h>
+#include 	<arpa/inet.h>
+#include 	<netinet/in.h>
+
+#include 	<unistd.h>
+#include 	<stdarg.h>
+#include    <stdio.h>      /*標準輸入輸出定義*/
+#include    <stdlib.h>     /*標準函數庫定義*/
+#include    <unistd.h>     /*Unix 標準函數定義*/
+#include    <fcntl.h>      /*檔控制定義*/
+#include    <termios.h>    /*PPSIX 終端控制定義*/
+#include    <errno.h>      /*錯誤號定義*/
+#include 	<string.h>
+#include 	<stdint.h>
+#include	<time.h>
+#include	<ctype.h>
+#include 	<ifaddrs.h>
+#include 	<math.h>
+#include 	<stdbool.h>
+#include 	<dirent.h>
+
+#define _SYSTEM_TASK_LOST_ITEM_MAIN         1
+#define _SYSTEM_TASK_LOST_ITEM_EVCOMM       2
+#define _SYSTEM_TASK_LOST_ITEM_EVENTLOG     3
+#define _SYSTEM_TASK_LOST_ITEM_PRIMARYCOMM  4
+#define _SYSTEM_TASK_LOST_ITEM_LCMCONTROL   5
+#define _SYSTEM_TASK_LOST_ITEM_INTERCOMM    6
+#define _SYSTEM_TASK_LOST_ITEM_DOCOMM       7
+#define _SYSTEM_TASK_LOST_ITEM_PRODUCTUTILS 8
+
+#define _SYSTEM_TASK_COUNT_MAIN             5
+#define _SYSTEM_TASK_COUNT_EVCOMM           2
+#define _SYSTEM_TASK_COUNT_INTERNALCOMM     2
+#define _SYSTEM_TASK_COUNT_EVENTLOGGING     1
+#define _SYSTEM_TASK_COUNT_PRIMARYCOMM      1
+#define _SYSTEM_TASK_COUNT_LCM              1
+#define _SYSTEM_TASK_COUNT_DOCOMM           1
+#define _SYSTEM_TASK_COUNT_PRODUCEUTILS     1
+
+
+unsigned char CheckSystemTask(unsigned char systemPage);
+
+#endif /* CHECKSYSTEMTASK_H_ */

+ 12 - 0
EVSE/Projects/DD360/Apps/CSU/Primary.c

@@ -136,11 +136,15 @@ void PrimaryLedIndicatorCtrlFork(void)
 
                 case S_CHARGING:
                     pLedConfig->RedLED = NO;
+#ifdef DD360ComBox
                     if (pLedConfig->YellowLED == YES) {
                         pLedConfig->YellowLED = NO;
                     } else {
                         pLedConfig->YellowLED = YES;
                     }
+#else
+                        pLedConfig->YellowLED = YES;
+#endif
                     pLedConfig->GreenLED = NO;
                     break;
 
@@ -166,7 +170,15 @@ void PrimaryLedIndicatorCtrlFork(void)
                     //    pLedConfig->RedLED = YES;
                     //} else {
                     pLedConfig->RedLED = NO;
+#ifdef DD360ComBox
                     pLedConfig->YellowLED = YES;
+#else
+                    if (pLedConfig->YellowLED == YES) {
+                        pLedConfig->YellowLED = NO;
+                    } else {
+                        pLedConfig->YellowLED = YES;
+                    }
+#endif
                     pLedConfig->GreenLED = NO;
                     //}
                     break;

+ 15 - 0
EVSE/Projects/DD360/Apps/CSU/SelfTest.c

@@ -18,6 +18,7 @@ extern void ChkPrimaryStatus(void);
 void SelfTestRun(void)
 {
     bool evInitFlag = false;
+    bool isRelayBypass = false;
     uint8_t index = 0;
     struct SysConfigData *pSysConfig = (struct SysConfigData *)GetShmSysConfigData();
     struct SysInfoData *pSysInfo = (struct SysInfoData *)GetShmSysInfoData();
@@ -34,6 +35,15 @@ void SelfTestRun(void)
     struct ChargingInfoData *pDcChargingInfo = NULL;
     struct ChargingInfoData *pAcChargingInfo = NULL;
 
+    for(int i = 0; i < pSysConfig->TotalConnectorCount; i++)
+    {
+        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
+        if(pDcChargingInfo->PantographFlag == YES)
+        {
+            isRelayBypass = true;
+        }
+    }
+
     StartSystemTimeoutDet(Timeout_SelftestChk);
     pSysInfo->SelfTestSeq = _STEST_VERSION;
 
@@ -62,6 +72,11 @@ void SelfTestRun(void)
 
         switch (pSysInfo->SelfTestSeq) {
         case _STEST_VERSION:
+            if(isRelayBypass == YES && ShmRelayModuleData->SelfTest_Comp != YES)
+            {
+                log_info("Relay Board Bypass");
+                ShmRelayModuleData->SelfTest_Comp = YES;
+            }
             if ((strlen((char *)pSysInfo->RelayModuleFwRev) != 0 ||
                     pSysInfo->RelayModuleFwRev[0] != '\0') &&
                     (ShmRelayModuleData->SelfTest_Comp != YES)

+ 8 - 0
EVSE/Projects/DD360/Apps/CSU/UpgradeFW.c

@@ -12,6 +12,11 @@
 #include "../ShareMemory/shmMem.h"
 
 #include "main.h"
+//WatchDog.c
+extern void CreateWatchdog(void);
+extern void TryCloseWatchdog(void);
+extern void TryFeedWatchdog(void);
+
 
 //------------------------------------------------------------------------------
 static char *_priPortName = "/dev/ttyS1";
@@ -325,6 +330,8 @@ void CheckFwUpdateFunction(void)
     //log_info("pSysInfo->FirmwareUpdate = %d \n", pSysInfo->FirmwareUpdate);
     if (pSysInfo->FirmwareUpdate == YES) {
         log_info("ftp : update start. \n");
+        TryCloseWatchdog();
+
         for (uint8_t gun_index = 0; gun_index < pSysConfig->TotalConnectorCount; gun_index++) {
             setChargerMode(gun_index, MODE_UPDATE);
         }
@@ -352,6 +359,7 @@ void CheckFwUpdateFunction(void)
 
         if (strcmp((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, "Downloaded") == EQUAL) {
             log_info("Backend : update start. \n");
+            TryCloseWatchdog();
             strcpy((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, "");
             strcpy((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, "Installing");
             ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = YES;

+ 39 - 17
EVSE/Projects/DD360/Apps/CSU/WatchDog.c

@@ -8,41 +8,63 @@
 #include "../Define/define.h"
 #include "../ShareMemory/shmMem.h"
 
-//------------------------------------------------------------------------------
-static int gWatchDogfd = -1;
+int wtdFd = -1;
+struct StatusCodeData           *ShmStatusCodeData;
 
-//------------------------------------------------------------------------------
-void WriteWatchDogState(char *value)
-{
-    write(gWatchDogfd, value, 1);
-}
+void CreateWatchdog(void);
+void TryCloseWatchdog(void);
+void TryFeedWatchdog(void);
 
-static int initWatchDog(void)
+int InitWatchDog()
 {
     int fd;
+    int timeout = 180;
+
     system("/usr/bin/fuser -k /dev/watchdog");
     sleep(1);
     system("echo V > /dev/watchdog");
     sleep(1);
-    fd = open("/dev/watchdog", O_RDWR);
+    fd=open("/dev/watchdog", O_RDWR);
 
-    if (fd <= 0) {
+    if(fd<=0)
+    {
         log_error("System watch dog initial fail.\r\n");
     }
+    ioctl(fd, _IOWR('W', 6, int), &timeout);
 
     return fd;
 }
 
 void CreateWatchdog(void)
 {
-    struct SysConfigData *pSysConfig = (struct SysConfigData *)GetShmSysConfigData();
-    struct AlarmCodeData *pAlarmCode = (struct AlarmCodeData *)GetShmAlarmCodeData();
+    wtdFd = InitWatchDog();
+
+    ShmStatusCodeData = (struct StatusCodeData*)GetShmStatusCodeData();
+    if(wtdFd < 0)
+    {
+        log_info("Watchdog Initial Fail");
+        ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1;
+    }
+    else
+    {
+        log_info("Watchdog Initial Success");
+    }
+}
 
-    if (pSysConfig->SwitchDebugFlag == NO) {
-        gWatchDogfd = initWatchDog();
+void TryCloseWatchdog(void)
+{
+    if(wtdFd > 0)
+    {
+        write(wtdFd, "V", 1);
+        close(wtdFd);
+    }
+}
 
-        if (gWatchDogfd < 0) {
-            pAlarmCode->AlarmEvents.bits.CsuInitFailed = 1;
-        }
+void TryFeedWatchdog(void)
+{
+    if(wtdFd > 0)
+    {
+        write(wtdFd, "a", 1);
     }
 }
+

+ 48 - 0
EVSE/Projects/DD360/Apps/CSU/WatchDog.c.old

@@ -0,0 +1,48 @@
+#include <stdio.h>      /*標準輸入輸出定義*/
+#include <stdlib.h>     /*標準函數庫定義*/
+#include <string.h>
+#include <stdint.h>
+
+#include "../Config.h"
+#include "../Log/log.h"
+#include "../Define/define.h"
+#include "../ShareMemory/shmMem.h"
+
+//------------------------------------------------------------------------------
+static int gWatchDogfd = -1;
+
+//------------------------------------------------------------------------------
+void WriteWatchDogState(char *value)
+{
+    write(gWatchDogfd, value, 1);
+}
+
+static int initWatchDog(void)
+{
+    int fd;
+    system("/usr/bin/fuser -k /dev/watchdog");
+    sleep(1);
+    system("echo V > /dev/watchdog");
+    sleep(1);
+    fd = open("/dev/watchdog", O_RDWR);
+
+    if (fd <= 0) {
+        log_error("System watch dog initial fail.\r\n");
+    }
+
+    return fd;
+}
+
+void CreateWatchdog(void)
+{
+    struct SysConfigData *pSysConfig = (struct SysConfigData *)GetShmSysConfigData();
+    struct AlarmCodeData *pAlarmCode = (struct AlarmCodeData *)GetShmAlarmCodeData();
+
+    if (pSysConfig->SwitchDebugFlag == NO) {
+        gWatchDogfd = initWatchDog();
+
+        if (gWatchDogfd < 0) {
+            pAlarmCode->AlarmEvents.bits.CsuInitFailed = 1;
+        }
+    }
+}

+ 145 - 20
EVSE/Projects/DD360/Apps/CSU/main.c

@@ -29,6 +29,7 @@
 #include <math.h>
 #include <stdbool.h>
 #include <dirent.h>
+#include <signal.h>
 
 #include "../Config.h"
 #include "main.h"
@@ -40,6 +41,7 @@
 #include "../Define/define.h"
 #include "../ShareMemory/shmMem.h"
 #include "../SelectGun/SelectGun.h"
+#include "CheckSystemTask.h"
 
 //------------------------------------------------------------------------------
 static struct SysInfoData *pSysInfo = NULL;
@@ -71,13 +73,16 @@ static SelectGunInfo *ShmSelectGunInfo = NULL; //Jerry add
 static EvBoardErrMsg gEvBoardErr = {0};
 static ChillerTempErr gChillerTempErr = {0};
 
+struct SysConfigAndInfo         *ShmSysConfigAndInfo;
+struct StatusCodeData           *ShmStatusCodeData;
+
 // for initial index to check EV board type is correct
 uint8_t bd0_1_status = 0;
 uint8_t bd0_2_status = 0;
 uint8_t bd1_1_status = 0;
 uint8_t bd1_2_status = 0;
 
-char *fwVersion = "V1.13.00.0000.00"; // "V0.16.00.0000.00";
+char *fwVersion = "V1.15.00.0000.00"; // "V0.16.00.0000.00";
 
 //sqlite3 *localDb;
 bool isDb_ready;
@@ -89,6 +94,8 @@ long long DiffTimebWithNow(struct timeb ST);
 uint8_t DetectBitValue(uint8_t _byte, uint8_t _bit);
 void SetBitValue(uint8_t *_byte, uint8_t _bit, uint8_t value);
 unsigned long GetTimeoutValue(struct timeval _sour_time);
+void GetClockTime(struct timespec *_now_time, void *null);
+unsigned long GetClockTimeoutValue(struct timespec _start_time);
 void gpio_set_value(unsigned int gpio, unsigned int value);
 void InformOcppErrOccur(uint8_t codeType);
 
@@ -121,7 +128,8 @@ extern void GetMacAddress(void);
 
 //WatchDog.c
 extern void CreateWatchdog(void);
-extern void WriteWatchDogState(char *value);
+extern void TryCloseWatchdog(void);
+extern void TryFeedWatchdog(void);
 
 //ZipFile.c
 extern void zipLogFiles(void);
@@ -753,6 +761,24 @@ unsigned long GetTimeoutValue(struct timeval _sour_time)
     return 1000000 * (_end_time.tv_sec - _sour_time.tv_sec) + _end_time.tv_usec - _sour_time.tv_usec;
 }
 
+void GetClockTime(struct timespec *_now_time, void *null)
+{
+    clock_gettime(CLOCK_MONOTONIC, _now_time);
+}
+
+// return value unit: 1us
+unsigned long GetClockTimeoutValue(struct timespec _start_time)
+{
+    struct timespec ts_end;
+    unsigned long ret = 0;
+
+    clock_gettime(CLOCK_MONOTONIC, &ts_end);
+
+    ret = ((unsigned long)(ts_end.tv_sec - _start_time.tv_sec) * 1000000) + ((unsigned long)((ts_end.tv_nsec / 1000) - (_start_time.tv_nsec/ 1000)));
+
+    return ret;
+}
+
 int DiffTimeb(struct timeb ST, struct timeb ET)
 {
     //return milli-second
@@ -1611,7 +1637,11 @@ void _DetectPlugInTimeout(void)
     ClearDetectPluginFlag();
 
     sleep(1); //等待DoComm回報插槍訊號給主櫃
-
+#if defined DD360Audi || DD360 || DD360Combox
+	    //pSysInfo->SystemPage = _LCM_COMPLETE;
+		setChargerMode(pSysInfo->CurGunSelected, S_TERMINATING);
+	    return;
+#endif
     systemPageRestoreInit();
 }
 
@@ -1641,7 +1671,12 @@ void _DetectEvseChargingEnableTimeout(uint8_t gunIndex)
     log_info("*********** _DetectEvseChargingEnableTimeout (GFD timeout) ***********\n");
     //if (chargingInfo[gunIndex]->GroundFaultStatus != GFD_PASS)
     {
+#if defined DD360Audi || DD360 || DD360Combox
+        pSysInfo->SystemPage = _LCM_COMPLETE;
+        setChargerMode(gunIndex, S_TERMINATING);
+#else
         setChargerMode(gunIndex, MODE_IDLE);
+#endif
         _AutoReturnTimeout();
     }
 }
@@ -1649,7 +1684,12 @@ void _DetectEvseChargingEnableTimeout(uint8_t gunIndex)
 void _PrepareTimeout(uint8_t gunIndex)
 {
     log_info("*********** _PrepareTimeout ***********\n");
-    setChargerMode(gunIndex, MODE_IDLE);
+#if defined DD360Audi || DD360 || DD360Combox
+        pSysInfo->SystemPage = _LCM_COMPLETE;
+        setChargerMode(gunIndex, S_TERMINATING);
+#else
+     setChargerMode(gunIndex, MODE_IDLE);
+#endif
     pAlarmCode->AlarmEvents.bits.PsuNoResource = YES;
     _AutoReturnTimeout();
 }
@@ -1657,9 +1697,76 @@ void _PrepareTimeout(uint8_t gunIndex)
 void _CcsPrechargeTimeout(uint8_t gunIndex)
 {
     log_info("*********** _CcsPrechargeTimeout ***********\n");
-    setChargerMode(gunIndex, MODE_IDLE);
+#if defined DD360Audi || DD360 || DD360Combox
+        pSysInfo->SystemPage = _LCM_COMPLETE;
+        setChargerMode(gunIndex, S_TERMINATING);
+#else
+     setChargerMode(gunIndex, MODE_IDLE);
+#endif
 }
 
+//===============================================
+// Check System Task alive
+// ==============================================
+void CheckSystemTaskAlive()
+{
+    unsigned char lostId = CheckSystemTask(ShmSysConfigAndInfo->SysInfo.SystemPage);
+    if (lostId != 0) {
+        log_info("Check task(%d) lost\n",lostId);
+        if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemTaskLost == NO) {
+           if (lostId == _SYSTEM_TASK_LOST_ITEM_MAIN)
+               log_info("System task lost (CSU). \n");
+           else if (lostId == _SYSTEM_TASK_LOST_ITEM_EVCOMM)
+               log_info("System task lost (EVComm). \n");
+//           else if (lostId == _SYSTEM_TASK_LOST_ITEM_PSUCOMM)
+//               PRINTF_FUNC("System task lost (PSU Task). \n");
+           else if (lostId == _SYSTEM_TASK_LOST_ITEM_EVENTLOG)
+               log_info("System task lost (Event log). \n");
+           else if (lostId == _SYSTEM_TASK_LOST_ITEM_PRIMARYCOMM)
+               log_info("System task lost (Primary). \n");
+           else if (lostId == _SYSTEM_TASK_LOST_ITEM_LCMCONTROL)
+               log_info("System task lost (LCM Comm). \n");
+           else if (lostId == _SYSTEM_TASK_LOST_ITEM_INTERCOMM)
+               log_info("System task lost (Internal Comm). \n");
+           else if (lostId == _SYSTEM_TASK_LOST_ITEM_DOCOMM)
+               log_info("System task lost (Do Comm). \n");
+           else if (lostId == _SYSTEM_TASK_LOST_ITEM_PRODUCTUTILS)
+               log_info("System task lost (ProcductUtils Comm). \n");
+           ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemTaskLost = YES;
+        }
+    } else
+        ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemTaskLost = NO;
+}
+
+void CreateCheckSystemTaskFork()
+{
+    pid_t taskPid;
+    taskPid = fork();
+    if (taskPid == 0)
+    {
+        while(true)
+        {
+			/*
+			for (int _index = 0; _index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _index++)
+			{
+				if (chargingInfo[_index]->SystemStatus == SYS_MODE_UPDATE ||
+						chargingInfo[_index]->Type == 0x09)
+				{
+					stopToDet = true;
+					continue;
+				}
+			}
+			*/
+			for (uint8_t gun = 0; gun < pSysConfig->TotalConnectorCount; gun++) {
+				pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gun);
+				if (pDcChargingInfo->SystemStatus == SYS_MODE_UPDATE )
+						continue;
+			}
+			CheckSystemTaskAlive();
+			sleep(5);
+		}
+	}
+}
 //===============================================
 // 取得卡號與卡號驗證
 //===============================================
@@ -2510,6 +2617,7 @@ bool CheckConnectorTypeStatus(void)
             return false;
         }
 
+		pDcChargingInfo->SystemStatus = S_BOOTING;
         switch (gunIndex) {
         case 0:
             if (pSysConfig->TotalConnectorCount == 1) {
@@ -2645,14 +2753,14 @@ void KillAllTask(void)
 void StartSystemTimeoutDet(uint8_t flag)
 {
     if (pSysInfo->SystemTimeoutFlag != flag) {
-        gettimeofday(&pSysInfo->SystemTimeoutTimer, NULL);
+        GetClockTime(&pSysInfo->SystemTimeoutTimer, NULL);
     }
     pSysInfo->SystemTimeoutFlag = flag;
 }
 
 void StopSystemTimeoutDet(void)
 {
-    gettimeofday(&pSysInfo->SystemTimeoutTimer, NULL);
+    GetClockTime(&pSysInfo->SystemTimeoutTimer, NULL);
     pSysInfo->SystemTimeoutFlag = Timeout_None;
 }
 
@@ -2724,7 +2832,7 @@ void CreateTimeoutFork(void)
             // 系統
             switch (pSysInfo->SystemTimeoutFlag) {
             case Timeout_SelftestChk:
-                if (GetTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= SELFTEST_TIMEOUT) {
+                if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= SELFTEST_TIMEOUT) {
                     _SelfTestTimeout();
                     StopSystemTimeoutDet();
                     destroySelGun(DESTROY_ALL_SEL); //jerry add
@@ -2732,7 +2840,7 @@ void CreateTimeoutFork(void)
                 break;
 
             case Timeout_Authorizing:
-                if (GetTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= AUTHORIZE_TIMEOUT) {
+                if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= AUTHORIZE_TIMEOUT) {
                     _AuthorizedTimeout();
                     StopSystemTimeoutDet();
                     destroySelGun(pSysInfo->CurGunSelected);
@@ -2748,7 +2856,7 @@ void CreateTimeoutFork(void)
                 break;
 
             case Timeout_VerifyFail:
-                if (GetTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= AUTHORIZE_FAIL_TIMEOUT) {
+                if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= AUTHORIZE_FAIL_TIMEOUT) {
                     _AutoReturnTimeout();
                     StopSystemTimeoutDet();
                     destroySelGun(pSysInfo->CurGunSelected);
@@ -2764,14 +2872,14 @@ void CreateTimeoutFork(void)
                 break;
 
             case Timeout_VerifyComp:
-                if (GetTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= AUTHORIZE_COMP_TIMEOUT) {
+                if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= AUTHORIZE_COMP_TIMEOUT) {
                     _AutoReturnTimeout();
                     StopSystemTimeoutDet();
                 }
                 break;
 
             case Timeout_WaitPlug:
-                if (GetTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= _connectionTimeout) {
+                if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= _connectionTimeout) {
                     _DetectPlugInTimeout();
                     StopSystemTimeoutDet();
                     destroySelGun(pSysInfo->CurGunSelected);
@@ -2779,7 +2887,7 @@ void CreateTimeoutFork(void)
                 break;
 
             case Timeout_ReturnToChargingGunDet:
-                if (GetTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= RETURN_TO_CHARGING_PAGE) {
+                if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= RETURN_TO_CHARGING_PAGE) {
 #if defined DD360Audi
                     if (getCurLcmPage() != _LCM_PRE_CHARGE &&
                             getCurLcmPage() != _LCM_CHARGING &&
@@ -2794,7 +2902,7 @@ void CreateTimeoutFork(void)
                 break;
 
             case Timeout_AuthorizingForStop:
-                if (GetTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= AUTHORIZE_STOP_TIMEOUT) {
+                if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= AUTHORIZE_STOP_TIMEOUT) {
                     strcpy((char *)pSysConfig->UserId, "");
                     ClearAuthorizedFlag();
                     StopSystemTimeoutDet();
@@ -2950,6 +3058,7 @@ void CheckOcppStatus(void)
                 sleep(3);
                 system("killall OcppBackend &");
                 KillAllTask();
+                TryCloseWatchdog();
                 system("/usr/bin/run_evse_restart.sh");
             }
         }
@@ -3329,6 +3438,7 @@ void StopProcessingLoop()
                 log_info("Soft reboot for retry self-tets (Primary). \n");
                 KillAllTask();
                 sleep(3);
+                TryCloseWatchdog();
                 system("/usr/bin/run_evse_restart.sh");
                 return;
             }
@@ -3400,10 +3510,11 @@ void CheckTask()
 #endif //0
 
     /*--- 20200908, vern, disable it for DD360 ---*/
+    /*
     if (system("pidof -s Module_ProduceUtils > /dev/null") != 0) {
         log_error("Module_ProduceUtils not running, restart it.\r\n");
         system ("/root/Module_ProduceUtils &");
-    }
+    }*/
 }
 
 //==========================================
@@ -4139,6 +4250,9 @@ int main(void)
     ShmOCPP16Data = (struct OCPP16Data *)GetShmOCPP16Data();
     ShmDcCommonData = (DcCommonInfo *)GetShmDcCommonData();
     ShmSelectGunInfo = (SelectGunInfo *)GetShmSelectGunInfo();
+	
+    ShmSysConfigAndInfo = (struct SysConfigAndInfo *)GetShmSysConfigAndInfo();
+    ShmStatusCodeData = (struct StatusCodeData *)GetShmStatusCodeData();	
 
     log_info(" ****************  FileSystem Boot up ***************\n");
     if (!InitialSystemDefaultConfig()) {
@@ -4236,8 +4350,6 @@ int main(void)
     // 1. Thernal - 控制風扇轉速
     // 2. ouput fuse - 控制風扇轉速
     CreateRfidFork();
-    // Create Watchdog
-    //CreateWatchdog();
     // Main loop
 
     log_info("===== Charger info ===== ");
@@ -4249,6 +4361,12 @@ int main(void)
 
     GunIndexInfo *pGunIndexInfo = (GunIndexInfo *)GetGunIndexInfo();
 
+    //signal(SIGCHLD,SIG_IGN);
+
+	CreateCheckSystemTaskFork();
+
+    CreateWatchdog();
+
     for (;;) {
         CheckOcppStatus();
 
@@ -4283,7 +4401,7 @@ int main(void)
         }
 
         if ((GetTimeoutValue(_cmdMainPriority_time) / 1000) > 5000) {
-            CheckTask();
+            //CheckTask();
 
             for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) {
                 pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
@@ -4545,6 +4663,9 @@ int main(void)
                 if (pSysInfo->CurGunSelected == gunIndex) {
                     pSysInfo->ConnectorPage = _LCM_PRE_CHARGE;
                 }
+#ifdef DD360Audi
+				pDcChargingInfo->Replug_flag = true;
+#endif
             }
             break;
 
@@ -4822,6 +4943,9 @@ int main(void)
                 if (pSysInfo->CurGunSelected == gunIndex) {
                     pSysInfo->ConnectorPage = _LCM_CHARGING;
                 }
+#ifdef DD360Audi
+				pDcChargingInfo->Replug_flag = false;
+#endif
                 break;
 
             case S_ALARM:
@@ -4996,7 +5120,7 @@ int main(void)
                 // 切換 D+ Relay to Precharge Relay
                 if (isPrechargeStatus_ccs(gunIndex) == 39 ||
                         isPrechargeStatus_ccs(gunIndex) == 40) {
-                    if (pDcChargingInfo->RelayKPK2Status == YES &&
+                    if ((pDcChargingInfo->RelayKPK2Status == YES || pDcChargingInfo->PantographFlag == YES) &&
                             pDcChargingInfo->PrechargeStatus != PRECHARGE_READY)
                         //if (pDcChargingInfo->PrechargeStatus != PRECHARGE_PRERELAY_PASS)
                     {
@@ -5041,7 +5165,7 @@ int main(void)
 
                 // 等待小板通知進入充電
                 // 切換 D+ Relay to Precharge Relay
-                if (pDcChargingInfo->RelayK1K2Status == YES) {
+                if (pDcChargingInfo->RelayK1K2Status == YES || pDcChargingInfo->PantographFlag == YES) {
                     pDcChargingInfo->PrechargeStatus = PRECHARGE_READY;
                     setChargerMode(gunIndex, MODE_CHARGING);
                 }
@@ -5051,6 +5175,7 @@ int main(void)
                 }
                 break;
             }//switch
+            TryFeedWatchdog();
         }//for
 
 #if defined DD360Audi

+ 106 - 82
EVSE/Projects/DD360/Apps/Define/define.h

@@ -176,6 +176,11 @@ Storage							0x0A200000-0x7FFFFFFF		1886 MB
 /**************************************************************************************/
 /****************** Share memory configuration value constant define ******************/
 /**************************************************************************************/
+struct NoneUse
+{
+    unsigned char       unknown;                    // None use struct
+};
+
 enum SYSTEM_STATUS
 {
 	SYS_MODE_BOOTING		= 0,
@@ -287,7 +292,7 @@ enum CoreProfile {
 	 TransactionMessageRetryInterval,
 	 UnlockConnectorOnEVSideDisconnect,
 	 WebSocketPingInterval,
-	 QueueOffLineStartTransactionMessage,
+	 QueueOffLineMeterValues,
 	 AuthorizationKey,
 	 SecurityProfile,
      DefaultPrice,
@@ -304,15 +309,21 @@ enum OCPP_RUNNING_VERSION {
     OCPP_RUNNING_VERSION_16=0,
     OCPP_RUNNING_VERSION_20
 };
+
+enum OCPP_START_ID_TYPE {
+    IdTokenType_Central=0,
+    IdTokenType_eMAID,
+    IdTokenType_ISO14443,
+    IdTokenType_KeyCode,
+    IdTokenType_Local,
+    IdTokenType_NoAuthorization,
+    IdTokenType_ISO15693
+};
 /**************************************************************************************/
 /****structure SysConfigData => shall store the data to NAND flash****************/
 /****structure SysInfoData => shall NOT store the data to NAND flash***************/
 /****according to System Configuration and Information Table.xlsx Rev.0.2 *******/
 /**************************************************************************************/
-struct NoneUse
-{
-	unsigned char		unknown;					// None use struct
-};
 
 struct EthConfigData
 {
@@ -454,9 +465,9 @@ typedef struct
     unsigned int isCalibratedCaOffset:1;                // Current phase a offset is calibrated, 0: default 1: Calibrated
     unsigned int isCalibratedCbOffset:1;                // Current phase b offset is calibrated, 0: default 1: Calibrated
     unsigned int isCalibratedCcOffset:1;                // Current phase c offset is calibrated, 0: default 1: Calibrated
-    unsigned int isCalibratedPa:1;                      // Phase angle a is calibrated, 0: default  1: Calibrated
-    unsigned int isCalibratedPb:1;                      // Phase angle b gain is calibrated, 0: default 1: Calibrated
-    unsigned int isCalibratedPc:1;                      // Phase angle c gain is calibrated, 0: default 1: Calibrated
+    unsigned int isCalibratedPa:1;                      // Phase angle a is calibrated, 0: default          1: Calibrated
+    unsigned int isCalibratedPb:1;                      // Phase angle b gain is calibrated, 0: default     1: Calibrated
+    unsigned int isCalibratedPc:1;                      // Phase angle c gain is calibrated, 0: default     1: Calibrated
     unsigned int :1;
 }MeterIcCalibration;
 
@@ -515,8 +526,8 @@ struct SysConfigData
 	unsigned char 			OcppServerURL[512];			//http: non-secure OCPP 1.5-S, https: secure OCPP 1.5-S, ws: non-secure OCPP 1.6-J, wss: secure OCPP 1.6-J"
 	unsigned char 			ChargeBoxId[128];
 	unsigned char			chargePointVendor[20];		//the Vendor of the ChargePoint
-	unsigned char			OcppSecurityProfile;		//OCPP security profile 0~3
-	unsigned char			OcppSecurityPassword[41];	//OCPP AuthorizationKey for security profile
+    unsigned char           OcppSecurityProfile;        //OCPP security profile 0~3
+    unsigned char           OcppSecurityPassword[41];   //OCPP AuthorizationKey for security profile
 	unsigned int 			Checksum;					//4 bytes checksum
 	struct LED				LedInfo;					// LED configuration info
 	unsigned char			ShowInformation;
@@ -544,14 +555,14 @@ struct ChargingInfoData
 	unsigned char 		IsAvailable;
 	float MaximumChargingVoltage;	// unit 0.1V
 	float AvailableChargingCurrent;	// unit 0.1A
-	float AvailableChargingPower;	// unit .01kW
+	float AvailableChargingPower;	// unit 0.1kW
 	float DividChargingCurrent;		//0~6553.5 amp
-	float DeratingChargingCurrent;  //0~6553.5 amp
-	float DeratingChargingPower;	//0~6553.5 kW
+	float DeratingChargingCurrent;  // unit 0.1A
+	float DeratingChargingPower;	// unit 0.1kW
 	float FuseChargingVoltage;		//0~6553.5 volt
 	float FireChargingVoltage;		//0~6553.5 volt
-	float PresentChargingVoltage;	//0~6553.5 volt
-	float PresentChargingCurrent;		//0~6553.5 amp
+	float PresentChargingVoltage;   // unit: 1V
+	float PresentChargingCurrent;   // unit: 1A
 	float PresentChargingPower;		//0~6553.5 kW
 	float PresentChargedEnergy;		//0~6553.5 kWh
 	int PresentChargedDuration;	// second
@@ -566,17 +577,18 @@ struct ChargingInfoData
 	unsigned char PilotState;//1:state A, 2:State B1, 3:State B2, 4:State C, 5:State D, 6:State E, 7:State F, 8: Pilot error
 	unsigned char PilotDuty;					// 0~100%
 	unsigned char			StartUserId[32];			// This ID is trigger start charging event user by RFID, back-end, BLE.
+	unsigned char           StartIdType;                // 0: Central   1: eMAID    2: ISO14443 3: ISO15693 4: KeyCode  5: Local    6: MaxAddress   7: NoAuthorization
 	unsigned char			StartDateTime[32];			// Charging cycle start date time
 	unsigned char			StopDateTime[32];			// Charging cycle stop date time
 	unsigned char			StartMethod;
 	float					ChargingFee;
 	// Connector Temp
 	unsigned char 		ConnectorTemp;			//0x00: -60¢XC  ~  0xFE: 194
-	//Chiller Temp
+    //Chiller Temp
     unsigned char       ChillerTemp;            //0x00: -60¢XC  ~  0xFE: 194
 	// Charging Status
 	unsigned char 		GroundFaultStatus;		// for GFD result => 0x00 : None, 0x01 : Can Start Charging, 0x02 : Stop Charging
-	unsigned short		RealRatingPower;
+	unsigned short		RealRatingPower;        // unit: 0.1kW
 	unsigned char 		RelayWeldingCheck;		// 0 : No Comp., 1 : Comp.
 	unsigned char 		PrechargeStatus;		// for ccs precharge => 0x00 : None defined, 0x01 : Accepted
 	float 				PowerConsumption;		// This contains the meter value (Power Consumption) kWh
@@ -590,7 +602,7 @@ struct ChargingInfoData
 	unsigned char		AcCcsChargingMode;				// 0:BC (PWM) only, 1:BC & PLC mixed
 	unsigned short		SampleChargingCur[10];
 
-	/**************Alston for AC***************/
+	/************** Alston ***************/
 	unsigned char 		SelfTest_Comp;
 	unsigned char		version[16];
 	unsigned char 		IsModeChagned;
@@ -603,7 +615,7 @@ struct ChargingInfoData
 	unsigned char 		ConnectorAlarmCode[7];
 	unsigned char 		EvConnAlarmCode[7];
 	float 				ChargingProfileCurrent;			//0~6553.5 amp
-	float 				ChargingProfilePower;			//0~6553.5 kW
+	float 				ChargingProfilePower;			//0~6553.5 W
 	float 				PresentChargingVoltageL2;		//0~6553.5 volt
 	float 				PresentChargingVoltageL3;		//0~6553.5 volt
 	float 				PresentChargingCurrentL2;		//0~6553.5 amp	
@@ -616,11 +628,16 @@ struct ChargingInfoData
 	int 				EvBatteryStartSoc;				// 0~100%
 	unsigned char 		NormalStopChargeFlag;			// for EV board
 	ChargingStop        ChargingStopFlag;
-	char 				ReservedStartFlag;
-	float 				ConnectorMaxVoltage;			// 0~6553.5 volt
-	float 				ConnectorMaxCurrent;			// 0~6553.5 volt
-	unsigned char 		ModelType;
+    char                ReservedStartFlag;
+    float               ConnectorMaxVoltage;            // 0~6553.5 volt
+    float               ConnectorMaxCurrent;            // 0~6553.5 volt
+    unsigned char       ModelType;
     MeterIcCalibration  meterIcCalInfo;
+    float               PowerOffered;                   //0~6553.5 kW
+    float               CurrentOffered;                 //0~6553.5 amp
+    struct timespec     ConnectorTimeout;
+    unsigned char       PantographFlag;                 // 0: normal gun type,  1: pantograph gun type
+	unsigned char 		Replug_flag;
 };
 
 typedef union
@@ -772,7 +789,8 @@ typedef union
         unsigned int  AlarmStopRequest:1;               // 0: no effect,    1: connector alarm stop request                     ( dispenser -> cabinet)
         unsigned int  FaultStatusRequest:1;
         unsigned int  Disconnection:1;
-        unsigned int  res:10;
+        unsigned int  GfdDetection:1;                   // 0: stop,         1: start
+        unsigned int  res:9;
     }bits;
 }ConnectorParameter;
 
@@ -821,8 +839,8 @@ typedef union
         unsigned int AuthorizingCompleted:1;    // 0: not yet, 1: authorizing completed
         unsigned int DispenserDisconnection:1;  // 0: no connection,  1: dispenser connected
         unsigned int BackendAuthorized:1;       // 0: local authorized, 1: backend authorized
-        unsigned int WiringInfoChanged:1;       // 0: no effect, 1: wiring info has changed
-        unsigned int EnableWriteWiringInfo:1;   // 0: no effect, 1: enable write wiring info after timeout
+        unsigned int FlashConfigChanged:1;      // 0: no effect, 1: flash config has changed
+        unsigned int EnableWriteFlash:1;        // 0: no effect, 1: enable to write flash after timeout
         unsigned int CleanWiringInfo:1;         // 0: no effect, 1: clean wiring info
         unsigned int res:25;
     }bits;
@@ -905,6 +923,7 @@ struct SysInfoData
 	/**************Backend***************/
 	unsigned char 		OcppConnStatus;					//0: disconnected, 1: connected
 	char 				OrderCharging;
+    float               MaxChargingProfilePower;        //0~6553.5 W
 	/**************Alston***************/
 	unsigned char 		WaitForPlugit;					//0: none scan, 1: scanning
 	unsigned char 		PageIndex;						//0 : Initialize
@@ -923,7 +942,7 @@ struct SysInfoData
 	unsigned char 		FirmwareUpdate;					// 0 : none, 1 : update.
 	unsigned char 		AcContactorStatus;				// 0: disconnected, 1: connected
 	unsigned char 	 	SystemTimeoutFlag;				// 0 : none, 1 : self test
-	struct timeval		SystemTimeoutTimer;
+	struct timespec		SystemTimeoutTimer;
 	unsigned char 		SystemPage;
 	unsigned char 		ConnectorPage;
 	unsigned char		IsAlternatvieConf;				// 0 : normal, 1 : alternative
@@ -1124,8 +1143,8 @@ struct FaultCodeData
 			unsigned char BleModuleBroken:1;					//bit 2
 			unsigned char RotarySwitchFault:1;					//bit 3 
 			unsigned char CcsLiquidChillerWaterLevelFault:1;    //bit 4
-			unsigned char ChillerTempSensorBroken:1;            //bit 5
-			unsigned char :2;									//bit 6 ~ 7	reserved
+            unsigned char ChillerTempSensorBroken:1;            //bit 5
+            unsigned char :2;                                   //bit 6 ~ 7 reserved
 		}bits;
 	}FaultEvents;
 };
@@ -1257,9 +1276,9 @@ char AlarmStatusCode[128][6]=
     "012321",   // System CCS output UCP
     "012322",   // System GBT output UCP
     "012323",   // System Chiller output OTP
-    "012324",   // reserved
-    "012325",   // reserved
-    "012326",   // reserved
+    "012324",   // Connector 1 detects abnormal voltage on the output line
+    "012325",   // Connector 2 detects abnormal voltage on the output line
+    "012326",   // System task is lost
     "012327",   // reserved
 };
 */
@@ -1411,7 +1430,10 @@ struct AlarmCodeData
             unsigned char SystemCCSOutputUCP:1;                     //bit 1
             unsigned char SystemGBTOutputUCP:1;                     //bit 2
             unsigned char SystemChillerOTP:1;                       //bit 3
-            unsigned char Reserved:4;                               //bit 4~7
+            unsigned char AbnormalVoltageOnOutputLine_1:1;          //bit 4
+            unsigned char AbnormalVoltageOnOutputLine_2:1;          //bit 5
+            unsigned char SystemTaskLost:1;                         //bit 6
+            unsigned char Reserved:1;                               //bit 7
 		}bits;
 	}AlarmEvents;
 };
@@ -2148,8 +2170,8 @@ struct PsuModuleData
 	unsigned short 	InputCurrentL3;		//abcd=abc.d amp
 	unsigned short 	PresentOutputVoltage;	//abcd=abc.d volt
 	unsigned short 	PresentOutputCurrent;	//abcd=abc.d amp
-	unsigned short 	AvailableCurrent;		//abcd=abc.d amp
-	unsigned int 		AvailablePower;		//abcd=abc.d kWatt
+	unsigned short 	AvailableCurrent;		// unit: 0.1A
+	unsigned int 		AvailablePower;		// unit: 0.1kW
 	char 				CriticalTemp1;			//0x00: -60¢XC  ~  0xFE: 194¢XC, resolution: 1¢XC, offset: -60¢XC, 0xFF: invalid
 	char 				CriticalTemp2;			//0x00: -60¢XC  ~  0xFE: 194¢XC, resolution: 1¢XC, offset: -60¢XC, 0xFF: invalid
 	char 				CriticalTemp3;			//0x00: -60¢XC  ~  0xFE: 194¢XC, resolution: 1¢XC, offset: -60¢XC, 0xFF: invalid
@@ -2160,7 +2182,7 @@ struct PsuModuleData
 	char 				OutletTemp;			//0x00: -60¢XC  ~  0xFE: 194¢XC, resolution: 1¢XC, offset: -60¢XC, 0xFF: invalid
 	unsigned int 		AlarmCode;
 	unsigned int 		FaultCode;			//
-	unsigned int 		IAvailableCurrent;		//abcd=abc.d amp
+	unsigned int 		IAvailableCurrent;		            // unit: 0.1A
 };
 
 /*Following are the information for each PSU Group*/
@@ -2170,12 +2192,12 @@ struct PsuGroupData
 	unsigned char           GroupOutputPowerSwitch;         //0: D.D normal OFF,  1: D.D emergency OFF,  2: D.D ON
 	unsigned short          GroupTargetOutputVoltage;       //abcd=abc.d volt
 	unsigned short          GroupTargetOutputCurrent;       //abcd=abc.d amp
-	unsigned short          GroupAvailableCurrent;          //abcd=abc.d amp
-	unsigned int            GroupAvailablePower;            //abcd=abc.d kWatt
-	unsigned int            GroupRealOutputPower;           //Watt
-	unsigned short          GroupPresentOutputVoltage; 	    //abcd=abc.d volt
-	unsigned short          GroupPresentOutputCurrent;      //abcd=abc.d Amps
-	unsigned int            GroupPresentOutputPower;        //Watt
+	unsigned short          GroupAvailableCurrent;          // unit: 0.1A
+	unsigned int            GroupAvailablePower;            // unit: 0.1kW
+	unsigned int            GroupRealOutputPower;           // unit: 1kW
+	unsigned short          GroupPresentOutputVoltage; 	    // unit: 0.1V
+	unsigned short          GroupPresentOutputCurrent;      // unit: 0.1A
+	unsigned int            GroupPresentOutputPower;        // unit: 0.1kW
 	struct PsuModuleData 	PsuModule[MAX_PSU_QUANTITY];
 	PsuGroupError           GroupErrorFlag;
     unsigned short          TotalIAvailableCurrent;         // unit: 0.1A
@@ -3832,49 +3854,49 @@ struct CcsData
 /**************************************************************************************/
 struct PrimaryMcuData
 {
-	unsigned char 	SelfTest_Comp;
-	unsigned char	version[16];									//STM32F407 firmware version
-	unsigned int 	InputVoltage;									//value comes from external meter
-	unsigned int 	InputCurrent;									//value comes from external meter
-	union
-	{
-		unsigned char OutputDrvValue[1];
-		struct
-		{
-			//OutputDrvValue[0]
-			unsigned char OnButtonLedDrv:1;                     //bit 0,    H: ON,      L:OFF
-			unsigned char OffButtonLedDrv:1;                    //bit 1,    H: ON,      L:OFF
-			unsigned char SystemLed1Drv:1;                      //bit 2,    H: ON,      L:OFF
-			unsigned char SystemLed2Drv:1;                      //bit 3,    H: ON,      L:OFF
-			unsigned char SystemLed3Drv:1;                      //bit 4,    H: ON,      L:OFF
-			unsigned char SystemLed4Drv:1;                      //bit 5,    H: ON,      L:OFF
-			unsigned char AcContactorDrv:1;                     //bit 6,    H: ON,      L:OFF
-			unsigned char:1;                                    //bit 7 reserved
-		}bits;
-	}OutputDrv;
-	union
-	{
-		unsigned char InputDetValue[2];
-		struct
-		{
-			//InputDetValue[0]
-		    unsigned char AcContactorDetec:1;					//bit 0,	H: ON, 		L:OFF
-			unsigned char AcMainBreakerDetec:1;					//bit 1,	H: ON, 		L:OFF
-			unsigned char SpdDetec:1; 							//bit 2,	H: ON, 		L:OFF
-			unsigned char DoorOpen:1;							//bit 3,	H: Open,		L:Close
-			unsigned char Gfd1:1;								//bit 4,	H: Trigger,		L:Normal
-			unsigned char Gfd2:1;								//bit 5,	H: Trigger,		L:Normal
-			unsigned char Button1:1;								//bit 6 ,	H: Push, 		L:Release
-			unsigned char Button2:1;								//bit 7,	H: Push, 		L:Release
-			//InputDetValue[1]
-			unsigned char EmergencyButton:1;						//bit 0,	H: Push, 		L:Release
+    unsigned char   SelfTest_Comp;
+    unsigned char   version[16];                                //STM32F407 firmware version
+    unsigned int    InputVoltage;                               //value comes from external meter
+    unsigned int    InputCurrent;                               //value comes from external meter
+    union
+    {
+        unsigned char OutputDrvValue[1];
+        struct
+        {
+            //OutputDrvValue[0]
+            unsigned char OnButtonLedDrv:1;                     //bit 0,    H: ON,      L:OFF
+            unsigned char OffButtonLedDrv:1;                    //bit 1,    H: ON,      L:OFF
+            unsigned char SystemLed1Drv:1;                      //bit 2,    H: ON,      L:OFF
+            unsigned char SystemLed2Drv:1;                      //bit 3,    H: ON,      L:OFF
+            unsigned char SystemLed3Drv:1;                      //bit 4,    H: ON,      L:OFF
+            unsigned char SystemLed4Drv:1;                      //bit 5,    H: ON,      L:OFF
+            unsigned char AcContactorDrv:1;                     //bit 6,    H: ON,      L:OFF
+            unsigned char:1;                                    //bit 7 reserved
+        }bits;
+    }OutputDrv;
+    union
+    {
+        unsigned char InputDetValue[2];
+        struct
+        {
+            //InputDetValue[0]
+            unsigned char AcContactorDetec:1;                   //bit 0,    H: ON,      L:OFF
+            unsigned char AcMainBreakerDetec:1;                 //bit 1,    H: ON,      L:OFF
+            unsigned char SpdDetec:1;                           //bit 2,    H: ON,      L:OFF
+            unsigned char DoorOpen:1;                           //bit 3,    H: Open,    L:Close
+            unsigned char Gfd1:1;                               //bit 4,    H: Trigger, L:Normal
+            unsigned char Gfd2:1;                               //bit 5,    H: Trigger, L:Normal
+            unsigned char Button1:1;                            //bit 6 ,   H: Push,    L:Release
+            unsigned char Button2:1;                            //bit 7,    H: Push,    L:Release
+            //InputDetValue[1]
+            unsigned char EmergencyButton:1;                    //bit 0,    H: Push,    L:Release
             unsigned char Key0:1;                               //bit 1,    H: ON,      L:OFF
             unsigned char Key1:1;                               //bit 2,    H: ON,      L:OFF
             unsigned char Key2:1;                               //bit 3,    H: ON,      L:OFF
             unsigned char Key3:1;                               //bit 4,    H: ON,      L:OFF
             unsigned char :3;                                   //bit 5~7,  Reserved
-		}bits;
-	}InputDet;
+        }bits;
+    }InputDet;
 };
 /**************************************************************************************/
 /*************Fan power module Communication Share memory******************/
@@ -4295,7 +4317,7 @@ struct OCPP16ConfigurationItem
 {
 	unsigned char 		ItemName[64];
 	unsigned char 		ItemAccessibility;//0:RO, 1:RW
-	unsigned char 		ItemData[128];
+	unsigned char 		ItemData[500];
 };
 
 struct OCPP16ConfigurationTable
@@ -4750,6 +4772,7 @@ enum OCPP20CtrlrVariable
 	OCPPCommCtrlr_WebSocketPingInterval,
 	OCPPCommCtrlr_ResetRetries,
 	OCPPCommCtrlr_PublicKeyWithSignedMeterValue,
+    OCPPCommCtrlr_VariableVersion,
 	ReservationCtrlr_Enabled,
 	ReservationCtrlr_Available,
 	ReservationCtrlr_NonEvseSpecific,
@@ -5119,7 +5142,7 @@ struct UnitOfMeasureType
 
 struct SampledValueType
 {
-	float value;													// Required. Indicates the measured value.
+    double value;													// Required. Indicates the measured value.
 	unsigned char context[32];										// Optional. Type of detail value: start, end or sample. Default = "Sample.Periodic"
 	unsigned char measurand[32];									// Optional. Type of measurement. Default = "Energy.Active.Import.Register"
 	unsigned char phase[8];											// Optional. Indicates how the measured value is to be interpreted.
@@ -5371,6 +5394,7 @@ struct GetCertificateStatus_20
 	struct OCSPRequestDataType ocspRequestData;						// Required. Indicates the certificate of which the status is requested.
 	unsigned char Response_status[16];								// Required. This indicates whether the charging station was able to retrieve the OCSP certificate status.
 	unsigned char Response_ocspResult[5501];						// Optional. OCSPResponse class as defined in IETF RFC 6960. DER encoded (as defined in IETF RFC 6960), and then base64 encoded. MAY only be omitted when status is not Accepted.
+	struct StatusInfoType Response_statusInfo;                      // Optional. Detailed status information.
 };
 
 struct GetChargingProfiles_20

+ 4 - 2
EVSE/Projects/DD360/Apps/Makefile

@@ -70,7 +70,8 @@ COMMON_OBJ_FILES = common.o \
 MAIN_OBJ_FILES = $(COMMON_OBJ_FILES) $(DataBaseLib)/DataBase.o \
 					$(CSULib)/main.o  $(CSULib)/Primary.o $(CSULib)/WatchDog.o $(CSULib)/ZipFile.o \
 					$(CSULib)/RFID.o $(CSULib)/SelfTest.o $(CSULib)/UpgradeFW.o \
-					$(CSULib)/Ethernet.o
+					$(CSULib)/Ethernet.o $(CSULib)/CheckSystemTask.o
+					
 MAIN_SRC_FILES = $(patsubst %.o, %.c, $(MAIN_OBJ_FILES))
 %.o: %.c
 	$(CC) $(CFLAGS) -c $<
@@ -129,7 +130,8 @@ apps: MainTask DoCommTask EvCommTask \
 
 MainTask:
 	$(CC) $(DEFINE) $(MAIN_SRC_FILES) $(CFLAGS) $(TFLAGS) $(INC_FLAGS) $(SQLite3_H) $(ModuleUpgrade_H) $(RateCurrent_H) \
-		$(RFID_H) $(Lib_Module_RFID) $(Lib_Module_Upgrade) $(Lib_SQLite3) $(Lib_Module_RateCurrent) -o main
+		$(RFID_H) $(Lib_Module_RFID) $(Lib_Module_Upgrade) $(Lib_SQLite3) $(Lib_Module_RateCurrent) \
+		$(CheckSystemTask_H) -o main
 	#$(CC) $(DEFINE) $(SQLite3_H) $(ModuleUpgrade_H) $(RFID_H) $(RatedCurrent_H) $(CFLAGS) -c -o main.o main.c
 	#$(CC) $(DEFINE) $(SQLite3_H) $(ModuleUpgrade_H) $(RFID_H) $(RatedCurrent_H) $(CFLAGS) -c -o timeout.o timeout.c
 	#$(CC) $(DEFINE) $(CFLAGS) -c -o common.o common.c

+ 74 - 6
EVSE/Projects/DD360/Apps/ModuleDoComm/DoComm.c

@@ -57,10 +57,16 @@ static void removeFaultCodeToBuf(uint8_t *Code);
 static void addFaultCodeToBuf(uint8_t *Code);
 static int readMiscCommand(int fd, uint8_t id);
 static int writeCsuModuleVersion(int fd);
+static int writeGroundFaultDetection(int fd, uint8_t status, uint8_t id);
 
 //------------------------------------------------------------------------------
 //--- Common function ---
 //------------------------------------------------------------------------------
+void GetClockTime(struct timespec *_now_time, void *null)
+{
+    clock_gettime(CLOCK_MONOTONIC, _now_time);
+}
+
 /*static int StoreLogMsg(const char *fmt, ...)
 {
     char Buf[4096 + 256];
@@ -715,7 +721,7 @@ static int miscCommandHandle(uint8_t dataLen, uint8_t plugNum, uint8_t *data)
                     pSysInfo->WaitForPlugit = NO;
                     sleep(1); //Jerry add
                     pSysInfo->SystemPage = _LCM_SELECT_GUN;
-                    gettimeofday(&pSysInfo->SystemTimeoutTimer, NULL);
+                    GetClockTime(&pSysInfo->SystemTimeoutTimer, NULL);
                     pSysInfo->SystemTimeoutFlag = Timeout_None;
                 }
 
@@ -727,7 +733,7 @@ static int miscCommandHandle(uint8_t dataLen, uint8_t plugNum, uint8_t *data)
                     pSysInfo->WaitForPlugit = NO;
                     sleep(1); //Jerry add
                     pSysInfo->SystemPage = _LCM_SELECT_GUN;
-                    gettimeofday(&pSysInfo->SystemTimeoutTimer, NULL);
+                    GetClockTime(&pSysInfo->SystemTimeoutTimer, NULL);
                     pSysInfo->SystemTimeoutFlag = Timeout_None;
                 }
 
@@ -756,7 +762,7 @@ static int miscCommandHandle(uint8_t dataLen, uint8_t plugNum, uint8_t *data)
             strcpy((char *)pSysConfig->UserId, "");
             pSysInfo->WaitForPlugit = NO;
             pSysInfo->SystemPage = _LCM_SELECT_GUN;
-            gettimeofday(&pSysInfo->SystemTimeoutTimer, NULL);
+            GetClockTime(&pSysInfo->SystemTimeoutTimer, NULL);
             pSysInfo->SystemTimeoutFlag = Timeout_None;
             destroySelectGun(plugNum);
 
@@ -776,7 +782,7 @@ static int miscCommandHandle(uint8_t dataLen, uint8_t plugNum, uint8_t *data)
                 strcpy((char *)pSysConfig->UserId, "");
                 pSysInfo->WaitForPlugit = NO;
                 pSysInfo->SystemPage = _LCM_SELECT_GUN;
-                gettimeofday(&pSysInfo->SystemTimeoutTimer, NULL);
+                GetClockTime(&pSysInfo->SystemTimeoutTimer, NULL);
                 pSysInfo->SystemTimeoutFlag = Timeout_None;
                 destroySelectGun(plugNum);
             } else {
@@ -1167,6 +1173,26 @@ static int responsePackeHandle(int fd, uint8_t *pResult, uint8_t plugNum, uint8_
     case REG_WAIT_PLUG_IT_STATE:
         break;
 
+    case REG_Ground_Fault_Detection:
+        if (pCsuResult->Data.Result == COMMAND_RESULT_NG) {
+            return COMMAND_RESULT_NG;
+        }
+
+        //集電弓relay 不打開才能進入動作
+        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(plugNum);
+        if(pDcChargingInfo->PantographFlag == YES)
+        {
+            GroundFaultDetection *gfd = (GroundFaultDetection *)&pCsuResult->Data.Data[0];
+            if(pDcChargingInfo->GroundFaultStatus != gfd->Status)
+            {
+                log_info("id = %d, GFD Result = %d\r\n",
+                           pCsuResult->Head.ID,
+                           gfd->Status);
+            }
+            pDcChargingInfo->GroundFaultStatus = gfd->Status;
+        }
+        break;
+
     default:
         break;
     }
@@ -1277,8 +1303,16 @@ static int writePresentChargingInfo(int fd, uint8_t plugNum, uint8_t id)
     PreChargingInfo *pPreChargingInfo = (PreChargingInfo *)dataBuf;
     pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(plugNum);
 
-    pPreChargingInfo->PresentChargingVoltage = htons((uint16_t)(pDcChargingInfo->PresentChargingVoltage * 10));
-    pPreChargingInfo->PresentChargingCurrent = htons((uint16_t)(pDcChargingInfo->PresentChargingCurrent * 10));
+    if(pDcChargingInfo->PantographFlag == NO)
+    {
+        pPreChargingInfo->PresentChargingVoltage = htons((uint16_t)(pDcChargingInfo->PresentChargingVoltage * 10));
+        pPreChargingInfo->PresentChargingCurrent = htons((uint16_t)(pDcChargingInfo->PresentChargingCurrent * 10));
+    }
+    else
+    {
+        pPreChargingInfo->PresentChargingVoltage = htons((uint16_t)(ShmDcCommonData->PcPsuOutput[plugNum].Voltage));
+        pPreChargingInfo->PresentChargingCurrent = htons((uint16_t)(ShmDcCommonData->PcPsuOutput[plugNum].Current));
+    }
     pPreChargingInfo->RemainChargingDuration = htonl(pDcChargingInfo->RemainChargingDuration);
     pPreChargingInfo->EvBatterySoc = pDcChargingInfo->EvBatterySoc;
 
@@ -1369,6 +1403,19 @@ static int readChargePermission(int fd, uint8_t id)
                              NULL);
 }
 
+static int writeGroundFaultDetection(int fd, uint8_t status, uint8_t id)
+{
+    int ret = PASS;
+    uint8_t dataBuf[1] = {status};
+    ret = composeSocketData(fd,
+                            id,
+                            OP_WRITE_DATA,
+                            REG_Ground_Fault_Detection,
+                            1,
+                            &dataBuf[0]);
+    return ret;
+}
+
 static int writeUserID(int fd, uint8_t id, uint8_t *pUserID)
 {
     if ((strlen((char *)pUserID) <= 0) || (pUserID == NULL)) {
@@ -1940,6 +1987,8 @@ static void systemStatusProcess(int fd, uint8_t totalGun, uint8_t plugNum, uint8
                 DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_CAP], AuthNowTime) < 0
            ) {
             readChargingCapability(fd, gunID);
+			if (pDcChargingInfo->PantographFlag)
+				writeGroundFaultDetection(fd, 0, gunID);
             ftime(&gRegTimeUp[plugNum][REG_CHARGING_CAP]);
         }
         break;
@@ -1973,6 +2022,8 @@ static void systemStatusProcess(int fd, uint8_t totalGun, uint8_t plugNum, uint8
                 DiffTimeb(gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO], AuthNowTime) < 0
            ) {
             writePresentChargingInfo(fd, plugNum, gunID);
+			if (pDcChargingInfo->PantographFlag)
+				writeGroundFaultDetection(fd, 0, gunID);
             ftime(&gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO]);
         }
         break;
@@ -2004,6 +2055,8 @@ static void systemStatusProcess(int fd, uint8_t totalGun, uint8_t plugNum, uint8
                 DiffTimeb(gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO], AuthNowTime) < 0
            ) {
             writePresentChargingInfo(fd, plugNum, gunID);
+			if (pDcChargingInfo->PantographFlag)
+				writeGroundFaultDetection(fd, 0, gunID);
             ftime(&gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO]);
         }
         break;
@@ -2012,6 +2065,8 @@ static void systemStatusProcess(int fd, uint8_t totalGun, uint8_t plugNum, uint8
     case S_CCS_PRECHARGE_ST0:
     case S_CCS_PRECHARGE_ST1:
         writeChargingTarget(fd, plugNum, gunID);
+		if (pDcChargingInfo->PantographFlag)
+			writeGroundFaultDetection(fd, 1, gunID);
 
         ftime(&AuthNowTime);
         if (DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_CAP], AuthNowTime) > LOOP_RETRY_TIME ||
@@ -2045,6 +2100,17 @@ static void systemStatusProcess(int fd, uint8_t totalGun, uint8_t plugNum, uint8
 
     case S_CHARGING: //charging
     case S_TERMINATING:
+        if(pDcChargingInfo->Type == _Type_GB || pDcChargingInfo->Type == _Type_Chademo)
+        {
+			if (pDcChargingInfo->PantographFlag)
+				writeGroundFaultDetection(fd, 0, gunID);
+        }
+        else
+        {
+			if (pDcChargingInfo->PantographFlag)
+				writeGroundFaultDetection(fd, 1, gunID);
+        }
+
         ftime(&AuthNowTime);
         if (DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_CAP], AuthNowTime) > LOOP_RETRY_TIME ||
                 DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_CAP], AuthNowTime) < 0
@@ -2083,6 +2149,8 @@ static void systemStatusProcess(int fd, uint8_t totalGun, uint8_t plugNum, uint8
                 DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_CAP], AuthNowTime) < 0
            ) {
             readChargingCapability(fd, gunID);
+			if (pDcChargingInfo->PantographFlag)
+				writeGroundFaultDetection(fd, 0, gunID);
             ftime(&gRegTimeUp[plugNum][REG_CHARGING_CAP]);
         }
         break;

+ 5 - 0
EVSE/Projects/DD360/Apps/ModuleDoComm/DoComm.h

@@ -79,6 +79,7 @@
 #define REG_PRESENT_CHARGING_INFO               0X0F
 #define REG_QRCODE_URL_INFO                     0X10
 #define REG_WAIT_PLUG_IT_STATE                  0x11
+#define REG_Ground_Fault_Detection              0x12
 
 //------------------------------------------------------------------------------
 //--- dispenser result ---
@@ -207,6 +208,10 @@ typedef struct StPresentChargingInfo {
     uint8_t EvBatterySoc;               // 0~100%
 } PreChargingInfo;
 
+typedef struct StGroundFaultDetection { //Ground Fault Detection
+    uint8_t Status;
+} GroundFaultDetection;
+
 typedef struct StSoftwareUpdInfo {
     uint8_t UpdateState;         //1:update , 2: not update
     uint8_t ImgName[248];

+ 4 - 2
EVSE/Projects/DD360/Apps/ModuleEvComm/AbnormalState.c

@@ -27,8 +27,10 @@ bool AbnormalStopAnalysis(uint8_t gun_index, uint8_t *errCode)
     //iflog_info("NOTIFICATION_EV_STOP : Err Code = %s \n", string);
 
     if (strncmp(string, "000000", 6) == EQUAL ||
-            strncmp(string, "012219", 6) == EQUAL
-       ) {
+            strncmp(string, "012219", 6) == EQUAL ||
+            strncmp(string, "023979", 6) == EQUAL )
+    {
+		log_info("NOTIFICATION_EV_STOP : EvCode = %s\n", string);
         return false;
     }
 

+ 14 - 9
EVSE/Projects/DD360/Apps/ModuleEvComm/Module_EvTxComm.c

@@ -15,6 +15,7 @@
 
 #include <linux/can.h>
 #include <linux/can/raw.h>
+#include <signal.h>
 
 #include "../Config.h"
 #include "../Log/log.h"
@@ -505,7 +506,7 @@ static void SetPresentChargingOutputPower(void)
     PcPsuOutput *pPcPsuOutput2 = NULL;
     struct ChargingInfoData *chargingData_1 = NULL;
     struct ChargingInfoData *chargingData_2 = NULL;
-    bool isPsuOutput1 = false, isPsuOutput2 = false;
+    bool isPsuVol1 = false, isPsuVol2 = false, isPsuCur1 = false, isPsuCur2 = false;
 
     if (pSysConfig->TotalConnectorCount == 1) {
         pPcPsuOutput1 = (PcPsuOutput *)&ShmDcCommonData->PcPsuOutput[0];
@@ -522,15 +523,17 @@ static void SetPresentChargingOutputPower(void)
     psuOutputReady[0] = chargingData_1->SystemStatus != S_CHARGING ? false : psuOutputReady[0];
     psuOutputReady[1] = chargingData_2->SystemStatus != S_CHARGING ? false : psuOutputReady[1];
 
-    isPsuOutput1 = (pPcPsuOutput1->Voltage != 0 && psuOutputReady[0] == true);
-    isPsuOutput2 = (pPcPsuOutput2->Voltage != 0 && psuOutputReady[1] == true);
+    isPsuVol1 = chargingData_1->PantographFlag ? true : (pPcPsuOutput1->Voltage != 0 && psuOutputReady[0] == true);
+    isPsuVol2 = chargingData_2->PantographFlag ? true : (pPcPsuOutput2->Voltage != 0 && psuOutputReady[1] == true);
+    isPsuCur1 = chargingData_1->PantographFlag ? true : false;
+    isPsuCur2 = chargingData_2->PantographFlag ? true : false;
 
     //vol1 = chargingData_1->FireChargingVoltage;
-    vol1 = isPsuOutput1 == false ? chargingData_1->FireChargingVoltage : (((float)pPcPsuOutput1->Voltage));
-    cur1 = (chargingData_1->PresentChargingCurrent * 10);
+    vol1 = isPsuVol1 == false ? chargingData_1->FireChargingVoltage : (((float)pPcPsuOutput1->Voltage));
+    cur1 = isPsuCur1 == false ? (chargingData_1->PresentChargingCurrent * 10) : pPcPsuOutput1->Current;
     //vol2 = chargingData_2->FireChargingVoltage;
-    vol2 = isPsuOutput2 == false ? chargingData_2->FireChargingVoltage : (((float)pPcPsuOutput2->Voltage));
-    cur2 = (chargingData_2->PresentChargingCurrent * 10);
+    vol2 = isPsuVol2 == false ? chargingData_2->FireChargingVoltage : (((float)pPcPsuOutput2->Voltage));
+    cur2 = isPsuCur2 == false ? (chargingData_2->PresentChargingCurrent * 10) : pPcPsuOutput2->Current;
 
     //DS60-120 add
     if ((LogInfo[0][EV_LOG_NOW_OUTPUT_VOL] >= vol1 + CHK_VOL_RANGE) ||
@@ -543,10 +546,10 @@ static void SetPresentChargingOutputPower(void)
             (LogInfo[1][EV_LOG_NOW_OUTPUT_CUR] <= cur2 - CHK_CUR_RANGE)
        ) {
         log_info("G1 -> Output Vol(%s) = %.1f, Output Cur = %.1f -- G2 -> Output Vol(%s) = %.1f, Output Cur = %.1f\r\n",
-                 isPsuOutput1 == true ? "P" : "R",
+                 isPsuVol1 == true ? "P" : "R",
                  vol1 / 10,
                  cur1 / 10,
-                 isPsuOutput2 == true ? "P" : "R",
+                 isPsuVol2 == true ? "P" : "R",
                  vol2 / 10,
                  cur2 / 10);
 
@@ -711,6 +714,8 @@ int main(int argc, char *argv[])
 
     FormatVoltageAndCurrent();
 
+    signal(SIGCHLD,SIG_IGN);
+    
     CANReceiver(CanFd);
 
     rtc = GetRtcInfoForEpoch();

+ 4 - 1
EVSE/Projects/DD360/Apps/ModuleInternalComm/Module_InternalComm.c

@@ -100,7 +100,10 @@ int main(int argc, char *argv[])
     //FanBoardTask(fd);
 
     while (isContinue) {
-        AcPlugTask(fd);
+        if(AC_QUANTITY > 0)
+        {
+            AcPlugTask(fd);
+        }
         usleep(100000);
     }
 

+ 41 - 4
EVSE/Projects/DD360/Apps/ModuleInternalComm/RelayBoard.c

@@ -780,6 +780,13 @@ void CableCheckDetected(uint8_t index)
                     SetGfdConfig(targetID, GFD_CHARGING);
                 }
             }
+        }
+        else if(pDcChargingInfo->SystemStatus == S_TERMINATING || pDcChargingInfo->SystemStatus == S_ALARM)
+        {
+            if (pDcChargingInfo->Type == _Type_CCS_2)
+            {
+                SetGfdConfig(targetID, GFD_CHARGING);
+            }
         } else {
             SetGfdConfig(targetID, GFD_IDLE);
         }
@@ -1648,6 +1655,7 @@ static void LEDBoardProcess(void)
 
 void RelayBoardTask(int uartFD)
 {
+    bool isRelayBypass = false;
     pid_t pid = fork();
 
     if (pid == 0) {
@@ -1671,8 +1679,20 @@ void RelayBoardTask(int uartFD)
 
         Uart5Fd = uartFD;
 
+        for(int i = 0; i < pSysConfig->TotalConnectorCount; i++)
+        {
+            pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
+            if(pDcChargingInfo->PantographFlag == YES)
+            {
+                isRelayBypass = true;
+            }
+        }
+
         //relay init
-        outputRelayInit(uartFD);
+        if(isRelayBypass == false)
+        {
+            outputRelayInit(uartFD);
+        }
 
         while (isContinue) {
 
@@ -1683,7 +1703,7 @@ void RelayBoardTask(int uartFD)
             }
 
             // 程序開始之前~ 必須先確定 FW 版本與硬體版本,確認後!!~ 該模組才算是真正的 Initial Comp.
-            if (ShmRelayModuleData->SelfTest_Comp == NO) {
+            if (ShmRelayModuleData->SelfTest_Comp == NO && isRelayBypass == false) {
                 GetFwAndHwVersion_Relay();
                 SetModelName_Relay(); //DS60-120 add
                 SetRtcData_Relay();
@@ -1698,7 +1718,7 @@ void RelayBoardTask(int uartFD)
             LEDBoardSelfTest();
 #endif //defined DD360ComBox
 
-            if (ShmRelayModuleData->SelfTest_Comp == YES)
+            if (ShmRelayModuleData->SelfTest_Comp == YES && isRelayBypass == false)
             {
                 // ==============優先權最高 10 ms ==============
                 // 輸出電壓
@@ -1711,7 +1731,6 @@ void RelayBoardTask(int uartFD)
 
                 // 讀取當前 AC relay 狀態
                 regRelay.relay_event.bits.AC_Contactor = pSysInfo->AcContactorStatus;
-
                 GetRelayOutputStatus();
 
                 // Cable check (Get)
@@ -1848,6 +1867,24 @@ void RelayBoardTask(int uartFD)
                     }
                 }
             }
+            else if(isRelayBypass == true)
+            {
+                for(i = 0; i < pSysConfig->TotalConnectorCount; i++)
+                {
+                    pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
+
+                    if (pDcChargingInfo->SystemStatus == S_IDLE ||
+                            pDcChargingInfo->SystemStatus == S_RESERVATION ||
+                            pDcChargingInfo->SystemStatus == S_MAINTAIN)
+                    {
+                        _isOvpChkTimeFlag[i] = NO;
+                    }
+                    if (pDcChargingInfo->SystemStatus == S_CHARGING)
+                    {
+                        CheckOutputPowerOverCarReq(i);
+                    }
+                }
+            }
 
 #if !defined NO_FAN_BOARD && !defined DD360ComBox
             fanBoardPorcess();

+ 39 - 0
EVSE/Projects/DD360/Apps/ModuleLcmCtrl/Module_LcmControl.c

@@ -223,6 +223,11 @@ uint8_t _right_gun_disable_map  = 68;
 uint8_t _right_gun_enable_map   = 69;
 uint8_t _select_gun_btn         = 70;
 uint8_t _emergency_disable_map  = 72;
+// For replug
+struct timespec showReplugStrTimer;
+short __show_replugString_value = 0x0460;
+uint8_t _showReplugStr_1 = 74;
+uint8_t _showReplugStr_2 = 75;
 
 //#define log_info(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
 //#define log_warn(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
@@ -853,6 +858,31 @@ bool FindAcChargingInfoData(uint8_t target, struct ChargingInfoData **acCharging
 
     return false;
 }
+int GetTimeoutValue(struct timespec *startTime)
+{
+    struct timespec endTime;
+    clock_gettime(CLOCK_MONOTONIC_COARSE, &endTime);
+    return endTime.tv_sec - startTime->tv_sec;
+}
+void GetTimespecFunc(struct timespec *time)
+{
+    clock_gettime(CLOCK_MONOTONIC_COARSE, time);
+}
+
+void RunReplugStringFunction(bool isRun)
+{
+    if (isRun) {
+        int time = GetTimeoutValue(&showReplugStrTimer);
+        if (time >=1 && time <2) {
+            ChangeDisplay2Value(__show_replugString_value, _showReplugStr_1);
+        } else if (time < 1) {
+            ChangeDisplay2Value(__show_replugString_value, _showReplugStr_2);
+        } else
+            GetTimespecFunc(&showReplugStrTimer);
+
+    } else
+        ChangeDisplay2Value(__show_replugString_value, _disappear);
+}
 
 /**
  * [ChangeBalanceValue :print balance information]
@@ -2041,6 +2071,15 @@ void ProcessPageInfo()
                     } else {
                         ChangeDisplay2Value(__charging_fee_map, _money_map);
                     }
+#ifdef DD360Audi
+                    // Warming Occur in prepare or precharing state, turn into complete mode
+                    if (pDcChargingInfo->Replug_flag) {
+                        RunReplugStringFunction(true);
+                    } else {
+                        RunReplugStringFunction(false);
+                    }
+#else
+#endif					
                 }
             }
         }

+ 54 - 6
EVSE/Projects/DD360/Apps/ModulePrimary/Module_PrimaryComm.c

@@ -48,6 +48,11 @@ static struct PrimaryMcuData *ShmPrimaryMcuData;
 const char *priPortName = "/dev/ttyS1";
 uint8_t gun_count; //DS60-120 add
 
+uint8_t EmgBtn_count = 0;
+uint8_t Door_count = 0;
+uint8_t EmgBtn_flag = 0;
+uint8_t Door_flag = 0;
+
 //struct ChargingInfoData *ChargingData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 
 //------------------------------------------------------------------------------
@@ -180,13 +185,31 @@ void GetInputGpioStatus(int fd)
     }
 
     ShmPrimaryMcuData->InputDet.bits.SpdDetec = gpio_in.SPD;
-
 #if defined DD360ComBox
-    ShmPrimaryMcuData->InputDet.bits.EmergencyButton = ~gpio_in.Emergency_Btn;
+    if (gpio_in.Emergency_Btn == 0 && (EmgBtn_flag == gpio_in.Emergency_Btn))
 #else
-    ShmPrimaryMcuData->InputDet.bits.EmergencyButton = gpio_in.Emergency_Btn;
+    if (gpio_in.Emergency_Btn && (EmgBtn_flag != gpio_in.Emergency_Btn))
 #endif //defined DD360ComBox
-
+    {
+            EmgBtn_count++;
+        if (EmgBtn_count > SensorTrigCount) {
+           EmgBtn_flag = 1;
+           EmgBtn_count = 0; // Avoid Overflow
+       }
+#ifdef DD360ComBox
+    } else if ( gpio_in.Emergency_Btn && EmgBtn_flag ) {
+#else
+    } else if (EmgBtn_flag != gpio_in.Emergency_Btn ) {
+#endif    
+        EmgBtn_count++;
+        if (EmgBtn_count > SensorTrigCount) {
+            EmgBtn_flag = 0;
+            EmgBtn_count = 0;
+        }
+    }
+ 
+    ShmPrimaryMcuData->InputDet.bits.EmergencyButton = EmgBtn_flag;
+ 
     dispenserSwTmp |= (ShmPrimaryMcuData->InputDet.bits.Key0);
     dispenserSwTmp |= (ShmPrimaryMcuData->InputDet.bits.Key1 << 1);
     dispenserSwTmp |= (ShmPrimaryMcuData->InputDet.bits.Key2 << 2);
@@ -219,10 +242,35 @@ void GetInputGpioStatus(int fd)
     }
 
 #if defined DD360ComBox
-    ShmPrimaryMcuData->InputDet.bits.DoorOpen = gpio_in.Door_Open;
+    if (gpio_in.Door_Open && (Door_flag != gpio_in.Door_Open))
 #else
-    ShmPrimaryMcuData->InputDet.bits.DoorOpen = ~gpio_in.Door_Open;
+    if (gpio_in.Door_Open == 0 && (Door_flag == gpio_in.Door_Open))
 #endif //defined DD360ComBox
+    {
+        Door_count++;
+        if (Door_count > SensorTrigCount) {
+            Door_flag = 1;
+            Door_count = 0; // Avoid Overflow
+       }
+#ifdef DD360ComBox
+    } else if (gpio_in.Door_Open == 0 && Door_flag) {
+#else
+    } else if (gpio_in.Door_Open && Door_flag) {
+#endif
+        Door_count++;
+        if (Door_count > SensorTrigCount) {
+            Door_flag = 0;
+            Door_count = 0;
+        }
+    }
+ 
+    ShmPrimaryMcuData->InputDet.bits.DoorOpen = Door_flag;
+/*
+    log_info("Emergency Button Count = %d , Emergency flag = %d\n",
+            EmgBtn_count,EmgBtn_flag);
+    log_info("Door Sensor Count = %d , Door Sensor flag = %d\n",
+            Door_count,Door_flag);
+*/
 
     ShmPrimaryMcuData->InputDet.bits.Key0 = ~gpio_in.Key[0] & 0x01;
     ShmPrimaryMcuData->InputDet.bits.Key1 = ~gpio_in.Key[1] & 0x01;

+ 1 - 0
EVSE/Projects/DD360/Apps/ModulePrimary/Module_PrimaryComm.h

@@ -30,5 +30,6 @@ typedef struct StLedConfig {
 
 //------------------------------------------------------------------------------
 //int StoreLogMsg(const char *fmt, ...);
+#define SensorTrigCount 3
 
 #endif /* _MODULE_PRIMARY_COMM_H_ */

+ 4 - 0
EVSE/Projects/DD360/Apps/Script/kill.sh

@@ -12,6 +12,10 @@ pkill Module_ProduceUtils;
 pkill Module_DoComm;
 pkill main;
 
+sleep 1
+
+echo V > /dev/watchdog
+
 ipcrm -M 0x000003e9;
 ipcrm -M 0x000003ed;
 ipcrm -M 0x000003ea;

+ 35 - 17
EVSE/Projects/DD360/Apps/ShareMemory/shmMem.c

@@ -833,7 +833,7 @@ static int findDcChargingInfoData(uint8_t gunIndex)
     return FAIL;
 }
 
-static bool addGunInfoByConnector(uint8_t typeValue, uint8_t slots)
+static bool addGunInfoByConnector(uint8_t typeValue, uint8_t slots,char *whichtask)
 {
     bool result = true;
     struct SysInfoData *pSysInfo = (struct SysInfoData *)GetShmSysInfoData();
@@ -862,11 +862,14 @@ static bool addGunInfoByConnector(uint8_t typeValue, uint8_t slots)
             pAcChargingInfo->ReservationId = -1;
             pAcChargingInfo->SystemStatus = S_IDLE;
             pAcChargingInfo->Type = _Type_AC;
-            pAcChargingInfo->IsAvailable = YES;
             pAcChargingInfo->schedule.isTriggerStart = NO; //DS60-120 add
             pAcChargingInfo->schedule.isTriggerStop = NO;  //DS60-120 add
-            gGunIndexInfo.AcIndex++;
-            gGunIndexInfo.AcGunIndex++;
+            //if( strcmp(whichtask,"CSU task") == EQUAL ) 
+            {
+                gGunIndexInfo.AcIndex++;
+                gGunIndexInfo.AcGunIndex++;
+                pAcChargingInfo->IsAvailable = YES;
+            }
         } else {
             result = false;
         }
@@ -886,13 +889,17 @@ static bool addGunInfoByConnector(uint8_t typeValue, uint8_t slots)
             pDcChargingInfo->Index = gGunIndexInfo.DcGunIndex;
             pDcChargingInfo->ReservationId = -1;
             pDcChargingInfo->slotsIndex = slots;
-            pDcChargingInfo->SystemStatus = S_BOOTING;
+            //pDcChargingInfo->SystemStatus = S_BOOTING;
+			//pDcChargingInfo->SystemStatus = S_IDLE;
             pDcChargingInfo->Type = _Type_Chademo;
             pDcChargingInfo->type_index = gGunIndexInfo.ChademoIndex;
-            pDcChargingInfo->IsAvailable = YES;
             setAcGunTiggerStatus();
-            gGunIndexInfo.ChademoIndex++;
-            gGunIndexInfo.DcGunIndex++;
+            //if( strcmp(whichtask,"CSU task") == EQUAL ) 
+            {
+                pDcChargingInfo->IsAvailable = YES;
+                gGunIndexInfo.ChademoIndex++;
+                gGunIndexInfo.DcGunIndex++;
+            }
         } else {
             result = false;
         }
@@ -914,15 +921,23 @@ static bool addGunInfoByConnector(uint8_t typeValue, uint8_t slots)
             pDcChargingInfo->Index = gGunIndexInfo.DcGunIndex;
             pDcChargingInfo->ReservationId = -1;
             pDcChargingInfo->slotsIndex = slots;
-            pDcChargingInfo->SystemStatus = S_BOOTING;
+            //pDcChargingInfo->SystemStatus = S_BOOTING;
             pDcChargingInfo->Type = _Type_CCS_2;
             pDcChargingInfo->type_index = gGunIndexInfo.CcsIndex;
-            pDcChargingInfo->IsAvailable = YES;
+
             setAcGunTiggerStatus();
             // 現階段預設為走 DIN70121
             pCcsData->CommProtocol = _CCS_COMM_V2GMessage_DIN70121;
-            gGunIndexInfo.CcsIndex++;
-            gGunIndexInfo.DcGunIndex++;
+            //if( strcmp(whichtask,"CSU task") == EQUAL ) 
+            {
+                pDcChargingInfo->IsAvailable = YES;
+                gGunIndexInfo.CcsIndex++;
+                gGunIndexInfo.DcGunIndex++;
+            }
+            if(typeValue == 'P')
+            {
+                pDcChargingInfo->PantographFlag = YES;
+            }
         } else {
             result = false;
         }
@@ -935,13 +950,16 @@ static bool addGunInfoByConnector(uint8_t typeValue, uint8_t slots)
             pDcChargingInfo->Index = gGunIndexInfo.DcGunIndex;
             pDcChargingInfo->ReservationId = -1;
             pDcChargingInfo->slotsIndex = slots;
-            pDcChargingInfo->SystemStatus = S_BOOTING;
+            //pDcChargingInfo->SystemStatus = S_BOOTING;
             pDcChargingInfo->Type = _Type_GB;
             pDcChargingInfo->type_index = gGunIndexInfo.GbIndex;
-            pDcChargingInfo->IsAvailable = YES;
             setAcGunTiggerStatus();
-            gGunIndexInfo.GbIndex++;
-            gGunIndexInfo.DcGunIndex++;
+            //if( strcmp(whichtask,"CSU task") == EQUAL ) 
+            {
+                pDcChargingInfo->IsAvailable = YES;
+                gGunIndexInfo.GbIndex++;
+                gGunIndexInfo.DcGunIndex++;
+            }
         } else {
             result = false;
         }
@@ -984,7 +1002,7 @@ bool MappingGunChargingInfo(char *whichTask)
 
     //printf("1 CheckConnectorTypeStatus\r\n");
     for (typeIndex = 7; typeIndex <= 9; typeIndex++) {
-        if (!addGunInfoByConnector(pSysConfig->ModelName[typeIndex], slots)) {
+        if (!addGunInfoByConnector(pSysConfig->ModelName[typeIndex], slots, whichTask)) {
             log_error("%s add gun info failed\r\n", whichTask);
             return false;
         }

二進制
EVSE/Projects/DD360/Apps/UnsafetyOutputTask


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


二進制
EVSE/Projects/DD360/output/FactoryConfig


二進制
EVSE/Projects/DD360/output/Module_DoComm


二進制
EVSE/Projects/DD360/output/Module_EvComm


二進制
EVSE/Projects/DD360/output/Module_EventLogging


二進制
EVSE/Projects/DD360/output/Module_InternalComm


二進制
EVSE/Projects/DD360/output/Module_LcmControl


二進制
EVSE/Projects/DD360/output/Module_PrimaryComm


二進制
EVSE/Projects/DD360/output/ReadCmdline


二進制
EVSE/Projects/DD360/output/main


+ 184 - 0
EVSE/Projects/DD360Audi/Apps/CSU/CheckSystemTask.c

@@ -0,0 +1,184 @@
+/*
+ * CheckTask.c
+ *
+ *  Created on: 2021年9月22日
+ *      Author: 8513
+ */
+
+#include "CheckSystemTask.h"
+
+bool Taskconutstring(char *src, char *taskname)
+{
+    bool result = false;
+
+    if (src == NULL || strlen(src) == 0)
+        return result;
+
+    if (strstr(src, taskname) != NULL &&
+        strstr(src, "grep") == NULL &&
+        strstr(src, "[") == NULL)
+    {
+        result = true;
+    }
+
+    return result;
+}
+
+int GetProcessCount(char *procName)
+{
+	int result = 0;
+	FILE *fp;
+	char cmd[256];
+	char buf[256];
+
+	sprintf(cmd, "ps -ef |grep %s", procName);
+	fp = popen(cmd, "r");
+	if(fp != NULL)
+	{
+		while(fgets(buf, sizeof(buf), fp) != NULL)
+		{
+			if (Taskconutstring(buf, procName))
+				result++;
+		}
+	}
+
+	pclose(fp);
+
+	return result;
+}
+
+unsigned char CheckSystemTask(unsigned char systemPage)
+{
+	unsigned char result = 0;
+	unsigned char count_main 		= GetProcessCount("main");
+	unsigned char count_evComm 		= GetProcessCount("Module_EvComm");
+	unsigned char count_interComm	= GetProcessCount("Module_InternalComm");
+	unsigned char count_eventComm	= GetProcessCount("Module_EventLogging");
+	unsigned char count_primaryComm	= GetProcessCount("Module_PrimaryComm");
+	unsigned char count_lcmComm	    = GetProcessCount("Module_LcmControl");
+	unsigned char count_doComm	    = GetProcessCount("Module_DoComm");
+	unsigned char count_produceComm	= GetProcessCount("Module_ProduceUtils");
+//	unsigned char count_psuComm 	= GetProcessCount("Module_PsuComm");
+
+//	printf("*************************** \n");
+//	printf("count_main = %d \n", count_main);
+//	printf("count_eventLog = %d \n", count_eventLog);
+//	printf("count_primary = %d \n", count_primary);
+//	printf("count_evComm = %d \n", count_evComm);
+//	printf("count_lcmCtrl = %d \n", count_lcmCtrl);
+//	printf("count_interComm = %d \n", count_interComm);
+//	printf("count_psuComm = %d \n", count_psuComm);
+//	printf("*************************** \n");
+
+//	if (systemPage == 0x09 || systemPage == 0x0A)
+	{
+		if (count_main < _SYSTEM_TASK_COUNT_MAIN )
+		{
+			system("killall Module_EventLogging");
+			system("killall Module_PrimaryComm");
+			system("killall Module_EvComm");
+			system("killall Module_LcmControl");
+			system("killall Module_InternalComm");
+			system("killall Module_DoComm");
+//			system("killall Module_PsuComm");
+//			system("killall OcppBackend &");
+//			system("killall Module_4g &");
+//			system("killall Module_Wifi &");
+			system("killall Module_ProduceUtils &");
+			sleep(3);
+			system("/usr/bin/run_evse_restart.sh");
+		}
+		else
+		{
+			/*
+			if(system("pidof -s Module_EventLogging > /dev/null") != 0)
+				system("/root/Module_EventLogging &");
+
+			if(system("pidof -s Module_PrimaryComm > /dev/null") != 0)
+				system("/root/Module_PrimaryComm &");
+
+			if(system("pidof -s Module_LcmControl > /dev/null") != 0)
+				system("/root/Module_LcmControl &");
+
+            if(system("pidof -s Module_DoComm > /dev/null") != 0)
+                system("/root/Module_DoComm &");
+
+            if(system("pidof -s Module_ProduceUtils > /dev/null") != 0)
+                system("/root/Module_ProduceUtils &");
+
+			*/
+			if (count_evComm < _SYSTEM_TASK_COUNT_EVCOMM )
+			{
+				system("killall Module_EvComm");
+				sleep(3);
+				system("/root/Module_EvComm &");
+			}
+        	if (count_interComm < _SYSTEM_TASK_COUNT_INTERNALCOMM )
+			{
+				system("killall Module_InternalComm");
+				sleep(3);
+				system("/root/Module_InternalComm &");
+			}
+			if (count_eventComm < _SYSTEM_TASK_COUNT_EVENTLOGGING )
+			{
+				system("killall Module_EventLogging");
+				sleep(3);
+				system("/root/Module_EventLogging &");
+			}
+			if (count_primaryComm < _SYSTEM_TASK_COUNT_PRIMARYCOMM )
+			{
+				system("killall Module_PrimaryComm");
+				sleep(3);
+				system("/root/Module_PrimaryComm &");
+			}
+			if (count_lcmComm < _SYSTEM_TASK_COUNT_LCM )
+			{
+				system("killall Module_LcmControl");
+				sleep(3);
+				system("/root/Module_LcmControl &");
+			}
+			if (count_doComm < _SYSTEM_TASK_COUNT_DOCOMM )
+			{
+				system("killall Module_DoComm");
+				sleep(3);
+				system("/root/Module_DoComm &");
+			}
+			if (count_produceComm < _SYSTEM_TASK_COUNT_PRODUCEUTILS )
+			{
+				system("killall Module_ProduceUtils");
+				sleep(3);
+				system("/root/Module_ProduceUtils &");
+			}
+			/*
+			if (count_psuComm < 2)
+			{
+				system("killall Module_PsuComm");
+				sleep(3);
+				system("/root/Module_PsuComm &");
+			}*/
+		}
+
+		sleep(2);
+	}
+
+	if (count_main < _SYSTEM_TASK_COUNT_MAIN)
+		result = _SYSTEM_TASK_LOST_ITEM_MAIN;
+	else if (count_evComm < _SYSTEM_TASK_COUNT_EVCOMM)
+		result = _SYSTEM_TASK_LOST_ITEM_EVCOMM;
+/*	else if (count_psuComm < 2)
+		result = 3; */
+    else if (count_eventComm < _SYSTEM_TASK_COUNT_EVENTLOGGING )
+        result = _SYSTEM_TASK_LOST_ITEM_EVENTLOG;
+    else if (count_primaryComm < _SYSTEM_TASK_COUNT_PRIMARYCOMM)
+        result = _SYSTEM_TASK_LOST_ITEM_PRIMARYCOMM;
+    else if (count_lcmComm < _SYSTEM_TASK_COUNT_LCM)
+        result = _SYSTEM_TASK_LOST_ITEM_LCMCONTROL;
+    else if (count_interComm < 2 )
+        result = _SYSTEM_TASK_LOST_ITEM_INTERCOMM;
+    else if (count_doComm < _SYSTEM_TASK_COUNT_DOCOMM)
+        result = _SYSTEM_TASK_LOST_ITEM_DOCOMM;
+    else if (count_produceComm < _SYSTEM_TASK_COUNT_PRODUCEUTILS)
+        result = _SYSTEM_TASK_LOST_ITEM_PRODUCTUTILS;
+
+	return result;
+}

+ 60 - 0
EVSE/Projects/DD360Audi/Apps/CSU/CheckSystemTask.h

@@ -0,0 +1,60 @@
+/*
+ * CheckTask.h
+ *
+ *  Created on: 2021年9月2日
+ *      Author: 7564
+ */
+
+#ifndef CHECKTASK_H_
+#define CHECKTASK_H_
+
+#include 	<sys/timeb.h>
+#include 	<sys/types.h>
+#include 	<sys/ioctl.h>
+#include 	<sys/socket.h>
+#include 	<sys/ipc.h>
+#include 	<sys/shm.h>
+#include 	<sys/mman.h>
+#include 	<linux/wireless.h>
+#include 	<arpa/inet.h>
+#include 	<netinet/in.h>
+
+#include 	<unistd.h>
+#include 	<stdarg.h>
+#include    <stdio.h>      /*標準輸入輸出定義*/
+#include    <stdlib.h>     /*標準函數庫定義*/
+#include    <unistd.h>     /*Unix 標準函數定義*/
+#include    <fcntl.h>      /*檔控制定義*/
+#include    <termios.h>    /*PPSIX 終端控制定義*/
+#include    <errno.h>      /*錯誤號定義*/
+#include 	<string.h>
+#include 	<stdint.h>
+#include	<time.h>
+#include	<ctype.h>
+#include 	<ifaddrs.h>
+#include 	<math.h>
+#include 	<stdbool.h>
+#include 	<dirent.h>
+
+#define _SYSTEM_TASK_LOST_ITEM_MAIN         1
+#define _SYSTEM_TASK_LOST_ITEM_EVCOMM       2
+#define _SYSTEM_TASK_LOST_ITEM_EVENTLOG     3
+#define _SYSTEM_TASK_LOST_ITEM_PRIMARYCOMM  4
+#define _SYSTEM_TASK_LOST_ITEM_LCMCONTROL   5
+#define _SYSTEM_TASK_LOST_ITEM_INTERCOMM    6
+#define _SYSTEM_TASK_LOST_ITEM_DOCOMM       7
+#define _SYSTEM_TASK_LOST_ITEM_PRODUCTUTILS 8
+
+#define _SYSTEM_TASK_COUNT_MAIN             5
+#define _SYSTEM_TASK_COUNT_EVCOMM           2
+#define _SYSTEM_TASK_COUNT_INTERNALCOMM     2
+#define _SYSTEM_TASK_COUNT_EVENTLOGGING     1
+#define _SYSTEM_TASK_COUNT_PRIMARYCOMM      1
+#define _SYSTEM_TASK_COUNT_LCM              1
+#define _SYSTEM_TASK_COUNT_DOCOMM           1
+#define _SYSTEM_TASK_COUNT_PRODUCEUTILS     1
+
+
+unsigned char CheckSystemTask(unsigned char systemPage);
+
+#endif /* CHECKSYSTEMTASK_H_ */

+ 12 - 0
EVSE/Projects/DD360Audi/Apps/CSU/Primary.c

@@ -136,11 +136,15 @@ void PrimaryLedIndicatorCtrlFork(void)
 
                 case S_CHARGING:
                     pLedConfig->RedLED = NO;
+#ifdef DD360ComBox
                     if (pLedConfig->YellowLED == YES) {
                         pLedConfig->YellowLED = NO;
                     } else {
                         pLedConfig->YellowLED = YES;
                     }
+#else
+                        pLedConfig->YellowLED = YES;
+#endif
                     pLedConfig->GreenLED = NO;
                     break;
 
@@ -166,7 +170,15 @@ void PrimaryLedIndicatorCtrlFork(void)
                     //    pLedConfig->RedLED = YES;
                     //} else {
                     pLedConfig->RedLED = NO;
+#ifdef DD360ComBox
                     pLedConfig->YellowLED = YES;
+#else
+                    if (pLedConfig->YellowLED == YES) {
+                        pLedConfig->YellowLED = NO;
+                    } else {
+                        pLedConfig->YellowLED = YES;
+                    }
+#endif
                     pLedConfig->GreenLED = NO;
                     //}
                     break;

+ 15 - 0
EVSE/Projects/DD360Audi/Apps/CSU/SelfTest.c

@@ -18,6 +18,7 @@ extern void ChkPrimaryStatus(void);
 void SelfTestRun(void)
 {
     bool evInitFlag = false;
+    bool isRelayBypass = false;
     uint8_t index = 0;
     struct SysConfigData *pSysConfig = (struct SysConfigData *)GetShmSysConfigData();
     struct SysInfoData *pSysInfo = (struct SysInfoData *)GetShmSysInfoData();
@@ -34,6 +35,15 @@ void SelfTestRun(void)
     struct ChargingInfoData *pDcChargingInfo = NULL;
     struct ChargingInfoData *pAcChargingInfo = NULL;
 
+    for(int i = 0; i < pSysConfig->TotalConnectorCount; i++)
+    {
+        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
+        if(pDcChargingInfo->PantographFlag == YES)
+        {
+            isRelayBypass = true;
+        }
+    }
+
     StartSystemTimeoutDet(Timeout_SelftestChk);
     pSysInfo->SelfTestSeq = _STEST_VERSION;
 
@@ -62,6 +72,11 @@ void SelfTestRun(void)
 
         switch (pSysInfo->SelfTestSeq) {
         case _STEST_VERSION:
+            if(isRelayBypass == YES && ShmRelayModuleData->SelfTest_Comp != YES)
+            {
+                log_info("Relay Board Bypass");
+                ShmRelayModuleData->SelfTest_Comp = YES;
+            }
             if ((strlen((char *)pSysInfo->RelayModuleFwRev) != 0 ||
                     pSysInfo->RelayModuleFwRev[0] != '\0') &&
                     (ShmRelayModuleData->SelfTest_Comp != YES)

+ 8 - 0
EVSE/Projects/DD360Audi/Apps/CSU/UpgradeFW.c

@@ -12,6 +12,11 @@
 #include "../ShareMemory/shmMem.h"
 
 #include "main.h"
+//WatchDog.c
+extern void CreateWatchdog(void);
+extern void TryCloseWatchdog(void);
+extern void TryFeedWatchdog(void);
+
 
 //------------------------------------------------------------------------------
 static char *_priPortName = "/dev/ttyS1";
@@ -325,6 +330,8 @@ void CheckFwUpdateFunction(void)
     //log_info("pSysInfo->FirmwareUpdate = %d \n", pSysInfo->FirmwareUpdate);
     if (pSysInfo->FirmwareUpdate == YES) {
         log_info("ftp : update start. \n");
+        TryCloseWatchdog();
+
         for (uint8_t gun_index = 0; gun_index < pSysConfig->TotalConnectorCount; gun_index++) {
             setChargerMode(gun_index, MODE_UPDATE);
         }
@@ -352,6 +359,7 @@ void CheckFwUpdateFunction(void)
 
         if (strcmp((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, "Downloaded") == EQUAL) {
             log_info("Backend : update start. \n");
+            TryCloseWatchdog();
             strcpy((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, "");
             strcpy((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, "Installing");
             ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = YES;

+ 39 - 17
EVSE/Projects/DD360Audi/Apps/CSU/WatchDog.c

@@ -8,41 +8,63 @@
 #include "../Define/define.h"
 #include "../ShareMemory/shmMem.h"
 
-//------------------------------------------------------------------------------
-static int gWatchDogfd = -1;
+int wtdFd = -1;
+struct StatusCodeData           *ShmStatusCodeData;
 
-//------------------------------------------------------------------------------
-void WriteWatchDogState(char *value)
-{
-    write(gWatchDogfd, value, 1);
-}
+void CreateWatchdog(void);
+void TryCloseWatchdog(void);
+void TryFeedWatchdog(void);
 
-static int initWatchDog(void)
+int InitWatchDog()
 {
     int fd;
+    int timeout = 180;
+
     system("/usr/bin/fuser -k /dev/watchdog");
     sleep(1);
     system("echo V > /dev/watchdog");
     sleep(1);
-    fd = open("/dev/watchdog", O_RDWR);
+    fd=open("/dev/watchdog", O_RDWR);
 
-    if (fd <= 0) {
+    if(fd<=0)
+    {
         log_error("System watch dog initial fail.\r\n");
     }
+    ioctl(fd, _IOWR('W', 6, int), &timeout);
 
     return fd;
 }
 
 void CreateWatchdog(void)
 {
-    struct SysConfigData *pSysConfig = (struct SysConfigData *)GetShmSysConfigData();
-    struct AlarmCodeData *pAlarmCode = (struct AlarmCodeData *)GetShmAlarmCodeData();
+    wtdFd = InitWatchDog();
+
+    ShmStatusCodeData = (struct StatusCodeData*)GetShmStatusCodeData();
+    if(wtdFd < 0)
+    {
+        log_info("Watchdog Initial Fail");
+        ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1;
+    }
+    else
+    {
+        log_info("Watchdog Initial Success");
+    }
+}
 
-    if (pSysConfig->SwitchDebugFlag == NO) {
-        gWatchDogfd = initWatchDog();
+void TryCloseWatchdog(void)
+{
+    if(wtdFd > 0)
+    {
+        write(wtdFd, "V", 1);
+        close(wtdFd);
+    }
+}
 
-        if (gWatchDogfd < 0) {
-            pAlarmCode->AlarmEvents.bits.CsuInitFailed = 1;
-        }
+void TryFeedWatchdog(void)
+{
+    if(wtdFd > 0)
+    {
+        write(wtdFd, "a", 1);
     }
 }
+

+ 48 - 0
EVSE/Projects/DD360Audi/Apps/CSU/WatchDog.c.old

@@ -0,0 +1,48 @@
+#include <stdio.h>      /*標準輸入輸出定義*/
+#include <stdlib.h>     /*標準函數庫定義*/
+#include <string.h>
+#include <stdint.h>
+
+#include "../Config.h"
+#include "../Log/log.h"
+#include "../Define/define.h"
+#include "../ShareMemory/shmMem.h"
+
+//------------------------------------------------------------------------------
+static int gWatchDogfd = -1;
+
+//------------------------------------------------------------------------------
+void WriteWatchDogState(char *value)
+{
+    write(gWatchDogfd, value, 1);
+}
+
+static int initWatchDog(void)
+{
+    int fd;
+    system("/usr/bin/fuser -k /dev/watchdog");
+    sleep(1);
+    system("echo V > /dev/watchdog");
+    sleep(1);
+    fd = open("/dev/watchdog", O_RDWR);
+
+    if (fd <= 0) {
+        log_error("System watch dog initial fail.\r\n");
+    }
+
+    return fd;
+}
+
+void CreateWatchdog(void)
+{
+    struct SysConfigData *pSysConfig = (struct SysConfigData *)GetShmSysConfigData();
+    struct AlarmCodeData *pAlarmCode = (struct AlarmCodeData *)GetShmAlarmCodeData();
+
+    if (pSysConfig->SwitchDebugFlag == NO) {
+        gWatchDogfd = initWatchDog();
+
+        if (gWatchDogfd < 0) {
+            pAlarmCode->AlarmEvents.bits.CsuInitFailed = 1;
+        }
+    }
+}

+ 145 - 20
EVSE/Projects/DD360Audi/Apps/CSU/main.c

@@ -29,6 +29,7 @@
 #include <math.h>
 #include <stdbool.h>
 #include <dirent.h>
+#include <signal.h>
 
 #include "../Config.h"
 #include "main.h"
@@ -40,6 +41,7 @@
 #include "../Define/define.h"
 #include "../ShareMemory/shmMem.h"
 #include "../SelectGun/SelectGun.h"
+#include "CheckSystemTask.h"
 
 //------------------------------------------------------------------------------
 static struct SysInfoData *pSysInfo = NULL;
@@ -71,13 +73,16 @@ static SelectGunInfo *ShmSelectGunInfo = NULL; //Jerry add
 static EvBoardErrMsg gEvBoardErr = {0};
 static ChillerTempErr gChillerTempErr = {0};
 
+struct SysConfigAndInfo         *ShmSysConfigAndInfo;
+struct StatusCodeData           *ShmStatusCodeData;
+
 // for initial index to check EV board type is correct
 uint8_t bd0_1_status = 0;
 uint8_t bd0_2_status = 0;
 uint8_t bd1_1_status = 0;
 uint8_t bd1_2_status = 0;
 
-char *fwVersion = "V1.13.00.0000.00"; // "V0.16.00.0000.00";
+char *fwVersion = "V1.15.00.0000.00"; // "V0.16.00.0000.00";
 
 //sqlite3 *localDb;
 bool isDb_ready;
@@ -89,6 +94,8 @@ long long DiffTimebWithNow(struct timeb ST);
 uint8_t DetectBitValue(uint8_t _byte, uint8_t _bit);
 void SetBitValue(uint8_t *_byte, uint8_t _bit, uint8_t value);
 unsigned long GetTimeoutValue(struct timeval _sour_time);
+void GetClockTime(struct timespec *_now_time, void *null);
+unsigned long GetClockTimeoutValue(struct timespec _start_time);
 void gpio_set_value(unsigned int gpio, unsigned int value);
 void InformOcppErrOccur(uint8_t codeType);
 
@@ -121,7 +128,8 @@ extern void GetMacAddress(void);
 
 //WatchDog.c
 extern void CreateWatchdog(void);
-extern void WriteWatchDogState(char *value);
+extern void TryCloseWatchdog(void);
+extern void TryFeedWatchdog(void);
 
 //ZipFile.c
 extern void zipLogFiles(void);
@@ -753,6 +761,24 @@ unsigned long GetTimeoutValue(struct timeval _sour_time)
     return 1000000 * (_end_time.tv_sec - _sour_time.tv_sec) + _end_time.tv_usec - _sour_time.tv_usec;
 }
 
+void GetClockTime(struct timespec *_now_time, void *null)
+{
+    clock_gettime(CLOCK_MONOTONIC, _now_time);
+}
+
+// return value unit: 1us
+unsigned long GetClockTimeoutValue(struct timespec _start_time)
+{
+    struct timespec ts_end;
+    unsigned long ret = 0;
+
+    clock_gettime(CLOCK_MONOTONIC, &ts_end);
+
+    ret = ((unsigned long)(ts_end.tv_sec - _start_time.tv_sec) * 1000000) + ((unsigned long)((ts_end.tv_nsec / 1000) - (_start_time.tv_nsec/ 1000)));
+
+    return ret;
+}
+
 int DiffTimeb(struct timeb ST, struct timeb ET)
 {
     //return milli-second
@@ -1611,7 +1637,11 @@ void _DetectPlugInTimeout(void)
     ClearDetectPluginFlag();
 
     sleep(1); //等待DoComm回報插槍訊號給主櫃
-
+#if defined DD360Audi || DD360 || DD360Combox
+	    //pSysInfo->SystemPage = _LCM_COMPLETE;
+		setChargerMode(pSysInfo->CurGunSelected, S_TERMINATING);
+	    return;
+#endif
     systemPageRestoreInit();
 }
 
@@ -1641,7 +1671,12 @@ void _DetectEvseChargingEnableTimeout(uint8_t gunIndex)
     log_info("*********** _DetectEvseChargingEnableTimeout (GFD timeout) ***********\n");
     //if (chargingInfo[gunIndex]->GroundFaultStatus != GFD_PASS)
     {
+#if defined DD360Audi || DD360 || DD360Combox
+        pSysInfo->SystemPage = _LCM_COMPLETE;
+        setChargerMode(gunIndex, S_TERMINATING);
+#else
         setChargerMode(gunIndex, MODE_IDLE);
+#endif
         _AutoReturnTimeout();
     }
 }
@@ -1649,7 +1684,12 @@ void _DetectEvseChargingEnableTimeout(uint8_t gunIndex)
 void _PrepareTimeout(uint8_t gunIndex)
 {
     log_info("*********** _PrepareTimeout ***********\n");
-    setChargerMode(gunIndex, MODE_IDLE);
+#if defined DD360Audi || DD360 || DD360Combox
+        pSysInfo->SystemPage = _LCM_COMPLETE;
+        setChargerMode(gunIndex, S_TERMINATING);
+#else
+     setChargerMode(gunIndex, MODE_IDLE);
+#endif
     pAlarmCode->AlarmEvents.bits.PsuNoResource = YES;
     _AutoReturnTimeout();
 }
@@ -1657,9 +1697,76 @@ void _PrepareTimeout(uint8_t gunIndex)
 void _CcsPrechargeTimeout(uint8_t gunIndex)
 {
     log_info("*********** _CcsPrechargeTimeout ***********\n");
-    setChargerMode(gunIndex, MODE_IDLE);
+#if defined DD360Audi || DD360 || DD360Combox
+        pSysInfo->SystemPage = _LCM_COMPLETE;
+        setChargerMode(gunIndex, S_TERMINATING);
+#else
+     setChargerMode(gunIndex, MODE_IDLE);
+#endif
 }
 
+//===============================================
+// Check System Task alive
+// ==============================================
+void CheckSystemTaskAlive()
+{
+    unsigned char lostId = CheckSystemTask(ShmSysConfigAndInfo->SysInfo.SystemPage);
+    if (lostId != 0) {
+        log_info("Check task(%d) lost\n",lostId);
+        if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemTaskLost == NO) {
+           if (lostId == _SYSTEM_TASK_LOST_ITEM_MAIN)
+               log_info("System task lost (CSU). \n");
+           else if (lostId == _SYSTEM_TASK_LOST_ITEM_EVCOMM)
+               log_info("System task lost (EVComm). \n");
+//           else if (lostId == _SYSTEM_TASK_LOST_ITEM_PSUCOMM)
+//               PRINTF_FUNC("System task lost (PSU Task). \n");
+           else if (lostId == _SYSTEM_TASK_LOST_ITEM_EVENTLOG)
+               log_info("System task lost (Event log). \n");
+           else if (lostId == _SYSTEM_TASK_LOST_ITEM_PRIMARYCOMM)
+               log_info("System task lost (Primary). \n");
+           else if (lostId == _SYSTEM_TASK_LOST_ITEM_LCMCONTROL)
+               log_info("System task lost (LCM Comm). \n");
+           else if (lostId == _SYSTEM_TASK_LOST_ITEM_INTERCOMM)
+               log_info("System task lost (Internal Comm). \n");
+           else if (lostId == _SYSTEM_TASK_LOST_ITEM_DOCOMM)
+               log_info("System task lost (Do Comm). \n");
+           else if (lostId == _SYSTEM_TASK_LOST_ITEM_PRODUCTUTILS)
+               log_info("System task lost (ProcductUtils Comm). \n");
+           ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemTaskLost = YES;
+        }
+    } else
+        ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemTaskLost = NO;
+}
+
+void CreateCheckSystemTaskFork()
+{
+    pid_t taskPid;
+    taskPid = fork();
+    if (taskPid == 0)
+    {
+        while(true)
+        {
+			/*
+			for (int _index = 0; _index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; _index++)
+			{
+				if (chargingInfo[_index]->SystemStatus == SYS_MODE_UPDATE ||
+						chargingInfo[_index]->Type == 0x09)
+				{
+					stopToDet = true;
+					continue;
+				}
+			}
+			*/
+			for (uint8_t gun = 0; gun < pSysConfig->TotalConnectorCount; gun++) {
+				pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gun);
+				if (pDcChargingInfo->SystemStatus == SYS_MODE_UPDATE )
+						continue;
+			}
+			CheckSystemTaskAlive();
+			sleep(5);
+		}
+	}
+}
 //===============================================
 // 取得卡號與卡號驗證
 //===============================================
@@ -2510,6 +2617,7 @@ bool CheckConnectorTypeStatus(void)
             return false;
         }
 
+		pDcChargingInfo->SystemStatus = S_BOOTING;
         switch (gunIndex) {
         case 0:
             if (pSysConfig->TotalConnectorCount == 1) {
@@ -2645,14 +2753,14 @@ void KillAllTask(void)
 void StartSystemTimeoutDet(uint8_t flag)
 {
     if (pSysInfo->SystemTimeoutFlag != flag) {
-        gettimeofday(&pSysInfo->SystemTimeoutTimer, NULL);
+        GetClockTime(&pSysInfo->SystemTimeoutTimer, NULL);
     }
     pSysInfo->SystemTimeoutFlag = flag;
 }
 
 void StopSystemTimeoutDet(void)
 {
-    gettimeofday(&pSysInfo->SystemTimeoutTimer, NULL);
+    GetClockTime(&pSysInfo->SystemTimeoutTimer, NULL);
     pSysInfo->SystemTimeoutFlag = Timeout_None;
 }
 
@@ -2724,7 +2832,7 @@ void CreateTimeoutFork(void)
             // 系統
             switch (pSysInfo->SystemTimeoutFlag) {
             case Timeout_SelftestChk:
-                if (GetTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= SELFTEST_TIMEOUT) {
+                if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= SELFTEST_TIMEOUT) {
                     _SelfTestTimeout();
                     StopSystemTimeoutDet();
                     destroySelGun(DESTROY_ALL_SEL); //jerry add
@@ -2732,7 +2840,7 @@ void CreateTimeoutFork(void)
                 break;
 
             case Timeout_Authorizing:
-                if (GetTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= AUTHORIZE_TIMEOUT) {
+                if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= AUTHORIZE_TIMEOUT) {
                     _AuthorizedTimeout();
                     StopSystemTimeoutDet();
                     destroySelGun(pSysInfo->CurGunSelected);
@@ -2748,7 +2856,7 @@ void CreateTimeoutFork(void)
                 break;
 
             case Timeout_VerifyFail:
-                if (GetTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= AUTHORIZE_FAIL_TIMEOUT) {
+                if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= AUTHORIZE_FAIL_TIMEOUT) {
                     _AutoReturnTimeout();
                     StopSystemTimeoutDet();
                     destroySelGun(pSysInfo->CurGunSelected);
@@ -2764,14 +2872,14 @@ void CreateTimeoutFork(void)
                 break;
 
             case Timeout_VerifyComp:
-                if (GetTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= AUTHORIZE_COMP_TIMEOUT) {
+                if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= AUTHORIZE_COMP_TIMEOUT) {
                     _AutoReturnTimeout();
                     StopSystemTimeoutDet();
                 }
                 break;
 
             case Timeout_WaitPlug:
-                if (GetTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= _connectionTimeout) {
+                if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= _connectionTimeout) {
                     _DetectPlugInTimeout();
                     StopSystemTimeoutDet();
                     destroySelGun(pSysInfo->CurGunSelected);
@@ -2779,7 +2887,7 @@ void CreateTimeoutFork(void)
                 break;
 
             case Timeout_ReturnToChargingGunDet:
-                if (GetTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= RETURN_TO_CHARGING_PAGE) {
+                if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= RETURN_TO_CHARGING_PAGE) {
 #if defined DD360Audi
                     if (getCurLcmPage() != _LCM_PRE_CHARGE &&
                             getCurLcmPage() != _LCM_CHARGING &&
@@ -2794,7 +2902,7 @@ void CreateTimeoutFork(void)
                 break;
 
             case Timeout_AuthorizingForStop:
-                if (GetTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= AUTHORIZE_STOP_TIMEOUT) {
+                if (GetClockTimeoutValue(pSysInfo->SystemTimeoutTimer) / uSEC_VAL >= AUTHORIZE_STOP_TIMEOUT) {
                     strcpy((char *)pSysConfig->UserId, "");
                     ClearAuthorizedFlag();
                     StopSystemTimeoutDet();
@@ -2950,6 +3058,7 @@ void CheckOcppStatus(void)
                 sleep(3);
                 system("killall OcppBackend &");
                 KillAllTask();
+                TryCloseWatchdog();
                 system("/usr/bin/run_evse_restart.sh");
             }
         }
@@ -3329,6 +3438,7 @@ void StopProcessingLoop()
                 log_info("Soft reboot for retry self-tets (Primary). \n");
                 KillAllTask();
                 sleep(3);
+                TryCloseWatchdog();
                 system("/usr/bin/run_evse_restart.sh");
                 return;
             }
@@ -3400,10 +3510,11 @@ void CheckTask()
 #endif //0
 
     /*--- 20200908, vern, disable it for DD360 ---*/
+    /*
     if (system("pidof -s Module_ProduceUtils > /dev/null") != 0) {
         log_error("Module_ProduceUtils not running, restart it.\r\n");
         system ("/root/Module_ProduceUtils &");
-    }
+    }*/
 }
 
 //==========================================
@@ -4139,6 +4250,9 @@ int main(void)
     ShmOCPP16Data = (struct OCPP16Data *)GetShmOCPP16Data();
     ShmDcCommonData = (DcCommonInfo *)GetShmDcCommonData();
     ShmSelectGunInfo = (SelectGunInfo *)GetShmSelectGunInfo();
+	
+    ShmSysConfigAndInfo = (struct SysConfigAndInfo *)GetShmSysConfigAndInfo();
+    ShmStatusCodeData = (struct StatusCodeData *)GetShmStatusCodeData();	
 
     log_info(" ****************  FileSystem Boot up ***************\n");
     if (!InitialSystemDefaultConfig()) {
@@ -4236,8 +4350,6 @@ int main(void)
     // 1. Thernal - 控制風扇轉速
     // 2. ouput fuse - 控制風扇轉速
     CreateRfidFork();
-    // Create Watchdog
-    //CreateWatchdog();
     // Main loop
 
     log_info("===== Charger info ===== ");
@@ -4249,6 +4361,12 @@ int main(void)
 
     GunIndexInfo *pGunIndexInfo = (GunIndexInfo *)GetGunIndexInfo();
 
+    //signal(SIGCHLD,SIG_IGN);
+
+	CreateCheckSystemTaskFork();
+
+    CreateWatchdog();
+
     for (;;) {
         CheckOcppStatus();
 
@@ -4283,7 +4401,7 @@ int main(void)
         }
 
         if ((GetTimeoutValue(_cmdMainPriority_time) / 1000) > 5000) {
-            CheckTask();
+            //CheckTask();
 
             for (gunIndex = 0; gunIndex < pSysConfig->TotalConnectorCount; gunIndex++) {
                 pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(gunIndex);
@@ -4545,6 +4663,9 @@ int main(void)
                 if (pSysInfo->CurGunSelected == gunIndex) {
                     pSysInfo->ConnectorPage = _LCM_PRE_CHARGE;
                 }
+#ifdef DD360Audi
+				pDcChargingInfo->Replug_flag = true;
+#endif
             }
             break;
 
@@ -4822,6 +4943,9 @@ int main(void)
                 if (pSysInfo->CurGunSelected == gunIndex) {
                     pSysInfo->ConnectorPage = _LCM_CHARGING;
                 }
+#ifdef DD360Audi
+				pDcChargingInfo->Replug_flag = false;
+#endif
                 break;
 
             case S_ALARM:
@@ -4996,7 +5120,7 @@ int main(void)
                 // 切換 D+ Relay to Precharge Relay
                 if (isPrechargeStatus_ccs(gunIndex) == 39 ||
                         isPrechargeStatus_ccs(gunIndex) == 40) {
-                    if (pDcChargingInfo->RelayKPK2Status == YES &&
+                    if ((pDcChargingInfo->RelayKPK2Status == YES || pDcChargingInfo->PantographFlag == YES) &&
                             pDcChargingInfo->PrechargeStatus != PRECHARGE_READY)
                         //if (pDcChargingInfo->PrechargeStatus != PRECHARGE_PRERELAY_PASS)
                     {
@@ -5041,7 +5165,7 @@ int main(void)
 
                 // 等待小板通知進入充電
                 // 切換 D+ Relay to Precharge Relay
-                if (pDcChargingInfo->RelayK1K2Status == YES) {
+                if (pDcChargingInfo->RelayK1K2Status == YES || pDcChargingInfo->PantographFlag == YES) {
                     pDcChargingInfo->PrechargeStatus = PRECHARGE_READY;
                     setChargerMode(gunIndex, MODE_CHARGING);
                 }
@@ -5051,6 +5175,7 @@ int main(void)
                 }
                 break;
             }//switch
+            TryFeedWatchdog();
         }//for
 
 #if defined DD360Audi

+ 106 - 82
EVSE/Projects/DD360Audi/Apps/Define/define.h

@@ -176,6 +176,11 @@ Storage							0x0A200000-0x7FFFFFFF		1886 MB
 /**************************************************************************************/
 /****************** Share memory configuration value constant define ******************/
 /**************************************************************************************/
+struct NoneUse
+{
+    unsigned char       unknown;                    // None use struct
+};
+
 enum SYSTEM_STATUS
 {
 	SYS_MODE_BOOTING		= 0,
@@ -287,7 +292,7 @@ enum CoreProfile {
 	 TransactionMessageRetryInterval,
 	 UnlockConnectorOnEVSideDisconnect,
 	 WebSocketPingInterval,
-	 QueueOffLineStartTransactionMessage,
+	 QueueOffLineMeterValues,
 	 AuthorizationKey,
 	 SecurityProfile,
      DefaultPrice,
@@ -304,15 +309,21 @@ enum OCPP_RUNNING_VERSION {
     OCPP_RUNNING_VERSION_16=0,
     OCPP_RUNNING_VERSION_20
 };
+
+enum OCPP_START_ID_TYPE {
+    IdTokenType_Central=0,
+    IdTokenType_eMAID,
+    IdTokenType_ISO14443,
+    IdTokenType_KeyCode,
+    IdTokenType_Local,
+    IdTokenType_NoAuthorization,
+    IdTokenType_ISO15693
+};
 /**************************************************************************************/
 /****structure SysConfigData => shall store the data to NAND flash****************/
 /****structure SysInfoData => shall NOT store the data to NAND flash***************/
 /****according to System Configuration and Information Table.xlsx Rev.0.2 *******/
 /**************************************************************************************/
-struct NoneUse
-{
-	unsigned char		unknown;					// None use struct
-};
 
 struct EthConfigData
 {
@@ -454,9 +465,9 @@ typedef struct
     unsigned int isCalibratedCaOffset:1;                // Current phase a offset is calibrated, 0: default 1: Calibrated
     unsigned int isCalibratedCbOffset:1;                // Current phase b offset is calibrated, 0: default 1: Calibrated
     unsigned int isCalibratedCcOffset:1;                // Current phase c offset is calibrated, 0: default 1: Calibrated
-    unsigned int isCalibratedPa:1;                      // Phase angle a is calibrated, 0: default  1: Calibrated
-    unsigned int isCalibratedPb:1;                      // Phase angle b gain is calibrated, 0: default 1: Calibrated
-    unsigned int isCalibratedPc:1;                      // Phase angle c gain is calibrated, 0: default 1: Calibrated
+    unsigned int isCalibratedPa:1;                      // Phase angle a is calibrated, 0: default          1: Calibrated
+    unsigned int isCalibratedPb:1;                      // Phase angle b gain is calibrated, 0: default     1: Calibrated
+    unsigned int isCalibratedPc:1;                      // Phase angle c gain is calibrated, 0: default     1: Calibrated
     unsigned int :1;
 }MeterIcCalibration;
 
@@ -515,8 +526,8 @@ struct SysConfigData
 	unsigned char 			OcppServerURL[512];			//http: non-secure OCPP 1.5-S, https: secure OCPP 1.5-S, ws: non-secure OCPP 1.6-J, wss: secure OCPP 1.6-J"
 	unsigned char 			ChargeBoxId[128];
 	unsigned char			chargePointVendor[20];		//the Vendor of the ChargePoint
-	unsigned char			OcppSecurityProfile;		//OCPP security profile 0~3
-	unsigned char			OcppSecurityPassword[41];	//OCPP AuthorizationKey for security profile
+    unsigned char           OcppSecurityProfile;        //OCPP security profile 0~3
+    unsigned char           OcppSecurityPassword[41];   //OCPP AuthorizationKey for security profile
 	unsigned int 			Checksum;					//4 bytes checksum
 	struct LED				LedInfo;					// LED configuration info
 	unsigned char			ShowInformation;
@@ -544,14 +555,14 @@ struct ChargingInfoData
 	unsigned char 		IsAvailable;
 	float MaximumChargingVoltage;	// unit 0.1V
 	float AvailableChargingCurrent;	// unit 0.1A
-	float AvailableChargingPower;	// unit .01kW
+	float AvailableChargingPower;	// unit 0.1kW
 	float DividChargingCurrent;		//0~6553.5 amp
-	float DeratingChargingCurrent;  //0~6553.5 amp
-	float DeratingChargingPower;	//0~6553.5 kW
+	float DeratingChargingCurrent;  // unit 0.1A
+	float DeratingChargingPower;	// unit 0.1kW
 	float FuseChargingVoltage;		//0~6553.5 volt
 	float FireChargingVoltage;		//0~6553.5 volt
-	float PresentChargingVoltage;	//0~6553.5 volt
-	float PresentChargingCurrent;		//0~6553.5 amp
+	float PresentChargingVoltage;   // unit: 1V
+	float PresentChargingCurrent;   // unit: 1A
 	float PresentChargingPower;		//0~6553.5 kW
 	float PresentChargedEnergy;		//0~6553.5 kWh
 	int PresentChargedDuration;	// second
@@ -566,17 +577,18 @@ struct ChargingInfoData
 	unsigned char PilotState;//1:state A, 2:State B1, 3:State B2, 4:State C, 5:State D, 6:State E, 7:State F, 8: Pilot error
 	unsigned char PilotDuty;					// 0~100%
 	unsigned char			StartUserId[32];			// This ID is trigger start charging event user by RFID, back-end, BLE.
+	unsigned char           StartIdType;                // 0: Central   1: eMAID    2: ISO14443 3: ISO15693 4: KeyCode  5: Local    6: MaxAddress   7: NoAuthorization
 	unsigned char			StartDateTime[32];			// Charging cycle start date time
 	unsigned char			StopDateTime[32];			// Charging cycle stop date time
 	unsigned char			StartMethod;
 	float					ChargingFee;
 	// Connector Temp
 	unsigned char 		ConnectorTemp;			//0x00: -60¢XC  ~  0xFE: 194
-	//Chiller Temp
+    //Chiller Temp
     unsigned char       ChillerTemp;            //0x00: -60¢XC  ~  0xFE: 194
 	// Charging Status
 	unsigned char 		GroundFaultStatus;		// for GFD result => 0x00 : None, 0x01 : Can Start Charging, 0x02 : Stop Charging
-	unsigned short		RealRatingPower;
+	unsigned short		RealRatingPower;        // unit: 0.1kW
 	unsigned char 		RelayWeldingCheck;		// 0 : No Comp., 1 : Comp.
 	unsigned char 		PrechargeStatus;		// for ccs precharge => 0x00 : None defined, 0x01 : Accepted
 	float 				PowerConsumption;		// This contains the meter value (Power Consumption) kWh
@@ -590,7 +602,7 @@ struct ChargingInfoData
 	unsigned char		AcCcsChargingMode;				// 0:BC (PWM) only, 1:BC & PLC mixed
 	unsigned short		SampleChargingCur[10];
 
-	/**************Alston for AC***************/
+	/************** Alston ***************/
 	unsigned char 		SelfTest_Comp;
 	unsigned char		version[16];
 	unsigned char 		IsModeChagned;
@@ -603,7 +615,7 @@ struct ChargingInfoData
 	unsigned char 		ConnectorAlarmCode[7];
 	unsigned char 		EvConnAlarmCode[7];
 	float 				ChargingProfileCurrent;			//0~6553.5 amp
-	float 				ChargingProfilePower;			//0~6553.5 kW
+	float 				ChargingProfilePower;			//0~6553.5 W
 	float 				PresentChargingVoltageL2;		//0~6553.5 volt
 	float 				PresentChargingVoltageL3;		//0~6553.5 volt
 	float 				PresentChargingCurrentL2;		//0~6553.5 amp	
@@ -616,11 +628,16 @@ struct ChargingInfoData
 	int 				EvBatteryStartSoc;				// 0~100%
 	unsigned char 		NormalStopChargeFlag;			// for EV board
 	ChargingStop        ChargingStopFlag;
-	char 				ReservedStartFlag;
-	float 				ConnectorMaxVoltage;			// 0~6553.5 volt
-	float 				ConnectorMaxCurrent;			// 0~6553.5 volt
-	unsigned char 		ModelType;
+    char                ReservedStartFlag;
+    float               ConnectorMaxVoltage;            // 0~6553.5 volt
+    float               ConnectorMaxCurrent;            // 0~6553.5 volt
+    unsigned char       ModelType;
     MeterIcCalibration  meterIcCalInfo;
+    float               PowerOffered;                   //0~6553.5 kW
+    float               CurrentOffered;                 //0~6553.5 amp
+    struct timespec     ConnectorTimeout;
+    unsigned char       PantographFlag;                 // 0: normal gun type,  1: pantograph gun type
+	unsigned char 		Replug_flag;
 };
 
 typedef union
@@ -772,7 +789,8 @@ typedef union
         unsigned int  AlarmStopRequest:1;               // 0: no effect,    1: connector alarm stop request                     ( dispenser -> cabinet)
         unsigned int  FaultStatusRequest:1;
         unsigned int  Disconnection:1;
-        unsigned int  res:10;
+        unsigned int  GfdDetection:1;                   // 0: stop,         1: start
+        unsigned int  res:9;
     }bits;
 }ConnectorParameter;
 
@@ -821,8 +839,8 @@ typedef union
         unsigned int AuthorizingCompleted:1;    // 0: not yet, 1: authorizing completed
         unsigned int DispenserDisconnection:1;  // 0: no connection,  1: dispenser connected
         unsigned int BackendAuthorized:1;       // 0: local authorized, 1: backend authorized
-        unsigned int WiringInfoChanged:1;       // 0: no effect, 1: wiring info has changed
-        unsigned int EnableWriteWiringInfo:1;   // 0: no effect, 1: enable write wiring info after timeout
+        unsigned int FlashConfigChanged:1;      // 0: no effect, 1: flash config has changed
+        unsigned int EnableWriteFlash:1;        // 0: no effect, 1: enable to write flash after timeout
         unsigned int CleanWiringInfo:1;         // 0: no effect, 1: clean wiring info
         unsigned int res:25;
     }bits;
@@ -905,6 +923,7 @@ struct SysInfoData
 	/**************Backend***************/
 	unsigned char 		OcppConnStatus;					//0: disconnected, 1: connected
 	char 				OrderCharging;
+    float               MaxChargingProfilePower;        //0~6553.5 W
 	/**************Alston***************/
 	unsigned char 		WaitForPlugit;					//0: none scan, 1: scanning
 	unsigned char 		PageIndex;						//0 : Initialize
@@ -923,7 +942,7 @@ struct SysInfoData
 	unsigned char 		FirmwareUpdate;					// 0 : none, 1 : update.
 	unsigned char 		AcContactorStatus;				// 0: disconnected, 1: connected
 	unsigned char 	 	SystemTimeoutFlag;				// 0 : none, 1 : self test
-	struct timeval		SystemTimeoutTimer;
+	struct timespec		SystemTimeoutTimer;
 	unsigned char 		SystemPage;
 	unsigned char 		ConnectorPage;
 	unsigned char		IsAlternatvieConf;				// 0 : normal, 1 : alternative
@@ -1124,8 +1143,8 @@ struct FaultCodeData
 			unsigned char BleModuleBroken:1;					//bit 2
 			unsigned char RotarySwitchFault:1;					//bit 3 
 			unsigned char CcsLiquidChillerWaterLevelFault:1;    //bit 4
-			unsigned char ChillerTempSensorBroken:1;            //bit 5
-			unsigned char :2;									//bit 6 ~ 7	reserved
+            unsigned char ChillerTempSensorBroken:1;            //bit 5
+            unsigned char :2;                                   //bit 6 ~ 7 reserved
 		}bits;
 	}FaultEvents;
 };
@@ -1257,9 +1276,9 @@ char AlarmStatusCode[128][6]=
     "012321",   // System CCS output UCP
     "012322",   // System GBT output UCP
     "012323",   // System Chiller output OTP
-    "012324",   // reserved
-    "012325",   // reserved
-    "012326",   // reserved
+    "012324",   // Connector 1 detects abnormal voltage on the output line
+    "012325",   // Connector 2 detects abnormal voltage on the output line
+    "012326",   // System task is lost
     "012327",   // reserved
 };
 */
@@ -1411,7 +1430,10 @@ struct AlarmCodeData
             unsigned char SystemCCSOutputUCP:1;                     //bit 1
             unsigned char SystemGBTOutputUCP:1;                     //bit 2
             unsigned char SystemChillerOTP:1;                       //bit 3
-            unsigned char Reserved:4;                               //bit 4~7
+            unsigned char AbnormalVoltageOnOutputLine_1:1;          //bit 4
+            unsigned char AbnormalVoltageOnOutputLine_2:1;          //bit 5
+            unsigned char SystemTaskLost:1;                         //bit 6
+            unsigned char Reserved:1;                               //bit 7
 		}bits;
 	}AlarmEvents;
 };
@@ -2148,8 +2170,8 @@ struct PsuModuleData
 	unsigned short 	InputCurrentL3;		//abcd=abc.d amp
 	unsigned short 	PresentOutputVoltage;	//abcd=abc.d volt
 	unsigned short 	PresentOutputCurrent;	//abcd=abc.d amp
-	unsigned short 	AvailableCurrent;		//abcd=abc.d amp
-	unsigned int 		AvailablePower;		//abcd=abc.d kWatt
+	unsigned short 	AvailableCurrent;		// unit: 0.1A
+	unsigned int 		AvailablePower;		// unit: 0.1kW
 	char 				CriticalTemp1;			//0x00: -60¢XC  ~  0xFE: 194¢XC, resolution: 1¢XC, offset: -60¢XC, 0xFF: invalid
 	char 				CriticalTemp2;			//0x00: -60¢XC  ~  0xFE: 194¢XC, resolution: 1¢XC, offset: -60¢XC, 0xFF: invalid
 	char 				CriticalTemp3;			//0x00: -60¢XC  ~  0xFE: 194¢XC, resolution: 1¢XC, offset: -60¢XC, 0xFF: invalid
@@ -2160,7 +2182,7 @@ struct PsuModuleData
 	char 				OutletTemp;			//0x00: -60¢XC  ~  0xFE: 194¢XC, resolution: 1¢XC, offset: -60¢XC, 0xFF: invalid
 	unsigned int 		AlarmCode;
 	unsigned int 		FaultCode;			//
-	unsigned int 		IAvailableCurrent;		//abcd=abc.d amp
+	unsigned int 		IAvailableCurrent;		            // unit: 0.1A
 };
 
 /*Following are the information for each PSU Group*/
@@ -2170,12 +2192,12 @@ struct PsuGroupData
 	unsigned char           GroupOutputPowerSwitch;         //0: D.D normal OFF,  1: D.D emergency OFF,  2: D.D ON
 	unsigned short          GroupTargetOutputVoltage;       //abcd=abc.d volt
 	unsigned short          GroupTargetOutputCurrent;       //abcd=abc.d amp
-	unsigned short          GroupAvailableCurrent;          //abcd=abc.d amp
-	unsigned int            GroupAvailablePower;            //abcd=abc.d kWatt
-	unsigned int            GroupRealOutputPower;           //Watt
-	unsigned short          GroupPresentOutputVoltage; 	    //abcd=abc.d volt
-	unsigned short          GroupPresentOutputCurrent;      //abcd=abc.d Amps
-	unsigned int            GroupPresentOutputPower;        //Watt
+	unsigned short          GroupAvailableCurrent;          // unit: 0.1A
+	unsigned int            GroupAvailablePower;            // unit: 0.1kW
+	unsigned int            GroupRealOutputPower;           // unit: 1kW
+	unsigned short          GroupPresentOutputVoltage; 	    // unit: 0.1V
+	unsigned short          GroupPresentOutputCurrent;      // unit: 0.1A
+	unsigned int            GroupPresentOutputPower;        // unit: 0.1kW
 	struct PsuModuleData 	PsuModule[MAX_PSU_QUANTITY];
 	PsuGroupError           GroupErrorFlag;
     unsigned short          TotalIAvailableCurrent;         // unit: 0.1A
@@ -3832,49 +3854,49 @@ struct CcsData
 /**************************************************************************************/
 struct PrimaryMcuData
 {
-	unsigned char 	SelfTest_Comp;
-	unsigned char	version[16];									//STM32F407 firmware version
-	unsigned int 	InputVoltage;									//value comes from external meter
-	unsigned int 	InputCurrent;									//value comes from external meter
-	union
-	{
-		unsigned char OutputDrvValue[1];
-		struct
-		{
-			//OutputDrvValue[0]
-			unsigned char OnButtonLedDrv:1;                     //bit 0,    H: ON,      L:OFF
-			unsigned char OffButtonLedDrv:1;                    //bit 1,    H: ON,      L:OFF
-			unsigned char SystemLed1Drv:1;                      //bit 2,    H: ON,      L:OFF
-			unsigned char SystemLed2Drv:1;                      //bit 3,    H: ON,      L:OFF
-			unsigned char SystemLed3Drv:1;                      //bit 4,    H: ON,      L:OFF
-			unsigned char SystemLed4Drv:1;                      //bit 5,    H: ON,      L:OFF
-			unsigned char AcContactorDrv:1;                     //bit 6,    H: ON,      L:OFF
-			unsigned char:1;                                    //bit 7 reserved
-		}bits;
-	}OutputDrv;
-	union
-	{
-		unsigned char InputDetValue[2];
-		struct
-		{
-			//InputDetValue[0]
-		    unsigned char AcContactorDetec:1;					//bit 0,	H: ON, 		L:OFF
-			unsigned char AcMainBreakerDetec:1;					//bit 1,	H: ON, 		L:OFF
-			unsigned char SpdDetec:1; 							//bit 2,	H: ON, 		L:OFF
-			unsigned char DoorOpen:1;							//bit 3,	H: Open,		L:Close
-			unsigned char Gfd1:1;								//bit 4,	H: Trigger,		L:Normal
-			unsigned char Gfd2:1;								//bit 5,	H: Trigger,		L:Normal
-			unsigned char Button1:1;								//bit 6 ,	H: Push, 		L:Release
-			unsigned char Button2:1;								//bit 7,	H: Push, 		L:Release
-			//InputDetValue[1]
-			unsigned char EmergencyButton:1;						//bit 0,	H: Push, 		L:Release
+    unsigned char   SelfTest_Comp;
+    unsigned char   version[16];                                //STM32F407 firmware version
+    unsigned int    InputVoltage;                               //value comes from external meter
+    unsigned int    InputCurrent;                               //value comes from external meter
+    union
+    {
+        unsigned char OutputDrvValue[1];
+        struct
+        {
+            //OutputDrvValue[0]
+            unsigned char OnButtonLedDrv:1;                     //bit 0,    H: ON,      L:OFF
+            unsigned char OffButtonLedDrv:1;                    //bit 1,    H: ON,      L:OFF
+            unsigned char SystemLed1Drv:1;                      //bit 2,    H: ON,      L:OFF
+            unsigned char SystemLed2Drv:1;                      //bit 3,    H: ON,      L:OFF
+            unsigned char SystemLed3Drv:1;                      //bit 4,    H: ON,      L:OFF
+            unsigned char SystemLed4Drv:1;                      //bit 5,    H: ON,      L:OFF
+            unsigned char AcContactorDrv:1;                     //bit 6,    H: ON,      L:OFF
+            unsigned char:1;                                    //bit 7 reserved
+        }bits;
+    }OutputDrv;
+    union
+    {
+        unsigned char InputDetValue[2];
+        struct
+        {
+            //InputDetValue[0]
+            unsigned char AcContactorDetec:1;                   //bit 0,    H: ON,      L:OFF
+            unsigned char AcMainBreakerDetec:1;                 //bit 1,    H: ON,      L:OFF
+            unsigned char SpdDetec:1;                           //bit 2,    H: ON,      L:OFF
+            unsigned char DoorOpen:1;                           //bit 3,    H: Open,    L:Close
+            unsigned char Gfd1:1;                               //bit 4,    H: Trigger, L:Normal
+            unsigned char Gfd2:1;                               //bit 5,    H: Trigger, L:Normal
+            unsigned char Button1:1;                            //bit 6 ,   H: Push,    L:Release
+            unsigned char Button2:1;                            //bit 7,    H: Push,    L:Release
+            //InputDetValue[1]
+            unsigned char EmergencyButton:1;                    //bit 0,    H: Push,    L:Release
             unsigned char Key0:1;                               //bit 1,    H: ON,      L:OFF
             unsigned char Key1:1;                               //bit 2,    H: ON,      L:OFF
             unsigned char Key2:1;                               //bit 3,    H: ON,      L:OFF
             unsigned char Key3:1;                               //bit 4,    H: ON,      L:OFF
             unsigned char :3;                                   //bit 5~7,  Reserved
-		}bits;
-	}InputDet;
+        }bits;
+    }InputDet;
 };
 /**************************************************************************************/
 /*************Fan power module Communication Share memory******************/
@@ -4295,7 +4317,7 @@ struct OCPP16ConfigurationItem
 {
 	unsigned char 		ItemName[64];
 	unsigned char 		ItemAccessibility;//0:RO, 1:RW
-	unsigned char 		ItemData[128];
+	unsigned char 		ItemData[500];
 };
 
 struct OCPP16ConfigurationTable
@@ -4750,6 +4772,7 @@ enum OCPP20CtrlrVariable
 	OCPPCommCtrlr_WebSocketPingInterval,
 	OCPPCommCtrlr_ResetRetries,
 	OCPPCommCtrlr_PublicKeyWithSignedMeterValue,
+    OCPPCommCtrlr_VariableVersion,
 	ReservationCtrlr_Enabled,
 	ReservationCtrlr_Available,
 	ReservationCtrlr_NonEvseSpecific,
@@ -5119,7 +5142,7 @@ struct UnitOfMeasureType
 
 struct SampledValueType
 {
-	float value;													// Required. Indicates the measured value.
+    double value;													// Required. Indicates the measured value.
 	unsigned char context[32];										// Optional. Type of detail value: start, end or sample. Default = "Sample.Periodic"
 	unsigned char measurand[32];									// Optional. Type of measurement. Default = "Energy.Active.Import.Register"
 	unsigned char phase[8];											// Optional. Indicates how the measured value is to be interpreted.
@@ -5371,6 +5394,7 @@ struct GetCertificateStatus_20
 	struct OCSPRequestDataType ocspRequestData;						// Required. Indicates the certificate of which the status is requested.
 	unsigned char Response_status[16];								// Required. This indicates whether the charging station was able to retrieve the OCSP certificate status.
 	unsigned char Response_ocspResult[5501];						// Optional. OCSPResponse class as defined in IETF RFC 6960. DER encoded (as defined in IETF RFC 6960), and then base64 encoded. MAY only be omitted when status is not Accepted.
+	struct StatusInfoType Response_statusInfo;                      // Optional. Detailed status information.
 };
 
 struct GetChargingProfiles_20

+ 4 - 2
EVSE/Projects/DD360Audi/Apps/Makefile

@@ -70,7 +70,8 @@ COMMON_OBJ_FILES = common.o \
 MAIN_OBJ_FILES = $(COMMON_OBJ_FILES) $(DataBaseLib)/DataBase.o \
 					$(CSULib)/main.o  $(CSULib)/Primary.o $(CSULib)/WatchDog.o $(CSULib)/ZipFile.o \
 					$(CSULib)/RFID.o $(CSULib)/SelfTest.o $(CSULib)/UpgradeFW.o \
-					$(CSULib)/Ethernet.o
+					$(CSULib)/Ethernet.o $(CSULib)/CheckSystemTask.o
+					
 MAIN_SRC_FILES = $(patsubst %.o, %.c, $(MAIN_OBJ_FILES))
 %.o: %.c
 	$(CC) $(CFLAGS) -c $<
@@ -129,7 +130,8 @@ apps: MainTask DoCommTask EvCommTask \
 
 MainTask:
 	$(CC) $(DEFINE) $(MAIN_SRC_FILES) $(CFLAGS) $(TFLAGS) $(INC_FLAGS) $(SQLite3_H) $(ModuleUpgrade_H) $(RateCurrent_H) \
-		$(RFID_H) $(Lib_Module_RFID) $(Lib_Module_Upgrade) $(Lib_SQLite3) $(Lib_Module_RateCurrent) -o main
+		$(RFID_H) $(Lib_Module_RFID) $(Lib_Module_Upgrade) $(Lib_SQLite3) $(Lib_Module_RateCurrent) \
+		$(CheckSystemTask_H) -o main
 	#$(CC) $(DEFINE) $(SQLite3_H) $(ModuleUpgrade_H) $(RFID_H) $(RatedCurrent_H) $(CFLAGS) -c -o main.o main.c
 	#$(CC) $(DEFINE) $(SQLite3_H) $(ModuleUpgrade_H) $(RFID_H) $(RatedCurrent_H) $(CFLAGS) -c -o timeout.o timeout.c
 	#$(CC) $(DEFINE) $(CFLAGS) -c -o common.o common.c

+ 74 - 6
EVSE/Projects/DD360Audi/Apps/ModuleDoComm/DoComm.c

@@ -57,10 +57,16 @@ static void removeFaultCodeToBuf(uint8_t *Code);
 static void addFaultCodeToBuf(uint8_t *Code);
 static int readMiscCommand(int fd, uint8_t id);
 static int writeCsuModuleVersion(int fd);
+static int writeGroundFaultDetection(int fd, uint8_t status, uint8_t id);
 
 //------------------------------------------------------------------------------
 //--- Common function ---
 //------------------------------------------------------------------------------
+void GetClockTime(struct timespec *_now_time, void *null)
+{
+    clock_gettime(CLOCK_MONOTONIC, _now_time);
+}
+
 /*static int StoreLogMsg(const char *fmt, ...)
 {
     char Buf[4096 + 256];
@@ -715,7 +721,7 @@ static int miscCommandHandle(uint8_t dataLen, uint8_t plugNum, uint8_t *data)
                     pSysInfo->WaitForPlugit = NO;
                     sleep(1); //Jerry add
                     pSysInfo->SystemPage = _LCM_SELECT_GUN;
-                    gettimeofday(&pSysInfo->SystemTimeoutTimer, NULL);
+                    GetClockTime(&pSysInfo->SystemTimeoutTimer, NULL);
                     pSysInfo->SystemTimeoutFlag = Timeout_None;
                 }
 
@@ -727,7 +733,7 @@ static int miscCommandHandle(uint8_t dataLen, uint8_t plugNum, uint8_t *data)
                     pSysInfo->WaitForPlugit = NO;
                     sleep(1); //Jerry add
                     pSysInfo->SystemPage = _LCM_SELECT_GUN;
-                    gettimeofday(&pSysInfo->SystemTimeoutTimer, NULL);
+                    GetClockTime(&pSysInfo->SystemTimeoutTimer, NULL);
                     pSysInfo->SystemTimeoutFlag = Timeout_None;
                 }
 
@@ -756,7 +762,7 @@ static int miscCommandHandle(uint8_t dataLen, uint8_t plugNum, uint8_t *data)
             strcpy((char *)pSysConfig->UserId, "");
             pSysInfo->WaitForPlugit = NO;
             pSysInfo->SystemPage = _LCM_SELECT_GUN;
-            gettimeofday(&pSysInfo->SystemTimeoutTimer, NULL);
+            GetClockTime(&pSysInfo->SystemTimeoutTimer, NULL);
             pSysInfo->SystemTimeoutFlag = Timeout_None;
             destroySelectGun(plugNum);
 
@@ -776,7 +782,7 @@ static int miscCommandHandle(uint8_t dataLen, uint8_t plugNum, uint8_t *data)
                 strcpy((char *)pSysConfig->UserId, "");
                 pSysInfo->WaitForPlugit = NO;
                 pSysInfo->SystemPage = _LCM_SELECT_GUN;
-                gettimeofday(&pSysInfo->SystemTimeoutTimer, NULL);
+                GetClockTime(&pSysInfo->SystemTimeoutTimer, NULL);
                 pSysInfo->SystemTimeoutFlag = Timeout_None;
                 destroySelectGun(plugNum);
             } else {
@@ -1167,6 +1173,26 @@ static int responsePackeHandle(int fd, uint8_t *pResult, uint8_t plugNum, uint8_
     case REG_WAIT_PLUG_IT_STATE:
         break;
 
+    case REG_Ground_Fault_Detection:
+        if (pCsuResult->Data.Result == COMMAND_RESULT_NG) {
+            return COMMAND_RESULT_NG;
+        }
+
+        //集電弓relay 不打開才能進入動作
+        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(plugNum);
+        if(pDcChargingInfo->PantographFlag == YES)
+        {
+            GroundFaultDetection *gfd = (GroundFaultDetection *)&pCsuResult->Data.Data[0];
+            if(pDcChargingInfo->GroundFaultStatus != gfd->Status)
+            {
+                log_info("id = %d, GFD Result = %d\r\n",
+                           pCsuResult->Head.ID,
+                           gfd->Status);
+            }
+            pDcChargingInfo->GroundFaultStatus = gfd->Status;
+        }
+        break;
+
     default:
         break;
     }
@@ -1277,8 +1303,16 @@ static int writePresentChargingInfo(int fd, uint8_t plugNum, uint8_t id)
     PreChargingInfo *pPreChargingInfo = (PreChargingInfo *)dataBuf;
     pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(plugNum);
 
-    pPreChargingInfo->PresentChargingVoltage = htons((uint16_t)(pDcChargingInfo->PresentChargingVoltage * 10));
-    pPreChargingInfo->PresentChargingCurrent = htons((uint16_t)(pDcChargingInfo->PresentChargingCurrent * 10));
+    if(pDcChargingInfo->PantographFlag == NO)
+    {
+        pPreChargingInfo->PresentChargingVoltage = htons((uint16_t)(pDcChargingInfo->PresentChargingVoltage * 10));
+        pPreChargingInfo->PresentChargingCurrent = htons((uint16_t)(pDcChargingInfo->PresentChargingCurrent * 10));
+    }
+    else
+    {
+        pPreChargingInfo->PresentChargingVoltage = htons((uint16_t)(ShmDcCommonData->PcPsuOutput[plugNum].Voltage));
+        pPreChargingInfo->PresentChargingCurrent = htons((uint16_t)(ShmDcCommonData->PcPsuOutput[plugNum].Current));
+    }
     pPreChargingInfo->RemainChargingDuration = htonl(pDcChargingInfo->RemainChargingDuration);
     pPreChargingInfo->EvBatterySoc = pDcChargingInfo->EvBatterySoc;
 
@@ -1369,6 +1403,19 @@ static int readChargePermission(int fd, uint8_t id)
                              NULL);
 }
 
+static int writeGroundFaultDetection(int fd, uint8_t status, uint8_t id)
+{
+    int ret = PASS;
+    uint8_t dataBuf[1] = {status};
+    ret = composeSocketData(fd,
+                            id,
+                            OP_WRITE_DATA,
+                            REG_Ground_Fault_Detection,
+                            1,
+                            &dataBuf[0]);
+    return ret;
+}
+
 static int writeUserID(int fd, uint8_t id, uint8_t *pUserID)
 {
     if ((strlen((char *)pUserID) <= 0) || (pUserID == NULL)) {
@@ -1940,6 +1987,8 @@ static void systemStatusProcess(int fd, uint8_t totalGun, uint8_t plugNum, uint8
                 DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_CAP], AuthNowTime) < 0
            ) {
             readChargingCapability(fd, gunID);
+			if (pDcChargingInfo->PantographFlag)
+				writeGroundFaultDetection(fd, 0, gunID);
             ftime(&gRegTimeUp[plugNum][REG_CHARGING_CAP]);
         }
         break;
@@ -1973,6 +2022,8 @@ static void systemStatusProcess(int fd, uint8_t totalGun, uint8_t plugNum, uint8
                 DiffTimeb(gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO], AuthNowTime) < 0
            ) {
             writePresentChargingInfo(fd, plugNum, gunID);
+			if (pDcChargingInfo->PantographFlag)
+				writeGroundFaultDetection(fd, 0, gunID);
             ftime(&gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO]);
         }
         break;
@@ -2004,6 +2055,8 @@ static void systemStatusProcess(int fd, uint8_t totalGun, uint8_t plugNum, uint8
                 DiffTimeb(gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO], AuthNowTime) < 0
            ) {
             writePresentChargingInfo(fd, plugNum, gunID);
+			if (pDcChargingInfo->PantographFlag)
+				writeGroundFaultDetection(fd, 0, gunID);
             ftime(&gRegTimeUp[plugNum][REG_PRESENT_CHARGING_INFO]);
         }
         break;
@@ -2012,6 +2065,8 @@ static void systemStatusProcess(int fd, uint8_t totalGun, uint8_t plugNum, uint8
     case S_CCS_PRECHARGE_ST0:
     case S_CCS_PRECHARGE_ST1:
         writeChargingTarget(fd, plugNum, gunID);
+		if (pDcChargingInfo->PantographFlag)
+			writeGroundFaultDetection(fd, 1, gunID);
 
         ftime(&AuthNowTime);
         if (DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_CAP], AuthNowTime) > LOOP_RETRY_TIME ||
@@ -2045,6 +2100,17 @@ static void systemStatusProcess(int fd, uint8_t totalGun, uint8_t plugNum, uint8
 
     case S_CHARGING: //charging
     case S_TERMINATING:
+        if(pDcChargingInfo->Type == _Type_GB || pDcChargingInfo->Type == _Type_Chademo)
+        {
+			if (pDcChargingInfo->PantographFlag)
+				writeGroundFaultDetection(fd, 0, gunID);
+        }
+        else
+        {
+			if (pDcChargingInfo->PantographFlag)
+				writeGroundFaultDetection(fd, 1, gunID);
+        }
+
         ftime(&AuthNowTime);
         if (DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_CAP], AuthNowTime) > LOOP_RETRY_TIME ||
                 DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_CAP], AuthNowTime) < 0
@@ -2083,6 +2149,8 @@ static void systemStatusProcess(int fd, uint8_t totalGun, uint8_t plugNum, uint8
                 DiffTimeb(gRegTimeUp[plugNum][REG_CHARGING_CAP], AuthNowTime) < 0
            ) {
             readChargingCapability(fd, gunID);
+			if (pDcChargingInfo->PantographFlag)
+				writeGroundFaultDetection(fd, 0, gunID);
             ftime(&gRegTimeUp[plugNum][REG_CHARGING_CAP]);
         }
         break;

+ 5 - 0
EVSE/Projects/DD360Audi/Apps/ModuleDoComm/DoComm.h

@@ -79,6 +79,7 @@
 #define REG_PRESENT_CHARGING_INFO               0X0F
 #define REG_QRCODE_URL_INFO                     0X10
 #define REG_WAIT_PLUG_IT_STATE                  0x11
+#define REG_Ground_Fault_Detection              0x12
 
 //------------------------------------------------------------------------------
 //--- dispenser result ---
@@ -207,6 +208,10 @@ typedef struct StPresentChargingInfo {
     uint8_t EvBatterySoc;               // 0~100%
 } PreChargingInfo;
 
+typedef struct StGroundFaultDetection { //Ground Fault Detection
+    uint8_t Status;
+} GroundFaultDetection;
+
 typedef struct StSoftwareUpdInfo {
     uint8_t UpdateState;         //1:update , 2: not update
     uint8_t ImgName[248];

+ 4 - 2
EVSE/Projects/DD360Audi/Apps/ModuleEvComm/AbnormalState.c

@@ -27,8 +27,10 @@ bool AbnormalStopAnalysis(uint8_t gun_index, uint8_t *errCode)
     //iflog_info("NOTIFICATION_EV_STOP : Err Code = %s \n", string);
 
     if (strncmp(string, "000000", 6) == EQUAL ||
-            strncmp(string, "012219", 6) == EQUAL
-       ) {
+            strncmp(string, "012219", 6) == EQUAL ||
+            strncmp(string, "023979", 6) == EQUAL )
+    {
+		log_info("NOTIFICATION_EV_STOP : EvCode = %s\n", string);
         return false;
     }
 

+ 14 - 9
EVSE/Projects/DD360Audi/Apps/ModuleEvComm/Module_EvTxComm.c

@@ -15,6 +15,7 @@
 
 #include <linux/can.h>
 #include <linux/can/raw.h>
+#include <signal.h>
 
 #include "../Config.h"
 #include "../Log/log.h"
@@ -505,7 +506,7 @@ static void SetPresentChargingOutputPower(void)
     PcPsuOutput *pPcPsuOutput2 = NULL;
     struct ChargingInfoData *chargingData_1 = NULL;
     struct ChargingInfoData *chargingData_2 = NULL;
-    bool isPsuOutput1 = false, isPsuOutput2 = false;
+    bool isPsuVol1 = false, isPsuVol2 = false, isPsuCur1 = false, isPsuCur2 = false;
 
     if (pSysConfig->TotalConnectorCount == 1) {
         pPcPsuOutput1 = (PcPsuOutput *)&ShmDcCommonData->PcPsuOutput[0];
@@ -522,15 +523,17 @@ static void SetPresentChargingOutputPower(void)
     psuOutputReady[0] = chargingData_1->SystemStatus != S_CHARGING ? false : psuOutputReady[0];
     psuOutputReady[1] = chargingData_2->SystemStatus != S_CHARGING ? false : psuOutputReady[1];
 
-    isPsuOutput1 = (pPcPsuOutput1->Voltage != 0 && psuOutputReady[0] == true);
-    isPsuOutput2 = (pPcPsuOutput2->Voltage != 0 && psuOutputReady[1] == true);
+    isPsuVol1 = chargingData_1->PantographFlag ? true : (pPcPsuOutput1->Voltage != 0 && psuOutputReady[0] == true);
+    isPsuVol2 = chargingData_2->PantographFlag ? true : (pPcPsuOutput2->Voltage != 0 && psuOutputReady[1] == true);
+    isPsuCur1 = chargingData_1->PantographFlag ? true : false;
+    isPsuCur2 = chargingData_2->PantographFlag ? true : false;
 
     //vol1 = chargingData_1->FireChargingVoltage;
-    vol1 = isPsuOutput1 == false ? chargingData_1->FireChargingVoltage : (((float)pPcPsuOutput1->Voltage));
-    cur1 = (chargingData_1->PresentChargingCurrent * 10);
+    vol1 = isPsuVol1 == false ? chargingData_1->FireChargingVoltage : (((float)pPcPsuOutput1->Voltage));
+    cur1 = isPsuCur1 == false ? (chargingData_1->PresentChargingCurrent * 10) : pPcPsuOutput1->Current;
     //vol2 = chargingData_2->FireChargingVoltage;
-    vol2 = isPsuOutput2 == false ? chargingData_2->FireChargingVoltage : (((float)pPcPsuOutput2->Voltage));
-    cur2 = (chargingData_2->PresentChargingCurrent * 10);
+    vol2 = isPsuVol2 == false ? chargingData_2->FireChargingVoltage : (((float)pPcPsuOutput2->Voltage));
+    cur2 = isPsuCur2 == false ? (chargingData_2->PresentChargingCurrent * 10) : pPcPsuOutput2->Current;
 
     //DS60-120 add
     if ((LogInfo[0][EV_LOG_NOW_OUTPUT_VOL] >= vol1 + CHK_VOL_RANGE) ||
@@ -543,10 +546,10 @@ static void SetPresentChargingOutputPower(void)
             (LogInfo[1][EV_LOG_NOW_OUTPUT_CUR] <= cur2 - CHK_CUR_RANGE)
        ) {
         log_info("G1 -> Output Vol(%s) = %.1f, Output Cur = %.1f -- G2 -> Output Vol(%s) = %.1f, Output Cur = %.1f\r\n",
-                 isPsuOutput1 == true ? "P" : "R",
+                 isPsuVol1 == true ? "P" : "R",
                  vol1 / 10,
                  cur1 / 10,
-                 isPsuOutput2 == true ? "P" : "R",
+                 isPsuVol2 == true ? "P" : "R",
                  vol2 / 10,
                  cur2 / 10);
 
@@ -711,6 +714,8 @@ int main(int argc, char *argv[])
 
     FormatVoltageAndCurrent();
 
+    signal(SIGCHLD,SIG_IGN);
+    
     CANReceiver(CanFd);
 
     rtc = GetRtcInfoForEpoch();

+ 4 - 1
EVSE/Projects/DD360Audi/Apps/ModuleInternalComm/Module_InternalComm.c

@@ -100,7 +100,10 @@ int main(int argc, char *argv[])
     //FanBoardTask(fd);
 
     while (isContinue) {
-        AcPlugTask(fd);
+        if(AC_QUANTITY > 0)
+        {
+            AcPlugTask(fd);
+        }
         usleep(100000);
     }
 

+ 41 - 4
EVSE/Projects/DD360Audi/Apps/ModuleInternalComm/RelayBoard.c

@@ -780,6 +780,13 @@ void CableCheckDetected(uint8_t index)
                     SetGfdConfig(targetID, GFD_CHARGING);
                 }
             }
+        }
+        else if(pDcChargingInfo->SystemStatus == S_TERMINATING || pDcChargingInfo->SystemStatus == S_ALARM)
+        {
+            if (pDcChargingInfo->Type == _Type_CCS_2)
+            {
+                SetGfdConfig(targetID, GFD_CHARGING);
+            }
         } else {
             SetGfdConfig(targetID, GFD_IDLE);
         }
@@ -1648,6 +1655,7 @@ static void LEDBoardProcess(void)
 
 void RelayBoardTask(int uartFD)
 {
+    bool isRelayBypass = false;
     pid_t pid = fork();
 
     if (pid == 0) {
@@ -1671,8 +1679,20 @@ void RelayBoardTask(int uartFD)
 
         Uart5Fd = uartFD;
 
+        for(int i = 0; i < pSysConfig->TotalConnectorCount; i++)
+        {
+            pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
+            if(pDcChargingInfo->PantographFlag == YES)
+            {
+                isRelayBypass = true;
+            }
+        }
+
         //relay init
-        outputRelayInit(uartFD);
+        if(isRelayBypass == false)
+        {
+            outputRelayInit(uartFD);
+        }
 
         while (isContinue) {
 
@@ -1683,7 +1703,7 @@ void RelayBoardTask(int uartFD)
             }
 
             // 程序開始之前~ 必須先確定 FW 版本與硬體版本,確認後!!~ 該模組才算是真正的 Initial Comp.
-            if (ShmRelayModuleData->SelfTest_Comp == NO) {
+            if (ShmRelayModuleData->SelfTest_Comp == NO && isRelayBypass == false) {
                 GetFwAndHwVersion_Relay();
                 SetModelName_Relay(); //DS60-120 add
                 SetRtcData_Relay();
@@ -1698,7 +1718,7 @@ void RelayBoardTask(int uartFD)
             LEDBoardSelfTest();
 #endif //defined DD360ComBox
 
-            if (ShmRelayModuleData->SelfTest_Comp == YES)
+            if (ShmRelayModuleData->SelfTest_Comp == YES && isRelayBypass == false)
             {
                 // ==============優先權最高 10 ms ==============
                 // 輸出電壓
@@ -1711,7 +1731,6 @@ void RelayBoardTask(int uartFD)
 
                 // 讀取當前 AC relay 狀態
                 regRelay.relay_event.bits.AC_Contactor = pSysInfo->AcContactorStatus;
-
                 GetRelayOutputStatus();
 
                 // Cable check (Get)
@@ -1848,6 +1867,24 @@ void RelayBoardTask(int uartFD)
                     }
                 }
             }
+            else if(isRelayBypass == true)
+            {
+                for(i = 0; i < pSysConfig->TotalConnectorCount; i++)
+                {
+                    pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
+
+                    if (pDcChargingInfo->SystemStatus == S_IDLE ||
+                            pDcChargingInfo->SystemStatus == S_RESERVATION ||
+                            pDcChargingInfo->SystemStatus == S_MAINTAIN)
+                    {
+                        _isOvpChkTimeFlag[i] = NO;
+                    }
+                    if (pDcChargingInfo->SystemStatus == S_CHARGING)
+                    {
+                        CheckOutputPowerOverCarReq(i);
+                    }
+                }
+            }
 
 #if !defined NO_FAN_BOARD && !defined DD360ComBox
             fanBoardPorcess();

+ 39 - 0
EVSE/Projects/DD360Audi/Apps/ModuleLcmCtrl/Module_LcmControl.c

@@ -223,6 +223,11 @@ uint8_t _right_gun_disable_map  = 68;
 uint8_t _right_gun_enable_map   = 69;
 uint8_t _select_gun_btn         = 70;
 uint8_t _emergency_disable_map  = 72;
+// For replug
+struct timespec showReplugStrTimer;
+short __show_replugString_value = 0x0460;
+uint8_t _showReplugStr_1 = 74;
+uint8_t _showReplugStr_2 = 75;
 
 //#define log_info(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
 //#define log_warn(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
@@ -853,6 +858,31 @@ bool FindAcChargingInfoData(uint8_t target, struct ChargingInfoData **acCharging
 
     return false;
 }
+int GetTimeoutValue(struct timespec *startTime)
+{
+    struct timespec endTime;
+    clock_gettime(CLOCK_MONOTONIC_COARSE, &endTime);
+    return endTime.tv_sec - startTime->tv_sec;
+}
+void GetTimespecFunc(struct timespec *time)
+{
+    clock_gettime(CLOCK_MONOTONIC_COARSE, time);
+}
+
+void RunReplugStringFunction(bool isRun)
+{
+    if (isRun) {
+        int time = GetTimeoutValue(&showReplugStrTimer);
+        if (time >=1 && time <2) {
+            ChangeDisplay2Value(__show_replugString_value, _showReplugStr_1);
+        } else if (time < 1) {
+            ChangeDisplay2Value(__show_replugString_value, _showReplugStr_2);
+        } else
+            GetTimespecFunc(&showReplugStrTimer);
+
+    } else
+        ChangeDisplay2Value(__show_replugString_value, _disappear);
+}
 
 /**
  * [ChangeBalanceValue :print balance information]
@@ -2041,6 +2071,15 @@ void ProcessPageInfo()
                     } else {
                         ChangeDisplay2Value(__charging_fee_map, _money_map);
                     }
+#ifdef DD360Audi
+                    // Warming Occur in prepare or precharing state, turn into complete mode
+                    if (pDcChargingInfo->Replug_flag) {
+                        RunReplugStringFunction(true);
+                    } else {
+                        RunReplugStringFunction(false);
+                    }
+#else
+#endif					
                 }
             }
         }

+ 54 - 6
EVSE/Projects/DD360Audi/Apps/ModulePrimary/Module_PrimaryComm.c

@@ -48,6 +48,11 @@ static struct PrimaryMcuData *ShmPrimaryMcuData;
 const char *priPortName = "/dev/ttyS1";
 uint8_t gun_count; //DS60-120 add
 
+uint8_t EmgBtn_count = 0;
+uint8_t Door_count = 0;
+uint8_t EmgBtn_flag = 0;
+uint8_t Door_flag = 0;
+
 //struct ChargingInfoData *ChargingData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 
 //------------------------------------------------------------------------------
@@ -180,13 +185,31 @@ void GetInputGpioStatus(int fd)
     }
 
     ShmPrimaryMcuData->InputDet.bits.SpdDetec = gpio_in.SPD;
-
 #if defined DD360ComBox
-    ShmPrimaryMcuData->InputDet.bits.EmergencyButton = ~gpio_in.Emergency_Btn;
+    if (gpio_in.Emergency_Btn == 0 && (EmgBtn_flag == gpio_in.Emergency_Btn))
 #else
-    ShmPrimaryMcuData->InputDet.bits.EmergencyButton = gpio_in.Emergency_Btn;
+    if (gpio_in.Emergency_Btn && (EmgBtn_flag != gpio_in.Emergency_Btn))
 #endif //defined DD360ComBox
-
+    {
+            EmgBtn_count++;
+        if (EmgBtn_count > SensorTrigCount) {
+           EmgBtn_flag = 1;
+           EmgBtn_count = 0; // Avoid Overflow
+       }
+#ifdef DD360ComBox
+    } else if ( gpio_in.Emergency_Btn && EmgBtn_flag ) {
+#else
+    } else if (EmgBtn_flag != gpio_in.Emergency_Btn ) {
+#endif    
+        EmgBtn_count++;
+        if (EmgBtn_count > SensorTrigCount) {
+            EmgBtn_flag = 0;
+            EmgBtn_count = 0;
+        }
+    }
+ 
+    ShmPrimaryMcuData->InputDet.bits.EmergencyButton = EmgBtn_flag;
+ 
     dispenserSwTmp |= (ShmPrimaryMcuData->InputDet.bits.Key0);
     dispenserSwTmp |= (ShmPrimaryMcuData->InputDet.bits.Key1 << 1);
     dispenserSwTmp |= (ShmPrimaryMcuData->InputDet.bits.Key2 << 2);
@@ -219,10 +242,35 @@ void GetInputGpioStatus(int fd)
     }
 
 #if defined DD360ComBox
-    ShmPrimaryMcuData->InputDet.bits.DoorOpen = gpio_in.Door_Open;
+    if (gpio_in.Door_Open && (Door_flag != gpio_in.Door_Open))
 #else
-    ShmPrimaryMcuData->InputDet.bits.DoorOpen = ~gpio_in.Door_Open;
+    if (gpio_in.Door_Open == 0 && (Door_flag == gpio_in.Door_Open))
 #endif //defined DD360ComBox
+    {
+        Door_count++;
+        if (Door_count > SensorTrigCount) {
+            Door_flag = 1;
+            Door_count = 0; // Avoid Overflow
+       }
+#ifdef DD360ComBox
+    } else if (gpio_in.Door_Open == 0 && Door_flag) {
+#else
+    } else if (gpio_in.Door_Open && Door_flag) {
+#endif
+        Door_count++;
+        if (Door_count > SensorTrigCount) {
+            Door_flag = 0;
+            Door_count = 0;
+        }
+    }
+ 
+    ShmPrimaryMcuData->InputDet.bits.DoorOpen = Door_flag;
+/*
+    log_info("Emergency Button Count = %d , Emergency flag = %d\n",
+            EmgBtn_count,EmgBtn_flag);
+    log_info("Door Sensor Count = %d , Door Sensor flag = %d\n",
+            Door_count,Door_flag);
+*/
 
     ShmPrimaryMcuData->InputDet.bits.Key0 = ~gpio_in.Key[0] & 0x01;
     ShmPrimaryMcuData->InputDet.bits.Key1 = ~gpio_in.Key[1] & 0x01;

+ 1 - 0
EVSE/Projects/DD360Audi/Apps/ModulePrimary/Module_PrimaryComm.h

@@ -30,5 +30,6 @@ typedef struct StLedConfig {
 
 //------------------------------------------------------------------------------
 //int StoreLogMsg(const char *fmt, ...);
+#define SensorTrigCount 3
 
 #endif /* _MODULE_PRIMARY_COMM_H_ */

+ 4 - 0
EVSE/Projects/DD360Audi/Apps/Script/kill.sh

@@ -12,6 +12,10 @@ pkill Module_ProduceUtils;
 pkill Module_DoComm;
 pkill main;
 
+sleep 1
+
+echo V > /dev/watchdog
+
 ipcrm -M 0x000003e9;
 ipcrm -M 0x000003ed;
 ipcrm -M 0x000003ea;

+ 35 - 17
EVSE/Projects/DD360Audi/Apps/ShareMemory/shmMem.c

@@ -833,7 +833,7 @@ static int findDcChargingInfoData(uint8_t gunIndex)
     return FAIL;
 }
 
-static bool addGunInfoByConnector(uint8_t typeValue, uint8_t slots)
+static bool addGunInfoByConnector(uint8_t typeValue, uint8_t slots,char *whichtask)
 {
     bool result = true;
     struct SysInfoData *pSysInfo = (struct SysInfoData *)GetShmSysInfoData();
@@ -862,11 +862,14 @@ static bool addGunInfoByConnector(uint8_t typeValue, uint8_t slots)
             pAcChargingInfo->ReservationId = -1;
             pAcChargingInfo->SystemStatus = S_IDLE;
             pAcChargingInfo->Type = _Type_AC;
-            pAcChargingInfo->IsAvailable = YES;
             pAcChargingInfo->schedule.isTriggerStart = NO; //DS60-120 add
             pAcChargingInfo->schedule.isTriggerStop = NO;  //DS60-120 add
-            gGunIndexInfo.AcIndex++;
-            gGunIndexInfo.AcGunIndex++;
+            //if( strcmp(whichtask,"CSU task") == EQUAL ) 
+            {
+                gGunIndexInfo.AcIndex++;
+                gGunIndexInfo.AcGunIndex++;
+                pAcChargingInfo->IsAvailable = YES;
+            }
         } else {
             result = false;
         }
@@ -886,13 +889,17 @@ static bool addGunInfoByConnector(uint8_t typeValue, uint8_t slots)
             pDcChargingInfo->Index = gGunIndexInfo.DcGunIndex;
             pDcChargingInfo->ReservationId = -1;
             pDcChargingInfo->slotsIndex = slots;
-            pDcChargingInfo->SystemStatus = S_BOOTING;
+            //pDcChargingInfo->SystemStatus = S_BOOTING;
+			//pDcChargingInfo->SystemStatus = S_IDLE;
             pDcChargingInfo->Type = _Type_Chademo;
             pDcChargingInfo->type_index = gGunIndexInfo.ChademoIndex;
-            pDcChargingInfo->IsAvailable = YES;
             setAcGunTiggerStatus();
-            gGunIndexInfo.ChademoIndex++;
-            gGunIndexInfo.DcGunIndex++;
+            //if( strcmp(whichtask,"CSU task") == EQUAL ) 
+            {
+                pDcChargingInfo->IsAvailable = YES;
+                gGunIndexInfo.ChademoIndex++;
+                gGunIndexInfo.DcGunIndex++;
+            }
         } else {
             result = false;
         }
@@ -914,15 +921,23 @@ static bool addGunInfoByConnector(uint8_t typeValue, uint8_t slots)
             pDcChargingInfo->Index = gGunIndexInfo.DcGunIndex;
             pDcChargingInfo->ReservationId = -1;
             pDcChargingInfo->slotsIndex = slots;
-            pDcChargingInfo->SystemStatus = S_BOOTING;
+            //pDcChargingInfo->SystemStatus = S_BOOTING;
             pDcChargingInfo->Type = _Type_CCS_2;
             pDcChargingInfo->type_index = gGunIndexInfo.CcsIndex;
-            pDcChargingInfo->IsAvailable = YES;
+
             setAcGunTiggerStatus();
             // 現階段預設為走 DIN70121
             pCcsData->CommProtocol = _CCS_COMM_V2GMessage_DIN70121;
-            gGunIndexInfo.CcsIndex++;
-            gGunIndexInfo.DcGunIndex++;
+            //if( strcmp(whichtask,"CSU task") == EQUAL ) 
+            {
+                pDcChargingInfo->IsAvailable = YES;
+                gGunIndexInfo.CcsIndex++;
+                gGunIndexInfo.DcGunIndex++;
+            }
+            if(typeValue == 'P')
+            {
+                pDcChargingInfo->PantographFlag = YES;
+            }
         } else {
             result = false;
         }
@@ -935,13 +950,16 @@ static bool addGunInfoByConnector(uint8_t typeValue, uint8_t slots)
             pDcChargingInfo->Index = gGunIndexInfo.DcGunIndex;
             pDcChargingInfo->ReservationId = -1;
             pDcChargingInfo->slotsIndex = slots;
-            pDcChargingInfo->SystemStatus = S_BOOTING;
+            //pDcChargingInfo->SystemStatus = S_BOOTING;
             pDcChargingInfo->Type = _Type_GB;
             pDcChargingInfo->type_index = gGunIndexInfo.GbIndex;
-            pDcChargingInfo->IsAvailable = YES;
             setAcGunTiggerStatus();
-            gGunIndexInfo.GbIndex++;
-            gGunIndexInfo.DcGunIndex++;
+            //if( strcmp(whichtask,"CSU task") == EQUAL ) 
+            {
+                pDcChargingInfo->IsAvailable = YES;
+                gGunIndexInfo.GbIndex++;
+                gGunIndexInfo.DcGunIndex++;
+            }
         } else {
             result = false;
         }
@@ -984,7 +1002,7 @@ bool MappingGunChargingInfo(char *whichTask)
 
     //printf("1 CheckConnectorTypeStatus\r\n");
     for (typeIndex = 7; typeIndex <= 9; typeIndex++) {
-        if (!addGunInfoByConnector(pSysConfig->ModelName[typeIndex], slots)) {
+        if (!addGunInfoByConnector(pSysConfig->ModelName[typeIndex], slots, whichTask)) {
             log_error("%s add gun info failed\r\n", whichTask);
             return false;
         }

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


二進制
EVSE/Projects/DD360Audi/output/FactoryConfig


二進制
EVSE/Projects/DD360Audi/output/Module_DoComm


二進制
EVSE/Projects/DD360Audi/output/Module_EvComm


二進制
EVSE/Projects/DD360Audi/output/Module_EventLogging


二進制
EVSE/Projects/DD360Audi/output/Module_InternalComm


二進制
EVSE/Projects/DD360Audi/output/Module_LcmControl


二進制
EVSE/Projects/DD360Audi/output/Module_PrimaryComm


二進制
EVSE/Projects/DD360Audi/output/ReadCmdline


二進制
EVSE/Projects/DD360Audi/output/main


+ 0 - 0
EVSE/Projects/DD360ComBox/Apps/.metadata/.lock


+ 184 - 0
EVSE/Projects/DD360ComBox/Apps/CSU/CheckSystemTask.c

@@ -0,0 +1,184 @@
+/*
+ * CheckTask.c
+ *
+ *  Created on: 2021年9月22日
+ *      Author: 8513
+ */
+
+#include "CheckSystemTask.h"
+
+bool Taskconutstring(char *src, char *taskname)
+{
+    bool result = false;
+
+    if (src == NULL || strlen(src) == 0)
+        return result;
+
+    if (strstr(src, taskname) != NULL &&
+        strstr(src, "grep") == NULL &&
+        strstr(src, "[") == NULL)
+    {
+        result = true;
+    }
+
+    return result;
+}
+
+int GetProcessCount(char *procName)
+{
+	int result = 0;
+	FILE *fp;
+	char cmd[256];
+	char buf[256];
+
+	sprintf(cmd, "ps -ef |grep %s", procName);
+	fp = popen(cmd, "r");
+	if(fp != NULL)
+	{
+		while(fgets(buf, sizeof(buf), fp) != NULL)
+		{
+			if (Taskconutstring(buf, procName))
+				result++;
+		}
+	}
+
+	pclose(fp);
+
+	return result;
+}
+
+unsigned char CheckSystemTask(unsigned char systemPage)
+{
+	unsigned char result = 0;
+	unsigned char count_main 		= GetProcessCount("main");
+	unsigned char count_evComm 		= GetProcessCount("Module_EvComm");
+	unsigned char count_interComm	= GetProcessCount("Module_InternalComm");
+	unsigned char count_eventComm	= GetProcessCount("Module_EventLogging");
+	unsigned char count_primaryComm	= GetProcessCount("Module_PrimaryComm");
+	unsigned char count_lcmComm	    = GetProcessCount("Module_LcmControl");
+	unsigned char count_doComm	    = GetProcessCount("Module_DoComm");
+	unsigned char count_produceComm	= GetProcessCount("Module_ProduceUtils");
+//	unsigned char count_psuComm 	= GetProcessCount("Module_PsuComm");
+
+//	printf("*************************** \n");
+//	printf("count_main = %d \n", count_main);
+//	printf("count_eventLog = %d \n", count_eventLog);
+//	printf("count_primary = %d \n", count_primary);
+//	printf("count_evComm = %d \n", count_evComm);
+//	printf("count_lcmCtrl = %d \n", count_lcmCtrl);
+//	printf("count_interComm = %d \n", count_interComm);
+//	printf("count_psuComm = %d \n", count_psuComm);
+//	printf("*************************** \n");
+
+//	if (systemPage == 0x09 || systemPage == 0x0A)
+	{
+		if (count_main < _SYSTEM_TASK_COUNT_MAIN )
+		{
+			system("killall Module_EventLogging");
+			system("killall Module_PrimaryComm");
+			system("killall Module_EvComm");
+			system("killall Module_LcmControl");
+			system("killall Module_InternalComm");
+			system("killall Module_DoComm");
+//			system("killall Module_PsuComm");
+//			system("killall OcppBackend &");
+//			system("killall Module_4g &");
+//			system("killall Module_Wifi &");
+			system("killall Module_ProduceUtils &");
+			sleep(3);
+			system("/usr/bin/run_evse_restart.sh");
+		}
+		else
+		{
+			/*
+			if(system("pidof -s Module_EventLogging > /dev/null") != 0)
+				system("/root/Module_EventLogging &");
+
+			if(system("pidof -s Module_PrimaryComm > /dev/null") != 0)
+				system("/root/Module_PrimaryComm &");
+
+			if(system("pidof -s Module_LcmControl > /dev/null") != 0)
+				system("/root/Module_LcmControl &");
+
+            if(system("pidof -s Module_DoComm > /dev/null") != 0)
+                system("/root/Module_DoComm &");
+
+            if(system("pidof -s Module_ProduceUtils > /dev/null") != 0)
+                system("/root/Module_ProduceUtils &");
+
+			*/
+			if (count_evComm < _SYSTEM_TASK_COUNT_EVCOMM )
+			{
+				system("killall Module_EvComm");
+				sleep(3);
+				system("/root/Module_EvComm &");
+			}
+        	if (count_interComm < _SYSTEM_TASK_COUNT_INTERNALCOMM )
+			{
+				system("killall Module_InternalComm");
+				sleep(3);
+				system("/root/Module_InternalComm &");
+			}
+			if (count_eventComm < _SYSTEM_TASK_COUNT_EVENTLOGGING )
+			{
+				system("killall Module_EventLogging");
+				sleep(3);
+				system("/root/Module_EventLogging &");
+			}
+			if (count_primaryComm < _SYSTEM_TASK_COUNT_PRIMARYCOMM )
+			{
+				system("killall Module_PrimaryComm");
+				sleep(3);
+				system("/root/Module_PrimaryComm &");
+			}
+			if (count_lcmComm < _SYSTEM_TASK_COUNT_LCM )
+			{
+				system("killall Module_LcmControl");
+				sleep(3);
+				system("/root/Module_LcmControl &");
+			}
+			if (count_doComm < _SYSTEM_TASK_COUNT_DOCOMM )
+			{
+				system("killall Module_DoComm");
+				sleep(3);
+				system("/root/Module_DoComm &");
+			}
+			if (count_produceComm < _SYSTEM_TASK_COUNT_PRODUCEUTILS )
+			{
+				system("killall Module_ProduceUtils");
+				sleep(3);
+				system("/root/Module_ProduceUtils &");
+			}
+			/*
+			if (count_psuComm < 2)
+			{
+				system("killall Module_PsuComm");
+				sleep(3);
+				system("/root/Module_PsuComm &");
+			}*/
+		}
+
+		sleep(2);
+	}
+
+	if (count_main < _SYSTEM_TASK_COUNT_MAIN)
+		result = _SYSTEM_TASK_LOST_ITEM_MAIN;
+	else if (count_evComm < _SYSTEM_TASK_COUNT_EVCOMM)
+		result = _SYSTEM_TASK_LOST_ITEM_EVCOMM;
+/*	else if (count_psuComm < 2)
+		result = 3; */
+    else if (count_eventComm < _SYSTEM_TASK_COUNT_EVENTLOGGING )
+        result = _SYSTEM_TASK_LOST_ITEM_EVENTLOG;
+    else if (count_primaryComm < _SYSTEM_TASK_COUNT_PRIMARYCOMM)
+        result = _SYSTEM_TASK_LOST_ITEM_PRIMARYCOMM;
+    else if (count_lcmComm < _SYSTEM_TASK_COUNT_LCM)
+        result = _SYSTEM_TASK_LOST_ITEM_LCMCONTROL;
+    else if (count_interComm < 2 )
+        result = _SYSTEM_TASK_LOST_ITEM_INTERCOMM;
+    else if (count_doComm < _SYSTEM_TASK_COUNT_DOCOMM)
+        result = _SYSTEM_TASK_LOST_ITEM_DOCOMM;
+    else if (count_produceComm < _SYSTEM_TASK_COUNT_PRODUCEUTILS)
+        result = _SYSTEM_TASK_LOST_ITEM_PRODUCTUTILS;
+
+	return result;
+}

+ 60 - 0
EVSE/Projects/DD360ComBox/Apps/CSU/CheckSystemTask.h

@@ -0,0 +1,60 @@
+/*
+ * CheckTask.h
+ *
+ *  Created on: 2021年9月2日
+ *      Author: 7564
+ */
+
+#ifndef CHECKTASK_H_
+#define CHECKTASK_H_
+
+#include 	<sys/timeb.h>
+#include 	<sys/types.h>
+#include 	<sys/ioctl.h>
+#include 	<sys/socket.h>
+#include 	<sys/ipc.h>
+#include 	<sys/shm.h>
+#include 	<sys/mman.h>
+#include 	<linux/wireless.h>
+#include 	<arpa/inet.h>
+#include 	<netinet/in.h>
+
+#include 	<unistd.h>
+#include 	<stdarg.h>
+#include    <stdio.h>      /*標準輸入輸出定義*/
+#include    <stdlib.h>     /*標準函數庫定義*/
+#include    <unistd.h>     /*Unix 標準函數定義*/
+#include    <fcntl.h>      /*檔控制定義*/
+#include    <termios.h>    /*PPSIX 終端控制定義*/
+#include    <errno.h>      /*錯誤號定義*/
+#include 	<string.h>
+#include 	<stdint.h>
+#include	<time.h>
+#include	<ctype.h>
+#include 	<ifaddrs.h>
+#include 	<math.h>
+#include 	<stdbool.h>
+#include 	<dirent.h>
+
+#define _SYSTEM_TASK_LOST_ITEM_MAIN         1
+#define _SYSTEM_TASK_LOST_ITEM_EVCOMM       2
+#define _SYSTEM_TASK_LOST_ITEM_EVENTLOG     3
+#define _SYSTEM_TASK_LOST_ITEM_PRIMARYCOMM  4
+#define _SYSTEM_TASK_LOST_ITEM_LCMCONTROL   5
+#define _SYSTEM_TASK_LOST_ITEM_INTERCOMM    6
+#define _SYSTEM_TASK_LOST_ITEM_DOCOMM       7
+#define _SYSTEM_TASK_LOST_ITEM_PRODUCTUTILS 8
+
+#define _SYSTEM_TASK_COUNT_MAIN             5
+#define _SYSTEM_TASK_COUNT_EVCOMM           2
+#define _SYSTEM_TASK_COUNT_INTERNALCOMM     2
+#define _SYSTEM_TASK_COUNT_EVENTLOGGING     1
+#define _SYSTEM_TASK_COUNT_PRIMARYCOMM      1
+#define _SYSTEM_TASK_COUNT_LCM              1
+#define _SYSTEM_TASK_COUNT_DOCOMM           1
+#define _SYSTEM_TASK_COUNT_PRODUCEUTILS     1
+
+
+unsigned char CheckSystemTask(unsigned char systemPage);
+
+#endif /* CHECKSYSTEMTASK_H_ */

+ 12 - 0
EVSE/Projects/DD360ComBox/Apps/CSU/Primary.c

@@ -136,11 +136,15 @@ void PrimaryLedIndicatorCtrlFork(void)
 
                 case S_CHARGING:
                     pLedConfig->RedLED = NO;
+#ifdef DD360ComBox
                     if (pLedConfig->YellowLED == YES) {
                         pLedConfig->YellowLED = NO;
                     } else {
                         pLedConfig->YellowLED = YES;
                     }
+#else
+                        pLedConfig->YellowLED = YES;
+#endif
                     pLedConfig->GreenLED = NO;
                     break;
 
@@ -166,7 +170,15 @@ void PrimaryLedIndicatorCtrlFork(void)
                     //    pLedConfig->RedLED = YES;
                     //} else {
                     pLedConfig->RedLED = NO;
+#ifdef DD360ComBox
                     pLedConfig->YellowLED = YES;
+#else
+                    if (pLedConfig->YellowLED == YES) {
+                        pLedConfig->YellowLED = NO;
+                    } else {
+                        pLedConfig->YellowLED = YES;
+                    }
+#endif
                     pLedConfig->GreenLED = NO;
                     //}
                     break;

+ 15 - 0
EVSE/Projects/DD360ComBox/Apps/CSU/SelfTest.c

@@ -18,6 +18,7 @@ extern void ChkPrimaryStatus(void);
 void SelfTestRun(void)
 {
     bool evInitFlag = false;
+    bool isRelayBypass = false;
     uint8_t index = 0;
     struct SysConfigData *pSysConfig = (struct SysConfigData *)GetShmSysConfigData();
     struct SysInfoData *pSysInfo = (struct SysInfoData *)GetShmSysInfoData();
@@ -34,6 +35,15 @@ void SelfTestRun(void)
     struct ChargingInfoData *pDcChargingInfo = NULL;
     struct ChargingInfoData *pAcChargingInfo = NULL;
 
+    for(int i = 0; i < pSysConfig->TotalConnectorCount; i++)
+    {
+        pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(i);
+        if(pDcChargingInfo->PantographFlag == YES)
+        {
+            isRelayBypass = true;
+        }
+    }
+
     StartSystemTimeoutDet(Timeout_SelftestChk);
     pSysInfo->SelfTestSeq = _STEST_VERSION;
 
@@ -62,6 +72,11 @@ void SelfTestRun(void)
 
         switch (pSysInfo->SelfTestSeq) {
         case _STEST_VERSION:
+            if(isRelayBypass == YES && ShmRelayModuleData->SelfTest_Comp != YES)
+            {
+                log_info("Relay Board Bypass");
+                ShmRelayModuleData->SelfTest_Comp = YES;
+            }
             if ((strlen((char *)pSysInfo->RelayModuleFwRev) != 0 ||
                     pSysInfo->RelayModuleFwRev[0] != '\0') &&
                     (ShmRelayModuleData->SelfTest_Comp != YES)

部分文件因文件數量過多而無法顯示