Browse Source

2021-01-15 / Wendell
Actions
1. fix internet connected status logic
2. start charging directly when remote start
3. add fault status replace original alarm status
4. modify alarm status behavior
5. add psu exception process to restart all psu when error occur
6. bypass soc to ocpp module
7. add check psu task function to avoid No-Psu-Resource event

Files
1. As follow commit history

Image version : D0.09.XX.XXXX.XX

Wendell 4 years ago
parent
commit
fede739f59

+ 36 - 40
EVSE/Modularization/Infypwr_PsuCommObj.c

@@ -1,7 +1,7 @@
 /*
  * Infypwr_PsuCommObj.c
  *
- *  Created on: 2019¦~11¤ë26¤é
+ *  Created on: 2019年11月26日
  *      Author: 7564
  */
 
@@ -17,7 +17,7 @@ void PRINTF_LIB_FUNC(char *string, ...);
 float IEEE_754_to_float(const byte raw[4]);
 void IEEE_754_to_bytes(float target, byte *bytes2);
 
-// ³]³Æ¸¹ 0x09 »P 0x0C ¦ü¥G¬O¼Ò¶ô
+// 設備號 0x09 與 0x0C 似乎是模塊
 unsigned int filter[3] = { 0x87570000, 0x8E9B0000, 0x829B0000 };
 
 //================================================
@@ -346,7 +346,7 @@ void ReceiveDataFromCanBus()
 
 				case INFYPWR_GROUP_SHIFT | MODULE_COUNT:
 				{
-					// ¦^¶Ç¼Ò²Õ¼Æ¶q
+					// 回傳模組數�
 					group = frame.can_id & 0x000000FF;
 
 					byte count = frame.data[2];
@@ -366,7 +366,7 @@ void ReceiveDataFromCanBus()
 					if (!colFinished)
 						break;
 
-					// ¦^¶Ç¿é¥X¯à¤O : ³Ì¤j¹qÀ£¡B³Ì¤p¹qÀ£¡B³Ì¤j¹q¬y¡BÃB©w¥\²v
+					// 回傳輸出能力 : 最大電壓�最�電壓�最大電���定功率
 					address = frame.can_id & 0x000000FF;
 					if(!GetRealIndexByGroup(&address))
 						break;
@@ -384,7 +384,7 @@ void ReceiveDataFromCanBus()
 
 				case INFYPWR_GROUP_SHIFT | MODULE_OUTPUT_VOL_CUR:
 				{
-					// ¦^¶Ç·í«e¿é¥X¹qÀ£¹q¬y
+					// 回傳當�輸出電壓電�
 					address = frame.can_id & 0x000000FF;
 
 					int outputVol = ((frame.data[0] << 24) + (frame.data[1] << 16) + (frame.data[2] << 8) + frame.data[3]) / 100;
@@ -414,7 +414,7 @@ void ReceiveDataFromCanBus()
 					if (!colFinished)
 						break;
 
-					// ¦^¶Ç­°¸ü«áªº¹q¬y
+					// 回傳�載後的電�
 					address = frame.can_id & 0x000000FF;
 					if(!GetRealIndexByGroup(&address))
 						break;
@@ -468,7 +468,7 @@ void ReceiveDataFromCanBus()
 					if (!colFinished)
 						break;
 
-					// ¦^¶Çª©¸¹ : µL¨t²Î¦^ÂÐ¥\¯à
+					// 回傳版號 : 無系統回覆功能
 					address = frame.can_id & 0x000000FF;
 					if(!GetRealIndexByGroup(&address))
 						break;
@@ -484,7 +484,7 @@ void ReceiveDataFromCanBus()
 
 				case INFYPWR_GROUP_SHIFT | MODULE_BARCODE:
 				{
-					// ¦^¶ÇBarCode
+					// 回傳BarCode
 				}
 					break;
 
@@ -493,7 +493,7 @@ void ReceiveDataFromCanBus()
 					if (!colFinished)
 						break;
 
-					// ¦^¶Ç¤T¦V¿é¤J¹qÀ£
+					// 回傳三�輸入電壓
 					address = frame.can_id & 0x000000FF;
 					if(!GetRealIndexByGroup(&address))
 						break;
@@ -512,7 +512,7 @@ void ReceiveDataFromCanBus()
 						break;
 
 					/*Test mode used*/
-					// ¦^¶Ç¿é¥X­È»P¤J­·¤f·Å«×
+					// 回傳輸出值與入風�溫度
 					address = frame.can_id & 0x000000FF;
 					if(!GetRealIndexByGroup(&address))
 						break;
@@ -532,7 +532,7 @@ void ReceiveDataFromCanBus()
 						break;
 
 					/*Test mode used*/
-					// ¦^¶Ç¿é¥X­È»P¤J­·¤f·Å«×
+					// 回傳輸出值與入風�溫度
 					address = frame.can_id & 0x000000FF;
 					if(!GetRealIndexByGroup(&address))
 						break;
@@ -554,7 +554,7 @@ void ReceiveDataFromCanBus()
 						break;
 
 					/*Test mode used*/
-					// ¦^¶Ç¿é¥X­È»P¤J­·¤f·Å«×
+					// 回傳輸出值與入風�溫度
 					address = frame.can_id & 0x000000FF;
 					if(!GetRealIndexByGroup(&address))
 						break;
@@ -581,7 +581,7 @@ void SendCmdToPsu(int cmd, byte *data, byte dataLen)
 {
     struct can_frame frame;
 
-    //³]©w CANBSU 2.0B ªø«Ê¥]
+    //設定 CANBSU 2.0B 長�包
     cmd = cmd | 0x80000000;
 
     frame.can_id = cmd;
@@ -589,7 +589,7 @@ void SendCmdToPsu(int cmd, byte *data, byte dataLen)
     memcpy(frame.data, data, dataLen);
 
     write(CanFd, &frame, sizeof(struct can_frame));
-    // ¸s©R¥O¤~ delay
+    // 群命令� delay
     if ((cmd & 0x0000FF00) == INFYPWR_BROADCAST)
     	usleep(CMD_DELAY_TIME);
 }
@@ -605,14 +605,10 @@ bool InitialCommunication()
 	}
 
     recFork = fork();
-    if(recFork > 0)
+    if(recFork == 0)
     {
     	ReceiveDataFromCanBus();
 	}
-    else if(recFork > 0)
-    {
-    	PRINTF_LIB_FUNC("fork fail\n");
-    }
 
     return true;
 }
@@ -626,8 +622,8 @@ void SwitchPower(byte group, byte value)
 	uint cmd = INFYPWR_CMD | SWITCH_POWER;
 
 	memset(data, 0x00, ARRAY_SIZE(data));
-	// 1 : Ãö¾÷
-	// 0 : ¶}¾÷
+	// 1 : 關機
+	// 0 : é–‹æ©Ÿ
 	data[0] = value;
 
 	if (group == SYSTEM_CMD)
@@ -643,8 +639,8 @@ void SleepMode(byte group, byte value)
 	uint cmd = INFYPWR_CMD | SLEEP_MODE;
 
 	memset(data, 0x00, ARRAY_SIZE(data));
-	// 1 : ¥ð¯v
-	// 0 : °_§É
+	// 1 : 休眠
+	// 0 : 起床
 	data[0] = value;
 
 	if (group == SYSTEM_CMD)
@@ -660,8 +656,8 @@ void FlashLed(byte group, byte value)
 	uint cmd = INFYPWR_CMD | FLASH_LED;
 
 	memset(data, 0x00, ARRAY_SIZE(data));
-	// 1 : °{Ã{
-	// 0 : ¥¿±`
+	// 1 : 閃�
+	// 0 : 正常
 	data[0] = value;
 
 	if (group == SYSTEM_CMD)
@@ -680,12 +676,12 @@ void PresentOutputVol(byte group, int voltage, int current)
 
 	memset(data, 0x00, ARRAY_SIZE(data));
 
-	// ¿é¥X¹qÀ£
+	// 輸出電壓
 	data[0] = (Vol >> 24) & 0xFF;
 	data[1] = (Vol >> 16) & 0xFF;
 	data[2] = (Vol >> 8) & 0xFF;
 	data[3] = Vol & 0xFF;
-	// ¿é¥X¹q¬y
+	// 輸出電�
 	data[4] = (Cur >> 24) & 0xFF;
 	data[5] = (Cur >> 16) & 0xFF;
 	data[6] = (Cur >> 8) & 0xFF;
@@ -705,7 +701,7 @@ void FanNoiseInfo(byte group, byte value)
 
 	memset(data, 0x00, ARRAY_SIZE(data));
 
-	// ­·®°§C¾¸­µ
+	// 風扇低噪音
 	data[0] = 0x11;
 	data[1] = 0x13;
 
@@ -752,13 +748,13 @@ void SetDirModulePresentOutput(byte group, int voltage, int current, byte _switc
 
 	memset(data, 0x00, ARRAY_SIZE(data));
 
-	// ¿é¥X¹qÀ£
+	// 輸出電壓
 	data[0] = (voltage >> 8) & 0xFF;
 	data[1] = voltage & 0xFF;
-	// ¿é¥X¹q¬y
+	// 輸出電�
 	data[2] = (current >> 8) & 0xFF;
 	data[3] = current & 0xFF;
-	// ¶} / Ãö
+	// 開 / 關
 	data[4] = _switch;
 	// Internal Relay
 	data[5] = _interRelay;
@@ -772,14 +768,14 @@ void SetDirModulePresentOutput(byte group, int voltage, int current, byte _switc
 
 void SetDipSwitchMode()
 {
-	byte data[8];
-	uint cmd = INFYPWR_CMD | DIP_SWITCH_MODE;
+    byte data[8];
+    uint cmd = INFYPWR_CMD | DIP_SWITCH_MODE;
 
-	memset(data, 0x00, ARRAY_SIZE(data));
-	data[0] = 0x01;
+    memset(data, 0x00, ARRAY_SIZE(data));
+    data[0] = 0x01;
 
-	cmd |= INFYPWR_BROADCAST | INFYPWR_DEFAULT;
-	SendCmdToPsu(cmd, data, sizeof(data));
+    cmd |= INFYPWR_BROADCAST | INFYPWR_DEFAULT;
+    SendCmdToPsu(cmd, data, sizeof(data));
 }
 /**********************************************************************************/
 /***                                                                            ***/
@@ -870,7 +866,7 @@ void GetModuleCount(byte group)
 
 void GetModuleVer(byte group)
 {
-	// µL¨t²Î¼s¼½¥\¯à
+	// 無系統廣播功能
 	byte data[8];
 	uint cmd = INFYPWR_CMD | MODULE_VER;
 
@@ -895,7 +891,7 @@ void GetModuleCap(byte group)
 
 void GetModuleBarCode(byte group)
 {
-	// µL¨t²Î¼s¼½¥\¯à
+	// 無系統廣播功能
 	byte data[8];
 	uint cmd = INFYPWR_CMD | MODULE_BARCODE;
 
@@ -907,7 +903,7 @@ void GetModuleBarCode(byte group)
 
 void GetModuleInput(byte group)
 {
-	// µL¨t²Î¼s¼½¥\¯à
+	// 無系統廣播功能
 	byte data[8];
 	uint cmd = INFYPWR_CMD | MODULE_INPUT;
 

+ 32 - 32
EVSE/Modularization/Infypwr_PsuCommObj.h

@@ -1,7 +1,7 @@
 /*
  * Infypwr_PsuCommObj.h
  *
- *  Created on: 2019¦~11¤ë26¤é
+ *  Created on: 2019年11月26日
  *      Author: 7564
  */
 
@@ -26,12 +26,12 @@
 #include 	<stdbool.h>
 #include 	<unistd.h>
 #include 	<stdarg.h>
-#include    <stdio.h>      /*¼Ð·Ç¿é¤J¿é¥X©w¸q*/
-#include    <stdlib.h>     /*¼Ð·Ç¨ç¼Æ®w©w¸q*/
-#include    <unistd.h>     /*Unix ¼Ð·Ç¨ç¼Æ©w¸q*/
-#include    <fcntl.h>      /*Àɱ±¨î©w¸q*/
-#include    <termios.h>    /*PPSIX ²×ºÝ±±¨î©w¸q*/
-#include    <errno.h>      /*¿ù»~¸¹©w¸q*/
+#include    <stdio.h>      /*標準輸入輸出定義*/
+#include    <stdlib.h>     /*標準函數庫定義*/
+#include    <unistd.h>     /*Unix 標準函數定義*/
+#include    <fcntl.h>      /*檔控制定義*/
+#include    <termios.h>    /*PPSIX 終端控制定義*/
+#include    <errno.h>      /*錯誤號定義*/
 #include 	<errno.h>
 #include 	<string.h>
 #include	<time.h>
@@ -87,35 +87,35 @@ enum PSU_FAN_NOISE_CMD
 
 enum PSU_SET_CMD
 {
-	MIS_INFO = 					0x008F0000,		// ²{¦b¥u¯à§ïÅÜ­°¾¸¼Ò¦¡
-	FLASH_LED = 				0x00940000,
-	WALK_IN_MODE = 				0x00930000,
-	SLEEP_MODE =  	            0x00990000,		// ·í SWITCH POWER ¥´¶}®É¡A¥i³z¹L¸Ó«ü¥OÅý¼Ò¶ô¥ð¯v (­·®°·|°±)
-    SWITCH_POWER = 	            0x009A0000,		// ¥´¶}¡A«h¼Ò¶ô¨Ì·Ó³]©wªº¿é¥X¥\²v¿é¥X
-	PRESENT_OUT_VOL = 			0x009B0000,
-	DIP_SWITCH_MODE	=			0x009F0000,		// ³]©w©Ò¦³¼Ò¶ôªº¦a§}¬°¼·½X¤è¦¡
-	/*Ver : 9.06 used*/
-	TEST_PRESENT_OUT = 			0x180100E5,
-	/*Upgrade*/
-	CHANGE_BAUDRATE = 			0x028F0000
+    MIS_INFO =                  0x008F0000,     // �在�能改變�噪模�
+    FLASH_LED =                 0x00940000,
+    WALK_IN_MODE =              0x00930000,
+    SLEEP_MODE =                0x00990000,     // 當 SWITCH POWER 打開時,���該指令讓模塊休眠 (風扇會�)
+    SWITCH_POWER =              0x009A0000,     // 打開,則模塊�照設定的輸出功率輸出
+    PRESENT_OUT_VOL =           0x009B0000,
+    DIP_SWITCH_MODE =           0x009F0000,     // 設定所有模塊的地�為撥碼方�
+    /*Ver : 9.06 used*/
+    TEST_PRESENT_OUT =          0x180100E5,
+    /*Upgrade*/
+    CHANGE_BAUDRATE =           0x028F0000
 };
 
 enum PSU_GET_CMD
 {
-	MODULE_OUTPUT_VOL_CUR_FLOAT = 	0x00810000,		// ¨ú±o·í«e¿é¥X¹qÀ£¹q¬y (float)
-	MODULE_COUNT = 	            	0x00820000,		// ¨ú±o¼Ò¶ô¼Æ¶q
-	STATUS = 						0x00840000,		// ¨ú±o·Å«×¡Bª¬ºA
-	MODULE_INPUT = 					0x00860000,		// ¨ú±o¤T¦V¿é¤J¹qÀ£
-	MODULE_VER = 					0x00870000,		// ¨ú±oª©¸¹
-	MODULE_OUTPUT_VOL_CUR = 		0x00880000,		// ¨ú±o·í«e¿é¥X¹qÀ£¹q¬y
-	MODULE_CAP = 					0x008A0000,		// ¨ú±o·í«e Group ªº³Ì¤j¹qÀ£¡B³Ì¤j¹q¬y¡B³Ì¤p¹qÀ£¡BÃB©w¥\²v
-	MODULE_BARCODE =				0x008B0000,		// ¨ú±o BarCode
-	MODULE_IAVAILABLE =				0x008C0000,		// ¨ú±o¹ê»Ú¼Ò¶ô¥i¿é¥Xªº¹q¬y¯à¤O (­°¸ü)
-	MODULE_MIS_INFO = 				0x008E0000,		// ¨ú±o¼Ò¶ô¸ê°T (Tdc¡BTpfc¡B­·®°³t«×)
-	/*Ver : 9.06 used*/
-	AUTO_OUTPUT_TEMP = 				0x00010000,
-	AUTO_MODULE_STATUS = 			0x00020000,
-	AUTO_MODULE_INPUT = 			0x00030000,
+    MODULE_OUTPUT_VOL_CUR_FLOAT =   0x00810000,     // �得當�輸出電壓電� (float)
+    MODULE_COUNT =                  0x00820000,     // �得模塊數�
+    STATUS =                        0x00840000,     // �得溫度�狀態
+    MODULE_INPUT =                  0x00860000,     // �得三�輸入電壓
+    MODULE_VER =                    0x00870000,     // �得版號
+    MODULE_OUTPUT_VOL_CUR =         0x00880000,     // �得當�輸出電壓電�
+    MODULE_CAP =                    0x008A0000,     // �得當� Group 的最大電壓�最大電��最�電壓��定功率
+    MODULE_BARCODE =                0x008B0000,     // �得 BarCode
+    MODULE_IAVAILABLE =             0x008C0000,     // �得實際模塊�輸出的電�能力 (�載)
+    MODULE_MIS_INFO =               0x008E0000,     // �得模塊資訊 (Tdc�Tpfc�風扇速度)
+    /*Ver : 9.06 used*/
+    AUTO_OUTPUT_TEMP =              0x00010000,
+    AUTO_MODULE_STATUS =            0x00020000,
+    AUTO_MODULE_INPUT =             0x00030000,
 };
 
 union FloatingPointIEEE754

+ 51 - 8
EVSE/Projects/DO360/Apps/Module_EvComm.c

@@ -1026,9 +1026,9 @@ void ChargingCapabilityResponse(int socket, struct PACKET_STRUCTURE *packet)
 	cost = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].TotalCost;
 	account = ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].AccountBalance;
 
-	if(ConnectorCapability[packet->Header.id - 1].MaxOuputVoltage != voltage ||
-        ConnectorCapability[packet->Header.id - 1].MaxOuputCurrent != current ||
-        ConnectorCapability[packet->Header.id - 1].MaxOuputPower != power)
+	if((ConnectorCapability[packet->Header.id - 1].MaxOuputVoltage / 10) != (voltage / 10) ||
+        (ConnectorCapability[packet->Header.id - 1].MaxOuputCurrent / 10) != (current / 10) ||
+        (ConnectorCapability[packet->Header.id - 1].MaxOuputPower / 10) != (power / 10))
 	{
 	    PRINTF_FUNC("Connector %d Capability Voltage: %d, Current: %d, Power: %d", packet->Header.id, (int)(voltage), (int)(current), (int)(power));
 	}
@@ -1226,6 +1226,28 @@ void MiscControlResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned c
             AddMiscCommand(&sendBuffer, &misc);
         }
 
+//        if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.RemoteStopRequest)
+//        {
+//            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.RemoteStopRequest = false;
+//            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.RemoteStopConfirm = true;
+//            misc.Command = _MiscCmd_RemoteStop;
+//            misc.Value = true;
+
+//            PRINTF_FUNC("Announce Connector %d Remote Stop: %d", packet->Header.id, misc.Value);
+//            AddMiscCommand(&sendBuffer, &misc);
+//        }
+
+//        if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.UnlockStopRequest)
+//        {
+//            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.UnlockStopRequest = false;
+//            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.UnlockStopConfirm = true;
+//            misc.Command = _MiscCmd_UnlockStop;
+//            misc.Value = true;
+
+//            PRINTF_FUNC("Announce Connector %d Unlock Stop: %d", packet->Header.id, misc.Value);
+//            AddMiscCommand(&sendBuffer, &misc);
+//        }
+
         if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.AccountBalanceRequest)
         {
             ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.AccountBalanceRequest = false;
@@ -1707,7 +1729,8 @@ BOOL ConnectorChargingTargetHandler(struct PACKET_STRUCTURE *packet, unsigned ch
 		ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteLimitVoltage = voltage;
 		ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteLimitCurrent = current;
 
-		if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.SystemStatus == S_CHARGING)
+		if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.SystemStatus == S_PREPARING_FOR_EVSE ||
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.SystemStatus == S_CHARGING)
 		{
 		    float targetVol = (float)(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteLimitVoltage / 10);
 		    float targetCur = (float)(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteLimitCurrent / 10);
@@ -1818,7 +1841,7 @@ BOOL ConnectorStateHandler(struct PACKET_STRUCTURE *packet, unsigned char dispen
 				packet->Payload.data[0] == _CRS_Terminating)
 			{
 			    PRINTF_FUNC("*********** Connector id %d Set Stop Flag ***********\n", packet->Header.id);
-				ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.StopChargeFlag = true;
+				ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.ChargingStopFlag.bits.NormalStop = true;
 			}
 		}
 		ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus = packet->Payload.data[0];
@@ -1901,6 +1924,13 @@ unsigned char ChargingPermissionHandler(struct PACKET_STRUCTURE *packet, unsigne
                 }
                 break;
 
+            case S_AUTHORIZING:
+            case S_REASSIGN_CHECK:
+            case S_REASSIGN:
+            case S_PREPARNING:
+                permission = _DAS_Wait;
+                break;
+
             case S_PREPARING_FOR_EV:
                 if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.RemoteStopRequest ||
                     ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.UnlockStopRequest)
@@ -1932,6 +1962,10 @@ unsigned char ChargingPermissionHandler(struct PACKET_STRUCTURE *packet, unsigne
                 }
                 break;
 
+            case S_PREPARING_FOR_EVSE:
+                permission = _DAS_Allowed;
+                break;
+
             case S_CHARGING:
                 if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.RemoteStopRequest ||
                     ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.UnlockStopRequest)
@@ -1960,6 +1994,7 @@ unsigned char ChargingPermissionHandler(struct PACKET_STRUCTURE *packet, unsigne
             case S_TERMINATING:
             case S_COMPLETE:
             case S_ALARM:
+            case S_FAULT:
             case S_RESERVATION:
             case S_MAINTAIN:
                 permission = _DAS_NotAllowed;
@@ -2115,13 +2150,21 @@ unsigned char DispenserWriteChargingInfoHandler(struct PACKET_STRUCTURE *packet,
     {
         unsigned short voltage = (packet->Payload.data[0] << 8) + (packet->Payload.data[1]);
         unsigned short current = (packet->Payload.data[2] << 8) + (packet->Payload.data[3]);
-        unsigned int time = (packet->Payload.data[4] << 24) + (packet->Payload.data[5] << 16) + (packet->Payload.data[6] << 8) + (packet->Payload.data[7]);
+        //unsigned int time = (packet->Payload.data[4] << 24) + (packet->Payload.data[5] << 16) + (packet->Payload.data[6] << 8) + (packet->Payload.data[7]);
         unsigned char soc = (packet->Payload.data[8]);
 
+        if((ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteChargingVoltage / 10) != (voltage / 10) ||
+            (ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteChargingCurrent / 10) != (current / 10) ||
+            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteSoc != soc)
+        {
+            PRINTF_FUNC("Connector %d Charging Info: Voltage %4dV Current %4dA Soc %d\% ", packet->Header.id, voltage, current, soc);
+        }
+
         ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteChargingVoltage = voltage;
         ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteChargingCurrent = current;
-        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteRemainChargingDuration = time;
+        //ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteRemainChargingDuration = time;
         ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteSoc = soc;
+        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.EvBatterySoc = soc;
     }
     else
     {
@@ -2564,7 +2607,7 @@ void tcpSocketServerStart(void)
 	bind(sockFd, (struct sockaddr *)&serverInfo, sizeof(serverInfo));
 	listen(sockFd, CONNECTION_LIMIT);
 
-	PRINTF_FUNC("TCP Server Start\n");
+	PRINTF_FUNC("TCP Server Start");
 
 	signal(SIGCHLD, SIG_IGN);
 	// Main loop

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

@@ -169,6 +169,8 @@ enum MiscCommand
     _MiscCmd_HardwareReboot     = 0x0101,
     _MiscCmd_SoftwareRestart    = 0x0102,
     _MiscCmd_RemoteStart        = 0x0103,
+    _MiscCmd_RemoteStop         = 0x0104,
+    _MiscCmd_UnlockStop         = 0x0105,
 };
 
 struct ChargingCapabilityResponse

+ 36 - 3
EVSE/Projects/DO360/Apps/Module_EventLogging.c

@@ -36,6 +36,7 @@
 
 struct SysConfigAndInfo			*ShmSysConfigAndInfo;
 struct StatusCodeData 			*ShmStatusCodeData;
+struct StatusCodeData           StatusCodeDisableMask;
 
 void PRINTF_FUNC(char *string, ...);
 
@@ -229,6 +230,32 @@ int main(void)
 		return 0;
 	}
 
+	memset((char *)&StatusCodeDisableMask, 0x00, sizeof(struct StatusCodeData));
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuFuseBurnOut = YES;
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuPfcAndDcdcCommFault = YES;
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuBusVoltageUnbalance = YES;
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuBusOverVoltage = YES;
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuBusVoltageAbnormal = YES;
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuInputOVP = YES;
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuDuplicateID = YES;
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuBusUnderVoltage = YES;
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuInputPhaseLoss = YES;
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuInputUVP = NO;
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuCommunicationFail = YES;
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuSevereUnevenCurrent = YES;
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuFfcSideShutDown = YES;
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuFanFullSpeed = YES;
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = YES;
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuPowerLimitedState = YES;
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuTemperaturePowerLimit = YES;
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuAcPowerLimit = YES;
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuDcdcEepromFault = YES;
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuFanFailureAlarm = YES;
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuOutputShortCircuit = YES;
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuPfcEepromFault = YES;
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuCriticalPointOTP = YES;
+	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuDcdcOverVoltage = YES;
+
 	for(;;)
 	{
 	    if(MiscRequirement != ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.MiscNeedAnnouncement)
@@ -298,7 +325,7 @@ int main(void)
 		}
 
 		//check Alarm Status
-		for(ByteCount=0;ByteCount<13;ByteCount++)
+		for(ByteCount=0;ByteCount<16;ByteCount++)
 		{
 			if(ShmStatusCodeData->AlarmCode.AlarmEvents.AlarmVal[ByteCount] != ShmStatusCodeData->AlarmCode.PreviousAlarmVal[ByteCount])
 			{
@@ -314,13 +341,19 @@ int main(void)
 							//EventCodeTmp[0]=1;
 							DEBUG_INFO("Recovery Alarm Code = %s\n", EventCodeTmp);
 							ShmStatusCodeData->AlarmCode.PreviousAlarmVal[ByteCount] &= ~(1<<BitCount);
-							RemoveFaultCodeToBuf(EventCodeTmp);
+							if(!(StatusCodeDisableMask.AlarmCode.AlarmEvents.AlarmVal[ByteCount] & (1<<BitCount)))
+							{
+							    RemoveFaultCodeToBuf(EventCodeTmp);
+							}
 						}
 						else
 						{
 							DEBUG_INFO("Alarm Code = %s\n", EventCodeTmp);
 							ShmStatusCodeData->AlarmCode.PreviousAlarmVal[ByteCount] |= (1<<BitCount);
-							AddFaultCodeToBuf(EventCodeTmp);
+							if(!(StatusCodeDisableMask.AlarmCode.AlarmEvents.AlarmVal[ByteCount] & (1<<BitCount)))
+							{
+							    AddFaultCodeToBuf(EventCodeTmp);
+							}
 						}
 					}
 				}

+ 131 - 46
EVSE/Projects/DO360/Apps/Module_InternalComm.c

@@ -153,6 +153,7 @@ Gpio_in gpio_in;
 Gpio_out gpio_out;
 Relay outputRelay[2];
 Relay regRelay[2];
+Relay TempRegRelay[2];
 Rtc rtc;
 Led_Color cur_led_color;
 Led_Color led_color;
@@ -1097,7 +1098,8 @@ void SetK1K2RelayStatus(byte index)
 		}
 	}
 	else if ((_chargingData[index]->SystemStatus >= S_TERMINATING &&
-			_chargingData[index]->SystemStatus <= S_COMPLETE))
+			_chargingData[index]->SystemStatus <= S_COMPLETE) ||
+            _chargingData[index]->SystemStatus == S_ALARM)
 	{
 		if ((_chargingData[index]->PresentChargingCurrent * 10) <= SEFETY_SWITCH_RELAY_CUR)
 		{
@@ -1181,8 +1183,8 @@ void SetParalleRelayStatus()
 	if (gunCount >= 2)
 	{
 		if (_chargingData[0]->SystemStatus == S_BOOTING || _chargingData[1]->SystemStatus == S_BOOTING ||
-				((_chargingData[0]->SystemStatus == S_IDLE || _chargingData[0]->SystemStatus == S_MAINTAIN) &&
-				(_chargingData[1]->SystemStatus == S_IDLE || _chargingData[1]->SystemStatus == S_MAINTAIN)))
+				((_chargingData[0]->SystemStatus == S_IDLE || _chargingData[0]->SystemStatus == S_MAINTAIN || _chargingData[0]->SystemStatus == S_FAULT) &&
+				(_chargingData[1]->SystemStatus == S_IDLE || _chargingData[1]->SystemStatus == S_MAINTAIN || _chargingData[0]->SystemStatus == S_FAULT)))
 		{
 			// 初始化~ 不搭橋接
 			if (regRelay[0].relay_event.bits.Gun1_Parallel_P == YES)
@@ -1737,25 +1739,95 @@ bool IsNoneMatchRelayStatus(byte index)
 		(regRelay[index].relay_event.bits.Gun2_Parallel_N != outputRelay[index].relay_event.bits.Gun2_Parallel_N))
 	{
 		if (regRelay[index].relay_event.bits.AC_Contactor != outputRelay[index].relay_event.bits.AC_Contactor)
-			PRINTF_FUNC("[%d]AC Contact Relay none match. \n", index);
+		{
+		    if(TempRegRelay[index].relay_event.bits.AC_Contactor != outputRelay[index].relay_event.bits.AC_Contactor)
+		    {
+		        PRINTF_FUNC("[%d]AC Contact Relay none match, need to %s", index,
+                    outputRelay[index].relay_event.bits.AC_Contactor == YES ? "On" : "Off");
+		        TempRegRelay[index].relay_event.bits.AC_Contactor = outputRelay[index].relay_event.bits.AC_Contactor;
+		    }
+		}
 		if (regRelay[index].relay_event.bits.CCS_Precharge != outputRelay[index].relay_event.bits.CCS_Precharge)
-			PRINTF_FUNC("[%d]CCS Precharge Relay none match. \n", index);
+		{
+		    if(TempRegRelay[index].relay_event.bits.CCS_Precharge != outputRelay[index].relay_event.bits.CCS_Precharge)
+		    {
+		        PRINTF_FUNC("[%d]CCS Precharge Relay none match, need to %s", index,
+                    outputRelay[index].relay_event.bits.CCS_Precharge == YES ? "On" : "Off");
+		        TempRegRelay[index].relay_event.bits.CCS_Precharge = outputRelay[index].relay_event.bits.CCS_Precharge;
+		    }
+		}
 		if (regRelay[index].relay_event.bits.Gun1_P != outputRelay[index].relay_event.bits.Gun1_P)
-			PRINTF_FUNC("[%d]SMR1:D+ Relay none match. \n", index);
+		{
+		    if(TempRegRelay[index].relay_event.bits.Gun1_P != outputRelay[index].relay_event.bits.Gun1_P)
+		    {
+		        PRINTF_FUNC("[%d]SMR1:D+ Relay none match, need to %s", index,
+                    outputRelay[index].relay_event.bits.Gun1_P == YES ? "On" : "Off");
+		        TempRegRelay[index].relay_event.bits.Gun1_P = outputRelay[index].relay_event.bits.Gun1_P;
+		    }
+		}
 		if (regRelay[index].relay_event.bits.Gun1_N != outputRelay[index].relay_event.bits.Gun1_N)
-			PRINTF_FUNC("[%d]SMR1:D- Relay none match. \n", index);
+		{
+		    if(TempRegRelay[index].relay_event.bits.Gun1_N != outputRelay[index].relay_event.bits.Gun1_N)
+		    {
+		        PRINTF_FUNC("[%d]SMR1:D- Relay none match, need to %s", index,
+                    outputRelay[index].relay_event.bits.Gun1_N == YES ? "On" : "Off");
+		        TempRegRelay[index].relay_event.bits.Gun1_N = outputRelay[index].relay_event.bits.Gun1_N;
+		    }
+		}
 		if (regRelay[index].relay_event.bits.Gun2_P != outputRelay[index].relay_event.bits.Gun2_P)
-			PRINTF_FUNC("[%d]SMR2:D+ Relay none match. \n", index);
+		{
+		    if(TempRegRelay[index].relay_event.bits.Gun2_P != outputRelay[index].relay_event.bits.Gun2_P)
+		    {
+		        PRINTF_FUNC("[%d]SMR2:D+ Relay none match, need to %s", index,
+                    outputRelay[index].relay_event.bits.Gun2_P == YES ? "On" : "Off");
+		        TempRegRelay[index].relay_event.bits.Gun2_P = outputRelay[index].relay_event.bits.Gun2_P;
+		    }
+		}
 		if (regRelay[index].relay_event.bits.Gun2_N != outputRelay[index].relay_event.bits.Gun2_N)
-			PRINTF_FUNC("[%d]SMR2:D- Relay none match. \n", index);
+		{
+		    if(TempRegRelay[index].relay_event.bits.Gun2_N != outputRelay[index].relay_event.bits.Gun2_N)
+		    {
+		        PRINTF_FUNC("[%d]SMR2:D- Relay none match, need to %s", index,
+                    outputRelay[index].relay_event.bits.Gun2_N == YES ? "On" : "Off");
+		        TempRegRelay[index].relay_event.bits.Gun2_N = outputRelay[index].relay_event.bits.Gun2_N;
+		    }
+		}
 		if (regRelay[index].relay_event.bits.Gun1_Parallel_P != outputRelay[index].relay_event.bits.Gun1_Parallel_P)
-			PRINTF_FUNC("[%d]Parallel:D+ Relay none match. \n", index);
+		{
+		    if(TempRegRelay[index].relay_event.bits.Gun1_Parallel_P != outputRelay[index].relay_event.bits.Gun1_Parallel_P)
+		    {
+		        PRINTF_FUNC("[%d]Parallel:D+ Relay none match, need to %s", index,
+                    outputRelay[index].relay_event.bits.Gun1_Parallel_P == YES ? "On" : "Off");
+		        TempRegRelay[index].relay_event.bits.Gun1_Parallel_P = outputRelay[index].relay_event.bits.Gun1_Parallel_P;
+		    }
+		}
 		if (regRelay[index].relay_event.bits.Gun1_Parallel_N != outputRelay[index].relay_event.bits.Gun1_Parallel_N)
-			PRINTF_FUNC("[%d]Parallel:D- Relay none match. \n", index);
+		{
+		    if(TempRegRelay[index].relay_event.bits.Gun1_Parallel_N != outputRelay[index].relay_event.bits.Gun1_Parallel_N)
+		    {
+		        PRINTF_FUNC("[%d]Parallel:D- Relay none match, need to %s", index,
+                    outputRelay[index].relay_event.bits.Gun1_Parallel_N == YES ? "On" : "Off");
+		        TempRegRelay[index].relay_event.bits.Gun1_Parallel_N = outputRelay[index].relay_event.bits.Gun1_Parallel_N;
+		    }
+		}
 		if (regRelay[index].relay_event.bits.Gun2_Parallel_P != outputRelay[index].relay_event.bits.Gun2_Parallel_P)
-			PRINTF_FUNC("[%d]Parallel2:D+ Relay none match. \n", index);
+		{
+		    if(TempRegRelay[index].relay_event.bits.Gun2_Parallel_P != outputRelay[index].relay_event.bits.Gun2_Parallel_P)
+		    {
+		        PRINTF_FUNC("[%d]Parallel2:D+ Relay none match, need to %s", index,
+                    outputRelay[index].relay_event.bits.Gun2_Parallel_P == YES ? "On" : "Off");
+		        TempRegRelay[index].relay_event.bits.Gun2_Parallel_P = outputRelay[index].relay_event.bits.Gun2_Parallel_P;
+		    }
+		}
 		if (regRelay[index].relay_event.bits.Gun2_Parallel_N != outputRelay[index].relay_event.bits.Gun2_Parallel_N)
-			PRINTF_FUNC("[%d]Parallel2:D- Relay none match. \n", index);
+		{
+		    if(TempRegRelay[index].relay_event.bits.Gun2_Parallel_N != outputRelay[index].relay_event.bits.Gun2_Parallel_N)
+		    {
+		        PRINTF_FUNC("[%d]Parallel2:D- Relay none match, need to %s", index,
+                    outputRelay[index].relay_event.bits.Gun2_Parallel_N == YES ? "On" : "Off");
+		        TempRegRelay[index].relay_event.bits.Gun2_Parallel_N = outputRelay[index].relay_event.bits.Gun2_Parallel_N;
+		    }
+		}
 
 		result = true;
 	}
@@ -2286,7 +2358,7 @@ void AcChargeTypeProcess()
 				{
 					if (isModeChange())
 					{
-						ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE;
+						//ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE;
 						ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = DEFAULT_AC_INDEX;
 						if (ShmSysConfigAndInfo->SysInfo.OrderCharging != NO_DEFINE)
 							ShmSysConfigAndInfo->SysInfo.OrderCharging = NO_DEFINE;
@@ -2409,9 +2481,9 @@ int main(void)
 	memset(&outputRelay[1], 0x00, sizeof(Relay));
 
 	if(Config_Relay_Output(Uart5Fd, Addr.DO360_RC1, &outputRelay[0]) != PASS)
-		PRINTF_FUNC("Config_Relay1_Output fail \n");
+		PRINTF_FUNC("Config_Relay1_Output fail");
 	if(Config_Relay_Output(Uart5Fd, Addr.DO360_RC2, &outputRelay[1]) != PASS)
-		PRINTF_FUNC("Config_Relay2_Output fail \n");
+		PRINTF_FUNC("Config_Relay2_Output fail");
 
 	cur_led_color.Connect_1_Red = COLOR_MIN_LV;
 	cur_led_color.Connect_1_Green = COLOR_MIN_LV;
@@ -2485,8 +2557,19 @@ int main(void)
                 GetPresentInputVol();
 
                 // 讀取當前 AC relay 狀態
+                if(regRelay[0].relay_event.bits.AC_Contactor != ShmSysConfigAndInfo->SysInfo.AcContactorStatus)
+                {
+                    PRINTF_FUNC("[%d]AC Contact Relay already %s", 0,
+                        ShmSysConfigAndInfo->SysInfo.AcContactorStatus == YES ? "On" : "Off");
+                }
+                if(regRelay[1].relay_event.bits.AC_Contactor != ShmSysConfigAndInfo->SysInfo.AcContactorStatus)
+                {
+                    PRINTF_FUNC("[%d]AC Contact Relay already %s", 1,
+                        ShmSysConfigAndInfo->SysInfo.AcContactorStatus == YES ? "On" : "Off");
+                }
                 regRelay[0].relay_event.bits.AC_Contactor = ShmSysConfigAndInfo->SysInfo.AcContactorStatus;
                 regRelay[1].relay_event.bits.AC_Contactor = ShmSysConfigAndInfo->SysInfo.AcContactorStatus;
+
                 //GetRelayOutputStatus();
 
                 for (int i = 0; i < gunCount; i++)
@@ -2518,13 +2601,13 @@ int main(void)
                         isCharging = true;
 
                         // 限定只有在槍類別為 GBT 的時候才做 relay welding 的判斷
-                        if (_chargingData[i]->Type == _Type_GB)
-                        {
-                            if (_chargingData[i]->SystemStatus >= S_PREPARING_FOR_EVSE &&
-                                _chargingData[i]->RelayWeldingCheck == NO)
-                                CheckRelayWeldingStatus(i);
-                        }
-                        else
+//                        if (_chargingData[i]->Type == _Type_GB)
+//                        {
+//                            if (_chargingData[i]->SystemStatus >= S_PREPARING_FOR_EVSE &&
+//                                _chargingData[i]->RelayWeldingCheck == NO)
+//                                CheckRelayWeldingStatus(i);
+//                        }
+//                        else
                             _chargingData[i]->RelayWeldingCheck = YES;
 
                         if (_chargingData[i]->SystemStatus == S_CHARGING)
@@ -2560,10 +2643,12 @@ int main(void)
                     else
                     {
                         if (((outputRelay[0].relay_event.bits.AC_Contactor == YES || outputRelay[1].relay_event.bits.AC_Contactor == YES)&&
-                                GetTimeoutValue(_close_ac_contactor) / 1000 >= (TEN_MINUTES * 1000)))
+                                GetTimeoutValue(_close_ac_contactor) / 1000 >= (TEN_MINUTES * 1000)) ||
+                                ShmSysConfigAndInfo->SysInfo.ForceAcContactorOff == YES)
                         {
                             outputRelay[0].relay_event.bits.AC_Contactor = NO;
                             outputRelay[1].relay_event.bits.AC_Contactor = NO;
+                            ShmSysConfigAndInfo->SysInfo.ForceAcContactorOff = NO;
                         }
                     }
                 }
@@ -2589,17 +2674,17 @@ int main(void)
                         regRelay[0].relay_event.bits.Gun2_Parallel_P = outputRelay[0].relay_event.bits.Gun2_Parallel_P;
                         regRelay[0].relay_event.bits.Gun2_Parallel_N = outputRelay[0].relay_event.bits.Gun2_Parallel_N;
 
-                        PRINTF_FUNC("Match Relay, AC = %x, g1_p = %x, g1_n = %x, g2_p = %x, g2_n = %x, pre = %x, bri_p = %x, bri_n = %x, bri2_p = %x, bri2_n = %x \n",
-                                regRelay[0].relay_event.bits.AC_Contactor,
-                                regRelay[0].relay_event.bits.Gun1_P,
-                                regRelay[0].relay_event.bits.Gun1_N,
-                                regRelay[0].relay_event.bits.Gun2_P,
-                                regRelay[0].relay_event.bits.Gun2_N,
-                                regRelay[0].relay_event.bits.CCS_Precharge,
-                                regRelay[0].relay_event.bits.Gun1_Parallel_P,
-                                regRelay[0].relay_event.bits.Gun1_Parallel_N,
-                                regRelay[0].relay_event.bits.Gun2_Parallel_P,
-                                regRelay[0].relay_event.bits.Gun2_Parallel_N);
+//                        PRINTF_FUNC("Match Relay, AC = %x, g1_p = %x, g1_n = %x, g2_p = %x, g2_n = %x, pre = %x, bri_p = %x, bri_n = %x, bri2_p = %x, bri2_n = %x \n",
+//                                regRelay[0].relay_event.bits.AC_Contactor,
+//                                regRelay[0].relay_event.bits.Gun1_P,
+//                                regRelay[0].relay_event.bits.Gun1_N,
+//                                regRelay[0].relay_event.bits.Gun2_P,
+//                                regRelay[0].relay_event.bits.Gun2_N,
+//                                regRelay[0].relay_event.bits.CCS_Precharge,
+//                                regRelay[0].relay_event.bits.Gun1_Parallel_P,
+//                                regRelay[0].relay_event.bits.Gun1_Parallel_N,
+//                                regRelay[0].relay_event.bits.Gun2_Parallel_P,
+//                                regRelay[0].relay_event.bits.Gun2_Parallel_N);
                     }
                 }
 
@@ -2619,17 +2704,17 @@ int main(void)
                         regRelay[1].relay_event.bits.Gun2_Parallel_P = outputRelay[1].relay_event.bits.Gun2_Parallel_P;
                         regRelay[1].relay_event.bits.Gun2_Parallel_N = outputRelay[1].relay_event.bits.Gun2_Parallel_N;
 
-                        PRINTF_FUNC("Match Relay2, AC = %x, g1_p = %x, g1_n = %x, g2_p = %x, g2_n = %x, pre = %x, bri_p = %x, bri_n = %x, bri2_p = %x, bri2_n = %x \n",
-                                regRelay[1].relay_event.bits.AC_Contactor,
-                                regRelay[1].relay_event.bits.Gun1_P,
-                                regRelay[1].relay_event.bits.Gun1_N,
-                                regRelay[1].relay_event.bits.Gun2_P,
-                                regRelay[1].relay_event.bits.Gun2_N,
-                                regRelay[1].relay_event.bits.CCS_Precharge,
-                                regRelay[1].relay_event.bits.Gun1_Parallel_P,
-                                regRelay[1].relay_event.bits.Gun1_Parallel_N,
-                                regRelay[1].relay_event.bits.Gun2_Parallel_P,
-                                regRelay[1].relay_event.bits.Gun2_Parallel_N);
+//                        PRINTF_FUNC("Match Relay2, AC = %x, g1_p = %x, g1_n = %x, g2_p = %x, g2_n = %x, pre = %x, bri_p = %x, bri_n = %x, bri2_p = %x, bri2_n = %x \n",
+//                                regRelay[1].relay_event.bits.AC_Contactor,
+//                                regRelay[1].relay_event.bits.Gun1_P,
+//                                regRelay[1].relay_event.bits.Gun1_N,
+//                                regRelay[1].relay_event.bits.Gun2_P,
+//                                regRelay[1].relay_event.bits.Gun2_N,
+//                                regRelay[1].relay_event.bits.CCS_Precharge,
+//                                regRelay[1].relay_event.bits.Gun1_Parallel_P,
+//                                regRelay[1].relay_event.bits.Gun1_Parallel_N,
+//                                regRelay[1].relay_event.bits.Gun2_Parallel_P,
+//                                regRelay[1].relay_event.bits.Gun2_Parallel_N);
                     }
                 }
             }

+ 293 - 59
EVSE/Projects/DO360/Apps/Module_PsuComm.c

@@ -21,6 +21,7 @@
 #define PRE_CHARG_RANGE		50
 #define EQUAL				0
 #define CMD_DELAY_TIME 		25000
+#define PSU_TASK_CHECK_TIME 1
 
 struct SysConfigAndInfo			*ShmSysConfigAndInfo;
 struct StatusCodeData 			*ShmStatusCodeData;
@@ -31,8 +32,12 @@ byte getAvailableCapOffset = 5;
 byte deratingKeepCount = 0;
 byte psuCmdSeq = _PSU_CMD_CAP;
 
+byte startModuleFlag = false;
+bool psuReceiveRecovery = false;
+
 float evseOutVol[CONNECTOR_QUANTITY] = {0, 0, 0, 0};
 float evseOutCur[CONNECTOR_QUANTITY] = {0, 0, 0, 0};
+struct timeval _PsuReceiveRecoveryCheck_time;
 
 void PRINTF_FUNC(char *string, ...);
 
@@ -188,7 +193,7 @@ unsigned char DetectBitValue(unsigned char _byte, unsigned char _bit)
 
 void AbnormalStopAnalysis(byte gun_index, int errCode)
 {
-	for (char i = 0; i < 3; i++)
+	for (char i = 0; i < 4; i++)
 	{
 		unsigned char byteIndex = (errCode >> (8 * i)) & 0xff;
 
@@ -196,48 +201,172 @@ void AbnormalStopAnalysis(byte gun_index, int errCode)
 		{
 			if(DetectBitValue(byteIndex , bitIndex) == 1)
 			{
-				switch(byteIndex)
+				switch(i)
 				{
 					case 0:
 					{
-						if (bitIndex == 0)
-							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuOutputShortCircuit = YES;
-						else if (bitIndex == 5)
-							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = YES;
+					    // err 1
+						if (bitIndex == 2)
+						{
+						    // 012307
+						    // fuse burn-out
+						    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFuseBurnOut = YES;
+						}
+						else if (bitIndex == 3)
+						{
+						    // 012308
+						    // Communication fault between PFC and DCDC
+						    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPfcAndDcdcCommFault = YES;
+						}
+                        else if (bitIndex == 6)
+                        {
+                            // 012309
+                            // Unbalance positive and negative BUS voltage
+                            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusVoltageUnbalance = YES;
+                        }
+                        else if (bitIndex == 7)
+                        {
+                            // 012310
+                            // BUS over voltage
+                            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusOverVoltage = YES;
+                        }
 					}
 						break;
 				case 1:
 					{
-						if (bitIndex == 1)
-							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFailureAlarm = YES;
-						else if (bitIndex == 2)
-							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuProtectionAlarm = YES;
-						else if (bitIndex == 3)
-							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFailureAlarm = YES;
-						else if (bitIndex == 4)
-							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCriticalPointOTP = YES;
-						else if (bitIndex == 5)
-							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = YES;
+					    // err 2
+						if (bitIndex == 0)
+						{
+						    // 012311
+						    // BUS voltage abnormal
+						    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusVoltageAbnormal = YES;
+						}
+						else if (bitIndex == 1)
+                        {
+						    // 012270
+						    // Over voltage of any phase
+						    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputOVP = YES;
+                        }
+                        else if (bitIndex == 2)
+                        {
+                            // 012263
+                            // ID number repetition
+                            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDuplicateID = YES;
+                        }
+                        else if (bitIndex == 3)
+                        {
+                            // 012312
+                            // BUS under voltage
+                            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusUnderVoltage = YES;
+                        }
+                        else if (bitIndex == 4)
+                        {
+                            // 012313
+                            // Phase loss
+                            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputPhaseLoss = YES;
+                        }
+                        else if (bitIndex == 6)
+                        {
+                            // 012271
+                            // Under voltage of any phase
+                            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputUVP = NO;
+                        }
 					}
 					break;
 				case 2:
 					{
+					    // err3
 						if (bitIndex == 0)
-							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPowerLimitedState = YES;
+						{
+						    // 012240
+						    // CAN communication fault
+						    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCommunicationFail = YES;
+						}
 						else if (bitIndex == 1)
-							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDuplicateID = YES;
-						else if (bitIndex == 2)
-							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuThreePhaseOnputImbalance = YES;
-						else if (bitIndex == 3)
-							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuThreePhaseInputInadequate = YES;
-						else if (bitIndex == 4)
-							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuThreePhaseInputInadequate = YES;
-						else if (bitIndex == 5)
-							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputUVP = YES;
-						else if (bitIndex == 6)
-							ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputOVP = YES;
+						{
+						    // 012275
+						    // DCDC uneven current sharing
+						    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuSevereUnevenCurrent = YES;
+						}
+                        else if (bitIndex == 3)
+                        {
+                            // 012278
+                            // PFC power off
+                            //ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFfcSideShutDown = YES;
+                        }
+                        else if (bitIndex == 5)
+                        {
+                            // 012314
+                            // Full speed of fan
+                            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFullSpeed = YES;
+                        }
+                        else if (bitIndex == 6)
+                        {
+                            // 012266
+                            // DCDC power off
+                            //ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = YES;
+                        }
+                        else if (bitIndex == 7)
+                        {
+                            // 012273
+                            // Module unders power limiting status
+                            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPowerLimitedState = YES;
+                        }
 					}
 					break;
+				case 3:
+                    {
+                        // err 4
+                        if (bitIndex == 0)
+                        {
+                            // 012315
+                            // Temperature power limiting
+                            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuTemperaturePowerLimit = YES;
+                        }
+                        else if (bitIndex == 1)
+                        {
+                            // 012316
+                            // AC power limiting
+                            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuAcPowerLimit = YES;
+                        }
+                        else if (bitIndex == 2)
+                        {
+                            // 012317
+                            // DCDC eeprom faults
+                            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcdcEepromFault = YES;
+                        }
+                        else if (bitIndex == 3)
+                        {
+                            // 012269
+                            // Fan faults
+                            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFailureAlarm = YES;
+                        }
+                        else if (bitIndex == 4)
+                        {
+                            // 012264
+                            // DCDC short circuit
+                            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuOutputShortCircuit = YES;
+                        }
+                        else if (bitIndex == 5)
+                        {
+                            // 012318
+                            // PFC eeprom faults
+                            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPfcEepromFault = YES;
+                        }
+                        else if (bitIndex == 6)
+                        {
+                            // 012226
+                            // DCDC over temperature
+                            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCriticalPointOTP = YES;
+                        }
+                        else if (bitIndex == 7)
+                        {
+                            // 012319
+                            // DCDC output over voltage
+                            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcdcOverVoltage = YES;
+                        }
+                    }
+                    break;
 				}
 			}
 //			else
@@ -344,10 +473,10 @@ void GetStatusCallback(byte group, byte SN, byte temp, int alarm)
 		}
 
 		for(byte psuIndex = 0; psuIndex < conn_1_count; psuIndex++)
-			PRINTF_FUNC("Connector 1 - Number = %d \n", connector_1[psuIndex]);
+			PRINTF_FUNC("Connector 1 - Number = %d", connector_1[psuIndex]);
 
 		for(byte psuIndex = 0; psuIndex < conn_2_count; psuIndex++)
-			PRINTF_FUNC("Connector 2 - Number = %d \n", connector_2[psuIndex]);
+			PRINTF_FUNC("Connector 2 - Number = %d", connector_2[psuIndex]);
 	}
 }
 // no using -- GetOutputAndTempCallback End
@@ -499,7 +628,9 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
 				ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A))
 		{
 			if (chargingInfo[group]->DividChargingCurrent == 0)
+			{
 				return;
+			}
 			else
 			{
 				halfCur = chargingInfo[group]->DividChargingCurrent;
@@ -888,7 +1019,8 @@ void GetPresentOutputFCallback(byte group, float outVol, float outCur)
 			}
 
 			if ((chargingInfo[group]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[group]->SystemStatus <= S_COMPLETE) ||
-				(chargingInfo[group]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[group]->SystemStatus <= S_CCS_PRECHARGE_ST1))
+				(chargingInfo[group]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[group]->SystemStatus <= S_CCS_PRECHARGE_ST1) ||
+				chargingInfo[group]->SystemStatus == S_ALARM)
 			{
 				float _vol_buf = outputVol;
 				float _cur_buf = outputCur;
@@ -1050,7 +1182,7 @@ void GetModuleStatusCallback(byte address, unsigned char isErr, unsigned char st
 	if (group1 == 1)
 		address -= ShmPsuData->PsuGroup[group1 - 1].GroupPresentPsuQuantity;
 
-	int alarm = (err2 << 24) | (err3 << 16) | (err4 << 8);
+	int alarm = (err4 << 24) | (err3 << 16) | (err2 << 8) | err1;
 
 //	ShmPsuData->PsuGroup[group1].PsuModule[address].CriticalTemp1 = temp;
 //	ShmPsuData->PsuGroup[group1].PsuModule[address].CriticalTemp2 = temp;
@@ -1059,6 +1191,13 @@ void GetModuleStatusCallback(byte address, unsigned char isErr, unsigned char st
 	ShmPsuData->PsuGroup[group1].PsuModule[address].AlarmCode = alarm;
 	AbnormalStopAnalysis(group1, alarm);
 
+	if(isErr)
+	{
+	    // 012267
+	    //ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFailureAlarm = YES;
+	    ShmPsuData->PsuGroup[group1].GroupErrorFlag.bits.PsuFailure = true;
+	}
+
 	// err2 == state 2
 	// err3 == state 1
 	// err4 == state 0
@@ -1098,14 +1237,14 @@ int InitShareMemory()
 	if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo),  0777)) < 0)
     {
 		#ifdef SystemLogMessage
-		DEBUG_ERROR("shmget ShmSysConfigAndInfo NG %d \n");
+		DEBUG_ERROR("shmget ShmSysConfigAndInfo NG %d");
 		#endif
 		result = FAIL;
 	}
     else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
     {
     	#ifdef SystemLogMessage
-    	DEBUG_ERROR("shmat ShmSysConfigAndInfo NG \n");
+    	DEBUG_ERROR("shmat ShmSysConfigAndInfo NG");
 		#endif
     	result = FAIL;
    	 }
@@ -1116,14 +1255,14 @@ int InitShareMemory()
    	if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData),  0777)) < 0)
     {
 		#ifdef SystemLogMessage
-   		DEBUG_ERROR("shmget ShmStatusCodeData NG \n");
+   		DEBUG_ERROR("shmget ShmStatusCodeData NG");
 		#endif
    		result = FAIL;
 	}
     else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
     {
     	#ifdef SystemLogMessage
-    	DEBUG_ERROR("shmat ShmStatusCodeData NG \n");
+    	DEBUG_ERROR("shmat ShmStatusCodeData NG");
 		#endif
     	result = FAIL;
    	}
@@ -1134,14 +1273,14 @@ int InitShareMemory()
 	if ((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData),  0777)) < 0)
 	{
 		#ifdef SystemLogMessage
-		DEBUG_ERROR("shmget ShmPsuData NG \n");
+		DEBUG_ERROR("shmget ShmPsuData NG");
 		#endif
 		result = FAIL;
 	}
 	else if ((ShmPsuData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
 	{
 		#ifdef SystemLogMessage
-		DEBUG_ERROR("shmat ShmPsuData NG \n");
+		DEBUG_ERROR("shmat ShmPsuData NG");
 		#endif
 		result = FAIL;
 	 }
@@ -1157,13 +1296,39 @@ void InitialPsuData()
 	ShmPsuData->SystemPresentPsuQuantity = 0;
 	ShmPsuData->SystemAvailablePower = 0;
 
-	PRINTF_FUNC("************ psu Group = %d \n", ShmPsuData->GroupCount);
+	PRINTF_FUNC("************ psu Group = %d", ShmPsuData->GroupCount);
 	for (byte _groupCount = 0; _groupCount < ShmPsuData->GroupCount; _groupCount++)
 	{
 		ShmPsuData->PsuGroup[_groupCount].GroupPresentPsuQuantity = 0;
 		ShmPsuData->PsuGroup[_groupCount].GroupAvailablePower = 0;
 		ShmPsuData->PsuGroup[_groupCount].GroupAvailableCurrent = 0;
+		ShmPsuData->PsuGroup[_groupCount].GroupErrorFlag.PsuGroupErrorValue = 0;
 	}
+
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFuseBurnOut = YES;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPfcAndDcdcCommFault = YES;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusVoltageUnbalance = YES;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusOverVoltage = YES;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusVoltageAbnormal = YES;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputOVP = YES;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDuplicateID = YES;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusUnderVoltage = YES;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputPhaseLoss = YES;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputUVP = NO;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCommunicationFail = YES;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuSevereUnevenCurrent = YES;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFfcSideShutDown = YES;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFullSpeed = YES;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = YES;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPowerLimitedState = YES;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuTemperaturePowerLimit = YES;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuAcPowerLimit = YES;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcdcEepromFault = YES;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFailureAlarm = YES;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuOutputShortCircuit = YES;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPfcEepromFault = YES;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCriticalPointOTP = YES;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcdcOverVoltage = YES;
 }
 
 void Initialization()
@@ -1176,7 +1341,7 @@ void Initialization()
 		{
 			if (!FindChargingInfoData(_index, &chargingInfo[0]))
 			{
-				DEBUG_ERROR("Module_PsuComm : FindChargingInfoData false \n");
+				DEBUG_ERROR("Module_PsuComm : FindChargingInfoData false");
 				isPass = false;
 				break;
 			}
@@ -1287,6 +1452,14 @@ void PreCheckSmartChargingStep()
 				toAverVolCount = 3;
 			}
 		}
+        else if (chargingInfo[index]->SystemStatus == S_COMPLETE ||
+                chargingInfo[index]->SystemStatus == S_ALARM)
+        {
+            if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_PREPARE_M_TO_A)
+            {
+                ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_RELAY_M_TO_A;
+            }
+        }
 
 		if ((chargingInfo[index]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[index]->SystemStatus <= S_CHARGING) ||
 				(chargingInfo[index]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[index]->SystemStatus <= S_CCS_PRECHARGE_ST1))
@@ -1308,12 +1481,55 @@ void Await()
 	usleep(CMD_DELAY_TIME);
 }
 
+void PsuReceiveRecoveryCheck(void)
+{
+    char *ptrSave, *ptrToken;
+    int fd, psuTaskCount = 0;
+    char pathBuffer[64], psuTaskPidString[64];
+
+    system("pidof Module_PsuComm > /tmp/Module_PsuTask");
+
+    snprintf(pathBuffer, sizeof(pathBuffer), "/tmp/Module_PsuTask");
+    fd = open(pathBuffer, O_RDWR);
+
+    if(fd < 0)
+    {
+        return;
+    }
+    if(read(fd, psuTaskPidString, 64) < 0)
+    {
+        return;
+    }
+
+    ptrToken = strtok_r(psuTaskPidString, " ", &ptrSave);
+    while(ptrToken != NULL)
+    {
+        int psuPid = atoi(ptrToken);
+
+        if(psuPid > 0)
+        {
+            psuTaskCount++;
+        }
+
+        ptrToken = strtok_r(NULL, ";", &ptrSave);
+    }
+    close(fd);
+
+    if(psuTaskCount == 1)
+    {
+        PRINTF_FUNC("************ PSU Receive Task Need Recovery ************\n");
+        InitialCommunication();
+
+        psuReceiveRecovery = true;
+    }
+}
+
 int main(void)
 {
 	if(InitShareMemory() == FAIL)
 	{
 		#ifdef SystemLogMessage
-		DEBUG_ERROR("InitShareMemory NG\n");
+		DEBUG_ERROR("InitShareMemory NG");
 		#endif
 		if(ShmStatusCodeData != NULL)
 		{
@@ -1323,7 +1539,9 @@ int main(void)
 		return 0;
 	}
 
-	PRINTF_FUNC("InitShareMemory OK\n");
+	PRINTF_FUNC("InitShareMemory OK");
+
+	signal(SIGCHLD,SIG_IGN);
 
 	// register callback function
 	RefreshStatus(&GetStatusCallback);
@@ -1376,15 +1594,21 @@ int main(void)
 		// 自檢失敗
 		if (ShmPsuData->Work_Step == _NO_WORKING)
 		{
-			PRINTF_FUNC("== PSU == self test fail. \n");
+			PRINTF_FUNC("== PSU == self test fail.");
 			sleep(5);
 		}
 
+		if((GetTimeoutValue(_PsuReceiveRecoveryCheck_time) / 1000000) >= PSU_TASK_CHECK_TIME)
+		{
+		    PsuReceiveRecoveryCheck();
+		    gettimeofday(&_PsuReceiveRecoveryCheck_time, NULL);
+		}
+
 		switch(ShmPsuData->Work_Step)
 		{
 			case INITIAL_START:
 			{
-				PRINTF_FUNC("== PSU == INITIAL_START \n");
+				PRINTF_FUNC("== PSU == INITIAL_START");
 				gettimeofday(&_cmdSubPriority_time, NULL);
 				sleep(5);
 				SwitchPower(SYSTEM_CMD, PSU_POWER_OFF);
@@ -1415,22 +1639,22 @@ int main(void)
 						// 取各群模組數量
 						GetModuleCount(index);
 					}
-					PRINTF_FUNC("== PSU == indexCount = %d, moduleCount = %d, sysCount = %d\n",
+					PRINTF_FUNC("== PSU == indexCount = %d, moduleCount = %d, sysCount = %d",
 							ShmPsuData->GroupCount, moduleCount, ShmPsuData->SystemPresentPsuQuantity);
 
 					// 判斷系統數量與各群數量一致
 					if(moduleCount == ShmPsuData->SystemPresentPsuQuantity && moduleCount > 0)
 					{
-						PRINTF_FUNC("Psu Count = %d \n", moduleCount);
-						if (ShmSysConfigAndInfo->SysInfo.BootingStatus == BOOTTING)
+						PRINTF_FUNC("Psu Count = %d", moduleCount);
+						if (ShmSysConfigAndInfo->SysInfo.BootingStatus == BOOTTING || psuReceiveRecovery)
 						{
 							// 電樁在 Booting 的狀態 - 自檢
-							PRINTF_FUNC("== PSU == GET_SYS_CAP \n");
+							PRINTF_FUNC("== PSU == GET_SYS_CAP");
 							ShmPsuData->Work_Step = GET_SYS_CAP;
 						}
 						else
 						{
-							PRINTF_FUNC("== PSU == _WORK_CHARGING \n");
+							PRINTF_FUNC("== PSU == _WORK_CHARGING");
 							ShmPsuData->Work_Step = _WORK_CHARGING;
 
 							gettimeofday(&_test_time, NULL);
@@ -1489,10 +1713,10 @@ int main(void)
 					else
 					{
 						// 判斷系統輸出額定功率與電流
-						PRINTF_FUNC("SystemAvailableCurrent = %d, SystemAvailablePower = %d \n",
+						PRINTF_FUNC("SystemAvailableCurrent = %d, SystemAvailablePower = %d",
 							ShmPsuData->SystemAvailableCurrent, ShmPsuData->SystemAvailablePower);
 
-						PRINTF_FUNC("== PSU == BOOTING_COMPLETE \n");
+						PRINTF_FUNC("== PSU == BOOTING_COMPLETE");
 						ShmPsuData->Work_Step = BOOTING_COMPLETE;
 					}
 
@@ -1526,6 +1750,7 @@ int main(void)
 				if (time > 1500)
 				{
 					PreCheckSmartChargingStep();
+					startModuleFlag = true;
 					gettimeofday(&_cmdSubPriority_time, NULL);
 				}
 
@@ -1576,7 +1801,7 @@ int main(void)
 						{
 						    if((int)evseOutVol[groupIndex] != (int)chargingInfo[groupIndex]->PresentChargingVoltage)
 						    {
-	                            PRINTF_FUNC("groupIndex = %d, ev need vol = %.1fV, evse output vol = %.1fV, fire voltage vol = %.1fV \n",
+	                            PRINTF_FUNC("groupIndex = %d, ev need vol = %.1fV, evse output vol = %.1fV, fire voltage vol = %.1fV",
 	                                groupIndex, chargingInfo[groupIndex]->EvBatterytargetVoltage,
 	                                chargingInfo[groupIndex]->PresentChargingVoltage, chargingInfo[groupIndex]->FireChargingVoltage);
 						    }
@@ -1588,7 +1813,7 @@ int main(void)
 						{
 							if((int)evseOutCur[groupIndex] != (int)chargingInfo[groupIndex]->PresentChargingCurrent)
 							{
-                                PRINTF_FUNC("groupIndex = %d, ev need cur = %.1fA, evse output cur = %.1fA \n", groupIndex,
+                                PRINTF_FUNC("groupIndex = %d, ev need cur = %.1fA, evse output cur = %.1fA", groupIndex,
                                     chargingInfo[groupIndex]->EvBatterytargetCurrent, chargingInfo[groupIndex]->PresentChargingCurrent);
 							}
 							evseOutCur[groupIndex] = chargingInfo[groupIndex]->PresentChargingCurrent;
@@ -1608,10 +1833,14 @@ int main(void)
 									if (chargingInfo[groupIndex]->DividChargingCurrent == 0)
 									{
 										chargingInfo[groupIndex]->DividChargingCurrent = ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent;
+										if(chargingInfo[groupIndex]->DividChargingCurrent == 0)
+										{
+										    chargingInfo[groupIndex]->DividChargingCurrent = (chargingInfo[groupIndex]->EvBatterytargetCurrent * 10) / 2;
+										}
 									}
 								}
 
-								PRINTF_FUNC("Index = %d, DividChargingCurrent = %.1f \n", groupIndex, chargingInfo[groupIndex]->DividChargingCurrent);
+								PRINTF_FUNC("Index = %d, DividChargingCurrent = %.1f", groupIndex, chargingInfo[groupIndex]->DividChargingCurrent);
 							}
 							else
 							{
@@ -1628,7 +1857,7 @@ int main(void)
 										deratingKeepCount >= DERATING_COUNT)
 									{
 										// 車端降載完成
-										PRINTF_FUNC("Index = %d, newEvCurrent = %f \n", groupIndex, (chargingInfo[groupIndex]->EvBatterytargetCurrent * 10));
+										PRINTF_FUNC("Index = %d, newEvCurrent = %f", groupIndex, (chargingInfo[groupIndex]->EvBatterytargetCurrent * 10));
 										PRINTF_FUNC("=============Smart Charging : _REASSIGNED_ADJUST_M_TO_A============= Step 3 \n");
 										ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_ADJUST_M_TO_A;
 										gettimeofday(&_derating_time, NULL);
@@ -1817,7 +2046,7 @@ int main(void)
 										isStartOutputSwitch[index] = true;
 									}
 
-									if (isNeedToOpenPower)
+									if (isNeedToOpenPower || startModuleFlag)
 									{
 										SwitchPower(SYSTEM_CMD, PSU_POWER_ON);
 										FlashLed(SYSTEM_CMD, PSU_FLASH_ON);
@@ -1835,6 +2064,7 @@ int main(void)
 								for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++)
 								{
 									if (chargingInfo[subIndex]->SystemStatus == S_IDLE ||
+									        chargingInfo[subIndex]->SystemStatus == S_FAULT ||
 											chargingInfo[subIndex]->SystemStatus == S_RESERVATION)
 									{
 										// 各群電壓接近平衡
@@ -1874,6 +2104,7 @@ int main(void)
 								{
 									if (chargingInfo[subIndex]->SystemStatus == S_IDLE ||
 											chargingInfo[subIndex]->SystemStatus == S_RESERVATION ||
+											chargingInfo[subIndex]->SystemStatus == S_FAULT ||
 											chargingInfo[subIndex]->SystemStatus == S_REASSIGN_CHECK)
 										idleCurrent = ShmPsuData->PsuGroup[subIndex].GroupPresentOutputCurrent;
 									else
@@ -1904,6 +2135,7 @@ int main(void)
 									{
 										if (chargingInfo[subIndex]->SystemStatus == S_IDLE ||
 												chargingInfo[subIndex]->SystemStatus == S_RESERVATION ||
+												chargingInfo[subIndex]->SystemStatus == S_FAULT ||
 												chargingInfo[subIndex]->SystemStatus == S_REASSIGN_CHECK)
 										{
 											reassignIndex = subIndex;
@@ -2002,7 +2234,7 @@ int main(void)
 									}
 									else
 									{
-										if (!isStartOutputSwitch[groupIndex])
+									    if (!isStartOutputSwitch[groupIndex] || startModuleFlag)
 										{
 											isStartOutputSwitch[groupIndex] = true;
 											SwitchPower(groupIndex, PSU_POWER_ON); Await();
@@ -2013,8 +2245,9 @@ int main(void)
 							}
 						}
 					}
-					else if (chargingInfo[groupIndex]->SystemStatus >= S_TERMINATING &&
-								chargingInfo[groupIndex]->SystemStatus <= S_COMPLETE)
+					else if ((chargingInfo[groupIndex]->SystemStatus >= S_TERMINATING &&
+								chargingInfo[groupIndex]->SystemStatus <= S_COMPLETE) ||
+                                chargingInfo[groupIndex]->SystemStatus == S_ALARM)
 					{
 						if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
 						{
@@ -2106,6 +2339,7 @@ int main(void)
 					}
 				}
 
+				startModuleFlag = false;
 				break;
 			}
 			case _TEST_MODE:

File diff suppressed because it is too large
+ 244 - 490
EVSE/Projects/DO360/Apps/main.c


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


+ 89 - 26
EVSE/Projects/define.h

@@ -377,6 +377,18 @@ struct Schedule
 	unsigned char   isTriggerStop;    					// 0: disable; 1: enable
 };
 
+typedef union
+{
+    unsigned int ChargingStopValue;
+    struct
+    {
+        unsigned int NormalStop:1;                  // 0: no effect,    1: normal stop
+        unsigned int AlarmStop:1;                   // 0: no effect,    1: alarm stop
+        unsigned int BackendStop:1;                 // 0: no effect,    1: backend stop
+        unsigned int res:29;
+    }bits;
+}ChargingStop;
+
 struct SysConfigData
 {
 	/**************System***************/
@@ -520,6 +532,7 @@ struct ChargingInfoData
 	struct Schedule		schedule;						// Schedule
 	int 				EvBatteryStartSoc;				// 0~100%
 	unsigned char 		UnKnowStopChargeFlag;			// for EV board
+	ChargingStop        ChargingStopFlag;
 };
 
 typedef union
@@ -638,7 +651,9 @@ typedef union
         unsigned int  RemoteStartRequest:1;             // 0: no request,    1: remote start                                    (    ocpp   -> cabinet -> dispenser)
         unsigned int  RemoteStartConfirm:1;
         unsigned int  RemoteStopRequest:1;              // 0: no request,    1: remote stop                                     (    ocpp   -> cabinet -> dispenser)
+        unsigned int  RemoteStopConfirm:1;
         unsigned int  UnlockStopRequest:1;              // 0: no request,    1: Unlock stop                                     (    ocpp   -> cabinet -> dispenser)
+        unsigned int  UnlockStopConfirm:1;
         unsigned int  TimeoutStopRequest:1;             // 0: no request,    1: ethernet timeout stop                           ( dispenser -> cabinet)
         unsigned int  PsuReleasable:1;
         unsigned int  AvailabilityRequest:1;            // 0: no request,    1: change availability                             (    ocpp   -> cabinet -> dispenser)
@@ -650,7 +665,7 @@ typedef union
         unsigned int  SwipeRfidConfirm:1;
         unsigned int  OutputLimitEnable:1;              // 0: disable,      1: enable
         unsigned int  ChargingPermission:2;             // 0: not allowed,  1: allowed,         2: wait
-        unsigned int  res:11;
+        unsigned int  res:9;
     }bits;
 }ConnectorParameter;
 
@@ -708,7 +723,7 @@ typedef union
 struct SysInfoData
 {
 	/**************System***************/
-	unsigned char OcppRunningVer;			// 0: 1.6J      1:2.0
+    unsigned char OcppRunningVer;           // 0: 1.6J      1:2.0
 	unsigned char BootingStatus;			// 0 : booting, 1 : Initializing Complete.
 	unsigned char AuthorizeFlag;			// 0 : None, 1 : Authorizing
 	unsigned char FactoryConfiguration;	//0: normal, 1: trigger, charger will return the configuration to factory default if trigger
@@ -789,6 +804,7 @@ struct SysInfoData
     struct DispenserInfoData DispenserInfo;
     struct ConnectorInfoData ConnectorInfo[GENERAL_GUN_QUANTITY];
     CabinetSettingFlag       CabinetSetting;
+    unsigned char       ForceAcContactorOff;            // 0: no effect,    1: ac contactor off
 };
 
 struct SysConfigAndInfo
@@ -1078,13 +1094,34 @@ char AlarmStatusCode[128][6]=
 	"012304",   // connection disconnected from power cabinet
 	"012305",   // Meter communication timeout
 	"012306",   // The dip switch of the PSU may be incorrect
+    "012307",   // Psu Fuse Burn-Out
+    "012308",   // Psu Pfc And Dcdc Communication Fault
+    "012309",   // Psu Bus Voltage Unbalance
+    "012310",   // Psu Bus Over Voltage
+    "012311",   // Psu Bus Voltage Abnormal
+    "012312",   // Psu Bus Under Voltage
+    "012313",   // Psu Input Phase Loss
+    "012314",   // Psu Fan Full Speed
+    "012315",   // Psu Temperature Power Limit
+    "012316",   // Psu Ac Power Limit
+    "012317",   // Psu Dcdc Eeprom Fault
+    "012318",   // Psu Pfc Eeprom Fault
+    "012319",   // Psu Dcdc Over Voltage
+    "012320",   // reserved
+    "012321",   // reserved
+    "012322",   // reserved
+    "012323",   // reserved
+    "012324",   // reserved
+    "012325",   // reserved
+    "012326",   // reserved
+    "012327",   // reserved
 };
 struct AlarmCodeData
 {
-	unsigned char PreviousAlarmVal[14];
+	unsigned char PreviousAlarmVal[16];
 	union
 	{
-		unsigned char AlarmVal[14];
+		unsigned char AlarmVal[16];
 		struct
 		{
 			//AlarmVal[0]
@@ -1208,7 +1245,22 @@ struct AlarmCodeData
             unsigned char DisconnectedFromDo:1;                     //bit 0
             unsigned char MeterCommTimeout:1;                       //bit 1
             unsigned char PsuDipSwitchStestFail:1;                  //bit 2
-            unsigned char Reserved:5;                               //bit 3~bit7
+            unsigned char PsuFuseBurnOut:1;                         //bit 3
+            unsigned char PsuPfcAndDcdcCommFault:1;                 //bit 4
+            unsigned char PsuBusVoltageUnbalance:1;                 //bit 5
+            unsigned char PsuBusOverVoltage:1;                      //bit 6
+            unsigned char PsuBusVoltageAbnormal:1;                  //bit 7
+            //AlarmVal[14]
+            unsigned char PsuBusUnderVoltage:1;                     //bit 0
+            unsigned char PsuInputPhaseLoss:1;                      //bit 1
+            unsigned char PsuFanFullSpeed:1;                        //bit 2
+            unsigned char PsuTemperaturePowerLimit:1;               //bit 3
+            unsigned char PsuAcPowerLimit:1;                        //bit 4
+            unsigned char PsuDcdcEepromFault:1;                     //bit 5
+            unsigned char PsuPfcEepromFault:1;                      //bit 6
+            unsigned char PsuDcdcOverVoltage:1;                     //bit 7
+            //AlarmVal[15]
+            unsigned char Reserved:8;                               //bit 0~7
 		}bits;
 	}AlarmEvents;
 };
@@ -1887,6 +1939,16 @@ struct StatusCodeData
 /**************************************************************************************/
 /**************************PSU Share memory***************************************/
 /**************************************************************************************/
+typedef union
+{
+    unsigned int PsuGroupErrorValue;
+    struct
+    {
+        unsigned int PsuFailure:1;              // 0: no effect,    1: Psu Failure
+        unsigned int res:31;
+    }bits;
+}PsuGroupError;
+
 struct PsuModuleVer
 {
 	unsigned char 		FwPrimaryVersion[16];
@@ -1936,29 +1998,30 @@ struct PsuModuleData
 /*Following are the information for each PSU Group*/
 struct PsuGroupData
 {
-	unsigned char 			GroupPresentPsuQuantity;
-	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 char           GroupPresentPsuQuantity;
+	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
 	struct PsuModuleData 	PsuModule[MAX_PSU_QUANTITY];
+	PsuGroupError           GroupErrorFlag;
 };
 
 /*Following is the information for system all PSU*/
 struct PsuData
 {
-	unsigned char 			SystemPresentPsuQuantity;
-	unsigned short 		SystemAvailableCurrent;			//abcd=abc.d amp
-	unsigned int 			SystemAvailablePower;			//Watt
-	struct PsuGroupData 	PsuGroup[4];
-	unsigned char 			GroupCount;
-	unsigned char 			Work_Step;
-	struct PsuModuleVer		PsuVersion[MAX_PSU_QUANTITY];
+	unsigned char           SystemPresentPsuQuantity;
+	unsigned short          SystemAvailableCurrent;			//abcd=abc.d amp
+	unsigned int            SystemAvailablePower;			//Watt
+	struct PsuGroupData     PsuGroup[4];
+	unsigned char           GroupCount;
+	unsigned char           Work_Step;
+	struct PsuModuleVer     PsuVersion[MAX_PSU_QUANTITY];
 };
 
 /************************************************************************************/
@@ -5357,9 +5420,9 @@ struct UpdateFirmware_20
 
 struct NetworkConnectionProfile_20
 {
-	unsigned int slot;
-	unsigned char retryCount;
-	struct NetworkConnectionProfileType connectionData;
+    unsigned int slot;
+    unsigned char retryCount;
+    struct NetworkConnectionProfileType connectionData;
 };
 
 struct OCPP20Data
@@ -5370,7 +5433,7 @@ struct OCPP20Data
 	unsigned int 							Timeout_Secs;
 	unsigned short 							Ping_Pong_Interval;
 	struct ReportDataType                   ControllerComponentVariable[CtrlrVariable_CNT];
-	struct NetworkConnectionProfile_20		NetworkConnectionProfile[10];
+	struct NetworkConnectionProfile_20      NetworkConnectionProfile[10];
 
 	union
 	{

BIN
EVSE/rootfs/root/OcppBackend20


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