Browse Source

2020.05.20 / TC Hsu

Actions: Merge D0.13 application code from model DS60.

         Include following:

         D0.10
         ---------------------------------------------------
         1. Porting ReadCmdline command.
         ===================================================

         D0.11
         ---------------------------------------------------
         1. Improve, add foolproof mechanism for RFID card scan feature.
         2. Bug fixed for fan speed setup error, modify fan speed control function,
            will not reference the fan speed feedback.
         3. Bug fixed for incomplete firmware version display in Web, When copy the
            firmware version from CAN data frame to share memory, modify the copy
            length from constant to the length of CAN data. Since the firmware version
            length of every sub-board may be different.
         4. Improve, add model name parsing function to dispatch PSU quantity.
         5. Improve, for smart charge feature, the new charging requirement will
            be paused until the ongoing charging process be stable.
         ===================================================

         D0.12
         ---------------------------------------------------
         1. Improve, for smart charge, add charging cancel feature when the charging
            process is waiting for PSU dispatch.
         2. Improve, Add dual CCS function support, but the precharge relay will not
            available for left side, instead, it will using the DC relay.
         3. Improve, for smart charge, add protection mechaism to current control
            function to prevent current drop when maximum charging feature.
         4. Improve, Add rating current setup feature for AC.
         ===================================================

         D0.13
         ---------------------------------------------------
         1. Bug fixed, resolve the freezing issue, for samrt charge, when one
            charging process stop, charging mode of the other one process will
            transfer form balance charging to maximum charging, if the translation
            still not completed, and the new charging requirement happend, the
            charging process will be freezed.
         2. Bug fixed, when charging start, before the available current obtained
            from PSU, the available current to EV board will using the defined
            maximum output current of PSU.
         3. Bug fixed, resolve the error code display fail issue for dual charger.

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

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

Files:

	modified:   Config.h
	modified:   FactoryConfig.c
	modified:   Module_EvComm.c
	modified:   Module_InternalComm.c
	modified:   Module_LcmControl.c
	modified:   Module_LcmControl.h
	modified:   Module_PsuComm.c
	modified:   Module_PsuComm.h
	modified:   ReadCmdline.c
	modified:   internalComm.c
	modified:   internalComm.h
	modified:   main.c
	new file:   web.sh
TC_Hsu 5 years ago
parent
commit
94d5daa34b

+ 17 - 0
EVSE/Projects/DM30/Apps/Config.h

@@ -70,11 +70,22 @@ enum _SYSTEM_STATUS
     S_NONE                              = 20,
     S_NONE                              = 20,
 };
 };
 
 
+enum _AC_SYSTEM_STATUS
+{
+    AC_SYS_NONE                         = 0,
+    AC_SYS_A                            = 1,
+    AC_SYS_B                            = 2,
+    AC_SYS_C                            = 3,
+    AC_SYS_D                            = 4,
+    AC_SYS_E                            = 5,
+};
+
 enum _GUN_TYPE
 enum _GUN_TYPE
 {
 {
     _Type_Chademo                       = 0,
     _Type_Chademo                       = 0,
     _Type_CCS_2                         = 1,
     _Type_CCS_2                         = 1,
     _Type_GB                            = 2,
     _Type_GB                            = 2,
+    _Type_AC                            = 3,
 };
 };
 
 
 enum _LCM_INDEX
 enum _LCM_INDEX
@@ -149,4 +160,10 @@ enum _EXTRA_ERR_PROCESS
     _EXTRA_ERR_PROCESS_INOVP            = 2,
     _EXTRA_ERR_PROCESS_INOVP            = 2,
 };
 };
 
 
+enum _CHARGER_TYPE
+{
+    _CHARGER_TYPE_IEC                   = 0,
+    _CHARGER_TYPE_UL                    = 1,
+};
+
 #endif /* CONFIG_H_ */
 #endif /* CONFIG_H_ */

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

@@ -103,7 +103,7 @@ int main(int argc,char *argv[])
      */
      */
     //********** System **********// udhcpc -i eth1 -s ./dhcp_script/eth1.script
     //********** System **********// udhcpc -i eth1 -s ./dhcp_script/eth1.script
     //
     //
-    strcpy((char *)SysConfig.ModelName, "DWWU301U00W1PH");
+    strcpy((char *)SysConfig.ModelName, "DMYE301E00W2PH");
     strcpy((char *)SysConfig.SerialNumber, "");
     strcpy((char *)SysConfig.SerialNumber, "");
 
 
     memset(SysConfig.SystemId, 0x00, sizeof(SysConfig.SystemId));
     memset(SysConfig.SystemId, 0x00, sizeof(SysConfig.SystemId));
@@ -128,8 +128,9 @@ int main(int argc,char *argv[])
     SysConfig.isRFID = 1;
     SysConfig.isRFID = 1;
     //********** Charging **********//
     //********** Charging **********//
     SysConfig.MaxChargingEnergy = 0;
     SysConfig.MaxChargingEnergy = 0;
-    SysConfig.MaxChargingCurrent = 65;      // 最大可輸出電流
+    SysConfig.MaxChargingCurrent = 60;      // 最大可輸出電流
     SysConfig.MaxChargingDuration = 0;
     SysConfig.MaxChargingDuration = 0;
+    SysConfig.AcMaxChargingCurrent = 0;
     SysConfig.PhaseLossPolicy = 0;
     SysConfig.PhaseLossPolicy = 0;
     for(unsigned char i = 0; i < 10; i++)
     for(unsigned char i = 0; i < 10; i++)
         strcpy((char *)SysConfig.LocalWhiteCard, "");
         strcpy((char *)SysConfig.LocalWhiteCard, "");

File diff suppressed because it is too large
+ 1919 - 232
EVSE/Projects/DM30/Apps/Module_EvComm.c


+ 531 - 177
EVSE/Projects/DM30/Apps/Module_InternalComm.c

@@ -39,6 +39,7 @@
 #define TEN_MINUTES         600
 #define TEN_MINUTES         600
 #define ENV_TEMP_MIN        45
 #define ENV_TEMP_MIN        45
 #define ENV_TEMP_MAX        50
 #define ENV_TEMP_MAX        50
+#define DEFAULT_AC_INDEX    2
 
 
 struct SysConfigAndInfo         *ShmSysConfigAndInfo;
 struct SysConfigAndInfo         *ShmSysConfigAndInfo;
 struct StatusCodeData           *ShmStatusCodeData;
 struct StatusCodeData           *ShmStatusCodeData;
@@ -48,16 +49,19 @@ struct CHAdeMOData              *ShmCHAdeMOData;
 struct CcsData                  *ShmCcsData;
 struct CcsData                  *ShmCcsData;
 struct PsuData                  *ShmPsuData;
 struct PsuData                  *ShmPsuData;
 
 
-#define VIN_MAX_VOLTAGE     310 // 大於該值 : OVP
-#define VIN_MIN_VOLTAGE     150 // 小於該值 : UVP
+#define VIN_MAX_VOLTAGE_IEC     296 // 大於該值 : OVP
+#define VIN_MIN_VOLTAGE_IEC     166 // 小於該值 : UVP
+#define VIN_MAX_VOLTAGE_UL      305 // 大於該值 : OVP
+#define VIN_MIN_VOLTAGE_UL      215 // 小於該值 : UVP
+
 #define VIN_DROP_VOLTAGE    150 // 小於該值 : ac drop
 #define VIN_DROP_VOLTAGE    150 // 小於該值 : ac drop
 
 
-#define VOUT_MAX_VOLTAGE    750
+#define VOUT_MAX_VOLTAGE    995
 #define VOUT_MIN_VOLTAGE    150
 #define VOUT_MIN_VOLTAGE    150
 #define IOUT_MAX_CURRENT    50
 #define IOUT_MAX_CURRENT    50
 
 
 #define MAX_FAN_SPEED       13500
 #define MAX_FAN_SPEED       13500
-#define MIN_FAN_SPEED       2800
+#define MIN_FAN_SPEED       3000
 #define NORMAL_FAN_SPEED    7000
 #define NORMAL_FAN_SPEED    7000
 
 
 // GFD Status
 // GFD Status
@@ -77,8 +81,10 @@ struct PsuData                  *ShmPsuData;
 #define RELAY_WELDING_DET                   300
 #define RELAY_WELDING_DET                   300
 
 
 byte gunCount;
 byte gunCount;
+byte acgunCount;
 // 槍資訊
 // 槍資訊
 struct ChargingInfoData *_chargingData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 struct ChargingInfoData *_chargingData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
+struct ChargingInfoData *ac_chargingInfo[AC_QUANTITY];
 
 
 bool _isOutputNoneMatch[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 bool _isOutputNoneMatch[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 struct timeval _checkOutputNoneMatchTimer[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 struct timeval _checkOutputNoneMatchTimer[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
@@ -90,14 +96,20 @@ bool FindChargingInfoData(byte target, struct ChargingInfoData **chargingData);
 
 
 int Uart5Fd;
 int Uart5Fd;
 char *relayRs485PortName = "/dev/ttyS5";
 char *relayRs485PortName = "/dev/ttyS5";
-unsigned short fanSpeedSmoothValue = 1000;
+unsigned short fanSpeedSmoothValue = 500;
 
 
 bool isStopChargingCount = false;
 bool isStopChargingCount = false;
-bool isSystemBooting = false;
 struct timeval _close_ac_contactor;
 struct timeval _close_ac_contactor;
 
 
 struct timeval _priority_time;
 struct timeval _priority_time;
 
 
+struct timeval  _ac_charging_comp;
+struct timeval  _ac_preparing;
+struct timeb    _ac_startChargingTime;
+struct timeb    _ac_endChargingTime;
+
+unsigned short _setFanSpeed = 0;
+
 Ver ver;
 Ver ver;
 PresentInputVoltage inputVoltage;
 PresentInputVoltage inputVoltage;
 PresentOutputVoltage outputVoltage;
 PresentOutputVoltage outputVoltage;
@@ -112,6 +124,37 @@ Relay outputRelay;
 Relay regRelay;
 Relay regRelay;
 Rtc rtc;
 Rtc rtc;
 
 
+Ac_Status acStatus;
+Ac_Led_Status ledStatus;
+Ac_Alarm_code acAlarmCode;
+Ac_Charging_energy acChargingEnergy;
+Ac_Charging_current acChargingCurrent;
+
+#define AC_OVP                      1
+#define AC_UVP                      2
+#define AC_OCP                      4
+#define AC_OTP                      8
+#define AC_GMI_FAULT                16
+#define AC_CP_ERROR                 32
+#define AC_AC_LEAKAGE               64
+#define AC_DC_LEAKAGE               128
+#define AC_SYSTEM_SELFTEST_FAULT    256
+#define AC_HANDSHAKE_TIMEOUT        512
+#define AC_EMC_STOP                 1024
+#define AC_RELAY_WELDING            2048
+#define AC_GF_MODULE_FAULT          4096
+#define AC_SHUTTER_FAULT            8192
+#define AC_LOCKER_FAULT             16384
+#define AC_POWER_DROP               32768
+#define AC_CIRCUIT_SHORT            65536
+#define AC_ROTARY_SWITCH_FAULT      131072
+#define AC_RELAY_DRIVE_FAULT        262144
+
+int _alarm_code[] = {AC_OVP, AC_UVP, AC_OCP, AC_OTP, AC_GMI_FAULT, AC_CP_ERROR, AC_AC_LEAKAGE
+        , AC_DC_LEAKAGE, AC_SYSTEM_SELFTEST_FAULT, AC_HANDSHAKE_TIMEOUT, AC_EMC_STOP, AC_RELAY_WELDING
+        , AC_GF_MODULE_FAULT, AC_SHUTTER_FAULT, AC_LOCKER_FAULT, AC_POWER_DROP, AC_CIRCUIT_SHORT
+        , AC_ROTARY_SWITCH_FAULT, AC_RELAY_DRIVE_FAULT};
+
 void PRINTF_FUNC(char *string, ...);
 void PRINTF_FUNC(char *string, ...);
 
 
 int StoreLogMsg(const char *fmt, ...);
 int StoreLogMsg(const char *fmt, ...);
@@ -156,11 +199,11 @@ int StoreLogMsg(const char *fmt, ...)
 int DiffTimeb(struct timeb ST, struct timeb ET)
 int DiffTimeb(struct timeb ST, struct timeb ET)
 {
 {
     //return milli-second
     //return milli-second
-    unsigned int StartTime,StopTime;
+    unsigned int StartTime, StopTime;
 
 
-    StartTime=(unsigned int)ST.time;
-    StopTime=(unsigned int)ET.time;
-    return (StopTime-StartTime)*1000+ET.millitm-ST.millitm;
+    StartTime = (unsigned int) ST.time;
+    StopTime = (unsigned int) ET.time;
+    return (StopTime - StartTime);
 }
 }
 
 
 unsigned short MaxValue(unsigned short value1, unsigned short value2)
 unsigned short MaxValue(unsigned short value1, unsigned short value2)
@@ -223,6 +266,15 @@ void GetFwAndHwVersion_Relay()
     }
     }
 }
 }
 
 
+void GetFwVersion_AC()
+{
+    if (Query_FW_Ver(Uart5Fd, Addr.AcPlug, &ver) == PASS)
+    {
+        ac_chargingInfo[0]->SelfTest_Comp = YES;
+        strcpy((char *) ac_chargingInfo[0]->version, ver.Version_FW);
+    }
+}
+
 void SetRtcData_Relay()
 void SetRtcData_Relay()
 {
 {
     struct timeb csuTime;
     struct timeb csuTime;
@@ -316,38 +368,77 @@ void GetPresentInputVol()
         ShmSysConfigAndInfo->SysInfo.InputVoltageT = ShmRelayModuleData->InputL3Volt = inputVoltage.L3N_L31;
         ShmSysConfigAndInfo->SysInfo.InputVoltageT = ShmRelayModuleData->InputL3Volt = inputVoltage.L3N_L31;
 
 
         //********************************************************************************************************//
         //********************************************************************************************************//
-        // VIN < 170
-        if (inputVoltage.L1N_L12 < VIN_MIN_VOLTAGE)
-            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP = YES;
-        else
-            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP = NO;
+        // Vin (UVP)
+        if (ShmSysConfigAndInfo->SysInfo.ChargerType == _CHARGER_TYPE_IEC)
+        {
+            if (inputVoltage.L1N_L12 < VIN_MIN_VOLTAGE_IEC)
+                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP = YES;
+            else
+                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP = NO;
 
 
-        if (inputVoltage.L2N_L23 < VIN_MIN_VOLTAGE)
-            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP = YES;
-        else
-            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP = NO;
+            if (inputVoltage.L2N_L23 < VIN_MIN_VOLTAGE_IEC)
+                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP = YES;
+            else
+                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP = NO;
 
 
-        if (inputVoltage.L3N_L31 < VIN_MIN_VOLTAGE)
-            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP = YES;
-        else
-            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP = NO;
+            if (inputVoltage.L3N_L31 < VIN_MIN_VOLTAGE_IEC)
+                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP = YES;
+            else
+                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP = NO;
+        }
+        else if (ShmSysConfigAndInfo->SysInfo.ChargerType == _CHARGER_TYPE_UL)
+        {
+            if (inputVoltage.L1N_L12 < VIN_MIN_VOLTAGE_UL)
+                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP = YES;
+            else
+                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP = NO;
+
+            if (inputVoltage.L2N_L23 < VIN_MIN_VOLTAGE_UL)
+                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP = YES;
+            else
+                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP = NO;
 
 
+            if (inputVoltage.L3N_L31 < VIN_MIN_VOLTAGE_UL)
+                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP = YES;
+            else
+                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP = NO;
+        }
         //********************************************************************************************************//
         //********************************************************************************************************//
-        // VIN > 277
-        if (inputVoltage.L1N_L12 > VIN_MAX_VOLTAGE)
-            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP = YES;
-        else
-            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP = NO;
+        // Vin (OVP)
+        if (ShmSysConfigAndInfo->SysInfo.ChargerType == _CHARGER_TYPE_IEC)
+        {
+            if (inputVoltage.L1N_L12 > VIN_MAX_VOLTAGE_IEC)
+                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP = YES;
+            else
+                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP = NO;
 
 
-        if (inputVoltage.L2N_L23 > VIN_MAX_VOLTAGE)
-            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP = YES;
-        else
-            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP = NO;
+            if (inputVoltage.L2N_L23 > VIN_MAX_VOLTAGE_IEC)
+                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP = YES;
+            else
+                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP = NO;
 
 
-        if (inputVoltage.L3N_L31 > VIN_MAX_VOLTAGE)
-            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP = YES;
-        else
-            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP = NO;
+            if (inputVoltage.L3N_L31 > VIN_MAX_VOLTAGE_IEC)
+                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP = YES;
+            else
+                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP = NO;
+        }
+        else if (ShmSysConfigAndInfo->SysInfo.ChargerType == _CHARGER_TYPE_UL)
+        {
+            if (inputVoltage.L1N_L12 > VIN_MAX_VOLTAGE_UL)
+                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP = YES;
+            else
+                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP = NO;
+
+            if (inputVoltage.L2N_L23 > VIN_MAX_VOLTAGE_UL)
+                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP = YES;
+            else
+                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP = NO;
+
+            if (inputVoltage.L3N_L31 > VIN_MAX_VOLTAGE_UL)
+                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP = YES;
+            else
+                ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP = NO;
+        }
     }
     }
 }
 }
 
 
@@ -449,11 +540,21 @@ void CheckK1K2RelayOutput(byte index)
 
 
             if(_chargingData[index]->Type == _Type_CCS_2)
             if(_chargingData[index]->Type == _Type_CCS_2)
             {
             {
+                if (gunCount == 1)
+                {
                 if (regRelay.relay_event.bits.Gun1_N == YES && regRelay.relay_event.bits.CCS_Precharge == YES)
                 if (regRelay.relay_event.bits.Gun1_N == YES && regRelay.relay_event.bits.CCS_Precharge == YES)
                     _chargingData[index]->RelayKPK2Status = YES;
                     _chargingData[index]->RelayKPK2Status = YES;
                 else
                 else
                     _chargingData[index]->RelayKPK2Status = NO;
                     _chargingData[index]->RelayKPK2Status = NO;
             }
             }
+                else
+                {
+                    if (_chargingData[index]->SystemStatus == S_CCS_PRECHARGE_ST0)
+                        _chargingData[index]->RelayKPK2Status = YES;
+                    else
+                        _chargingData[index]->RelayKPK2Status = NO;
+                }
+            }
         }
         }
         else if (_chargingData[index]->Evboard_id == 0x02)
         else if (_chargingData[index]->Evboard_id == 0x02)
         {
         {
@@ -505,7 +606,7 @@ void GetGfdAdc()
     {
     {
         for (int i = 0; i < gunCount; i++)
         for (int i = 0; i < gunCount; i++)
         {
         {
-            if (_chargingData[i]->Type == 9)
+            if (_chargingData[i]->Type == 0x09 && !ShmSysConfigAndInfo->SysConfig.AlwaysGfdFlag)
             {
             {
                 if ((_chargingData[i]->PresentChargingVoltage * 10) >= VOUT_MIN_VOLTAGE)
                 if ((_chargingData[i]->PresentChargingVoltage * 10) >= VOUT_MIN_VOLTAGE)
                     _chargingData[i]->GroundFaultStatus = GFD_PASS;
                     _chargingData[i]->GroundFaultStatus = GFD_PASS;
@@ -646,78 +747,22 @@ void GetAuxPower()
 void SetFanModuleSpeed()
 void SetFanModuleSpeed()
 {
 {
     // 調整風扇速度要漸進式 : 500 rpm/p
     // 調整風扇速度要漸進式 : 500 rpm/p
-    if (ShmFanModuleData->PresentFan1Speed != ShmFanModuleData->SetFan1Speed ||
-            ShmFanModuleData->PresentFan2Speed != ShmFanModuleData->SetFan2Speed ||
-            ShmFanModuleData->PresentFan3Speed != ShmFanModuleData->SetFan3Speed ||
-            ShmFanModuleData->PresentFan4Speed != ShmFanModuleData->SetFan4Speed)
-    {
-        //printf("ShmFanModuleData->SetFan1Speed = %d \n", ShmFanModuleData->SetFan1Speed);
-
-        FanSpeed _fanSpeed;
-
-        unsigned short speed = ShmFanModuleData->PresentFan1Speed + fanSpeedSmoothValue;
-        if (speed >= ShmFanModuleData->SetFan1Speed)
-            speed = ShmFanModuleData->SetFan1Speed;
-        _fanSpeed.speed[0] = speed;
-
-        speed = ShmFanModuleData->PresentFan2Speed + fanSpeedSmoothValue;
-        if (speed >= ShmFanModuleData->SetFan2Speed)
-            speed = ShmFanModuleData->SetFan2Speed;
-        _fanSpeed.speed[1] = speed;
-
-        speed = ShmFanModuleData->PresentFan3Speed + fanSpeedSmoothValue;
-        if (speed >= ShmFanModuleData->SetFan3Speed)
-            speed = ShmFanModuleData->SetFan3Speed;
-        _fanSpeed.speed[2] = speed;
+    FanSpeed _fanSpeed;
 
 
-        speed = ShmFanModuleData->PresentFan4Speed + fanSpeedSmoothValue;
-        if (speed >= ShmFanModuleData->SetFan4Speed)
-            speed = ShmFanModuleData->SetFan4Speed;
-        _fanSpeed.speed[3] = speed;
+    _setFanSpeed += fanSpeedSmoothValue;
 
 
-        if (Config_Fan_Speed(Uart5Fd, Addr.Fan, &_fanSpeed) == PASS)
-        {
-            //PRINTF_FUNC("successfully Fan\n");
-        }
-    }
-}
-
-void SetRelayModuleFanSpeed()
-{
-    // 調整風扇速度要漸進式 : 100 rpm/p
-    if (ShmFanModuleData->PresentFan1Speed != ShmFanModuleData->SetFan1Speed)
+    if (_setFanSpeed >= ShmFanModuleData->SetFan1Speed)
+        _setFanSpeed = ShmFanModuleData->SetFan1Speed;
     {
     {
-        FanSpeed _fanSpeed;
-        unsigned short speed = 0;
-
-        if (ShmFanModuleData->SetFan1Speed > ShmFanModuleData->PresentFan1Speed)
-        {
-            speed = ShmFanModuleData->PresentFan1Speed + fanSpeedSmoothValue;
-            if (speed >= ShmFanModuleData->SetFan1Speed)
-                speed = ShmFanModuleData->SetFan1Speed;
-        }
-        else
-        {
-            speed = ShmFanModuleData->PresentFan1Speed - fanSpeedSmoothValue;
-            if (speed <= 0)
-                speed = ShmFanModuleData->SetFan1Speed;
-        }
-
-        _fanSpeed.speed[0] = speed & 0xff;
-        _fanSpeed.speed[1] = (speed >> 8) & 0xff;
-        ShmFanModuleData->PresentFan1Speed = speed;
-
-        Config_Fan_Speed(Uart5Fd, Addr.Relay, &_fanSpeed);
+        _fanSpeed.speed[0] = _setFanSpeed;
     }
     }
-}
 
 
-void GetRelayModuleFanSpeed()
-{
-    PRINTF_FUNC("Get fan board speed \n");
-    if (Query_Fan_Speed(Uart5Fd, Addr.Relay, &fanSpeed) == PASS)
+    _fanSpeed.speed[1] = _setFanSpeed;
+    _fanSpeed.speed[2] = _setFanSpeed;
+    _fanSpeed.speed[3] = _setFanSpeed;
+    if (Config_Fan_Speed(Uart5Fd, Addr.Fan, &_fanSpeed) == PASS)
     {
     {
-        ShmFanModuleData->PresentFan1Speed = fanSpeed.speed[0] + (fanSpeed.speed[1] >> 8);
-        PRINTF_FUNC("SystemFanRotaSpeed_1 = %d \n", fanSpeed.speed[0]);
+        //PRINTF_FUNC("successfully Fan\n");
     }
     }
 }
 }
 
 
@@ -735,7 +780,7 @@ void SetK1K2RelayStatus(byte index)
             else if (regRelay.relay_event.bits.Gun1_N == YES)
             else if (regRelay.relay_event.bits.Gun1_N == YES)
                 outputRelay.relay_event.bits.Gun1_N = NO;
                 outputRelay.relay_event.bits.Gun1_N = NO;
 
 
-            if (_chargingData[index]->Type == _Type_CCS_2)
+            if (gunCount == 1 && _chargingData[index]->Type == _Type_CCS_2)
             {
             {
                 if(regRelay.relay_event.bits.CCS_Precharge == YES)
                 if(regRelay.relay_event.bits.CCS_Precharge == YES)
                     outputRelay.relay_event.bits.CCS_Precharge = NO;
                     outputRelay.relay_event.bits.CCS_Precharge = NO;
@@ -759,24 +804,25 @@ void SetK1K2RelayStatus(byte index)
             _chargingData[index]->SystemStatus <= S_CHARGING))
             _chargingData[index]->SystemStatus <= S_CHARGING))
     {
     {
         if (_chargingData[index]->RelayWeldingCheck == YES)
         if (_chargingData[index]->RelayWeldingCheck == YES)
-    {
-        if (_chargingData[index]->Evboard_id == 0x01)
-        {
-            if(regRelay.relay_event.bits.Gun1_N == NO)
-                outputRelay.relay_event.bits.Gun1_N = YES;
-            else if (regRelay.relay_event.bits.Gun1_P == NO)
-                outputRelay.relay_event.bits.Gun1_P = YES;
-        }
-        else if (_chargingData[index]->Evboard_id == 0x02)
         {
         {
-            if(regRelay.relay_event.bits.Gun2_N == NO)
-                outputRelay.relay_event.bits.Gun2_N = YES;
-            else if (regRelay.relay_event.bits.Gun2_P == NO)
-                outputRelay.relay_event.bits.Gun2_P = YES;
+            if (_chargingData[index]->Evboard_id == 0x01)
+            {
+                if(regRelay.relay_event.bits.Gun1_N == NO)
+                    outputRelay.relay_event.bits.Gun1_N = YES;
+                else if (regRelay.relay_event.bits.Gun1_P == NO)
+                    outputRelay.relay_event.bits.Gun1_P = YES;
+            }
+            else if (_chargingData[index]->Evboard_id == 0x02)
+            {
+                if(regRelay.relay_event.bits.Gun2_N == NO)
+                    outputRelay.relay_event.bits.Gun2_N = YES;
+                else if (regRelay.relay_event.bits.Gun2_P == NO)
+                    outputRelay.relay_event.bits.Gun2_P = YES;
+            }
         }
         }
     }
     }
-    }
-    else if ((_chargingData[index]->SystemStatus >= S_TERMINATING && _chargingData[index]->SystemStatus <= S_COMPLETE))
+    else if ((_chargingData[index]->SystemStatus >= S_TERMINATING &&
+            _chargingData[index]->SystemStatus <= S_COMPLETE))
     {
     {
         if ((_chargingData[index]->PresentChargingCurrent * 10) <= SEFETY_SWITCH_RELAY_CUR)
         if ((_chargingData[index]->PresentChargingCurrent * 10) <= SEFETY_SWITCH_RELAY_CUR)
         {
         {
@@ -802,10 +848,13 @@ void SetK1K2RelayStatus(byte index)
         {
         {
             if (_chargingData[index]->Type == _Type_CCS_2)
             if (_chargingData[index]->Type == _Type_CCS_2)
             {
             {
-                if (regRelay.relay_event.bits.CCS_Precharge == NO)
-                    outputRelay.relay_event.bits.CCS_Precharge = YES;
-                else if (regRelay.relay_event.bits.CCS_Precharge == YES)
-                    outputRelay.relay_event.bits.Gun1_P = NO;
+                if (gunCount == 1)
+                {
+                    if (regRelay.relay_event.bits.CCS_Precharge == NO)
+                        outputRelay.relay_event.bits.CCS_Precharge = YES;
+                    else if (regRelay.relay_event.bits.CCS_Precharge == YES)
+                        outputRelay.relay_event.bits.Gun1_P = NO;
+                }
             }
             }
         }
         }
         else if (_chargingData[index]->Evboard_id == 0x02)
         else if (_chargingData[index]->Evboard_id == 0x02)
@@ -825,10 +874,13 @@ void SetK1K2RelayStatus(byte index)
         {
         {
             if (_chargingData[index]->Type == _Type_CCS_2)
             if (_chargingData[index]->Type == _Type_CCS_2)
             {
             {
-                if (regRelay.relay_event.bits.Gun1_P == NO)
-                    outputRelay.relay_event.bits.Gun1_P = YES;
-                else if(regRelay.relay_event.bits.Gun1_P == YES)
-                    outputRelay.relay_event.bits.CCS_Precharge = NO;
+                if (gunCount == 1)
+                {
+                    if (regRelay.relay_event.bits.Gun1_P == NO)
+                        outputRelay.relay_event.bits.Gun1_P = YES;
+                    else if(regRelay.relay_event.bits.Gun1_P == YES)
+                        outputRelay.relay_event.bits.CCS_Precharge = NO;
+                }
             }
             }
         }
         }
         else if (_chargingData[index]->Evboard_id == 0x02)
         else if (_chargingData[index]->Evboard_id == 0x02)
@@ -847,8 +899,8 @@ void SetK1K2RelayStatus(byte index)
 void CheckAcInputOvpStatus(byte index)
 void CheckAcInputOvpStatus(byte index)
 {
 {
     if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP == YES ||
     if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP == YES ||
-            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP == YES ||
-            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP == YES)
+        ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP == YES ||
+        ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP == YES)
     {
     {
         _chargingData[index]->StopChargeFlag = YES;
         _chargingData[index]->StopChargeFlag = YES;
     }
     }
@@ -857,8 +909,8 @@ void CheckAcInputOvpStatus(byte index)
 void CheckPhaseLossStatus(byte index)
 void CheckPhaseLossStatus(byte index)
 {
 {
     if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP == YES ||
     if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP == YES ||
-            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP == YES ||
-            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP == YES)
+        ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP == YES ||
+        ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP == YES)
     {
     {
         _chargingData[index]->StopChargeFlag = YES;
         _chargingData[index]->StopChargeFlag = YES;
     }
     }
@@ -869,7 +921,7 @@ void SetParalleRelayStatus()
     if (gunCount >= 2 && ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == NO)
     if (gunCount >= 2 && ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == NO)
     {
     {
         if (_chargingData[0]->SystemStatus == S_BOOTING || _chargingData[1]->SystemStatus == S_BOOTING ||
         if (_chargingData[0]->SystemStatus == S_BOOTING || _chargingData[1]->SystemStatus == S_BOOTING ||
-                (_chargingData[0]->SystemStatus == S_IDLE && _chargingData[1]->SystemStatus == S_IDLE))
+            (_chargingData[0]->SystemStatus == S_IDLE && _chargingData[1]->SystemStatus == S_IDLE))
         {
         {
             // 初始化~ 不搭橋接
             // 初始化~ 不搭橋接
             if (regRelay.relay_event.bits.Gun1_Parallel_P == YES)
             if (regRelay.relay_event.bits.Gun1_Parallel_P == YES)
@@ -880,7 +932,7 @@ void SetParalleRelayStatus()
         else
         else
         {
         {
             if (_chargingData[0]->IsReadyToCharging == YES ||
             if (_chargingData[0]->IsReadyToCharging == YES ||
-                    _chargingData[1]->IsReadyToCharging == YES)
+                _chargingData[1]->IsReadyToCharging == YES)
             {
             {
                 // ************需考慮在切換中 - 切開 relay 與搭回 relay 的時機點************
                 // ************需考慮在切換中 - 切開 relay 與搭回 relay 的時機點************
                 if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
                 if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
@@ -926,6 +978,67 @@ void SetParalleRelayStatus()
     }
     }
 }
 }
 
 
+void CheckAlarmOccur()
+{
+    bool isErr = false;
+    for(byte count = 0; count < sizeof(_alarm_code)/sizeof(_alarm_code[0]); count++)
+    {
+        if (acAlarmCode.AcAlarmCode & _alarm_code[count])
+        {
+            isErr = true;
+            switch(_alarm_code[count])
+            {
+                case AC_OVP: ShmStatusCodeData->AlarmCode.AlarmEvents.bits.AcSystemInputOVP = YES; break;
+                case AC_UVP: ShmStatusCodeData->AlarmCode.AlarmEvents.bits.AcSystemInputUVP = YES; break;
+                case AC_OCP: ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP = YES; break;
+                case AC_OTP: ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAmbientOTP = YES; break;
+                case AC_GMI_FAULT: ShmStatusCodeData->AlarmCode.AlarmEvents.bits.AcGroundfaultFail = YES; break;
+                case AC_CP_ERROR: ShmStatusCodeData->InfoCode.InfoEvents.bits.PilotFault = YES; break;
+                case AC_AC_LEAKAGE: ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RcdTrip = YES; break;
+                case AC_DC_LEAKAGE: ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RcdTrip = YES; break;
+                case AC_SYSTEM_SELFTEST_FAULT: ShmStatusCodeData->AlarmCode.AlarmEvents.bits.McuSelftestFail = YES; break;
+                case AC_HANDSHAKE_TIMEOUT: break;
+                case AC_EMC_STOP: ShmStatusCodeData->AlarmCode.AlarmEvents.bits.EmergencyStopTrip = YES; break;
+                case AC_RELAY_WELDING: ShmStatusCodeData->FaultCode.FaultEvents.bits.AcOutputRelayWelding = YES; break;
+                case AC_GF_MODULE_FAULT: ShmStatusCodeData->FaultCode.FaultEvents.bits.RcdSelfTestFail = YES; break;
+                case AC_SHUTTER_FAULT: break;
+                case AC_LOCKER_FAULT: ShmStatusCodeData->FaultCode.FaultEvents.bits.AcConnectorLockFail = YES; break;
+                case AC_POWER_DROP: ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputDrop = YES; break;
+                case AC_CIRCUIT_SHORT: ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CircuitShort = YES; break;
+                case AC_ROTARY_SWITCH_FAULT: break;
+                case AC_RELAY_DRIVE_FAULT: ShmStatusCodeData->FaultCode.FaultEvents.bits.AcOutputRelayDrivingFault = YES; break;
+            }
+        }
+        else
+        {
+            switch(_alarm_code[count])
+            {
+                case AC_OVP: ShmStatusCodeData->AlarmCode.AlarmEvents.bits.AcSystemInputOVP = NO; break;
+                case AC_UVP: ShmStatusCodeData->AlarmCode.AlarmEvents.bits.AcSystemInputUVP = NO; break;
+                case AC_OCP: ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAcOutputOCP = NO; break;
+                case AC_OTP: ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemAmbientOTP = NO; break;
+                case AC_GMI_FAULT: ShmStatusCodeData->AlarmCode.AlarmEvents.bits.AcGroundfaultFail = NO; break;
+                case AC_CP_ERROR: ShmStatusCodeData->InfoCode.InfoEvents.bits.PilotFault = NO; break;
+                case AC_AC_LEAKAGE: ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RcdTrip = NO; break;
+                case AC_DC_LEAKAGE: ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RcdTrip = NO; break;
+                case AC_SYSTEM_SELFTEST_FAULT: ShmStatusCodeData->AlarmCode.AlarmEvents.bits.McuSelftestFail = NO; break;
+                case AC_HANDSHAKE_TIMEOUT: break;
+                case AC_EMC_STOP: ShmStatusCodeData->AlarmCode.AlarmEvents.bits.EmergencyStopTrip = NO; break;
+                case AC_RELAY_WELDING: ShmStatusCodeData->FaultCode.FaultEvents.bits.AcOutputRelayWelding = NO; break;
+                case AC_GF_MODULE_FAULT: ShmStatusCodeData->FaultCode.FaultEvents.bits.RcdSelfTestFail = NO; break;
+                case AC_SHUTTER_FAULT: break;
+                case AC_LOCKER_FAULT: ShmStatusCodeData->FaultCode.FaultEvents.bits.AcConnectorLockFail = NO; break;
+                case AC_POWER_DROP: ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputDrop = NO; break;
+                case AC_CIRCUIT_SHORT: ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CircuitShort = NO; break;
+                case AC_ROTARY_SWITCH_FAULT:  break;
+                case AC_RELAY_DRIVE_FAULT: ShmStatusCodeData->FaultCode.FaultEvents.bits.AcOutputRelayDrivingFault = NO; break;
+            }
+        }
+    }
+
+    ac_chargingInfo[0]->IsErrorOccur = isErr;
+}
+
 //==========================================
 //==========================================
 // Init all share memory
 // Init all share memory
 //==========================================
 //==========================================
@@ -1120,6 +1233,17 @@ bool FindChargingInfoData(byte target, struct ChargingInfoData **chargingData)
     return false;
     return false;
 }
 }
 
 
+bool FindAcChargingInfoData(byte target, struct ChargingInfoData **acChargingData)
+{
+    if (target < AC_QUANTITY)
+    {
+        acChargingData[target] = &ShmSysConfigAndInfo->SysInfo.AcChargingData[target];
+        return true;
+    }
+
+    return false;
+}
+
 void Initialization()
 void Initialization()
 {
 {
     bool isPass = false;
     bool isPass = false;
@@ -1142,6 +1266,25 @@ void Initialization()
             }
             }
         }
         }
     }
     }
+
+    isPass = false;
+
+    if (acgunCount > 0)
+    {
+        while(!isPass)
+        {
+            isPass = true;
+            for (byte _index = 0; _index < acgunCount; _index++)
+            {
+                if (!FindAcChargingInfoData(_index, &ac_chargingInfo[0]))
+                {
+                    DEBUG_ERROR("EvComm : FindAcChargingInfoData false \n");
+                    isPass = false;
+                    break;
+                }
+            }
+        }
+    }
 }
 }
 
 
 bool IsNoneMatchRelayStatus()
 bool IsNoneMatchRelayStatus()
@@ -1197,7 +1340,7 @@ void MatchRelayStatus()
 void CheckRelayStatusByADC()
 void CheckRelayStatusByADC()
 {
 {
     if (ShmRelayModuleData->Gun1FuseOutputVolt > 0 && ShmRelayModuleData->Gun1RelayOutputVolt > 0 &&
     if (ShmRelayModuleData->Gun1FuseOutputVolt > 0 && ShmRelayModuleData->Gun1RelayOutputVolt > 0 &&
-            (ShmRelayModuleData->Gun1FuseOutputVolt == ShmRelayModuleData->Gun1RelayOutputVolt))
+        (ShmRelayModuleData->Gun1FuseOutputVolt == ShmRelayModuleData->Gun1RelayOutputVolt))
     {
     {
         // Relay 前後電壓一致
         // Relay 前後電壓一致
         _chargingData[0]->RelayK1K2Status = 0x01;
         _chargingData[0]->RelayK1K2Status = 0x01;
@@ -1206,7 +1349,7 @@ void CheckRelayStatusByADC()
         _chargingData[0]->RelayK1K2Status = 0x00;
         _chargingData[0]->RelayK1K2Status = 0x00;
 
 
     if (ShmRelayModuleData->Gun2FuseOutputVolt > 0 && ShmRelayModuleData->Gun2RelayOutputVolt > 0 &&
     if (ShmRelayModuleData->Gun2FuseOutputVolt > 0 && ShmRelayModuleData->Gun2RelayOutputVolt > 0 &&
-                (ShmRelayModuleData->Gun2FuseOutputVolt == ShmRelayModuleData->Gun2RelayOutputVolt))
+        (ShmRelayModuleData->Gun2FuseOutputVolt == ShmRelayModuleData->Gun2RelayOutputVolt))
     {
     {
         // Relay 前後電壓一致
         // Relay 前後電壓一致
         _chargingData[1]->RelayK1K2Status = 0x01;
         _chargingData[1]->RelayK1K2Status = 0x01;
@@ -1238,13 +1381,14 @@ void CableCheckDetected(byte index)
     // Warning : Rgfd <= 150 歐/V 假設電壓為 500V 則~ Rgfd <= 75000 歐
     // Warning : Rgfd <= 150 歐/V 假設電壓為 500V 則~ Rgfd <= 75000 歐
     // Pre-Warning : 150 歐/V < Rgfd <= 500 歐/V 假設電壓為 500V 則 75000 歐 < Rgfd <= 250000
     // Pre-Warning : 150 歐/V < Rgfd <= 500 歐/V 假設電壓為 500V 則 75000 歐 < Rgfd <= 250000
     // SO Normal : Rgfd > 500 歐/V 假設電壓為 500 V 則 Rgfd > 250000 歐
     // SO Normal : Rgfd > 500 歐/V 假設電壓為 500 V 則 Rgfd > 250000 歐
-    if (_chargingData[index]->Type >= _Type_Chademo && _chargingData[index]->Type <= _Type_GB)
+    if ((_chargingData[index]->Type >= _Type_Chademo && _chargingData[index]->Type <= _Type_GB) ||
+        (_chargingData[index]->Type == 0x09 && ShmSysConfigAndInfo->SysConfig.AlwaysGfdFlag))
     {
     {
         if ((_chargingData[index]->SystemStatus >= S_PREPARING_FOR_EVSE && _chargingData[index]->SystemStatus <= S_CHARGING) ||
         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))
             (_chargingData[index]->SystemStatus >= S_CCS_PRECHARGE_ST0 && _chargingData[index]->SystemStatus <= S_CCS_PRECHARGE_ST1))
         {
         {
             if (_chargingData[index]->SystemStatus == S_PREPARING_FOR_EVSE &&
             if (_chargingData[index]->SystemStatus == S_PREPARING_FOR_EVSE &&
-                    _chargingData[index]->RelayWeldingCheck == YES)
+                _chargingData[index]->RelayWeldingCheck == YES)
             {
             {
                 SetGfdConfig(index, GFD_CABLECHK);
                 SetGfdConfig(index, GFD_CABLECHK);
             }
             }
@@ -1258,7 +1402,7 @@ void CableCheckDetected(byte index)
                 if (_chargingData[index]->Type == _Type_GB)
                 if (_chargingData[index]->Type == _Type_GB)
                     SetGfdConfig(index, GFD_IDLE);
                     SetGfdConfig(index, GFD_IDLE);
                 else
                 else
-                SetGfdConfig(index, GFD_CHARGING);
+                    SetGfdConfig(index, GFD_CHARGING);
             }
             }
         }
         }
         else if(_chargingData[index]->SystemStatus == S_COMPLETE || _chargingData[index]->SystemStatus == S_PREPARNING
         else if(_chargingData[index]->SystemStatus == S_COMPLETE || _chargingData[index]->SystemStatus == S_PREPARNING
@@ -1275,9 +1419,9 @@ void CheckOutputPowerOverCarReq(byte index)
     float carV = _chargingData[index]->EvBatterytargetVoltage;
     float carV = _chargingData[index]->EvBatterytargetVoltage;
 
 
     if (_chargingData[index]->EvBatterytargetVoltage > 1500 &&
     if (_chargingData[index]->EvBatterytargetVoltage > 1500 &&
-            (_chargingData[index]->Type == _Type_Chademo ||
-                _chargingData[index]->Type == _Type_CCS_2 ||
-                _chargingData[index]->Type == _Type_GB))
+        (_chargingData[index]->Type == _Type_Chademo ||
+         _chargingData[index]->Type == _Type_CCS_2 ||
+         _chargingData[index]->Type == _Type_GB))
     {
     {
         if (fireV >= (carV + (carV * 0.1)))
         if (fireV >= (carV + (carV * 0.1)))
         {
         {
@@ -1293,12 +1437,12 @@ void CheckOutputPowerOverCarReq(byte index)
 void CheckOutputVolNoneMatchFire(byte index)
 void CheckOutputVolNoneMatchFire(byte index)
 {
 {
     if (_chargingData[index]->EvBatterytargetVoltage > 1500 &&
     if (_chargingData[index]->EvBatterytargetVoltage > 1500 &&
-            (_chargingData[index]->Type == _Type_Chademo ||
-                    _chargingData[index]->Type == _Type_CCS_2 ||
-                    _chargingData[index]->Type == _Type_GB))
+        (_chargingData[index]->Type == _Type_Chademo ||
+         _chargingData[index]->Type == _Type_CCS_2 ||
+         _chargingData[index]->Type == _Type_GB))
     {
     {
         if (((_chargingData[index]->PresentChargingVoltage * 10) < _chargingData[index]->FireChargingVoltage - 300) ||
         if (((_chargingData[index]->PresentChargingVoltage * 10) < _chargingData[index]->FireChargingVoltage - 300) ||
-                ((_chargingData[index]->PresentChargingVoltage * 10) > _chargingData[index]->FireChargingVoltage + 300))
+            ((_chargingData[index]->PresentChargingVoltage * 10) > _chargingData[index]->FireChargingVoltage + 300))
         {
         {
             if (!_isOutputNoneMatch[index])
             if (!_isOutputNoneMatch[index])
             {
             {
@@ -1384,6 +1528,228 @@ void GetPsuTempForFanSpeed()
     }
     }
 }
 }
 
 
+void GetAcStatus()
+{
+    if (Query_AC_Status(Uart5Fd, Addr.AcPlug, &acStatus) == PASS)
+    {
+        ShmSysConfigAndInfo->SysConfig.AcRatingCurrent = acStatus.MaxCurrent;
+
+        if(ShmSysConfigAndInfo->SysConfig.AcMaxChargingCurrent == 0)
+            ShmSysConfigAndInfo->SysConfig.AcMaxChargingCurrent = ShmSysConfigAndInfo->SysConfig.AcRatingCurrent;
+
+    //              printf("CpStatus = %d \n", acStatus.CpStatus);
+    //              printf("CurLimit = %d \n", acStatus.CurLimit);
+    //              printf("PilotVol_P = %d \n", acStatus.PilotVol_P);
+    //              printf("PilotVol_N = %d \n", acStatus.PilotVol_N);
+    //              printf("LockStatus = %d \n", acStatus.LockStatus);
+    //              printf("RelayStatus = %d \n", acStatus.RelayStatus);
+    //              printf("ShutterStatus = %d \n", acStatus.ShutterStatus);
+    //              printf("MeterStatus = %d \n", acStatus.MeterStatus);
+    //              printf("PpStatus = %d \n", acStatus.PpStatus);
+    //              printf("MaxCurrent = %d \n", acStatus.MaxCurrent);
+    //              printf("RotateSwitchStatus = %d \n", acStatus.RelayStatus);
+    //              printf("============================== \n");
+    //
+    //              ac_chargingInfo[0]->SystemStatus = acStatus.CpStatus;
+    }
+}
+
+void GetAcAlarmCode()
+{
+    if (Query_AC_Alarm_Code(Uart5Fd, Addr.AcPlug, &acAlarmCode) == PASS)
+    {
+        CheckAlarmOccur();
+    }
+}
+
+unsigned char GetChargingEnergy()
+{
+    return Query_Charging_Energy(Uart5Fd, Addr.AcPlug, &acChargingEnergy);
+}
+
+unsigned char GetChargingCurrent()
+{
+    return Query_Charging_Current(Uart5Fd, Addr.AcPlug, &acChargingCurrent);
+}
+
+void ChangeLedStatus()
+{
+    if (ac_chargingInfo[0]->SystemStatus == S_IDLE)
+        ledStatus.ActionMode = 1;
+    else if (ac_chargingInfo[0]->SystemStatus == S_PREPARNING)
+        ledStatus.ActionMode = 3;
+    else if (ac_chargingInfo[0]->SystemStatus == S_CHARGING)
+        ledStatus.ActionMode = 4;
+
+    Config_LED_Status(Uart5Fd, Addr.AcPlug, &ledStatus);
+}
+
+void SetLegacyReq(byte _switch)
+{
+    Config_Legacy_Req(Uart5Fd, Addr.AcPlug, _switch);
+}
+
+void SetCpDuty(byte _value)
+{
+    Config_Ac_Duty(Uart5Fd, Addr.AcPlug, _value);
+}
+
+void ChangeToCsuMode()
+{
+    ac_chargingInfo[0]->IsModeChagned = Config_CSU_Mode(Uart5Fd, Addr.AcPlug);
+
+//  if (ac_chargingInfo[0]->IsModeChagned == PASS)
+//  {
+//      Config_Reset_MCU(Uart5Fd, Addr.AcPlug);
+//  }
+}
+
+void AcChargeTypeProcess()
+{
+    if (acgunCount > 0)
+    {
+        if (ac_chargingInfo[0]->SelfTest_Comp == NO)
+        {
+            ac_chargingInfo[0]->IsModeChagned = NO;
+            GetFwVersion_AC();
+        }
+        else if (ac_chargingInfo[0]->SelfTest_Comp == YES)
+        {
+            if (ac_chargingInfo[0]->IsModeChagned != PASS)
+            {
+                ChangeToCsuMode();
+                return;
+            }
+            GetAcStatus();
+            GetAcAlarmCode();
+
+            byte _status = S_NONE;
+            bool _isStatusChanged = false;
+
+            if (acStatus.CpStatus == AC_SYS_A || ac_chargingInfo[0]->IsErrorOccur)
+            {
+                if (ac_chargingInfo[0]->SystemStatus == S_CHARGING)
+                    _status = S_TERMINATING;
+                else if (ac_chargingInfo[0]->SystemStatus >= S_TERMINATING)
+                {
+                    if (GetTimeoutValue(_ac_charging_comp) >= 10000000)
+                        _status = S_IDLE;
+                }
+                else
+                    _status = S_IDLE;
+            }
+            else if (ac_chargingInfo[0]->SystemStatus >= S_PREPARNING &&
+                    ac_chargingInfo[0]->SystemStatus < S_CHARGING)
+            {
+                if (acStatus.CpStatus == AC_SYS_C && acStatus.RelayStatus == YES)
+                    _status = S_CHARGING;
+                else if (GetTimeoutValue(_ac_preparing) >= 30000000)
+                    _status = S_IDLE;
+            }
+            else if (acStatus.CpStatus == AC_SYS_B &&
+                     ac_chargingInfo[0]->IsAvailable &&
+                     !ac_chargingInfo[0]->IsErrorOccur &&
+                     (ShmSysConfigAndInfo->SysInfo.WaitForPlugit == YES ||
+                      ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE))
+            {
+                PRINTF_FUNC("** UserId = %s \n", ShmSysConfigAndInfo->SysConfig.UserId);
+                strcpy((char *)ac_chargingInfo[0]->StartUserId, (char *)ShmSysConfigAndInfo->SysConfig.UserId);
+                PRINTF_FUNC("** CardNumber = %s \n", ac_chargingInfo[0]->StartUserId);
+                strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, "");
+                ShmSysConfigAndInfo->SysInfo.WaitForPlugit = NO;
+                _status = S_PREPARNING;
+            }
+
+            //printf("_status = %d \n", _status);
+
+            if (_status != S_NONE && ac_chargingInfo[0]->SystemStatus != _status)
+            {
+                _isStatusChanged = true;
+                ac_chargingInfo[0]->SystemStatus = _status;
+            }
+
+            // 設定限制最大充電電流 >= 6 ~ <= 32
+            switch(ac_chargingInfo[0]->SystemStatus)
+            {
+                case S_IDLE:
+                {
+                    if (_isStatusChanged)
+                    {
+                        ac_chargingInfo[0]->PresentChargedEnergy = 0.0;
+                    }
+
+                    ChangeLedStatus();
+                }
+                    break;
+                case S_PREPARNING:
+                {
+                    if (_isStatusChanged)
+                    {
+                        ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE;
+                        ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = DEFAULT_AC_INDEX;
+                        gettimeofday(&_ac_preparing, NULL);
+                    }
+
+                    if (GetChargingEnergy() == PASS)
+                    {
+                        ac_chargingInfo[0]->PresentChargedEnergy = acChargingEnergy.Energy / 100;
+                    }
+
+                    SetLegacyReq(YES);
+                    ChangeLedStatus();
+                }
+                    break;
+                case S_CHARGING:
+                {
+                    if (_isStatusChanged)
+                    {
+                        ftime(&_ac_startChargingTime);
+                        ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = DEFAULT_AC_INDEX;
+                    }
+
+                    if (GetChargingEnergy() == PASS)
+                        ac_chargingInfo[0]->PresentChargedEnergy = acChargingEnergy.Energy / 100;
+
+                    if (GetChargingCurrent() == PASS)
+                        ac_chargingInfo[0]->PresentChargingPower = (220 * (acChargingCurrent.OuputCurrentL1 / 10)) / 1000;
+
+                    ftime(&_ac_endChargingTime);
+                    ac_chargingInfo[0]->RemainChargingDuration = DiffTimeb(_ac_startChargingTime, _ac_endChargingTime);
+
+                    // 用以判斷是否有在輸出
+                    ac_chargingInfo[0]->IsCharging = acStatus.RelayStatus;
+
+                    SetCpDuty(ShmSysConfigAndInfo->SysConfig.AcMaxChargingCurrent);
+                    ChangeLedStatus();
+                }
+                    break;
+                case S_TERMINATING:
+                {
+                    if (_isStatusChanged)
+                    {
+                        gettimeofday(&_ac_charging_comp, NULL);
+                    }
+
+                    SetLegacyReq(NO);
+                    if (acStatus.RelayStatus == NO)
+                        ac_chargingInfo[0]->SystemStatus = S_COMPLETE;
+                }
+                    break;
+                case S_COMPLETE:
+                {
+                    if (_isStatusChanged)
+                    {
+                        gettimeofday(&_ac_charging_comp, NULL);
+                        ftime(&_ac_endChargingTime);
+                        ac_chargingInfo[0]->RemainChargingDuration = DiffTimeb(_ac_startChargingTime, _ac_endChargingTime);
+                    }
+                }
+                    break;
+            }
+        }
+    }
+}
+
 int main(void)
 int main(void)
 {
 {
     if(InitShareMemory() == FAIL)
     if(InitShareMemory() == FAIL)
@@ -1400,6 +1766,7 @@ int main(void)
     }
     }
 
 
     gunCount = ShmSysConfigAndInfo->SysConfig.TotalConnectorCount;
     gunCount = ShmSysConfigAndInfo->SysConfig.TotalConnectorCount;
+    acgunCount = ShmSysConfigAndInfo->SysConfig.AcConnectorCount;
     // Open Uart5 for RB
     // Open Uart5 for RB
     Uart5Fd = InitComPort();
     Uart5Fd = InitComPort();
     Initialization();
     Initialization();
@@ -1442,6 +1809,8 @@ int main(void)
             gettimeofday(&_priority_time, NULL);
             gettimeofday(&_priority_time, NULL);
         }
         }
 
 
+        AcChargeTypeProcess();
+
         if (ShmRelayModuleData->SelfTest_Comp == YES)
         if (ShmRelayModuleData->SelfTest_Comp == YES)
         {
         {
             // ==============優先權最高 10 ms ==============
             // ==============優先權最高 10 ms ==============
@@ -1451,7 +1820,8 @@ int main(void)
             // 三相輸入電壓
             // 三相輸入電壓
             GetPresentInputVol();
             GetPresentInputVol();
 
 
-            // 讀取當前 relay 狀態
+            // 讀取當前 AC relay 狀態
+            regRelay.relay_event.bits.AC_Contactor = ShmSysConfigAndInfo->SysInfo.AcContactorStatus;
             //GetRelayOutputStatus();
             //GetRelayOutputStatus();
 
 
             for (int i = 0; i < gunCount; i++)
             for (int i = 0; i < gunCount; i++)
@@ -1477,8 +1847,9 @@ int main(void)
                 }
                 }
 
 
                 if (_chargingData[i]->SystemStatus == S_BOOTING ||
                 if (_chargingData[i]->SystemStatus == S_BOOTING ||
-                    (_chargingData[i]->SystemStatus >= S_PREPARNING && _chargingData[i]->SystemStatus <= S_COMPLETE) ||
+                    (_chargingData[i]->SystemStatus >= S_REASSIGN_CHECK && _chargingData[i]->SystemStatus <= S_COMPLETE) ||
                     (_chargingData[i]->SystemStatus >= S_CCS_PRECHARGE_ST0 && _chargingData[i]->SystemStatus <= S_CCS_PRECHARGE_ST1) ||
                     (_chargingData[i]->SystemStatus >= S_CCS_PRECHARGE_ST0 && _chargingData[i]->SystemStatus <= S_CCS_PRECHARGE_ST1) ||
+                    ShmSysConfigAndInfo->SysInfo.WaitForPlugit == YES ||
                     (ShmSysConfigAndInfo->SysInfo.PageIndex >= _LCM_AUTHORIZING && ShmSysConfigAndInfo->SysInfo.PageIndex <= _LCM_WAIT_FOR_PLUG))
                     (ShmSysConfigAndInfo->SysInfo.PageIndex >= _LCM_AUTHORIZING && ShmSysConfigAndInfo->SysInfo.PageIndex <= _LCM_WAIT_FOR_PLUG))
                 {
                 {
                     _chargingData[i]->IsReadyToCharging = YES;
                     _chargingData[i]->IsReadyToCharging = YES;
@@ -1511,12 +1882,6 @@ int main(void)
             // 橋接 relay
             // 橋接 relay
             SetParalleRelayStatus();
             SetParalleRelayStatus();
 
 
-            // 搭上 AC Contactor
-            if (isCharging)
-                outputRelay.relay_event.bits.AC_Contactor = YES;
-            else
-                outputRelay.relay_event.bits.AC_Contactor = NO;
-
             if (isCharging)
             if (isCharging)
             {
             {
                 isStopChargingCount = false;
                 isStopChargingCount = false;
@@ -1531,8 +1896,7 @@ int main(void)
                 }
                 }
                 else
                 else
                 {
                 {
-                    if (!isSystemBooting ||
-                        (outputRelay.relay_event.bits.AC_Contactor == YES && GetTimeoutValue(_close_ac_contactor) / 1000 >= (TEN_MINUTES * 1000)))
+                    if ((outputRelay.relay_event.bits.AC_Contactor == YES && GetTimeoutValue(_close_ac_contactor) / 1000 >= (TEN_MINUTES * 1000)))
                         outputRelay.relay_event.bits.AC_Contactor = NO;
                         outputRelay.relay_event.bits.AC_Contactor = NO;
                 }
                 }
             }
             }
@@ -1541,8 +1905,7 @@ int main(void)
             if(IsNoneMatchRelayStatus())
             if(IsNoneMatchRelayStatus())
             {
             {
                 if (Config_Relay_Output(Uart5Fd, Addr.Relay, &outputRelay))
                 if (Config_Relay_Output(Uart5Fd, Addr.Relay, &outputRelay))
-            {
-                    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.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_P = outputRelay.relay_event.bits.Gun1_P;
                     regRelay.relay_event.bits.Gun1_N = outputRelay.relay_event.bits.Gun1_N;
                     regRelay.relay_event.bits.Gun1_N = outputRelay.relay_event.bits.Gun1_N;
@@ -1571,19 +1934,16 @@ int main(void)
                 GetPsuTempForFanSpeed();
                 GetPsuTempForFanSpeed();
 
 
                 GetFanSpeed();
                 GetFanSpeed();
+                ShmSysConfigAndInfo->SysInfo.SystemFanRotaSpeed = _setFanSpeed;
+
                 gettimeofday(&_priority_time, NULL);
                 gettimeofday(&_priority_time, NULL);
                 if (isCharging)
                 if (isCharging)
                 {
                 {
-                    if (ShmFanModuleData->PresentFan1Speed < MAX_FAN_SPEED ||
-                        ShmFanModuleData->PresentFan2Speed < MAX_FAN_SPEED ||
-                        ShmFanModuleData->PresentFan3Speed < MAX_FAN_SPEED ||
-                        ShmFanModuleData->PresentFan4Speed < MAX_FAN_SPEED)
-                    {
-                        ShmFanModuleData->SetFan1Speed = MAX_FAN_SPEED;
-                        ShmFanModuleData->SetFan2Speed = MAX_FAN_SPEED;
-                        ShmFanModuleData->SetFan3Speed = MAX_FAN_SPEED;
-                        ShmFanModuleData->SetFan4Speed = MAX_FAN_SPEED;
-                    }
+                    // 在還沒問到 PSU 溫度~ 還是要有個最小轉速
+                    ShmFanModuleData->SetFan1Speed = MIN_FAN_SPEED;
+                    ShmFanModuleData->SetFan2Speed = MIN_FAN_SPEED;
+                    ShmFanModuleData->SetFan3Speed = MIN_FAN_SPEED;
+                    ShmFanModuleData->SetFan4Speed = MIN_FAN_SPEED;
 
 
                     if (ShmFanModuleData->TestFanSpeed > 0)
                     if (ShmFanModuleData->TestFanSpeed > 0)
                     {
                     {
@@ -1595,16 +1955,10 @@ int main(void)
                 }
                 }
                 else
                 else
                 {
                 {
-                    if (ShmFanModuleData->PresentFan1Speed > MIN_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;
-                    }
+                    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)
                     if (ShmFanModuleData->TestFanSpeed >= MAX_FAN_SPEED)

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

@@ -471,6 +471,81 @@ bool FindChargingInfoData(byte target, struct ChargingInfoData **_chargingData)
     return false;
     return false;
 }
 }
 
 
+bool FindAcChargingInfoData(byte target, struct ChargingInfoData **acChargingData)
+{
+    if (target < AC_QUANTITY)
+    {
+        acChargingData[target] = &ShmSysConfigAndInfo->SysInfo.AcChargingData[target];
+        return true;
+    }
+
+    return false;
+}
+
+void ChangeAcBattMapAndValue(short page)
+{
+    if (page == _LCM_CHARGING)
+    {
+        if (isDiffStatus != _battery_display_ani)
+        {
+            isChangeBattMap = false;
+            isDiffStatus = _battery_display_ani;
+        }
+
+        if (ac_chargingInfo[0]->IsCharging && !isChangeBattMap)
+        {
+            isChangeBattMap = true;
+            if (ac_ani_battery_level == _BATTERY_LEVEL_FOR_MAP_LV5)
+            {
+                ChangeDisplay2Value(__batt_map, _battery_empty);
+                ac_ani_battery_level = _BATTERY_LEVEL_FOR_MAP_EMP;
+            }
+            else if (ac_ani_battery_level == _BATTERY_LEVEL_FOR_MAP_EMP)
+            {
+                ChangeDisplay2Value(__batt_map, _battery_cap_20);
+                ac_ani_battery_level = _BATTERY_LEVEL_FOR_MAP_LV1;
+            }
+            else if (ac_ani_battery_level == _BATTERY_LEVEL_FOR_MAP_LV1)
+            {
+                ChangeDisplay2Value(__batt_map, _battery_cap_40);
+                ac_ani_battery_level = _BATTERY_LEVEL_FOR_MAP_LV2;
+            }
+            else if (ac_ani_battery_level == _BATTERY_LEVEL_FOR_MAP_LV2)
+            {
+                ChangeDisplay2Value(__batt_map, _battery_cap_60);
+                ac_ani_battery_level = _BATTERY_LEVEL_FOR_MAP_LV3;
+            }
+            else if (ac_ani_battery_level == _BATTERY_LEVEL_FOR_MAP_LV3)
+            {
+                ChangeDisplay2Value(__batt_map, _battery_cap_80);
+                ac_ani_battery_level = _BATTERY_LEVEL_FOR_MAP_LV4;
+            }
+            else if (ac_ani_battery_level == _BATTERY_LEVEL_FOR_MAP_LV4)
+            {
+                ChangeDisplay2Value(__batt_map, _battery_cap_100);
+                ac_ani_battery_level = _BATTERY_LEVEL_FOR_MAP_LV5;
+            }
+        }
+    }
+    else if (page == _LCM_COMPLETE)
+    {
+        if (ac_ani_battery_level == _BATTERY_LEVEL_FOR_MAP_LV5)
+            ChangeDisplay2Value(__batt_map, _battery_soc_20);
+        else if (ac_ani_battery_level == _BATTERY_LEVEL_FOR_MAP_EMP)
+            ChangeDisplay2Value(__batt_map, _battery_soc_20);
+        else if (ac_ani_battery_level == _BATTERY_LEVEL_FOR_MAP_LV1)
+            ChangeDisplay2Value(__batt_map, _battery_soc_40);
+        else if (ac_ani_battery_level == _BATTERY_LEVEL_FOR_MAP_LV2)
+            ChangeDisplay2Value(__batt_map, _battery_soc_60);
+        else if (ac_ani_battery_level == _BATTERY_LEVEL_FOR_MAP_LV3)
+            ChangeDisplay2Value(__batt_map, _battery_soc_80);
+        else if (ac_ani_battery_level == _BATTERY_LEVEL_FOR_MAP_LV4)
+            ChangeDisplay2Value(__batt_map, _battery_soc_100);
+    }
+
+    ChangeDisplay2Value(__soc_value_charging, _disappear);
+}
+
 void ChangeBattMapAndValue(short page, int soc)
 void ChangeBattMapAndValue(short page, int soc)
 {
 {
 //  srand(time(NULL));
 //  srand(time(NULL));
@@ -562,7 +637,7 @@ void ChangeChargingEnergyValue(float energy)
     byte value[10];
     byte value[10];
 
 
     memset(cmd, 0x00, sizeof(cmd));
     memset(cmd, 0x00, sizeof(cmd));
-    if(energy > 0.05)
+    if (energy >= 0.05)
     {
     {
         energy -= 0.05;
         energy -= 0.05;
     }
     }
@@ -765,7 +840,7 @@ void ProcessPageInfo()
         case _LCM_CHARGING:
         case _LCM_CHARGING:
         case _LCM_COMPLETE:
         case _LCM_COMPLETE:
         {
         {
-            if (_totalCount == 2)
+            if (_totalCount + acgunCount >= 2)
             {
             {
                 ChangeDisplay2Value(__sel_gun_btn, _sel_gun_btn);
                 ChangeDisplay2Value(__sel_gun_btn, _sel_gun_btn);
 
 
@@ -796,14 +871,91 @@ void ProcessPageInfo()
                 ChangeDisplay2Value(__sel_gun_btn, _disappear);
                 ChangeDisplay2Value(__sel_gun_btn, _disappear);
             }
             }
 
 
-            // gun type and charging info
+            bool isShowAc = false;
+            if (acgunCount > 0)
+            {
+                if (ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc != NO_DEFINE)
+                {
+                    isShowAc = true;
+                    ChangeDisplay2Value(__gun_type_index + (2 * 2), _actype_light);
+
+                    if (_currentPage == _LCM_CHARGING)
+                    {
+                        ChangeAcBattMapAndValue(_LCM_CHARGING);
+                        if (ac_chargingInfo[0]->RemainChargingDuration >= 0)
+                            ChangeRemainTime(ac_chargingInfo[0]->RemainChargingDuration);
+                        else
+                            ChangeRemainTime(0);
+
+                        if (ac_chargingInfo[0]->PresentChargingPower >= 0.1)
+                            ChangeChargingPowerValue(ac_chargingInfo[0]->PresentChargingPower);
+                        else
+                            ChangeChargingPowerValue(0);
+
+                        if (ac_chargingInfo[0]->PresentChargedEnergy >= 0.1)
+                            ChangeChargingEnergyValue(ac_chargingInfo[0]->PresentChargedEnergy);
+                        else
+                            ChangeChargingEnergyValue(0);
+
+                        if (strcmp((char *)ac_chargingInfo[0]->StartUserId, "") == 0)
+                            ChangeDisplay2Value(__stop_method_btn, _stop_charging_btn);
+                        else
+                            ChangeDisplay2Value(__stop_method_btn, _stop_charging_btn_scan);
+                    }
+                    else if (_currentPage == _LCM_COMPLETE)
+                    {
+                        ChangeAcBattMapAndValue(_LCM_COMPLETE);
+                        if (ac_chargingInfo[0]->RemainChargingDuration >= 0)
+                            ChangeRemainTime(ac_chargingInfo[0]->RemainChargingDuration);
+                        else
+                            ChangeRemainTime(0);
+
+                        if (ac_chargingInfo[0]->PresentChargingPower >= 0.1)
+                            ChangeChargingPowerValue(ac_chargingInfo[0]->PresentChargingPower);
+                        else
+                            ChangeChargingPowerValue(0);
+
+                        if (ac_chargingInfo[0]->PresentChargedEnergy >= 0.1)
+                        {
+                            ChangeChargingEnergyValue(ac_chargingInfo[0]->PresentChargedEnergy);
+
+                            if (ShmSysConfigAndInfo->SysConfig.BillingData.isBilling &&
+                                    ac_chargingInfo[0]->ChargingFee >= 0)
+                            {
+                                ChangeChargingFeeValue(ac_chargingInfo[0]->ChargingFee);
+                            }
+                        }
+                        else
+                        {
+                            ChangeChargingEnergyValue(0);
+                            if (ShmSysConfigAndInfo->SysConfig.BillingData.isBilling)
+                                ChangeChargingFeeValue(0);
+                        }
+
+                        if(!ShmSysConfigAndInfo->SysConfig.BillingData.isBilling)
+                        {
+                            ChangeDisplay2Value(__charging_fee_map, _disappear);
+                            ChangeDisplay2Value(__charging_fee_tx, _disappear);
+                        }
+                        else
+                        {
+                            ChangeDisplay2Value(__charging_fee_map, _money_map);
+                        }
+                    }
+                }
+                else
+                    ChangeDisplay2Value(__gun_type_index + (2 * 2), _actype_dark);
+            }
+            else
+                ChangeDisplay2Value(__gun_type_index + (2 * 2), _disappear);
+
             for(byte i = 0; i < _totalCount; i++)
             for(byte i = 0; i < _totalCount; i++)
             {
             {
                 switch(_chargingInfoData[i]->Type)
                 switch(_chargingInfoData[i]->Type)
                 {
                 {
                     case _Type_Chademo:
                     case _Type_Chademo:
                     {
                     {
-                        if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == i)
+                        if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == i && !isShowAc)
                         {
                         {
                             ChangeDisplay2Value(__gun_type_index + (i * 2), _chademo_light);
                             ChangeDisplay2Value(__gun_type_index + (i * 2), _chademo_light);
                         }
                         }
@@ -815,7 +967,7 @@ void ProcessPageInfo()
                         break;
                         break;
                     case _Type_GB:
                     case _Type_GB:
                     {
                     {
-                        if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == i)
+                        if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == i && !isShowAc)
                         {
                         {
                             ChangeDisplay2Value(__gun_type_index + (i * 2), _gbt_light);
                             ChangeDisplay2Value(__gun_type_index + (i * 2), _gbt_light);
                         }
                         }
@@ -827,7 +979,7 @@ void ProcessPageInfo()
                         break;
                         break;
                     case _Type_CCS_2:
                     case _Type_CCS_2:
                     {
                     {
-                        if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == i)
+                        if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == i && !isShowAc)
                         {
                         {
                             ChangeDisplay2Value(__gun_type_index + (i * 2), _ccs_light);
                             ChangeDisplay2Value(__gun_type_index + (i * 2), _ccs_light);
                         }
                         }
@@ -839,7 +991,7 @@ void ProcessPageInfo()
                         break;
                         break;
                 }
                 }
 
 
-                if (_currentPage == _LCM_CHARGING)
+                if (_currentPage == _LCM_CHARGING && !isShowAc)
                 {
                 {
                     if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == i)
                     if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == i)
                     {
                     {
@@ -848,10 +1000,12 @@ void ProcessPageInfo()
                             ChangeRemainTime(_chargingInfoData[i]->RemainChargingDuration);
                             ChangeRemainTime(_chargingInfoData[i]->RemainChargingDuration);
                         else
                         else
                             ChangeRemainTime(0);
                             ChangeRemainTime(0);
+
                         if (_chargingInfoData[i]->PresentChargingPower >= 0)
                         if (_chargingInfoData[i]->PresentChargingPower >= 0)
                             ChangeChargingPowerValue(_chargingInfoData[i]->PresentChargingPower);
                             ChangeChargingPowerValue(_chargingInfoData[i]->PresentChargingPower);
                         else
                         else
                             ChangeChargingPowerValue(0);
                             ChangeChargingPowerValue(0);
+
                         if (_chargingInfoData[i]->PresentChargedEnergy >= 0.1)
                         if (_chargingInfoData[i]->PresentChargedEnergy >= 0.1)
                             ChangeChargingEnergyValue(_chargingInfoData[i]->PresentChargedEnergy);
                             ChangeChargingEnergyValue(_chargingInfoData[i]->PresentChargedEnergy);
                         else
                         else
@@ -863,7 +1017,7 @@ void ProcessPageInfo()
                             ChangeDisplay2Value(__stop_method_btn, _stop_charging_btn_scan);
                             ChangeDisplay2Value(__stop_method_btn, _stop_charging_btn_scan);
                     }
                     }
                 }
                 }
-                else if (_currentPage == _LCM_COMPLETE)
+                else if (_currentPage == _LCM_COMPLETE && !isShowAc)
                 {
                 {
                     if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == i)
                     if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == i)
                     {
                     {
@@ -872,6 +1026,7 @@ void ProcessPageInfo()
                             ChangeRemainTime(_chargingInfoData[i]->RemainChargingDuration);
                             ChangeRemainTime(_chargingInfoData[i]->RemainChargingDuration);
                         else
                         else
                             ChangeRemainTime(0);
                             ChangeRemainTime(0);
+
                         if (_chargingInfoData[i]->PresentChargingPower >= 0)
                         if (_chargingInfoData[i]->PresentChargingPower >= 0)
                             ChangeChargingPowerValue(_chargingInfoData[i]->PresentChargingPower);
                             ChangeChargingPowerValue(_chargingInfoData[i]->PresentChargingPower);
                         else
                         else
@@ -890,14 +1045,25 @@ void ProcessPageInfo()
                         else
                         else
                         {
                         {
                             ChangeChargingEnergyValue(0);
                             ChangeChargingEnergyValue(0);
+                            if (ShmSysConfigAndInfo->SysConfig.BillingData.isBilling)
                             ChangeChargingFeeValue(0);
                             ChangeChargingFeeValue(0);
                         }
                         }
+
+                        if(!ShmSysConfigAndInfo->SysConfig.BillingData.isBilling)
+                        {
+                            ChangeDisplay2Value(__charging_fee_map, _disappear);
+                            ChangeDisplay2Value(__charging_fee_tx, _disappear);
+                        }
+                        else
+                        {
+                            ChangeDisplay2Value(__charging_fee_map, _money_map);
+                        }
                     }
                     }
                 }
                 }
             }
             }
 
 
             // gun btn and QR code
             // gun btn and QR code
-            if (_totalCount == 2 && _currentPage)
+            if (_totalCount + acgunCount >= 2 && _currentPage)
             {
             {
                 byte index = 0;
                 byte index = 0;
                 for(index = 0; index < _totalCount; index++)
                 for(index = 0; index < _totalCount; index++)
@@ -975,6 +1141,25 @@ void Initialization()
         }
         }
     }
     }
 
 
+    isPass = false;
+
+    if (acgunCount > 0)
+    {
+        while(!isPass)
+        {
+            isPass = true;
+            for (byte _index = 0; _index < acgunCount; _index++)
+            {
+                if (!FindAcChargingInfoData(_index, &ac_chargingInfo[0]))
+                {
+                    DEBUG_ERROR("EvComm : FindAcChargingInfoData false \n");
+                    isPass = false;
+                    break;
+                }
+            }
+        }
+    }
+
     if (count == 0)
     if (count == 0)
         PRINTF_FUNC("LCM Initialization Gun Fail.............\n");
         PRINTF_FUNC("LCM Initialization Gun Fail.............\n");
 }
 }
@@ -997,11 +1182,11 @@ int main(void)
     _port = CreateCommunicationLcmPort();
     _port = CreateCommunicationLcmPort();
     byte changeWarningPriority = 0;
     byte changeWarningPriority = 0;
     byte curWarningCount = 255;
     byte curWarningCount = 255;
-    //ChangeBackLight(true);
+    ChangeBackLight(true);
     _totalCount = ShmSysConfigAndInfo->SysConfig.TotalConnectorCount;
     _totalCount = ShmSysConfigAndInfo->SysConfig.TotalConnectorCount;
+    acgunCount = ShmSysConfigAndInfo->SysConfig.AcConnectorCount;
     Initialization();
     Initialization();
 
 
-    //ChangeToOtherPage(_LCM_INIT);
     //return 0;
     //return 0;
 
 
     while(_port != -1)
     while(_port != -1)

+ 18 - 0
EVSE/Projects/DM30/Apps/Module_LcmControl.h

@@ -41,6 +41,8 @@ struct SysConfigAndInfo         *ShmSysConfigAndInfo;
 struct StatusCodeData           *ShmStatusCodeData;
 struct StatusCodeData           *ShmStatusCodeData;
 struct FanModuleData            *ShmFanModuleData;
 struct FanModuleData            *ShmFanModuleData;
 
 
+#define NO_DEFINE           255
+
 #define CMD_TITLE_1             0x5A
 #define CMD_TITLE_1             0x5A
 #define CMD_TITLE_2             0xA5
 #define CMD_TITLE_2             0xA5
 #define CMD_READ                0x80
 #define CMD_READ                0x80
@@ -51,13 +53,28 @@ struct FanModuleData            *ShmFanModuleData;
 #define CMD_BACKLIGHT           0x01
 #define CMD_BACKLIGHT           0x01
 #define CMD_REGISTER            0x03
 #define CMD_REGISTER            0x03
 
 
+enum _BATTERY_LEVEL_FOR_MAP
+{
+    _BATTERY_LEVEL_FOR_MAP_EMP = 0x00,
+    _BATTERY_LEVEL_FOR_MAP_LV1 = 0x01,
+    _BATTERY_LEVEL_FOR_MAP_LV2 = 0x02,
+    _BATTERY_LEVEL_FOR_MAP_LV3 = 0x03,
+    _BATTERY_LEVEL_FOR_MAP_LV4 = 0x04,
+    _BATTERY_LEVEL_FOR_MAP_LV5 = 0x05,
+};
+
 int _port;
 int _port;
 //char* pPortName = "/dev/ttyO2";
 //char* pPortName = "/dev/ttyO2";
 char* pPortName = "/dev/ttyS3";
 char* pPortName = "/dev/ttyS3";
 char* moduleName = "DMT80480T070_09WT";
 char* moduleName = "DMT80480T070_09WT";
 byte _totalCount;
 byte _totalCount;
+byte acgunCount;
 struct ChargingInfoData *_chargingInfoData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 struct ChargingInfoData *_chargingInfoData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
+struct ChargingInfoData *ac_chargingInfo[AC_QUANTITY];
 
 
+byte ac_ani_battery_level = _BATTERY_LEVEL_FOR_MAP_LV5;
+byte isDiffStatus = false;
+byte isChangeBattMap = false;
 // 當前選擇的槍號
 // 當前選擇的槍號
 short _currentPage = _LCM_NONE;
 short _currentPage = _LCM_NONE;
 short _oldPage = _LCM_NONE;
 short _oldPage = _LCM_NONE;
@@ -103,6 +120,7 @@ short __remain_time_tx = 0x0110;
 short __output_eng_tx = 0x0120;
 short __output_eng_tx = 0x0120;
 short __total_out_eng_tx = 0x0130;
 short __total_out_eng_tx = 0x0130;
 short __conn_line_comp = 0x0140;
 short __conn_line_comp = 0x0140;
+short __charging_fee_map = 0x0146;
 short __charging_fee_tx = 0x0150;
 short __charging_fee_tx = 0x0150;
 
 
 short __money_by_rate = 0x0200;
 short __money_by_rate = 0x0200;

+ 296 - 148
EVSE/Projects/DM30/Apps/Module_PsuComm.c

@@ -7,13 +7,16 @@
 #define NO                  0
 #define NO                  0
 #define DERATING            30
 #define DERATING            30
 #define ELEMENT_NOT_FIND    255
 #define ELEMENT_NOT_FIND    255
-#define CHK_VOL_RANGE       20
+#define CHK_VOL_RANGE       50
 #define CHK_CUR_RANGE       10
 #define CHK_CUR_RANGE       10
 #define DERATING_RANGE      100
 #define DERATING_RANGE      100
-#define ZERO_CURRENT        0
-#define ZERO_VOLTAGE        10
+#define ZERO_CURRENT        10          // 該值須保持最小為 1A
+#define ZERO_VOLTAGE        50
 #define STOP_CURRENT        30
 #define STOP_CURRENT        30
-#define PSU_MIN_CUR         100
+#define PSU_MIN_CUR         1000
+#define PRE_CHARG_STEP_CUR  30
+#define PRE_CHARG_RANGE     5
+#define EQUAL               0
 
 
 struct SysConfigAndInfo         *ShmSysConfigAndInfo;
 struct SysConfigAndInfo         *ShmSysConfigAndInfo;
 struct StatusCodeData           *ShmStatusCodeData;
 struct StatusCodeData           *ShmStatusCodeData;
@@ -186,7 +189,7 @@ void AbnormalStopAnalysis(byte gun_index, int errCode)
                             ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = YES;
                             ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = YES;
                     }
                     }
                         break;
                         break;
-                case 1:
+                    case 1:
                     {
                     {
                         if (bitIndex == 1)
                         if (bitIndex == 1)
                             ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFailureAlarm = YES;
                             ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFailureAlarm = YES;
@@ -200,7 +203,7 @@ void AbnormalStopAnalysis(byte gun_index, int errCode)
                             ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = YES;
                             ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = YES;
                     }
                     }
                     break;
                     break;
-                case 2:
+                    case 2:
                     {
                     {
                         if (bitIndex == 0)
                         if (bitIndex == 0)
                             ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPowerLimitedState = YES;
                             ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPowerLimitedState = YES;
@@ -331,7 +334,7 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
         ShmPsuData->PsuGroup[group].PsuModule[address].AvailableCurrent = maxCur;
         ShmPsuData->PsuGroup[group].PsuModule[address].AvailableCurrent = maxCur;
 
 
     ShmPsuData->PsuGroup[group].PsuModule[address].AvailablePower = totalPow;
     ShmPsuData->PsuGroup[group].PsuModule[address].AvailablePower = totalPow;
-
+    // 總和該 Group 的可輸出電流
     for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
     for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++)
     {
     {
         _groupCurrent += ShmPsuData->PsuGroup[group].PsuModule[index].AvailableCurrent;
         _groupCurrent += ShmPsuData->PsuGroup[group].PsuModule[index].AvailableCurrent;
@@ -345,19 +348,26 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
     chargingInfo[group]->MaximumChargingVoltage = maxVol;
     chargingInfo[group]->MaximumChargingVoltage = maxVol;
 
 
     int _power = 0, _current = 0, _ratingcurrent = 0;
     int _power = 0, _current = 0, _ratingcurrent = 0;
+    bool isGetAllDeratingCurrent = true;
+
     for (byte index = 0; index < ShmPsuData->GroupCount; index++)
     for (byte index = 0; index < ShmPsuData->GroupCount; index++)
     {
     {
         _power += ShmPsuData->PsuGroup[index].GroupAvailablePower;
         _power += ShmPsuData->PsuGroup[index].GroupAvailablePower;
         _current += ShmPsuData->PsuGroup[index].GroupAvailableCurrent;
         _current += ShmPsuData->PsuGroup[index].GroupAvailableCurrent;
         _ratingcurrent += chargingInfo[index]->DeratingChargingCurrent;
         _ratingcurrent += chargingInfo[index]->DeratingChargingCurrent;
+        if (chargingInfo[index]->DeratingChargingCurrent == 0)
+            isGetAllDeratingCurrent = false;
     }
     }
 
 
+    // 如果不是所有群都得到 Derating current,則先不採樣該次的 ratingCurrent
+    if (!isGetAllDeratingCurrent) _ratingcurrent = 0;
+
     ShmPsuData->SystemAvailableCurrent = _current;
     ShmPsuData->SystemAvailableCurrent = _current;
     ShmPsuData->SystemAvailablePower = _power;
     ShmPsuData->SystemAvailablePower = _power;
 
 
     if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER ||
     if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER ||
-            (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_GET_NEW_CAP &&
-             ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A))
+        (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_GET_NEW_CAP &&
+        ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A))
     {
     {
         int halfPow = ShmPsuData->PsuGroup[group].GroupAvailablePower;
         int halfPow = ShmPsuData->PsuGroup[group].GroupAvailablePower;
         int halfCur = ShmPsuData->PsuGroup[group].GroupAvailableCurrent;
         int halfCur = ShmPsuData->PsuGroup[group].GroupAvailableCurrent;
@@ -382,23 +392,23 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
     }
     }
     else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
     else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
     {
     {
-    GetMaxPowerAndCur(_MAIN_CHARGING_MODE_MAX, _ratingcurrent, &_power, &_current);
+        GetMaxPowerAndCur(_MAIN_CHARGING_MODE_MAX, _ratingcurrent, &_power, &_current);
 
 
-    if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES)
-    {
-            for (byte count = 0; count < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; count++)
+        if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES)
         {
         {
-            chargingInfo[count]->MaximumChargingVoltage = maxVol;
-            chargingInfo[count]->AvailableChargingCurrent = _current;
-            chargingInfo[count]->AvailableChargingPower = _power;
+            for (byte count = 0; count < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; count++)
+            {
+                chargingInfo[count]->MaximumChargingVoltage = maxVol;
+                chargingInfo[count]->AvailableChargingCurrent = _current;
+                chargingInfo[count]->AvailableChargingPower = _power;
+            }
         }
         }
-    }
-    else
-    {
+        else
+        {
             // 如果是最大充,該槍資訊中的輸出能力為各群輸出能力的和
             // 如果是最大充,該槍資訊中的輸出能力為各群輸出能力的和
-        chargingInfo[group]->AvailableChargingCurrent = _current;
-        chargingInfo[group]->AvailableChargingPower = _power;
-    }
+            chargingInfo[group]->AvailableChargingCurrent = _current;
+            chargingInfo[group]->AvailableChargingPower = _power;
+        }
     }
     }
 }
 }
 
 
@@ -409,6 +419,8 @@ void GetFwCallback(byte address, short dcSwVer, short pfcSwVer, short hwVer)
 
 
     byte group = FindTargetGroup(address);
     byte group = FindTargetGroup(address);
 
 
+    sprintf((char *)ShmPsuData->PsuVersion[address].FwPrimaryVersion, "DC %d.%02d", (dcSwVer & 0xFF00) >> 8, dcSwVer & 0xFF);
+    sprintf((char *)ShmPsuData->PsuVersion[address].FwSecondVersion, "PFC %d.%02d", (pfcSwVer & 0xFF00) >> 8, pfcSwVer & 0xFF);
     if (group == 1)
     if (group == 1)
         address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity;
         address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity;
     sprintf((char *)ShmPsuData->PsuGroup[group].PsuModule[address].FwVersion, "DC %d.%02d", (dcSwVer & 0xFF00) >> 8, dcSwVer & 0xFF);
     sprintf((char *)ShmPsuData->PsuGroup[group].PsuModule[address].FwVersion, "DC %d.%02d", (dcSwVer & 0xFF00) >> 8, dcSwVer & 0xFF);
@@ -440,7 +452,11 @@ void GetPresentOutputCallback(byte group, unsigned short outVol, unsigned short
     // PSU Group - 電流
     // PSU Group - 電流
     ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent = outputCur;
     ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent = outputCur;
 
 
-    if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
+    if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX ||
+        (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER &&
+        (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_WAITING &&
+        ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_COMP))
+        )
     {
     {
         outputVol = 0;
         outputVol = 0;
         outputCur = 0;
         outputCur = 0;
@@ -520,16 +536,15 @@ void GetFanSpeedCallback(byte address, unsigned int fanSpeed)
 void GetIavailableCallback(byte address, unsigned short Iavail, unsigned short Vext)
 void GetIavailableCallback(byte address, unsigned short Iavail, unsigned short Vext)
 {
 {
     if (IsOverModuleCount(address))
     if (IsOverModuleCount(address))
-            return;
+        return;
 
 
+    //PRINTF_FUNC("address = %d, Iavail = %d \n", address, Iavail);
     byte group = FindTargetGroup(address);
     byte group = FindTargetGroup(address);
 
 
     if (group == 1)
     if (group == 1)
         address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity;
         address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity;
 
 
     //PRINTF_FUNC("group = %d, address_%d, Iavail = %d \n", group, address, Iavail);
     //PRINTF_FUNC("group = %d, address_%d, Iavail = %d \n", group, address, Iavail);
-
-    // PSU Group - 電壓
     ShmPsuData->PsuGroup[group].PsuModule[address].IAvailableCurrent = Iavail;
     ShmPsuData->PsuGroup[group].PsuModule[address].IAvailableCurrent = Iavail;
 
 
     bool isPass = true;
     bool isPass = true;
@@ -563,7 +578,7 @@ void GetIavailableCallback(byte address, unsigned short Iavail, unsigned short V
                 {
                 {
                     chargingInfo[group]->SampleChargingCur[count] = totalCur;
                     chargingInfo[group]->SampleChargingCur[count] = totalCur;
                     isPass = false;
                     isPass = false;
-                    continue;
+                    break;
                 }
                 }
             }
             }
         }
         }
@@ -571,6 +586,7 @@ void GetIavailableCallback(byte address, unsigned short Iavail, unsigned short V
 
 
     if (isPass)
     if (isPass)
     {
     {
+        //PRINTF_FUNC("rating pass value = %d \n", totalCur);
         chargingInfo[group]->DeratingChargingCurrent = totalCur;
         chargingInfo[group]->DeratingChargingCurrent = totalCur;
     }
     }
 }
 }
@@ -666,7 +682,7 @@ void Initialization()
         {
         {
             if (!FindChargingInfoData(_index, &chargingInfo[0]))
             if (!FindChargingInfoData(_index, &chargingInfo[0]))
             {
             {
-                DEBUG_ERROR("EvComm (main) : FindChargingInfoData false \n");
+                DEBUG_ERROR("Module_PsuComm : FindChargingInfoData false \n");
                 isPass = false;
                 isPass = false;
                 break;
                 break;
             }
             }
@@ -677,21 +693,80 @@ void Initialization()
         ShmPsuData->GroupCount = 1;
         ShmPsuData->GroupCount = 1;
     else
     else
         ShmPsuData->GroupCount = _gunCount;
         ShmPsuData->GroupCount = _gunCount;
-}
 
 
-void CheckSmartChargingStep(bool isCharging)
-{
-    if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_PREPARE_M_TO_A)
+    char EvsePower[2];
+
+    EvsePower[2] = '\0';
+    char count = 0;
+    byte psuTarIndex = 0;
+    // 解析 ModelName 取得各槍各有幾個 PSU 及編號
+    if (strlen((char *) ShmSysConfigAndInfo->SysConfig.ModelName) >= 6)
     {
     {
-        if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
+        strncpy(EvsePower, (char *)(ShmSysConfigAndInfo->SysConfig.ModelName + 4), 2);
+        if (strcmp(EvsePower, "15") == EQUAL)
+            count = 5;
+        else if (strcmp(EvsePower, "30") == EQUAL)
+            count = 1;
+        else if (strcmp(EvsePower, "60") == EQUAL)
+            count = 2;
+        else if (strcmp(EvsePower, "18") == EQUAL)
+            count = 6;
+        else if (strcmp(EvsePower, "36") == EQUAL)
+            count = 12;
+
+        if (count > 0)
         {
         {
-            PRINTF_FUNC("=============Smart Charging : _REASSIGNED_GET_NEW_CAP============= Step 2 \n");
-            ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_GET_NEW_CAP;
+            if (ShmPsuData->GroupCount == 1)
+                conn_1_count = count;
+            else if (ShmPsuData->GroupCount == 2)
+            {
+                if(count % 2 > 0)
+                    conn_1_count = (count / 2) + 1;
+                else
+                    conn_1_count = (count / 2);
+
+                conn_2_count = count - conn_1_count;
+            }
+
+            for(byte psuIndex = 0; psuIndex < conn_1_count; psuIndex++)
+            {
+                connector_1[psuIndex] = psuTarIndex;
+                psuTarIndex++;
+            }
+
+            for(byte psuIndex = 0; psuIndex < conn_2_count; psuIndex++)
+            {
+                connector_2[psuIndex] = psuTarIndex;
+                psuTarIndex++;
+            }
+
+            for(byte psuIndex = 0; psuIndex < conn_1_count; psuIndex++)
+                PRINTF_FUNC("Connector 1 - Number = %d \n", connector_1[psuIndex]);
+
+            for(byte psuIndex = 0; psuIndex < conn_2_count; psuIndex++)
+                PRINTF_FUNC("Connector 2 - Number = %d \n", connector_2[psuIndex]);
         }
         }
         else
         else
+            DEBUG_ERROR("Module_PsuComm : Can't parsing model name. \n");
+    }
+}
+
+void CheckSmartChargingStep(bool isWaitingAver, bool isCharging)
+{
+    if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_PREPARE_M_TO_A)
+    {
+        if (isWaitingAver)
         {
         {
-            PRINTF_FUNC("=============Smart Charging : _REASSIGNED_NONE============= Step 0 \n");
-            ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE;
+            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)
     else  if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag ==  _REASSIGNED_PREPARE_A_TO_M)
@@ -705,10 +780,15 @@ void CheckSmartChargingStep(bool isCharging)
             }
             }
             else
             else
             {
             {
-                PRINTF_FUNC("=============Smart Charging : _REASSIGNED_COMP============= Step 15 \n");
+                PRINTF_FUNC("=============Smart Charging_1  : _REASSIGNED_COMP============= Step 15 \n");
                 ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_COMP;
                 ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_COMP;
             }
             }
         }
         }
+        else
+        {
+            PRINTF_FUNC("=============Smart Charging_2 : _REASSIGNED_COMP============= Step 15 \n");
+            ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_COMP;
+        }
     }
     }
 }
 }
 
 
@@ -780,6 +860,7 @@ int main(void)
                 PRINTF_FUNC("== PSU == INITIAL_START \n");
                 PRINTF_FUNC("== PSU == INITIAL_START \n");
                 gettimeofday(&_cmdSubPriority_time, NULL);
                 gettimeofday(&_cmdSubPriority_time, NULL);
                 sleep(5);
                 sleep(5);
+                SwitchPower(SYSTEM_CMD, PSU_POWER_OFF);
                 ShmPsuData->Work_Step = GET_PSU_COUNT;
                 ShmPsuData->Work_Step = GET_PSU_COUNT;
             }
             }
                 break;
                 break;
@@ -790,7 +871,8 @@ int main(void)
 
 
                 if (time > 2000)
                 if (time > 2000)
                 {
                 {
-                    PRINTF_FUNC("== PSU == %d \n", ShmPsuData->GroupCount);
+                    PRINTF_FUNC("== PSU == indexCount = %d, moduleCount = %d, sysCount = %d\n",
+                            ShmPsuData->GroupCount, moduleCount, ShmPsuData->SystemPresentPsuQuantity);
 //                  if (ShmPsuData->GroupCount == 0)
 //                  if (ShmPsuData->GroupCount == 0)
 //                      ShmPsuData->GroupCount = ShmSysConfigAndInfo->SysConfig.TotalConnectorCount;
 //                      ShmPsuData->GroupCount = ShmSysConfigAndInfo->SysConfig.TotalConnectorCount;
                     // 分別取各群模組數量
                     // 分別取各群模組數量
@@ -866,19 +948,30 @@ int main(void)
                 break;
                 break;
             case BOOTING_COMPLETE:
             case BOOTING_COMPLETE:
             {
             {
+                bool isSelfTestPass = true;
+                for (byte groupIndex = 0; groupIndex < _gunCount; groupIndex++)
+                {
+                    if (chargingInfo[groupIndex]->SystemStatus == S_BOOTING)
+                    {
+                        isSelfTestPass = false;
+                    }
+                }
+
+                if (isSelfTestPass)
+                    ShmPsuData->Work_Step = _WORK_CHARGING;
                 sleep(1);
                 sleep(1);
             }
             }
                 break;
                 break;
             case _WORK_CHARGING:
             case _WORK_CHARGING:
             {
             {
                 int time = GetTimeoutValue(_cmdSubPriority_time) / 1000;
                 int time = GetTimeoutValue(_cmdSubPriority_time) / 1000;
-                // sdlu - test
-                int testtime = GetTimeoutValue(_test_time) / 1000;
 
 
-                bool isCharging = false;
                 // 低 Priority 的指令
                 // 低 Priority 的指令
                 if (time > 1500)
                 if (time > 1500)
                 {
                 {
+                    isCharging = false;
+                    isWaitingAver = false;
+                    isReadToCharging = false;
                     for (byte index = 0; index < ShmPsuData->GroupCount; index++)
                     for (byte index = 0; index < ShmPsuData->GroupCount; index++)
                     {
                     {
                         // Pooling Status
                         // Pooling Status
@@ -894,39 +987,54 @@ int main(void)
                         GetModuleIavailable(index);
                         GetModuleIavailable(index);
 
 
                         if (chargingInfo[index]->SystemStatus == S_CHARGING)
                         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);
+                            isCharging = true;
+                            if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_PREPARE_M_TO_A)
+                            {
+                                if (toAverVolPoint > 0 &&
+                                        toAverVolPoint == chargingInfo[index]->EvBatterytargetCurrent)
+                                {
+                                    // 欲最大充 -> 均充需要等待充電中的輸出電流拉高到目標電流
+                                    if ((chargingInfo[index]->PresentChargingCurrent * 10) >=
+                                        chargingInfo[index]->EvBatterytargetCurrent - CHK_CUR_RANGE)
+                                    {
+                                        if (toAverVolCount == 0)
+                                            isWaitingAver = true;
+                                        else
+                                            toAverVolCount--;
+                                    }
+                                }
+                                else
+                                {
+                                    toAverVolPoint = chargingInfo[index]->EvBatterytargetCurrent;
+                                    toAverVolCount = 3;
+                                }
+                            }
+                            else
+                            {
+                                toAverVolPoint = 0;
+                                toAverVolCount = 3;
+                            }
                         }
                         }
 
 
-                        if ((chargingInfo[gunIndex]->PresentChargingCurrent * 10) > 0 &&
-                            evseOutCur != (chargingInfo[gunIndex]->PresentChargingCurrent * 10))
+                        if ((chargingInfo[index]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[index]->SystemStatus <= S_CHARGING) ||
+                            (chargingInfo[index]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[index]->SystemStatus <= S_CCS_PRECHARGE_ST1))
                         {
                         {
-                            evseOutCur = (chargingInfo[gunIndex]->PresentChargingCurrent * 10);
-                            PRINTF_FUNC("groupIndex = %d, evse output cur = %f \n", gunIndex,
-                                (chargingInfo[gunIndex]->PresentChargingCurrent * 10));
+                            isReadToCharging = true;
                         }
                         }
                     }
                     }
 
 
                     gettimeofday(&_cmdSubPriority_time, NULL);
                     gettimeofday(&_cmdSubPriority_time, NULL);
+                    CheckSmartChargingStep(isWaitingAver, isCharging);
                 }
                 }
 
 
-                CheckSmartChargingStep(isCharging);
                 for (byte groupIndex = 0; groupIndex < _gunCount; groupIndex++)
                 for (byte groupIndex = 0; groupIndex < _gunCount; groupIndex++)
                 {
                 {
                     GetModuleOutput(groupIndex);
                     GetModuleOutput(groupIndex);
                     // 針對各槍當前狀態,傳送需要回傳的資料指令
                     // 針對各槍當前狀態,傳送需要回傳的資料指令
                     if (((chargingInfo[groupIndex]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[groupIndex]->SystemStatus <= S_CHARGING) && chargingInfo[groupIndex]->RelayK1K2Status) ||
                     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]->Type == _Type_GB) ||
-                            (chargingInfo[groupIndex]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[groupIndex]->SystemStatus <= S_CCS_PRECHARGE_ST1))
+                        (chargingInfo[groupIndex]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[groupIndex]->SystemStatus <= S_CHARGING && chargingInfo[groupIndex]->Type == _Type_GB) ||
+                        (chargingInfo[groupIndex]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[groupIndex]->SystemStatus <= S_CCS_PRECHARGE_ST1))
                     {
                     {
                         if (chargingInfo[groupIndex]->EvBatterytargetVoltage > 0 &&
                         if (chargingInfo[groupIndex]->EvBatterytargetVoltage > 0 &&
                             carReqVol != chargingInfo[groupIndex]->EvBatterytargetVoltage)
                             carReqVol != chargingInfo[groupIndex]->EvBatterytargetVoltage)
@@ -942,8 +1050,30 @@ int main(void)
                             DEBUG_INFO("ev need cur = %f \n", chargingInfo[groupIndex]->EvBatterytargetCurrent);
                             DEBUG_INFO("ev need cur = %f \n", chargingInfo[groupIndex]->EvBatterytargetCurrent);
                         }
                         }
 
 
+                        if (time > 1500)
+                        {
+                            if (chargingInfo[groupIndex]->FireChargingVoltage > 0 &&
+                                evseOutVol != (chargingInfo[groupIndex]->FireChargingVoltage / 10))
+                            {
+                                evseOutVol = (chargingInfo[groupIndex]->FireChargingVoltage / 10);
+                                PRINTF_FUNC("groupIndex = %d, evse output vol = %f \n", groupIndex,
+                                    chargingInfo[groupIndex]->FireChargingVoltage);
+                            }
+
+                            if ((chargingInfo[groupIndex]->PresentChargingCurrent * 10) > 0 &&
+                                evseOutCur != (chargingInfo[groupIndex]->PresentChargingCurrent * 10))
+                            {
+                                evseOutCur = (chargingInfo[groupIndex]->PresentChargingCurrent * 10);
+                                PRINTF_FUNC("groupIndex = %d, evse output cur = %f \n", groupIndex,
+                                    (chargingInfo[groupIndex]->PresentChargingCurrent * 10));
+                            }
+                        }
+
                         if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
                         if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
                         {
                         {
+//                          PRINTF_FUNC("index = %d, SystemStatus = %d, Ev = %f, curCur = %f \n", groupIndex,
+//                                  chargingInfo[groupIndex]->SystemStatus, chargingInfo[groupIndex]->EvBatterytargetCurrent,
+//                                  (chargingInfo[groupIndex]->PresentChargingCurrent * 10));
                             // 智能判斷 Start -----------------------------------------------------------
                             // 智能判斷 Start -----------------------------------------------------------
                             if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_GET_NEW_CAP)
                             if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_GET_NEW_CAP)
                             {
                             {
@@ -960,9 +1090,9 @@ int main(void)
                                         deratingKeepCount = 0;
                                         deratingKeepCount = 0;
                                     }
                                     }
                                     else
                                     else
-                        {
+                                    {
                                         deratingKeepCount++;
                                         deratingKeepCount++;
-                        }
+                                    }
                                 }
                                 }
 
 
                             }
                             }
@@ -972,7 +1102,7 @@ int main(void)
 
 
                                 // 需求電流不降低的情況下 -> 依然要切
                                 // 需求電流不降低的情況下 -> 依然要切
                                 if (chargingInfo[groupIndex]->AvailableChargingCurrent < chargingInfo[groupIndex]->EvBatterytargetCurrent)
                                 if (chargingInfo[groupIndex]->AvailableChargingCurrent < chargingInfo[groupIndex]->EvBatterytargetCurrent)
-                        {
+                                {
                                     PRINTF_FUNC("** _REASSIGNED_ADJUST_M_TO_A ** Gun_%d, AvailableChargingCurrent = %f, EvBatterytargetCurrent = %f \n", groupIndex,
                                     PRINTF_FUNC("** _REASSIGNED_ADJUST_M_TO_A ** Gun_%d, AvailableChargingCurrent = %f, EvBatterytargetCurrent = %f \n", groupIndex,
                                             (chargingInfo[groupIndex]->PresentChargingCurrent * 10),
                                             (chargingInfo[groupIndex]->PresentChargingCurrent * 10),
                                             chargingInfo[groupIndex]->AvailableChargingCurrent);
                                             chargingInfo[groupIndex]->AvailableChargingCurrent);
@@ -980,7 +1110,7 @@ int main(void)
                                     {
                                     {
                                         if (chargingInfo[subIndex]->SystemStatus == S_REASSIGN)
                                         if (chargingInfo[subIndex]->SystemStatus == S_REASSIGN)
                                         {
                                         {
-                                            if ((chargingInfo[subIndex]->PresentChargingCurrent * 10) <= CHK_CUR_RANGE)
+                                            if ((ShmPsuData->PsuGroup[subIndex].GroupPresentOutputCurrent) <= CHK_CUR_RANGE)
                                                 isChanged = true;
                                                 isChanged = true;
                                             break;
                                             break;
                                         }
                                         }
@@ -988,16 +1118,24 @@ int main(void)
 
 
                                     // 這狀況下輸出端的電流載滿載衝的狀況下,並不會降電流
                                     // 這狀況下輸出端的電流載滿載衝的狀況下,並不會降電流
                                     // 所以只能拉載到該槍端的最大輸出能力
                                     // 所以只能拉載到該槍端的最大輸出能力
-                                    if ((chargingInfo[groupIndex]->PresentChargingCurrent * 10)>= chargingInfo[groupIndex]->AvailableChargingCurrent - CHK_CUR_RANGE ||
-                                            (chargingInfo[groupIndex]->PresentChargingCurrent * 10) <= CHK_CUR_RANGE)
-                                    {
-                                        isChanged = true;
-                                    }
+//                                  if ((chargingInfo[groupIndex]->PresentChargingCurrent * 10) >= chargingInfo[groupIndex]->AvailableChargingCurrent - CHK_CUR_RANGE ||
+//                                          (chargingInfo[groupIndex]->PresentChargingCurrent * 10) <= CHK_CUR_RANGE)
+//                                  {
+//                                      isChanged = true;
+//                                  }
                                 }
                                 }
                                 else if (((chargingInfo[groupIndex]->PresentChargingCurrent * 10) >= ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent - CHK_CUR_RANGE) &&
                                 else if (((chargingInfo[groupIndex]->PresentChargingCurrent * 10) >= ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent - CHK_CUR_RANGE) &&
                                         ((chargingInfo[groupIndex]->PresentChargingCurrent * 10) <= ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent + CHK_CUR_RANGE))
                                         ((chargingInfo[groupIndex]->PresentChargingCurrent * 10) <= ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent + CHK_CUR_RANGE))
                                 {
                                 {
-                                    isChanged = true;
+                                    for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++)
+                                    {
+                                        if (chargingInfo[subIndex]->SystemStatus == S_REASSIGN)
+                                        {
+                                            if ((ShmPsuData->PsuGroup[subIndex].GroupPresentOutputCurrent) <= CHK_CUR_RANGE)
+                                                isChanged = true;
+                                            break;
+                                        }
+                                    }
                                 }
                                 }
 
 
                                 if (isChanged)
                                 if (isChanged)
@@ -1012,34 +1150,15 @@ int main(void)
                                 }
                                 }
                             }
                             }
 
 
-                            // 智能判斷 End -----------------------------------------------------------
-                            if (testtime > 500 &&
-                                (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_GET_NEW_CAP && ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A))
+                            if (ShmPsuData->SystemAvailablePower > 0)
                             {
                             {
-                                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 * 10),
-                                        (chargingInfo[groupIndex]->PresentChargingCurrent * 10));
-
-                                gettimeofday(&_test_time, NULL);
-                        }
-
-                        if (ShmPsuData->SystemAvailablePower > 0)
-                        {
                                 // 調整輸出電流 : 漸進調整方式
                                 // 調整輸出電流 : 漸進調整方式
                                 if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_ADJUST_M_TO_A)
                                 if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_ADJUST_M_TO_A)
                                 {
                                 {
                                     // 當前充電中的目標電壓
                                     // 當前充電中的目標電壓
                                     float targetVol = chargingInfo[groupIndex]->EvBatterytargetVoltage;
                                     float targetVol = chargingInfo[groupIndex]->EvBatterytargetVoltage;
                                     // 當前充電中的目標電流
                                     // 當前充電中的目標電流
-                                    float targetCur = 0;
+                                    //float targetCur = 0;
                                     // 準備切出去的模塊電流
                                     // 準備切出去的模塊電流
                                     float deratingCur = 0;
                                     float deratingCur = 0;
 
 
@@ -1070,10 +1189,11 @@ int main(void)
                                             }
                                             }
                                         }
                                         }
 
 
+                                        // ***********直接降低要移除的模塊電流即可*************
                                         // 因為爬的速度沒有降的速度快,所以採兩倍速度爬升
                                         // 因為爬的速度沒有降的速度快,所以採兩倍速度爬升
-                                        targetCur = ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent + (DERATING_RANGE * 2);
-                                        if (targetCur >= chargingInfo[groupIndex]->EvBatterytargetCurrent)
-                                                targetCur = chargingInfo[groupIndex]->EvBatterytargetCurrent;
+//                                      targetCur = ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent + (DERATING_RANGE * 2);
+//                                      if (targetCur >= chargingInfo[groupIndex]->EvBatterytargetCurrent)
+//                                              targetCur = chargingInfo[groupIndex]->EvBatterytargetCurrent;
 
 
                                         if (targetVol == 0)
                                         if (targetVol == 0)
                                         {
                                         {
@@ -1089,24 +1209,24 @@ int main(void)
                                 }
                                 }
                                 else
                                 else
                                 {
                                 {
-                            // 該充電槍的目標電壓與目標電流
-                            PresentOutputVol(SYSTEM_CMD,
-                                    chargingInfo[groupIndex]->EvBatterytargetVoltage,
-                                    chargingInfo[groupIndex]->EvBatterytargetCurrent);
+                                    // 該充電槍的目標電壓與目標電流
+                                    PresentOutputVol(SYSTEM_CMD,
+                                        chargingInfo[groupIndex]->EvBatterytargetVoltage,
+                                        chargingInfo[groupIndex]->EvBatterytargetCurrent);
 
 
-                            if (chargingInfo[groupIndex]->EvBatterytargetVoltage == 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);
+                                    if (chargingInfo[groupIndex]->EvBatterytargetVoltage == 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 if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER)
                         else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER)
                         {
                         {
                             // 智能判斷 Start -----------------------------------------------------------
                             // 智能判斷 Start -----------------------------------------------------------
@@ -1117,7 +1237,7 @@ int main(void)
                                 for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++)
                                 for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++)
                                 {
                                 {
                                     if (chargingInfo[subIndex]->SystemStatus == S_IDLE ||
                                     if (chargingInfo[subIndex]->SystemStatus == S_IDLE ||
-                                            chargingInfo[subIndex]->SystemStatus == S_RESERVATION)
+                                        chargingInfo[subIndex]->SystemStatus == S_RESERVATION)
                                     {
                                     {
                                         // 各群電壓接近平衡
                                         // 各群電壓接近平衡
                                         if (((chargingInfo[subIndex]->PresentChargingVoltage * 10) < (chargingInfo[groupIndex]->PresentChargingVoltage * 10) - ZERO_VOLTAGE) ||
                                         if (((chargingInfo[subIndex]->PresentChargingVoltage * 10) < (chargingInfo[groupIndex]->PresentChargingVoltage * 10) - ZERO_VOLTAGE) ||
@@ -1137,60 +1257,63 @@ int main(void)
                                 {
                                 {
                                     // 閒置端與車端要求電壓接近
                                     // 閒置端與車端要求電壓接近
                                     PRINTF_FUNC("=============Smart Charging : _REASSIGNED_RELAY_A_TO_M============= Step 13 \n");
                                     PRINTF_FUNC("=============Smart Charging : _REASSIGNED_RELAY_A_TO_M============= Step 13 \n");
+                                    preChargingCur = preChargingTarget = 0;
                                     ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_RELAY_A_TO_M;
                                     ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_RELAY_A_TO_M;
-                                    GetTimeoutValue(_averageComp_time);
                                 }
                                 }
                             }
                             }
                             else if(ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_WAITING)
                             else if(ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_WAITING)
                             {
                             {
-                                int avrTime = GetTimeoutValue(_averageComp_time) / 1000;
+                                int idleCurrent = 0;
+                                int chargingCurrent = 0;
 
 
-                                if (avrTime > 3000)
+                                for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++)
                                 {
                                 {
-                                    // 閒置端與車端要求電壓接近
-                                    PRINTF_FUNC("=============Smart Charging : _REASSIGNED_COMP============= Step 15 \n");
-                                    ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_COMP;
+                                    if (chargingInfo[subIndex]->SystemStatus == S_IDLE ||
+                                        chargingInfo[subIndex]->SystemStatus == S_RESERVATION ||
+                                        chargingInfo[subIndex]->SystemStatus == S_REASSIGN_CHECK)
+                                        idleCurrent = ShmPsuData->PsuGroup[subIndex].GroupPresentOutputCurrent;
+                                    else
+                                        chargingCurrent = ShmPsuData->PsuGroup[subIndex].GroupPresentOutputCurrent;
                                 }
                                 }
-                            }
-                            // 智能判斷 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 * 10),
-                                    (chargingInfo[groupIndex]->PresentChargingCurrent * 10));
-
-                                gettimeofday(&_test_time, NULL);
+                                if (idleCurrent >= chargingCurrent - PRE_CHARG_RANGE)
+                                {
+                                    PRINTF_FUNC("=============Smart Charging_0 : _REASSIGNED_COMP============= Step 15 \n");
+                                    ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_COMP;
+                                }
                             }
                             }
 
 
                             if (chargingInfo[groupIndex]->AvailableChargingCurrent > 0)
                             if (chargingInfo[groupIndex]->AvailableChargingCurrent > 0)
                             {
                             {
-                                if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_ADJUST_A_TO_M)
+                                if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_ADJUST_A_TO_M)
                                 {
                                 {
                                     for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++)
                                     for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++)
                                     {
                                     {
                                         if (chargingInfo[subIndex]->SystemStatus == S_IDLE ||
                                         if (chargingInfo[subIndex]->SystemStatus == S_IDLE ||
-                                                chargingInfo[subIndex]->SystemStatus == S_RESERVATION)
+                                            chargingInfo[subIndex]->SystemStatus == S_RESERVATION ||
+                                            chargingInfo[subIndex]->SystemStatus == S_REASSIGN_CHECK)
                                         {
                                         {
-                                            // 閒置模塊升壓
+                                            // 閒置模塊升壓,另對剛分配近來的模塊,預上升電流值 (preChargingCur)
                                             PresentOutputVol(subIndex,
                                             PresentOutputVol(subIndex,
                                                     chargingInfo[groupIndex]->EvBatterytargetVoltage,
                                                     chargingInfo[groupIndex]->EvBatterytargetVoltage,
-                                                    ZERO_CURRENT);
+                                                    ZERO_CURRENT + preChargingTarget);
+
+                                            preChargingCur = ShmPsuData->PsuGroup[subIndex].GroupPresentOutputCurrent;
                                         }
                                         }
                                         else
                                         else
                                         {
                                         {
+                                            PRINTF_FUNC("CurOutputCurrent = %d \n", ShmPsuData->PsuGroup[subIndex].GroupPresentOutputCurrent + preChargingCur);
                                             // 充電中的模塊維持輸出
                                             // 充電中的模塊維持輸出
                                             PresentOutputVol(subIndex,
                                             PresentOutputVol(subIndex,
                                                 chargingInfo[subIndex]->EvBatterytargetVoltage,
                                                 chargingInfo[subIndex]->EvBatterytargetVoltage,
-                                                chargingInfo[subIndex]->EvBatterytargetCurrent);
+                                                chargingInfo[subIndex]->EvBatterytargetCurrent - preChargingCur);
+
+                                            if ((ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_WAITING) &&
+                                                (preChargingCur >= preChargingTarget - ZERO_CURRENT))
+                                                preChargingTarget += PRE_CHARG_STEP_CUR;
+
+                                            if (preChargingTarget >= chargingInfo[subIndex]->EvBatterytargetCurrent / 2)
+                                                preChargingTarget = chargingInfo[subIndex]->EvBatterytargetCurrent / 2;
                                         }
                                         }
 
 
                                         if (chargingInfo[groupIndex]->EvBatterytargetVoltage == 0)
                                         if (chargingInfo[groupIndex]->EvBatterytargetVoltage == 0)
@@ -1226,28 +1349,53 @@ int main(void)
                         }
                         }
                     }
                     }
                     else if (chargingInfo[groupIndex]->SystemStatus >= S_TERMINATING &&
                     else if (chargingInfo[groupIndex]->SystemStatus >= S_TERMINATING &&
-                                chargingInfo[groupIndex]->SystemStatus <= S_COMPLETE)
+                             chargingInfo[groupIndex]->SystemStatus <= S_COMPLETE)
                     {
                     {
                         if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
                         if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
                         {
                         {
-                            SwitchPower(SYSTEM_CMD, PSU_POWER_OFF);
-                            FlashLed(SYSTEM_CMD, PSU_FLASH_NORMAL);
+                            if (!isCharging)
+                            {
+                                SwitchPower(SYSTEM_CMD, PSU_POWER_OFF);
+                                FlashLed(SYSTEM_CMD, PSU_FLASH_NORMAL);
 
 
-                            if (chargingInfo[groupIndex]->SystemStatus == S_TERMINATING)
+                                if (chargingInfo[groupIndex]->SystemStatus == S_COMPLETE)
+                                {
+                                    if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_PREPARE_M_TO_A &&
+                                        ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A)
+                                    {
+                                        // 代表在切換的過程中,停止充電了
+                                        if ((chargingInfo[groupIndex]->PresentChargingCurrent * 10) <= STOP_CURRENT)
+                                            ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_RELAY_M_TO_A;
+                                    }
+                                }
+                            }
+                            else if (chargingInfo[groupIndex]->SystemStatus == S_COMPLETE)
                             {
                             {
+                                // 代表充電的槍依舊在充電,欲進入充電的槍取消充電了
                                 if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_PREPARE_M_TO_A &&
                                 if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_PREPARE_M_TO_A &&
-                                        ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A)
+                                    ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A)
                                 {
                                 {
-                                    // 代表在切換的過程中,停止充電了
-                                    if ((chargingInfo[groupIndex]->PresentChargingCurrent * 10) <= STOP_CURRENT)
-                                        ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_RELAY_M_TO_A;
+                                    ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE;
                                 }
                                 }
                             }
                             }
                         }
                         }
                         else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER)
                         else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER)
                         {
                         {
-                            SwitchPower(groupIndex, PSU_POWER_OFF);
-                            FlashLed(groupIndex, PSU_FLASH_NORMAL);
+                            if (!isReadToCharging)
+                            {
+                                SwitchPower(SYSTEM_CMD, PSU_POWER_OFF);
+                                FlashLed(SYSTEM_CMD, PSU_FLASH_NORMAL);
+                            }
+                            else
+                            {
+                                SwitchPower(groupIndex, PSU_POWER_OFF);
+                                FlashLed(groupIndex, PSU_FLASH_NORMAL);
+                            }
+
+                            if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_WAITING)
+                                ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_COMP;
+                            else
+                                ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE;
                         }
                         }
                     }
                     }
                 }
                 }

+ 13 - 3
EVSE/Projects/DM30/Apps/Module_PsuComm.h

@@ -41,10 +41,20 @@ struct ChargingInfoData *chargingInfo[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANT
 
 
 struct timeval _cmdSubPriority_time;
 struct timeval _cmdSubPriority_time;
 byte _getCapDelayCount;
 byte _getCapDelayCount;
-struct timeval _averageComp_time;
 struct timeval _derating_time;
 struct timeval _derating_time;
 
 
 struct timeval _test_time;
 struct timeval _test_time;
 
 
-int connector_1[] = {0};
-int connector_2[] = {1};
+bool isCharging = false;
+bool isWaitingAver = false;
+bool isReadToCharging = false;
+int preChargingTarget;
+int preChargingCur;
+
+float toAverVolPoint;
+byte toAverVolCount;
+
+int connector_1[12];
+int connector_2[12];
+byte conn_1_count = 0;
+byte conn_2_count = 0;

+ 238 - 79
EVSE/Projects/DM30/Apps/ReadCmdline.c

@@ -42,6 +42,8 @@ typedef unsigned char           byte;
 #define PASS                1
 #define PASS                1
 #define FAIL                -1
 #define FAIL                -1
 #define ARRAY_SIZE(A)       (sizeof(A) / sizeof(A[0]))
 #define ARRAY_SIZE(A)       (sizeof(A) / sizeof(A[0]))
+#define NO_DEFINE           255
+#define DEFAULT_AC_INDEX    2
 
 
 #define TTY_PATH            "/dev/tty"
 #define TTY_PATH            "/dev/tty"
 #define STTY_US             "stty raw -echo -F "
 #define STTY_US             "stty raw -echo -F "
@@ -58,7 +60,7 @@ struct RelayModuleData          *ShmRelayModuleData;
 struct PsuData                  *ShmPsuData;
 struct PsuData                  *ShmPsuData;
 
 
 struct ChargingInfoData         *_chargingData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
 struct ChargingInfoData         *_chargingData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY];
-int gunCount = CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY;
+struct ChargingInfoData         *ac_chargingInfo[AC_QUANTITY];
 
 
 char *msg = "state : get gun state (index) \n"
 char *msg = "state : get gun state (index) \n"
         "card : scanning card (x) : \n"
         "card : scanning card (x) : \n"
@@ -100,6 +102,17 @@ bool FindChargingInfoData(byte target, struct ChargingInfoData **chargingData)
     return false;
     return false;
 }
 }
 
 
+bool FindAcChargingInfoData(byte target, struct ChargingInfoData **acChargingData)
+{
+    if (target < AC_QUANTITY)
+    {
+        acChargingData[target] = &ShmSysConfigAndInfo->SysInfo.AcChargingData[target];
+        return true;
+    }
+
+    return false;
+}
+
 int InitShareMemory()
 int InitShareMemory()
 {
 {
     int result = PASS;
     int result = PASS;
@@ -113,7 +126,7 @@ int InitShareMemory()
     else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
     else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
     {
     {
         result = FAIL;
         result = FAIL;
-     }
+    }
     else
     else
     {}
     {}
 
 
@@ -129,10 +142,9 @@ int InitShareMemory()
     else
     else
     {}
     {}
 
 
-    if(CHAdeMO_QUANTITY > 0)
-    {
+    if (CHAdeMO_QUANTITY > 0) {
         if ((MeterSMId = shmget(ShmCHAdeMOCommKey, sizeof(struct CHAdeMOData),
         if ((MeterSMId = shmget(ShmCHAdeMOCommKey, sizeof(struct CHAdeMOData),
-                IPC_CREAT | 0777)) < 0) {
+        IPC_CREAT | 0777)) < 0) {
             result = FAIL;
             result = FAIL;
         } else if ((ShmCHAdeMOData = shmat(MeterSMId, NULL, 0))
         } else if ((ShmCHAdeMOData = shmat(MeterSMId, NULL, 0))
                 == (void *) -1) {
                 == (void *) -1) {
@@ -141,10 +153,9 @@ int InitShareMemory()
         }
         }
     }
     }
 
 
-    if(CCS_QUANTITY > 0)
-    {
+    if (CCS_QUANTITY > 0) {
         if ((MeterSMId = shmget(ShmCcsCommKey, sizeof(struct CcsData),
         if ((MeterSMId = shmget(ShmCcsCommKey, sizeof(struct CcsData),
-                IPC_CREAT | 0777)) < 0) {
+        IPC_CREAT | 0777)) < 0) {
             result = FAIL;
             result = FAIL;
         } else if ((ShmCcsData = shmat(MeterSMId, NULL, 0)) == (void *) -1) {
         } else if ((ShmCcsData = shmat(MeterSMId, NULL, 0)) == (void *) -1) {
             result = FAIL;
             result = FAIL;
@@ -152,8 +163,7 @@ int InitShareMemory()
         }
         }
     }
     }
 
 
-    if (GB_QUANTITY > 0)
-    {
+    if (GB_QUANTITY > 0) {
         if ((MeterSMId = shmget(ShmGBTCommKey, sizeof(struct GBTData),
         if ((MeterSMId = shmget(ShmGBTCommKey, sizeof(struct GBTData),
         IPC_CREAT | 0777)) < 0) {
         IPC_CREAT | 0777)) < 0) {
             return 0;
             return 0;
@@ -205,37 +215,66 @@ int InitShareMemory()
 void RunStatusProc(char *v1, char *v2)
 void RunStatusProc(char *v1, char *v2)
 {
 {
     int _index = atoi(v1);
     int _index = atoi(v1);
-    if (!FindChargingInfoData(_index, &_chargingData[0]))
+    if (_index <= 1)
     {
     {
-        printf ("FindChargingInfoData error\n");
-        return;
-    }
+        if (!FindChargingInfoData(_index, &_chargingData[0]))
+        {
+            printf ("FindChargingInfoData error\n");
+            return;
+        }
 
 
-    if (strcmp(v2, "-1") == 0 || strcmp(v2, "") == 0)
-    {
-        // get
-        printf ("index = %x, status = %x (%d)\n", _index, _chargingData[_index]->SystemStatus, _chargingData[_index]->IsAvailable);
-        printf ("SystemTimeoutFlag = %d, PageIndex = %d\n",
-                ShmSysConfigAndInfo->SysInfo.SystemTimeoutFlag, ShmSysConfigAndInfo->SysInfo.PageIndex);
+        if (strcmp(v2, "-1") == 0 || strcmp(v2, "") == 0)
+        {
+            // get
+            printf ("index = %x, status = %x (%d)\n", _index, _chargingData[_index]->SystemStatus, _chargingData[_index]->IsAvailable);
+            printf ("SystemTimeoutFlag = %d, PageIndex = %d\n",
+                    ShmSysConfigAndInfo->SysInfo.SystemTimeoutFlag, ShmSysConfigAndInfo->SysInfo.PageIndex);
+        }
+        else
+        {
+            // set
+            _chargingData[_index]->SystemStatus = atoi(v2);
+        }
     }
     }
     else
     else
     {
     {
-        // set
-        _chargingData[_index]->SystemStatus = atoi(v2);
+        if (!FindAcChargingInfoData(0, &ac_chargingInfo[0]))
+        {
+            printf("FindChargingInfoData (AC) false \n");
+        }
+
+        if (strcmp(v2, "-1") == 0 || strcmp(v2, "") == 0)
+        {
+            // get
+            printf ("AC Type, status = %x (%d)\n", ac_chargingInfo[0]->SystemStatus, ac_chargingInfo[0]->IsAvailable);
+        }
+        else
+        {
+            // set
+            ac_chargingInfo[0]->SystemStatus = atoi(v2);
+        }
     }
     }
 }
 }
 
 
 void RunCardProc(char *v1, char *v2)
 void RunCardProc(char *v1, char *v2)
 {
 {
-    if (ShmSysConfigAndInfo->SysInfo.WaitForPlugit)
+    if (strcmp(v1, "-1") == 0 || strcmp(v1, "") == 0)
     {
     {
-        ShmSysConfigAndInfo->SysInfo.WaitForPlugit = 0x00;
-        printf ("SysInfo.WaitForPlugit = %x \n", ShmSysConfigAndInfo->SysInfo.WaitForPlugit);
+        if (ShmSysConfigAndInfo->SysInfo.WaitForPlugit)
+        {
+            ShmSysConfigAndInfo->SysInfo.WaitForPlugit = 0x00;
+            printf ("SysInfo.WaitForPlugit = %x \n", ShmSysConfigAndInfo->SysInfo.WaitForPlugit);
+        }
+        else
+        {
+            ShmSysConfigAndInfo->SysInfo.WaitForPlugit = 0x01;
+            printf ("SysInfo.WaitForPlugit = %x \n", ShmSysConfigAndInfo->SysInfo.WaitForPlugit);
+        }
     }
     }
     else
     else
     {
     {
-        ShmSysConfigAndInfo->SysInfo.WaitForPlugit = 0x01;
-        printf ("SysInfo.WaitForPlugit = %x \n", ShmSysConfigAndInfo->SysInfo.WaitForPlugit);
+        memcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, v1, ARRAY_SIZE(v1));
+        printf("StartUserId = %s \n", ShmSysConfigAndInfo->SysConfig.UserId);
     }
     }
 }
 }
 
 
@@ -313,6 +352,22 @@ void GetFwVerProc(char *v1)
     {
     {
         printf("DC Main Version = %s \n", ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev);
         printf("DC Main Version = %s \n", ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev);
     }
     }
+    else if (strcmp(v1, "ac") == 0)
+    {
+        if (!FindAcChargingInfoData(0, &ac_chargingInfo[0]))
+        {
+            printf("FindChargingInfoData (AC) false \n");
+        }
+        printf("AC Version = %s \n", ac_chargingInfo[0]->version);
+    }
+}
+
+void CreateOneError(char *v1)
+{
+    int value = atoi(v1);
+
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PrimaryStestFail = value;
+    ShmSysConfigAndInfo->SysConfig.BillingData.isBilling = value;
 }
 }
 
 
 void FwUpdateFlagProc()
 void FwUpdateFlagProc()
@@ -344,6 +399,10 @@ void SetPowerValue(char *v1, char *v2)
 {
 {
     int _index = atoi(v1);
     int _index = atoi(v1);
     float _Current = atof(v2);
     float _Current = atof(v2);
+    // 盲沖的時候才允許使用~
+    if (_chargingData[_index]->Type != 9)
+        return;
+
     if (!FindChargingInfoData(_index, &_chargingData[0]))
     if (!FindChargingInfoData(_index, &_chargingData[0]))
     {
     {
         printf ("FindChargingInfoData error\n");
         printf ("FindChargingInfoData error\n");
@@ -361,15 +420,49 @@ void GetSystemInfo()
             ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent);
             ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent);
 }
 }
 
 
+void ChangeGunNum()
+{
+    if (ShmSysConfigAndInfo->SysInfo.CurGunSelected + 1 < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount)
+    {
+        ShmSysConfigAndInfo->SysInfo.CurGunSelected += 1;
+        ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = NO_DEFINE;
+    }
+    else if (ShmSysConfigAndInfo->SysConfig.AcConnectorCount > 0 &&
+            ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc == NO_DEFINE)
+        ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = DEFAULT_AC_INDEX;
+    else
+    {
+        ShmSysConfigAndInfo->SysInfo.CurGunSelected = 0;
+        ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = NO_DEFINE;
+    }
+}
+
 void GetGunSelectedNum(char *v1)
 void GetGunSelectedNum(char *v1)
 {
 {
     if (strcmp(v1, "-1") == 0 || strcmp(v1, "") == 0)
     if (strcmp(v1, "-1") == 0 || strcmp(v1, "") == 0)
-        printf("connector selected = %d \n", ShmSysConfigAndInfo->SysInfo.CurGunSelected);
+    {
+        if (AC_QUANTITY > 0 &&
+            ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc != NO_DEFINE)
+        {
+            printf("connector select changed = AC \n");
+        }
+        else
+            printf("connector selected = %d \n", ShmSysConfigAndInfo->SysInfo.CurGunSelected);
+    }
     else
     else
     {
     {
         int _index = atoi(v1);
         int _index = atoi(v1);
-        ShmSysConfigAndInfo->SysInfo.CurGunSelected = _index;
-        printf("connector select changed = %d \n", _index);
+        if (_index <= 1)
+        {
+            ShmSysConfigAndInfo->SysInfo.CurGunSelected = _index;
+            ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = NO_DEFINE;
+            printf("connector select changed = %d \n", _index);
+        }
+        else if (AC_QUANTITY > 0)
+        {
+            ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = DEFAULT_AC_INDEX;
+            printf("connector select changed = AC \n");
+        }
     }
     }
 }
 }
 
 
@@ -395,6 +488,13 @@ void SetDebugMode(char *v1)
     ShmSysConfigAndInfo->SysConfig.SwitchDebugFlag = mode;
     ShmSysConfigAndInfo->SysConfig.SwitchDebugFlag = mode;
 }
 }
 
 
+void SetGFDMode(char *v1)
+{
+    int mode = atoi(v1);
+
+    ShmSysConfigAndInfo->SysConfig.AlwaysGfdFlag = mode;
+}
+
 void GetPsuTemp()
 void GetPsuTemp()
 {
 {
     for (byte index = 0; index < ShmPsuData->GroupCount; index++)
     for (byte index = 0; index < ShmPsuData->GroupCount; index++)
@@ -406,9 +506,17 @@ void GetPsuTemp()
     }
     }
 }
 }
 
 
+void GetAcInputVol()
+{
+    printf("L1N_L12 = %f, L2N_L23 = %f, L3N_L31 = %f \n",
+            ShmSysConfigAndInfo->SysInfo.InputVoltageR,
+            ShmSysConfigAndInfo->SysInfo.InputVoltageS,
+            ShmSysConfigAndInfo->SysInfo.InputVoltageT);
+}
+
 void GetPsuInformation(char *v1)
 void GetPsuInformation(char *v1)
 {
 {
-    printf("**********************須搭上 AC Contact*************************\n");
+    printf("**********************AC Contact needed*************************\n");
     if(strcmp(v1, "count") == 0)
     if(strcmp(v1, "count") == 0)
     {
     {
         for (int i = 0; i < 4; i++)
         for (int i = 0; i < 4; i++)
@@ -418,6 +526,12 @@ void GetPsuInformation(char *v1)
     }
     }
     else if(strcmp(v1, "ver") == 0)
     else if(strcmp(v1, "ver") == 0)
     {
     {
+        for (int i = 0; i < ShmPsuData->SystemPresentPsuQuantity; i++)
+        {
+            printf("Psu Index = %d, PriVersion = %s, SecVersion = %s \n",
+                    i, ShmPsuData->PsuVersion[i].FwPrimaryVersion, ShmPsuData->PsuVersion[i].FwSecondVersion);
+        }
+
         for (int i = 0; i < ShmPsuData->GroupCount; i++)
         for (int i = 0; i < ShmPsuData->GroupCount; i++)
         {
         {
             for (int j = 0; j < ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity; j++)
             for (int j = 0; j < ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity; j++)
@@ -446,11 +560,31 @@ void GetPsuInformation(char *v1)
     printf("*************************************************\n");
     printf("*************************************************\n");
 }
 }
 
 
-static int get_char()
+void GetConnectorCapInfo(char *v1)
+{
+    int _GunIndex = atoi(v1);
+
+    if (!FindChargingInfoData(_GunIndex, &_chargingData[0]))
+    {
+        printf ("FindChargingInfoData error\n");
+        return;
+    }
+
+    printf ("Charger Max Current = %d, Max Power = %d \n",
+            ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent * 10,
+            ShmSysConfigAndInfo->SysConfig.MaxChargingPower * 10);
+
+    printf ("Index = %d, MaxPow = %f, MaxVol = %f, MaxCur = %f\n",
+            _GunIndex,
+            _chargingData[_GunIndex]->RealMaxPower,
+            _chargingData[_GunIndex]->RealMaxVoltage,
+            _chargingData[_GunIndex]->RealMaxCurrent);
+}
+
+static void get_char(char *word)
 {
 {
     fd_set rfds;
     fd_set rfds;
     struct timeval tv;
     struct timeval tv;
-    int ch = 0;
 
 
     FD_ZERO(&rfds);
     FD_ZERO(&rfds);
     FD_SET(0, &rfds);
     FD_SET(0, &rfds);
@@ -460,10 +594,8 @@ static int get_char()
     //if input
     //if input
     if (select(1, &rfds, NULL, NULL, &tv) > 0)
     if (select(1, &rfds, NULL, NULL, &tv) > 0)
     {
     {
-        ch = getchar();
+        fgets(word, 128, stdin);
     }
     }
-
-    return ch;
 }
 }
 
 
 void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
 void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
@@ -472,7 +604,6 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
     float _Voltage = atof(v2);
     float _Voltage = atof(v2);
     float _Current = atof(v3);
     float _Current = atof(v3);
     unsigned char PreviousSystemStatus = 0xff;
     unsigned char PreviousSystemStatus = 0xff;
-    int ch = 0;
 
 
     if (!FindChargingInfoData(_GunIndex, &_chargingData[0]))
     if (!FindChargingInfoData(_GunIndex, &_chargingData[0]))
     {
     {
@@ -635,8 +766,8 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
                 }
                 }
                 else if (_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus > 0x02)
                 else if (_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus > 0x02)
                 {
                 {
-                         printf ("First Ground Fault check Fail (%d)\n",_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus);
-                        _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_TERMINATING;
+                    printf ("First Ground Fault check Fail (%d)\n",_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus);
+                    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_TERMINATING;
                 }
                 }
 
 
             }
             }
@@ -658,7 +789,8 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
                 }
                 }
 
 
                 //ev task do this
                 //ev task do this
-                _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingPower = ((float)((_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingVoltage) * (_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->PresentChargingCurrent)) / 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){
                 if (_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus == 0x02){
                      printf ("Charging Ground Fault check Fail (%d)\n",_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus);
                      printf ("Charging Ground Fault check Fail (%d)\n",_chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->GroundFaultStatus);
@@ -699,7 +831,6 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
                     PreviousSystemStatus = _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus;
                     PreviousSystemStatus = _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus;
 
 
                     printf ("[UnconditionalCharge - S_COMPLETE]\n");
                     printf ("[UnconditionalCharge - S_COMPLETE]\n");
-
                 }
                 }
                 sleep(3);
                 sleep(3);
                 return;
                 return;
@@ -707,51 +838,60 @@ void RunUnconditionalChargeIndex1(char *v1, char *v2, char *v3)
             break;
             break;
         }
         }
 
 
-        /*
-        //使用 Keyboard input 阻塞方法
-        fgets(InputChar, sizeof(InputChar), stdin);
+        char word[128];
+        char newString[7][10];
+        int i,j,ctr;
 
 
-        if (InputChar[0] == 's' && InputChar[1] == 't' && InputChar[2] == 'o' && InputChar[3] == 'p')
-        {
-           printf ("Precharge Done\n");
-           _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_TERMINATING;
+        memset(word, 0x00, sizeof(word));
+        get_char(word);
 
 
-        }
-        */
+        if (strlen(word) == 0)
+            continue;
 
 
-        //使用 keybaord input 非阻塞方法
-        ch = get_char();
-        if (ch)
+        j=0; ctr=0;
+        strcpy(newString[1], "-1");
+        strcpy(newString[2], "-1");
+        for (i = 0; i <= (strlen(word)); i++)
         {
         {
-            printf("%c \n\r", ch);
-
-            switch (ch)
+            if (word[i] == ' ' || word[i] == '\0' || word[i] == 10)
             {
             {
-                //Ctrl + C
-                case 3:
-                    //system(STTY_DEF TTY_PATH);
-                        return;
-                //input c or C
-                case 'c':
-                case 'C':
-                    printf("stop \n\r");
-                    //system(STTY_DEF TTY_PATH);
-                    ShmSysConfigAndInfo->SysInfo.StartToChargingFlag = 0x00;
-                    _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_TERMINATING;
-                    break;
+                newString[ctr][j] = '\0';
+                ctr++;
+                j = 0;
+            }
+            else
+            {
+                newString[ctr][j] = word[i];
+                j++;
             }
             }
         }
         }
 
 
-    }
+        if(strcmp(newString[0], "chg") == 0)
+        {
+            if (strcmp(newString[1], "-1") == 0 || strcmp(newString[1], "") == 0)
+               continue;
+            if (strcmp(newString[2], "-1") == 0 || strcmp(newString[2], "") == 0)
+               continue;
 
 
-}
+            float _vol = atof(newString[1]);
+            float _cur = atof(newString[2]);
 
 
-void test()
-{
-    printf("L1 = %d, L2 = %d, L3 = %d \n", ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP,
-            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP,
-            ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP);
-    printf("ExtraErrProcess = %d \n", ShmSysConfigAndInfo->SysWarningInfo.ExtraErrProcess);
+            if (_cur <= 0 || _cur <= 0)
+               continue;
+
+            printf("vol = %f, cur = %f \n", _vol, _cur);
+            _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetVoltage = _vol * 10;
+            _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->EvBatterytargetCurrent = _cur * 10;
+        }
+        else if (strcmp(newString[0], "c") == 0)
+        {
+            printf("stop \n\r");
+            ShmSysConfigAndInfo->SysInfo.StartToChargingFlag = 0x00;
+            _chargingData[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_TERMINATING;
+        }
+
+        usleep(100000);
+    }
 }
 }
 
 
 int main(void)
 int main(void)
@@ -869,9 +1009,14 @@ int main(void)
         }
         }
         else if(strcmp(newString[0], "select") == 0)
         else if(strcmp(newString[0], "select") == 0)
         {
         {
-            // 取得當前選的槍號
+            // 取得 / 設定 當前選的槍號
             GetGunSelectedNum(newString[1]);
             GetGunSelectedNum(newString[1]);
         }
         }
+        else if(strcmp(newString[0], "change") == 0)
+        {
+            // 模擬按鈕改變選槍
+            ChangeGunNum();
+        }
         else if(strcmp(newString[0], "fan") == 0)
         else if(strcmp(newString[0], "fan") == 0)
         {
         {
             // 設定風扇速度
             // 設定風扇速度
@@ -887,11 +1032,21 @@ int main(void)
             // 設定 debug mode
             // 設定 debug mode
             SetDebugMode(newString[1]);
             SetDebugMode(newString[1]);
         }
         }
+        else if (strcmp(newString[0], "gfd") == 0)
+        {
+            // 設定盲沖使用 GFD 功能
+            SetGFDMode(newString[1]);
+        }
         else if(strcmp(newString[0], "temp") == 0)
         else if(strcmp(newString[0], "temp") == 0)
         {
         {
             // 取得 PSU 溫度
             // 取得 PSU 溫度
             GetPsuTemp();
             GetPsuTemp();
         }
         }
+        else if(strcmp(newString[0], "acin") == 0)
+        {
+            // 取得三向輸入電壓
+            GetAcInputVol();
+        }
         else if(strcmp(newString[0], "psu") == 0)
         else if(strcmp(newString[0], "psu") == 0)
         {
         {
             //如果連一個參數都沒有 (此命令不理會) 加上判斷第二參數
             //如果連一個參數都沒有 (此命令不理會) 加上判斷第二參數
@@ -904,9 +1059,13 @@ int main(void)
             // 取得 PSU 資訊
             // 取得 PSU 資訊
             GetPsuInformation(newString[1]);
             GetPsuInformation(newString[1]);
         }
         }
-        else if(strcmp(newString[0], "test") == 0)
+        else if (strcmp(newString[0], "cap") == 0)
+        {
+            GetConnectorCapInfo(newString[1]);
+        }
+        else if(strcmp(newString[0], "error") == 0)
         {
         {
-            test();
+            CreateOneError(newString[1]);
         }
         }
         else if(strcmp(newString[0], "strchg") == 0)
         else if(strcmp(newString[0], "strchg") == 0)
         {
         {

+ 319 - 11
EVSE/Projects/DM30/Apps/internalComm.c

@@ -38,8 +38,9 @@
 #define PASS                1
 #define PASS                1
 #define FAIL                -1
 #define FAIL                -1
 
 
-struct Address Addr={0x01,0x02,0x03,0xFF};
-struct Command Cmd={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x81,0x83,0x85,0x86, 0x87,0x8B,0xe0,0xe1,0xe2,0xe3};
+struct Address Addr={0x01,0x02,0x03,0x05,0xFF};
+struct Command Cmd={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x27,0x28,0x29,0x2C,0x81,0x83,
+                    0x85,0x86,0x87,0x88,0x089,0x8A,0x8B,0x8C,0x90,0xe0,0xe1,0xe2,0xe3};
 
 
 int tranceive(int fd, unsigned char* cmd, unsigned char cmd_len, unsigned char* rx)
 int tranceive(int fd, unsigned char* cmd, unsigned char cmd_len, unsigned char* rx)
 {
 {
@@ -48,7 +49,7 @@ int tranceive(int fd, unsigned char* cmd, unsigned char cmd_len, unsigned char*
     tcflush(fd,TCIOFLUSH);
     tcflush(fd,TCIOFLUSH);
     if(write(fd, cmd, cmd_len) >= cmd_len)
     if(write(fd, cmd, cmd_len) >= cmd_len)
     {
     {
-        usleep(30000);
+        usleep(15000);
         len = read(fd, rx, 512);
         len = read(fd, rx, 512);
     }
     }
     else
     else
@@ -551,8 +552,7 @@ unsigned char Config_Gpio_Output(unsigned char fd, unsigned char targetAddr, Gpi
         if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
         if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
            (rx[2] == tx[1]) &&
            (rx[2] == tx[1]) &&
            (rx[1] == tx[2]) &&
            (rx[1] == tx[2]) &&
-           (rx[3] == tx[3]) &&
-           (rx[6] == tx[6]))
+           (rx[3] == tx[3]))
         {
         {
             result = PASS;
             result = PASS;
         }
         }
@@ -591,8 +591,7 @@ unsigned char Config_Gfd_Value(unsigned char fd, unsigned char targetAddr, Gfd_c
         if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
         if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
            (rx[2] == tx[1]) &&
            (rx[2] == tx[1]) &&
            (rx[1] == tx[2]) &&
            (rx[1] == tx[2]) &&
-           (rx[3] == tx[3]) &&
-           (rx[6] == tx[6]))
+           (rx[3] == tx[3]))
         {
         {
             result = PASS;
             result = PASS;
         }
         }
@@ -634,8 +633,7 @@ unsigned char Config_Model_Name(unsigned char fd, unsigned char targetAddr, unsi
         if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
         if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
               (rx[2] == tx[1]) &&
               (rx[2] == tx[1]) &&
               (rx[1] == tx[2]) &&
               (rx[1] == tx[2]) &&
-              (rx[3] == tx[3]) &&
-              (rx[6] == tx[6]))
+              (rx[3] == tx[3]))
         {
         {
             result = PASS;
             result = PASS;
         }
         }
@@ -668,8 +666,7 @@ unsigned char Config_Rtc_Data(unsigned char fd, unsigned char targetAddr, Rtc *S
         if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
         if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
                 (rx[2] == tx[1]) &&
                 (rx[2] == tx[1]) &&
                 (rx[1] == tx[2]) &&
                 (rx[1] == tx[2]) &&
-                (rx[3] == tx[3]) &&
-                (rx[6] == tx[6]))
+                (rx[3] == tx[3]))
         {
         {
             result = PASS;
             result = PASS;
         }
         }
@@ -823,3 +820,314 @@ unsigned char Update_Finish(unsigned char fd, unsigned char targetAddr)
 
 
     return result;
     return result;
 }
 }
+
+unsigned char Query_AC_Status(unsigned char fd, unsigned char targetAddr, Ac_Status *Ret_Buf)
+{
+    unsigned char result = FAIL;
+    unsigned char tx[7] = {0xaa, 0x00, targetAddr, Cmd.query_ac_status, 0x00, 0x00, 0x00};
+    unsigned char rx[512];
+    unsigned char chksum = 0x00;
+    unsigned char len = tranceive(fd, tx, sizeof(tx), rx);
+
+    if(len > 6)
+    {
+        if (len < 6+(rx[4] | rx[5]<<8))
+            return result;
+
+        for(int idx = 0;idx<(rx[4] | rx[5]<<8);idx++)
+        {
+            chksum ^= rx[6+idx];
+        }
+
+        if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
+                (rx[2] == tx[1]) &&
+                (rx[1] == tx[2]) &&
+                (rx[3] == tx[3]))
+        {
+            Ret_Buf->CpStatus = rx[6];
+            Ret_Buf->CurLimit = (rx[7] | (rx[8] << 8));
+            Ret_Buf->PilotVol_P = (rx[9] | (rx[10] << 8));
+            Ret_Buf->PilotVol_N = (rx[11] | (rx[12] << 8));
+            Ret_Buf->LockStatus = rx[13];
+            Ret_Buf->RelayStatus = rx[14];
+            Ret_Buf->ShutterStatus = rx[15];
+            Ret_Buf->MeterStatus = rx[16];
+            Ret_Buf->PpStatus = rx[17];
+            Ret_Buf->MaxCurrent = rx[18];
+            Ret_Buf->RotateSwitchStatus = rx[19];
+//
+//          Ret_Buf->AC_Connector       = (rx[6] >> 0) & 0x01;
+//          Ret_Buf->AC_MainBreaker     = (rx[6] >> 1) & 0x01;
+//          Ret_Buf->SPD                = (rx[6] >> 2) & 0x01;
+//          Ret_Buf->Door_Open          = (rx[6] >> 3) & 0x01;
+//          Ret_Buf->GFD[0]             = (rx[6] >> 4) & 0x01;
+//          Ret_Buf->GFD[1]             = (rx[6] >> 5) & 0x01;
+//          Ret_Buf->AC_Drop            = (rx[6] >> 6) & 0x01;
+//
+//          Ret_Buf->Emergency_IO       = (rx[7] >> 0) & 0x01;
+//
+//          Ret_Buf->Button_Emergency_Press = (rx[8] >> 0) & 0x01;
+//          Ret_Buf->Button_On_Press    = (rx[8] >> 1) & 0x01;
+//          Ret_Buf->Button_Off_Press   = (rx[8] >> 2) & 0x01;
+//          Ret_Buf->Key_1_Press        = (rx[8] >> 3) & 0x01;
+//          Ret_Buf->Key_2_Press        = (rx[8] >> 4) & 0x01;
+//          Ret_Buf->Key_3_Press        = (rx[8] >> 5) & 0x01;
+//          Ret_Buf->Key_4_Press        = (rx[8] >> 6) & 0x01;
+
+            result = PASS;
+        }
+    }
+
+    return result;
+}
+
+unsigned char Query_AC_Alarm_Code(unsigned char fd, unsigned char targetAddr, Ac_Alarm_code *Ret_Buf)
+{
+    unsigned char result = FAIL;
+    unsigned char tx[7] = {0xaa, 0x00, targetAddr, Cmd.query_ac_alarm_code, 0x00, 0x00};
+    unsigned char rx[512];
+    unsigned char chksum = 0x00;
+    unsigned char len = tranceive(fd, tx, sizeof(tx), rx);
+
+    if(len > 6)
+    {
+        if (len < 6+(rx[4] | rx[5]<<8))
+            return result;
+
+        for(int idx = 0;idx<(rx[4] | rx[5]<<8);idx++)
+        {
+            chksum ^= rx[6+idx];
+        }
+
+        if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
+           (rx[2] == tx[1]) &&
+           (rx[1] == tx[2]) &&
+           (rx[3] == tx[3]))
+        {
+            Ret_Buf->AcAlarmCode = rx[6] + (rx[7] << 8) + (rx[8] << 16) + (rx[9] << 24);
+            result = PASS;
+        }
+    }
+
+    return result;
+}
+
+unsigned char Query_Charging_Energy(unsigned char fd, unsigned char targetAddr, Ac_Charging_energy *Ret_Buf)
+{
+    unsigned char result = FAIL;
+    unsigned char tx[7] = {0xaa, 0x00, targetAddr, Cmd.query_ac_output_energy, 0x00, 0x00,0x00};
+    unsigned char rx[512];
+    unsigned char chksum = 0x00;
+    unsigned char len = tranceive(fd, tx, sizeof(tx), rx);
+
+    if(len > 6)
+    {
+        if (len < 6+(rx[4] | rx[5]<<8))
+            return result;
+
+        for(int idx = 0;idx<(rx[4] | rx[5]<<8);idx++)
+        {
+            chksum ^= rx[6+idx];
+        }
+
+        if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
+           (rx[2] == tx[1]) &&
+           (rx[1] == tx[2]) &&
+           (rx[3] == tx[3]))
+        {
+            Ret_Buf->Energy = rx[6] + (rx[7] << 8) + (rx[8] << 16) + (rx[9] << 24);
+            result = PASS;
+        }
+    }
+
+    return result;
+}
+
+unsigned char Query_Charging_Current(unsigned char fd, unsigned char targetAddr, Ac_Charging_current *Ret_Buf)
+{
+    unsigned char result = FAIL;
+    unsigned char tx[7] = {0xaa, 0x00, targetAddr, Cmd.query_ac_output_current, 0x00, 0x00, 0x00};
+    unsigned char rx[512];
+    unsigned char chksum = 0x00;
+    unsigned char len = tranceive(fd, tx, sizeof(tx), rx);
+
+    if(len > 6)
+    {
+        if (len < 6+(rx[4] | rx[5]<<8))
+            return result;
+
+        for(int idx = 0;idx<(rx[4] | rx[5]<<8);idx++)
+        {
+            chksum ^= rx[6+idx];
+        }
+
+        if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
+           (rx[2] == tx[1]) &&
+           (rx[1] == tx[2]) &&
+           (rx[3] == tx[3]))
+        {
+            Ret_Buf->OuputCurrentL1 = rx[6] + (rx[7] << 8);
+            Ret_Buf->OuputCurrentL2 = rx[8] + (rx[9] << 8);
+            Ret_Buf->OuputCurrentL3 = rx[10] + (rx[11] << 8);
+            result = PASS;
+        }
+    }
+
+    return result;
+}
+
+unsigned char Config_LED_Status(unsigned char fd, unsigned char targetAddr, Ac_Led_Status *Ret_Buf)
+{
+    unsigned char result = FAIL;
+    unsigned char tx[12] = {0xaa, 0x00, targetAddr, Cmd.config_ac_led_status, 0x05, 0x00, Ret_Buf->ActionMode, (Ret_Buf->AcAlarmCode >> 0) & 0xFF,
+            (Ret_Buf->AcAlarmCode >> 8) & 0xFF, (Ret_Buf->AcAlarmCode >> 16) & 0xFF, (Ret_Buf->AcAlarmCode >> 24) & 0xFF};
+    unsigned char rx[512];
+    unsigned char chksum = 0x00;
+
+    for (int idx = 0; idx < (tx[4] | tx[5] << 8); idx++)
+        chksum ^= tx[6 + idx];
+    tx[11] = chksum;
+
+    if (tranceive(fd, tx, sizeof(tx), rx) > 0)
+    {
+        chksum = 0x00;
+        for (int idx = 0; idx < (rx[4] | rx[5] << 8); idx++)
+        {
+            chksum ^= rx[6 + idx];
+        }
+
+        if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
+            (rx[2] == tx[1]) &&
+            (rx[1] == tx[2]) &&
+            (rx[3] == tx[3]))
+        {
+            result = PASS;
+        }
+    }
+
+    return result;
+}
+
+unsigned char Config_Legacy_Req(unsigned char fd, unsigned char targetAddr, unsigned char _switch)
+{
+    unsigned char result = FAIL;
+    unsigned char tx[9] = {0xaa, 0x00, targetAddr, Cmd.config_Legacy_Req, 0x02, 0x00, _switch, 0x00};
+    unsigned char rx[512];
+    unsigned char chksum = 0x00;
+
+    for (int idx = 0; idx < (tx[4] | tx[5] << 8); idx++)
+        chksum ^= tx[6 + idx];
+    tx[8] = chksum;
+
+    if (tranceive(fd, tx, sizeof(tx), rx) > 0)
+    {
+        chksum = 0x00;
+        for (int idx = 0; idx < (rx[4] | rx[5] << 8); idx++)
+        {
+            chksum ^= rx[6 + idx];
+        }
+
+        if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
+           (rx[2] == tx[1]) &&
+           (rx[1] == tx[2]) &&
+           (rx[3] == tx[3]))
+        {
+            result = PASS;
+        }
+    }
+
+    return result;
+}
+
+unsigned char Config_Ac_Duty(unsigned char fd, unsigned char targetAddr, unsigned char _value)
+{
+    unsigned char result = FAIL;
+    unsigned char tx[8] = {0xaa, 0x00, targetAddr, Cmd.config_ac_duty, 0x01, 0x00, _value};
+    unsigned char rx[512];
+    unsigned char chksum = 0x00;
+
+    for (int idx = 0; idx < (tx[4] | tx[5] << 8); idx++)
+        chksum ^= tx[6 + idx];
+    tx[7] = chksum;
+
+    if (tranceive(fd, tx, sizeof(tx), rx) > 0)
+    {
+        chksum = 0x00;
+        for (int idx = 0; idx < (rx[4] | rx[5] << 8); idx++)
+        {
+            chksum ^= rx[6 + idx];
+        }
+
+        if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
+           (rx[2] == tx[1]) &&
+           (rx[1] == tx[2]) &&
+           (rx[3] == tx[3]))
+        {
+            result = PASS;
+        }
+    }
+
+    return result;
+}
+
+unsigned char Config_CSU_Mode(unsigned char fd, unsigned char targetAddr)
+{
+    unsigned char result = FAIL;
+    unsigned char tx[9] = {0xaa, 0x00, targetAddr, Cmd.config_csu_mode, 0x02, 0x00, 0x01, 0x00};
+    unsigned char rx[512];
+    unsigned char chksum = 0x00;
+
+    for (int idx = 0; idx < (tx[4] | tx[5] << 8); idx++)
+        chksum ^= tx[6 + idx];
+    tx[7] = chksum;
+
+    if (tranceive(fd, tx, sizeof(tx), rx) > 0)
+    {
+        chksum = 0x00;
+        for (int idx = 0; idx < (rx[4] | rx[5] << 8); idx++)
+        {
+            chksum ^= rx[6 + idx];
+        }
+
+        if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
+           (rx[2] == tx[1]) &&
+           (rx[1] == tx[2]) &&
+           (rx[3] == tx[3]))
+        {
+            result = PASS;
+        }
+    }
+
+    return result;
+}
+
+unsigned char Config_Reset_MCU(unsigned char fd, unsigned char targetAddr)
+{
+    unsigned char result = FAIL;
+    unsigned char tx[9] = {0xaa, 0x00, targetAddr, Cmd.config_reset_mcu, 0x02, 0x00, 0x01, 0x00};
+    unsigned char rx[512];
+    unsigned char chksum = 0x00;
+
+    for (int idx = 0; idx < (tx[4] | tx[5] << 8); idx++)
+        chksum ^= tx[6 + idx];
+    tx[7] = chksum;
+
+    if (tranceive(fd, tx, sizeof(tx), rx) > 0)
+    {
+        chksum = 0x00;
+        for (int idx = 0; idx < (rx[4] | rx[5] << 8); idx++)
+        {
+            chksum ^= rx[6 + idx];
+        }
+
+        if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
+           (rx[2] == tx[1]) &&
+           (rx[1] == tx[2]) &&
+           (rx[3] == tx[3]))
+        {
+            result = PASS;
+        }
+    }
+
+    return result;
+}

+ 66 - 0
EVSE/Projects/DM30/Apps/internalComm.h

@@ -13,6 +13,7 @@ extern struct Address
     unsigned char Aux;
     unsigned char Aux;
     unsigned char Fan;
     unsigned char Fan;
     unsigned char Relay;
     unsigned char Relay;
+    unsigned char AcPlug;
     unsigned char Broadcast;
     unsigned char Broadcast;
 }Addr;
 }Addr;
 
 
@@ -29,12 +30,25 @@ extern struct Command
     unsigned char query_Gfd_Adc;                //0x09
     unsigned char query_Gfd_Adc;                //0x09
     unsigned char query_Gpio_In;                //0x0a
     unsigned char query_Gpio_In;                //0x0a
 
 
+    unsigned char query_ac_output_current;      //0x27
+    unsigned char query_ac_status;              //0x28
+    unsigned char query_ac_alarm_code;          //0x29
+
+    unsigned char query_ac_output_energy;       //0x2C
+
     unsigned char config_Fan_Speed;             //0x81
     unsigned char config_Fan_Speed;             //0x81
     unsigned char config_Model_Name;            //0x83
     unsigned char config_Model_Name;            //0x83
     unsigned char config_Relay_Output;          //0x85
     unsigned char config_Relay_Output;          //0x85
     unsigned char config_Gpio_Output;           //0x86
     unsigned char config_Gpio_Output;           //0x86
     unsigned char config_Rtc_Data;              //0x87
     unsigned char config_Rtc_Data;              //0x87
+    unsigned char config_ac_led_status;         //0x88
+
+    unsigned char config_ac_duty;               //0x89
+    unsigned char config_Legacy_Req;            //0x8A
     unsigned char config_Gfd_Value;             //0x8B
     unsigned char config_Gfd_Value;             //0x8B
+    unsigned char config_reset_mcu;             //0x8C
+
+    unsigned char config_csu_mode;              //0x90
 
 
     unsigned char update_Start;                 //0xe0
     unsigned char update_Start;                 //0xe0
     unsigned char update_Abort;                 //0xe1
     unsigned char update_Abort;                 //0xe1
@@ -168,6 +182,49 @@ typedef struct RTC
     unsigned char RtcData[14];
     unsigned char RtcData[14];
 }Rtc;
 }Rtc;
 
 
+typedef struct AC_Status
+{
+    unsigned char       CpStatus;
+    unsigned short      CurLimit;
+    short               PilotVol_P;
+    short               PilotVol_N;
+    unsigned char       LockStatus;
+    unsigned char       RelayStatus;
+    unsigned char       ShutterStatus;
+    unsigned char       MeterStatus;
+    unsigned char       PpStatus;
+    unsigned char       MaxCurrent;
+    unsigned char       RotateSwitchStatus;
+}
+Ac_Status;
+
+typedef struct AC_LED_Status
+{
+    unsigned char       ActionMode;
+    unsigned long       AcAlarmCode;
+}
+Ac_Led_Status;
+
+typedef struct AC_Alarm_Code
+{
+    unsigned int        AcAlarmCode;
+}
+Ac_Alarm_code;
+
+typedef struct AC_Charging_Energy
+{
+    unsigned int        Energy;
+}
+Ac_Charging_energy;
+
+typedef struct AC_Charging_Current
+{
+    unsigned short      OuputCurrentL1;
+    unsigned short      OuputCurrentL2;
+    unsigned short      OuputCurrentL3;
+}
+Ac_Charging_current;
+
 extern unsigned char Query_FW_Ver(unsigned char fd, unsigned char targetAddr, Ver *Ret_Buf);
 extern unsigned char Query_FW_Ver(unsigned char fd, unsigned char targetAddr, Ver *Ret_Buf);
 extern unsigned char Query_HW_Ver(unsigned char fd, unsigned char targetAddr, Ver *Ret_Buf);
 extern unsigned char Query_HW_Ver(unsigned char fd, unsigned char targetAddr, Ver *Ret_Buf);
 extern unsigned char Query_Present_InputVoltage(unsigned char fd, unsigned char targetAddr, PresentInputVoltage *Ret_Buf);
 extern unsigned char Query_Present_InputVoltage(unsigned char fd, unsigned char targetAddr, PresentInputVoltage *Ret_Buf);
@@ -191,4 +248,13 @@ extern unsigned char Update_Abord(unsigned char fd, unsigned char targetAddr);
 extern unsigned char Update_Transfer(unsigned char fd, unsigned char targetAddr, unsigned int startAddr, unsigned char *data, unsigned short int length);
 extern unsigned char Update_Transfer(unsigned char fd, unsigned char targetAddr, unsigned int startAddr, unsigned char *data, unsigned short int length);
 extern unsigned char Update_Finish(unsigned char fd, unsigned char targetAddr);
 extern unsigned char Update_Finish(unsigned char fd, unsigned char targetAddr);
 
 
+extern unsigned char Query_AC_Status(unsigned char fd, unsigned char targetAddr, Ac_Status *Ret_Buf);
+extern unsigned char Query_AC_Alarm_Code(unsigned char fd, unsigned char targetAddr, Ac_Alarm_code *Ret_Buf);
+extern unsigned char Query_Charging_Energy(unsigned char fd, unsigned char targetAddr, Ac_Charging_energy *Ret_Buf);
+extern unsigned char Query_Charging_Current(unsigned char fd, unsigned char targetAddr, Ac_Charging_current *Ret_Buf);
+extern unsigned char Config_LED_Status(unsigned char fd, unsigned char targetAddr, Ac_Led_Status *Ret_Buf);
+extern unsigned char Config_Legacy_Req(unsigned char fd, unsigned char targetAddr, unsigned char _switch);
+extern unsigned char Config_Ac_Duty(unsigned char fd, unsigned char targetAddr, unsigned char _value);
+extern unsigned char Config_CSU_Mode(unsigned char fd, unsigned char targetAddr);
+extern unsigned char Config_Reset_MCU(unsigned char fd, unsigned char targetAddr);
 #endif /* INTERNALCOMM_H_ */
 #endif /* INTERNALCOMM_H_ */

File diff suppressed because it is too large
+ 379 - 145
EVSE/Projects/DM30/Apps/main.c


+ 1 - 0
EVSE/Projects/DM30/Apps/web.sh

@@ -0,0 +1 @@
+/sbin/lighttpd -f /etc/lighttpd/lighttpd.conf  -m /lib

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