Преглед на файлове

Merge branch 'DS60-120'

FolusWen преди 4 години
родител
ревизия
81043556b1

+ 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


Някои файлове не бяха показани, защото твърде много файлове са промени