#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /*標準輸入輸出定義*/ #include /*標準函數庫定義*/ #include /*Unix 標準函數定義*/ #include /*檔控制定義*/ #include /*PPSIX 終端控制定義*/ #include /*錯誤號定義*/ #include #include #include #include #include #include #include #include "../Define/define.h" #include "Module_InternalComm.h" #include "internalComm.h" #include "../Config.h" //------------------------------------------------------------------------------ struct SysConfigAndInfo *ShmSysConfigAndInfo; struct StatusCodeData *ShmStatusCodeData; struct FanModuleData *ShmFanModuleData; struct RelayModuleData *ShmRelayModuleData; struct LedModuleData *ShmLedModuleData; struct PsuData *ShmPsuData; struct OCPP16Data *ShmOCPP16Data; DcCommonInfo *ShmDcCommonData; uint8_t gunCount; uint8_t acgunCount; // 槍資訊 struct ChargingInfoData *_chargingData[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY]; struct ChargingInfoData *ac_chargingInfo[AC_QUANTITY]; bool _isOutputNoneMatch[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY]; struct timeval _checkOutputNoneMatchTimer[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY]; bool _isRelayWelding[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY]; struct timeval _checkRelayWeldingTimer[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY]; bool _isOvpChkTimeFlag[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY]; //DS60-120 add struct timeval _checkOutputVolProtectTimer[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY]; //DS60-120 add // SMR1 *2 + SMR2 * 2 + Parallel * 2 struct timeval _relayStateChkTimer[6]; //DS60-120 add uint8_t _threePhaseOvp[3] = {0, 0, 0}; //DS60-120 add uint8_t _threePhaseUvp[3] = {0, 0, 0}; //DS60-120 add bool FindChargingInfoData(uint8_t target, struct ChargingInfoData **chargingData); int Uart5Fd; char *relayRs485PortName = "/dev/ttyS5"; unsigned short fanSpeedSmoothValue = 500; bool isStopChargingCount = false; struct timeval _close_ac_contactor; struct timeval _priority_time; struct timeval _led_priority_time; struct timeval _ac_charging_comp; struct timeval _ac_preparing; struct timeb _ac_startChargingTime; struct timeb _ac_endChargingTime; unsigned short _setFanSpeed = 0; float _beforeChargingTotalEnergy = 0.0; uint8_t _checkLedChanged = 3; Ver ver; PresentInputVoltage inputVoltage; PresentOutputVoltage outputVoltage; FanSpeed fanSpeed; Temperature temperature; AuxPower auxPower; Gfd gfd_adc; Gfd_config gfd_config; Gpio_in gpio_in; Gpio_out gpio_out; Relay outputRelay; Relay regRelay; Rtc rtc; Led_Color cur_led_color; Led_Color led_color; Ac_Status acStatus; Ac_Led_Status ledStatus; Ac_Alarm_code acAlarmCode; Ac_Charging_energy acChargingEnergy; Ac_Charging_current acChargingCurrent; 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 }; uint8_t getCommTargetID(uint8_t index) { uint8_t targetID = 0; if (gunCount == 1) { if (strncmp((char *)&ShmSysConfigAndInfo->SysConfig.ModelName[7], "0", 1) != 0) { targetID = 0x01; } else if (strncmp((char *)&ShmSysConfigAndInfo->SysConfig.ModelName[9], "0", 1) != 0) { targetID = 0x02; } } else { targetID = _chargingData[index]->Evboard_id; } return targetID; } unsigned long GetTimeoutValue(struct timeval _sour_time) { struct timeval _end_time; gettimeofday(&_end_time, NULL); return 1000000 * (_end_time.tv_sec - _sour_time.tv_sec) + _end_time.tv_usec - _sour_time.tv_usec; } int StoreLogMsg(const char *fmt, ...) { char Buf[4096 + 256]; char buffer[4096]; va_list args; struct timeb SeqEndTime; struct tm *tm; va_start(args, fmt); int rc = vsnprintf(buffer, sizeof(buffer), fmt, args); va_end(args); memset(Buf, 0, sizeof(Buf)); ftime(&SeqEndTime); SeqEndTime.time = time(NULL); tm = localtime(&SeqEndTime.time); if (ShmSysConfigAndInfo->SysConfig.SwitchDebugFlag == YES) { sprintf(Buf, "%02d:%02d:%02d:%03d - %s", tm->tm_hour, tm->tm_min, tm->tm_sec, SeqEndTime.millitm, buffer); printf("%s \n", Buf); } else { sprintf(Buf, "echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, SeqEndTime.millitm, buffer, tm->tm_year + 1900, tm->tm_mon + 1); system(Buf); } return rc; } int DiffTimeb(struct timeb ST, struct timeb ET) { //return milli-second unsigned int StartTime, StopTime; StartTime = (unsigned int) ST.time; StopTime = (unsigned int) ET.time; //return (StopTime-StartTime)*1000+ET.millitm-ST.millitm; return (StopTime - StartTime); } unsigned short MaxValue(unsigned short value1, unsigned short value2) { return value1 >= value2 ? value1 : value2; } //========================================== // Communication Function //========================================== void GetFwAndHwVersion_Fan() { if (Query_FW_Ver(Uart5Fd, ADDR_FAN, &ver) == PASS) { // FanModuleData strcpy((char *) ShmFanModuleData->version, ver.Version_FW); // SystemInfo strcpy((char *) ShmSysConfigAndInfo->SysInfo.FanModuleFwRev, ver.Version_FW); //log_info("GetFwAndHwVersion_Fan s1 = %s \n", ver.Version_FW); } if (Query_HW_Ver(Uart5Fd, ADDR_FAN, &ver) == PASS) { // SystemInfo strcpy((char *) ShmSysConfigAndInfo->SysInfo.FanModuleHwRev, ver.Version_FW); //log_info("GetFwAndHwVersion_Fan s2 = %s \n", ver.Version_HW); } } void GetFwAndHwVersion_Relay() { if (Query_FW_Ver(Uart5Fd, ADDR_RELAY, &ver) == PASS) { // RelayModuleData strcpy((char *) ShmRelayModuleData->version, ver.Version_FW); // SystemInfo strcpy((char *) ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev, ver.Version_FW); //log_info("GetFwAndHwVersion_Relay s1 = %s \n", ver.Version_FW); } if (Query_HW_Ver(Uart5Fd, ADDR_RELAY, &ver) == PASS) { // SystemInfo strcpy((char *) ShmSysConfigAndInfo->SysInfo.RelayModuleHwRev, ver.Version_FW); //log_info("GetFwAndHwVersion_Relay s2 = %s \n", ver.Version_HW); } } void GetFwAndHwVersion_Led() { if (Query_FW_Ver(Uart5Fd, ADDR_LED, &ver) == PASS) { // LedModuleData strcpy((char *) ShmLedModuleData->version, ver.Version_FW); // SystemInfo strcpy((char *) ShmSysConfigAndInfo->SysInfo.LedModuleFwRev, ver.Version_FW); //log_info("GetFwAndHwVersion_Led s1 = %s \n", ver.Version_FW); ShmLedModuleData->SelfTest_Comp = YES; } else { //log_info("GetFwAndHwVersion_Led fail \n"); } // if (Query_HW_Ver(Uart5Fd, ADDR_LED, &ver) == PASS) // { // // SystemInfo // strcpy((char *) ShmSysConfigAndInfo->SysInfo.RelayModuleHwRev, ver.Version_FW); // //log_info("GetFwAndHwVersion_Relay s2 = %s \n", ver.Version_HW); // } } void GetFwVersion_AC() { if (Query_FW_Ver(Uart5Fd, ADDR_AC_PLUG, &ver) == PASS) { ac_chargingInfo[0]->SelfTest_Comp = YES; strcpy((char *) ac_chargingInfo[0]->version, ver.Version_FW); } } void GetAcModelName() { memset(ShmSysConfigAndInfo->SysConfig.AcModelName, 0x00, sizeof(ShmSysConfigAndInfo->SysConfig.AcModelName)); if (Query_Model_Name(Uart5Fd, ADDR_AC_PLUG, ShmSysConfigAndInfo->SysConfig.AcModelName) == PASS) { log_info("ac model name = %s \n", ShmSysConfigAndInfo->SysConfig.AcModelName); } } void SetRtcData_Relay() { struct timeb csuTime; struct tm *tmCSU; ftime(&csuTime); tmCSU = localtime(&csuTime.time); // log_info("Time : %04d-%02d-%02d %02d:%02d:%02d \n", tmCSU->tm_year + 1900, // tmCSU->tm_mon + 1, tmCSU->tm_mday, tmCSU->tm_hour, tmCSU->tm_min, // tmCSU->tm_sec); rtc.RtcData[0] = '0' + (tmCSU->tm_year + 1900) / 1000 % 10; rtc.RtcData[1] = '0' + (tmCSU->tm_year + 1900) / 100 % 10; rtc.RtcData[2] = '0' + (tmCSU->tm_year + 1900) / 10 % 10; rtc.RtcData[3] = '0' + (tmCSU->tm_year + 1900) / 1 % 10; rtc.RtcData[4] = '0' + (tmCSU->tm_mon + 1) / 10 % 10; rtc.RtcData[5] = '0' + (tmCSU->tm_mon + 1) / 1 % 10; rtc.RtcData[6] = '0' + (tmCSU->tm_mday) / 10 % 10; rtc.RtcData[7] = '0' + (tmCSU->tm_mday) / 1 % 10; rtc.RtcData[8] = '0' + (tmCSU->tm_hour) / 10 % 10; rtc.RtcData[9] = '0' + (tmCSU->tm_hour) / 1 % 10; rtc.RtcData[10] = '0' + (tmCSU->tm_min) / 10 % 10; rtc.RtcData[11] = '0' + (tmCSU->tm_min) / 1 % 10; rtc.RtcData[12] = '0' + (tmCSU->tm_sec) / 10 % 10; rtc.RtcData[13] = '0' + (tmCSU->tm_sec) / 1 % 10; if (Config_Rtc_Data(Uart5Fd, ADDR_RELAY, &rtc) == PASS) { //log_info("SetRtc (RB) sucessfully. \n"); } } void SetModelName_Relay() { if (Config_Model_Name(Uart5Fd, ADDR_RELAY, ShmSysConfigAndInfo->SysConfig.ModelName) == PASS) { //log_info("Set Model name (RB) PASS = %s \n", ShmSysConfigAndInfo->SysConfig.ModelName); } } void SetRtcData_Fan() { struct timeb csuTime; struct tm *tmCSU; ftime(&csuTime); tmCSU = localtime(&csuTime.time); // log_info("Time : %04d-%02d-%02d %02d:%02d:%02d \n", tmCSU->tm_year + 1900, // tmCSU->tm_mon + 1, tmCSU->tm_mday, tmCSU->tm_hour, tmCSU->tm_min, // tmCSU->tm_sec); rtc.RtcData[0] = '0' + (tmCSU->tm_year + 1900) / 1000 % 10; rtc.RtcData[1] = '0' + (tmCSU->tm_year + 1900) / 100 % 10; rtc.RtcData[2] = '0' + (tmCSU->tm_year + 1900) / 10 % 10; rtc.RtcData[3] = '0' + (tmCSU->tm_year + 1900) / 1 % 10; rtc.RtcData[4] = '0' + (tmCSU->tm_mon + 1) / 10 % 10; rtc.RtcData[5] = '0' + (tmCSU->tm_mon + 1) / 1 % 10; rtc.RtcData[6] = '0' + (tmCSU->tm_mday) / 10 % 10; rtc.RtcData[7] = '0' + (tmCSU->tm_mday) / 1 % 10; rtc.RtcData[8] = '0' + (tmCSU->tm_hour) / 10 % 10; rtc.RtcData[9] = '0' + (tmCSU->tm_hour) / 1 % 10; rtc.RtcData[10] = '0' + (tmCSU->tm_min) / 10 % 10; rtc.RtcData[11] = '0' + (tmCSU->tm_min) / 1 % 10; rtc.RtcData[12] = '0' + (tmCSU->tm_sec) / 10 % 10; rtc.RtcData[13] = '0' + (tmCSU->tm_sec) / 1 % 10; if (Config_Rtc_Data(Uart5Fd, ADDR_FAN, &rtc) == PASS) { //log_info("SetRtc (FB) sucessfully. \n"); } } void SetModelName_Fan() { if (Config_Model_Name(Uart5Fd, ADDR_FAN, ShmSysConfigAndInfo->SysConfig.ModelName) == PASS) { log_info("Set Model name PASS = %s \n", ShmSysConfigAndInfo->SysConfig.ModelName); } } // AC 三相輸入電壓 void GetPresentInputVol(void) { if (Query_Present_InputVoltage(Uart5Fd, ADDR_RELAY, &inputVoltage) == PASS) { // resolution : 0.1 ShmSysConfigAndInfo->SysInfo.InputVoltageR = ShmRelayModuleData->InputL1Volt = inputVoltage.L1N_L12; ShmSysConfigAndInfo->SysInfo.InputVoltageS = ShmRelayModuleData->InputL2Volt = inputVoltage.L2N_L23; ShmSysConfigAndInfo->SysInfo.InputVoltageT = ShmRelayModuleData->InputL3Volt = inputVoltage.L3N_L31; //********************************************************************************************************// // Vin (UVP) if (ShmSysConfigAndInfo->SysInfo.ChargerType == _CHARGER_TYPE_IEC) { if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP == NO) { if (inputVoltage.L1N_L12 < VIN_MIN_VOLTAGE_IEC) { log_info("In Uvp L1N_L12 = %f \n", inputVoltage.L1N_L12); if (_threePhaseUvp[0] >= OVP_UVP_CHK_COUNT) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP = YES; } else { _threePhaseUvp[0] += 1; } } } else { if (inputVoltage.L1N_L12 > VIN_MIN_REV_VOLTAGE_IEC) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP = NO; _threePhaseUvp[0] = 0; } } if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP == NO) { if (inputVoltage.L2N_L23 < VIN_MIN_VOLTAGE_IEC) { log_info("In Uvp L2N_L23 = %f \n", inputVoltage.L2N_L23); if (_threePhaseUvp[1] >= OVP_UVP_CHK_COUNT) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP = YES; } else { _threePhaseUvp[1] += 1; } } } else { if (inputVoltage.L2N_L23 > VIN_MIN_REV_VOLTAGE_IEC) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP = NO; _threePhaseUvp[1] = 0; } } if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP == NO) { if (inputVoltage.L3N_L31 < VIN_MIN_VOLTAGE_IEC) { log_info("In Uvp L3N_L31 = %f \n", inputVoltage.L3N_L31); if (_threePhaseUvp[2] >= OVP_UVP_CHK_COUNT) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP = YES; } else { _threePhaseUvp[2] += 1; } } } else { if (inputVoltage.L3N_L31 > VIN_MIN_REV_VOLTAGE_IEC) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP = NO; _threePhaseUvp[2] = 0; } } } else if (ShmSysConfigAndInfo->SysInfo.ChargerType == _CHARGER_TYPE_UL) { if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP == NO) { if (inputVoltage.L1N_L12 < VIN_MIN_VOLTAGE_UL) { log_info("In Uvp L1N_L12 = %f \n", inputVoltage.L1N_L12); if (_threePhaseUvp[0] >= OVP_UVP_CHK_COUNT) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP = YES; } else { _threePhaseUvp[0] += 1; } } } else { if (inputVoltage.L1N_L12 > VIN_MIN_REV_VOLTAGE_UL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP = NO; _threePhaseUvp[0] = 0; } } if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP == NO) { if (inputVoltage.L2N_L23 < VIN_MIN_VOLTAGE_UL) { log_info("In Uvp L2N_L23 = %f \n", inputVoltage.L2N_L23); if (_threePhaseUvp[1] >= OVP_UVP_CHK_COUNT) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP = YES; } else { _threePhaseUvp[1] += 1; } } } else { if (inputVoltage.L2N_L23 > VIN_MIN_REV_VOLTAGE_UL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP = NO; _threePhaseUvp[1] = 0; } } if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP == NO) { if (inputVoltage.L3N_L31 < VIN_MIN_VOLTAGE_UL) { log_info("In Uvp L3N_L31 = %f \n", inputVoltage.L3N_L31); if (_threePhaseUvp[2] >= OVP_UVP_CHK_COUNT) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP = YES; } else { _threePhaseUvp[2] += 1; } } } else { if (inputVoltage.L3N_L31 > VIN_MIN_REV_VOLTAGE_UL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP = NO; _threePhaseUvp[2] = 0; } } } //********************************************************************************************************// // Vin (OVP) if (ShmSysConfigAndInfo->SysInfo.ChargerType == _CHARGER_TYPE_IEC) { if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP == NO) { if (inputVoltage.L1N_L12 > VIN_MAX_VOLTAGE_IEC) { log_info("In Ovp L1N_L12 = %f \n", inputVoltage.L1N_L12); if (_threePhaseOvp[0] >= OVP_UVP_CHK_COUNT) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP = YES; } else { _threePhaseOvp[0] += 1; } } } else { if (inputVoltage.L1N_L12 < VIN_MAX_REV_VOLTAGE_IEC) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP = NO; _threePhaseOvp[0] = 0; } } if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP == NO) { if (inputVoltage.L2N_L23 > VIN_MAX_VOLTAGE_IEC) { log_info("In Ovp L2N_L23 = %f \n", inputVoltage.L2N_L23); if (_threePhaseOvp[1] >= OVP_UVP_CHK_COUNT) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP = YES; } else { _threePhaseOvp[1] += 1; } } } else { if (inputVoltage.L2N_L23 < VIN_MAX_REV_VOLTAGE_IEC) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP = NO; _threePhaseOvp[1] = 0; } } if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP == NO) { if (inputVoltage.L3N_L31 > VIN_MAX_VOLTAGE_IEC) { log_info("In Ovp L3N_L31 = %f \n", inputVoltage.L3N_L31); if (_threePhaseOvp[2] >= OVP_UVP_CHK_COUNT) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP = YES; } else { _threePhaseOvp[2] += 1; } } } else { if (inputVoltage.L3N_L31 < VIN_MAX_REV_VOLTAGE_IEC) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP = NO; _threePhaseOvp[2] = 0; } } } else if (ShmSysConfigAndInfo->SysInfo.ChargerType == _CHARGER_TYPE_UL) { if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP == NO) { if (inputVoltage.L1N_L12 > VIN_MAX_VOLTAGE_UL) { log_info("In Ovp L1N_L12 = %f \n", inputVoltage.L1N_L12); if (_threePhaseOvp[0] >= OVP_UVP_CHK_COUNT) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP = YES; } else { _threePhaseOvp[0] += 0; } } } else { if (inputVoltage.L1N_L12 < VIN_MAX_REV_VOLTAGE_UL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP = NO; _threePhaseOvp[0] = 0; } } if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP == NO) { if (inputVoltage.L2N_L23 > VIN_MAX_VOLTAGE_UL) { log_info("In Ovp L2N_L23 = %f \n", inputVoltage.L2N_L23); if (_threePhaseOvp[1] >= OVP_UVP_CHK_COUNT) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP = YES; } else { _threePhaseOvp[1] += 0; } } } else { if (inputVoltage.L2N_L23 < VIN_MAX_REV_VOLTAGE_UL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP = NO; _threePhaseOvp[1] = 0; } } if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP == NO) { if (inputVoltage.L3N_L31 > VIN_MAX_VOLTAGE_UL) { log_info("In Ovp L3N_L31 = %f \n", inputVoltage.L3N_L31); if (_threePhaseOvp[2] >= OVP_UVP_CHK_COUNT) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP = YES; } else { _threePhaseOvp[2] += 1; } } } else { if (inputVoltage.L3N_L31 < VIN_MAX_REV_VOLTAGE_UL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP = NO; _threePhaseOvp[2] = 0; } } } } } // 左右槍的 Relay 前後的輸出電壓 void GetPersentOutputVol(void) { uint8_t index = 0; uint8_t targetID = 0; if (Query_Present_OutputVoltage(Uart5Fd, ADDR_RELAY, &outputVoltage) != PASS) { return; } //log_info("Conn1 fuse 1 = %f \n", outputVoltage.behindFuse_Voltage_C1); //log_info("Conn1 relay 1 = %f \n", outputVoltage.behindRelay_Voltage_C1); //log_info("Conn2 fuse 2 = %f \n", outputVoltage.behindFuse_Voltage_C2); //log_info("Conn2 relay 2 = %f \n", outputVoltage.behindRelay_Voltage_C2); //log_info("outputVoltage.behindFuse_Voltage_C1 = %f \n", outputVoltage.behindFuse_Voltage_C1); //log_info("outputVoltage.behindFuse_Voltage_C2 = %f \n", outputVoltage.behindFuse_Voltage_C2); ShmRelayModuleData->Gun1FuseOutputVolt = outputVoltage.behindFuse_Voltage_C1; ShmRelayModuleData->Gun1RelayOutputVolt = outputVoltage.behindRelay_Voltage_C1; ShmRelayModuleData->Gun2FuseOutputVolt = outputVoltage.behindFuse_Voltage_C2; ShmRelayModuleData->Gun2RelayOutputVolt = outputVoltage.behindRelay_Voltage_C2; for (index = 0; index < gunCount; index++) { targetID = getCommTargetID(index); switch (targetID) { case 0x01: #if defined DD360Tcci || defined DD360Audi || defined DD360ComBox _chargingData[index]->FireChargingVoltage = ShmRelayModuleData->Gun1RelayOutputVolt; _chargingData[index]->PresentChargingCurrent = ShmRelayModuleData->Gun1FuseOutputVolt / 10; _chargingData[index]->PresentChargingVoltage = _chargingData[index]->FireChargingVoltage / 10; _chargingData[index]->FuseChargingVoltage = _chargingData[index]->FireChargingVoltage; break; #endif //defined DD360Tcci || defined DD360Audi || defined DD360ComBox _chargingData[index]->FireChargingVoltage = ShmRelayModuleData->Gun1RelayOutputVolt; _chargingData[index]->FuseChargingVoltage = ShmRelayModuleData->Gun1FuseOutputVolt; break; case 0x02: #if defined DD360Tcci || defined DD360Audi || defined DD360ComBox _chargingData[index]->FireChargingVoltage = ShmRelayModuleData->Gun2RelayOutputVolt; _chargingData[index]->PresentChargingCurrent = ShmRelayModuleData->Gun2FuseOutputVolt / 10; _chargingData[index]->PresentChargingVoltage = _chargingData[index]->FireChargingVoltage / 10; _chargingData[index]->FuseChargingVoltage = _chargingData[index]->FireChargingVoltage; break; #endif //defined DD360Tcci || defined DD360Audi || defined DD360ComBox _chargingData[index]->FireChargingVoltage = ShmRelayModuleData->Gun2RelayOutputVolt; _chargingData[index]->FuseChargingVoltage = ShmRelayModuleData->Gun2FuseOutputVolt; break; } //unsigned short Ovp = 0; //unsigned short Ocp = 0; //Ovp = MIN [VOUT_MAX_VOLTAGE, EV_BATTERY_VOLTAGE] // 最大輸出電壓與電池電壓最大值 //Ocp = MIN [IOUT_MAX_CURRENT, EV_CURRENT_REQ] // 最大輸出電流與需求電流最小值 //if (_chargingData[index]->Type == _Type_Chademo) { // //Ovp = MaxValue(_chargingData[index]->MaximumChargingVoltage, _chargingData[index]->EvBatteryMaxVoltage); // //Ocp = MaxValue(_chargingData[index]->PresentChargingCurrent, ShmCHAdeMOData->ev[_chargingData[index]->type_index].ChargingCurrentRequest); //} else if (_chargingData[index]->Type == _Type_CCS_2) { //} } } // 風扇速度 void GetFanSpeed() { //log_info("Get fan board speed \n"); if (Query_Fan_Speed(Uart5Fd, ADDR_FAN, &fanSpeed) == PASS) { ShmFanModuleData->PresentFan1Speed = fanSpeed.speed[0]; ShmFanModuleData->PresentFan2Speed = fanSpeed.speed[1]; ShmFanModuleData->PresentFan3Speed = fanSpeed.speed[2]; ShmFanModuleData->PresentFan4Speed = fanSpeed.speed[3]; // log_info("SystemFanRotaSpeed_1 = %d \n", fanSpeed.speed[0]); // log_info("SystemFanRotaSpeed_2 = %d \n", fanSpeed.speed[1]); // log_info("SystemFanRotaSpeed_3 = %d \n", fanSpeed.speed[2]); // log_info("SystemFanRotaSpeed_4 = %d \n", fanSpeed.speed[3]); // Config_Fan_Speed(Uart5Fd, ADDR_FAN, &fanSpeed[0]); //SysInfoData (SystemFanRotaSpeed) } } // 讀取 Relay 狀態 void GetRelayOutputStatus(void) { if (Query_Relay_Output(Uart5Fd, ADDR_RELAY, ®Relay) == PASS) { #if !defined DD360Tcci && !defined DD360Audi && !defined DD360ComBox regRelay.relay_event.bits.AC_Contactor = ShmSysConfigAndInfo->SysInfo.AcContactorStatus; #endif //!defined DD360Tcci && !defined DD360Audi } } // 確認 K1 K2 relay 的狀態 void CheckK1K2RelayOutput(uint8_t index) { uint8_t targetID = 0; targetID = getCommTargetID(index); switch (targetID) { case 0x01: if (regRelay.relay_event.bits.Gun1_N == YES && regRelay.relay_event.bits.Gun1_P == YES) { _chargingData[index]->RelayK1K2Status = YES; } else { _chargingData[index]->RelayK1K2Status = NO; } if (_chargingData[index]->Type == _Type_CCS_2) { #if !defined DD360Tcci && !defined DD360Audi && !defined DD360ComBox if (regRelay.relay_event.bits.Gun1_N == YES && regRelay.relay_event.bits.CCS_Precharge == YES) { _chargingData[index]->RelayKPK2Status = YES; } else { _chargingData[index]->RelayKPK2Status = NO; } #else if (_chargingData[index]->SystemStatus == S_CCS_PRECHARGE_ST0) { _chargingData[index]->RelayKPK2Status = YES; } else { _chargingData[index]->RelayKPK2Status = NO; } #endif //!defined DD360Tcci && !defined DD360Audi } break; case 0x02: if (regRelay.relay_event.bits.Gun2_N == YES && regRelay.relay_event.bits.Gun2_P == YES) { _chargingData[index]->RelayK1K2Status = YES; } else { _chargingData[index]->RelayK1K2Status = NO; } if (_chargingData[index]->Type == _Type_CCS_2) { #if !defined DD360Tcci && !defined DD360Audi && !defined DD360ComBox if (regRelay.relay_event.bits.Gun2_N == YES && regRelay.relay_event.bits.CCS_Precharge == YES) { _chargingData[index]->RelayKPK2Status = YES; } else { _chargingData[index]->RelayKPK2Status = NO; } #else if (_chargingData[index]->SystemStatus == S_CCS_PRECHARGE_ST0) { _chargingData[index]->RelayKPK2Status = YES; } else { _chargingData[index]->RelayKPK2Status = NO; } #endif //!defined DD360Tcci && !defined DD360Audi } break; } #if !defined DD360Tcci && !defined DD360Audi && !defined DD360ComBox //DS60-120 add if (ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus == YES) { if (regRelay.relay_event.bits.Gun1_Parallel_N == NO && regRelay.relay_event.bits.Gun1_Parallel_P == NO) { ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus = NO; } } else if (ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus == NO) { if (regRelay.relay_event.bits.Gun1_Parallel_N == YES && regRelay.relay_event.bits.Gun1_Parallel_P == YES) { ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus = YES; } } #else ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus = YES; #endif //!defined DD360Tcci && !defined DD360Audi } void GetGfdAdc() { int gunIndex = 0; uint8_t targetID = 0; // define : 每 0.2 ~ 1 秒一次 // occur : <= 75k 歐姆 @ 150 - 750 Vdc // warning : >= 100 歐姆 && <= 500 歐姆 @ 150-750 Vdc if (Query_Gfd_Adc(Uart5Fd, ADDR_RELAY, &gfd_adc) == PASS) { for (gunIndex = 0; gunIndex < gunCount; gunIndex++) { if (_chargingData[gunIndex]->Type == 0x09 && !ShmSysConfigAndInfo->SysConfig.AlwaysGfdFlag ) { if ((_chargingData[gunIndex]->PresentChargingVoltage * 10) >= VOUT_MIN_VOLTAGE) { _chargingData[gunIndex]->GroundFaultStatus = GFD_PASS; } continue; } targetID = getCommTargetID(gunIndex); if (targetID == 0x01) { if (gfd_adc.result_conn1 == GFD_WARNING) { gfd_adc.result_conn1 = GFD_PASS; } _chargingData[gunIndex]->GroundFaultStatus = gfd_adc.result_conn1; //log_info("GFD ******** Result = %d, Step = %d, R = %d, Vol = %d \n", // _chargingData[gunIndex]->GroundFaultStatus, // gfd_adc.rb_step_1, // gfd_adc.Resister_conn1, // gfd_adc.voltage_conn1); if (_chargingData[gunIndex]->GroundFaultStatus == GFD_FAIL) { log_info("GFD Fail. index = %d, Step = %d, R = %d, Vol = %d \n", gunIndex, gfd_adc.rb_step_1, gfd_adc.Resister_conn1, gfd_adc.voltage_conn1); } else if (_chargingData[gunIndex]->GroundFaultStatus == GFD_PASS || _chargingData[gunIndex]->GroundFaultStatus == GFD_WARNING ) { if (_chargingData[gunIndex]->GroundFaultStatus == GFD_WARNING) { log_info("GFD Warning. index = %d, Result = %d, R = %d, Vol = %d \n", gunIndex, _chargingData[gunIndex]->GroundFaultStatus, gfd_adc.Resister_conn1, gfd_adc.voltage_conn1); } } } else if (targetID == 0x02) { if (gfd_adc.result_conn2 == GFD_WARNING) { gfd_adc.result_conn2 = GFD_PASS; } _chargingData[gunIndex]->GroundFaultStatus = gfd_adc.result_conn2; if (_chargingData[gunIndex]->GroundFaultStatus == GFD_FAIL) { log_info("GFD Fail. index = %d, Step = %d, R = %d, Vol = %d \n", gunIndex, gfd_adc.rb_step_2, gfd_adc.Resister_conn2, gfd_adc.voltage_conn2); } else if (_chargingData[gunIndex]->GroundFaultStatus == GFD_PASS || _chargingData[gunIndex]->GroundFaultStatus == GFD_WARNING ) { if (_chargingData[gunIndex]->GroundFaultStatus == GFD_WARNING) { log_info("GFD Warning. index = %d, Result = %d, R = %d, Vol = %d \n", gunIndex, _chargingData[gunIndex]->GroundFaultStatus, gfd_adc.Resister_conn1, gfd_adc.voltage_conn1); } } } } } } void GetGpioInput() { if (Query_Gpio_Input(Uart5Fd, ADDR_AUX, &gpio_in) == PASS) { // AC Contactor Status if (gpio_in.AC_MainBreaker == 1) { // AC Main Breaker ON log_info("RB AC Main Breaker. \n"); } if (gpio_in.SPD == 1) { // SPD (雷擊保護) ON log_info("RB SPD. \n"); } if (gpio_in.Door_Open == 1) { // Door Open log_info("RB Door Open. \n"); } if (gpio_in.GFD[0] == 1) { // GFD_1 Trigger } if (gpio_in.GFD[1] == 1) { // GFD_2 Trigger } if (gpio_in.AC_Drop == 1) { // AC Drop log_info("RB AC Drop. \n"); } if (gpio_in.Emergency_IO == 1) { // Emergency IO ON log_info("RB Emergency IO ON. \n"); } if (gpio_in.Button_Emergency_Press == 1) { // Emergency button Press } if (gpio_in.Button_On_Press == 1) { // On button Press } if (gpio_in.Button_Off_Press == 1) { // Off button Press } if (gpio_in.Key_1_Press == 1) { // key 1 press } if (gpio_in.Key_2_Press == 1) { // key 2 press } if (gpio_in.Key_3_Press == 1) { // key 3 press } if (gpio_in.Key_4_Press == 1) { // key 4 press } } } // 5V 12V 24V 48V void GetAuxPower() { if (Query_Aux_PowerVoltage(Uart5Fd, ADDR_FAN, &auxPower) == PASS) { ShmSysConfigAndInfo->SysInfo.AuxPower48V = auxPower.voltage[0]; ShmSysConfigAndInfo->SysInfo.AuxPower24V = auxPower.voltage[1]; //ShmSysConfigAndInfo->SysInfo.AuxPower12V = auxPower.voltage[4]; //ShmSysConfigAndInfo->SysInfo.AuxPower5V = auxPower.voltage[6]; // aux power voltage //log_info("aux1 = %x, \n", auxPower.voltage[0]); //log_info("aux2 = %x, \n", auxPower.voltage[1]); } } void SetFanModuleSpeed() { { FanSpeed _fanSpeed; _setFanSpeed += fanSpeedSmoothValue; if (_setFanSpeed >= ShmFanModuleData->SetFan1Speed) { _setFanSpeed = ShmFanModuleData->SetFan1Speed; } //printf("_setFanSpeed = %d \n", _setFanSpeed); _fanSpeed.speed[0] = _setFanSpeed; _fanSpeed.speed[1] = _setFanSpeed; _fanSpeed.speed[2] = _setFanSpeed; _fanSpeed.speed[3] = _setFanSpeed; if (Config_Fan_Speed(Uart5Fd, ADDR_FAN, &_fanSpeed) == PASS) { //log_info("successfully Fan\n"); } } } //========================================== // Common Function //========================================== void SetK1K2RelayStatus(uint8_t index) { uint8_t targetID = 0; PreChargingState *pRegPreChargingState = NULL; PreChargingState *pOutputPreChargingState = NULL; GunPNState *pRegGunPNState = NULL; GunPNState *pOutputGunPNState = NULL; struct ChargingInfoData *pDcChargingInfo = (struct ChargingInfoData *)_chargingData[index]; if (ShmPsuData->Work_Step >= _TEST_MODE && ShmPsuData->Work_Step <= _TEST_MODE) { 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; } return; } targetID = getCommTargetID(index); pRegPreChargingState = (PreChargingState *)®Relay.relay_event.relay_status[0]; pOutputPreChargingState = (PreChargingState *)&outputRelay.relay_event.relay_status[0]; if (targetID == 0x01) { pRegGunPNState = (GunPNState *)®Relay.relay_event.relay_status[1]; pOutputGunPNState = (GunPNState *)&outputRelay.relay_event.relay_status[1]; } else if (targetID == 0x02) { pRegGunPNState = (GunPNState *)®Relay.relay_event.relay_status[2]; pOutputGunPNState = (GunPNState *)&outputRelay.relay_event.relay_status[2]; } switch (pDcChargingInfo->SystemStatus) { case S_BOOTING: case S_IDLE: case S_AUTHORIZING: case S_REASSIGN_CHECK: case S_REASSIGN: case S_PREPARNING: case S_PREPARING_FOR_EV: if (pRegGunPNState->GunP == YES) { pOutputGunPNState->GunP = NO; } else if (pRegGunPNState->GunN == YES) { pOutputGunPNState->GunN = NO; } if (targetID == 0x02 && pDcChargingInfo->Type == _Type_CCS_2) { if (pRegPreChargingState->CcsPrecharge == YES) { pOutputPreChargingState->CcsPrecharge = NO; } } break; case S_PREPARING_FOR_EVSE: case S_CHARGING: //if (pDcChargingInfo->RelayWeldingCheck != YES) { // break; //} if (pRegGunPNState->GunN == NO) { pOutputGunPNState->GunN = YES; } else if (pRegGunPNState->GunP == NO) { pOutputGunPNState->GunP = YES; } break; case S_TERMINATING: case S_COMPLETE: case S_ALARM: if ((pDcChargingInfo->PresentChargingCurrent * 10) <= SEFETY_SWITCH_RELAY_CUR) { if (pRegGunPNState->GunP == YES) { pOutputGunPNState->GunP = NO; } else if (pRegGunPNState->GunN == YES) { pOutputGunPNState->GunN = NO; } } break; case S_CCS_PRECHARGE_ST0: #if defined DD360Tcci || defined DD360Audi || defined DD360ComBox break; #endif //defined DD360Tcci || defined DD360Audi || defined DD360ComBox if (pDcChargingInfo->Type == _Type_CCS_2 && targetID == 0x02) { if (pRegPreChargingState->CcsPrecharge == NO) { pOutputPreChargingState->CcsPrecharge = YES; } else if (pRegPreChargingState->CcsPrecharge == YES) { pRegGunPNState->GunP = NO; } } break; case S_CCS_PRECHARGE_ST1: #if defined DD360Tcci || defined DD360Audi || defined DD360ComBox break; #endif //defined DD360Tcci || defined DD360Audi || defined DD360ComBox if (pDcChargingInfo->Type == _Type_CCS_2 && targetID == 0x02) { if (pRegGunPNState->GunP == NO) { pOutputGunPNState->GunP = YES; } else if (pRegGunPNState->GunP == YES) { pOutputPreChargingState->CcsPrecharge = NO; } } break; } } void CheckAcInputOvpStatus(uint8_t index) { if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP == YES || ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP == YES || ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP == YES) { // if ((_chargingData[index]->SystemStatus >= S_PREPARNING && _chargingData[index]->SystemStatus <= S_CHARGING) || // (_chargingData[index]->SystemStatus >= S_CCS_PRECHARGE_ST0 && _chargingData[index]->SystemStatus <= S_CCS_PRECHARGE_ST1)) // { // if (ShmSysConfigAndInfo->SysInfo.ChargerType == _CHARGER_TYPE_IEC) // { // if (_psuInputVolR > VIN_MAX_VOLTAGE_IEC || // _psuInputVolS > VIN_MAX_VOLTAGE_IEC || // _psuInputVolT > VIN_MAX_VOLTAGE_IEC) // { // log_info("IEC _psuInputVolR = %f, _psuInputVolS = %f, _psuInputVolT = %f \n", // _psuInputVolR, _psuInputVolS, _psuInputVolT); // _chargingData[index]->StopChargeFlag = YES; // } // // } // else if (ShmSysConfigAndInfo->SysInfo.ChargerType == _CHARGER_TYPE_UL) // { // if (_psuInputVolR > VIN_MAX_VOLTAGE_UL || // _psuInputVolS > VIN_MAX_VOLTAGE_UL || // _psuInputVolT > VIN_MAX_VOLTAGE_UL) // { // log_info("UL _psuInputVolR = %f, _psuInputVolS = %f, _psuInputVolT = %f \n", // _psuInputVolR, _psuInputVolS, _psuInputVolT); // _chargingData[index]->StopChargeFlag = YES; // } // } // } // else //log_info("CheckAcInputOvpStatus\r\n"); _chargingData[index]->StopChargeFlag = YES; } } void CheckPhaseLossStatus(uint8_t index) { if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP == YES || ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP == YES || ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP == YES) { //log_info("CheckPhaseLossStatus\r\n"); _chargingData[index]->StopChargeFlag = YES; } } void SetParalleRelayStatus(void) { #if defined DD360Tcci || defined DD360Audi || defined DD360ComBox return; #endif //!defined DD360Tcci || !defined DD360Audi || !defined DD360ComBox // 之後雙槍單模機種,橋接都會上 if (gunCount >= 2) { if (_chargingData[0]->SystemStatus == S_BOOTING || _chargingData[1]->SystemStatus == S_BOOTING || (_chargingData[0]->SystemStatus == S_IDLE && _chargingData[1]->SystemStatus == S_IDLE)) { // 初始化~ 不搭橋接 if (regRelay.relay_event.bits.Gun1_Parallel_P == YES) { outputRelay.relay_event.bits.Gun1_Parallel_P = NO; } else if (regRelay.relay_event.bits.Gun1_Parallel_N == YES) { outputRelay.relay_event.bits.Gun1_Parallel_N = NO; } } else { if (_chargingData[0]->IsReadyToCharging == YES || _chargingData[1]->IsReadyToCharging == YES) { // ************需考慮在切換中 - 切開 relay 與搭回 relay 的時機點************ if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX) { if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag < _REASSIGNED_RELAY_M_TO_A) { // 最大充 - 搭上橋接 if (regRelay.relay_event.bits.Gun1_Parallel_N == NO) { outputRelay.relay_event.bits.Gun1_Parallel_N = YES; } else if (regRelay.relay_event.bits.Gun1_Parallel_P == NO) { outputRelay.relay_event.bits.Gun1_Parallel_P = YES; } } else { // 平均充 - 不搭 if (regRelay.relay_event.bits.Gun1_Parallel_P == YES) { outputRelay.relay_event.bits.Gun1_Parallel_P = NO; } else if (regRelay.relay_event.bits.Gun1_Parallel_N == YES) { outputRelay.relay_event.bits.Gun1_Parallel_N = NO; } } } else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER) { if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag < _REASSIGNED_RELAY_A_TO_M) { // 平均充 - 不搭 if (regRelay.relay_event.bits.Gun1_Parallel_P == YES) { outputRelay.relay_event.bits.Gun1_Parallel_P = NO; } else if (regRelay.relay_event.bits.Gun1_Parallel_N == YES) { outputRelay.relay_event.bits.Gun1_Parallel_N = NO; } } else { // 最大充 - 搭上橋接 if (regRelay.relay_event.bits.Gun1_Parallel_N == NO) { outputRelay.relay_event.bits.Gun1_Parallel_N = YES; } else if (regRelay.relay_event.bits.Gun1_Parallel_P == NO) { outputRelay.relay_event.bits.Gun1_Parallel_P = YES; } } } } } } } void CheckAlarmOccur() { bool isErr = false; for (uint8_t 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; } bool IsNoneMatchLedColor() { bool result = false; if (cur_led_color.Connect_1_Red != led_color.Connect_1_Red || cur_led_color.Connect_1_Green != led_color.Connect_1_Green || cur_led_color.Connect_1_Blue != led_color.Connect_1_Blue || cur_led_color.Connect_2_Red != led_color.Connect_2_Red || cur_led_color.Connect_2_Green != led_color.Connect_2_Green || cur_led_color.Connect_2_Blue != led_color.Connect_2_Blue) { result = true; } return result; } void SetLedColor(struct ChargingInfoData *chargingData_1, struct ChargingInfoData *chargingData_2) { uint8_t _colorBuf = COLOR_MAX_LV * LED_INTENSITY_BRIGHTEST; if (ShmSysConfigAndInfo->SysConfig.LedInfo.Intensity == _LED_INTENSITY_DARKEST) { _colorBuf = COLOR_MAX_LV * LED_INTENSITY_DARKEST; } else if (ShmSysConfigAndInfo->SysConfig.LedInfo.Intensity == _LED_INTENSITY_MEDIUM) { _colorBuf = COLOR_MAX_LV * LED_INTENSITY_MEDIUM; } //printf("chargingData_1->SystemStatus=%d\n",chargingData_1->SystemStatus); //printf("chargingData_2->SystemStatus=%d\n",chargingData_2->SystemStatus); //printf("ShmSysConfigAndInfo->SysWarningInfo.Level=%d\n",ShmSysConfigAndInfo->SysWarningInfo.Level); if (ShmSysConfigAndInfo->SysWarningInfo.Level == 2) { led_color.Connect_1_Green = COLOR_MIN_LV; led_color.Connect_1_Blue = COLOR_MIN_LV; led_color.Connect_1_Red = _colorBuf; led_color.Connect_2_Green = COLOR_MIN_LV; led_color.Connect_2_Blue = COLOR_MIN_LV; led_color.Connect_2_Red = _colorBuf; } else { if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf) { if ((chargingData_1->SystemStatus == S_BOOTING || chargingData_1->SystemStatus == S_IDLE || chargingData_1->SystemStatus == S_RESERVATION) && (chargingData_2->SystemStatus == S_BOOTING || chargingData_2->SystemStatus == S_IDLE || chargingData_2->SystemStatus == S_RESERVATION)) { #if defined DD360Audi led_color.Connect_1_Green = _colorBuf; led_color.Connect_1_Blue = _colorBuf; led_color.Connect_1_Red = _colorBuf; led_color.Connect_2_Green = _colorBuf; led_color.Connect_2_Blue = _colorBuf; led_color.Connect_2_Red = _colorBuf; #else led_color.Connect_1_Green = _colorBuf; led_color.Connect_1_Blue = COLOR_MIN_LV; led_color.Connect_1_Red = COLOR_MIN_LV; led_color.Connect_2_Green = _colorBuf; led_color.Connect_2_Blue = COLOR_MIN_LV; led_color.Connect_2_Red = COLOR_MIN_LV; #endif } else if ((chargingData_1->SystemStatus >= S_AUTHORIZING && chargingData_1->SystemStatus <= S_COMPLETE) || (chargingData_1->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingData_1->SystemStatus <= S_CCS_PRECHARGE_ST1) || (chargingData_2->SystemStatus >= S_AUTHORIZING && chargingData_2->SystemStatus <= S_COMPLETE) || (chargingData_2->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingData_2->SystemStatus <= S_CCS_PRECHARGE_ST1)) { led_color.Connect_1_Green = COLOR_MIN_LV; led_color.Connect_1_Blue = _colorBuf; led_color.Connect_1_Red = COLOR_MIN_LV; led_color.Connect_2_Green = COLOR_MIN_LV; led_color.Connect_2_Blue = _colorBuf; led_color.Connect_2_Red = COLOR_MIN_LV; } } else { if (chargingData_1->SystemStatus == S_BOOTING || chargingData_1->SystemStatus == S_IDLE || chargingData_1->SystemStatus == S_RESERVATION || chargingData_1->SystemStatus == S_MAINTAIN) { if (chargingData_1->IsAvailable == NO) { //For Audi led_color.Connect_1_Green = COLOR_MIN_LV; led_color.Connect_1_Blue = COLOR_MIN_LV; led_color.Connect_1_Red = _colorBuf; } else { #if defined DD360Audi led_color.Connect_1_Green = _colorBuf; led_color.Connect_1_Blue = _colorBuf; led_color.Connect_1_Red = _colorBuf; #else led_color.Connect_1_Green = _colorBuf; led_color.Connect_1_Blue = COLOR_MIN_LV; led_color.Connect_1_Red = COLOR_MIN_LV; #endif } } else if ((chargingData_1->SystemStatus >= S_AUTHORIZING && chargingData_1->SystemStatus <= S_COMPLETE) || (chargingData_1->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingData_1->SystemStatus <= S_CCS_PRECHARGE_ST1)) { led_color.Connect_1_Green = COLOR_MIN_LV; led_color.Connect_1_Blue = _colorBuf; led_color.Connect_1_Red = COLOR_MIN_LV; } // -------------------------------------------------------------------------- if (chargingData_2->SystemStatus == S_BOOTING || chargingData_2->SystemStatus == S_IDLE || chargingData_2->SystemStatus == S_RESERVATION || chargingData_2->SystemStatus == S_MAINTAIN) { if (chargingData_2->IsAvailable == NO) { led_color.Connect_2_Green = COLOR_MIN_LV; led_color.Connect_2_Blue = COLOR_MIN_LV; led_color.Connect_2_Red = _colorBuf; } else { #if defined DD360Audi led_color.Connect_2_Green = _colorBuf; led_color.Connect_2_Blue = _colorBuf; led_color.Connect_2_Red = _colorBuf; #else led_color.Connect_2_Green = _colorBuf; led_color.Connect_2_Blue = COLOR_MIN_LV; led_color.Connect_2_Red = COLOR_MIN_LV; #endif } } else if ((chargingData_2->SystemStatus >= S_AUTHORIZING && chargingData_2->SystemStatus <= S_COMPLETE) || (chargingData_2->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingData_2->SystemStatus <= S_CCS_PRECHARGE_ST1)) { led_color.Connect_2_Green = COLOR_MIN_LV; led_color.Connect_2_Blue = _colorBuf; led_color.Connect_2_Red = COLOR_MIN_LV; } } } if (_checkLedChanged > 0) { if (Config_Led_Color(Uart5Fd, ADDR_LED, &led_color) == PASS) { _checkLedChanged--; cur_led_color.Connect_1_Red = led_color.Connect_1_Red; cur_led_color.Connect_1_Green = led_color.Connect_1_Green; cur_led_color.Connect_1_Blue = led_color.Connect_1_Blue; cur_led_color.Connect_2_Red = led_color.Connect_2_Red; cur_led_color.Connect_2_Green = led_color.Connect_2_Green; cur_led_color.Connect_2_Blue = led_color.Connect_2_Blue; } } else if (IsNoneMatchLedColor()) { _checkLedChanged = 3; } } //========================================== // Init all share memory //========================================== int InitShareMemory() { int result = PASS; int MeterSMId; if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), 0777)) < 0) { result = FAIL; } else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) - 1) { result = FAIL; } if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), 0777)) < 0) { result = FAIL; } else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) - 1) { result = FAIL; } if ((MeterSMId = shmget(ShmFanBdKey, sizeof(struct FanModuleData), 0777)) < 0) { result = FAIL; } else if ((ShmFanModuleData = shmat(MeterSMId, NULL, 0)) == (void *) - 1) { result = FAIL; } memset(ShmFanModuleData, 0, sizeof(struct FanModuleData)); if ((MeterSMId = shmget(ShmRelayBdKey, sizeof(struct RelayModuleData), 0777)) < 0) { result = FAIL; } else if ((ShmRelayModuleData = shmat(MeterSMId, NULL, 0)) == (void *) - 1) { result = FAIL; } memset(ShmRelayModuleData, 0, sizeof(struct RelayModuleData)); if ((MeterSMId = shmget(ShmLedBdKey, sizeof(struct LedModuleData), 0777)) < 0) { result = FAIL; } else if ((ShmLedModuleData = shmat(MeterSMId, NULL, 0)) == (void *) - 1) { result = FAIL; } memset(ShmLedModuleData, 0, sizeof(struct LedModuleData)); if ((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData), 0777)) < 0) { result = FAIL; } else if ((ShmPsuData = shmat(MeterSMId, NULL, 0)) == (void *) - 1) { result = FAIL; } if ((MeterSMId = shmget(ShmOcppModuleKey, sizeof(struct OCPP16Data), 0777)) < 0) { result = FAIL; } else if ((ShmOCPP16Data = shmat(MeterSMId, NULL, 0)) == (void *) - 1) { result = FAIL; } if ((MeterSMId = shmget(ShmCommonKey, sizeof(DcCommonInfo), IPC_CREAT | 0777)) < 0) { return FAIL; } else if ((ShmDcCommonData = shmat(MeterSMId, NULL, 0)) == (void *) - 1) { return FAIL; } return result; } int InitComPort() { int fd; struct termios tios; fd = open(relayRs485PortName, O_RDWR); if (fd <= 0) { #ifdef SystemLogMessage log_error("Module_InternalComm. InitComPort NG\n"); #endif if (ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); return -1; } ioctl (fd, TCGETS, &tios); tios.c_cflag = B115200 | CS8 | CLOCAL | CREAD; tios.c_lflag = 0; tios.c_iflag = 0; tios.c_oflag = 0; tios.c_cc[VMIN] = 0; tios.c_cc[VTIME] = (uint8_t)0; // timeout 0.5 second tios.c_lflag = 0; tcflush(fd, TCIFLUSH); ioctl (fd, TCSETS, &tios); return fd; } //================================================ // Main process //================================================ bool FindChargingInfoData(uint8_t target, struct ChargingInfoData **chargingData) { for (uint8_t index = 0; index < CHAdeMO_QUANTITY; index++) { if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == target) { chargingData[target] = &ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index]; return true; } } for (uint8_t index = 0; index < CCS_QUANTITY; index++) { if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == target) { chargingData[target] = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[index]; return true; } } for (uint8_t index = 0; index < GB_QUANTITY; index++) { if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == target) { chargingData[target] = &ShmSysConfigAndInfo->SysInfo.GbChargingData[index]; return true; } } return false; } bool FindAcChargingInfoData(uint8_t target, struct ChargingInfoData **acChargingData) { if (target < AC_QUANTITY) { acChargingData[target] = &ShmSysConfigAndInfo->SysInfo.AcChargingData[target]; return true; } return false; } void Initialization() { bool isPass = false; for (uint8_t index = 0; index < ARRAY_SIZE(outputRelay.relay_event.relay_status); index++) { outputRelay.relay_event.relay_status[index] = 0x00; } while (!isPass) { isPass = true; for (uint8_t _index = 0; _index < gunCount; _index++) { if (!FindChargingInfoData(_index, &_chargingData[0])) { log_error("InternalComm : FindChargingInfoData false \n"); isPass = false; break; } } sleep(1); } isPass = false; if (acgunCount > 0) { while (!isPass) { isPass = true; for (uint8_t _index = 0; _index < acgunCount; _index++) { if (!FindAcChargingInfoData(_index, &ac_chargingInfo[0])) { log_error("EvComm : FindAcChargingInfoData false \n"); isPass = false; break; } } sleep(1); } } } bool IsNoneMatchRelayStatus() { bool result = false; if ( #if !defined DD360Tcci && !defined DD360Audi && !defined DD360ComBox (regRelay.relay_event.bits.AC_Contactor != outputRelay.relay_event.bits.AC_Contactor) || (regRelay.relay_event.bits.CCS_Precharge != outputRelay.relay_event.bits.CCS_Precharge) || #endif //!defined DD360Tcci && !defined DD360Audi (regRelay.relay_event.bits.Gun1_P != outputRelay.relay_event.bits.Gun1_P) || (regRelay.relay_event.bits.Gun1_N != outputRelay.relay_event.bits.Gun1_N) || (regRelay.relay_event.bits.Gun2_P != outputRelay.relay_event.bits.Gun2_P) || (regRelay.relay_event.bits.Gun2_N != outputRelay.relay_event.bits.Gun2_N) #if !defined DD360Tcci && !defined DD360Audi && !defined DD360ComBox || (regRelay.relay_event.bits.Gun1_Parallel_P != outputRelay.relay_event.bits.Gun1_Parallel_P) || (regRelay.relay_event.bits.Gun1_Parallel_N != outputRelay.relay_event.bits.Gun1_Parallel_N) #endif //!defined DD360Tcci && !defined DD360Audi ) { /*if (regRelay.relay_event.bits.AC_Contactor != outputRelay.relay_event.bits.AC_Contactor) { log_info("AC Contact Relay none match. \n"); } if (regRelay.relay_event.bits.CCS_Precharge != outputRelay.relay_event.bits.CCS_Precharge) { log_info("CCS Precharge Relay none match. \n"); } if (regRelay.relay_event.bits.Gun1_P != outputRelay.relay_event.bits.Gun1_P) { log_info("SMR1:D+ Relay none match. \n"); } if (regRelay.relay_event.bits.Gun1_N != outputRelay.relay_event.bits.Gun1_N) { log_info("SMR1:D- Relay none match. \n"); } if (regRelay.relay_event.bits.Gun2_P != outputRelay.relay_event.bits.Gun2_P) { log_info("SMR2:D+ Relay none match. \n"); } if (regRelay.relay_event.bits.Gun2_N != outputRelay.relay_event.bits.Gun2_N) { log_info("SMR2:D- Relay none match. \n"); } if (regRelay.relay_event.bits.Gun1_Parallel_P != outputRelay.relay_event.bits.Gun1_Parallel_P) { log_info("Parallel:D+ Relay none match. \n"); } if (regRelay.relay_event.bits.Gun1_Parallel_N != outputRelay.relay_event.bits.Gun1_Parallel_N) { log_info("Parallel:D- Relay none match. \n"); }*/ result = true; } return result; } void MatchRelayStatus() { // 因為 AC Contactor 沒有 Feedback,所以暫時先這樣處理 //regRelay.relay_event.bits.AC_Contactor = outputRelay.relay_event.bits.AC_Contactor; #if !defined DD360Tcci && !defined DD360Audi && !defined DD360ComBox ShmSysConfigAndInfo->SysInfo.AcContactorStatus = regRelay.relay_event.bits.AC_Contactor = outputRelay.relay_event.bits.AC_Contactor; #endif //!defined DD360Tcci && !defined DD360Audi regRelay.relay_event.bits.CCS_Precharge = outputRelay.relay_event.bits.CCS_Precharge; regRelay.relay_event.bits.Gun1_P = outputRelay.relay_event.bits.Gun1_P; regRelay.relay_event.bits.Gun1_N = outputRelay.relay_event.bits.Gun1_N; regRelay.relay_event.bits.Gun2_P = outputRelay.relay_event.bits.Gun2_P; regRelay.relay_event.bits.Gun2_N = outputRelay.relay_event.bits.Gun2_N; regRelay.relay_event.bits.Gun1_Parallel_P = outputRelay.relay_event.bits.Gun1_Parallel_P; regRelay.relay_event.bits.Gun1_Parallel_N = outputRelay.relay_event.bits.Gun1_Parallel_N; } void CheckRelayStatusByADC() { if (ShmRelayModuleData->Gun1FuseOutputVolt > 0 && ShmRelayModuleData->Gun1RelayOutputVolt > 0 && (ShmRelayModuleData->Gun1FuseOutputVolt == ShmRelayModuleData->Gun1RelayOutputVolt)) { // Relay 前後電壓一致 _chargingData[0]->RelayK1K2Status = 0x01; } else { _chargingData[0]->RelayK1K2Status = 0x00; } if (ShmRelayModuleData->Gun2FuseOutputVolt > 0 && ShmRelayModuleData->Gun2RelayOutputVolt > 0 && (ShmRelayModuleData->Gun2FuseOutputVolt == ShmRelayModuleData->Gun2RelayOutputVolt)) { // Relay 前後電壓一致 _chargingData[1]->RelayK1K2Status = 0x01; } else { _chargingData[1]->RelayK1K2Status = 0x00; } } void SetGfdConfig(uint8_t index, uint8_t resister) { gfd_config.index = index; gfd_config.state = resister; //log_info("************************GFD Vol = %d, GFD Res = %d \n", gfd_config.reqVol, gfd_config.resister); if (Config_Gfd_Value(Uart5Fd, ADDR_RELAY, &gfd_config) == PASS) { // log_info("Set reqVol = %f, resister = %d \n", // gfd_config.reqVol, // gfd_config.resister); } } void CableCheckDetected(uint8_t index) { uint8_t targetID = 0; // Cable Check // 當火線上的電壓 = 車端要求的電壓電流 // _chargingData[targetGun]->EvBatterytargetVoltage // 才可以開始偵測 1s // Warning : Rgfd <= 150 歐/V 假設電壓為 500V 則~ Rgfd <= 75000 歐 // Pre-Warning : 150 歐/V < Rgfd <= 500 歐/V 假設電壓為 500V 則 75000 歐 < Rgfd <= 250000 // SO Normal : Rgfd > 500 歐/V 假設電壓為 500 V 則 Rgfd > 250000 歐 if (gunCount == 1) { if (strncmp((char *)&ShmSysConfigAndInfo->SysConfig.ModelName[7], "0", 1) != 0) { targetID = 0; } else if (strncmp((char *)&ShmSysConfigAndInfo->SysConfig.ModelName[9], "0", 1) != 0) { targetID = 1; } } else { targetID = index; } 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_TERMINATING) || (_chargingData[index]->SystemStatus >= S_CCS_PRECHARGE_ST0 && _chargingData[index]->SystemStatus <= S_CCS_PRECHARGE_ST1)) { if (_chargingData[index]->SystemStatus == S_PREPARING_FOR_EVSE && _chargingData[index]->RelayWeldingCheck == YES) { SetGfdConfig(targetID, GFD_CABLECHK); } else if (_chargingData[index]->SystemStatus >= S_CCS_PRECHARGE_ST0 && _chargingData[index]->SystemStatus <= S_CCS_PRECHARGE_ST1) { SetGfdConfig(targetID, GFD_PRECHARGE); } else if (_chargingData[index]->SystemStatus >= S_CHARGING && _chargingData[index]->SystemStatus <= S_TERMINATING) { if (_chargingData[index]->Type == _Type_GB || _chargingData[index]->Type == _Type_Chademo) { SetGfdConfig(targetID, GFD_IDLE); } else { SetGfdConfig(targetID, GFD_CHARGING); } } } else if (_chargingData[index]->SystemStatus == S_COMPLETE || _chargingData[index]->SystemStatus == S_PREPARNING || _chargingData[index]->SystemStatus == S_IDLE) { SetGfdConfig(targetID, GFD_IDLE); } } } void CheckOutputPowerOverCarReq(uint8_t index) { float fireV = _chargingData[index]->FireChargingVoltage; float carV = _chargingData[index]->EvBatteryMaxVoltage * 10; if ((_chargingData[index]->EvBatterytargetVoltage * 10) > 1500 && (_chargingData[index]->Type == _Type_Chademo || _chargingData[index]->Type == _Type_CCS_2 || _chargingData[index]->Type == _Type_GB)) { if (fireV >= (carV + (carV * 0.02))) { if (!_isOvpChkTimeFlag[index]) { if ((_chargingData[index]->PresentChargingVoltage * 10) >= VOUT_MIN_VOLTAGE * 10) { gettimeofday(&_checkOutputVolProtectTimer[index], NULL); _isOvpChkTimeFlag[index] = YES; } } else { log_info("[Module_InternalComm]CheckOutputPowerOverCarReq NG : fire = %f, battery = %f \n", _chargingData[index]->FireChargingVoltage, (_chargingData[index]->EvBatterytargetVoltage * 10)); log_error("[Module_InternalComm]CheckOutputPowerOverCarReq NG : fire = %f, battery = %f \n", _chargingData[index]->FireChargingVoltage, (_chargingData[index]->EvBatterytargetVoltage * 10)); if ((GetTimeoutValue(_checkOutputVolProtectTimer[index]) / 1000) >= OUTPUT_VOL_CHK_TIME) { //if (_chargingData[index]->Type == _Type_Chademo) { // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemChademoOutputOVP = YES; //} else if (_chargingData[index]->Type == _Type_CCS_2) { // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemCcsOutputOVP = YES; //} else if (_chargingData[index]->Type == _Type_GB) { // ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemGbOutputOVP = YES; //} if (_chargingData[index]->Type == _Type_Chademo) { ShmDcCommonData->ConnectErrList[index].GunBits.ChaConnectOVP = YES; if (strncmp((char *)_chargingData[index]->ConnectorAlarmCode, "", 6) == EQUAL) { memcpy(_chargingData[index]->ConnectorAlarmCode, "012217", 6); } } else if (_chargingData[index]->Type == _Type_CCS_2) { ShmDcCommonData->ConnectErrList[index].GunBits.CCSConnectOVP = YES; if (strncmp((char *)_chargingData[index]->ConnectorAlarmCode, "", 6) == EQUAL) { memcpy(_chargingData[index]->ConnectorAlarmCode, "012219", 6); } } else if (_chargingData[index]->Type == _Type_GB) { ShmDcCommonData->ConnectErrList[index].GunBits.GBTConnectOVP = YES; if (strncmp((char *)_chargingData[index]->ConnectorAlarmCode, "", 6) == EQUAL) { memcpy(_chargingData[index]->ConnectorAlarmCode, "012221", 6); } } _chargingData[index]->StopChargeFlag = YES; } } } else { if (_isOvpChkTimeFlag[index] == YES) { _isOvpChkTimeFlag[index] = NO; } } } } void CheckOutputVolNoneMatchFire(uint8_t index) { if ((_chargingData[index]->EvBatterytargetVoltage * 10) > 1500 && (_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) || ((_chargingData[index]->PresentChargingVoltage * 10) > _chargingData[index]->FireChargingVoltage + 300)) { if (!_isOutputNoneMatch[index]) { _isOutputNoneMatch[index] = YES; gettimeofday(&_checkOutputNoneMatchTimer[index], NULL); } else { if ((GetTimeoutValue(_checkOutputNoneMatchTimer[index]) / 1000) >= 5000) { /*log_info("[Module_InternalComm]CheckOutputVolNoneMatchFire NG (%d) : pre = %f, fire = %f \n", index, (_chargingData[index]->PresentChargingVoltage * 10), _chargingData[index]->FireChargingVoltage); log_error("[Module_InternalComm]CheckOutputVolNoneMatchFire NG (%d): pre = %f, fire = %f \n", index, (_chargingData[index]->PresentChargingVoltage * 10), _chargingData[index]->FireChargingVoltage); _chargingData[index]->StopChargeFlag = YES;*/ } } } else { _isOutputNoneMatch[index] = NO; } } } void CheckRelayWeldingStatus(uint8_t index) { if (!_isRelayWelding[index]) { if ((_chargingData[index]->PresentChargingVoltage * 10) >= VOUT_MIN_VOLTAGE * 10) { gettimeofday(&_checkRelayWeldingTimer[index], NULL); _isRelayWelding[index] = YES; } } else { if ((GetTimeoutValue(_checkRelayWeldingTimer[index]) / 1000) >= 1000) { _chargingData[index]->RelayWeldingCheck = YES; return; } if (_chargingData[index]->FireChargingVoltage >= VOUT_MIN_VOLTAGE) { if (_chargingData[index]->Type == _Type_Chademo) { ShmStatusCodeData->FaultCode.FaultEvents.bits.ChademoOutputRelayWelding = YES; } else if (_chargingData[index]->Type == _Type_GB) { ShmStatusCodeData->FaultCode.FaultEvents.bits.GbOutputRelayWelding = YES; } else if (_chargingData[index]->Type == _Type_CCS_2) { ShmStatusCodeData->FaultCode.FaultEvents.bits.CcsOutputRelayWelding = YES; } log_info("CheckRelayWeldingStatus : fail \n"); _chargingData[index]->StopChargeFlag = YES; } } } void GetPsuTempForFanSpeed() { char temp = 0; for (uint8_t index = 0; index < ShmPsuData->GroupCount; index++) { for (uint8_t count = 0; count < ShmPsuData->PsuGroup[index].GroupPresentPsuQuantity; count++) { if (temp < ShmPsuData->PsuGroup[index].PsuModule[count].ExletTemp) { temp = ShmPsuData->PsuGroup[index].PsuModule[count].ExletTemp; } } } ShmSysConfigAndInfo->SysInfo.SystemAmbientTemp = temp; if (ShmSysConfigAndInfo->SysConfig.SwitchDebugFlag == NO) { if (ShmFanModuleData->TestFanSpeed == NORMAL_FAN_SPEED) { if (temp >= ENV_TEMP_MAX) { ShmFanModuleData->TestFanSpeed = MAX_FAN_SPEED; } } else if (ShmFanModuleData->TestFanSpeed == MAX_FAN_SPEED) { if (temp <= ENV_TEMP_MIN) { ShmFanModuleData->TestFanSpeed = NORMAL_FAN_SPEED; } } else { ShmFanModuleData->TestFanSpeed = NORMAL_FAN_SPEED; } } } void GetFanSpeedByFunction() { if (ShmSysConfigAndInfo->SysConfig.SwitchDebugFlag == YES) { return; } // 風控修改 : // ******************************************************* // // // 當前PSU輸出總 KW PSU Temp // 30 x -------------------- x ---------- + 14 x (PSU Temp - 45) // 當前樁最大功率 KW 45 // // ******************************************************* // // 當前樁最大功率 KW : ShmPsuData->SystemAvailablePower unsigned int _maxPower = ShmPsuData->SystemAvailablePower; // 當前PSU輸出總 KW & PSU Temp : uint8_t temp = 0; float power = 0; for (uint8_t index = 0; index < ShmPsuData->GroupCount; index++) { for (uint8_t count = 0; count < ShmPsuData->PsuGroup[index].GroupPresentPsuQuantity; count++) { if (temp < ShmPsuData->PsuGroup[index].PsuModule[count].ExletTemp) { temp = ShmPsuData->PsuGroup[index].PsuModule[count].ExletTemp; } } } for (uint8_t gunIndex = 0; gunIndex < gunCount; gunIndex++) { power += (_chargingData[gunIndex]->PresentChargingPower * 10); } double _pw_rate = 0; if (_maxPower > 0) { _pw_rate = power / (double)_maxPower; } double _temp_rate = 0; if (temp > 0) { _temp_rate = (double)temp / 50; } uint8_t _temp_diff = 0; if (temp > 45) { _temp_diff = temp - 70; } ShmFanModuleData->TestFanSpeed = (((50 * _pw_rate * _temp_rate) + (0.5 * _temp_diff)) / 100) * MAX_FAN_SPEED; if (ShmFanModuleData->TestFanSpeed > MAX_FAN_SPEED) { ShmFanModuleData->TestFanSpeed = MAX_FAN_SPEED; } if (ShmFanModuleData->TestFanSpeed < 0) { ShmFanModuleData->TestFanSpeed = 0; } // // printf("power = %f \n", power); // printf("_maxPower = %d \n", _maxPower); // printf("temp = %d \n", temp); // // printf("_pw_rate = %f \n", _pw_rate); // printf("_temp_rate = %f \n", _temp_rate); // printf("_temp_diff = %d \n", _temp_diff); // printf("fan rate = %f \n", (30 * _pw_rate * _temp_rate + 14 * _temp_diff)); // printf("ShmFanModuleData->TestFanSpeed = %d \n", ShmFanModuleData->TestFanSpeed); } void GetAcStatus() { if (Query_AC_Status(Uart5Fd, ADDR_AC_PLUG, &acStatus) == PASS) { ShmSysConfigAndInfo->SysConfig.AcRatingCurrent = acStatus.MaxCurrent; if (ShmSysConfigAndInfo->SysConfig.AcMaxChargingCurrent == 0) { ShmSysConfigAndInfo->SysConfig.AcMaxChargingCurrent = ShmSysConfigAndInfo->SysConfig.AcRatingCurrent; } ac_chargingInfo[0]->ConnectorPlugIn = acStatus.CpStatus; // log_info("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; } // else // log_info("GetAcStatus return fail. \n"); } void GetAcAlarmCode() { if (Query_AC_Alarm_Code(Uart5Fd, ADDR_AC_PLUG, &acAlarmCode) == PASS) { CheckAlarmOccur(); } } uint8_t GetChargingEnergy() { return Query_Charging_Energy(Uart5Fd, ADDR_AC_PLUG, &acChargingEnergy); } uint8_t GetChargingCurrent() { return Query_Charging_Current(Uart5Fd, ADDR_AC_PLUG, &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_AC_PLUG, &ledStatus); } void SetLegacyReq(uint8_t _switch) { Config_Legacy_Req(Uart5Fd, ADDR_AC_PLUG, _switch); } void SetCpDuty(uint8_t _value) { Config_Ac_Duty(Uart5Fd, ADDR_AC_PLUG, _value); } void ChangeToCsuMode() { ac_chargingInfo[0]->IsModeChagned = Config_CSU_Mode(Uart5Fd, ADDR_AC_PLUG); // if (ac_chargingInfo[0]->IsModeChagned == PASS) // { // Config_Reset_MCU(Uart5Fd, ADDR_AC_PLUG); // } } void ChangeStartOrStopDateTime(uint8_t isStart) { char cmdBuf[32]; struct timeb csuTime; struct tm *tmCSU; ftime(&csuTime); tmCSU = localtime(&csuTime.time); sprintf(cmdBuf, "%04d-%02d-%02d %02d:%02d:%02d", tmCSU->tm_year + 1900, tmCSU->tm_mon + 1, tmCSU->tm_mday, tmCSU->tm_hour, tmCSU->tm_min, tmCSU->tm_sec); if (isStart) { strcpy((char *)ac_chargingInfo[0]->StartDateTime, cmdBuf); } else { strcpy((char *)ac_chargingInfo[0]->StopDateTime, cmdBuf); } } void OcppStartTransation(uint8_t gunIndex) { if (strcmp((char *)ac_chargingInfo[0]->StartUserId, "") == EQUAL) { strcpy((char *)ShmOCPP16Data->StartTransaction[gunIndex].IdTag, (char *)ShmOCPP16Data->StartTransaction[gunIndex].IdTag); } else { strcpy((char *)ShmOCPP16Data->StartTransaction[gunIndex].IdTag, (char *)ac_chargingInfo[0]->StartUserId); } log_info("AC IdTag = %s \n", ShmOCPP16Data->StartTransaction[gunIndex].IdTag); ShmOCPP16Data->CpMsg.bits[gunIndex].StartTransactionReq = YES; } void OcppStopTransation(uint8_t gunIndex) { if (strcmp((char *)ac_chargingInfo[0]->StartUserId, "") == EQUAL) { strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].IdTag, (char *)ShmOCPP16Data->StopTransaction[gunIndex].IdTag); } else { strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].IdTag, (char *)ac_chargingInfo[0]->StartUserId); } log_info("AC IdTag = %s \n", ShmOCPP16Data->StopTransaction[gunIndex].IdTag); ShmOCPP16Data->CpMsg.bits[gunIndex].StopTransactionReq = YES; } bool OcppRemoteStop(uint8_t gunIndex) { bool result = ShmOCPP16Data->CsMsg.bits[gunIndex].RemoteStopTransactionReq; if (ShmOCPP16Data->CsMsg.bits[gunIndex].RemoteStopTransactionReq == YES) { strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].StopReason, "Remote"); ShmOCPP16Data->CsMsg.bits[gunIndex].RemoteStopTransactionReq = NO; } return result; } uint8_t isModeChange() { uint8_t result = NO; if (ac_chargingInfo[0]->SystemStatus != ac_chargingInfo[0]->PreviousSystemStatus) { result = YES; ac_chargingInfo[0]->PreviousSystemStatus = ac_chargingInfo[0]->SystemStatus; } return result; } void AcChargeTypeProcess() { if (acgunCount > 0) { //ac_chargingInfo[0]->SelfTest_Comp = YES; //ac_chargingInfo[0]->IsModeChagned = PASS; //--------------------------------------------- if (ac_chargingInfo[0]->SelfTest_Comp == NO) { ac_chargingInfo[0]->IsModeChagned = NO; GetFwVersion_AC(); GetAcModelName(); } else if (ac_chargingInfo[0]->SelfTest_Comp == YES) { if (ac_chargingInfo[0]->IsModeChagned != PASS) { ChangeToCsuMode(); return; } GetAcStatus(); GetAcAlarmCode(); uint8_t _status = S_NONE; if (ac_chargingInfo[0]->SystemStatus == S_IDLE && ac_chargingInfo[0]->IsErrorOccur) { _status = S_ALARM; } else 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 && acStatus.CpStatus == AC_SYS_A) { _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]->ConnectorPlugIn == AC_SYS_B) && ac_chargingInfo[0]->IsAvailable && !ac_chargingInfo[0]->IsErrorOccur && (ShmSysConfigAndInfo->SysInfo.WaitForPlugit == YES || ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE)) { if (ac_chargingInfo[0]->RemoteStartFlag == YES) { log_info("** AC Remote \n"); ac_chargingInfo[0]->RemoteStartFlag = NO; strcpy((char *)ac_chargingInfo[0]->StartUserId, ""); ShmSysConfigAndInfo->SysInfo.WaitForPlugit = NO; _status = S_PREPARNING; } else if (ShmSysConfigAndInfo->SysInfo.OrderCharging == NO_DEFINE) { log_info("** UserId = %s \n", ShmSysConfigAndInfo->SysConfig.UserId); strcpy((char *)ac_chargingInfo[0]->StartUserId, (char *)ShmSysConfigAndInfo->SysConfig.UserId); log_info("** CardNumber = %s \n", ac_chargingInfo[0]->StartUserId); strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); ShmSysConfigAndInfo->SysInfo.WaitForPlugit = NO; _status = S_PREPARNING; } } else if (ac_chargingInfo[0]->SystemStatus == S_CHARGING) { if (OcppRemoteStop(1)) { _status = S_TERMINATING; } } //printf("_status = %d \n", _status); if (_status != S_NONE && ac_chargingInfo[0]->SystemStatus != _status) { ac_chargingInfo[0]->SystemStatus = _status; } // 設定限制最大充電電流 >= 6 ~ <= 32 switch (ac_chargingInfo[0]->SystemStatus) { case S_IDLE: case S_ALARM: { if (isModeChange()) { ac_chargingInfo[0]->PresentChargedEnergy = 0.0; ac_chargingInfo[0]->PresentChargingVoltage = 0; ac_chargingInfo[0]->ChargingFee = 0.0; strcpy((char *)ac_chargingInfo[0]->StartDateTime, ""); strcpy((char *)ac_chargingInfo[0]->StopDateTime, ""); _beforeChargingTotalEnergy = 0.0; } ChangeLedStatus(); } break; case S_PREPARNING: { if (isModeChange()) { ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = DEFAULT_AC_INDEX; if (ShmSysConfigAndInfo->SysInfo.OrderCharging != NO_DEFINE) { ShmSysConfigAndInfo->SysInfo.OrderCharging = NO_DEFINE; } gettimeofday(&_ac_preparing, NULL); } if (GetChargingEnergy() == PASS) { //ac_chargingInfo[0]->PresentChargedEnergy = acChargingEnergy.Energy / 100; _beforeChargingTotalEnergy = acChargingEnergy.Energy; } SetLegacyReq(YES); ChangeLedStatus(); } break; case S_CHARGING: { if (isModeChange()) { ftime(&_ac_startChargingTime); OcppStartTransation(1); ChangeStartOrStopDateTime(YES); ShmSysConfigAndInfo->SysInfo.CurGunSelectedByAc = DEFAULT_AC_INDEX; } if (GetChargingEnergy() == PASS) { if ((acChargingEnergy.Energy - _beforeChargingTotalEnergy) > 0) { ac_chargingInfo[0]->PresentChargedEnergy += (acChargingEnergy.Energy - _beforeChargingTotalEnergy) / 100; if (ShmSysConfigAndInfo->SysConfig.BillingData.isBilling) { ac_chargingInfo[0]->ChargingFee += ac_chargingInfo[0]->PresentChargedEnergy * ShmSysConfigAndInfo->SysConfig.BillingData.Cur_fee; } } _beforeChargingTotalEnergy = acChargingEnergy.Energy; } if (GetChargingCurrent() == PASS) { ac_chargingInfo[0]->PresentChargingPower = (((float)(AC_DEFAULT_VOL * acChargingCurrent.OuputCurrentL1) / 10) / 1000); } ftime(&_ac_endChargingTime); ac_chargingInfo[0]->PresentChargedDuration = DiffTimeb(_ac_startChargingTime, _ac_endChargingTime); ac_chargingInfo[0]->PresentChargingVoltage = AC_DEFAULT_VOL; ac_chargingInfo[0]->PresentChargingCurrent = ((float)acChargingCurrent.OuputCurrentL1 / 10); // 用以判斷是否有在輸出 ac_chargingInfo[0]->IsCharging = acStatus.RelayStatus; SetCpDuty(ShmSysConfigAndInfo->SysConfig.AcMaxChargingCurrent); ChangeLedStatus(); } break; case S_TERMINATING: { if (isModeChange()) { ChangeStartOrStopDateTime(NO); gettimeofday(&_ac_charging_comp, NULL); } SetLegacyReq(NO); if (acStatus.RelayStatus == NO) { ac_chargingInfo[0]->SystemStatus = S_COMPLETE; } } break; case S_COMPLETE: { if (isModeChange()) { gettimeofday(&_ac_charging_comp, NULL); ftime(&_ac_endChargingTime); if (strcmp((char *)ac_chargingInfo[0]->StartDateTime, "") != EQUAL) { // AC 固定為第2把槍 OcppStopTransation(1); } ChangeStartOrStopDateTime(NO); ac_chargingInfo[0]->PresentChargedDuration = DiffTimeb(_ac_startChargingTime, _ac_endChargingTime); } } break; } } } } void ResetDetAlarmStatus(uint8_t gun) { if (_chargingData[gun]->Type == _Type_Chademo) { if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemChademoOutputOVP == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemChademoOutputOVP = NO; } } else if (_chargingData[gun]->Type == _Type_GB) { if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemGbOutputOVP == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemGbOutputOVP = NO; } } else if (_chargingData[gun]->Type == _Type_CCS_2) { if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemCcsOutputOVP == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemCcsOutputOVP = NO; } } } int main(void) { uint8_t i = 0; if (InitShareMemory() == FAIL) { log_error("InitShareMemory NG\n"); if (ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory = 1; } sleep(5); return 0; } gunCount = ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; acgunCount = ShmSysConfigAndInfo->SysConfig.AcConnectorCount; // Open Uart5 for RB Uart5Fd = InitComPort(); Initialization(); sleep(1); if (Uart5Fd < 0) { log_info("(Internal) open port error. \n"); return 0; } outputRelay.relay_event.bits.AC_Contactor = 0x00; outputRelay.relay_event.bits.CCS_Precharge = 0x00; outputRelay.relay_event.bits.Gun1_Parallel_P = 0x00; outputRelay.relay_event.bits.Gun1_Parallel_N = 0x00; outputRelay.relay_event.bits.Gun1_P = 0x00; outputRelay.relay_event.bits.Gun1_N = 0x00; outputRelay.relay_event.bits.Gun2_N = 0x00; outputRelay.relay_event.bits.Gun2_P = 0x00; if (Config_Relay_Output(Uart5Fd, ADDR_RELAY, &outputRelay) != PASS) { log_info("Config_Relay_Output fail \n"); } cur_led_color.Connect_1_Red = COLOR_MIN_LV; cur_led_color.Connect_1_Green = COLOR_MIN_LV; cur_led_color.Connect_1_Blue = COLOR_MIN_LV; cur_led_color.Connect_2_Red = COLOR_MIN_LV; cur_led_color.Connect_2_Green = COLOR_MIN_LV; cur_led_color.Connect_2_Blue = COLOR_MIN_LV; //bool printRelayStatus = true; for (;;) { bool isCharging = false; // 程序開始之前~ 必須先確定 FW 版本與硬體版本,確認後!!~ 該模組才算是真正的 Initial Comp. if (ShmRelayModuleData->SelfTest_Comp == NO) { GetFwAndHwVersion_Relay(); SetModelName_Relay(); //DS60-120 add SetRtcData_Relay(); sleep(1); } #if !defined NO_FAN_BOARD && !defined DD360ComBox if (ShmFanModuleData->SelfTest_Comp == NO) { GetFwAndHwVersion_Fan(); SetModelName_Fan(); SetRtcData_Fan(); sleep(1); gettimeofday(&_priority_time, NULL); } #endif //NO_FAN_BOARD #if !defined DD360ComBox // 自檢階段處理,自檢階段如果讀不到版號則代表該系統沒有掛燈板 if (ShmLedModuleData->SelfTest_Comp == NO) { #if defined DD360Tcci ||defined DD360Audi GetFwAndHwVersion_Led(); sleep(1); gettimeofday(&_led_priority_time, NULL); #else // 自檢階段 if (ShmSysConfigAndInfo->SysInfo.SelfTestSeq <= _STEST_PSU_CAP) { GetFwAndHwVersion_Led(); sleep(1); gettimeofday(&_led_priority_time, NULL); } else { // 自檢階段沒有問到版號 if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.LedboardStestFail == NO) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.LedboardStestFail = YES; } } #endif //defined DD360Tcci || defined DD360Audi } #endif //!defined DD360ComBox AcChargeTypeProcess(); if (ShmRelayModuleData->SelfTest_Comp == YES) { // ==============優先權最高 10 ms ============== // 輸出電壓 GetPersentOutputVol(); #if !defined DD360Tcci && !defined DD360Audi && !defined DD360ComBox // 三相輸入電壓 GetPresentInputVol(); // 讀取當前 AC relay 狀態 regRelay.relay_event.bits.AC_Contactor = ShmSysConfigAndInfo->SysInfo.AcContactorStatus; GetRelayOutputStatus(); #endif //!defined DD360Tcci && !defined DD360Audi for (i = 0; i < gunCount; i++) { // Cable check (Set) CableCheckDetected(i); // check k1 k2 relay 狀態 CheckK1K2RelayOutput(i); // 依據當前各槍的狀態選擇 搭上/放開 Relay SetK1K2RelayStatus(i); #if !defined DD360Tcci && !defined DD360Audi && !defined DD360ComBox if (ShmSysConfigAndInfo->SysConfig.PhaseLossPolicy == YES) { CheckPhaseLossStatus(i); } CheckAcInputOvpStatus(i); #endif //!defined DD360Tcci && !defined DD360Audi if (_chargingData[i]->SystemStatus == S_IDLE) { _chargingData[i]->RelayWeldingCheck = NO; _isRelayWelding[i] = NO; _isOvpChkTimeFlag[i] = NO; ResetDetAlarmStatus(i); //DS60-120 add } if (_chargingData[i]->SystemStatus == S_BOOTING || (_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) || ShmSysConfigAndInfo->SysInfo.WaitForPlugit == YES || (ShmSysConfigAndInfo->SysInfo.PageIndex >= _LCM_AUTHORIZING && ShmSysConfigAndInfo->SysInfo.PageIndex <= _LCM_WAIT_FOR_PLUG)) { _chargingData[i]->IsReadyToCharging = YES; isCharging = true; // 限定只有在槍類別為 GBT 的時候才做 relay welding 的判斷 //if (_chargingData[i]->Type == _Type_GB) { // if (_chargingData[i]->SystemStatus >= S_PREPARING_FOR_EVSE && // _chargingData[i]->RelayWeldingCheck == NO) { // CheckRelayWeldingStatus(i); // } //} else { _chargingData[i]->RelayWeldingCheck = YES; //} if (_chargingData[i]->SystemStatus == S_CHARGING) { CheckOutputPowerOverCarReq(i); //CheckOutputVolNoneMatchFire(i); } else { _isOutputNoneMatch[i] = NO; } } else { _chargingData[i]->IsReadyToCharging = NO; } } // Cable check (Get) GetGfdAdc(); // 橋接 relay SetParalleRelayStatus(); // 搭上 AC Contactor //if (isCharging) { // outputRelay.relay_event.bits.AC_Contactor = YES; //} else { // outputRelay.relay_event.bits.AC_Contactor = NO; //} if (isCharging || (ShmPsuData->Work_Step >= _TEST_MODE && ShmPsuData->Work_Step <= _TEST_MODE)) { isStopChargingCount = false; outputRelay.relay_event.bits.AC_Contactor = YES; } else { if (!isStopChargingCount) { gettimeofday(&_close_ac_contactor, NULL); isStopChargingCount = true; } else { if ((outputRelay.relay_event.bits.AC_Contactor == YES && GetTimeoutValue(_close_ac_contactor) / 1000 >= (TEN_MINUTES * 1000))) { outputRelay.relay_event.bits.AC_Contactor = NO; } } } if (ShmPsuData->Work_Step >= _TEST_MODE && ShmPsuData->Work_Step <= _TEST_MODE) { outputRelay.relay_event.bits.Gun1_N = outputRelay.relay_event.bits.Gun1_P = YES; } // 搭上/鬆開 Relay if (IsNoneMatchRelayStatus()) { 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.Gun1_P = outputRelay.relay_event.bits.Gun1_P; regRelay.relay_event.bits.Gun1_N = outputRelay.relay_event.bits.Gun1_N; regRelay.relay_event.bits.Gun2_P = outputRelay.relay_event.bits.Gun2_P; regRelay.relay_event.bits.Gun2_N = outputRelay.relay_event.bits.Gun2_N; regRelay.relay_event.bits.Gun1_Parallel_P = outputRelay.relay_event.bits.Gun1_Parallel_P; regRelay.relay_event.bits.Gun1_Parallel_N = outputRelay.relay_event.bits.Gun1_Parallel_N; //log_info("Match Relay, AC = %x, g1_p = %x, g1_n = %x, g2_p = %x, g2_n = %x, pre = %x, bri_p = %x, bri_n = %x \n", // regRelay.relay_event.bits.AC_Contactor, // regRelay.relay_event.bits.Gun1_P, // regRelay.relay_event.bits.Gun1_N, // regRelay.relay_event.bits.Gun2_P, // regRelay.relay_event.bits.Gun2_N, // regRelay.relay_event.bits.CCS_Precharge, // regRelay.relay_event.bits.Gun1_Parallel_P, // regRelay.relay_event.bits.Gun1_Parallel_N); } } } #if !defined NO_FAN_BOARD && !defined DD360ComBox if (ShmFanModuleData->SelfTest_Comp == YES || strlen((char *)ShmSysConfigAndInfo->SysInfo.FanModuleFwRev) != 0 || ShmSysConfigAndInfo->SysInfo.FanModuleFwRev[0] != '\0') { ShmFanModuleData->SelfTest_Comp = YES; if (GetTimeoutValue(_priority_time) / 1000 >= 1000) { //GetPsuTempForFanSpeed(); GetFanSpeedByFunction(); GetFanSpeed(); ShmSysConfigAndInfo->SysInfo.SystemFanRotaSpeed = _setFanSpeed; gettimeofday(&_priority_time, NULL); ShmFanModuleData->SetFan1Speed = ShmFanModuleData->TestFanSpeed; ShmFanModuleData->SetFan2Speed = ShmFanModuleData->TestFanSpeed; ShmFanModuleData->SetFan3Speed = ShmFanModuleData->TestFanSpeed; ShmFanModuleData->SetFan4Speed = ShmFanModuleData->TestFanSpeed; //log_info("set fan = %d \n", ShmFanModuleData->SetFan1Speed); SetFanModuleSpeed(); } } #endif //NO_FAN_BOARD #if !defined DD360ComBox if (ShmLedModuleData->SelfTest_Comp == YES) { if (GetTimeoutValue(_led_priority_time) / 1000 >= 1000) { if (gunCount == 1) { SetLedColor(_chargingData[0], _chargingData[0]); } else if (gunCount == 2) { SetLedColor(_chargingData[0], _chargingData[1]); } gettimeofday(&_led_priority_time, NULL); } } #endif //defined DD360ComBox usleep(10000); } return FAIL; }