Эх сурвалжийг харах

2020-12-30 / Alston Lin

Actions
1. Send 0A to ev board if current output voltage is less than 50V
2. Optimize the update process
3. Support to read AC meter function
4. Added in self-test to check the status of psu dip switch
5. Added a method to check relay driving/welding failure
6. Modify OVP check function
7. Fix some bug

Files
1. As follow commit history
Alston 4 жил өмнө
parent
commit
18787a69b8

+ 51 - 17
EVSE/Projects/DS60-120/Apps/Config.h

@@ -7,6 +7,9 @@
 #ifndef CONFIG_H_
 #define CONFIG_H_
 
+#define ShmCsuMeterKey			2001
+#define ShmCommonKey			2002
+
 typedef unsigned char			byte;
 
 #define TOTAL_QUANTITY_GUN			4				//Max Count
@@ -88,21 +91,6 @@ enum _GUN_TYPE
 	_Type_AC,
 };
 
-//enum _LCM_INDEX
-//{
-//	_LCM_INIT = 			0x00,
-//	_LCM_IDLE = 			0x01,
-//	_LCM_AUTHORIZING = 		0x04,
-//	_LCM_AUTHORIZ_COMP = 	0x05,
-//	_LCM_AUTHORIZ_FAIL = 	0x06,
-//	_LCM_WAIT_FOR_PLUG = 	0x07,
-//	_LCM_PRE_CHARGE = 		0x08,
-//	_LCM_CHARGING = 		0x09,
-//	_LCM_COMPLETE = 		0x0A,
-//	_LCM_FIX = 				0x0B,
-//	_LCM_NONE = 			0xFF,
-//};
-
 enum _LCM_INDEX
 {
 	_LCM_INIT = 			0x00,
@@ -139,8 +127,7 @@ enum _MODULE_PSU_WORK_STEP
 
 	_TEST_MODE			=		20,
 
-	_NO_WORKING			= 		254,
-	_INIT_PSU_STATUS	= 		255
+	_NO_WORKING			= 		254
 };
 
 enum _OFFLINE_POLICY
@@ -220,4 +207,51 @@ enum _PRIMARY_CHECK_TAG
 	_PRIMARY_CHECK_TAG_MAIN_BREAKER		= 1,
 };
 
+struct StructMeter
+{
+	float curMeterValue;
+	float newMeterValue;
+	byte isCalculation;
+	float _chargingValue;
+	float _curTotalCharging;
+};
+
+struct MeterInformation
+{
+	struct StructMeter _meter[2];
+	byte isWorking;
+};
+
+enum _CCS_VERSION_CHECK_TAG
+{
+	_CCS_VERSION_CHECK_TAG_V015S0		= 0,
+	_CCS_VERSION_CHECK_TAG_V013S0		= 1,
+};
+
+enum RELAY_STATUS_ERROR_INDEX
+{
+	RELAY_SMR1_P_STATUS = 	0,
+	RELAY_SMR1_N_STATUS = 	1,
+	RELAY_SMR2_P_STATUS = 	2,
+	RELAY_SMR2_N_STATUS = 	3,
+	RELAY_PARA_P_STATUS = 	4,
+	RELAY_PARA_N_STATUS = 	5,
+};
+
+enum RELAY_STATUS_ERROR_TYPE
+{
+	RELAY_STATUS_ERROR_NONE = 0,
+	RELAY_STATUS_ERROR_WELDING = 10,
+	RELAY_STATUS_ERROR_DRIVING = 11
+};
+
+struct DcCommonInformation
+{
+	byte SysGunAreSameType;
+	byte CcsVersion;
+	char RelayCheckStatus[6];
+	char GunRelayWeldingOccur[2];
+	char GunRelayDrivingOccur[2];
+};
+
 #endif /* CONFIG_H_ */

BIN
EVSE/Projects/DS60-120/Apps/FactoryConfig


+ 6 - 4
EVSE/Projects/DS60-120/Apps/FactoryConfig.c

@@ -155,10 +155,12 @@ int main(int argc,char *argv[])
 	strcpy((char *) SysConfig.Eth1Interface.EthIpAddress, "192.168.0.10");
 	strcpy((char *) SysConfig.Eth1Interface.EthSubmaskAddress, "255.255.255.0");
 	strcpy((char *) SysConfig.Eth1Interface.EthGatewayAddress, "192.168.0.254");
-	if(SysConfig.ModelName[10] == 'W' || SysConfig.ModelName[10] == 'D')
-		SysConfig.AthInterface.WifiMode = 2;
-	else
-		SysConfig.AthInterface.WifiMode = 0;
+//	if(SysConfig.ModelName[10] == 'W' || SysConfig.ModelName[10] == 'D')
+//		SysConfig.AthInterface.WifiMode = 2;
+//	else
+//		SysConfig.AthInterface.WifiMode = 0;
+	SysConfig.AthInterface.WifiMode = 0;
+	SysConfig.TelecomInterface.TelcomEnabled = 0;
 	strcpy((char *) SysConfig.AthInterface.WifiSsid, "");
 	strcpy((char *) SysConfig.AthInterface.WifiPassword, "");
 	SysConfig.AthInterface.WifiRssi = 0;

BIN
EVSE/Projects/DS60-120/Apps/Module_EvComm


+ 231 - 88
EVSE/Projects/DS60-120/Apps/Module_EvComm.c

@@ -50,6 +50,8 @@ struct CHAdeMOData				*ShmCHAdeMOData;
 struct GBTData					*ShmGBTData;
 struct CcsData					*ShmCcsData;
 struct PsuData 					*ShmPsuData;
+struct MeterInformation			*ShmCsuMeterData;
+struct DcCommonInformation		*ShmDcCommonData;
 
 byte gun_count;
 int chargingTime[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
@@ -143,10 +145,11 @@ int StoreLogMsg(const char *fmt, ...)
 	}
 	else
 	{
-		sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog",
+		sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog_%s",
 			tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm,
 			buffer,
-			tm->tm_year+1900,tm->tm_mon+1);
+			tm->tm_year+1900,tm->tm_mon+1,
+			ShmSysConfigAndInfo->SysConfig.SerialNumber);
 		system(Buf);
 	}
 
@@ -187,30 +190,30 @@ void getTimeString(char *buff)
 	sprintf(buff, "[%04d-%02d-%02d %02d:%02d:%02d]", (1900+p->tm_year), (1+p->tm_mon), p->tm_mday, p->tm_hour, p->tm_hour, p->tm_sec);
 }
 
-bool CheckUniqNumber(byte value)
-{
-	for (byte index = 0; index < gun_count; index++)
-	{
-		if (_chargingData[index]->Evboard_id == value)
-		{
-			struct timeval _end_time;
-			gettimeofday(&_end_time, NULL);
-			unsigned long diff = 1000000 *	(_end_time.tv_sec - _id_assign_time.tv_sec) + _end_time.tv_usec - _id_assign_time.tv_usec;
-			if (diff >= 3000000)
-			{
-				gettimeofday(&_id_assign_time, NULL);
-				return true;
-			}
-			else
-			{
-				return false;
-			}
-		}
-	}
-
-	gettimeofday(&_id_assign_time, NULL);
-	return true;
-}
+//bool CheckUniqNumber(byte value)
+//{
+//	for (byte index = 0; index < gun_count; index++)
+//	{
+//		if (_chargingData[index]->Evboard_id == value)
+//		{
+//			struct timeval _end_time;
+//			gettimeofday(&_end_time, NULL);
+//			unsigned long diff = 1000000 *	(_end_time.tv_sec - _id_assign_time.tv_sec) + _end_time.tv_usec - _id_assign_time.tv_usec;
+//			if (diff >= 3000000)
+//			{
+//				gettimeofday(&_id_assign_time, NULL);
+//				return true;
+//			}
+//			else
+//			{
+//				return false;
+//			}
+//		}
+//	}
+//
+//	gettimeofday(&_id_assign_time, NULL);
+//	return true;
+//}
 
 //==========================================
 // Init all share memory
@@ -234,12 +237,10 @@ int InitShareMemory()
     	DEBUG_ERROR("shmat ShmSysConfigAndInfo NG\n");
 		#endif
     	result = FAIL;
-   	 }
-    else
-    {}
+   	}
 
-   	 //initial ShmStatusCodeData
-   	 if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData),  0777)) < 0)
+   	//initial ShmStatusCodeData
+   	if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData),  0777)) < 0)
     {
 		#ifdef SystemLogMessage
    		DEBUG_ERROR("shmget ShmStatusCodeData NG\n");
@@ -253,8 +254,6 @@ int InitShareMemory()
 		#endif
     	result = FAIL;
    	}
-    else
-    {}
 
  	//creat ShmPsuData
  	if ((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData),  0777)) < 0)
@@ -288,8 +287,6 @@ int InitShareMemory()
    			#endif
    			return FAIL;
    		}
-   		else
-   		{}
    	}
 	if(GB_QUANTITY > 0)
 	{
@@ -307,8 +304,6 @@ int InitShareMemory()
 	   		#endif
 	   		return FAIL;
 	   	}
-	   	else
-	   	{}
 	}
 
    	if(CCS_QUANTITY > 0)
@@ -326,8 +321,36 @@ int InitShareMemory()
    			#endif
    			return FAIL;
    		}
-   		else
-   		{}
+   	}
+
+   	if ((MeterSMId = shmget(ShmCsuMeterKey, sizeof(struct MeterInformation), IPC_CREAT | 0777)) < 0)
+   	{
+   		#ifdef SystemLogMessage
+   		DEBUG_ERROR("shmget ShmCsuMeterKey NG \n");
+   		#endif
+   		return 0;
+   	}
+   	else if ((ShmCsuMeterData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+   	{
+   		#ifdef SystemLogMessage
+   		DEBUG_ERROR("shmat ShmCsuMeterData NG \n");
+   		#endif
+   		return 0;
+   	}
+
+   	if ((MeterSMId = shmget(ShmCommonKey, sizeof(struct DcCommonInformation), IPC_CREAT | 0777)) < 0)
+   	{
+   		#ifdef SystemLogMessage
+   		DEBUG_ERROR("shmget ShmCommonKey NG \n");
+   		#endif
+   		return 0;
+   	}
+   	else if ((ShmDcCommonData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+   	{
+   		#ifdef SystemLogMessage
+   		DEBUG_ERROR("shmat ShmCommonKey NG \n");
+   		#endif
+   		return 0;
    	}
 
     return result;
@@ -2686,6 +2709,7 @@ void CANReceiver()
 		int nbytes;
 		struct can_frame frame;
 		int intCmd;
+		bool isClearBuf = false;
 
 		// 槍資訊
 		struct ChargingInfoData *_chargingData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
@@ -2731,10 +2755,18 @@ void CANReceiver()
 			{
 				byte target;
 				byte targetGun = 0x00;
+				byte findIndex = 0x00;
+
 				intCmd = (int) (frame.can_id & CAN_EFF_MASK);
 
+				if (!isClearBuf)
+				{
+					continue;
+				}
+
 				if (intCmd == ADDRESS_REQ)
 				{
+					ShmDcCommonData->CcsVersion = _CCS_VERSION_CHECK_TAG_V013S0;
 					AddrAssignment(frame.data);
 					continue;
 				}
@@ -2743,6 +2775,15 @@ void CANReceiver()
 
 				for (byte _index = 0; _index < gun_count; _index++)
 				{
+					// 假設有找到回應的 Index
+					findIndex = target;
+					if (gun_count == 1 &&
+							_chargingData[_index]->Type == _Type_CCS_2 &&
+							ShmDcCommonData->CcsVersion == _CCS_VERSION_CHECK_TAG_V015S0)
+					{
+						target -= 1;
+					}
+
 					if (_chargingData[_index]->Evboard_id == target)
 					{
 						targetGun = _index;
@@ -2755,6 +2796,13 @@ void CANReceiver()
 					PRINTF_FUNC("EvComm (CANReceiver) : Target index = %x is < 0 or > QUANTITY \n", targetGun);
 					continue;
 				}
+				else if (gun_count == 1 && targetGun == 0 && findIndex == 1 &&
+						ShmDcCommonData->CcsVersion == _CCS_VERSION_CHECK_TAG_V015S0)
+				{
+					// 這樣的條件下~ 也是單槍 CCS 舊版本的狀況 : 因為舊版 CCS 不會 timeout, then send request id
+					ShmDcCommonData->CcsVersion = _CCS_VERSION_CHECK_TAG_V013S0;
+				}
+
 				if(intCmd == 256)
 				{
 					continue;
@@ -2980,7 +3028,10 @@ void CANReceiver()
 				}
 			}
 			else
+			{
+				isClearBuf = true;
 				usleep(10000);
+			}
 		}
 	}
 }
@@ -3020,7 +3071,6 @@ void SetPresentChargingOutputPower(struct ChargingInfoData *chargingData_1, stru
 
 	cur2 = (chargingData_2->PresentChargingCurrent * 10);
 
-
 	if (
 		(LogInfo[0][EV_LOG_NOW_OUTPUT_VOL] >= vol1 + CHK_VOL_RANGE) || (LogInfo[0][EV_LOG_NOW_OUTPUT_VOL] <= vol1 - CHK_VOL_RANGE) ||
 		(LogInfo[0][EV_LOG_NOW_OUTPUT_CUR] >= cur1 + CHK_CUR_RANGE) || (LogInfo[0][EV_LOG_NOW_OUTPUT_CUR] <= cur1 - CHK_CUR_RANGE) ||
@@ -3094,10 +3144,10 @@ void SetPresentChargingOutputCap(struct ChargingInfoData *chargingData_1, struct
 		}
 	}
 
-	if ((LogInfo[0][EV_LOG_OUTPUT_CAP_POW] <= pow1 - 0.5 || LogInfo[0][EV_LOG_OUTPUT_CAP_POW] >= pow1 + 0.5) ||
-		(LogInfo[0][EV_LOG_OUTPUT_CAP_CUR] <= cur1 - 0.5 || LogInfo[0][EV_LOG_OUTPUT_CAP_CUR] >= cur1+ 0.5) ||
-		(LogInfo[1][EV_LOG_OUTPUT_CAP_POW] <=  pow2 - 0.5 || LogInfo[1][EV_LOG_OUTPUT_CAP_POW] >=  pow2 + 0.5) ||
-		(LogInfo[1][EV_LOG_OUTPUT_CAP_CUR] <=  cur2 - 0.5 || LogInfo[1][EV_LOG_OUTPUT_CAP_CUR] >=  cur2 + 0.5))
+	if ((LogInfo[0][EV_LOG_OUTPUT_CAP_POW] <= pow1 - 5 || LogInfo[0][EV_LOG_OUTPUT_CAP_POW] >= pow1 + 5) ||
+		(LogInfo[0][EV_LOG_OUTPUT_CAP_CUR] <= cur1 - 5 || LogInfo[0][EV_LOG_OUTPUT_CAP_CUR] >= cur1 + 5) ||
+		(LogInfo[1][EV_LOG_OUTPUT_CAP_POW] <= pow2 - 5 || LogInfo[1][EV_LOG_OUTPUT_CAP_POW] >= pow2 + 5) ||
+		(LogInfo[1][EV_LOG_OUTPUT_CAP_CUR] <= cur2 - 5 || LogInfo[1][EV_LOG_OUTPUT_CAP_CUR] >= cur2 + 5))
 	{
 		PRINTF_FUNC("----------------------------------------------------- \n");
 		PRINTF_FUNC("To EV (Real) Power_1 = %.1f, Cur_1 = %.1f, Power_2 = %.1f, Cur_2 = %.1f \n",
@@ -3312,20 +3362,38 @@ byte GetStopChargingReasonByEvse(byte gunIndex, byte *reason)
 
 void SendCommunicationOnly(byte index)
 {
+	byte targetID = _chargingData[index]->Evboard_id;
+
+	if (gun_count == 1 &&
+			_chargingData[index]->Type == _Type_CCS_2 &&
+			ShmDcCommonData->CcsVersion == _CCS_VERSION_CHECK_TAG_V015S0)
+	{
+		targetID += 1;
+	}
+
 	SetChargingPermission(index, COMMUNICATION,
 		_chargingData[index]->AvailableChargingPower,
 		0,
 		0,
-		_chargingData[index]->Evboard_id);
+		targetID);
 }
 
 void SendStopOnly(byte index)
 {
+	byte targetID = _chargingData[index]->Evboard_id;
+
+	if (gun_count == 1 &&
+			_chargingData[index]->Type == _Type_CCS_2 &&
+			ShmDcCommonData->CcsVersion == _CCS_VERSION_CHECK_TAG_V015S0)
+	{
+		targetID += 1;
+	}
+
 	SetChargingPermission(index, STOP,
 		_chargingData[index]->AvailableChargingPower,
 		0,
 		0,
-		_chargingData[index]->Evboard_id);
+		targetID);
 }
 
 void FormatVoltageAndCurrent()
@@ -3415,6 +3483,49 @@ void FormatVoltageAndCurrent()
 	}
 }
 
+// 如果是使用 Meter 計算的話
+void CalOutputPowerAndEnergy(int _index)
+{
+	if(ShmSysConfigAndInfo->SysConfig.ModelName[3] == 'M')
+	{
+		//printf("(%d), totalChargingValue = %f \n", _index, ShmCsuMeterData->_meter[_index]._curTotalCharging / 100);
+		float totalChargingValue = ShmCsuMeterData->_meter[_index]._curTotalCharging / 100;
+
+		_chargingData[_index]->PresentChargedEnergy = totalChargingValue;
+		_chargingData[_index]->PowerConsumption = totalChargingValue;
+
+		if (ShmSysConfigAndInfo->SysConfig.BillingData.isBilling)
+		{
+			_chargingData[_index]->ChargingFee = totalChargingValue * ShmSysConfigAndInfo->SysConfig.BillingData.Cur_fee;
+		}
+	}
+	else
+	{
+		if (chargingTime[_index] == 0 ||
+			chargingTime[_index] > _chargingData[_index]->PresentChargedDuration)
+		{
+			chargingTime[_index] = _chargingData[_index]->PresentChargedDuration;
+		}
+		else
+		{
+			int passTime = _chargingData[_index]->PresentChargedDuration - chargingTime[_index];
+
+			if (passTime > 0)
+			{
+				float changingPow = (_chargingData[_index]->PresentChargingPower) * passTime / 3600;
+				if (ShmSysConfigAndInfo->SysConfig.BillingData.isBilling)
+				{
+					_chargingData[_index]->ChargingFee += changingPow * ShmSysConfigAndInfo->SysConfig.BillingData.Cur_fee;
+				}
+
+				_chargingData[_index]->PresentChargedEnergy += changingPow;
+				_chargingData[_index]->PowerConsumption += changingPow;
+				chargingTime[_index] = _chargingData[_index]->PresentChargedDuration;
+			}
+		}
+	}
+}
+
 int main(int argc, char *argv[])
 {
 	if(InitShareMemory() == FAIL)
@@ -3463,6 +3574,15 @@ int main(int argc, char *argv[])
 	{
 		for(byte _index = 0; _index < gun_count; _index++)
 		{
+			byte targetID = _chargingData[_index]->Evboard_id;
+
+			if (gun_count == 1 &&
+					_chargingData[_index]->Type == _Type_CCS_2 &&
+					ShmDcCommonData->CcsVersion == _CCS_VERSION_CHECK_TAG_V015S0)
+			{
+				targetID += 1;
+			}
+
 			if (priorityLow == 1)
 			{
 				// 優先權較低 - 只要有回應即不會再詢問
@@ -3483,18 +3603,19 @@ int main(int argc, char *argv[])
 					if (ShmCcsData->CommProtocol == _CCS_COMM_V2GMessage_DIN70121 &&
 						ShmCcsData->V2GMessage_DIN70121[_chargingData[_index]->type_index].SelfTest_Comp != PASS)
 					{
-						SyncRtcInfo(_index, _chargingData[_index]->Evboard_id, (int)rtc);
-						GetFirmwareVersion(_index, _chargingData[_index]->Evboard_id);
+						SyncRtcInfo(_index, targetID, (int)rtc);
+						GetFirmwareVersion(_index, targetID);
 					}
 				}
 
 				// 固定要取得的資訊 : 1.槍鎖狀態, 2."Connector 1" 溫度, 3."Connector 2" 溫度, 4.Pilot Voltage
 				//PRINTF_FUNC("GetMiscellaneousInfo. index = %d, Eid = %d \n", _index, _chargingData[_index]->Evboard_id);
+
 				GetMiscellaneousInfo(_index,
 						_chargingData[_index]->RelayK1K2Status,
 						_chargingData[_index]->PresentChargedEnergy,
 						(_chargingData[_index]->PresentChargingVoltage * 10),
-						_chargingData[_index]->Evboard_id);
+						targetID);
 			}
 
 			switch (_chargingData[_index]->SystemStatus)
@@ -3560,6 +3681,22 @@ int main(int argc, char *argv[])
 						chargingTime[_index] = 0;
 						SendErrorCount[_index] = 0;
 
+						// 使用 Meter 狀況
+						if(ShmSysConfigAndInfo->SysConfig.ModelName[3] == 'M')
+						{
+							if (ShmCsuMeterData->_meter[_index].isCalculation == NO)
+							{
+								if (ShmCsuMeterData->_meter[_index].curMeterValue != 0 ||
+									ShmCsuMeterData->_meter[_index]._chargingValue != 0 ||
+									ShmCsuMeterData->_meter[_index]._curTotalCharging != 0 )
+								{
+									ShmCsuMeterData->_meter[_index].curMeterValue = 0;
+									ShmCsuMeterData->_meter[_index]._chargingValue = 0;
+									ShmCsuMeterData->_meter[_index]._curTotalCharging = 0;
+								}
+							}
+						}
+
 						//maxChargingPow = ShmSysConfigAndInfo->SysConfig.MaxChargingPower * 10;
 						// ShmPsuData->SystemAvailablePower 已是 * 10
 						maxChargingPow = ShmPsuData->SystemAvailablePower;
@@ -3572,6 +3709,11 @@ int main(int argc, char *argv[])
 						LogInfo[_index][EV_LOG_MAX_BATT_VOL] = 0;
 						LogInfo[_index][EV_LOG_REAL_CAP_POW] = 0;
 						LogInfo[_index][EV_LOG_SOC] = 0;
+
+						if (gun_count == 1)
+							SetPresentChargingOutputPower(_chargingData[0], _chargingData[0]);
+						else if (gun_count == 2)
+							SetPresentChargingOutputPower(_chargingData[0], _chargingData[1]);
 					}
 					break;
 				case S_PREPARNING:
@@ -3589,7 +3731,7 @@ int main(int argc, char *argv[])
 				case S_PREPARING_FOR_EV:
 				{
 					// 開始確認車端是否同意開始充電 : 1.SOC, 2.Target Vol, 3.Target Cur, 4.Charging remaining time
-					GetOutputReq(_index, _chargingData[_index]->Evboard_id);
+					GetOutputReq(_index, targetID);
 
 					// 設定當前輸出
 					if (gun_count == 1)
@@ -3622,10 +3764,10 @@ int main(int argc, char *argv[])
 						_chargingData[_index]->AvailableChargingPower,
 								maxCur,
 								maxVol,
-								_chargingData[_index]->Evboard_id);
+								targetID);
 
 						// 取得車端電池資訊 : 1.AC or DC ? 2.Total battery cap, 3.Max battery vol, 4.Max battery cur
-						GetEvBatteryInfo(_index, _chargingData[_index]->Evboard_id);
+						GetEvBatteryInfo(_index, targetID);
 					}
 					gettimeofday(&_chk_ratingPower_timeout[_index], NULL);
 				}
@@ -3635,7 +3777,7 @@ int main(int argc, char *argv[])
 				case S_CCS_PRECHARGE_ST1:
 				{
 					// 開始確認車端是否同意開始充電
-					GetOutputReq(_index, _chargingData[_index]->Evboard_id);
+					GetOutputReq(_index, targetID);
 
 					// 設定當前輸出
 					if (gun_count == 1)
@@ -3704,47 +3846,26 @@ int main(int argc, char *argv[])
 									_result = GFD_WAIT;
 							}
 
-							SetIsolationStatus(_index, _result, _chargingData[_index]->Evboard_id);
+							SetIsolationStatus(_index, _result, targetID);
 						}
 
 						if(_chargingData[_index]->SystemStatus == S_CCS_PRECHARGE_ST0 &&
 							_chargingData[_index]->PrechargeStatus == PRECHARGE_READY)
 						{
-							SetEvsePrechargeInfo(_index, PRECHARGE_PRERELAY_PASS, _chargingData[_index]->Evboard_id);
+							SetEvsePrechargeInfo(_index, PRECHARGE_PRERELAY_PASS, targetID);
 						}
 					}
 				}
 					break;
 				case S_CHARGING:
 				{
-					// 計算 Power
+					// 當前 Power
 					_chargingData[_index]->PresentChargingPower = ((float)((_chargingData[_index]->PresentChargingVoltage) * (_chargingData[_index]->PresentChargingCurrent)) / 1000);
 
-					if (chargingTime[_index] == 0 ||
-							chargingTime[_index] > _chargingData[_index]->PresentChargedDuration)
-					{
-						chargingTime[_index] = _chargingData[_index]->PresentChargedDuration;
-					}
-					else
-					{
-						int passTime = _chargingData[_index]->PresentChargedDuration - chargingTime[_index];
-
-						if (passTime > 0)
-						{
-							float changingPow = (_chargingData[_index]->PresentChargingPower) * passTime / 3600;
-							if (ShmSysConfigAndInfo->SysConfig.BillingData.isBilling)
-							{
-								_chargingData[_index]->ChargingFee += changingPow * ShmSysConfigAndInfo->SysConfig.BillingData.Cur_fee;
-							}
-
-							_chargingData[_index]->PresentChargedEnergy += changingPow;
-							_chargingData[_index]->PowerConsumption += changingPow;
-							chargingTime[_index] = _chargingData[_index]->PresentChargedDuration;
-						}
-					}
+					CalOutputPowerAndEnergy(_index);
 
 					// 開始確認車端是否同意開始充電
-					GetOutputReq(_index, _chargingData[_index]->Evboard_id);
+					GetOutputReq(_index, targetID);
 
 					if (LogInfo[_index][EV_LOG_MAX_BATT_VOL] != _chargingData[_index]->EvBatteryMaxVoltage)
 					{
@@ -3776,11 +3897,11 @@ int main(int argc, char *argv[])
 
 					if(_chargingData[_index]->GroundFaultStatus == GFD_FAIL)
 					{
-						SetIsolationStatus(_index, _chargingData[_index]->GroundFaultStatus, _chargingData[_index]->Evboard_id);
+						SetIsolationStatus(_index, _chargingData[_index]->GroundFaultStatus, targetID);
 					}
 					else if(_chargingData[_index]->Type == _Type_CCS_2)
 					{
-						SetIsolationStatus(_index, _chargingData[_index]->GroundFaultStatus, _chargingData[_index]->Evboard_id);
+						SetIsolationStatus(_index, _chargingData[_index]->GroundFaultStatus, targetID);
 					}
 
 					// GFD 失敗再通知
@@ -3789,7 +3910,7 @@ int main(int argc, char *argv[])
 						if(_chargingData[_index]->Type == _Type_CCS_2 &&
 							_chargingData[_index]->PrechargeStatus == PRECHARGE_READY)
 						{
-							SetEvsePrechargeInfo(_index, PRECHARGE_CHARELAY_PASS, _chargingData[_index]->Evboard_id);
+							SetEvsePrechargeInfo(_index, PRECHARGE_CHARELAY_PASS, targetID);
 						}
 					}
 				}
@@ -3799,10 +3920,21 @@ int main(int argc, char *argv[])
 				{
 					// 設定當前輸出
 					if (gun_count == 1)
+					{
+						if (_chargingData[0]->FireChargingVoltage <= 500)
+							_chargingData[0]->PresentChargingCurrent = 0;
+
 						SetPresentChargingOutputPower(_chargingData[0], _chargingData[0]);
+					}
 					else if (gun_count == 2)
-						SetPresentChargingOutputPower(_chargingData[0], _chargingData[1]);
+					{
+						if (_chargingData[0]->FireChargingVoltage <= 500)
+							_chargingData[0]->PresentChargingCurrent = 0;
+						if (_chargingData[1]->FireChargingVoltage <= 500)
+							_chargingData[1]->PresentChargingCurrent = 0;
 
+						SetPresentChargingOutputPower(_chargingData[0], _chargingData[1]);
+					}
 					// 槍鎖還在,則代表是樁端要求的停止
 					if (SendErrorCount[_index] < 3 &&
 							(_chargingData[_index]->GunLocked == START ||
@@ -3816,16 +3948,16 @@ int main(int argc, char *argv[])
 							normalStop = 0x02;
 						}
 
-						EvseStopChargingEvent(normalStop, stopReason, _chargingData[_index]->Evboard_id);
+						EvseStopChargingEvent(normalStop, stopReason, targetID);
 						SendErrorCount[_index] += 1;
 					}
 
 					if(_chargingData[_index]->Type == _Type_CCS_2)
 					{
-						SetIsolationStatus(_index, _chargingData[_index]->GroundFaultStatus, _chargingData[_index]->Evboard_id);
+						SetIsolationStatus(_index, _chargingData[_index]->GroundFaultStatus, targetID);
 					}
 
-					GetOutputReq(_index, _chargingData[_index]->Evboard_id);
+					GetOutputReq(_index, targetID);
 
 					if (_chargingData[_index]->SystemStatus == S_ALARM)
 					{
@@ -3842,7 +3974,7 @@ int main(int argc, char *argv[])
 									_chargingData[_index]->AvailableChargingPower,
 									maxCur,
 									maxVol,
-									_chargingData[_index]->Evboard_id);
+									targetID);
 						}
 					}
 				}
@@ -3868,7 +4000,18 @@ int main(int argc, char *argv[])
 								_chargingData[_index]->AvailableChargingPower,
 								maxCur,
 								maxVol,
-								_chargingData[_index]->Evboard_id);
+								targetID);
+
+						if (_chargingData[_index]->EvBatterySoc >= 100)
+						{
+							//滿電,則直接清掉錯誤
+							if (_chargingData[_index]->Type == _Type_Chademo)
+								ClearAbnormalStatus_Chademo(_index);
+							else if (_chargingData[_index]->Type == _Type_GB)
+								ClearAbnormalStatus_GB(_index);
+							else if (_chargingData[_index]->Type == _Type_CCS_2)
+								ClearAbnormalStatus_CCS(_index);
+						}
 					}
 				}
 					break;

BIN
EVSE/Projects/DS60-120/Apps/Module_EventLogging


+ 8 - 4
EVSE/Projects/DS60-120/Apps/Module_EventLogging.c

@@ -73,10 +73,11 @@ int StoreLogMsg(const char *fmt, ...)
 	}
 	else
 	{
-		sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog",
+		sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog_%s",
 			tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm,
 			buffer,
-			tm->tm_year+1900,tm->tm_mon+1);
+			tm->tm_year+1900,tm->tm_mon+1,
+			ShmSysConfigAndInfo->SysConfig.SerialNumber);
 		system(Buf);
 	}
 
@@ -379,6 +380,7 @@ int main(void)
 							DEBUG_INFO("Recovery Fault Code = %s\n", EventCodeTmp);
 							ShmStatusCodeData->FaultCode.PreviousFaultVal[ByteCount] &= ~(1<<BitCount);
 							RemoveFaultCodeToBuf(EventCodeTmp);
+							EventCodeTmp[0] = '1';
 						}
 						else
 						{
@@ -395,7 +397,7 @@ int main(void)
 		}
 
 		//check Alarm Status
-		for(ByteCount=0;ByteCount<13;ByteCount++)
+		for(ByteCount=0;ByteCount<14;ByteCount++)
 		{
 			if(ShmStatusCodeData->AlarmCode.AlarmEvents.AlarmVal[ByteCount] != ShmStatusCodeData->AlarmCode.PreviousAlarmVal[ByteCount])
 			{
@@ -405,13 +407,14 @@ int main(void)
 					if(((tmp>>BitCount)&0x01) != ((ShmStatusCodeData->AlarmCode.PreviousAlarmVal[ByteCount]>>BitCount)&0x01))
 					{
 						memset(EventCodeTmp,0,sizeof(EventCodeTmp));
-						memcpy(EventCodeTmp,AlarmStatusCode[ByteCount*8+BitCount],sizeof(EventCodeTmp)-1);
+						memcpy(EventCodeTmp, AlarmStatusCode[ByteCount*8+BitCount],sizeof(EventCodeTmp)-1);
 						if(((tmp>>BitCount)&0x01)==0)//Recovered
 						{
 							//EventCodeTmp[0]=1;
 							DEBUG_INFO("Recovery Alarm Code = %s\n", EventCodeTmp);
 							ShmStatusCodeData->AlarmCode.PreviousAlarmVal[ByteCount] &= ~(1<<BitCount);
 							RemoveFaultCodeToBuf(EventCodeTmp);
+							EventCodeTmp[0] = '1';
 						}
 						else
 						{
@@ -445,6 +448,7 @@ int main(void)
 							DEBUG_INFO("Recovery Info Code = %s\n", EventCodeTmp);
 							ShmStatusCodeData->InfoCode.PreviousInfoVal[ByteCount] &= ~(1<<BitCount);
 							RemoveFaultCodeToBuf(EventCodeTmp);
+							EventCodeTmp[0] = '1';
 						}
 						else
 						{

BIN
EVSE/Projects/DS60-120/Apps/Module_InternalComm


+ 205 - 98
EVSE/Projects/DS60-120/Apps/Module_InternalComm.c

@@ -36,7 +36,12 @@
 #define FAIL				-1
 #define YES					1
 #define NO					0
-#define TEN_MINUTES			600
+#define STOP				0
+#define START				1
+#define RELAY_CHECK_TIME	5		// s
+#define OUTPUT_VOL_CHK_TIME	200 	// ms
+#define TEN_MINUTES			600		// s
+//#define TEN_MINUTES			5
 #define ENV_TEMP_MIN		45
 #define ENV_TEMP_MAX		50
 #define DEFAULT_AC_INDEX	2
@@ -58,6 +63,7 @@ struct RelayModuleData			*ShmRelayModuleData;
 struct LedModuleData			*ShmLedModuleData;
 struct PsuData 					*ShmPsuData;
 struct OCPP16Data				*ShmOCPP16Data;
+struct DcCommonInformation		*ShmDcCommonData;
 
 #define VIN_MAX_VOLTAGE_IEC			285	// 大於該值 : OVP
 #define VIN_MAX_REV_VOLTAGE_IEC		275	// 小於賦歸 OVP
@@ -114,8 +120,13 @@ struct ChargingInfoData *ac_chargingInfo[AC_QUANTITY];
 bool _isOutputNoneMatch[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 struct timeval _checkOutputNoneMatchTimer[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 
-bool _isRelayWelding[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
-struct timeval _checkRelayWeldingTimer[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
+//bool _isRelayWelding[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
+//struct timeval _checkRelayWeldingTimer[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
+bool _isOvpChkTimeFlag[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
+struct timeval _checkOutputVolProtectTimer[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
+
+// SMR1 *2 + SMR2 * 2 + Parallel * 2
+struct timeval _relayStateChkTimer[6];
 
 byte _threePhaseOvp[3] = {0, 0, 0};
 byte _threePhaseUvp[3] = {0, 0, 0};
@@ -231,10 +242,11 @@ int StoreLogMsg(const char *fmt, ...)
 	}
 	else
 	{
-		sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog",
+		sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog_%s",
 			tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm,
 			buffer,
-			tm->tm_year+1900,tm->tm_mon+1);
+			tm->tm_year+1900,tm->tm_mon+1,
+			ShmSysConfigAndInfo->SysConfig.SerialNumber);
 		system(Buf);
 	}
 
@@ -851,10 +863,18 @@ void CheckK1K2RelayOutput(byte index)
 		}
 	}
 
-	if (regRelay.relay_event.bits.Gun1_Parallel_N == YES && regRelay.relay_event.bits.Gun1_Parallel_P == YES)
-		ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus = YES;
-	else
-		ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus = NO;
+	if (ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus == YES)
+	{
+		if (regRelay.relay_event.bits.Gun1_Parallel_N == NO &&
+				regRelay.relay_event.bits.Gun1_Parallel_P == NO)
+			ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus = NO;
+	}
+	else if (ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus == NO)
+	{
+		if (regRelay.relay_event.bits.Gun1_Parallel_N == YES &&
+				regRelay.relay_event.bits.Gun1_Parallel_P == YES)
+				ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus = YES;
+	}
 
 //	PRINTF_FUNC("Check Relay Output. index = %d, RelayKPK2Status = %d, BridgeRelayStatus = %d \n",
 //			index, _chargingData[index]->RelayKPK2Status, ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus);
@@ -1087,7 +1107,7 @@ void SetK1K2RelayStatus(byte index)
 	else if ((_chargingData[index]->SystemStatus >= S_PREPARING_FOR_EVSE &&
 			_chargingData[index]->SystemStatus <= S_CHARGING))
 	{
-		if (_chargingData[index]->RelayWeldingCheck == YES)
+		//if (_chargingData[index]->RelayWeldingCheck == YES)
 		{
 			if (_chargingData[index]->Evboard_id == 0x01)
 			{
@@ -1534,6 +1554,21 @@ int InitShareMemory()
 		result = FAIL;
 	}
 
+	if ((MeterSMId = shmget(ShmCommonKey, sizeof(struct DcCommonInformation), IPC_CREAT | 0777)) < 0)
+   	{
+   		#ifdef SystemLogMessage
+   		DEBUG_ERROR("shmget ShmCommonKey NG \n");
+   		#endif
+   		return 0;
+   	}
+   	else if ((ShmDcCommonData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+   	{
+   		#ifdef SystemLogMessage
+   		DEBUG_ERROR("shmat ShmCommonKey NG \n");
+   		#endif
+   		return 0;
+   	}
+
 	return result;
 }
 
@@ -1662,6 +1697,34 @@ void Initialization()
 	}
 }
 
+void StartCheckRelayInfo(byte _chkIndex, byte toState)
+{
+	if (ShmDcCommonData->RelayCheckStatus[_chkIndex] == STOP)
+	{
+		gettimeofday(&_relayStateChkTimer[_chkIndex], NULL);
+		ShmDcCommonData->RelayCheckStatus[_chkIndex] = START;
+	}
+	else
+	{
+		if ((GetTimeoutValue(_relayStateChkTimer[_chkIndex]) / 1000) > RELAY_CHECK_TIME * 1000)
+		{
+			//PRINTF_FUNC ("relay welding or driving fault = %d \n", _chkIndex);
+			if (toState == 1)
+				ShmDcCommonData->RelayCheckStatus[_chkIndex] = RELAY_STATUS_ERROR_DRIVING;
+			else
+				ShmDcCommonData->RelayCheckStatus[_chkIndex] = RELAY_STATUS_ERROR_WELDING;
+		}
+	}
+}
+
+void StopCheckRelayInfo(byte _chkIndex)
+{
+	if (ShmDcCommonData->RelayCheckStatus[_chkIndex] != STOP)
+	{
+		ShmDcCommonData->RelayCheckStatus[_chkIndex] = STOP;
+	}
+}
+
 bool IsNoneMatchRelayStatus()
 {
 	bool result = false;
@@ -1675,26 +1738,80 @@ bool IsNoneMatchRelayStatus()
 		(regRelay.relay_event.bits.Gun1_Parallel_P != outputRelay.relay_event.bits.Gun1_Parallel_P) ||
 		(regRelay.relay_event.bits.Gun1_Parallel_N != outputRelay.relay_event.bits.Gun1_Parallel_N))
 	{
-		if (regRelay.relay_event.bits.AC_Contactor != outputRelay.relay_event.bits.AC_Contactor)
-			PRINTF_FUNC("AC Contact Relay none match, try to switch to %d \n", outputRelay.relay_event.bits.AC_Contactor);
-		if (regRelay.relay_event.bits.CCS_Precharge != outputRelay.relay_event.bits.CCS_Precharge)
-			PRINTF_FUNC("CCS Precharge Relay none match, try to switch to %d \n", outputRelay.relay_event.bits.CCS_Precharge);
-		if (regRelay.relay_event.bits.Gun1_P != outputRelay.relay_event.bits.Gun1_P)
-			PRINTF_FUNC("SMR1:D+ Relay none match, try to switch to %d \n", outputRelay.relay_event.bits.Gun1_P);
-		if (regRelay.relay_event.bits.Gun1_N != outputRelay.relay_event.bits.Gun1_N)
-			PRINTF_FUNC("SMR1:D- Relay none match, try to switch to %d \n", outputRelay.relay_event.bits.Gun1_N);
-		if (regRelay.relay_event.bits.Gun2_P != outputRelay.relay_event.bits.Gun2_P)
-			PRINTF_FUNC("SMR2:D+ Relay none match, try to switch to %d \n", outputRelay.relay_event.bits.Gun2_P);
-		if (regRelay.relay_event.bits.Gun2_N != outputRelay.relay_event.bits.Gun2_N)
-			PRINTF_FUNC("SMR2:D- Relay none match, try to switch to %d \n", outputRelay.relay_event.bits.Gun2_N);
-		if (regRelay.relay_event.bits.Gun1_Parallel_P != outputRelay.relay_event.bits.Gun1_Parallel_P)
-			PRINTF_FUNC("Parallel:D+ Relay none match, try to switch to %d \n", outputRelay.relay_event.bits.Gun1_Parallel_P);
-		if (regRelay.relay_event.bits.Gun1_Parallel_N != outputRelay.relay_event.bits.Gun1_Parallel_N)
-			PRINTF_FUNC("Parallel:D- Relay none match, try to switch to %d \n", outputRelay.relay_event.bits.Gun1_Parallel_N);
-
 		result = true;
 	}
 
+	if (regRelay.relay_event.bits.AC_Contactor != outputRelay.relay_event.bits.AC_Contactor)
+	{
+		//PRINTF_FUNC("AC Contact Relay none match, try to switch to %d \n", outputRelay.relay_event.bits.AC_Contactor);
+	}
+
+	if (regRelay.relay_event.bits.CCS_Precharge != outputRelay.relay_event.bits.CCS_Precharge)
+	{
+		//PRINTF_FUNC("CCS Precharge Relay none match, try to switch to %d \n", outputRelay.relay_event.bits.CCS_Precharge);
+	}
+
+	if (regRelay.relay_event.bits.Gun1_P != outputRelay.relay_event.bits.Gun1_P)
+	{
+		StartCheckRelayInfo(RELAY_SMR1_P_STATUS, outputRelay.relay_event.bits.Gun1_P);
+		//PRINTF_FUNC("SMR1:D+ Relay none match, try to switch to %d \n", outputRelay.relay_event.bits.Gun1_P);
+	}
+	else
+	{
+		StopCheckRelayInfo(RELAY_SMR1_P_STATUS);
+		//PRINTF_FUNC("SMR1:D+ Release %d \n");
+	}
+
+	if (regRelay.relay_event.bits.Gun1_N != outputRelay.relay_event.bits.Gun1_N)
+	{
+		StartCheckRelayInfo(RELAY_SMR1_N_STATUS, outputRelay.relay_event.bits.Gun1_N);
+		//PRINTF_FUNC("SMR1:D- Relay none match, try to switch to %d \n", outputRelay.relay_event.bits.Gun1_N);
+	}
+	else
+	{
+		StopCheckRelayInfo(RELAY_SMR1_N_STATUS);
+	}
+
+	if (regRelay.relay_event.bits.Gun2_P != outputRelay.relay_event.bits.Gun2_P)
+	{
+		StartCheckRelayInfo(RELAY_SMR2_P_STATUS, outputRelay.relay_event.bits.Gun2_P);
+		//PRINTF_FUNC("SMR2:D+ Relay none match, try to switch to %d \n", outputRelay.relay_event.bits.Gun2_P);
+	}
+	else
+	{
+		StopCheckRelayInfo(RELAY_SMR2_P_STATUS);
+	}
+
+	if (regRelay.relay_event.bits.Gun2_N != outputRelay.relay_event.bits.Gun2_N)
+	{
+		StartCheckRelayInfo(RELAY_SMR2_N_STATUS, outputRelay.relay_event.bits.Gun2_N);
+		//PRINTF_FUNC("SMR2:D- Relay none match, try to switch to %d \n", outputRelay.relay_event.bits.Gun2_N);
+	}
+	else
+	{
+		StopCheckRelayInfo(RELAY_SMR2_N_STATUS);
+	}
+
+	if (regRelay.relay_event.bits.Gun1_Parallel_P != outputRelay.relay_event.bits.Gun1_Parallel_P)
+	{
+		StartCheckRelayInfo(RELAY_PARA_P_STATUS, outputRelay.relay_event.bits.Gun1_Parallel_P);
+		//PRINTF_FUNC("Parallel:D+ Relay none match, try to switch to %d \n", outputRelay.relay_event.bits.Gun1_Parallel_P);
+	}
+	else
+	{
+		StopCheckRelayInfo(RELAY_PARA_P_STATUS);
+	}
+
+	if (regRelay.relay_event.bits.Gun1_Parallel_N != outputRelay.relay_event.bits.Gun1_Parallel_N)
+	{
+		StartCheckRelayInfo(RELAY_PARA_N_STATUS, outputRelay.relay_event.bits.Gun1_Parallel_N);
+		//PRINTF_FUNC("Parallel:D- Relay none match, try to switch to %d \n", outputRelay.relay_event.bits.Gun1_Parallel_N);
+	}
+	else
+	{
+		StopCheckRelayInfo(RELAY_PARA_N_STATUS);
+	}
+
 	return result;
 }
 
@@ -1762,8 +1879,7 @@ void CableCheckDetected(byte index)
 		if ((_chargingData[index]->SystemStatus >= S_PREPARING_FOR_EVSE && _chargingData[index]->SystemStatus <= S_TERMINATING) ||
 			(_chargingData[index]->SystemStatus >= S_CCS_PRECHARGE_ST0 && _chargingData[index]->SystemStatus <= S_CCS_PRECHARGE_ST1))
 		{
-			if (_chargingData[index]->SystemStatus == S_PREPARING_FOR_EVSE &&
-					_chargingData[index]->RelayWeldingCheck == YES)
+			if (_chargingData[index]->SystemStatus == S_PREPARING_FOR_EVSE)
 			{
 				SetGfdConfig(index, GFD_CABLECHK);
 			}
@@ -1781,8 +1897,7 @@ void CableCheckDetected(byte index)
 					SetGfdConfig(index, GFD_CHARGING);
 			}
 		}
-		else if(_chargingData[index]->SystemStatus == S_COMPLETE || _chargingData[index]->SystemStatus == S_PREPARNING
-				|| _chargingData[index]->SystemStatus == S_IDLE)
+		else
 		{
 			SetGfdConfig(index, GFD_IDLE);
 		}
@@ -1792,28 +1907,42 @@ void CableCheckDetected(byte index)
 void CheckOutputPowerOverCarReq(byte index)
 {
 	float fireV = _chargingData[index]->FireChargingVoltage;
-	float carV = _chargingData[index]->EvBatterytargetVoltage * 10;
+	float carV = _chargingData[index]->EvBatteryMaxVoltage * 10;
 
 	if ((_chargingData[index]->EvBatterytargetVoltage * 10) > 1500 &&
 			(_chargingData[index]->Type == _Type_Chademo ||
 				_chargingData[index]->Type == _Type_CCS_2 ||
 				_chargingData[index]->Type == _Type_GB))
 	{
-		if (fireV >= (carV + (carV * 0.1)))
+		if (fireV >= (carV + (carV * 0.02)))
 		{
-			PRINTF_FUNC("[Module_InternalComm]CheckOutputPowerOverCarReq NG : fire = %f, battery = %f \n",
-					_chargingData[index]->FireChargingVoltage, (_chargingData[index]->EvBatterytargetVoltage * 10));
-			DEBUG_ERROR("[Module_InternalComm]CheckOutputPowerOverCarReq NG : fire = %f, battery = %f \n",
-					_chargingData[index]->FireChargingVoltage, (_chargingData[index]->EvBatterytargetVoltage * 10));
+			if (!_isOvpChkTimeFlag[index])
+			{
+				if ((_chargingData[index]->PresentChargingVoltage * 10) >= VOUT_MIN_VOLTAGE * 10)
+				{
+					gettimeofday(&_checkOutputVolProtectTimer[index], NULL);
+					_isOvpChkTimeFlag[index] = YES;
+				}
+			}
+			else
+			{
+				if ((GetTimeoutValue(_checkOutputVolProtectTimer[index]) / 1000) >= OUTPUT_VOL_CHK_TIME)
+				{
+					PRINTF_FUNC("[Module_InternalComm]CheckOutputPowerOverCarReq NG : fire = %f, battery = %f \n",
+							_chargingData[index]->FireChargingVoltage, (_chargingData[index]->EvBatterytargetVoltage * 10));
+					DEBUG_ERROR("[Module_InternalComm]CheckOutputPowerOverCarReq NG : fire = %f, battery = %f \n",
+							_chargingData[index]->FireChargingVoltage, (_chargingData[index]->EvBatterytargetVoltage * 10));
 
-			if (_chargingData[index]->Type == _Type_Chademo)
-				ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemChademoOutputOVP = YES;
-			else if (_chargingData[index]->Type == _Type_CCS_2)
-				ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemCcsOutputOVP = YES;
-			else if (_chargingData[index]->Type == _Type_GB)
-				ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemGbOutputOVP = YES;
+					if (_chargingData[index]->Type == _Type_Chademo)
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemChademoOutputOVP = YES;
+					else if (_chargingData[index]->Type == _Type_CCS_2)
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemCcsOutputOVP = YES;
+					else if (_chargingData[index]->Type == _Type_GB)
+						ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemGbOutputOVP = YES;
 
-			_chargingData[index]->StopChargeFlag = YES;
+					_chargingData[index]->StopChargeFlag = YES;
+				}
+			}
 		}
 	}
 }
@@ -1860,35 +1989,35 @@ void CheckOutputVolNoneMatchFire(byte index)
 
 void CheckRelayWeldingStatus(byte index)
 {
-	if (!_isRelayWelding[index])
-	{
-		if ((_chargingData[index]->PresentChargingVoltage * 10) >= VOUT_MIN_VOLTAGE * 10)
-		{
-			gettimeofday(&_checkRelayWeldingTimer[index], NULL);
-			_isRelayWelding[index] = YES;
-		}
-	}
-	else
-	{
-		if ((GetTimeoutValue(_checkRelayWeldingTimer[index]) / 1000) >= 1000)
-		{
-			_chargingData[index]->RelayWeldingCheck = YES;
-			return;
-		}
-
-		if (_chargingData[index]->FireChargingVoltage >= VOUT_MIN_VOLTAGE)
-		{
-			if (_chargingData[index]->Type == _Type_Chademo)
-				ShmStatusCodeData->FaultCode.FaultEvents.bits.ChademoOutputRelayWelding = YES;
-			else if (_chargingData[index]->Type == _Type_GB)
-				ShmStatusCodeData->FaultCode.FaultEvents.bits.GbOutputRelayWelding = YES;
-			else if (_chargingData[index]->Type == _Type_CCS_2)
-				ShmStatusCodeData->FaultCode.FaultEvents.bits.CcsOutputRelayWelding = YES;
-
-			PRINTF_FUNC("CheckRelayWeldingStatus : fail \n");
-			_chargingData[index]->StopChargeFlag = YES;
-		}
-	}
+//	if (!_isRelayWelding[index])
+//	{
+//		if ((_chargingData[index]->PresentChargingVoltage * 10) >= VOUT_MIN_VOLTAGE * 10)
+//		{
+//			gettimeofday(&_checkRelayWeldingTimer[index], NULL);
+//			_isRelayWelding[index] = YES;
+//		}
+//	}
+//	else
+//	{
+//		if ((GetTimeoutValue(_checkRelayWeldingTimer[index]) / 1000) >= 1000)
+//		{
+//			_chargingData[index]->RelayWeldingCheck = YES;
+//			return;
+//		}
+//
+//		if (_chargingData[index]->FireChargingVoltage >= VOUT_MIN_VOLTAGE)
+//		{
+//			if (_chargingData[index]->Type == _Type_Chademo)
+//				ShmStatusCodeData->FaultCode.FaultEvents.bits.ChademoOutputRelayWelding = YES;
+//			else if (_chargingData[index]->Type == _Type_GB)
+//				ShmStatusCodeData->FaultCode.FaultEvents.bits.GbOutputRelayWelding = YES;
+//			else if (_chargingData[index]->Type == _Type_CCS_2)
+//				ShmStatusCodeData->FaultCode.FaultEvents.bits.CcsOutputRelayWelding = YES;
+//
+//			PRINTF_FUNC("CheckRelayWeldingStatus : fail \n");
+//			_chargingData[index]->StopChargeFlag = YES;
+//		}
+//	}
 }
 
 void GetPsuTempForFanSpeed()
@@ -2341,28 +2470,16 @@ void ResetDetAlarmStatus(byte gun)
 {
 	if (_chargingData[gun]->Type == _Type_Chademo)
 	{
-		if (ShmStatusCodeData->FaultCode.FaultEvents.bits.ChademoOutputRelayWelding == YES)
-			ShmStatusCodeData->FaultCode.FaultEvents.bits.ChademoOutputRelayWelding = NO;
-		if (ShmStatusCodeData->FaultCode.FaultEvents.bits.ChademoOutputRelayDrivingFault == YES)
-			ShmStatusCodeData->FaultCode.FaultEvents.bits.ChademoOutputRelayDrivingFault = NO;
 		if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemChademoOutputOVP == YES)
 			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemChademoOutputOVP = NO;
 	}
 	else if (_chargingData[gun]->Type == _Type_GB)
 	{
-		if (ShmStatusCodeData->FaultCode.FaultEvents.bits.GbOutputRelayWelding == YES)
-			ShmStatusCodeData->FaultCode.FaultEvents.bits.GbOutputRelayWelding = NO;
-		if (ShmStatusCodeData->FaultCode.FaultEvents.bits.GbOutputRelayDrivingFault == YES)
-			ShmStatusCodeData->FaultCode.FaultEvents.bits.GbOutputRelayDrivingFault = NO;
 		if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemGbOutputOVP == YES)
 			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemGbOutputOVP = NO;
 	}
 	else if (_chargingData[gun]->Type == _Type_CCS_2)
 	{
-		if (ShmStatusCodeData->FaultCode.FaultEvents.bits.CcsOutputRelayWelding == YES)
-			ShmStatusCodeData->FaultCode.FaultEvents.bits.CcsOutputRelayWelding = NO;
-		if (ShmStatusCodeData->FaultCode.FaultEvents.bits.CcsOutputRelayDrivingFault == YES)
-			ShmStatusCodeData->FaultCode.FaultEvents.bits.CcsOutputRelayDrivingFault = NO;
 		if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemCcsOutputOVP == YES)
 			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemCcsOutputOVP = NO;
 	}
@@ -2482,8 +2599,8 @@ int main(void)
 
 				if (_chargingData[i]->SystemStatus == S_IDLE)
 				{
-					_chargingData[i]->RelayWeldingCheck = NO;
-					_isRelayWelding[i] = NO;
+					//_chargingData[i]->RelayWeldingCheck = NO;
+					_isOvpChkTimeFlag[i] = NO;
 					ResetDetAlarmStatus(i);
 				}
 
@@ -2496,19 +2613,9 @@ int main(void)
 					_chargingData[i]->IsReadyToCharging = YES;
 					isCharging = true;
 
-					// 限定只有在槍類別為 GBT 的時候才做 relay welding 的判斷
-					if (_chargingData[i]->Type == _Type_GB)
-					{
-						if (_chargingData[i]->SystemStatus >= S_PREPARING_FOR_EVSE &&
-							_chargingData[i]->RelayWeldingCheck == NO)
-							CheckRelayWeldingStatus(i);
-					}
-					else
-						_chargingData[i]->RelayWeldingCheck = YES;
-
 					if (_chargingData[i]->SystemStatus == S_CHARGING)
 					{
-						CheckOutputPowerOverCarReq(i);
+						CheckOutputPowerOverCarReq(i);    // load dump
 						CheckOutputVolNoneMatchFire(i);
 					}
 					else

BIN
EVSE/Projects/DS60-120/Apps/Module_LcmControl


+ 39 - 26
EVSE/Projects/DS60-120/Apps/Module_LcmControl.c

@@ -39,10 +39,11 @@ int StoreLogMsg(const char *fmt, ...)
 	}
 	else
 	{
-		sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog",
+		sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog_%s",
 			tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm,
 			buffer,
-			tm->tm_year+1900,tm->tm_mon+1);
+			tm->tm_year+1900,tm->tm_mon+1,
+			ShmSysConfigAndInfo->SysConfig.SerialNumber);
 		system(Buf);
 	}
 
@@ -373,36 +374,38 @@ void ChangeWarningFunc()
 //================================================
 // QR Code process
 //================================================
-void ChangeQrCode_Idle(char *input)
+void ChangeQrCode_Idle(char *input, byte len)
 {
-	int len = strlen(input);
 	byte cmd[len];
-
 	int loop = 0;
-	int i = 0;
 
+	input[len] = '\0';
+	cmd[len] = '\0';
 	while(input[loop] != '\0')
 	{
-		cmd[i++] = input[loop++];
+		cmd[loop] = input[loop];
+		loop++;
 	}
 
-	DisplayValueToLcm(__qr_code, cmd, len);
+	//printf("cmd = %s, len = %d \n", cmd, len + 1);
+	DisplayValueToLcm(__qr_code, cmd, len + 1);
 }
 
-void ChangeQrCode_Charge(char *input)
+void ChangeQrCode_Charge(char *input, byte len)
 {
-	int len = strlen(input);
 	byte cmd[len];
-
 	int loop = 0;
-	int i = 0;
 
+	input[len] = '\0';
+	cmd[len] = '\0';
 	while(input[loop] != '\0')
 	{
-		cmd[i++] = input[loop++];
+		cmd[loop] = input[loop];
+		loop++;
 	}
 
-	DisplayValueToLcm(__qr_code_pre, cmd, len);
+	//printf("2 - cmd = %s, len = %d \n", cmd, len + 1);
+	DisplayValueToLcm(__qr_code_pre, cmd, len + 1);
 }
 
 //================================================
@@ -1061,7 +1064,16 @@ void ProcessPageInfo()
 				if (ShmSysConfigAndInfo->SysConfig.isQRCode)
 				{
 					needReloadQr = false;
-					ChangeQrCode_Idle((char *)ShmSysConfigAndInfo->SysConfig.SystemId);
+					if (ShmSysConfigAndInfo->SysConfig.QRCodeMadeMode == NO)
+					{
+						byte len = strlen((char *)ShmSysConfigAndInfo->SysConfig.SystemId);
+						ChangeQrCode_Idle((char *)ShmSysConfigAndInfo->SysConfig.SystemId, len);
+					}
+					else
+					{
+						byte len = strlen((char *)ShmSysConfigAndInfo->SysConfig.QRCodeContent);
+						ChangeQrCode_Idle((char *)ShmSysConfigAndInfo->SysConfig.QRCodeContent, len);
+					}
 				}
 			}
 		}
@@ -1378,7 +1390,16 @@ void ProcessPageInfo()
 						if (ShmSysConfigAndInfo->SysConfig.isQRCode)
 						{
 							needReloadQr = false;
-							ChangeQrCode_Charge((char *)ShmSysConfigAndInfo->SysConfig.SystemId);
+							if (ShmSysConfigAndInfo->SysConfig.QRCodeMadeMode == NO)
+							{
+								byte len = strlen((char *)ShmSysConfigAndInfo->SysConfig.SystemId);
+								ChangeQrCode_Charge((char *)ShmSysConfigAndInfo->SysConfig.SystemId, len);
+							}
+							else
+							{
+								byte len = strlen((char *)ShmSysConfigAndInfo->SysConfig.QRCodeContent);
+								ChangeQrCode_Charge((char *)ShmSysConfigAndInfo->SysConfig.QRCodeContent, len);
+							}
 						}
 					}
 				}
@@ -1498,16 +1519,8 @@ int main(void)
 	Initialization();
 
 //	ChangeToOtherPage(_LCM_IDLE);
-//	ChangeDisplay2Value(__conn_status, _connect);
-//	ChangeDisplay2Value(__ethernet_status, _eth_connect);
-//	ChangeDisplay2Value(__wifi_status, _wifi_connect);
-//	ChangeDisplay2Value(__3G4G_status, _3G4G_connect);
-//
-//	ChangeDisplay2Value(__conn_status, _disconnect);
-//	ChangeDisplay2Value(__ethernet_status, _eth_disconnect);
-//	ChangeDisplay2Value(__wifi_status, _wifi_disconnect);
-//	ChangeDisplay2Value(__3G4G_status, _3G4G_disconnect);
-//	return 0;
+
+//	return -1;
 	DefaultIconStatus();
 
 	while(_port != -1)

BIN
EVSE/Projects/DS60-120/Apps/Module_PrimaryComm


+ 140 - 3
EVSE/Projects/DS60-120/Apps/Module_PrimaryComm.c

@@ -42,6 +42,7 @@ typedef unsigned char 		byte;
 struct SysConfigAndInfo			*ShmSysConfigAndInfo;
 struct StatusCodeData 			*ShmStatusCodeData;
 struct PrimaryMcuData			*ShmPrimaryMcuData;
+struct MeterInformation			*ShmCsuMeterData;
 
 void trim(char *s);
 int mystrcmp(char *p1,char *p2);
@@ -57,9 +58,13 @@ Rtc rtc;
 struct timeval _flash_time;
 byte flash = NO;
 
+byte gun_count;
+
 byte _curDeviceStatus[3] = {0, 0, 0};
 byte _reCheckCount[3] = {0, 0, 0};
 
+struct ChargingInfoData *_chargingData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
+
 void PRINTF_FUNC(char *string, ...);
 
 int StoreLogMsg(const char *fmt, ...);
@@ -92,10 +97,11 @@ int StoreLogMsg(const char *fmt, ...)
 	}
 	else
 	{
-		sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog",
+		sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog_%s",
 			tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm,
 			buffer,
-			tm->tm_year+1900,tm->tm_mon+1);
+			tm->tm_year+1900,tm->tm_mon+1,
+			ShmSysConfigAndInfo->SysConfig.SerialNumber);
 		system(Buf);
 	}
 
@@ -245,6 +251,21 @@ int InitShareMemory()
 		result = FAIL;
 	}
 
+	if ((MeterSMId = shmget(ShmCsuMeterKey, sizeof(struct MeterInformation), IPC_CREAT | 0777)) < 0)
+   	{
+   		#ifdef SystemLogMessage
+   		DEBUG_ERROR("shmget ShmCsuMeterKey NG \n");
+   		#endif
+   		return 0;
+   	}
+   	else if ((ShmCsuMeterData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+   	{
+   		#ifdef SystemLogMessage
+   		DEBUG_ERROR("shmat ShmCsuMeterData NG \n");
+   		#endif
+   		return 0;
+   	}
+
     return result;
 }
 
@@ -313,6 +334,54 @@ void GetInputGpioStatus()
 	}
 }
 
+void GetMeterConsumption(byte index)
+{
+	if (Query_Meter_value(Uart1Fd, Addr.IoExtend, &ShmCsuMeterData->_meter[index], &ShmCsuMeterData->isWorking, index) == PASS)
+	{
+		if (!ShmCsuMeterData->isWorking)
+		{
+			//ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MeterCommTimeout = YES;
+			return;
+		}
+
+		if (ShmCsuMeterData->_meter[index].isCalculation == YES)
+		{
+//			printf("Meter%d, Comsumption = %.1f, curMeterValue = %.1f \n",
+//					index,
+//					ShmCsuMeterData->_meter[index].newMeterValue,
+//					ShmCsuMeterData->_meter[index].curMeterValue);
+
+			if (ShmCsuMeterData->_meter[index].curMeterValue == 0)
+				ShmCsuMeterData->_meter[index].curMeterValue = ShmCsuMeterData->_meter[index].newMeterValue;
+			else
+			{
+				// 最大充時,兩個都會累加,但只輸出給一槍使用
+				ShmCsuMeterData->_meter[index]._chargingValue += ShmCsuMeterData->_meter[index].newMeterValue - ShmCsuMeterData->_meter[index].curMeterValue;
+
+				if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX ||
+					(ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER &&
+					ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_RELAY_A_TO_M))
+				{
+					for (byte subIndex = 0; subIndex < gun_count; subIndex++)
+					{
+						if (_chargingData[subIndex]->SystemStatus == S_CHARGING)
+						{
+							ShmCsuMeterData->_meter[subIndex]._curTotalCharging += ShmCsuMeterData->_meter[index].newMeterValue - ShmCsuMeterData->_meter[index].curMeterValue;
+							break;
+						}
+					}
+				}
+				else
+				{
+					ShmCsuMeterData->_meter[index]._curTotalCharging += ShmCsuMeterData->_meter[index].newMeterValue - ShmCsuMeterData->_meter[index].curMeterValue;
+				}
+
+				ShmCsuMeterData->_meter[index].curMeterValue = ShmCsuMeterData->_meter[index].newMeterValue;
+			}
+		}
+	}
+}
+
 void SetOutputGpio(byte flash)
 {
 	Gpio_out gpio;
@@ -422,6 +491,62 @@ 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;
 }
 
+//================================================
+//================================================
+// CANBUS receive task
+//================================================
+//================================================
+bool FindChargingInfoData(byte target, struct ChargingInfoData **chargingData)
+{
+	for (byte index = 0; index < CHAdeMO_QUANTITY; index++)
+	{
+		if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == target)
+		{
+			chargingData[target] = &ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index];
+			return true;
+		}
+	}
+
+	for (byte index = 0; index < CCS_QUANTITY; index++)
+	{
+		if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == target)
+		{
+			chargingData[target] = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[index];
+			return true;
+		}
+	}
+
+	for (byte index = 0; index < GB_QUANTITY; index++)
+	{
+		if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == target)
+		{
+			chargingData[target] = &ShmSysConfigAndInfo->SysInfo.GbChargingData[index];
+			return true;
+		}
+	}
+
+	return false;
+}
+
+void Initialization()
+{
+	bool isPass = false;
+	while(!isPass)
+	{
+		isPass = true;
+		for (byte _index = 0; _index < gun_count; _index++)
+		{
+			if (!FindChargingInfoData(_index, &_chargingData[0]))
+			{
+				DEBUG_ERROR("EvComm (main) : FindChargingInfoData false \n");
+				isPass = false;
+				break;
+			}
+		}
+		sleep(1);
+	}
+}
+
 int main(void)
 {
 	if(InitShareMemory() == FAIL)
@@ -453,8 +578,12 @@ int main(void)
 	}
 
 	SetRtcData();
-	//SetModelName();
+	SetModelName();
 	gettimeofday(&_flash_time, NULL);
+	gun_count = ShmSysConfigAndInfo->SysConfig.TotalConnectorCount;
+	Initialization();
+	byte _count = 0;
+
 	for(;;)
 	{
 		if (strcmp((char *)ShmSysConfigAndInfo->SysInfo.LcmHwRev, " ") == 0x00)
@@ -493,6 +622,14 @@ int main(void)
 		else
 		{
 			GetInputGpioStatus();
+
+			if(ShmSysConfigAndInfo->SysConfig.ModelName[3] == 'M')
+			{
+				GetMeterConsumption(_count);
+				_count++;
+				if (_count >= gun_count)
+					_count = 0;
+			}
 		}
 
 		usleep(100000);

BIN
EVSE/Projects/DS60-120/Apps/Module_PsuComm


+ 98 - 32
EVSE/Projects/DS60-120/Apps/Module_PsuComm.c

@@ -34,6 +34,8 @@ byte getAvailableCapOffset = 5;
 byte deratingKeepCount = 0;
 byte psuCmdSeq = _PSU_CMD_CAP;
 
+byte startModuleFlag = false;
+
 float chargingOutputLogInfo[2][4];
 
 void PRINTF_FUNC(char *string, ...);
@@ -78,10 +80,11 @@ int StoreLogMsg(const char *fmt, ...)
 	}
 	else
 	{
-		sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog",
+		sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog_%s",
 			tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm,
 			buffer,
-			tm->tm_year+1900,tm->tm_mon+1);
+			tm->tm_year+1900,tm->tm_mon+1,
+			ShmSysConfigAndInfo->SysConfig.SerialNumber);
 		system(Buf);
 	}
 
@@ -192,7 +195,7 @@ void AbnormalStopAnalysis(byte gun_index, int errCode)
 		{
 			if(DetectBitValue(byteIndex , bitIndex) == 1)
 			{
-				switch(byteIndex)
+				switch(i)
 				{
 					case 0:
 					{
@@ -340,10 +343,37 @@ void GetStatusCallback(byte group, byte SN, byte temp, int alarm)
 		}
 
 		for(byte psuIndex = 0; psuIndex < conn_1_count; psuIndex++)
-			PRINTF_FUNC("Connector 1 - PSU Number = %d \n", connector_1[psuIndex]);
+			PRINTF_FUNC("DC Left Gun - PSU Number = %d \n", connector_1[psuIndex]);
 
 		for(byte psuIndex = 0; psuIndex < conn_2_count; psuIndex++)
-			PRINTF_FUNC("Connector 2 - PSU Number = %d \n", connector_2[psuIndex]);
+			PRINTF_FUNC("DC Right Gun - PSU Number = %d \n", connector_2[psuIndex]);
+
+		if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount > 1)
+		{
+			// 雙槍才需要考慮是否模塊 switch 撥錯了
+			char EvsePower[2];
+			byte maxCount = 0;
+			int power = 0;
+
+			EvsePower[2] = '\0';
+			if (strlen((char *) ShmSysConfigAndInfo->SysConfig.ModelName) >= 6)
+			{
+				strncpy(EvsePower, (char *)(ShmSysConfigAndInfo->SysConfig.ModelName + 4), 2);
+				power = atoi(EvsePower);
+			}
+
+			// 超過 90 KW 或 360 KW
+			if (power < 30 || power == 36)
+				power *= 10;
+
+			maxCount = ((power / 30) + 1) / 2;
+
+			if (conn_1_count > maxCount ||
+					conn_2_count > maxCount)
+			{
+				ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDipSwitchStestFail = YES;
+			}
+		}
 	}
 }
 // no using -- GetOutputAndTempCallback End
@@ -1063,7 +1093,7 @@ void GetModuleStatusCallback(byte address, unsigned char isErr, unsigned char st
 	int alarm = (err2 << 24) | (err3 << 16) | (err4 << 8);
 
 	ShmPsuData->PsuGroup[group1].PsuModule[address].AlarmCode = alarm;
-	AbnormalStopAnalysis(group1, alarm);
+	//AbnormalStopAnalysis(group1, alarm);
 }
 
 void GetModuleInputCallback(byte address, unsigned short inputR,
@@ -1087,6 +1117,7 @@ void GetModuleInputCallback(byte address, unsigned short inputR,
 	//PRINTF_FUNC("***Input*** address = %d, R = %d, S = %d, T = %d \n",
 	//		address, inputR, inputS, inputT);
 }
+
 //==========================================
 // Init all share memory
 //==========================================
@@ -1146,7 +1177,6 @@ int InitShareMemory()
 		#endif
 		result = FAIL;
 	 }
-	memset(ShmPsuData,0,sizeof(struct PsuData));
 
     return result;
 }
@@ -1251,7 +1281,7 @@ void CheckSmartChargingStep(bool isWaitingAver, bool isCharging, bool canAverage
 			}
 			else
 			{
-				PRINTF_FUNC("=============Smart Charging : _REASSIGNED_NONE============= Step 0 \n");
+				PRINTF_FUNC("=============Smart Charging Aver mode : _REASSIGNED_NONE============= Step 0 \n");
 				ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE;
 			}
 		}
@@ -1304,8 +1334,9 @@ void PreCheckSmartChargingStep()
 				if (toAverVolPoint == (chargingInfo[index]->EvBatterytargetCurrent * 10))
 				{
 					// 欲最大充 -> 均充需要等待充電中的輸出電流拉高到目標電流
-					if ((chargingInfo[index]->PresentChargingCurrent * 10) >=
-							(chargingInfo[index]->EvBatterytargetCurrent * 10) - CHK_CUR_RANGE)
+//					chargingInfo[index]->PresentChargingCurrent = 60;
+//					if ((chargingInfo[index]->PresentChargingCurrent * 10) >=
+//							(chargingInfo[index]->EvBatterytargetCurrent * 10) - CHK_CUR_RANGE)
 					{
 						if (toAverVolCount == 0)
 							isWaitingAver = true;
@@ -1325,6 +1356,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))
@@ -1332,10 +1371,11 @@ void PreCheckSmartChargingStep()
 			isReadToCharging = true;
 		}
 
-		if (chargingInfo[index]->DeratingChargingCurrent < STOP_CURRENT)
-		{
-			CanAverageCharging = false;
-		}
+		// 不可用 : 因為電壓拔升過程~ 也是 < STOP_CURRENT
+//		if (chargingInfo[index]->DeratingChargingCurrent < STOP_CURRENT)
+//		{
+//			CanAverageCharging = false;
+//		}
 	}
 
 	CheckSmartChargingStep(isWaitingAver, isCharging, CanAverageCharging);
@@ -1563,6 +1603,7 @@ int main(void)
 				if (time > 1500)
 				{
 					PreCheckSmartChargingStep();
+					startModuleFlag = true;
 					gettimeofday(&_cmdSubPriority_time, NULL);
 				}
 
@@ -1641,7 +1682,7 @@ int main(void)
 
 							if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_GET_NEW_CAP)
 							{
-								if (ShmPsuData->SystemAvailableCurrent != chargingInfo[groupIndex]->AvailableChargingCurrent)
+								//if (ShmPsuData->SystemAvailableCurrent != chargingInfo[groupIndex]->AvailableChargingCurrent)
 								{
 									// 車端要求電流為該充電槍的額定輸出電流的範圍內
 									if ((chargingInfo[groupIndex]->EvBatterytargetCurrent * 10) <= ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent + DERATING_GAP ||
@@ -1669,13 +1710,14 @@ int main(void)
 							{
 								bool isChanged = false;
 
+								PRINTF_FUNC("Max To Ava mode (3-1) : Gun_%d, PresentChargingCurrent = %f, AvailableChargingCurrent = %f, EvBatterytargetCurrent = %f, GroupPresentOutputCurrent = %d \n", groupIndex,
+									(chargingInfo[groupIndex]->PresentChargingCurrent * 10),
+									chargingInfo[groupIndex]->AvailableChargingCurrent,
+									(chargingInfo[groupIndex]->EvBatterytargetCurrent * 10),
+									ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent);
+
 								if (chargingInfo[groupIndex]->AvailableChargingCurrent <= (chargingInfo[groupIndex]->EvBatterytargetCurrent * 10))
 								{
-									PRINTF_FUNC("Max To Ava mode (3-1) : Gun_%d, PresentChargingCurrent = %f, AvailableChargingCurrent = %f, EvBatterytargetCurrent = %f \n", groupIndex,
-										(chargingInfo[groupIndex]->PresentChargingCurrent * 10),
-										chargingInfo[groupIndex]->AvailableChargingCurrent,
-										(chargingInfo[groupIndex]->EvBatterytargetCurrent * 10));
-
 									for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++)
 									{
 										if (chargingInfo[subIndex]->SystemStatus == S_REASSIGN)
@@ -1687,8 +1729,9 @@ int main(void)
 										}
 									}
 								}
-								else if (((chargingInfo[groupIndex]->PresentChargingCurrent * 10) >= ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent - CHK_CUR_RANGE) &&
-									((chargingInfo[groupIndex]->PresentChargingCurrent * 10) <= ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent + CHK_CUR_RANGE))
+//								else if (((chargingInfo[groupIndex]->PresentChargingCurrent * 10) >= ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent - CHK_CUR_RANGE) &&
+//									((chargingInfo[groupIndex]->PresentChargingCurrent * 10) <= ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent + CHK_CUR_RANGE))
+								else if (chargingInfo[groupIndex]->PresentChargingCurrent == 0)
 								{
 									for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++)
 									{
@@ -1742,7 +1785,7 @@ int main(void)
 
 									if (reassignIndex != ELEMENT_NOT_FIND)
 									{
-										if ((GetTimeoutValue(_derating_time) / 1000) <= 50 ||
+										if ((GetTimeoutValue(_derating_time) / 1000) <= 150 ||
 											chargingInfo[groupIndex]->MaxChargingToAverPassFlag == 0)
 										{
 											chargingInfo[groupIndex]->MaxChargingToAverPassFlag = 1;
@@ -1823,7 +1866,7 @@ int main(void)
 										isStartOutputSwitch[index] = true;
 									}
 
-									if (isNeedToOpenPower)
+									if (isNeedToOpenPower || startModuleFlag)
 									{
 										SwitchPower(SYSTEM_CMD, PSU_POWER_ON);
 										FlashLed(SYSTEM_CMD, PSU_FLASH_ON);
@@ -1833,6 +1876,8 @@ int main(void)
 						}
 						else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER)
 						{
+							bool abnormalOutput = false;
+
 							// 智能判斷 Start -----------------------------------------------------------
 							if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_ADJUST_A_TO_M)
 							{
@@ -1841,6 +1886,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)
 									{
 										// 各群電壓接近平衡
@@ -1875,17 +1921,26 @@ int main(void)
 							{
 								int idleCurrent = 0;
 								int chargingCurrent = 0;
+								float outCurrent = 0;
 
 								for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++)
 								{
 									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
+									{
 										chargingCurrent = ShmPsuData->PsuGroup[subIndex].GroupPresentOutputCurrent;
+										outCurrent = chargingInfo[groupIndex]->EvBatterytargetVoltage * 10;
+									}
 								}
 
+								// 電樁輸出電流不足狀態
+								if (chargingCurrent + idleCurrent <= outCurrent - PRE_CHARG_RANGE)
+									abnormalOutput = true;
+
 								if (idleCurrent >= chargingCurrent - PRE_CHARG_RANGE)
 								{
 									PRINTF_FUNC("======= The Change to maximum charge mode is complete. (Step 15) ======= \n");
@@ -1893,7 +1948,7 @@ int main(void)
 								}
 								else
 								{
-									if ((GetTimeoutValue(_max_time) / 1000) > 500)
+									if ((GetTimeoutValue(_max_time) / 1000) > 300)
 									{
 										gettimeofday(&_max_time, NULL);
 									}
@@ -1910,6 +1965,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;
@@ -1934,19 +1990,28 @@ int main(void)
 
 									if (reassignIndex != ELEMENT_NOT_FIND)
 									{
-										if ((GetTimeoutValue(_max_time) / 1000) <= 50)
+										if ((GetTimeoutValue(_max_time) / 1000) <= 150)
 										{
 											//PRINTF_FUNC("set out (%d) value = %d******** 5 \n", reassignIndex, ZERO_CURRENT + preChargingTarget);
 											// 閒置模塊升壓,另對剛分配近來的模塊,預上升電流值 (preChargingCur)
 											PresentOutputVol(reassignIndex,
 												(chargingInfo[groupIndex]->EvBatterytargetVoltage * 10),
 												ZERO_CURRENT + preChargingTarget); Await();
+										}
 
-											byte _ovCahrgingCur = 0;
-											if (preChargingCur > PRE_CHARG_STEP_CUR)
-												_ovCahrgingCur = PRE_CHARG_STEP_CUR;
-
-											//PRINTF_FUNC("set out (%d) value = %f******** 6 \n", groupIndex, chargingInfo[groupIndex]->EvBatterytargetCurrent - preChargingCur - _ovCahrgingCur);
+										byte _ovCahrgingCur = 0;
+										if (preChargingCur > PRE_CHARG_STEP_CUR)
+											_ovCahrgingCur = PRE_CHARG_STEP_CUR;
+
+//										if (abnormalOutput)
+//										{
+//											PRINTF_FUNC("set out (%d) value = %f******** 6 \n", groupIndex, chargingInfo[groupIndex]->EvBatterytargetCurrent - preChargingCur - _ovCahrgingCur);
+//											PresentOutputVol(groupIndex,
+//												(chargingInfo[groupIndex]->EvBatterytargetVoltage * 10),
+//												ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent - preChargingCur - _ovCahrgingCur); Await();
+//										}
+//										else
+										{
 											PresentOutputVol(groupIndex,
 												(chargingInfo[groupIndex]->EvBatterytargetVoltage * 10),
 												(chargingInfo[groupIndex]->EvBatterytargetCurrent * 10) - preChargingCur - _ovCahrgingCur); Await();
@@ -2011,7 +2076,7 @@ int main(void)
 									}
 									else
 									{
-										if (!isStartOutputSwitch[groupIndex])
+										if (!isStartOutputSwitch[groupIndex] || startModuleFlag)
 										{
 											isStartOutputSwitch[groupIndex] = true;
 											SwitchPower(groupIndex, PSU_POWER_ON); Await();
@@ -2116,6 +2181,7 @@ int main(void)
 					}
 				}
 
+				startModuleFlag = false;
 				break;
 			}
 			case _TEST_MODE:

+ 35 - 1
EVSE/Projects/DS60-120/Apps/PrimaryComm.c

@@ -33,7 +33,7 @@
 #define FAIL				-1
 
 struct Address Addr={0x01,0x02,0x03,0x04,0xFF};
-struct Command Cmd={0x01,0x02,0x0a,0x83,0x86,0x87,0xe0,0xe1,0xe2,0xe3};
+struct Command Cmd={0x01,0x02,0x0a,0x2C,0x83,0x86,0x87,0xe0,0xe1,0xe2,0xe3};
 
 int tranceive(int fd, unsigned char* cmd, unsigned char cmd_len, unsigned char* rx)
 {
@@ -156,6 +156,40 @@ unsigned char Query_Gpio_Input(unsigned char fd, unsigned char targetAddr, Gpio_
 	return result;
 }
 
+unsigned char Query_Meter_value(unsigned char fd, unsigned char targetAddr, struct StructMeter *Ret_Buf, byte *isWork, unsigned char index)
+{
+	unsigned char result = FAIL;
+	unsigned char tx[8] = {0xaa, 0x00, targetAddr, Cmd.query_charging_power, 0x01, 0x00, index, 0x00};
+	unsigned char rx[512];
+	unsigned char chksum = 0x00;
+
+	for (int idx = 0; idx < (tx[4] | tx[5] << 8); idx++)
+			chksum ^= tx[6 + idx];
+	tx[7] = chksum;
+
+	unsigned char len = tranceive(fd, tx, sizeof(tx), rx);
+	if(len > 0)
+	{
+		chksum = 0x00;
+		for (int idx = 0; idx < (rx[4] | rx[5] << 8); idx++)
+		{
+			chksum ^= rx[6+idx];
+		}
+
+		if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
+		   (rx[2] == tx[1]) &&
+		   (rx[1] == tx[2]) &&
+		   (rx[3] == tx[3]))
+		{
+			Ret_Buf->newMeterValue = (rx[6] | (rx[7]<<8) | (rx[8]<<8) | (rx[9]<<8));
+			*isWork = rx[23];
+			result = PASS;
+		}
+	}
+
+	return result;
+}
+
 unsigned char Config_Gpio_Output(unsigned char fd, unsigned char targetAddr, Gpio_out *Set_Buf)
 {
 	unsigned char result = FAIL;

+ 3 - 0
EVSE/Projects/DS60-120/Apps/PrimaryComm.h

@@ -16,6 +16,8 @@ extern struct Command
 	unsigned char query_HW_Ver;		//0x02
 	unsigned char query_Gpio_In;		//0x0a
 
+	unsigned char query_charging_power;	// 0x2C
+
 	unsigned char config_Model_Name;			//0x83
 	unsigned char config_Gpio_Output;	//0x86
 	unsigned char config_Rtc_Data;		//0x87
@@ -64,6 +66,7 @@ typedef struct RTC
 extern unsigned char Query_FW_Ver(unsigned char fd, unsigned char targetAddr, Ver *Ret_Buf);
 extern unsigned char Query_HW_Ver(unsigned char fd, unsigned char targetAddr, Ver *Ret_Buf);
 extern unsigned char Query_Gpio_Input(unsigned char fd, unsigned char targetAddr, Gpio_in *Ret_Buf);
+extern unsigned char Query_Meter_value(unsigned char fd, unsigned char targetAddr, struct StructMeter *Ret_Buf, byte *isWork, unsigned char index);
 
 extern unsigned char Config_Gpio_Output(unsigned char fd, unsigned char targetAddr, Gpio_out *Set_Buf);
 extern unsigned char Config_Rtc_Data(unsigned char fd, unsigned char targetAddr, Rtc *Set_Buf);

BIN
EVSE/Projects/DS60-120/Apps/ReadCmdline


+ 20 - 2
EVSE/Projects/DS60-120/Apps/ReadCmdline.c

@@ -71,6 +71,7 @@ struct FanModuleData			*ShmFanModuleData;
 struct RelayModuleData			*ShmRelayModuleData;
 struct LedModuleData			*ShmLedModuleData;
 struct PsuData 					*ShmPsuData;
+struct DcCommonInformation		*ShmDcCommonData;
 
 struct ChargingInfoData 		*_chargingData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 struct ChargingInfoData 		*ac_chargingInfo[AC_QUANTITY];
@@ -231,6 +232,15 @@ int InitShareMemory()
    		result = FAIL;
    	}
 
+   	if ((MeterSMId = shmget(ShmCommonKey, sizeof(struct DcCommonInformation), IPC_CREAT | 0777)) < 0)
+   	{
+   		result = FAIL;
+   	}
+   	else if ((ShmDcCommonData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+   	{
+   		result = FAIL;
+   	}
+
     return result;
 }
 
@@ -271,6 +281,8 @@ void RunStatusProc(char *v1, char *v2)
 			printf ("index = %x, status = %x (%d)\n", _index, _chargingData[_index]->SystemStatus, _chargingData[_index]->IsAvailable);
 			printf ("SystemTimeoutFlag = %d, PageIndex = %d\n",
 					ShmSysConfigAndInfo->SysInfo.SystemTimeoutFlag, ShmSysConfigAndInfo->SysInfo.PageIndex);
+			printf ("SOC = %d \n", _chargingData[_index]->EvBatterySoc);
+			printf("Charging mode = %d \n", ShmSysConfigAndInfo->SysInfo.MainChargingMode);
 		}
 		else
 		{
@@ -435,7 +447,7 @@ void CreateOneError(char *v1)
 {
 	int value = atoi(v1);
 
-	ShmStatusCodeData->FaultCode.FaultEvents.bits.ChademoOutputRelayWelding = value;
+	ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CcsConnectorOTP = value;
 	//ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP = value;
 	//ShmSysConfigAndInfo->SysConfig.BillingData.isBilling = value;
 }
@@ -1147,13 +1159,15 @@ int main(void)
 			}
 		}
 
-		if(strcmp(newString[0], "state") == 0)
+		if(strcmp(newString[0], "state") == 0 || strcmp(newString[0], "st") == 0)
 		{
 			if (strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0)
 				continue;
 
 			// ºjª¬ºA
+			printf("=========================== \n");
 			RunStatusProc(newString[1], newString[2]);
+			printf("=========================== \n");
 		}
 		else if(strcmp(newString[0], "card") == 0)
 		{
@@ -1308,6 +1322,10 @@ int main(void)
 				printf ("FindChargingInfoData error\n");
 				continue;
 			}
+			printf("FirmwareUpdate = %d \n", ShmSysConfigAndInfo->SysInfo.FirmwareUpdate);
+			printf("ShmSysConfigAndInfo->SysInfo.WaitForPlugit = %d \n", ShmSysConfigAndInfo->SysInfo.WaitForPlugit);
+			printf("ShmSysConfigAndInfo->SysConfig.UserId = %s \n", ShmSysConfigAndInfo->SysConfig.UserId);
+			printf("ShmSysConfigAndInfo->SysInfo.AuthorizeFlag = %d \n", ShmSysConfigAndInfo->SysInfo.AuthorizeFlag);
 		}
 		else if(strcmp(newString[0], "strchg") == 0)
 		{

BIN
EVSE/Projects/DS60-120/Apps/UnsafetyOutputTask


BIN
EVSE/Projects/DS60-120/Apps/main


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 466 - 173
EVSE/Projects/DS60-120/Apps/main.c


BIN
EVSE/Projects/DS60-120/Images/FactoryDefaultConfig.bin


BIN
EVSE/Projects/DS60-120/Images/ramdisk.gz


BIN
EVSE/rootfs/root/OcppBackend20


Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно