소스 검색

Merge branch 'DD360Audi'

FolusWen 3 년 전
부모
커밋
e2489f9c5e
95개의 변경된 파일2640개의 추가작업 그리고 504개의 파일을 삭제
  1. 184 0
      EVSE/Projects/DD360/Apps/CSU/CheckSystemTask.c
  2. 60 0
      EVSE/Projects/DD360/Apps/CSU/CheckSystemTask.h
  3. 15 0
      EVSE/Projects/DD360/Apps/CSU/SelfTest.c
  4. 8 0
      EVSE/Projects/DD360/Apps/CSU/UpgradeFW.c
  5. 39 17
      EVSE/Projects/DD360/Apps/CSU/WatchDog.c
  6. 48 0
      EVSE/Projects/DD360/Apps/CSU/WatchDog.c.old
  7. 145 20
      EVSE/Projects/DD360/Apps/CSU/main.c
  8. 106 82
      EVSE/Projects/DD360/Apps/Define/define.h
  9. 4 2
      EVSE/Projects/DD360/Apps/Makefile
  10. 74 6
      EVSE/Projects/DD360/Apps/ModuleDoComm/DoComm.c
  11. 5 0
      EVSE/Projects/DD360/Apps/ModuleDoComm/DoComm.h
  12. 4 2
      EVSE/Projects/DD360/Apps/ModuleEvComm/AbnormalState.c
  13. 14 9
      EVSE/Projects/DD360/Apps/ModuleEvComm/Module_EvTxComm.c
  14. 4 1
      EVSE/Projects/DD360/Apps/ModuleInternalComm/Module_InternalComm.c
  15. 41 4
      EVSE/Projects/DD360/Apps/ModuleInternalComm/RelayBoard.c
  16. 39 0
      EVSE/Projects/DD360/Apps/ModuleLcmCtrl/Module_LcmControl.c
  17. 46 5
      EVSE/Projects/DD360/Apps/ModulePrimary/Module_PrimaryComm.c
  18. 1 0
      EVSE/Projects/DD360/Apps/ModulePrimary/Module_PrimaryComm.h
  19. 4 0
      EVSE/Projects/DD360/Apps/Script/kill.sh
  20. 35 17
      EVSE/Projects/DD360/Apps/ShareMemory/shmMem.c
  21. BIN
      EVSE/Projects/DD360/Apps/UnsafetyOutputTask
  22. BIN
      EVSE/Projects/DD360/Images/ramdisk.gz
  23. BIN
      EVSE/Projects/DD360/output/FactoryConfig
  24. BIN
      EVSE/Projects/DD360/output/Module_DoComm
  25. BIN
      EVSE/Projects/DD360/output/Module_EvComm
  26. BIN
      EVSE/Projects/DD360/output/Module_EventLogging
  27. BIN
      EVSE/Projects/DD360/output/Module_InternalComm
  28. BIN
      EVSE/Projects/DD360/output/Module_LcmControl
  29. BIN
      EVSE/Projects/DD360/output/Module_PrimaryComm
  30. BIN
      EVSE/Projects/DD360/output/ReadCmdline
  31. BIN
      EVSE/Projects/DD360/output/main
  32. 184 0
      EVSE/Projects/DD360Audi/Apps/CSU/CheckSystemTask.c
  33. 60 0
      EVSE/Projects/DD360Audi/Apps/CSU/CheckSystemTask.h
  34. 15 0
      EVSE/Projects/DD360Audi/Apps/CSU/SelfTest.c
  35. 8 0
      EVSE/Projects/DD360Audi/Apps/CSU/UpgradeFW.c
  36. 39 17
      EVSE/Projects/DD360Audi/Apps/CSU/WatchDog.c
  37. 48 0
      EVSE/Projects/DD360Audi/Apps/CSU/WatchDog.c.old
  38. 145 20
      EVSE/Projects/DD360Audi/Apps/CSU/main.c
  39. 106 82
      EVSE/Projects/DD360Audi/Apps/Define/define.h
  40. 4 2
      EVSE/Projects/DD360Audi/Apps/Makefile
  41. 74 6
      EVSE/Projects/DD360Audi/Apps/ModuleDoComm/DoComm.c
  42. 5 0
      EVSE/Projects/DD360Audi/Apps/ModuleDoComm/DoComm.h
  43. 4 2
      EVSE/Projects/DD360Audi/Apps/ModuleEvComm/AbnormalState.c
  44. 14 9
      EVSE/Projects/DD360Audi/Apps/ModuleEvComm/Module_EvTxComm.c
  45. 4 1
      EVSE/Projects/DD360Audi/Apps/ModuleInternalComm/Module_InternalComm.c
  46. 41 4
      EVSE/Projects/DD360Audi/Apps/ModuleInternalComm/RelayBoard.c
  47. 39 0
      EVSE/Projects/DD360Audi/Apps/ModuleLcmCtrl/Module_LcmControl.c
  48. 46 5
      EVSE/Projects/DD360Audi/Apps/ModulePrimary/Module_PrimaryComm.c
  49. 1 0
      EVSE/Projects/DD360Audi/Apps/ModulePrimary/Module_PrimaryComm.h
  50. 4 0
      EVSE/Projects/DD360Audi/Apps/Script/kill.sh
  51. 35 17
      EVSE/Projects/DD360Audi/Apps/ShareMemory/shmMem.c
  52. BIN
      EVSE/Projects/DD360Audi/Images/ramdisk.gz
  53. BIN
      EVSE/Projects/DD360Audi/output/FactoryConfig
  54. BIN
      EVSE/Projects/DD360Audi/output/Module_DoComm
  55. BIN
      EVSE/Projects/DD360Audi/output/Module_EvComm
  56. BIN
      EVSE/Projects/DD360Audi/output/Module_EventLogging
  57. BIN
      EVSE/Projects/DD360Audi/output/Module_InternalComm
  58. BIN
      EVSE/Projects/DD360Audi/output/Module_LcmControl
  59. BIN
      EVSE/Projects/DD360Audi/output/Module_PrimaryComm
  60. BIN
      EVSE/Projects/DD360Audi/output/ReadCmdline
  61. BIN
      EVSE/Projects/DD360Audi/output/main
  62. 0 0
      EVSE/Projects/DD360ComBox/Apps/.metadata/.lock
  63. 184 0
      EVSE/Projects/DD360ComBox/Apps/CSU/CheckSystemTask.c
  64. 60 0
      EVSE/Projects/DD360ComBox/Apps/CSU/CheckSystemTask.h
  65. 11 5
      EVSE/Projects/DD360ComBox/Apps/CSU/Primary.c
  66. 15 0
      EVSE/Projects/DD360ComBox/Apps/CSU/SelfTest.c
  67. 8 0
      EVSE/Projects/DD360ComBox/Apps/CSU/UpgradeFW.c
  68. 39 17
      EVSE/Projects/DD360ComBox/Apps/CSU/WatchDog.c
  69. 48 0
      EVSE/Projects/DD360ComBox/Apps/CSU/WatchDog.c.old
  70. 145 20
      EVSE/Projects/DD360ComBox/Apps/CSU/main.c
  71. 106 82
      EVSE/Projects/DD360ComBox/Apps/Define/define.h
  72. 4 2
      EVSE/Projects/DD360ComBox/Apps/Makefile
  73. 74 6
      EVSE/Projects/DD360ComBox/Apps/ModuleDoComm/DoComm.c
  74. 5 0
      EVSE/Projects/DD360ComBox/Apps/ModuleDoComm/DoComm.h
  75. 4 2
      EVSE/Projects/DD360ComBox/Apps/ModuleEvComm/AbnormalState.c
  76. 14 9
      EVSE/Projects/DD360ComBox/Apps/ModuleEvComm/Module_EvTxComm.c
  77. 4 1
      EVSE/Projects/DD360ComBox/Apps/ModuleInternalComm/Module_InternalComm.c
  78. 41 4
      EVSE/Projects/DD360ComBox/Apps/ModuleInternalComm/RelayBoard.c
  79. 39 0
      EVSE/Projects/DD360ComBox/Apps/ModuleLcmCtrl/Module_LcmControl.c
  80. 46 5
      EVSE/Projects/DD360ComBox/Apps/ModulePrimary/Module_PrimaryComm.c
  81. 1 0
      EVSE/Projects/DD360ComBox/Apps/ModulePrimary/Module_PrimaryComm.h
  82. 4 0
      EVSE/Projects/DD360ComBox/Apps/Script/kill.sh
  83. 35 17
      EVSE/Projects/DD360ComBox/Apps/ShareMemory/shmMem.c
  84. BIN
      EVSE/Projects/DD360ComBox/Apps/UnsafetyOutputTask
  85. BIN
      EVSE/Projects/DD360ComBox/Images/ramdisk.gz
  86. BIN
      EVSE/Projects/DD360ComBox/output/FactoryConfig
  87. BIN
      EVSE/Projects/DD360ComBox/output/Module_DoComm
  88. BIN
      EVSE/Projects/DD360ComBox/output/Module_EvComm
  89. BIN
      EVSE/Projects/DD360ComBox/output/Module_EventLogging
  90. BIN
      EVSE/Projects/DD360ComBox/output/Module_InternalComm
  91. BIN
      EVSE/Projects/DD360ComBox/output/Module_LcmControl
  92. BIN
      EVSE/Projects/DD360ComBox/output/Module_PrimaryComm
  93. BIN
      EVSE/Projects/DD360ComBox/output/ReadCmdline
  94. BIN
      EVSE/Projects/DD360ComBox/output/main
  95. 1 4
      EVSE/Projects/define.h

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

@@ -0,0 +1,184 @@
+/*
+ * CheckTask.c
+ *
+ *  Created on: 2021922
+ *      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_ */

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

+ 46 - 5
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];
 
 //------------------------------------------------------------------------------
@@ -182,11 +187,26 @@ 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)
 #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
+       }
+    } else if (EmgBtn_flag != gpio_in.Emergency_Btn) {
+        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 +239,31 @@ void GetInputGpioStatus(int fd)
     }
 
 #if defined DD360ComBox
-    ShmPrimaryMcuData->InputDet.bits.DoorOpen = gpio_in.Door_Open;
+    if (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
+       }
+    } else if (gpio_in.Door_Open && Door_flag) {
+        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;
         }

BIN
EVSE/Projects/DD360/Apps/UnsafetyOutputTask


BIN
EVSE/Projects/DD360/Images/ramdisk.gz


BIN
EVSE/Projects/DD360/output/FactoryConfig


BIN
EVSE/Projects/DD360/output/Module_DoComm


BIN
EVSE/Projects/DD360/output/Module_EvComm


BIN
EVSE/Projects/DD360/output/Module_EventLogging


BIN
EVSE/Projects/DD360/output/Module_InternalComm


BIN
EVSE/Projects/DD360/output/Module_LcmControl


BIN
EVSE/Projects/DD360/output/Module_PrimaryComm


BIN
EVSE/Projects/DD360/output/ReadCmdline


BIN
EVSE/Projects/DD360/output/main


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

@@ -0,0 +1,184 @@
+/*
+ * CheckTask.c
+ *
+ *  Created on: 2021922
+ *      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_ */

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

+ 46 - 5
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];
 
 //------------------------------------------------------------------------------
@@ -182,11 +187,26 @@ 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)
 #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
+       }
+    } else if (EmgBtn_flag != gpio_in.Emergency_Btn) {
+        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 +239,31 @@ void GetInputGpioStatus(int fd)
     }
 
 #if defined DD360ComBox
-    ShmPrimaryMcuData->InputDet.bits.DoorOpen = gpio_in.Door_Open;
+    if (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
+       }
+    } else if (gpio_in.Door_Open && Door_flag) {
+        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;
         }

BIN
EVSE/Projects/DD360Audi/Images/ramdisk.gz


BIN
EVSE/Projects/DD360Audi/output/FactoryConfig


BIN
EVSE/Projects/DD360Audi/output/Module_DoComm


BIN
EVSE/Projects/DD360Audi/output/Module_EvComm


BIN
EVSE/Projects/DD360Audi/output/Module_EventLogging


BIN
EVSE/Projects/DD360Audi/output/Module_InternalComm


BIN
EVSE/Projects/DD360Audi/output/Module_LcmControl


BIN
EVSE/Projects/DD360Audi/output/Module_PrimaryComm


BIN
EVSE/Projects/DD360Audi/output/ReadCmdline


BIN
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: 2021922
+ *      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_ */

+ 11 - 5
EVSE/Projects/DD360ComBox/Apps/CSU/Primary.c

@@ -136,11 +136,11 @@ void PrimaryLedIndicatorCtrlFork(void)
 
                 case S_CHARGING:
                     pLedConfig->RedLED = NO;
-                    if (pLedConfig->YellowLED == YES) {
-                        pLedConfig->YellowLED = NO;
-                    } else {
+                    //if (pLedConfig->YellowLED == YES) {
+                    //    pLedConfig->YellowLED = NO;
+                    //} else {
                         pLedConfig->YellowLED = YES;
-                    }
+                    //}
                     pLedConfig->GreenLED = NO;
                     break;
 
@@ -166,7 +166,13 @@ void PrimaryLedIndicatorCtrlFork(void)
                     //    pLedConfig->RedLED = YES;
                     //} else {
                     pLedConfig->RedLED = NO;
-                    pLedConfig->YellowLED = YES;
+                    //pLedConfig->YellowLED = YES;
+                    if (pLedConfig->YellowLED == YES) {
+                        pLedConfig->YellowLED = NO;
+                    } else {
+                        pLedConfig->YellowLED = YES;
+                    }
+
                     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)

+ 8 - 0
EVSE/Projects/DD360ComBox/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/DD360ComBox/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/DD360ComBox/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/DD360ComBox/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/DD360ComBox/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/DD360ComBox/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/DD360ComBox/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/DD360ComBox/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/DD360ComBox/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/DD360ComBox/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/DD360ComBox/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/DD360ComBox/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/DD360ComBox/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					
                 }
             }
         }

+ 46 - 5
EVSE/Projects/DD360ComBox/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];
 
 //------------------------------------------------------------------------------
@@ -182,11 +187,26 @@ 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)
 #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
+       }
+    } else if (EmgBtn_flag != gpio_in.Emergency_Btn) {
+        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 +239,31 @@ void GetInputGpioStatus(int fd)
     }
 
 #if defined DD360ComBox
-    ShmPrimaryMcuData->InputDet.bits.DoorOpen = gpio_in.Door_Open;
+    if (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
+       }
+    } else if (gpio_in.Door_Open && Door_flag) {
+        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/DD360ComBox/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/DD360ComBox/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/DD360ComBox/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;
         }

BIN
EVSE/Projects/DD360ComBox/Apps/UnsafetyOutputTask


BIN
EVSE/Projects/DD360ComBox/Images/ramdisk.gz


BIN
EVSE/Projects/DD360ComBox/output/FactoryConfig


BIN
EVSE/Projects/DD360ComBox/output/Module_DoComm


BIN
EVSE/Projects/DD360ComBox/output/Module_EvComm


BIN
EVSE/Projects/DD360ComBox/output/Module_EventLogging


BIN
EVSE/Projects/DD360ComBox/output/Module_InternalComm


BIN
EVSE/Projects/DD360ComBox/output/Module_LcmControl


BIN
EVSE/Projects/DD360ComBox/output/Module_PrimaryComm


BIN
EVSE/Projects/DD360ComBox/output/ReadCmdline


BIN
EVSE/Projects/DD360ComBox/output/main


+ 1 - 4
EVSE/Projects/define.h

@@ -638,6 +638,7 @@ struct ChargingInfoData
     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
@@ -6053,7 +6054,3 @@ struct OCPP20Data
 };
 
 #endif // DEFINE_H_
-
-
-
-