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

2020.04.10 / TC Hsu

Actions: Update D0.06 source code, which patch from 180KW's codebase.

Image version    : N/A
Image checksum   : N/A

Hardware PWB P/N : N/A
Hardware Version : N/A

Files:

	modified:   EVSE/Projects/DM30/Apps/Config.h
	modified:   EVSE/Projects/DM30/Apps/Ev_Comm.c
	modified:   EVSE/Projects/DM30/Apps/FactoryConfig.c
	modified:   EVSE/Projects/DM30/Apps/Module_EvComm.c
	modified:   EVSE/Projects/DM30/Apps/Module_EvComm.h
	modified:   EVSE/Projects/DM30/Apps/Module_InternalComm.c
	modified:   EVSE/Projects/DM30/Apps/Module_LcmControl.c
	renamed:    EVSE/Projects/DM30/Apps/Module_LcmContro.h -> EVSE/Projects/DM30/Apps/Module_LcmControl.h
	modified:   EVSE/Projects/DM30/Apps/Module_PrimaryComm.c
	modified:   EVSE/Projects/DM30/Apps/Module_PsuComm.c
	modified:   EVSE/Projects/DM30/Apps/Module_PsuComm.h
	modified:   EVSE/Projects/DM30/Apps/ReadCmdline.c
	modified:   EVSE/Projects/DM30/Apps/main.c
TC_Hsu преди 5 години
родител
ревизия
a4ac5c60ad

+ 14 - 3
EVSE/Projects/DM30/Apps/Config.h

@@ -126,7 +126,9 @@ enum _MODULE_PSU_WORK_STEP
     GET_PSU_COUNT                       = 1,
     GET_SYS_CAP                         = 2,
     BOOTING_COMPLETE                    = 3,
+
     _WORK_CHARGING                      = 10,
+
     _NO_WORKING                         = 254,
     _INIT_PSU_STATUS                    = 255,
 };
@@ -139,10 +141,19 @@ enum _OFFLINE_POLICY
     _OFFLINE_POLICY_NO_CHARGING         = 0x03,
 };
 
-enum _SYS_AUTHORIZE_MODE
+enum _REASSIGNED_RESOURCE_STEP
 {
-    _SYS_AUTHORIZE_OCPP                 = 0x00,
-    _SYS_AUTHORIZE_FREE                 = 0x01,
+    _REASSIGNED_NONE =              0,  //
+    _REASSIGNED_PREPARE_M_TO_A =    1,  // 系統收到需要降載需求 (輸出總電流降低),PSU Task 收到將狀態切換至下個狀態
+    _REASSIGNED_GET_NEW_CAP =       2,  // 充電中的重新取得屬於自己火線上的總能量並透過小板通知車端 - 超過10秒直接跳下一步
+    _REASSIGNED_ADJUST_M_TO_A =     3,  // 模塊重新分配完成
+    _REASSIGNED_RELAY_M_TO_A =      4,  // 切斷橋接的 Relay
+
+    _REASSIGNED_PREPARE_A_TO_M =    11,
+    _REASSIGNED_ADJUST_A_TO_M =     12, // 模塊升壓
+    _REASSIGNED_RELAY_A_TO_M =      13, // 搭接橋接的 Relay
+    _REASSIGNED_WAITING =           14,
+    _REASSIGNED_COMP =              15,
 };
 
 enum _MAIN_CHARGING_MODE

+ 10 - 2
EVSE/Projects/DM30/Apps/Ev_Comm.c

@@ -160,12 +160,20 @@ void EvseStopChargingEvent(byte stopResult, byte *stopReason, byte toId)
     SendCmdToEvboard(id, data, 7);
 }
 
-void GetMiscellaneousInfo(byte gun_index, byte toId)
+void GetMiscellaneousInfo(byte gun_index, byte relayStatus, float power, float voltage, byte toId)
 {
     int id = PackageIdCmd(Ev_Cmd.get_miscellaneous_info + toId);
     byte data[8];
 
-    SendCmdToEvboard(id, data, 0);
+    int _power = power * 10;
+
+    data[0] = relayStatus;
+    data[1] = (int)_power & 0xff;
+    data[2] = ((int)_power >> 8) & 0xff;
+    data[3] = (int)voltage & 0xff;
+    data[4] = ((int)voltage >> 8) & 0xff;
+
+    SendCmdToEvboard(id, data, 5);
 }
 
 void SetIsolationStatus(byte gun_index, byte result, byte toId)

+ 1 - 3
EVSE/Projects/DM30/Apps/FactoryConfig.c

@@ -114,7 +114,7 @@ int main(int argc,char *argv[])
     strcat((char *)SysConfig.SystemId, (char *)SysConfig.SerialNumber);
 
     strcpy((char *)SysConfig.SystemDateTime, "");
-    SysConfig.AuthorisationMode = _SYS_AUTHORIZE_OCPP;
+    SysConfig.AuthorisationMode = AUTH_MODE_ENABLE;
     SysConfig.DefaultLanguage = 0;
     SysConfig.RfidCardNumEndian = 0;
     SysConfig.AcPlugInTimes = 0;
@@ -123,9 +123,7 @@ int main(int argc,char *argv[])
     SysConfig.Ccs2PlugInTimes = 0;
     SysConfig.ChademoPlugInTimes = 0;
     //********** Charging **********//
-    SysConfig.RatingCurrent = 65;           // 最大可輸出電流
     SysConfig.MaxChargingEnergy = 0;
-    SysConfig.MaxChargingPower = 30;        // 最大功率 : 跟著 model name 跑
     SysConfig.MaxChargingCurrent = 65;      // 最大可輸出電流
     SysConfig.MaxChargingDuration = 0;
     SysConfig.PhaseLossPolicy = 0;

+ 235 - 14
EVSE/Projects/DM30/Apps/Module_EvComm.c

@@ -39,20 +39,24 @@
 #define YES                 1
 #define NO                  0
 
-#define GUN_COUNT               CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY
-
 struct SysConfigAndInfo         *ShmSysConfigAndInfo;
 struct StatusCodeData           *ShmStatusCodeData;
 struct FanModuleData            *ShmFanModuleData;
 struct CHAdeMOData              *ShmCHAdeMOData;
+struct GBTData                  *ShmGBTData;
 struct CcsData                  *ShmCcsData;
 
 byte gun_count;
 int chargingTime[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 
+float _pow_1 = 0;
+float _cur_1 = 0;
+float _pow_2 = 0;
+float _cur_2 = 0;
+
 // 限制最大充電電壓,因應不同 type 槍線來限制
-// Chademo : 500V, CCS : 950V
-float maxChargingVol[2] = { 10000, 9500 };          // 限制最大充電電壓,如依照模塊則填上 0
+// Chademo : 500V, GB : 750, CCS : 950V
+float maxChargingVol[2] = { 9500, 9500 };           // 限制最大充電電壓,如依照模塊則填上 0
 // 限制最大充電電流與能量透過 Web
 float maxChargingCur[2] = { 0, 0 };                 // 限制最大充電電流,如依照模塊則填上 0
 float maxChargingPow = 0;                           // 限制最大充電能量,如依照模塊則填上 0
@@ -145,7 +149,7 @@ void PRINTF_FUNC(char *string, ...)
     vsnprintf(buffer, sizeof(buffer), string, args);
     va_end(args);
 
-    if (DEBUG)
+    if (ShmSysConfigAndInfo->SysConfig.SwitchDebugFlag == YES)
         printf("%s \n", buffer);
     else
         DEBUG_INFO("%s \n", buffer);
@@ -252,6 +256,25 @@ int InitShareMemory()
         else
         {}
     }
+    if(GB_QUANTITY > 0)
+    {
+        if ((MeterSMId = shmget(ShmGBTCommKey, sizeof(struct GBTData),  IPC_CREAT | 0777)) < 0)
+        {
+            #ifdef SystemLogMessage
+            DEBUG_ERROR("[shmget ShmGBTData NG \n");
+            #endif
+            return FAIL;
+        }
+        else if ((ShmGBTData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+        {
+            #ifdef SystemLogMessage
+            DEBUG_ERROR("shmat ShmGBTData NG \n");
+            #endif
+            return FAIL;
+        }
+        else
+        {}
+    }
 
     if(CCS_QUANTITY > 0)
     {
@@ -369,7 +392,7 @@ void AddrAssignment(byte *data)
 
     if (gun_count == 1)
         index = 0x01;
-    if (CheckUniqNumber(index))
+//  if (CheckUniqNumber(index))
     {
         PRINTF_FUNC("EV board id = %x \n", index);
 //      PRINTF_FUNC("target_number[0] = %x \n", target_number[0]);
@@ -422,6 +445,71 @@ void ClearAbnormalStatus_Chademo(byte gun_index)
     ShmStatusCodeData->InfoCode.InfoEvents.bits.ChademoChargeRemainCountDown = 0x00;
 }
 
+void ClearAbnormalStatus_GB(byte gun_index)
+{
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_LOS_CC1 = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_CONNECTOR_LOCK_FAIL = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_BATTERY_INCOMPATIBLE = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_BMS_BROAA_TIMEOUT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_CSU_PRECHARGE_TIMEOUT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_BMS_PRESENT_VOLTAGE_FAULT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_BMS_VOLTAGE_OVER_RANGE = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_BSM_CHARGE_ALLOW_00_10MIN_COUUNTDONE = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_WAIT_GROUNDFAULT_TIMEOUT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_ADC_MORE_THAN_10V = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_ADC_MORE_THAN_60V = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_CHARGER_GET_NORMAL_STOP_CMD = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_CHARGER_GET_EMERGENCY_STOP_CMD = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_ISOLATION_RESULT_FAIL = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_MOTHER_BOARD_MISS_LINK = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_OUTPUT_VOLTAGE_MORE_THAN_LIMIT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_REQ_CURRENT_MORE_THAN_LIMIT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_OUTPUT_VOLTAGE_MORE_THAN_10_PERCENT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_OUTPUT_VOLTAGE_DIFF_BCS_5_PERCENT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_STOP_ADC_MORE_THAN_10V = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_CEM_BHM_TIMEOUT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_CEM_BRM_TIMEOUT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_CEM_BCP_TIMEOUT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_CEM_BRO_TIMEOUT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_CEM_BCL_TIMEOUT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_CEM_BCS_TIMEOUT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_CEM_BSM_TIMEOUT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_CEM_BST_TIMEOUT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_CEM_BSD_TIMEOUT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_CEM_BEM_OTHER_TIMEOUT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BEM_CRM_TIMEOUT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BEM_CRMAA_TIMEOUT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BEM_CTS_CML_TIMEOUT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BEM_CRO_TIMEOUT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BEM_CCS_TIMEOUT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BEM_CST_TIMEOUT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BEM_CSD_TIMEOUT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BEM_BEM_OTHER_TIMEOUT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_SOC_GOAL = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_TOTAL_VOLTAGE_GOAL = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_CELL_VOLTAGE_GOAL = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_GET_CST = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_ISOLATION = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_OUTPUT_CONNECTOR_OTP = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_COMPONENT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_CHARGE_CONNECTOR = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_OTP = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_OTHER = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_HIGH_V = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_CC2 = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_CURRENT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_VOLTAGE = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GET_BST_NO_REASON = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BSM_CELL_OVER_VOLTAGE = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BSM_CELL_UNDER_VOLTAGE = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BSM_OVER_SOC = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BSM_UNDER_SOC = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BSM_CURRENT = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BSM_TEMPERATURE = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BSM_ISOLATE = 0x00;
+    ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BSM_OUTPUT_CONNECTOR = 0x00;
+}
+
 void ClearAbnormalStatus_CCS(byte gun_index)
 {
     ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsRESTemperatureInhibit = 0x00;
@@ -737,6 +825,68 @@ void AbnormalStopAnalysis(byte gun_index, byte *errCode)
     if (strcmp(string, "023887") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsISO2_Msg_Decode_Error = 0x01;
     if (strcmp(string, "023888") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsISO2_Msg_Encode_Error = 0x01;
     if (strcmp(string, "023889") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.CcsCpStatus_Error = 0x01;
+
+    if (strcmp(string, "023900") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_LOS_CC1 = 0x01;
+    if (strcmp(string, "023901") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_CONNECTOR_LOCK_FAIL = 0x01;
+    if (strcmp(string, "023902") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_BATTERY_INCOMPATIBLE = 0x01;
+    if (strcmp(string, "023903") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_BMS_BROAA_TIMEOUT = 0x01;
+    if (strcmp(string, "023904") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_CSU_PRECHARGE_TIMEOUT = 0x01;
+    if (strcmp(string, "023905") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_BMS_PRESENT_VOLTAGE_FAULT = 0x01;
+    if (strcmp(string, "023906") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_BMS_VOLTAGE_OVER_RANGE = 0x01;
+    if (strcmp(string, "023907") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_BSM_CHARGE_ALLOW_00_10MIN_COUUNTDONE = 0x01;
+    if (strcmp(string, "023908") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_WAIT_GROUNDFAULT_TIMEOUT = 0x01;
+    if (strcmp(string, "023909") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_ADC_MORE_THAN_10V = 0x01;
+    if (strcmp(string, "023910") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_ADC_MORE_THAN_60V = 0x01;
+    if (strcmp(string, "023911") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_CHARGER_GET_NORMAL_STOP_CMD = 0x01;
+    if (strcmp(string, "023912") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_CHARGER_GET_EMERGENCY_STOP_CMD = 0x01;
+    if (strcmp(string, "023913") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_ISOLATION_RESULT_FAIL = 0x01;
+    if (strcmp(string, "023914") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_MOTHER_BOARD_MISS_LINK = 0x01;
+    if (strcmp(string, "023915") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_OUTPUT_VOLTAGE_MORE_THAN_LIMIT = 0x01;
+    if (strcmp(string, "023916") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_REQ_CURRENT_MORE_THAN_LIMIT = 0x01;
+    if (strcmp(string, "023917") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_OUTPUT_VOLTAGE_MORE_THAN_10_PERCENT = 0x01;
+    if (strcmp(string, "023918") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_OUTPUT_VOLTAGE_DIFF_BCS_5_PERCENT = 0x01;
+    if (strcmp(string, "023919") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GBT_STOP_ADC_MORE_THAN_10V = 0x01;
+    if (strcmp(string, "023930") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_CEM_BHM_TIMEOUT = 0x01;
+    if (strcmp(string, "023931") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_CEM_BRM_TIMEOUT = 0x01;
+    if (strcmp(string, "023932") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_CEM_BCP_TIMEOUT = 0x01;
+    if (strcmp(string, "023933") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_CEM_BRO_TIMEOUT = 0x01;
+    if (strcmp(string, "023934") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_CEM_BCL_TIMEOUT = 0x01;
+    if (strcmp(string, "023935") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_CEM_BCS_TIMEOUT = 0x01;
+    if (strcmp(string, "023936") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_CEM_BSM_TIMEOUT = 0x01;
+    if (strcmp(string, "023937") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_CEM_BST_TIMEOUT = 0x01;
+    if (strcmp(string, "023938") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_CEM_BSD_TIMEOUT = 0x01;
+    if (strcmp(string, "023939") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_CEM_BEM_OTHER_TIMEOUT = 0x01;
+    if (strcmp(string, "023940") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BEM_CRM_TIMEOUT = 0x01;
+    if (strcmp(string, "023941") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BEM_CRMAA_TIMEOUT = 0x01;
+    if (strcmp(string, "023942") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BEM_CTS_CML_TIMEOUT = 0x01;
+    if (strcmp(string, "023943") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BEM_CRO_TIMEOUT = 0x01;
+    if (strcmp(string, "023944") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BEM_CCS_TIMEOUT = 0x01;
+    if (strcmp(string, "023945") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BEM_CST_TIMEOUT = 0x01;
+    if (strcmp(string, "023946") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BEM_CSD_TIMEOUT = 0x01;
+    if (strcmp(string, "023947") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BEM_BEM_OTHER_TIMEOUT = 0x01;
+    if (strcmp(string, "023950") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_SOC_GOAL = 0x01;
+    if (strcmp(string, "023951") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_TOTAL_VOLTAGE_GOAL = 0x01;
+    if (strcmp(string, "023952") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_CELL_VOLTAGE_GOAL = 0x01;
+    if (strcmp(string, "023953") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_GET_CST = 0x01;
+    if (strcmp(string, "023954") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_ISOLATION = 0x01;
+    if (strcmp(string, "023955") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_OUTPUT_CONNECTOR_OTP = 0x01;
+    if (strcmp(string, "023956") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_COMPONENT = 0x01;
+    if (strcmp(string, "023957") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_CHARGE_CONNECTOR = 0x01;
+    if (strcmp(string, "023958") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_OTP = 0x01;
+    if (strcmp(string, "023959") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_OTHER = 0x01;
+    if (strcmp(string, "023960") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_HIGH_V = 0x01;
+    if (strcmp(string, "023961") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_CC2 = 0x01;
+    if (strcmp(string, "023962") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_CURRENT = 0x01;
+    if (strcmp(string, "023963") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BST_VOLTAGE = 0x01;
+    if (strcmp(string, "023964") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_GET_BST_NO_REASON = 0x01;
+    if (strcmp(string, "023970") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BSM_CELL_OVER_VOLTAGE = 0x01;
+    if (strcmp(string, "023971") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BSM_CELL_UNDER_VOLTAGE = 0x01;
+    if (strcmp(string, "023972") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BSM_OVER_SOC = 0x01;
+    if (strcmp(string, "023973") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BSM_UNDER_SOC = 0x01;
+    if (strcmp(string, "023974") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BSM_CURRENT = 0x01;
+    if (strcmp(string, "023975") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BSM_TEMPERATURE = 0x01;
+    if (strcmp(string, "023976") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BSM_ISOLATE = 0x01;
+    if (strcmp(string, "023977") == 0) ShmStatusCodeData->InfoCode.InfoEvents.bits.ERROR_CODE_BSM_OUTPUT_CONNECTOR = 0x01;
 }
 
 void CANReceiver()
@@ -755,7 +905,7 @@ void CANReceiver()
         struct timeval _cmd_ack_timeout[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 
         bool isPass = false;
-        gun_count = GUN_COUNT;
+        gun_count = ShmSysConfigAndInfo->SysConfig.TotalConnectorCount;
 
         while(!isPass)
         {
@@ -842,6 +992,12 @@ void CANReceiver()
                             ShmCHAdeMOData->evse[_chargingData[targetGun]->type_index].SelfTest_Comp = PASS;
                             PRINTF_FUNC("chademo ver. : %s\n", ShmCHAdeMOData->evse[_chargingData[targetGun]->type_index].version);
                         }
+                        else if (_chargingData[targetGun]->Type == _Type_GB)
+                        {
+                            memcpy(ShmGBTData->evse[_chargingData[targetGun]->type_index].version, frame.data, ARRAY_SIZE(frame.data));
+                            ShmGBTData->evse[_chargingData[targetGun]->type_index].SelfTest_Comp = PASS;
+                            PRINTF_FUNC("gbt ver. : %s\n", ShmGBTData->evse[_chargingData[targetGun]->type_index].version);
+                        }
                         else if (_chargingData[targetGun]->Type == _Type_CCS_2)
                         {
                             if (ShmCcsData->CommProtocol == 0x01)
@@ -877,6 +1033,18 @@ void CANReceiver()
                             ShmCHAdeMOData->ev[_chargingData[targetGun]->type_index].TargetBatteryVoltage = _chargingData[targetGun]->EvBatterytargetVoltage;
                             ShmCHAdeMOData->ev[_chargingData[targetGun]->type_index].ChargingCurrentRequest = _chargingData[targetGun]->EvBatterytargetCurrent;
                         }
+                        else if (_chargingData[targetGun]->Type == _Type_GB)
+                        {
+                            if (ShmGBTData->ev[_chargingData[targetGun]->type_index].EvDetection != frame.data[0])
+                            {
+                                ShmGBTData->ev[_chargingData[targetGun]->type_index].PresentMsgFlowStatus = frame.data[0];
+                            }
+
+                            ShmGBTData->ev[_chargingData[targetGun]->type_index].EvDetection = frame.data[0];
+                            ShmGBTData->ev[_chargingData[targetGun]->type_index].SOC = _chargingData[targetGun]->EvBatterySoc;
+                            ShmGBTData->ev[_chargingData[targetGun]->type_index].TargetBatteryVoltage = _chargingData[targetGun]->EvBatterytargetVoltage;
+                            ShmGBTData->ev[_chargingData[targetGun]->type_index].ChargingCurrentRequest = _chargingData[targetGun]->EvBatterytargetCurrent;
+                        }
                         else if (_chargingData[targetGun]->Type == _Type_CCS_2)
                         {
                             if(ShmCcsData->CommProtocol == 0x01)
@@ -907,6 +1075,11 @@ void CANReceiver()
                             //PRINTF_FUNC("TotalBatteryCapacity = %d \n", ShmCHAdeMOData->ev[_chargingData[target]->type_index].TotalBatteryCapacity);
                             //PRINTF_FUNC("MaxiBatteryVoltage = %d \n", ShmCHAdeMOData->ev[_chargingData[target]->type_index].MaxiBatteryVoltage);
                         }
+                        else if (_chargingData[targetGun]->Type == _Type_GB)
+                        {
+                            ShmGBTData->ev[_chargingData[targetGun]->type_index].TotalBatteryCapacity = ((short) frame.data[2] << 8) + (short) frame.data[1];
+                            ShmGBTData->ev[_chargingData[targetGun]->type_index].MaxiBatteryVoltage = _chargingData[targetGun]->EvBatteryMaxVoltage;
+                        }
                         else if (_chargingData[targetGun]->Type == _Type_CCS_2)
                         {
 
@@ -923,6 +1096,14 @@ void CANReceiver()
                             _chargingData[targetGun]->PilotVoltage = (float)(-120 + frame.data[3]) / 10;
                             ShmCHAdeMOData->evse[_chargingData[targetGun]->type_index].EvboardStatus = frame.data[7];
                         }
+                        else if (_chargingData[targetGun]->Type == _Type_GB)
+                        {
+                            _chargingData[targetGun]->GunLocked = frame.data[0];
+                            ShmGBTData->evse[_chargingData[targetGun]->type_index].ConnectorTemperatureP = frame.data[1];
+                            ShmGBTData->evse[_chargingData[targetGun]->type_index].ConnectorTemperatureN = frame.data[2];
+                            _chargingData[targetGun]->PilotVoltage = (float)(-120 + frame.data[3]) / 10;
+                            ShmGBTData->evse[_chargingData[targetGun]->type_index].EvboardStatus = frame.data[7];
+                        }
                         else if (_chargingData[targetGun]->Type == _Type_CCS_2)
                         {
                             if (ShmCcsData->CommProtocol == 0x01)
@@ -1025,7 +1206,16 @@ void SetPresentChargingOutputCap(struct ChargingInfoData *chargingData_1, struct
     GetMaxVolAndCurMethod(chargingData_2->Index, &vol, &cur2);
     GetMaxPowerMethod(&pow2);
 
-    PRINTF_FUNC("To EV Power_1 = %f, Cur_1 = %f, Power_2 = %f, Cur_2 = %f \n", pow1, cur1, pow2, cur2);
+    if (_pow_1 != pow1 ||
+        _cur_1 != cur1 ||
+        _pow_2 != pow2 ||
+        _cur_2 != cur2)
+    {
+        PRINTF_FUNC("To EV Power_1 = %f, Cur_1 = %f, Power_2 = %f, Cur_2 = %f \n",
+                pow1, cur1, pow2, cur2);
+        _pow_1 = pow1; _cur_1 = cur1; _pow_2 = pow2; _cur_2 = cur2;
+    }
+
     SetPresentOutputCapacity(pow1, cur1, pow2, cur2);
 }
 
@@ -1125,6 +1315,20 @@ byte GetStopChargingReasonByEvse(byte gunIndex, byte *reason)
             result = YES;
         }
     }
+    else if (_chargingData[gunIndex]->Type == _Type_GB)
+    {
+        if (ShmStatusCodeData->FaultCode.FaultEvents.bits.ChademoOutputRelayDrivingFault == YES)
+        {
+            // 012290
+            *(reason + 5) = 0;
+            *(reason + 4) = 1;
+            *(reason + 3) = 2;
+            *(reason + 2) = 2;
+            *(reason + 1) = 9;
+            *(reason + 0) = 0;
+            result = YES;
+        }
+    }
     else if (_chargingData[gunIndex]->Type == _Type_CCS_2)
     {
         if (ShmStatusCodeData->FaultCode.FaultEvents.bits.CcsOutputRelayDrivingFault == YES)
@@ -1169,7 +1373,7 @@ int main(int argc, char *argv[])
         return 0;
     }
 
-    gun_count = GUN_COUNT;
+    gun_count = ShmSysConfigAndInfo->SysConfig.TotalConnectorCount;
     Initialization();
     CanFd = InitCanBus();
     CANReceiver();
@@ -1188,7 +1392,12 @@ int main(int argc, char *argv[])
                 {
                     SyncRtcInfo(_index, _chargingData[_index]->Evboard_id, (int)rtc);
                     GetFirmwareVersion(_index, _chargingData[_index]->Evboard_id);
-                    GetHardwareVersion(_index, _chargingData[_index]->Evboard_id);
+                }
+                else if (_chargingData[_index]->Type == _Type_GB &&
+                        ShmGBTData->evse[_chargingData[_index]->type_index].SelfTest_Comp != PASS)
+                {
+                    SyncRtcInfo(_index, _chargingData[_index]->Evboard_id, (int)rtc);
+                    GetFirmwareVersion(_index, _chargingData[_index]->Evboard_id);
                 }
                 else if (_chargingData[_index]->Type == _Type_CCS_2)
                 {
@@ -1197,13 +1406,16 @@ int main(int argc, char *argv[])
                     {
                         SyncRtcInfo(_index, _chargingData[_index]->Evboard_id, (int)rtc);
                         GetFirmwareVersion(_index, _chargingData[_index]->Evboard_id);
-                        GetHardwareVersion(_index, _chargingData[_index]->Evboard_id);
                     }
                 }
 
                 // 固定要取得的資訊 : 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]->Evboard_id);
+                GetMiscellaneousInfo(_index,
+                        _chargingData[_index]->RelayK1K2Status,
+                        _chargingData[_index]->PresentChargedEnergy,
+                        (_chargingData[_index]->PresentChargingVoltage * 10),
+                        _chargingData[_index]->Evboard_id);
             }
 
             switch (_chargingData[_index]->SystemStatus)
@@ -1220,6 +1432,10 @@ int main(int argc, char *argv[])
                     {
                         ClearAbnormalStatus_Chademo(_index);
                     }
+                    else if (_chargingData[_index]->Type == _Type_GB)
+                    {
+                        ClearAbnormalStatus_GB(_index);
+                    }
                     else if (_chargingData[_index]->Type == _Type_CCS_2)
                     {
                         ClearAbnormalStatus_CCS(_index);
@@ -1266,7 +1482,8 @@ int main(int argc, char *argv[])
 
                         GetMaxVolAndCurMethod(_index, &maxVol, &maxCur);
 
-                        PRINTF_FUNC("To EV_%d Max_Vol = %f, Cap_Cur = %f, Cap_Pow = %f \n", _index, maxVol, maxCur, _chargingData[_index]->AvailableChargingPower);
+                        PRINTF_FUNC("To EV_%d Max_Vol = %f, Cap_Cur = %f, Cap_Pow = %f \n",
+                                _index, maxVol, maxCur, _chargingData[_index]->AvailableChargingPower);
                         SetChargingPermission(_index, START,
                         _chargingData[_index]->AvailableChargingPower,
                                 maxCur,
@@ -1304,6 +1521,10 @@ int main(int argc, char *argv[])
                     if (priorityLow == 1)
                     {
                         // 拉 500 V 如果在一秒鐘內 GFD 都符合則 PASS
+//                      if (_chargingData[_index]->FireChargingVoltage >= 3500)
+//                          _chargingData[_index]->GroundFaultStatus = GFD_PASS;
+
+                        //PRINTF_FUNC("To EV_%d GFD = %d \n",   _index, _chargingData[_index]->GroundFaultStatus);
                         if(_chargingData[_index]->GroundFaultStatus != GFD_WAIT)
                         {
                             SetIsolationStatus(_index, _chargingData[_index]->GroundFaultStatus, _chargingData[_index]->Evboard_id);
@@ -1320,7 +1541,7 @@ int main(int argc, char *argv[])
                 case S_CHARGING:
                 {
                     // 計算 Power
-                    _chargingData[_index]->PresentChargingPower = ((float)((_chargingData[_index]->PresentChargingVoltage / 10) * (_chargingData[_index]->PresentChargingCurrent / 10)) / 1000);
+                    _chargingData[_index]->PresentChargingPower = ((float)((_chargingData[_index]->PresentChargingVoltage) * (_chargingData[_index]->PresentChargingCurrent)) / 1000);
 
                     if (chargingTime[_index] == 0)
                     {

+ 1 - 1
EVSE/Projects/DM30/Apps/Module_EvComm.h

@@ -50,7 +50,7 @@ void SetPresentOutputPower(short outputVol_b1, short outputCur_b1, short outputV
 void SetPresentOutputCapacity(short aOutputPw_b1, short aOutputCur_b1, short aOutputPw_b2, short aOutputCur_b2);
 void GetOutputReq(byte gun_index, byte toId);
 void GetEvBatteryInfo(byte gun_index, byte toId);
-void GetMiscellaneousInfo(byte gun_index, byte toId);
+void GetMiscellaneousInfo(byte gun_index, byte relayStatus, float power, float voltage, byte toId);
 void SetIsolationStatus(byte gun_index, byte result, byte toId);
 void SetEvsePrechargeInfo(byte gun_index, byte result, byte toId);
 // 發送電樁主動停止充電結果及原因

+ 189 - 96
EVSE/Projects/DM30/Apps/Module_InternalComm.c

@@ -76,16 +76,16 @@ struct PsuData                  *ShmPsuData;
 // 確認 Relay Welding 電壓
 #define RELAY_WELDING_DET                   300
 
-#define GUN_COUNT                           CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY
-
 byte gunCount;
 // 槍資訊
 struct ChargingInfoData *_chargingData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
-byte gfdChkFailCount[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_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 FindChargingInfoData(byte target, struct ChargingInfoData **chargingData);
 
 int Uart5Fd;
@@ -176,7 +176,7 @@ void PRINTF_FUNC(char *string, ...)
     vsnprintf(buffer, sizeof(buffer), string, args);
     va_end(args);
 
-    if (DEBUG)
+    if (ShmSysConfigAndInfo->SysConfig.SwitchDebugFlag == YES)
         printf("%s \n", buffer);
     else
         DEBUG_INFO("%s \n", buffer);
@@ -423,22 +423,14 @@ void GetPersentOutputVol()
                 _chargingData[index]->FireChargingVoltage = ShmRelayModuleData->Gun2RelayOutputVolt;
             }
 
-            unsigned short Ovp = 0;
-            unsigned short Ocp = 0;
+            //unsigned short Ovp = 0;
+            //unsigned short Ocp = 0;
             //Ovp = MIN [VOUT_MAX_VOLTAGE, EV_BATTERY_VOLTAGE]  // 最大輸出電壓與電池電壓最大值
             //Ocp = MIN [IOUT_MAX_CURRENT, EV_CURRENT_REQ]      // 最大輸出電流與需求電流最小值
             if (_chargingData[index]->Type == _Type_Chademo)
             {
-                Ovp = MaxValue(_chargingData[index]->MaximumChargingVoltage, _chargingData[index]->EvBatteryMaxVoltage);
-                Ocp = MaxValue(_chargingData[index]->PresentChargingCurrent, ShmCHAdeMOData->ev[_chargingData[index]->type_index].ChargingCurrentRequest);
-                if (_chargingData[index]->PresentChargingVoltage >= Ovp)
-                {
-                    //ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemChademoOutputOVP = 0x01;
-                }
-                if (_chargingData[index]->PresentChargingCurrent >= Ocp)
-                {
-                    //ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemChademoOutputOCP = 0x01;
-                }
+                //Ovp = MaxValue(_chargingData[index]->MaximumChargingVoltage, _chargingData[index]->EvBatteryMaxVoltage);
+                //Ocp = MaxValue(_chargingData[index]->PresentChargingCurrent, ShmCHAdeMOData->ev[_chargingData[index]->type_index].ChargingCurrentRequest);
             }
             else if (_chargingData[index]->Type == _Type_CCS_2)
             {
@@ -548,10 +540,8 @@ void GetGfdAdc()
         {
             if (_chargingData[i]->Type == 9)
             {
-                if (_chargingData[i]->PresentChargingVoltage >= 1500)
-                {
+                if (_chargingData[i]->PresentChargingVoltage >= VOUT_MIN_VOLTAGE)
                     _chargingData[i]->GroundFaultStatus = GFD_PASS;
-                }
                 continue;
             }
 
@@ -560,16 +550,14 @@ void GetGfdAdc()
                 _chargingData[i]->GroundFaultStatus = gfd_adc.result_conn1;
                 if (_chargingData[i]->GroundFaultStatus == GFD_FAIL)
                 {
-                    DEBUG_ERROR("GFD Fail. index = %d, R = %d, Vol = %d \n",
-                            i, gfd_adc.Resister_conn1, gfd_adc.voltage_conn1);
-                    PRINTF_FUNC("GFD Fail. index = %d, R = %d, Vol = %d \n",
-                            i, gfd_adc.Resister_conn1, gfd_adc.voltage_conn1);
+                    PRINTF_FUNC("GFD Fail. index = %d, Step = %d, R = %d, Vol = %d \n",
+                            i, gfd_adc.rb_step_1, gfd_adc.Resister_conn1, gfd_adc.voltage_conn1);
                 }
                 else if (_chargingData[i]->GroundFaultStatus == GFD_PASS ||
                          _chargingData[i]->GroundFaultStatus == GFD_WARNING)
                 {
-                    PRINTF_FUNC("GFD Result. index = %d, Result = %d, R= %d, Vol = %d \n",
-                            i, _chargingData[i]->GroundFaultStatus, gfd_adc.Resister_conn1, gfd_adc.voltage_conn1);
+//                  PRINTF_FUNC("GFD Result. index = %d, Result = %d, R = %d, Vol = %d \n",
+//                      i, _chargingData[i]->GroundFaultStatus, gfd_adc.Resister_conn1, gfd_adc.voltage_conn1);
                 }
             }
             else if (i == 1)
@@ -577,28 +565,16 @@ void GetGfdAdc()
                 _chargingData[i]->GroundFaultStatus = gfd_adc.result_conn2;
                 if (_chargingData[i]->GroundFaultStatus == GFD_FAIL)
                 {
-                    DEBUG_ERROR("GFD Fail. index = %d, R = %d, Vol = %d \n",
-                            i, gfd_adc.Resister_conn2, gfd_adc.voltage_conn2);
-                    PRINTF_FUNC("GFD Fail. index = %d, R = %d, Vol = %d \n",
-                            i, gfd_adc.Resister_conn2, gfd_adc.voltage_conn2);
+                    PRINTF_FUNC("GFD Fail. index = %d, Step = %d, R = %d, Vol = %d \n",
+                            i, gfd_adc.rb_step_2, gfd_adc.Resister_conn2, gfd_adc.voltage_conn2);
                 }
                 else if (_chargingData[i]->GroundFaultStatus == GFD_PASS ||
                          _chargingData[i]->GroundFaultStatus == GFD_WARNING)
                 {
-                    PRINTF_FUNC("GFD Result. index = %d, Result = %d, R= %d, Vol = %d \n",
-                            i, _chargingData[i]->GroundFaultStatus, gfd_adc.Resister_conn2, gfd_adc.voltage_conn2);
+//                  PRINTF_FUNC("GFD Result. index = %d, Result = %d, R = %d, Vol = %d \n",
+//                      i, _chargingData[i]->GroundFaultStatus, gfd_adc.Resister_conn2, gfd_adc.voltage_conn2);
                 }
-
-            }
         }
-
-        //if (gfd_adc.result_conn1 != 0)
-        {
-//          PRINTF_FUNC("******************Resister_conn1 = %d, voltage_conn1 = %d, result_conn1 = %d, step = %d \n",
-//              gfd_adc.Resister_conn1,
-//              gfd_adc.voltage_conn1,
-//              gfd_adc.result_conn1,
-//              gfd_adc.rb_step_1);
         }
     }
 }
@@ -708,6 +684,8 @@ void SetFanModuleSpeed()
             ShmFanModuleData->PresentFan3Speed != ShmFanModuleData->SetFan3Speed ||
             ShmFanModuleData->PresentFan4Speed != ShmFanModuleData->SetFan4Speed)
     {
+        //printf("ShmFanModuleData->SetFan1Speed = %d \n", ShmFanModuleData->SetFan1Speed);
+
         FanSpeed _fanSpeed;
 
         unsigned short speed = ShmFanModuleData->PresentFan1Speed + fanSpeedSmoothValue;
@@ -810,7 +788,10 @@ void SetK1K2RelayStatus(byte index)
             }
         }
     }
-    else if ((_chargingData[index]->SystemStatus >= S_PREPARING_FOR_EVSE && _chargingData[index]->SystemStatus <= S_CHARGING))
+    else if ((_chargingData[index]->SystemStatus >= S_PREPARING_FOR_EVSE &&
+            _chargingData[index]->SystemStatus <= S_CHARGING))
+    {
+        if (_chargingData[index]->RelayWeldingCheck == YES)
     {
         if (_chargingData[index]->Evboard_id == 0x01)
         {
@@ -827,7 +808,8 @@ void SetK1K2RelayStatus(byte index)
                 outputRelay.relay_event.bits.Gun2_P = YES;
         }
     }
-    else if (_chargingData[index]->SystemStatus == S_COMPLETE)
+    }
+    else if ((_chargingData[index]->SystemStatus >= S_TERMINATING && _chargingData[index]->SystemStatus <= S_COMPLETE))
     {
         if (_chargingData[index]->PresentChargingCurrent <= SEFETY_SWITCH_RELAY_CUR)
         {
@@ -905,6 +887,68 @@ void CheckPhaseLossStatus(byte index)
     }
 }
 
+void SetParalleRelayStatus()
+{
+    if (gunCount >= 2 && ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == NO)
+    {
+        if (_chargingData[0]->SystemStatus == S_BOOTING || _chargingData[1]->SystemStatus == S_BOOTING ||
+                (_chargingData[0]->SystemStatus == S_IDLE && _chargingData[1]->SystemStatus == S_IDLE))
+        {
+            // 初始化~ 不搭橋接
+            if (regRelay.relay_event.bits.Gun1_Parallel_P == YES)
+                outputRelay.relay_event.bits.Gun1_Parallel_P = NO;
+            else if (regRelay.relay_event.bits.Gun1_Parallel_N == YES)
+                outputRelay.relay_event.bits.Gun1_Parallel_N = NO;
+        }
+        else
+        {
+            if (_chargingData[0]->IsReadyToCharging == YES ||
+                    _chargingData[1]->IsReadyToCharging == YES)
+            {
+                // ************需考慮在切換中 - 切開 relay 與搭回 relay 的時機點************
+                if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
+                {
+                    if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag < _REASSIGNED_RELAY_M_TO_A)
+                    {
+                        // 最大充 - 搭上橋接
+                        if (regRelay.relay_event.bits.Gun1_Parallel_N == NO)
+                            outputRelay.relay_event.bits.Gun1_Parallel_N = YES;
+                        else if (regRelay.relay_event.bits.Gun1_Parallel_P == NO)
+                            outputRelay.relay_event.bits.Gun1_Parallel_P = YES;
+                    }
+                    else
+                    {
+                        // 平均充 - 不搭
+                        if (regRelay.relay_event.bits.Gun1_Parallel_P == YES)
+                            outputRelay.relay_event.bits.Gun1_Parallel_P = NO;
+                        else if (regRelay.relay_event.bits.Gun1_Parallel_N == YES)
+                            outputRelay.relay_event.bits.Gun1_Parallel_N = NO;
+                    }
+                }
+                else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER)
+                {
+                    if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag < _REASSIGNED_RELAY_A_TO_M)
+                    {
+                        // 平均充 - 不搭
+                        if (regRelay.relay_event.bits.Gun1_Parallel_P == YES)
+                            outputRelay.relay_event.bits.Gun1_Parallel_P = NO;
+                        else if (regRelay.relay_event.bits.Gun1_Parallel_N == YES)
+                            outputRelay.relay_event.bits.Gun1_Parallel_N = NO;
+                    }
+                    else
+                    {
+                        // 最大充 - 搭上橋接
+                        if (regRelay.relay_event.bits.Gun1_Parallel_N == NO)
+                            outputRelay.relay_event.bits.Gun1_Parallel_N = YES;
+                        else if (regRelay.relay_event.bits.Gun1_Parallel_P == NO)
+                            outputRelay.relay_event.bits.Gun1_Parallel_P = YES;
+                    }
+                }
+            }
+        }
+    }
+}
+
 //==========================================
 // Init all share memory
 //==========================================
@@ -1127,16 +1171,6 @@ bool IsNoneMatchRelayStatus()
 {
     bool result = false;
 
-//  PRINTF_FUNC("Real Relay, AC = %x, g1_p = %x, g1_n = %x, g2_p = %x, g2_n = %x, pre = %x, bri_p = %x, bri_n = %x \n",
-//          regRelay.relay_event.bits.AC_Contactor,
-//          regRelay.relay_event.bits.Gun1_P,
-//          regRelay.relay_event.bits.Gun1_N,
-//          regRelay.relay_event.bits.Gun2_P,
-//          regRelay.relay_event.bits.Gun2_N,
-//          regRelay.relay_event.bits.CCS_Precharge,
-//          regRelay.relay_event.bits.Gun1_Parallel_P,
-//          regRelay.relay_event.bits.Gun1_Parallel_N);
-
     if ((regRelay.relay_event.bits.AC_Contactor != outputRelay.relay_event.bits.AC_Contactor) ||
         (regRelay.relay_event.bits.CCS_Precharge != outputRelay.relay_event.bits.CCS_Precharge) ||
         (regRelay.relay_event.bits.Gun1_P != outputRelay.relay_event.bits.Gun1_P) ||
@@ -1146,6 +1180,23 @@ 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. \n");
+        if (regRelay.relay_event.bits.CCS_Precharge != outputRelay.relay_event.bits.CCS_Precharge)
+            PRINTF_FUNC("CCS Precharge Relay none match. \n");
+        if (regRelay.relay_event.bits.Gun1_P != outputRelay.relay_event.bits.Gun1_P)
+            PRINTF_FUNC("SMR1:D+ Relay none match. \n");
+        if (regRelay.relay_event.bits.Gun1_N != outputRelay.relay_event.bits.Gun1_N)
+            PRINTF_FUNC("SMR1:D- Relay none match. \n");
+        if (regRelay.relay_event.bits.Gun2_P != outputRelay.relay_event.bits.Gun2_P)
+            PRINTF_FUNC("SMR2:D+ Relay none match. \n");
+        if (regRelay.relay_event.bits.Gun2_N != outputRelay.relay_event.bits.Gun2_N)
+            PRINTF_FUNC("SMR2:D- Relay none match. \n");
+        if (regRelay.relay_event.bits.Gun1_Parallel_P != outputRelay.relay_event.bits.Gun1_Parallel_P)
+            PRINTF_FUNC("Parallel:D+ Relay none match. \n");
+        if (regRelay.relay_event.bits.Gun1_Parallel_N != outputRelay.relay_event.bits.Gun1_Parallel_N)
+            PRINTF_FUNC("Parallel:D- Relay none match. \n");
+
         result = true;
     }
 
@@ -1215,7 +1266,8 @@ void CableCheckDetected(byte index)
         if ((_chargingData[index]->SystemStatus >= S_PREPARING_FOR_EVSE && _chargingData[index]->SystemStatus <= S_CHARGING) ||
             (_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 &&
+                    _chargingData[index]->RelayWeldingCheck == YES)
             {
                 SetGfdConfig(index, GFD_CABLECHK);
             }
@@ -1226,6 +1278,9 @@ void CableCheckDetected(byte index)
             }
             else if (_chargingData[index]->SystemStatus <= S_CHARGING)
             {
+                if (_chargingData[index]->Type == _Type_GB)
+                    SetGfdConfig(index, GFD_IDLE);
+                else
                 SetGfdConfig(index, GFD_CHARGING);
             }
         }
@@ -1265,8 +1320,8 @@ void CheckOutputVolNoneMatchFire(byte index)
                     _chargingData[index]->Type == _Type_CCS_2 ||
                     _chargingData[index]->Type == _Type_GB))
     {
-        if ((_chargingData[index]->PresentChargingVoltage < _chargingData[index]->FireChargingVoltage - 300) ||
-                (_chargingData[index]->PresentChargingVoltage > _chargingData[index]->FireChargingVoltage + 300))
+        if (((_chargingData[index]->PresentChargingVoltage * 10) < _chargingData[index]->FireChargingVoltage - 300) ||
+                ((_chargingData[index]->PresentChargingVoltage * 10) > _chargingData[index]->FireChargingVoltage + 300))
         {
             if (!_isOutputNoneMatch[index])
             {
@@ -1290,6 +1345,39 @@ void CheckOutputVolNoneMatchFire(byte index)
     }
 }
 
+void CheckRelayWeldingStatus(byte index)
+{
+    if (!_isRelayWelding[index])
+    {
+        if (_chargingData[index]->PresentChargingVoltage >= VOUT_MIN_VOLTAGE)
+        {
+            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()
 {
     char temp = 0;
@@ -1302,6 +1390,8 @@ void GetPsuTempForFanSpeed()
         }
     }
 
+    if (ShmSysConfigAndInfo->SysConfig.SwitchDebugFlag == NO)
+    {
     if (ShmFanModuleData->TestFanSpeed == NORMAL_FAN_SPEED)
     {
         if (temp >= ENV_TEMP_MAX)
@@ -1314,6 +1404,7 @@ void GetPsuTempForFanSpeed()
     }
     else
         ShmFanModuleData->TestFanSpeed = NORMAL_FAN_SPEED;
+    }
 }
 
 int main(void)
@@ -1331,7 +1422,7 @@ int main(void)
         return 0;
     }
 
-    gunCount = GUN_COUNT;
+    gunCount = ShmSysConfigAndInfo->SysConfig.TotalConnectorCount;
     // Open Uart5 for RB
     Uart5Fd = InitComPort();
     Initialization();
@@ -1344,18 +1435,17 @@ int main(void)
     }
 
     outputRelay.relay_event.bits.AC_Contactor = 0x00;
-    //outputRelay.relay_event.bits.CCS_Precharge = 0x00;
-    //outputRelay.relay_event.bits.Gun1_Parallel_P = 0x01;
-    //outputRelay.relay_event.bits.Gun1_Parallel_N = 0x01;
-    //outputRelay.relay_event.bits.Gun1_P = 0x01;
-    //outputRelay.relay_event.bits.Gun1_N = 0x01;
-    //outputRelay.relay_event.bits.Gun2_N = 0x01;
-    //outputRelay.relay_event.bits.Gun2_P = 0x01;
+    outputRelay.relay_event.bits.CCS_Precharge = 0x00;
+    outputRelay.relay_event.bits.Gun1_Parallel_P = 0x00;
+    outputRelay.relay_event.bits.Gun1_Parallel_N = 0x00;
+    outputRelay.relay_event.bits.Gun1_P = 0x00;
+    outputRelay.relay_event.bits.Gun1_N = 0x00;
+    outputRelay.relay_event.bits.Gun2_N = 0x00;
+    outputRelay.relay_event.bits.Gun2_P = 0x00;
     if(Config_Relay_Output(Uart5Fd, Addr.Relay, &outputRelay) != PASS)
         PRINTF_FUNC("Config_Relay_Output fail \n");
 
-    bool printRelayStatus = false;
-    //return 0;
+    bool printRelayStatus = true;
     for(;;)
     {
         bool isCharging = false;
@@ -1386,7 +1476,7 @@ int main(void)
             GetPresentInputVol();
 
             // 讀取當前 relay 狀態
-            GetRelayOutputStatus();
+            //GetRelayOutputStatus();
 
             for (int i = 0; i < gunCount; i++)
             {
@@ -1403,7 +1493,10 @@ int main(void)
                     CheckPhaseLossStatus(i);
 
                 if (_chargingData[i]->SystemStatus == S_IDLE)
-                    gfdChkFailCount[i] = 0;
+                {
+                    _chargingData[i]->RelayWeldingCheck = NO;
+                    _isRelayWelding[i] = NO;
+                }
 
                 if (_chargingData[i]->SystemStatus == S_BOOTING ||
                     (_chargingData[i]->SystemStatus >= S_PREPARNING && _chargingData[i]->SystemStatus <= S_COMPLETE) ||
@@ -1413,22 +1506,27 @@ int main(void)
                     _chargingData[i]->IsReadyToCharging = YES;
                     isCharging = true;
 
+                    if (_chargingData[i]->SystemStatus >= S_PREPARING_FOR_EVSE &&
+                            _chargingData[i]->RelayWeldingCheck == NO)
+                        CheckRelayWeldingStatus(i);
+
                     if (_chargingData[i]->SystemStatus == S_CHARGING)
                     {
                         CheckOutputPowerOverCarReq(i);
                         CheckOutputVolNoneMatchFire(i);
                     }
                     else
-                    {
                         _isOutputNoneMatch[i] = NO;
                     }
-                }
                 else
                     _chargingData[i]->IsReadyToCharging = NO;
             }
             // Cable check (Get)
             GetGfdAdc();
 
+            // 橋接 relay
+            SetParalleRelayStatus();
+
             // 搭上 AC Contactor
             if (isCharging)
                 outputRelay.relay_event.bits.AC_Contactor = YES;
@@ -1456,29 +1554,19 @@ int main(void)
             }
 
             // 搭上/鬆開 Relay
-            // 放開 Relay 之前要先確認輸出的電壓電流是否已經降到某個值
             if(IsNoneMatchRelayStatus())
             {
-                if (!printRelayStatus)
-                {
-                    PRINTF_FUNC("Match Relay Target, AC = %x, g1_p = %x, g1_n = %x, g2_p = %x, g2_n = %x, pre = %x, bri_p = %x, bri_n = %x \n",
-                            outputRelay.relay_event.bits.AC_Contactor,
-                            outputRelay.relay_event.bits.Gun1_P,
-                            outputRelay.relay_event.bits.Gun1_N,
-                            outputRelay.relay_event.bits.Gun2_P,
-                            outputRelay.relay_event.bits.Gun2_N,
-                            outputRelay.relay_event.bits.CCS_Precharge,
-                            outputRelay.relay_event.bits.Gun1_Parallel_P,
-                            outputRelay.relay_event.bits.Gun1_Parallel_N);
-                }
-                printRelayStatus = false;
                 if (Config_Relay_Output(Uart5Fd, Addr.Relay, &outputRelay))
-                {}
-            }
-            else
             {
-                if (!printRelayStatus)
-                {
+                    regRelay.relay_event.bits.AC_Contactor = ShmSysConfigAndInfo->SysInfo.AcContactorStatus;
+                    regRelay.relay_event.bits.CCS_Precharge = outputRelay.relay_event.bits.CCS_Precharge;
+                    regRelay.relay_event.bits.Gun1_P = outputRelay.relay_event.bits.Gun1_P;
+                    regRelay.relay_event.bits.Gun1_N = outputRelay.relay_event.bits.Gun1_N;
+                    regRelay.relay_event.bits.Gun2_P = outputRelay.relay_event.bits.Gun2_P;
+                    regRelay.relay_event.bits.Gun2_N = outputRelay.relay_event.bits.Gun2_N;
+                    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;
+
                     PRINTF_FUNC("Match Relay, AC = %x, g1_p = %x, g1_n = %x, g2_p = %x, g2_n = %x, pre = %x, bri_p = %x, bri_n = %x \n",
                             regRelay.relay_event.bits.AC_Contactor,
                             regRelay.relay_event.bits.Gun1_P,
@@ -1500,10 +1588,6 @@ int main(void)
                 GetPsuTempForFanSpeed();
 
                 GetFanSpeed();
-                //              printf("ShmFanModuleData->PresentFan1Speed = %d \n", ShmFanModuleData->PresentFan1Speed);
-                //              printf("ShmFanModuleData->PresentFan2Speed = %d \n", ShmFanModuleData->PresentFan2Speed);
-                //              printf("ShmFanModuleData->PresentFan3Speed = %d \n", ShmFanModuleData->PresentFan3Speed);
-                //              printf("ShmFanModuleData->PresentFan4Speed = %d \n", ShmFanModuleData->PresentFan4Speed);
                 gettimeofday(&_priority_time, NULL);
                 if (isCharging)
                 {
@@ -1529,15 +1613,24 @@ int main(void)
                 else
                 {
                     if (ShmFanModuleData->PresentFan1Speed > MIN_FAN_SPEED ||
-                        ShmFanModuleData->PresentFan2Speed < MAX_FAN_SPEED ||
-                        ShmFanModuleData->PresentFan3Speed < MAX_FAN_SPEED ||
-                        ShmFanModuleData->PresentFan4Speed < MAX_FAN_SPEED)
+                        ShmFanModuleData->PresentFan2Speed > MIN_FAN_SPEED ||
+                        ShmFanModuleData->PresentFan3Speed > MIN_FAN_SPEED ||
+                        ShmFanModuleData->PresentFan4Speed > MIN_FAN_SPEED)
                     {
                         ShmFanModuleData->SetFan1Speed = MIN_FAN_SPEED;
                         ShmFanModuleData->SetFan2Speed = MIN_FAN_SPEED;
                         ShmFanModuleData->SetFan3Speed = MIN_FAN_SPEED;
                         ShmFanModuleData->SetFan4Speed = MIN_FAN_SPEED;
                     }
+
+                    // 停止時,如溫度還是很高,則需要維持該轉速直到溫度降低
+                    if (ShmFanModuleData->TestFanSpeed >= MAX_FAN_SPEED)
+                    {
+                        ShmFanModuleData->SetFan1Speed = ShmFanModuleData->TestFanSpeed;
+                        ShmFanModuleData->SetFan2Speed = ShmFanModuleData->TestFanSpeed;
+                        ShmFanModuleData->SetFan3Speed = ShmFanModuleData->TestFanSpeed;
+                        ShmFanModuleData->SetFan4Speed = ShmFanModuleData->TestFanSpeed;
+                    }
                 }
 
                 //PRINTF_FUNC("set fan = %d \n", ShmFanModuleData->SetFan1Speed);

+ 23 - 11
EVSE/Projects/DM30/Apps/Module_LcmControl.c

@@ -1,4 +1,4 @@
-#include "Module_LcmContro.h"
+#include "Module_LcmControl.h"
 
 void PRINTF_FUNC(char *string, ...);
 
@@ -57,7 +57,7 @@ void PRINTF_FUNC(char *string, ...)
     vsnprintf(buffer, sizeof(buffer), string, args);
     va_end(args);
 
-    if (DEBUG)
+    if (ShmSysConfigAndInfo->SysConfig.SwitchDebugFlag == YES)
         printf("%s \n", buffer);
     else
         DEBUG_INFO("%s \n", buffer);
@@ -728,6 +728,18 @@ void ProcessPageInfo()
                 switch(_chargingInfoData[i]->Type)
                 {
                     case _Type_Chademo:
+                    {
+                        if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == i)
+                        {
+                            ChangeDisplay2Value(__gun_type_index + (i * 2), _chademo_light);
+                        }
+                        else
+                        {
+                            ChangeDisplay2Value(__gun_type_index + (i * 2), _chademo_dark);
+                        }
+                    }
+                        break;
+                    case _Type_GB:
                     {
                         if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == i)
                         {
@@ -813,7 +825,7 @@ void ProcessPageInfo()
 
 void Initialization()
 {
-    strcpy((char *)ShmSysConfigAndInfo->SysInfo.LcmHwRev, moduleName);
+    //strcpy((char *)ShmSysConfigAndInfo->SysInfo.LcmHwRev, moduleName);
 
     bool isPass = false;
     byte count = 5;
@@ -855,20 +867,20 @@ int main(void)
     byte changeWarningPriority = 0;
     byte curWarningCount = 255;
     //ChangeBackLight(true);
-    _totalCount = GUN_COUNT;
+    _totalCount = ShmSysConfigAndInfo->SysConfig.TotalConnectorCount;
     Initialization();
 
 //  ChangeToOtherPage(_LCM_FIX);
 //  return 0;
+
     while(_port != -1)
     {
-//      if (strlen((char *)ShmSysConfigAndInfo->SysInfo.LcmHwRev) != 0 ||
-//              ShmSysConfigAndInfo->SysInfo.LcmHwRev[0] != '\0')
-//      {
-//          GetCurrentPage();
-//          sleep(1);
-//      }
-//      else
+        if (strcmp((char *)ShmSysConfigAndInfo->SysInfo.LcmHwRev, moduleName) != 0x00)
+        {
+            GetCurrentPage();
+            sleep(1);
+        }
+        else
         {
             //DemoFunction();
 

+ 0 - 2
EVSE/Projects/DM30/Apps/Module_LcmContro.h → EVSE/Projects/DM30/Apps/Module_LcmControl.h

@@ -51,8 +51,6 @@ struct FanModuleData            *ShmFanModuleData;
 #define CMD_BACKLIGHT           0x01
 #define CMD_REGISTER            0x03
 
-#define GUN_COUNT               CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY
-
 int _port;
 //char* pPortName = "/dev/ttyO2";
 char* pPortName = "/dev/ttyS3";

+ 39 - 7
EVSE/Projects/DM30/Apps/Module_PrimaryComm.c

@@ -54,6 +54,9 @@ Ver ver;
 Gpio_in gpio_in;
 Rtc rtc;
 
+struct timeval _flash_time;
+byte flash = NO;
+
 void PRINTF_FUNC(char *string, ...);
 
 int StoreLogMsg(const char *fmt, ...);
@@ -103,7 +106,7 @@ void PRINTF_FUNC(char *string, ...)
     vsnprintf(buffer, sizeof(buffer), string, args);
     va_end(args);
 
-    if (DEBUG)
+    if (ShmSysConfigAndInfo->SysConfig.SwitchDebugFlag == YES)
         printf("%s \n", buffer);
     else
         DEBUG_INFO("%s \n", buffer);
@@ -272,11 +275,11 @@ void GetInputGpioStatus()
     }
 }
 
-void SetOutputGpio()
+void SetOutputGpio(byte flash)
 {
     Gpio_out gpio;
-    gpio.Button_LED[0] = 0x01;
-    gpio.Button_LED[1] = 0x01;
+    gpio.Button_LED[0] = flash;
+    gpio.Button_LED[1] = flash;
 
     gpio.System_LED[0] = 0x00;
     gpio.System_LED[1] = 0x00;
@@ -287,7 +290,7 @@ void SetOutputGpio()
     gpio.AC_Breaker = 0x00;
 
     if (Config_Gpio_Output(Uart1Fd, Addr.IoExtend, &gpio) == PASS)
-        PRINTF_FUNC("SetOutputGpio sucessfully. \n");
+        PRINTF_FUNC("SetOutputGpio sucessfully. %d \n", flash);
     else
         PRINTF_FUNC("SetOutputGpio fail. \n");
 }
@@ -359,6 +362,14 @@ int InitComPort()
     return fd;
 }
 
+unsigned long GetTimeoutValue(struct timeval _sour_time)
+{
+    struct timeval _end_time;
+    gettimeofday(&_end_time, NULL);
+
+    return 1000000 * (_end_time.tv_sec - _sour_time.tv_sec) + _end_time.tv_usec - _sour_time.tv_usec;
+}
+
 int main(void)
 {
     if(InitShareMemory() == FAIL)
@@ -390,17 +401,38 @@ int main(void)
         return 0;
     }
 
-    SetOutputGpio();
     SetRtcData();
+    gettimeofday(&_flash_time, NULL);
     for(;;)
     {
+        if (strcmp((char *)ShmSysConfigAndInfo->SysInfo.LcmHwRev, " ") == 0x00)
+        {
+            if ((GetTimeoutValue(_flash_time) / 1000) > 1000)
+            {
+                if (flash == NO)
+                    flash = YES;
+                else
+                    flash = NO;
+                SetOutputGpio(flash);
+                gettimeofday(&_flash_time, NULL);
+            }
+        }
+        else
+        {
+            if (flash == NO)
+            {
+                flash = YES;
+                SetOutputGpio(flash);
+            }
+        }
+
         // 程序開始之前~ 必須先確定 FW 版本與硬體版本,確認後!!~ 該模組才算是真正的 Initial Comp.
         // 模組更新 FW 後,需重新做
         if(ShmPrimaryMcuData->SelfTest_Comp != PASS)
         {
             PRINTF_FUNC("(407) Get Fw and Hw Ver. \n");
             GetFwAndHwVersion();
-            usleep(1000000);
+            sleep(1);
             ShmPrimaryMcuData->SelfTest_Comp = PASS;
         }
         else

+ 417 - 37
EVSE/Projects/DM30/Apps/Module_PsuComm.c

@@ -77,7 +77,7 @@ void PRINTF_FUNC(char *string, ...)
     vsnprintf(buffer, sizeof(buffer), string, args);
     va_end(args);
 
-    if (DEBUG)
+    if (ShmSysConfigAndInfo->SysConfig.SwitchDebugFlag == YES)
         printf("%s \n", buffer);
     else
         DEBUG_INFO("%s \n", buffer);
@@ -349,20 +349,44 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
     {
         _power += ShmPsuData->PsuGroup[index].GroupAvailablePower;
         _current += ShmPsuData->PsuGroup[index].GroupAvailableCurrent;
-        _ratingcurrent += chargingInfo[address]->DeratingChargingCurrent;
+        _ratingcurrent += chargingInfo[index]->DeratingChargingCurrent;
     }
 
     ShmPsuData->SystemAvailableCurrent = _current;
     ShmPsuData->SystemAvailablePower = _power;
 
+    if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER ||
+            (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_GET_NEW_CAP &&
+             ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A))
+    {
+        int halfPow = ShmPsuData->PsuGroup[group].GroupAvailablePower;
+        int halfCur = ShmPsuData->PsuGroup[group].GroupAvailableCurrent;
+        int ratingCur = chargingInfo[group]->DeratingChargingCurrent;
+
+        GetMaxPowerAndCur(_MAIN_CHARGING_MODE_AVER, ratingCur, &halfPow, &halfCur);
+
+//      if ((ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_GET_NEW_CAP &&
+//               ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A))
+//      {
+//          chargingInfo[group]->AvailableChargingCurrent = DERATING_RANGE;
+//          chargingInfo[group]->AvailableChargingPower = ShmPsuData->PsuGroup[group].GroupAvailablePower;
+//      }
+//      else
+        {
+            // 以下狀況 -> 槍資訊中的最大輸出能力,為該群的輸出能力
+            // 1. 如不是最大充
+            // 2. 智能切換成均充過程
+            chargingInfo[group]->AvailableChargingCurrent = halfCur;
+            chargingInfo[group]->AvailableChargingPower = halfPow;
+        }
+    }
+    else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
+    {
     GetMaxPowerAndCur(_MAIN_CHARGING_MODE_MAX, _ratingcurrent, &_power, &_current);
 
-    // 雙槍單模時,同步雙槍資訊
     if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES)
     {
-        byte _count = CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY;
-
-        for (byte count = 0; count < _count; count++)
+            for (byte count = 0; count < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; count++)
         {
             chargingInfo[count]->MaximumChargingVoltage = maxVol;
             chargingInfo[count]->AvailableChargingCurrent = _current;
@@ -371,9 +395,11 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
     }
     else
     {
+            // 如果是最大充,該槍資訊中的輸出能力為各群輸出能力的和
         chargingInfo[group]->AvailableChargingCurrent = _current;
         chargingInfo[group]->AvailableChargingPower = _power;
     }
+    }
 }
 
 void GetFwCallback(byte address, short dcSwVer, short pfcSwVer, short hwVer)
@@ -430,32 +456,45 @@ void GetPresentOutputCallback(byte group, unsigned short outVol, unsigned short
         // 黑白機
         if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES)
         {
-            byte _count = CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY;
-
-            for (byte count = 0; count < _count; count++)
+            for (byte count = 0; count < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; count++)
             {
+                float _vol_buf = outputVol;
+                float _cur_buf = outputCur;
+
                 // EVSE - 電壓
-                chargingInfo[count]->PresentChargingVoltage = outputVol;
+                _vol_buf /= 10;
+                chargingInfo[count]->PresentChargingVoltage = _vol_buf;
                 // EVSE - 電流
-                chargingInfo[count]->PresentChargingCurrent = outputCur;
+                _cur_buf /= 10;
+                chargingInfo[count]->PresentChargingCurrent = _cur_buf;
             }
         }
 
-        if ((chargingInfo[group]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[group]->SystemStatus <= S_CHARGING) ||
+        if ((chargingInfo[group]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[group]->SystemStatus <= S_COMPLETE) ||
             (chargingInfo[group]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[group]->SystemStatus <= S_CCS_PRECHARGE_ST1))
         {
+            float _vol_buf = outputVol;
+            float _cur_buf = outputCur;
+
             // EVSE - 電壓
-            chargingInfo[group]->PresentChargingVoltage = outputVol;
+            _vol_buf /= 10;
+            chargingInfo[group]->PresentChargingVoltage = _vol_buf;
             // EVSE - 電流
-            chargingInfo[group]->PresentChargingCurrent = outputCur;
+            _cur_buf /= 10;
+            chargingInfo[group]->PresentChargingCurrent = _cur_buf;
         }
     }
     else
     {
+        float _vol_buf = ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage;
+        float _cur_buf = ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent;
+
         // EVSE - 電壓
-        chargingInfo[group]->PresentChargingVoltage = ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage;
+        _vol_buf /= 10;
+        chargingInfo[group]->PresentChargingVoltage = _vol_buf;
         // EVSE - 電流
-        chargingInfo[group]->PresentChargingCurrent = ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent;
+        _cur_buf /= 10;
+        chargingInfo[group]->PresentChargingCurrent = _cur_buf;
     }
 
 //  PRINTF_FUNC("Gun_%d, PresentChargingCurrent = %f \n", group,
@@ -480,31 +519,49 @@ void GetFanSpeedCallback(byte address, unsigned int fanSpeed)
 
 void GetIavailableCallback(byte address, unsigned short Iavail, unsigned short Vext)
 {
-    //PRINTF_FUNC("GetIavailableCallback address_%d, Vext = %d, Iavail = %d \n", address, Vext, Iavail);
+    if (IsOverModuleCount(address))
+            return;
+
+    byte group = FindTargetGroup(address);
+
+    if (group == 1)
+        address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity;
+
+    //PRINTF_FUNC("group = %d, address_%d, Iavail = %d \n", group, address, Iavail);
+
+    // PSU Group - 電壓
+    ShmPsuData->PsuGroup[group].PsuModule[address].IAvailableCurrent = Iavail;
 
     bool isPass = true;
+    int totalCur = 0;
 
     if (Iavail == 0)
     {
         for (byte count = 0; count < 2; count++)
         {
-            chargingInfo[address]->SampleChargingCur[count] = Iavail;
+            chargingInfo[group]->SampleChargingCur[count] = Iavail;
         }
     }
     else
     {
+        // 該群的可輸出電流
+        for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
+        {
+            totalCur += ShmPsuData->PsuGroup[group].PsuModule[index].IAvailableCurrent;
+        }
+
         for (byte count = 0; count < 2; count++)
         {
-            if (chargingInfo[address]->SampleChargingCur[count] == 0)
+            if (chargingInfo[group]->SampleChargingCur[count] == 0)
             {
-                chargingInfo[address]->SampleChargingCur[count] = Iavail;
+                chargingInfo[group]->SampleChargingCur[count] = totalCur;
                 return;
             }
             else
             {
-                if (chargingInfo[address]->SampleChargingCur[count] != Iavail)
+                if (chargingInfo[group]->SampleChargingCur[count] != totalCur)
                 {
-                    chargingInfo[address]->SampleChargingCur[count] = Iavail;
+                    chargingInfo[group]->SampleChargingCur[count] = totalCur;
                     isPass = false;
                     continue;
                 }
@@ -514,7 +571,7 @@ void GetIavailableCallback(byte address, unsigned short Iavail, unsigned short V
 
     if (isPass)
     {
-        chargingInfo[address]->DeratingChargingCurrent = Iavail;
+        chargingInfo[group]->DeratingChargingCurrent = totalCur;
     }
 }
 
@@ -622,9 +679,41 @@ void Initialization()
         ShmPsuData->GroupCount = _gunCount;
 }
 
+void CheckSmartChargingStep(bool isCharging)
+{
+    if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_PREPARE_M_TO_A)
+    {
+        if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
+        {
+            PRINTF_FUNC("=============Smart Charging : _REASSIGNED_GET_NEW_CAP============= Step 2 \n");
+            ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_GET_NEW_CAP;
+        }
+        else
+        {
+            PRINTF_FUNC("=============Smart Charging : _REASSIGNED_NONE============= Step 0 \n");
+            ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE;
+        }
+    }
+    else  if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag ==  _REASSIGNED_PREPARE_A_TO_M)
+    {
+        if (isCharging)
+        {
+            if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER)
+            {
+                PRINTF_FUNC("=============Smart Charging : _REASSIGNED_ADJUST_A_TO_M============= Step 12 \n");
+                ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_ADJUST_A_TO_M;
+            }
+            else
+            {
+                PRINTF_FUNC("=============Smart Charging : _REASSIGNED_COMP============= Step 15 \n");
+                ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_COMP;
+            }
+        }
+    }
+}
+
 int main(void)
 {
-    PRINTF_FUNC("Psu Task boot .... \n");
     if(InitShareMemory() == FAIL)
     {
         #ifdef SystemLogMessage
@@ -650,7 +739,8 @@ int main(void)
     RefreshFanInfo(&GetFanSpeedCallback);
     RefreshIavailable(&GetIavailableCallback);
 
-    _gunCount = GUN_COUNT;
+    sleep(2);
+    _gunCount = ShmSysConfigAndInfo->SysConfig.TotalConnectorCount;
     // initial object
     InitialPsuData();
     Initialization();
@@ -700,9 +790,9 @@ int main(void)
 
                 if (time > 2000)
                 {
-                    PRINTF_FUNC("== PSU == GET_PSU_COUNT = %d \n", ShmPsuData->GroupCount);
-                    if (ShmPsuData->GroupCount == 0)
-                        ShmPsuData->GroupCount = 1;
+                    PRINTF_FUNC("== PSU == %d \n", ShmPsuData->GroupCount);
+//                  if (ShmPsuData->GroupCount == 0)
+//                      ShmPsuData->GroupCount = ShmSysConfigAndInfo->SysConfig.TotalConnectorCount;
                     // 分別取各群模組數量
                     for (byte index = 0; index < ShmPsuData->GroupCount; index++)
                     {
@@ -733,6 +823,9 @@ int main(void)
                         {
                             PRINTF_FUNC("== PSU == _WORK_CHARGING \n");
                             ShmPsuData->Work_Step = _WORK_CHARGING;
+
+                            //sdlu test
+                            gettimeofday(&_test_time, NULL);
                         }
                     }
 
@@ -779,6 +872,10 @@ int main(void)
             case _WORK_CHARGING:
             {
                 int time = GetTimeoutValue(_cmdSubPriority_time) / 1000;
+                // sdlu - test
+                int testtime = GetTimeoutValue(_test_time) / 1000;
+
+                bool isCharging = false;
                 // 低 Priority 的指令
                 if (time > 1500)
                 {
@@ -795,16 +892,40 @@ int main(void)
 
                         // 取得模塊輸出額定電流能力
                         GetModuleIavailable(index);
+
+                        if (chargingInfo[index]->SystemStatus == S_CHARGING)
+                            isCharging = true;
+                    }
+
+                    for (byte gunIndex = 0; gunIndex < _gunCount; gunIndex++)
+                    {
+                        if (chargingInfo[gunIndex]->FireChargingVoltage > 0 &&
+                            evseOutVol != (chargingInfo[gunIndex]->FireChargingVoltage / 10))
+                        {
+                            evseOutVol = (chargingInfo[gunIndex]->FireChargingVoltage / 10);
+                            PRINTF_FUNC("groupIndex = %d, evse output vol = %f \n", gunIndex,
+                                    chargingInfo[gunIndex]->FireChargingVoltage);
+                        }
+
+                        if (chargingInfo[gunIndex]->PresentChargingCurrent > 0 &&
+                            evseOutCur != chargingInfo[gunIndex]->PresentChargingCurrent)
+                        {
+                            evseOutCur = chargingInfo[gunIndex]->PresentChargingCurrent;
+                            PRINTF_FUNC("groupIndex = %d, evse output cur = %f \n", gunIndex,
+                                chargingInfo[gunIndex]->PresentChargingCurrent);
+                        }
                     }
 
                     gettimeofday(&_cmdSubPriority_time, NULL);
                 }
 
+                CheckSmartChargingStep(isCharging);
                 for (byte groupIndex = 0; groupIndex < _gunCount; groupIndex++)
                 {
                     GetModuleOutput(groupIndex);
                     // 針對各槍當前狀態,傳送需要回傳的資料指令
                     if (((chargingInfo[groupIndex]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[groupIndex]->SystemStatus <= S_CHARGING) && chargingInfo[groupIndex]->RelayK1K2Status) ||
+                            chargingInfo[groupIndex]->SystemStatus >= S_PREPARING_FOR_EVSE ||
                             (chargingInfo[groupIndex]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[groupIndex]->SystemStatus <= S_CCS_PRECHARGE_ST1))
                     {
                         if (chargingInfo[groupIndex]->EvBatterytargetVoltage > 0 &&
@@ -821,24 +942,153 @@ int main(void)
                             DEBUG_INFO("ev need cur = %f \n", chargingInfo[groupIndex]->EvBatterytargetCurrent);
                         }
 
-                        if (chargingInfo[groupIndex]->FireChargingVoltage > 0 &&
-                            evseOutVol != chargingInfo[groupIndex]->FireChargingVoltage)
+                        if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
+                        {
+                            // 智能判斷 Start -----------------------------------------------------------
+                            if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_GET_NEW_CAP)
+                            {
+                                if (ShmPsuData->SystemAvailableCurrent != chargingInfo[groupIndex]->AvailableChargingCurrent)
+                                {
+                                    // 車端要求電流為該充電槍的額定輸出電流的範圍內
+                                    if (chargingInfo[groupIndex]->EvBatterytargetCurrent <= chargingInfo[groupIndex]->AvailableChargingCurrent ||
+                                        deratingKeepCount >= DERATING)
+                                    {
+                                        // 車端降載完成
+                                        PRINTF_FUNC("=============Smart Charging : _REASSIGNED_ADJUST_M_TO_A============= Step 3 \n");
+                                        ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_ADJUST_M_TO_A;
+                                        gettimeofday(&_derating_time, NULL);
+                                        deratingKeepCount = 0;
+                                    }
+                                    else
                         {
-                            evseOutVol = chargingInfo[groupIndex]->FireChargingVoltage;
-                            PRINTF_FUNC("groupIndex = %d, evse output vol = %f \n", groupIndex,
-                                    chargingInfo[groupIndex]->FireChargingVoltage);
+                                        deratingKeepCount++;
                         }
+                                }
 
-                        if (chargingInfo[groupIndex]->PresentChargingCurrent > 0 &&
-                            evseOutCur != chargingInfo[groupIndex]->PresentChargingCurrent)
+                            }
+                            else if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_ADJUST_M_TO_A)
+                            {
+                                bool isChanged = false;
+
+                                // 需求電流不降低的情況下 -> 依然要切
+                                if (chargingInfo[groupIndex]->AvailableChargingCurrent < chargingInfo[groupIndex]->EvBatterytargetCurrent)
                         {
-                            evseOutCur = chargingInfo[groupIndex]->PresentChargingCurrent;
-                            PRINTF_FUNC("groupIndex = %d, evse output cur = %f \n", groupIndex,
+                                    PRINTF_FUNC("** _REASSIGNED_ADJUST_M_TO_A ** Gun_%d, AvailableChargingCurrent = %f, EvBatterytargetCurrent = %f \n", groupIndex,
+                                            chargingInfo[groupIndex]->PresentChargingCurrent,
+                                            chargingInfo[groupIndex]->AvailableChargingCurrent);
+                                    for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++)
+                                    {
+                                        if (chargingInfo[subIndex]->SystemStatus == S_REASSIGN)
+                                        {
+                                            if (chargingInfo[subIndex]->PresentChargingCurrent <= CHK_CUR_RANGE)
+                                                isChanged = true;
+                                            break;
+                                        }
+                                    }
+
+                                    // 這狀況下輸出端的電流載滿載衝的狀況下,並不會降電流
+                                    // 所以只能拉載到該槍端的最大輸出能力
+                                    if (chargingInfo[groupIndex]->PresentChargingCurrent >= chargingInfo[groupIndex]->AvailableChargingCurrent - CHK_CUR_RANGE ||
+                                            chargingInfo[groupIndex]->PresentChargingCurrent <= CHK_CUR_RANGE)
+                                    {
+                                        isChanged = true;
+                                    }
+                                }
+                                else if ((chargingInfo[groupIndex]->PresentChargingCurrent >= ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent - CHK_CUR_RANGE) &&
+                                        (chargingInfo[groupIndex]->PresentChargingCurrent <= ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent + CHK_CUR_RANGE))
+                                {
+                                    isChanged = true;
+                                }
+
+                                if (isChanged)
+                                {
+                                    PRINTF_FUNC("** _REASSIGNED_ADJUST_M_TO_A ** Gun_%d, PresentChargingCurrent = %f, GroupPresentOutputCurrent = %d \n", groupIndex,
+                                        chargingInfo[groupIndex]->PresentChargingCurrent,
+                                        ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent);
+
+                                    // 輸出端與車端要求電流接近
+                                    PRINTF_FUNC("=============Smart Charging : _REASSIGNED_RELAY_M_TO_A============= Step 4 \n");
+                                    ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_RELAY_M_TO_A;
+                                }
+                            }
+
+                            // 智能判斷 End -----------------------------------------------------------
+                            if (testtime > 500 &&
+                                (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_GET_NEW_CAP && ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A))
+                            {
+                                PRINTF_FUNC("Gun_%d, AvailableChargingCurrent = %f, AvailableChargingPower = %f \n", groupIndex,
+                                        chargingInfo[groupIndex]->AvailableChargingCurrent,
+                                        chargingInfo[groupIndex]->AvailableChargingPower);
+
+                                PRINTF_FUNC("Gun_%d, NeedVol = %f, NeedCur = %f \n", groupIndex,
+                                    chargingInfo[groupIndex]->EvBatterytargetVoltage,
+                                    chargingInfo[groupIndex]->EvBatterytargetCurrent);
+
+                                PRINTF_FUNC("Gun_%d OutputVol = %f, OutputCur = %f \n", groupIndex,
+                                        chargingInfo[groupIndex]->PresentChargingVoltage,
                                 chargingInfo[groupIndex]->PresentChargingCurrent);
+
+                                gettimeofday(&_test_time, NULL);
                         }
 
                         if (ShmPsuData->SystemAvailablePower > 0)
                         {
+                                // 調整輸出電流 : 漸進調整方式
+                                if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_ADJUST_M_TO_A)
+                                {
+                                    // 當前充電中的目標電壓
+                                    float targetVol = chargingInfo[groupIndex]->EvBatterytargetVoltage;
+                                    // 當前充電中的目標電流
+                                    float targetCur = 0;
+                                    // 準備切出去的模塊電流
+                                    float deratingCur = 0;
+
+                                    byte reassignIndex = ELEMENT_NOT_FIND;
+                                    // 找到等待分配的槍
+                                    for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++)
+                                    {
+                                        if (chargingInfo[subIndex]->SystemStatus == S_REASSIGN)
+                                        {
+                                            reassignIndex = subIndex;
+                                        }
+                                    }
+
+                                    if (reassignIndex != ELEMENT_NOT_FIND)
+                                    {
+                                        //int derating = GetTimeoutValue(_derating_time) / 1000;
+
+                                        //if (derating > 1000)
+                                        {
+                                            if (ShmPsuData->PsuGroup[reassignIndex].GroupPresentOutputCurrent > 0)
+                                            {
+                                                deratingCur = ShmPsuData->PsuGroup[reassignIndex].GroupPresentOutputCurrent - DERATING_RANGE;
+                                                if (deratingCur <= CHK_CUR_RANGE)
+                                                    deratingCur = CHK_CUR_RANGE;
+
+                                                PresentOutputVol(reassignIndex, targetVol, deratingCur);
+                                                gettimeofday(&_derating_time, NULL);
+                                            }
+                                        }
+
+                                        // 因為爬的速度沒有降的速度快,所以採兩倍速度爬升
+                                        targetCur = ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent + (DERATING_RANGE * 2);
+                                        if (targetCur >= chargingInfo[groupIndex]->EvBatterytargetCurrent)
+                                                targetCur = chargingInfo[groupIndex]->EvBatterytargetCurrent;
+
+                                        if (targetVol == 0)
+                                        {
+                                            SwitchPower(SYSTEM_CMD, PSU_POWER_OFF);
+                                            FlashLed(SYSTEM_CMD, PSU_FLASH_NORMAL);
+                                        }
+                                        else
+                                        {
+                                            SwitchPower(SYSTEM_CMD, PSU_POWER_ON);
+                                            FlashLed(SYSTEM_CMD, PSU_FLASH_ON);
+                                        }
+                                    }
+                                }
+                                else
+                                {
                             // 該充電槍的目標電壓與目標電流
                             PresentOutputVol(SYSTEM_CMD,
                                     chargingInfo[groupIndex]->EvBatterytargetVoltage,
@@ -855,6 +1105,125 @@ int main(void)
                                 FlashLed(SYSTEM_CMD, PSU_FLASH_ON);
                             }
                         }
+                    }
+                        }
+                        else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER)
+                        {
+                            // 智能判斷 Start -----------------------------------------------------------
+                            if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_ADJUST_A_TO_M)
+                            {
+                                bool balanceVol = true;
+
+                                for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++)
+                                {
+                                    if (chargingInfo[subIndex]->SystemStatus == S_IDLE ||
+                                            chargingInfo[subIndex]->SystemStatus == S_RESERVATION)
+                                    {
+                                        // 各群電壓接近平衡
+                                        if (((chargingInfo[subIndex]->PresentChargingVoltage * 10) < (chargingInfo[groupIndex]->PresentChargingVoltage * 10) - ZERO_VOLTAGE) ||
+                                            ((chargingInfo[subIndex]->PresentChargingVoltage * 10) < chargingInfo[groupIndex]->EvBatterytargetVoltage - CHK_VOL_RANGE))
+                                        {
+                                            PRINTF_FUNC("** _REASSIGNED_ADJUST_A_TO_M ** Gun_%d, PresentChargingVoltage = %f, PresentChargingVoltage_V = %f, EvBatterytargetVoltage = %f \n", subIndex,
+                                                chargingInfo[subIndex]->PresentChargingVoltage,
+                                                (chargingInfo[groupIndex]->PresentChargingVoltage - ZERO_VOLTAGE),
+                                                (chargingInfo[groupIndex]->EvBatterytargetVoltage - CHK_VOL_RANGE));
+                                            balanceVol = false;
+                                        }
+                                        break;
+                                    }
+                                }
+
+                                if (balanceVol)
+                                {
+                                    // 閒置端與車端要求電壓接近
+                                    PRINTF_FUNC("=============Smart Charging : _REASSIGNED_RELAY_A_TO_M============= Step 13 \n");
+                                    ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_RELAY_A_TO_M;
+                                    GetTimeoutValue(_averageComp_time);
+                                }
+                            }
+                            else if(ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_WAITING)
+                            {
+                                int avrTime = GetTimeoutValue(_averageComp_time) / 1000;
+
+                                if (avrTime > 3000)
+                                {
+                                    // 閒置端與車端要求電壓接近
+                                    PRINTF_FUNC("=============Smart Charging : _REASSIGNED_COMP============= Step 15 \n");
+                                    ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_COMP;
+                                }
+                            }
+                            // 智能判斷 End -----------------------------------------------------------
+                            if (testtime > 500 &&
+                                    (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_ADJUST_A_TO_M && ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_WAITING))
+                            {
+                                PRINTF_FUNC("Gun_%d, AvailableChargingCurrent = %f, AvailableChargingPower = %f \n", groupIndex,
+                                    chargingInfo[groupIndex]->AvailableChargingCurrent,
+                                    chargingInfo[groupIndex]->AvailableChargingPower);
+
+                                PRINTF_FUNC("Gun_%d, NeedVol = %f, NeedCur = %f \n", groupIndex,
+                                    chargingInfo[groupIndex]->EvBatterytargetVoltage,
+                                    chargingInfo[groupIndex]->EvBatterytargetCurrent);
+
+                                PRINTF_FUNC("Gun_%d OutputVol = %f, OutputCur = %f \n", groupIndex,
+                                    chargingInfo[groupIndex]->PresentChargingVoltage,
+                                    chargingInfo[groupIndex]->PresentChargingCurrent);
+
+                                gettimeofday(&_test_time, NULL);
+                            }
+
+                            if (chargingInfo[groupIndex]->AvailableChargingCurrent > 0)
+                            {
+                                if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_ADJUST_A_TO_M)
+                                {
+                                    for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++)
+                                    {
+                                        if (chargingInfo[subIndex]->SystemStatus == S_IDLE ||
+                                                chargingInfo[subIndex]->SystemStatus == S_RESERVATION)
+                                        {
+                                            // 閒置模塊升壓
+                                            PresentOutputVol(subIndex,
+                                                    chargingInfo[groupIndex]->EvBatterytargetVoltage,
+                                                    ZERO_CURRENT);
+                                        }
+                                        else
+                                        {
+                                            // 充電中的模塊維持輸出
+                                            PresentOutputVol(subIndex,
+                                                chargingInfo[subIndex]->EvBatterytargetVoltage,
+                                                chargingInfo[subIndex]->EvBatterytargetCurrent);
+                                        }
+
+                                        if (chargingInfo[groupIndex]->EvBatterytargetVoltage == 0)
+                                        {
+                                            SwitchPower(subIndex, PSU_POWER_OFF);
+                                            FlashLed(subIndex, PSU_FLASH_NORMAL);
+                                        }
+                                        else
+                                        {
+                                            SwitchPower(subIndex, PSU_POWER_ON);
+                                            FlashLed(subIndex, PSU_FLASH_ON);
+                                        }
+                                    }
+                                }
+                                else
+                                {
+                                    PresentOutputVol(groupIndex,
+                                        chargingInfo[groupIndex]->EvBatterytargetVoltage,
+                                        chargingInfo[groupIndex]->EvBatterytargetCurrent);
+
+                                    if (chargingInfo[groupIndex]->EvBatterytargetVoltage == 0)
+                                    {
+                                        SwitchPower(groupIndex, PSU_POWER_OFF);
+                                        FlashLed(groupIndex, PSU_FLASH_NORMAL);
+                                    }
+                                    else
+                                    {
+                                        SwitchPower(groupIndex, PSU_POWER_ON);
+                                        FlashLed(groupIndex, PSU_FLASH_ON);
+                                    }
+                                }
+                            }
+                        }
                     }
                     else if (chargingInfo[groupIndex]->SystemStatus >= S_TERMINATING &&
                                 chargingInfo[groupIndex]->SystemStatus <= S_COMPLETE)
@@ -863,6 +1232,17 @@ int main(void)
                         {
                             SwitchPower(SYSTEM_CMD, PSU_POWER_OFF);
                             FlashLed(SYSTEM_CMD, PSU_FLASH_NORMAL);
+
+                            if (chargingInfo[groupIndex]->SystemStatus == S_TERMINATING)
+                            {
+                                if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_PREPARE_M_TO_A &&
+                                        ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A)
+                                {
+                                    // 代表在切換的過程中,停止充電了
+                                    if (chargingInfo[groupIndex]->PresentChargingCurrent <= STOP_CURRENT)
+                                        ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_RELAY_M_TO_A;
+                                }
+                            }
                         }
                         else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER)
                         {

+ 4 - 4
EVSE/Projects/DM30/Apps/Module_PsuComm.h

@@ -33,18 +33,18 @@
 #include <stdbool.h>
 
 typedef unsigned char       byte;
-typedef unsigned short  word;
+typedef unsigned short      word;
 typedef unsigned int        unit;
 
-#define GUN_COUNT           CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY
-
 unsigned char _gunCount;
-struct ChargingInfoData *chargingInfo[GUN_COUNT];
+struct ChargingInfoData *chargingInfo[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 
 struct timeval _cmdSubPriority_time;
 byte _getCapDelayCount;
 struct timeval _averageComp_time;
 struct timeval _derating_time;
 
+struct timeval _test_time;
+
 int connector_1[] = {0};
 int connector_2[] = {1};

+ 62 - 6
EVSE/Projects/DM30/Apps/ReadCmdline.c

@@ -52,6 +52,7 @@ struct StatusCodeData           *ShmStatusCodeData;
 struct PrimaryMcuData           *ShmPrimaryMcuData;
 struct CHAdeMOData              *ShmCHAdeMOData;
 struct CcsData                  *ShmCcsData;
+struct GBTData                  *ShmGBTData;
 struct FanModuleData            *ShmFanModuleData;
 struct RelayModuleData          *ShmRelayModuleData;
 struct PsuData                  *ShmPsuData;
@@ -151,6 +152,17 @@ int InitShareMemory()
         }
     }
 
+    if (GB_QUANTITY > 0)
+    {
+        if ((MeterSMId = shmget(ShmGBTCommKey, sizeof(struct GBTData),
+        IPC_CREAT | 0777)) < 0) {
+            return 0;
+        } else if ((ShmGBTData = shmat(MeterSMId, NULL, 0)) == (void *) -1) {
+            return 0;
+        }
+        memset(ShmGBTData, 0, sizeof(struct GBTData));
+    }
+
     if ((MeterSMId = shmget(ShmPrimaryMcuKey, sizeof(struct PrimaryMcuData), IPC_CREAT | 0777)) < 0)
     {
         result = FAIL;
@@ -279,13 +291,15 @@ void GetFwVerProc(char *v1)
     }
     else if (strcmp(v1, "0") == 0)
     {
-        printf("Ev board 1 FW Version = %s \n", ShmCHAdeMOData->evse[0].version);
-        printf("Ev board 1 FW Version = %s \n", ShmCcsData->V2GMessage_DIN70121->version);
+        printf("Ev board 0 FW Version = %s \n", ShmCHAdeMOData->evse[0].version);
     }
     else if (strcmp(v1, "1") == 0)
     {
-        printf("Ev board 2 FW Version = %s \n", ShmCcsData->V2GMessage_DIN70121->version);
-        printf("Ev board 2 FW Version = %s \n", ShmCHAdeMOData->evse[1].version);
+        printf("Ev board 1 FW Version = %s \n", ShmCcsData->V2GMessage_DIN70121->version);
+    }
+    else if (strcmp(v1, "2") == 0)
+    {
+        printf("Ev board 2 FW Version = %s \n", ShmGBTData->evse[0].version);
     }
     else if (strcmp(v1, "rb") == 0)
     {
@@ -339,6 +353,14 @@ void SetPowerValue(char *v1, char *v2)
     _chargingData[_index]->EvBatterytargetCurrent = _Current * 10;
 }
 
+void GetSystemInfo()
+{
+    printf ("ModelName = %s \n", ShmSysConfigAndInfo->SysConfig.ModelName);
+    printf ("MaxChargingPower = %d, MaxChargingCurrent = %d \n",
+            ShmSysConfigAndInfo->SysConfig.MaxChargingPower,
+            ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent);
+}
+
 void GetGunSelectedNum(char *v1)
 {
     if (strcmp(v1, "-1") == 0 || strcmp(v1, "") == 0)
@@ -366,9 +388,27 @@ void GetFanSpeed()
     printf("ShmFanModuleData->PresentFan4Speed = %d \n", ShmFanModuleData->PresentFan4Speed);
 }
 
+void SetDebugMode(char *v1)
+{
+    int mode = atoi(v1);
+
+    ShmSysConfigAndInfo->SysConfig.SwitchDebugFlag = mode;
+}
+
+void GetPsuTemp()
+{
+    for (byte index = 0; index < ShmPsuData->GroupCount; index++)
+    {
+        for (byte count = 0; count < ShmPsuData->PsuGroup[index].GroupPresentPsuQuantity; count++)
+        {
+            printf("PSU Temp = %d \n", ShmPsuData->PsuGroup[index].PsuModule[count].ExletTemp);
+        }
+    }
+}
+
 void GetPsuInformation(char *v1)
 {
-    printf("*************************************************\n");
+    printf("**********************須搭上 AC Contact*************************\n");
     if(strcmp(v1, "count") == 0)
     {
         for (int i = 0; i < 4; i++)
@@ -483,6 +523,7 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
 
                 }
 
+                ShmSysConfigAndInfo->SysInfo.StartToChargingFlag = 0x01;
                 _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_PREPARNING;
             }
             break;
@@ -617,7 +658,7 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
                 }
 
                 //ev task do this
-                _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingPower = ((float)((_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingVoltage / 10) * (_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingCurrent / 10)) / 1000);
+                _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingPower = ((float)((_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingVoltage) * (_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingCurrent)) / 1000);
 
                 if (_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus == 0x02){
                      printf ("Charging Ground Fault check Fail (%d)\n",_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus);
@@ -695,6 +736,7 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
                 case 'C':
                     printf("stop \n\r");
                     //system(STTY_DEF TTY_PATH);
+                    ShmSysConfigAndInfo->SysInfo.StartToChargingFlag = 0x00;
                     _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_TERMINATING;
                     break;
             }
@@ -821,6 +863,10 @@ int main(void)
             // cable check pass
             SetPowerValue(newString[1], newString[2]);
         }
+        else if (strcmp(newString[0], "model") == 0)
+        {
+            GetSystemInfo();
+        }
         else if(strcmp(newString[0], "select") == 0)
         {
             // 取得當前選的槍號
@@ -836,6 +882,16 @@ int main(void)
             // 取得風扇速度
             GetFanSpeed();
         }
+        else if(strcmp(newString[0], "debug") == 0)
+        {
+            // 設定 debug mode
+            SetDebugMode(newString[1]);
+        }
+        else if(strcmp(newString[0], "temp") == 0)
+        {
+            // 取得 PSU 溫度
+            GetPsuTemp();
+        }
         else if(strcmp(newString[0], "psu") == 0)
         {
             //如果連一個參數都沒有 (此命令不理會) 加上判斷第二參數

Файловите разлики са ограничени, защото са твърде много
+ 388 - 78
EVSE/Projects/DM30/Apps/main.c


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