#include "Module_PsuComm.h" #define ARRAY_SIZE(A) (sizeof(A) / sizeof(A[0])) #define PASS 1 #define FAIL -1 #define YES 1 #define NO 0 #define DERATING_COUNT 30 #define DERATING_GAP 30 #define ELEMENT_NOT_FIND 255 #define CHK_VOL_RANGE 50 #define CHK_CUR_RANGE 10 #define DERATING_RANGE 100 #define MIN_1A_CURRENT 10 // 該值須保持最小為 1A #define MIN_5V_VOLTAGE 50 #define STOP_CURRENT 30 #define PSU_MIN_CUR 1000 #define PSU_MIN_VOL 1500 #define PRE_CHARG_STEP_CUR 30 #define PRE_CHARG_RANGE 50 #define EQUAL 0 #define CMD_DELAY_TIME 25000 #define LOG_VOL_GAP 50 #define LOG_CUR_GAP 5 #define PSU_MIN_OUTPUT_CUR 1 #define SHUTDOWN_OUTPUT 0 struct SysConfigAndInfo *ShmSysConfigAndInfo; struct StatusCodeData *ShmStatusCodeData; struct PsuData *ShmPsuData; struct DcCommonInformation *ShmDcCommonData; bool libInitialize = false; byte getAvailableCapOffset = 5; byte deratingKeepCount = 0; byte step3KeepCount = 0; byte psuCmdSeq = _PSU_CMD_CAP; byte startModuleFlag = false; float chargingOutputLogInfo[2][4]; void PRINTF_FUNC(char *string, ...); int StoreLogMsg(const char *fmt, ...); #define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args) #define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args) #define DEBUG_ERROR(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, __FILE__, __LINE__, __FUNCTION__, ##args) int GetTimeoutValue(struct timespec *startTime); long int GetTimeoutMValue(struct timespec *startTime) { struct timespec endTime; clock_gettime(CLOCK_MONOTONIC, &endTime); return 1000 * (endTime.tv_sec - startTime->tv_sec) + (endTime.tv_nsec - startTime->tv_nsec) / 1000000; } void GetTimespecMFunc(struct timespec *time) { clock_gettime(CLOCK_MONOTONIC, time); } int GetTimeoutValue(struct timespec *startTime) { struct timespec endTime; clock_gettime(CLOCK_MONOTONIC_COARSE, &endTime); return endTime.tv_sec - startTime->tv_sec; } void GetTimespecFunc(struct timespec *time) { clock_gettime(CLOCK_MONOTONIC_COARSE, time); } 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_%s", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm, buffer, tm->tm_year+1900,tm->tm_mon+1, ShmSysConfigAndInfo->SysConfig.SerialNumber); system(Buf); } return rc; } void PRINTF_FUNC(char *string, ...) { va_list args; char buffer[4096]; va_start(args, string); vsnprintf(buffer, sizeof(buffer), string, args); va_end(args); DEBUG_INFO("%s ", buffer); } //================================= // Common routine //================================= size_t FindIndex(const int a[], size_t size, int value, byte group) { size_t index = 0; while ( index < size && a[index] != value ) ++index; return (index == size ? ELEMENT_NOT_FIND : group); } byte FindTargetGroup(byte address) { byte _group = ELEMENT_NOT_FIND; if (ShmPsuData->GroupCount == 1) _group = 0; else { _group = FindIndex(ShmDcCommonData->connector[0], ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity, address, 0); if (_group == ELEMENT_NOT_FIND) _group = FindIndex(ShmDcCommonData->connector[1], ShmPsuData->PsuGroup[1].GroupPresentPsuQuantity, address, 1); } return _group; } byte FindRealAddr(byte group, byte address) { byte _addr = 0; byte index = 0; if (group == 0) { while (index < ShmDcCommonData->conn_1_count) { if (ShmDcCommonData->connector[group][index] == address) { _addr = index; break; } ++index; } } else if (group == 1) { while (index < ShmDcCommonData->conn_2_count) { if (ShmDcCommonData->connector [group][index] == address) { _addr = index; break; } ++ index; } } return _addr; } bool IsOverModuleCount(byte count) { bool result = false; if (count >= ShmPsuData->SystemPresentPsuQuantity) result = true; return result; } //================================= // Save data to share memory Function //================================= bool FindChargingInfoData(byte target, struct ChargingInfoData **chargingData) { for (byte index = 0; index < CHAdeMO_QUANTITY; index++) { if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == target) { chargingData[target] = &ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index]; return true; } } for (byte index = 0; index < CCS_QUANTITY; index++) { if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == target) { chargingData[target] = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[index]; return true; } } for (byte index = 0; index < GB_QUANTITY; index++) { if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == target) { chargingData[target] = &ShmSysConfigAndInfo->SysInfo.GbChargingData[index]; return true; } } return false; } //================================= // Alarm code mapping to share memory Function //================================= // 檢查 Byte 中某個 Bit 的值 // _byte : 欲改變的 byte // _bit : 該 byte 的第幾個 bit int mask_table[] = { 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, 0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200, 0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000, 0x00008000, 0x00010000, 0x00020000, 0x00040000, 0x00080000, 0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000 }; #define NONE_DEFINE_1 0 #define NONE_DEFINE_2 1 #define FUSE_BURN_OUT 2 #define PFC_DC_COMM_FAIL 3 #define NONE_DEFINE_3 4 #define NONE_DEFINE_4 5 #define UNBALANCE_POSI_NEGA_BUS_VOL 6 #define BUS_OVER_VOL 7 #define BUS_ABNORMAL_VOL 8 #define PHASE_OVP 9 #define ID_REPETITION 10 #define BUS_UVP 11 #define PHASE_LOSE 12 #define NONE_DEFINE_5 13 #define PHASE_UVP 14 #define NONE_DEFINE_6 15 #define CAN_COMM_FAULT 16 #define DC_DC_UNEVEN_CUR_SHARING 17 #define NONE_DEFINE_7 18 #define PFC_POW_OFF 19 #define NONE_DEFINE_8 20 #define FULL_SPEED_OF_FAN 21 #define DC_DC_POW_OFF 22 #define MODULE_UNDER_POW_LIMIT 23 #define TEMP_POW_LIMIT 24 #define AC_POW_LIMIT 25 #define DC_DC_EEPROM_FAULT 26 #define FAN_FAULT 27 #define DC_DC_SHORT_CIRCUIT 28 #define PFC_EEPROM_FAULT 29 #define DC_DC_OTP 30 #define DC_DC_OVP 31 unsigned char DetectBitValue(int _value, unsigned char _bit) { return ( _value & mask_table[_bit] ) != 0x00; } bool AbnormalStopAnalysis(byte gun_index, int errCode) { bool isErr = false; for(byte count = 0; count < sizeof(mask_table)/sizeof(mask_table[0]); count++) { byte value = DetectBitValue(errCode, count); if (value == 1) { switch(count) { case NONE_DEFINE_1 : {} break; case NONE_DEFINE_2 : {} break; case FUSE_BURN_OUT : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFuseBurnOut == NO) { PRINTF_FUNC("PSU AbnormalStop : FUSE_BURN_OUT \n"); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFuseBurnOut = YES; } } break; case PFC_DC_COMM_FAIL : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPfcAndDcdcCommFault == NO) { PRINTF_FUNC ( "PSU AbnormalStop : PFC_DC_COMM_FAIL \n" ); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPfcAndDcdcCommFault = YES; } } break; case NONE_DEFINE_3 : {} break; case NONE_DEFINE_4 : {} break; case UNBALANCE_POSI_NEGA_BUS_VOL : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusVoltageUnbalance == NO) { PRINTF_FUNC ( "PSU AbnormalStop : UNBALANCE_POSI_NEGA_BUS_VOL \n" ); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusVoltageUnbalance = YES; } } break; case BUS_OVER_VOL : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusOverVoltage == NO) { PRINTF_FUNC ( "PSU AbnormalStop : BUS_OVER_VOL \n" ); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusOverVoltage = YES; } } break; case BUS_ABNORMAL_VOL : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusVoltageAbnormal == NO) { PRINTF_FUNC ( "PSU AbnormalStop : BUS_ABNORMAL_VOL \n" ); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusVoltageAbnormal = YES; } } break; case PHASE_OVP : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DcInputOVP == NO) { PRINTF_FUNC ( "PSU AbnormalStop : PHASE_OVP \n" ); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DcInputOVP = YES; } } break; case ID_REPETITION : { isErr = true; if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuIdRepeat == NO) { PRINTF_FUNC ( "PSU AbnormalStop : ID_REPETITION \n" ); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuIdRepeat = YES; } } break; case BUS_UVP : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusUnderVoltage == NO) { PRINTF_FUNC ( "PSU AbnormalStop : BUS_UVP \n" ); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusUnderVoltage = YES; } } break; case PHASE_LOSE : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputPhaseLoss == NO) { PRINTF_FUNC ( "PSU AbnormalStop : PHASE_LOSE \n" ); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputPhaseLoss = YES; } } break; case NONE_DEFINE_5 : {} break; case PHASE_UVP : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DcInputUVP == NO) { PRINTF_FUNC ( "PSU AbnormalStop : PHASE_UVP \n" ); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DcInputUVP = YES; } } break; case NONE_DEFINE_6 : {} break; case CAN_COMM_FAULT : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCanCommFault == NO) { PRINTF_FUNC ( "PSU AbnormalStop : CAN_COMM_FAULT \n" ); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCanCommFault = YES; } } break; case DC_DC_UNEVEN_CUR_SHARING : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuSevereUnevenCurrent == NO) { PRINTF_FUNC ( "PSU AbnormalStop : DC_DC_UNEVEN_CUR_SHARING \n" ); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuSevereUnevenCurrent = YES; } } break; case NONE_DEFINE_7 : {} break; case PFC_POW_OFF : { //if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPfcPowOff == NO) { //PRINTF_FUNC ( "PSU AbnormalStop : PFC_POW_OFF \n" ); //ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPfcPowOff = YES; } } break; case NONE_DEFINE_8 : {} break; case FULL_SPEED_OF_FAN : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFullSpeed == NO) { PRINTF_FUNC ( "PSU AbnormalStop : FULL_SPEED_OF_FAN \n" ); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFullSpeed = YES; } } break; case DC_DC_POW_OFF : { //if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcDcPowOff == NO) { //PRINTF_FUNC ( "PSU AbnormalStop : DC_DC_POW_OFF \n" ); //ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcDcPowOff = YES; } } break; case MODULE_UNDER_POW_LIMIT : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPowerLimitedState == NO) { PRINTF_FUNC("PSU AbnormalStop : MODULE_UNDER_POW_LIMIT \n"); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPowerLimitedState = YES; } } break; case TEMP_POW_LIMIT : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuTemperaturePowerLimit == NO) { PRINTF_FUNC ( "PSU AbnormalStop : TEMP_POW_LIMIT \n" ); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuTemperaturePowerLimit = YES; } } break; case AC_POW_LIMIT : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuAcPowerLimit == NO) { PRINTF_FUNC ( "PSU AbnormalStop : AC_POW_LIMIT \n" ); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuAcPowerLimit = YES; } } break; case DC_DC_EEPROM_FAULT : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcdcEepromFault == NO) { PRINTF_FUNC ( "PSU AbnormalStop : DC_DC_EEPROM_FAULT \n" ); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcdcEepromFault = YES; } } break; case FAN_FAULT : { isErr = true; if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFailureAlarm == NO) { PRINTF_FUNC ( "PSU AbnormalStop : FAN_FAULT \n" ); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFailureAlarm = YES; } } break; case DC_DC_SHORT_CIRCUIT : { isErr = true; if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuOutputShortCircuit == NO) { PRINTF_FUNC ( "PSU AbnormalStop : DC_DC_SHORT_CIRCUIT \n" ); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuOutputShortCircuit = YES; } } break; case PFC_EEPROM_FAULT : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPfcEepromFault == NO) { PRINTF_FUNC ( "PSU AbnormalStop : PFC_EEPROM_FAULT \n" ); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPfcEepromFault = YES; } } break; case DC_DC_OTP : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcDcOtp == NO) { PRINTF_FUNC ( "PSU AbnormalStop : DC_DC_OTP \n" ); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcDcOtp = YES; } } break; case DC_DC_OVP : { isErr = true; if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcDcOvp == NO) { PRINTF_FUNC ( "PSU AbnormalStop : DC_DC_OVP \n" ); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcDcOvp = YES; } } break; } } else if (value == 0) { switch(count) { case NONE_DEFINE_1 : {} break; case NONE_DEFINE_2 : {} break; case FUSE_BURN_OUT : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFuseBurnOut == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFuseBurnOut = NO; } } break; case PFC_DC_COMM_FAIL : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPfcAndDcdcCommFault == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPfcAndDcdcCommFault = NO; } } break; case NONE_DEFINE_3 : {} break; case NONE_DEFINE_4 : {} break; case UNBALANCE_POSI_NEGA_BUS_VOL : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusVoltageUnbalance == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusVoltageUnbalance = NO; } } break; case BUS_OVER_VOL : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusOverVoltage == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusOverVoltage = NO; } } break; case BUS_ABNORMAL_VOL : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusVoltageAbnormal == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusVoltageAbnormal = NO; } } break; case PHASE_OVP : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DcInputOVP == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DcInputOVP = NO; } } break; case ID_REPETITION : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuIdRepeat == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuIdRepeat = NO; } } break; case BUS_UVP : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusUnderVoltage == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusUnderVoltage = NO; } } break; case PHASE_LOSE : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputPhaseLoss == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputPhaseLoss = NO; } } break; case NONE_DEFINE_5 : {} break; case PHASE_UVP : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DcInputUVP == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DcInputUVP = NO; } } break; case NONE_DEFINE_6 : {} break; case CAN_COMM_FAULT : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCanCommFault == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCanCommFault = NO; } } break; case DC_DC_UNEVEN_CUR_SHARING : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuSevereUnevenCurrent == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuSevereUnevenCurrent = NO; } } break; case NONE_DEFINE_7 : {} break; case PFC_POW_OFF : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFfcSideShutDown == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFfcSideShutDown = NO; } } break; case NONE_DEFINE_8 : {} break; case FULL_SPEED_OF_FAN : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFullSpeed == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFullSpeed = NO; } } break; case DC_DC_POW_OFF : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = NO; } } break; case MODULE_UNDER_POW_LIMIT : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPowerLimitedState == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPowerLimitedState = NO; } } break; case TEMP_POW_LIMIT : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuTemperaturePowerLimit == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuTemperaturePowerLimit = NO; } } break; case AC_POW_LIMIT : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuAcPowerLimit == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuAcPowerLimit = NO; } } break; case DC_DC_EEPROM_FAULT : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcdcEepromFault == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcdcEepromFault = NO; } } break; case FAN_FAULT : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFailureAlarm == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFailureAlarm = NO; } } break; case DC_DC_SHORT_CIRCUIT : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuOutputShortCircuit == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuOutputShortCircuit = NO; } } break; case PFC_EEPROM_FAULT : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPfcEepromFault == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPfcEepromFault = NO; } } break; case DC_DC_OTP : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcDcOtp == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcDcOtp = NO; } } break; case DC_DC_OVP : { if(ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcDcOvp == YES) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcDcOvp = NO; } } break; } } } return isErr; } //================================= // Callback Function //================================= // no using -- GetOutputAndTempCallback void GetStatusCallback(byte group, byte SN, byte temp, int alarm) { bool isFind = false; bool isComp = false; if ((ShmDcCommonData->conn_1_count + ShmDcCommonData->conn_2_count) != ShmPsuData->SystemPresentPsuQuantity) { if (group == 0) { for(byte psuIndex = 0; psuIndex < ShmDcCommonData->conn_1_count; psuIndex++) { if (ShmDcCommonData->connector[0][psuIndex] == SN) { isFind = true; break; } } if(!isFind) { ShmDcCommonData->connector[0][ShmDcCommonData->conn_1_count] = SN; ShmDcCommonData->conn_1_count++; } } else if (group == 1) { for(byte psuIndex = 0; psuIndex < ShmDcCommonData->conn_2_count; psuIndex++) { if (ShmDcCommonData->connector[1][psuIndex] == SN) { isFind = true; break; } } if(!isFind) { ShmDcCommonData->connector[1][ShmDcCommonData->conn_2_count] = SN; ShmDcCommonData->conn_2_count++; } } } else { isComp = true; } if ((ShmDcCommonData->conn_1_count + ShmDcCommonData->conn_2_count) == ShmPsuData->SystemPresentPsuQuantity) { // Arrangment // for(byte psuIndex = 0; psuIndex < ShmDcCommonData->conn_1_count; psuIndex++) // { // ShmDcCommonData->connector[0][psuIndex] = psuIndex; // } // // for(byte psuIndex = 0; psuIndex < ShmDcCommonData->conn_2_count; psuIndex++) // { // ShmDcCommonData->connector[1][psuIndex] = ShmDcCommonData->conn_1_count + psuIndex; // } if (!isComp) { for(byte psuIndex = 0; psuIndex < ShmDcCommonData->conn_1_count; psuIndex++) PRINTF_FUNC("DC Left Gun - PSU Number = %d \n", ShmDcCommonData->connector[0][psuIndex]); for(byte psuIndex = 0; psuIndex < ShmDcCommonData->conn_2_count; psuIndex++) PRINTF_FUNC("DC Right Gun - PSU Number = %d \n", ShmDcCommonData->connector[1][psuIndex]); } if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount > 1 && ShmDcCommonData->chargerType == CHARGER_TYPE_STANDARD) { // 雙槍才需要考慮是否模塊 switch 撥錯了 char EvsePower[2]; byte maxCount = 0; int power = 0; EvsePower[2] = '\0'; if (strlen((char *) ShmSysConfigAndInfo->SysConfig.ModelName) >= 6) { strncpy(EvsePower, (char *)(ShmSysConfigAndInfo->SysConfig.ModelName + 4), 2); power = atoi(EvsePower); } // 超過 90 KW 或 360 KW if (power < 30 || power == 36) power *= 10; maxCount = ((power / 30) + 1) / 2; if (ShmDcCommonData->conn_1_count > maxCount || ShmDcCommonData->conn_2_count > maxCount) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDipSwitchStestFail = YES; } } } } // no using -- GetOutputAndTempCallback End void GetModuleCountCallback(byte group, byte count) { if (group == SYSTEM_CMD) ShmPsuData->SystemPresentPsuQuantity = count; else { if (group >= ShmSysConfigAndInfo->SysConfig.TotalConnectorCount) return; ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity = count; } } void GetMaxPowerAndCur(unsigned char mode, int ratingCur, int *pow, int *cur) { if (ShmPsuData->Work_Step < GET_SYS_CAP) return; unsigned short maxCurrent = ShmPsuData->SystemAvailableCurrent; unsigned short maxPower = ShmPsuData->SystemAvailablePower; if (ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent * 10 != 0 && ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent * 10 < maxCurrent) maxCurrent = ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent * 10; if (ShmSysConfigAndInfo->SysConfig.MaxChargingPower * 10 != 0 && ShmSysConfigAndInfo->SysConfig.MaxChargingPower * 10 < maxPower) maxPower = ShmSysConfigAndInfo->SysConfig.MaxChargingPower * 10; if (mode == _MAIN_CHARGING_MODE_AVER) { maxCurrent /= 2; maxPower /= 2; } if (ShmSysConfigAndInfo->SysInfo.MaxChargingProfilePower >= 0 && maxPower > ShmSysConfigAndInfo->SysInfo.MaxChargingProfilePower) maxPower = ShmSysConfigAndInfo->SysInfo.MaxChargingProfilePower; if (maxPower != 0 && maxPower <= *pow) *pow = maxPower; if (maxCurrent != 0 && maxCurrent <= *cur) *cur = maxCurrent; if (ratingCur != 0 && ratingCur <= *cur) *cur = ratingCur; } void GetAvailableCapCallback(byte address, short maxVol, short minVol, short maxCur, short totalPow) { if (ShmPsuData->Work_Step < GET_SYS_CAP) return; int _groupPower = 0, _groupCurrent = 0; byte group = FindTargetGroup(address); byte addr = FindRealAddr(group, address); float _chargingVol = 0, _targetVol = 0; // if (group == 1) // address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity; if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX) { for (byte groupIndex = 0; groupIndex < _gunCount; groupIndex++) { if (chargingInfo[groupIndex]->EvBatteryMaxVoltage > 0) { _chargingVol = chargingInfo[groupIndex]->EvBatteryMaxVoltage; _targetVol = chargingInfo[groupIndex]->EvBatterytargetVoltage; break; } } } if (chargingInfo[group]->DeratingChargingCurrent == 0) { // 在還沒取得真正可輸出的電流前,依照 GFD 階段得到的真正 POWER / 模塊個數 / 車子電池最大電壓 if (ShmPsuData->PsuGroup[group].GroupRealOutputPower > 0 && _chargingVol > 0) { ShmPsuData->PsuGroup[group].PsuModule[addr].AvailableCurrent = ((ShmPsuData->PsuGroup[group].GroupRealOutputPower / ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity) * 1000 / (int)_chargingVol) * 10; } else { // 注一 : 獲取模塊最大輸出能力 (忽視 Derating 狀態),所以這邊需要限制實際可輸出的電流 if (ShmPsuData->PsuGroup[group].PsuModule[addr].AvailableCurrent <= 0) ShmPsuData->PsuGroup[group].PsuModule[addr].AvailableCurrent = PSU_MIN_CUR; } } else { ShmPsuData->PsuGroup[group].PsuModule[addr].AvailableCurrent = maxCur; } ShmPsuData->PsuGroup[group].PsuModule[addr].AvailablePower = totalPow; // 總和該 Group 的可輸出電流 for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++) { _groupCurrent += ShmPsuData->PsuGroup[group].PsuModule[index].AvailableCurrent; _groupPower += ShmPsuData->PsuGroup[group].PsuModule[index].AvailablePower; } // 各群得到最大輸出能力 (電流、Power) ShmPsuData->PsuGroup[group].GroupAvailableCurrent = _groupCurrent; ShmPsuData->PsuGroup[group].GroupAvailablePower = _groupPower; if (chargingInfo[group]->MaximumChargingVoltage != maxVol) { PRINTF_FUNC("G_%d -> Max Vol = %d \n", group, maxVol / 10); chargingInfo[group]->MaximumChargingVoltage = maxVol; } int _power = 0, _current = 0, _ratingcurrent = 0, _sysRealPower = 0; bool isGetAllDeratingCurrent = true; for (byte index = 0; index < ShmPsuData->GroupCount; index++) { _power += ShmPsuData->PsuGroup[index].GroupAvailablePower; _current += ShmPsuData->PsuGroup[index].GroupAvailableCurrent; _ratingcurrent += chargingInfo[index]->DeratingChargingCurrent; _sysRealPower += ShmPsuData->PsuGroup[index].GroupRealOutputPower; if (ShmPsuData->PsuGroup[index].GroupPresentOutputVoltage >= PSU_MIN_VOL && chargingInfo[index]->DeratingChargingCurrent == 0) isGetAllDeratingCurrent = false; } // 如果不是所有群都得到 Derating current,則先不採樣該次的 ratingCurrent if (!isGetAllDeratingCurrent) _ratingcurrent = 0; // 因應注一,為避免一值改變通知車子電樁最大可輸出電流所做的限制 // 而因為 rating value 一般都會小於模塊的最大可輸出電流 // 所以如果該值大於在注一所限制的輸出電流,則以此值為主 if (_ratingcurrent != 0) _current = _ratingcurrent; if (ShmSysConfigAndInfo->SysInfo.BootingStatus == BOOTTING) { ShmPsuData->SystemAvailableCurrent = _current; ShmPsuData->SystemAvailablePower = _power; } if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER || (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_GET_NEW_CAP && ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A)) { int halfPow = ShmPsuData->PsuGroup[group].GroupAvailablePower; int halfCur = ShmPsuData->PsuGroup[group].GroupAvailableCurrent; int ratingCur = chargingInfo[group]->DeratingChargingCurrent; int gpRealPow = ShmPsuData->PsuGroup[group].GroupRealOutputPower; if ((ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_GET_NEW_CAP && ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A)) { if (chargingInfo[group]->DividChargingCurrent == 0) return; else { halfCur = chargingInfo[group]->DividChargingCurrent; ratingCur = 0; } } GetMaxPowerAndCur(_MAIN_CHARGING_MODE_AVER, ratingCur, &halfPow, &halfCur); { // 以下狀況 -> 槍資訊中的最大輸出能力,為該群的輸出能力 // 1. 如不是最大充 // 2. 智能切換成均充過程 chargingInfo[group]->AvailableChargingCurrent = halfCur; chargingInfo[group]->AvailableChargingPower = halfPow; chargingInfo[group]->RealRatingPower = gpRealPow; if(chargingInfo[group]->DeratingChargingCurrent > 0) { unsigned short _powBuf = 0; _powBuf = ((chargingInfo[group]->DeratingChargingCurrent / 10) * ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage / 10) / 1000; // 單位是 KW if (_powBuf > ShmPsuData->PsuGroup[group].GroupRealOutputPower || chargingInfo[group]->EvBatterytargetVoltage > 0) { ShmPsuData->PsuGroup[group].GroupRealOutputPower = _powBuf; } } } } else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX) { GetMaxPowerAndCur(_MAIN_CHARGING_MODE_MAX, _ratingcurrent, &_power, &_current); if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES) { for (byte count = 0; count < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; count++) { chargingInfo[count]->MaximumChargingVoltage = maxVol; chargingInfo[count]->AvailableChargingCurrent = _current; chargingInfo[count]->AvailableChargingPower = _power; chargingInfo[count]->RealRatingPower = _sysRealPower; } } else { // 如果是最大充,該槍資訊中的輸出能力為各群輸出能力的和 chargingInfo[group]->AvailableChargingCurrent = _current; chargingInfo[group]->AvailableChargingPower = _power; chargingInfo[group]->RealRatingPower = _sysRealPower; } if(chargingInfo[group]->DeratingChargingCurrent > 0) { unsigned short _powBuf = 0; _powBuf = ((chargingInfo[group]->DeratingChargingCurrent / 10) * ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage / 10) / 1000; // 單位是 KW if (_powBuf > ShmPsuData->PsuGroup[group].GroupRealOutputPower || chargingInfo[group]->EvBatterytargetVoltage > 0 || _targetVol > 0) { ShmPsuData->PsuGroup[group].GroupRealOutputPower = _powBuf; } } } } void GetFwCallback(byte address, short dcSwVer, short pfcSwVer, short hwVer) { if (ShmPsuData->Work_Step < GET_SYS_CAP) return; if (IsOverModuleCount(address)) return; byte group = FindTargetGroup(address); byte addr = FindRealAddr(group, 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) // address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity; sprintf((char *)ShmPsuData->PsuGroup[group].PsuModule[addr].FwVersion, "DC %d.%02d", (dcSwVer & 0xFF00) >> 8, dcSwVer & 0xFF); //DEBUG_INFO("fw Ver. = %s \n", ShmPsuData->PsuGroup[group].PsuModule[address].FwVersion); } // no using -- GetInputVoltageCallback void GetInputVoltageCallback(byte address, unsigned short vol1, unsigned short vol2, unsigned short vol3) { // if (ShmPsuData->Work_Step < GET_SYS_CAP) // return; // // if (IsOverModuleCount(address)) // return; // // byte group = FindTargetGroup(address); // // if (group == 1) // address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity; // // ShmPsuData->PsuGroup[group].PsuModule[address].InputVoltageL1 = vol1; // ShmPsuData->PsuGroup[group].PsuModule[address].InputVoltageL2 = vol2; // ShmPsuData->PsuGroup[group].PsuModule[address].InputVoltageL3 = vol3; // // PRINTF_FUNC("***Input*** address = %d, R = %d, S = %d, T = %d, gp = %d \n", // address, vol1, vol2, vol3, group); } // no using -- GetInputVoltageCallback End // no using -- GetOutputAndTempCallback void GetPresentOutputCallback(byte group, unsigned short outVol, unsigned short outCur) { // if (ShmPsuData->Work_Step < GET_SYS_CAP) // return; //if (outCur != ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent) //{ // PRINTF_FUNC("Gp_%d, gp output cur = %d \n", group, outCur); //} // // PSU Group - 電壓 // ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage = outVol; // // PSU Group - 電流 // ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent = outCur; // // 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)) // ) // { // unsigned short outputVol = 0; // unsigned short outputCur = 0; // // for (byte index = 0; index < ShmPsuData->GroupCount; index++) // { // bool needtoAdd = true; // // if (ShmPsuData->PsuGroup[index].GroupPresentOutputVoltage > outputVol) // outputVol = ShmPsuData->PsuGroup[index].GroupPresentOutputVoltage; // // if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_ADJUST_M_TO_A && // ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A) // { //// PRINTF_FUNC("Gp_%d, DividChargingCurrent = %d \n", index, //// chargingInfo[index]->DividChargingCurrent); // if (chargingInfo[index]->DividChargingCurrent == 0) // needtoAdd = false; // } // // if (needtoAdd) // outputCur += ShmPsuData->PsuGroup[index].GroupPresentOutputCurrent; // } // // // 黑白機 // if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES) // { // for (byte count = 0; count < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; count++) // { // float _vol_buf = outputVol; // float _cur_buf = outputCur; // // // EVSE - 電壓 // _vol_buf /= 10; // chargingInfo[count]->PresentChargingVoltage = _vol_buf; // // EVSE - 電流 // _cur_buf /= 10; // chargingInfo[count]->PresentChargingCurrent = _cur_buf; // } // } // // if ((chargingInfo[group]->SystemStatus >= SYS_MODE_PREPARE_FOR_EVSE && chargingInfo[group]->SystemStatus <= SYS_MODE_COMPLETE) || // (chargingInfo[group]->SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0 && chargingInfo[group]->SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1)) // { // float _vol_buf = outputVol; // float _cur_buf = outputCur; // // // EVSE - 電壓 // _vol_buf /= 10; // chargingInfo[group]->PresentChargingVoltage = _vol_buf; // // EVSE - 電流 // _cur_buf /= 10; // chargingInfo[group]->PresentChargingCurrent = _cur_buf; // } // } // else // { // float _vol_buf = ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage; // float _cur_buf = ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent; // // // EVSE - 電壓 // _vol_buf /= 10; // chargingInfo[group]->PresentChargingVoltage = _vol_buf; // // EVSE - 電流 // _cur_buf /= 10; // chargingInfo[group]->PresentChargingCurrent = _cur_buf; // } // // PRINTF_FUNC("Gun_%d, PresentChargingVoltage = %f, PresentChargingCurrent = %f \n", group, // chargingInfo[group]->PresentChargingVoltage, // chargingInfo[group]->PresentChargingCurrent); } // no using -- GetOutputAndTempCallback End void GetMisCallback(byte address, unsigned int value, byte type) { if (ShmPsuData->Work_Step < GET_SYS_CAP) return; if (IsOverModuleCount(address)) return; byte group = FindTargetGroup(address); byte addr = FindRealAddr(group, address); // if (group == 1) // address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity; if (type == 1) { ShmPsuData->PsuGroup[group].PsuModule[addr].FanSpeed_1 = value; ShmPsuData->PsuGroup[group].PsuModule[addr].FanSpeed_2 = value; ShmPsuData->PsuGroup[group].PsuModule[addr].FanSpeed_3 = value; ShmPsuData->PsuGroup[group].PsuModule[addr].FanSpeed_4 = value; } else if (type == 2) { //printf("DC - group = %d, index = %d, value = %d \n", group, address, value); // ShmPsuData->PsuGroup[group].PsuModule[addr].CriticalTemp1 = value; // ShmPsuData->PsuGroup[group].PsuModule[addr].CriticalTemp2 = value; // ShmPsuData->PsuGroup[group].PsuModule[addr].CriticalTemp3 = value; ShmPsuData->PsuGroup[group].PsuModule[addr].ExletTemp = value; } else if (type == 3) { printf("PFC - group = %d, index = %d, value = %d \n", group, address, value); } } void GetIavailableCallback(byte address, unsigned short Iavail, unsigned short Vext) { if (ShmPsuData->Work_Step < GET_SYS_CAP) return; if (IsOverModuleCount(address)) return; // 經度 0.1 byte group = FindTargetGroup(address); byte addr = FindRealAddr(group, address); // if (group == 1) // address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity; ShmPsuData->PsuGroup[group].PsuModule[addr].IAvailableCurrent = Iavail; bool isPass = true; int totalCur = 0; byte sampleCount = 8; if (Iavail == 0) { for (byte count = 0; count < sampleCount; count++) { chargingInfo[group]->SampleChargingCur[count] = Iavail; } } else { // 該群的可輸出電流 for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++) { totalCur += ShmPsuData->PsuGroup[group].PsuModule[index].IAvailableCurrent; } for (byte count = 0; count < sampleCount; count++) { if (chargingInfo[group]->SampleChargingCur[count] == 0) { chargingInfo[group]->SampleChargingCur[count] = totalCur; return; } else { if (chargingInfo[group]->SampleChargingCur[count] != totalCur) { chargingInfo[group]->SampleChargingCur[count] = totalCur; isPass = false; break; } } } } if (isPass) { chargingInfo[group]->DeratingChargingCurrent = totalCur; } } void GetPresentOutputFCallback(byte group, float outVol, float outCur) { // isinf : -1 = 負無窮,1 = 正無窮,0 = 其他 if (isinf(outVol) == 0) ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage = (unsigned short)(outVol * 10); else ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage = 0; if (isinf(outCur) == 0) ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent = (unsigned short)(outCur * 10); else ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent = 0; //printf("group = %d, Current = %d \n", group, ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent); 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)) ) { unsigned short outputVol = 0; unsigned short outputCur = 0; unsigned char _maxTOaver = 0; for (byte index = 0; index < ShmPsuData->GroupCount; index++) { bool needtoAdd = true; if (ShmPsuData->PsuGroup[index].GroupPresentOutputVoltage > outputVol) outputVol = ShmPsuData->PsuGroup[index].GroupPresentOutputVoltage; if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_ADJUST_M_TO_A && ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A) { if (chargingInfo[index]->DividChargingCurrent == 0) needtoAdd = false; else _maxTOaver = index; } if (needtoAdd) outputCur += ShmPsuData->PsuGroup[index].GroupPresentOutputCurrent; } if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_ADJUST_M_TO_A && ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A) { if (chargingInfo[_maxTOaver]->DividChargingCurrent != 0) { float _cur_buf = outputCur; _cur_buf /= 10; chargingInfo[_maxTOaver]->PresentChargingCurrent = _cur_buf; } } // 黑白機 if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES) { for (byte count = 0; count < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; count++) { float _vol_buf = outputVol; float _cur_buf = outputCur; // EVSE - 電壓 _vol_buf /= 10; chargingInfo[count]->PresentChargingVoltage = _vol_buf; _cur_buf /= 10; chargingInfo[count]->PresentChargingCurrent = _cur_buf; } } if ((chargingInfo[group]->SystemStatus >= SYS_MODE_PREPARE_FOR_EVSE && chargingInfo[group]->SystemStatus <= SYS_MODE_COMPLETE) || (chargingInfo[group]->SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0 && chargingInfo[group]->SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1) || chargingInfo[group]->SystemStatus == SYS_MODE_ALARM) { float _vol_buf = outputVol; float _cur_buf = outputCur; // EVSE - 電壓 _vol_buf /= 10; chargingInfo[group]->PresentChargingVoltage = _vol_buf; if (chargingInfo[group]->SystemStatus == SYS_MODE_COMPLETE || chargingInfo[group]->SystemStatus == SYS_MODE_ALARM) { chargingInfo[group]->PresentChargingCurrent = 0; } else { _cur_buf /= 10; chargingInfo[group]->PresentChargingCurrent = _cur_buf; } } } else { float _vol_buf = ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage; float _cur_buf = ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent; // EVSE - 電壓 _vol_buf /= 10; chargingInfo[group]->PresentChargingVoltage = _vol_buf; _cur_buf /= 10; chargingInfo[group]->PresentChargingCurrent = _cur_buf; } } //========================================== // 特規用指令 //========================================== void GetOutputAndTempCallback(byte address, unsigned short outputVol_s, unsigned short outputCur_s, unsigned short outputPower, unsigned char Temperature) { if (ShmPsuData->Work_Step < GET_SYS_CAP) return; if (IsOverModuleCount(address)) return; byte group = FindTargetGroup(address); byte addr = FindRealAddr(group, address); // if (group == 1) // address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity; ShmPsuData->PsuGroup[group].PsuModule[addr].CriticalTemp1 = Temperature; ShmPsuData->PsuGroup[group].PsuModule[addr].CriticalTemp2 = Temperature; ShmPsuData->PsuGroup[group].PsuModule[addr].CriticalTemp3 = Temperature; // ShmPsuData->PsuGroup[group].PsuModule[address].ExletTemp = Temperature; // PRINTF_FUNC("***Output Value and Temp*** group = %d, Vol = %d, Cur = %d \n", // group, outputVol_s, outputCur_s); } void GetModuleStatusCallback(byte address, unsigned char isErr, unsigned char status, unsigned char err1, unsigned char err2, unsigned char err3, unsigned char err4) { ShmDcCommonData->psuKeepCommunication = ShmDcCommonData->acContactSwitch; int _timebuf = GetTimeoutValue(&ShmDcCommonData->_psuComm_time); if (_timebuf > 1 || _timebuf < 0) { GetTimespecFunc(&ShmDcCommonData->_psuComm_time); } if (ShmPsuData->Work_Step < GET_SYS_CAP) return; if (IsOverModuleCount(address)) return; byte group1 = FindTargetGroup(address); byte addr = FindRealAddr(group1, address); int alarm = err1 | (err2 << 8) | (err3 << 16) | (err4 << 24); ShmPsuData->PsuGroup[group1].PsuModule[addr].AlarmCode = alarm; if(AbnormalStopAnalysis(group1, alarm)) { if (!ShmPsuData->PsuGroup[group1].GroupErrorFlag.bits.PsuFailure) { ShmPsuData->PsuGroup[group1].GroupErrorFlag.bits.PsuFailure = YES; ShmPsuData->PsuStopChargeFlag = YES; ShmDcCommonData->_isPsuErrorOccur = YES; PRINTF_FUNC("Group_%d - Address_%d, PSU Error Occurred. \n", group1, addr); } } } void GetModuleInputCallback(byte address, unsigned short inputR, unsigned short inputS, unsigned short inputT) { if (ShmPsuData->Work_Step < GET_SYS_CAP) return; if (IsOverModuleCount(address)) return; byte group = FindTargetGroup(address); byte addr = FindRealAddr(group, address); // if (group == 1) // address -= ShmPsuData->PsuGroup[group - 1].GroupPresentPsuQuantity; ShmPsuData->PsuGroup[group].PsuModule[addr].InputVoltageL1 = inputR; ShmPsuData->PsuGroup[group].PsuModule[addr].InputVoltageL2 = inputS; ShmPsuData->PsuGroup[group].PsuModule[addr].InputVoltageL3 = inputT; //PRINTF_FUNC("***Input*** address = %d, R = %d, S = %d, T = %d \n", // address, inputR, inputS, inputT); } //========================================== // Init all share memory //========================================== int InitShareMemory() { int result = PASS; int MeterSMId; //creat ShmSysConfigAndInfo if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), 0777)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR("shmget ShmSysConfigAndInfo NG %d \n"); #endif result = FAIL; } else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR("shmat ShmSysConfigAndInfo NG \n"); #endif result = FAIL; } //creat ShmStatusCodeData if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), 0777)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR("shmget ShmStatusCodeData NG \n"); #endif result = FAIL; } else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR("shmat ShmStatusCodeData NG \n"); #endif result = FAIL; } //creat ShmPsuData if ((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData), 0777)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR("shmget ShmPsuData NG \n"); #endif result = FAIL; } else if ((ShmPsuData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR("shmat ShmPsuData NG \n"); #endif result = FAIL; } if ((MeterSMId = shmget(ShmCommonKey, sizeof(struct DcCommonInformation), IPC_CREAT | 0777)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR("shmget ShmCommonKey NG \n"); #endif result = FAIL; } else if ((ShmDcCommonData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR("shmat ShmCommonKey NG \n"); #endif result = FAIL; } return result; } //================================================ // Log function //================================================ void OutputChargingLogFuncion(byte groupIndex) { // 列印時機 : 需求改變或輸出電壓與紀錄落差超過 5V 或者輸出電流與紀錄落差超過 0.5A if (chargingOutputLogInfo[groupIndex][_CHARGING_LOG_NEED_VOL] != chargingInfo[groupIndex]->EvBatterytargetVoltage * 10 || (chargingInfo[groupIndex]->FireChargingVoltage <= chargingOutputLogInfo[groupIndex][_CHARGING_LOG_OUTPUT_VOL] - LOG_VOL_GAP || chargingInfo[groupIndex]->FireChargingVoltage >= chargingOutputLogInfo[groupIndex][_CHARGING_LOG_OUTPUT_VOL] + LOG_VOL_GAP)) { chargingOutputLogInfo[groupIndex][_CHARGING_LOG_NEED_VOL] = chargingInfo[groupIndex]->EvBatterytargetVoltage * 10; chargingOutputLogInfo[groupIndex][_CHARGING_LOG_OUTPUT_VOL] = chargingInfo[groupIndex]->FireChargingVoltage; PRINTF_FUNC("Conn %d, EV Req Voltage : %.1f, EVSE Output Voltage = %.1f \n", groupIndex, chargingOutputLogInfo[groupIndex][_CHARGING_LOG_NEED_VOL] / 10, chargingOutputLogInfo[groupIndex][_CHARGING_LOG_OUTPUT_VOL] / 10); } if (chargingOutputLogInfo[groupIndex][_CHARGING_LOG_NEED_CUR] != chargingInfo[groupIndex]->EvBatterytargetCurrent * 10 || (chargingInfo[groupIndex]->PresentChargingCurrent <= chargingOutputLogInfo[groupIndex][_CHARGING_LOG_OUTPUT_CUR] - LOG_CUR_GAP || chargingInfo[groupIndex]->PresentChargingCurrent >= chargingOutputLogInfo[groupIndex][_CHARGING_LOG_OUTPUT_CUR] + LOG_CUR_GAP)) { chargingOutputLogInfo[groupIndex][_CHARGING_LOG_NEED_CUR] = chargingInfo[groupIndex]->EvBatterytargetCurrent * 10; chargingOutputLogInfo[groupIndex][_CHARGING_LOG_OUTPUT_CUR] = chargingInfo[groupIndex]->PresentChargingCurrent; PRINTF_FUNC("Conn %d, EV Req Current : %.1f, EVSE Output Current = %.1f \n", groupIndex, chargingOutputLogInfo[groupIndex][_CHARGING_LOG_NEED_CUR] / 10, chargingOutputLogInfo[groupIndex][_CHARGING_LOG_OUTPUT_CUR]); } } //================================================ // Main process //================================================ void InitialPsuData() { ShmPsuData->SystemPresentPsuQuantity = 0; PRINTF_FUNC("InitialPsuData : PSU Group = %d \n", ShmPsuData->GroupCount); for (byte _groupCount = 0; _groupCount < ShmPsuData->GroupCount; _groupCount++) { ShmPsuData->PsuGroup[_groupCount].GroupAvailablePower = 0; ShmPsuData->PsuGroup[_groupCount].GroupAvailableCurrent = 0; chargingInfo[_groupCount]->PresentChargingVoltage = 0; chargingInfo[_groupCount]->PresentChargingCurrent = 0; ShmPsuData->PsuGroup[_groupCount].GroupErrorFlag.bits.PsuFailure = NO; } ShmPsuData->PsuStopChargeFlag = NO; ShmDcCommonData->_isPsuErrorOccur = NO; } void Initialization() { bool isPass = false; while(!isPass) { isPass = true; for (byte _index = 0; _index < _gunCount; _index++) { if (!FindChargingInfoData(_index, &chargingInfo[0])) { DEBUG_ERROR("Module_PsuComm : FindChargingInfoData false \n"); isPass = false; break; } } sleep(1); } if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES) ShmPsuData->GroupCount = 1; else ShmPsuData->GroupCount = _gunCount; ShmPsuData->SystemAvailableCurrent = 0; ShmPsuData->SystemAvailablePower = 0; GetTimespecFunc(&ShmDcCommonData->_psuComm_time); } void CheckSmartChargingStep(byte chargingStatus) { // 跑切換均充的邏輯 if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX) { // 確認 A 槍是否已經進入充電階段 if (chargingStatus == _CHARGING_GUN_STATUS_CHARGING) { if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_PREPARE_M_TO_A) { PRINTF_FUNC("======= Max -> Aver : Update new charging capacity. (Step 2) ======= \n"); ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_GET_NEW_CAP; } } else if (chargingStatus == _CHARGING_GUN_STATUS_STOP) { if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag != _REASSIGNED_NONE) { PRINTF_FUNC("============= Max -> Aver : Charging mode = MAX. (Step 0) ============= \n"); ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE; } } } // 跑切換最大充邏輯 else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER) { if (chargingStatus == _CHARGING_GUN_STATUS_CHARGING) { if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_PREPARE_A_TO_M) { PRINTF_FUNC("======= Aver -> Max : switch on the psu voltage. (Step 12) ======= \n"); preChargingCur = preChargingTarget = 0; GetTimespecMFunc(&_max_time); ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_ADJUST_A_TO_M; } } else if (chargingStatus == _CHARGING_GUN_STATUS_STOP && ShmSysConfigAndInfo->SysInfo.ReAssignedFlag != _REASSIGNED_COMP) { PRINTF_FUNC("======= Aver -> Max : Charging mode = MAX. (Step 15) ======= \n"); ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_COMP; } } // if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_PREPARE_M_TO_A) // { // if (isWaitingAver) // { // if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX) // { // ShmSysConfigAndInfo->SysInfo.CanAverageCharging = canAverageCharging; // // if (canAverageCharging) // { // PRINTF_FUNC("======= Only to get the charging side capacity (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 // { // PRINTF_FUNC("=============Smart Charging Aver mode : _REASSIGNED_NONE============= Step 0 \n"); // ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE; // } // } // } // else if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_PREPARE_A_TO_M) // { // if (isCharging) // { // if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER) // { // PRINTF_FUNC("======= To raise voltage of idle module to charging voltage (Step 12) ======= \n"); // preChargingCur = preChargingTarget = 0; // gettimeofday(&_max_time, NULL); // ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_ADJUST_A_TO_M; // } // else // { // PRINTF_FUNC("======= The Change to maximum charge mode is complete. (Step 15) ======= \n"); // ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_COMP; // } // } // else // { // PRINTF_FUNC("======= The Change to maximum charge mode is complete. (Step 15) ======= \n"); // ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_COMP; // } // } } void PreCheckSmartChargingStep() { _maxChargingStatus = _CHARGING_GUN_STATUS_NONE; isReadyToCharging = false; for (byte index = 0; index < ShmPsuData->GroupCount; index++) { if ((chargingInfo[index]->SystemStatus >= SYS_MODE_PREPARE_FOR_EVSE && chargingInfo[index]->SystemStatus <= SYS_MODE_CHARGING) || (chargingInfo[index]->SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0 && chargingInfo[index]->SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1)) { isReadyToCharging = true; } } for (byte index = 0; index < ShmPsuData->GroupCount; index++) { if ((chargingInfo[index]->SystemStatus >= SYS_MODE_PREPARE_FOR_EVSE && chargingInfo[index]->SystemStatus < SYS_MODE_CHARGING) || (chargingInfo[index]->SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0 && chargingInfo[index]->SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1)) { _maxChargingStatus = _CHARGING_GUN_STATUS_COMM; } else if (chargingInfo[index]->SystemStatus == SYS_MODE_CHARGING) { _maxChargingStatus = _CHARGING_GUN_STATUS_CHARGING; break; } else if (chargingInfo[index]->SystemStatus == SYS_MODE_COMPLETE || chargingInfo[index]->SystemStatus == SYS_MODE_ALARM) { _maxChargingStatus = _CHARGING_GUN_STATUS_STOP; } } CheckSmartChargingStep(_maxChargingStatus); } void Await() { usleep(CMD_DELAY_TIME); } bool MaxToAverChargingProc(byte groupIndex) { // 智能判斷 Start ----------------------------------------------------------- if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_GET_NEW_CAP && ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A) { if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_GET_NEW_CAP) { if (chargingInfo[groupIndex]->DividChargingCurrent == 0) { chargingInfo[groupIndex]->DividChargingCurrent = ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent; PRINTF_FUNC("Index = %d, DividChargingCurrent = %.1f \n", groupIndex, chargingInfo[groupIndex]->DividChargingCurrent); } // 車端要求電流為該充電槍的額定輸出電流的範圍內 if ((chargingInfo[groupIndex]->EvBatterytargetCurrent * 10) <= ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent + DERATING_GAP || deratingKeepCount >= DERATING_COUNT) { // 車端降載完成 PRINTF_FUNC("Index = %d, newEvCurrent = %f \n", groupIndex, (chargingInfo[groupIndex]->EvBatterytargetCurrent * 10)); PRINTF_FUNC("======= Max -> Aver : wait the target current is down. (Step 3) ======= \n"); ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_ADJUST_M_TO_A; GetTimespecMFunc(&_derating_time); deratingKeepCount = 0; step3KeepCount = 0; } else { deratingKeepCount++; if (deratingKeepCount % 3 == 0) { PRINTF_FUNC("Max To Ava mode (2) : Index = %d, EvBatterytargetCurrent = %f, TargetCurrent = %d, Count = %d \n", groupIndex, (chargingInfo[groupIndex]->EvBatterytargetCurrent * 10), (ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent + DERATING_GAP), deratingKeepCount); } } } else if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_ADJUST_M_TO_A) { bool isChanged = false; if (chargingInfo[groupIndex]->DividChargingCurrent == 0 || (chargingInfo[groupIndex]->DividChargingCurrent != 0 && (chargingInfo[groupIndex]->DividChargingCurrent == chargingInfo[groupIndex]->AvailableChargingCurrent) && chargingInfo[groupIndex]->AvailableChargingCurrent >= (chargingInfo[groupIndex]->EvBatterytargetCurrent * 10))) { for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++) { if (chargingInfo[subIndex]->SystemStatus == SYS_MODE_REASSIGN) { // 當 B 模塊輸出電流小於 5A 及退開 relay if ((ShmPsuData->PsuGroup[subIndex].GroupPresentOutputCurrent) <= 50) isChanged = true; break; } } } else if (chargingInfo[groupIndex]->PresentChargingCurrent == 0) { for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++) { if (chargingInfo[subIndex]->SystemStatus == SYS_MODE_REASSIGN) { if ((ShmPsuData->PsuGroup[subIndex].GroupPresentOutputCurrent) <= CHK_CUR_RANGE) isChanged = true; break; } } } if (!isChanged) { if (step3KeepCount < DERATING_COUNT) step3KeepCount++; else isChanged = true; } if (isChanged) { PRINTF_FUNC("Max To Ava mode (3-2) : Gun_%d, PresentChargingCurrent = %f, GroupPresentOutputCurrent = %d \n", groupIndex, (chargingInfo[groupIndex]->PresentChargingCurrent * 10), ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent); // 輸出端與車端要求電流接近 PRINTF_FUNC("======= Max -> Aver : off the Parallel relay. (Step 4) ======= \n"); ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_RELAY_M_TO_A; } else { int _t = GetTimeoutMValue(&_derating_time); if (_t > 1000 || _t < 0) { PRINTF_FUNC("Max To Ava mode (3-1) : Gun_%d, AvailableChargingCurrent = %f, EvBatterytargetCurrent = %f, step3KeepCount = %d \n", groupIndex, chargingInfo[groupIndex]->AvailableChargingCurrent, (chargingInfo[groupIndex]->EvBatterytargetCurrent * 10), step3KeepCount); PRINTF_FUNC("Max To Ava mode (3-1) : Gun_%d, PresentChargingCurrent = %f, GroupPresentOutputCurrent = %d, GroupCount = %d \n", groupIndex, (chargingInfo[groupIndex]->PresentChargingCurrent * 10), ShmPsuData->PsuGroup[groupIndex].GroupPresentOutputCurrent, ShmPsuData->GroupCount); GetTimespecMFunc(&_derating_time); } } } } else { chargingInfo[groupIndex]->DividChargingCurrent = 0; chargingInfo[groupIndex]->MaxChargingToAverPassFlag = 0; } // 調整輸出電流 : 漸進調整方式 if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_GET_NEW_CAP && ShmSysConfigAndInfo->SysInfo.ReAssignedFlag < _REASSIGNED_RELAY_M_TO_A) { if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_ADJUST_M_TO_A) { // 當前充電中的目標電壓 float targetVol = (chargingInfo[groupIndex]->EvBatterytargetVoltage * 10); byte reassignIndex = ELEMENT_NOT_FIND; // 找到等待分配的槍 for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++) { if (chargingInfo[subIndex]->SystemStatus == SYS_MODE_REASSIGN) { reassignIndex = subIndex; break; } } if (reassignIndex != ELEMENT_NOT_FIND) { if (GetTimeoutMValue(&_derating_time) <= 150 || chargingInfo[groupIndex]->MaxChargingToAverPassFlag == 0) { chargingInfo[groupIndex]->MaxChargingToAverPassFlag = 1; if(chargingInfo[groupIndex]->EvBatterytargetCurrent <= PSU_MIN_OUTPUT_CUR) chargingInfo[groupIndex]->EvBatterytargetCurrent = PSU_MIN_OUTPUT_CUR; PresentOutputVol(groupIndex, targetVol, (chargingInfo[groupIndex]->EvBatterytargetCurrent * 10)); Await(); PresentOutputVol(reassignIndex, targetVol, CHK_CUR_RANGE); Await(); } } } if ((chargingInfo[groupIndex]->EvBatterytargetVoltage * 10) == 0) { bool isNeedToClosePower = false; for (byte index = 0; index < ShmPsuData->GroupCount; index++) { if (isStartOutputSwitch[index]) { isNeedToClosePower = true; } isStartOutputSwitch[index] = false; } if (isNeedToClosePower) { SwitchPower(SYSTEM_CMD, PSU_POWER_OFF); FlashLed(SYSTEM_CMD, PSU_FLASH_NORMAL); } } } else if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_RELAY_M_TO_A) { //PRINTF_FUNC("set out (%d) value = %f******** 3 \n", groupIndex, chargingInfo[groupIndex]->EvBatterytargetCurrent); if(chargingInfo[groupIndex]->EvBatterytargetCurrent <= PSU_MIN_OUTPUT_CUR) chargingInfo[groupIndex]->EvBatterytargetCurrent = PSU_MIN_OUTPUT_CUR; PresentOutputVol(groupIndex, (chargingInfo[groupIndex]->EvBatterytargetVoltage * 10), (chargingInfo[groupIndex]->EvBatterytargetCurrent * 10)); Await(); } else { return false; } return true; } bool AverToMaxChargingProc(byte groupIndex) { if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_ADJUST_A_TO_M) { byte reassignIndex = ELEMENT_NOT_FIND; for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++) { if (chargingInfo[subIndex]->SystemStatus == SYS_MODE_IDLE || chargingInfo[subIndex]->SystemStatus == SYS_MODE_RESERVATION || chargingInfo[subIndex]->SystemStatus == SYS_MODE_FAULT || chargingInfo[subIndex]->SystemStatus == SYS_MODE_MODE_REASSIGN_CHECK || chargingInfo[subIndex]->SystemStatus == SYS_MODE_COMPLETE || chargingInfo[subIndex]->SystemStatus == SYS_MODE_ALARM) { reassignIndex = subIndex; if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_WAITING) { preChargingCur = ShmPsuData->PsuGroup[subIndex].GroupPresentOutputCurrent; } else preChargingCur = 0; } else { if ((ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_WAITING) && (preChargingCur >= preChargingTarget - MIN_1A_CURRENT)) preChargingTarget += PRE_CHARG_STEP_CUR; if (preChargingTarget >= (chargingInfo[subIndex]->EvBatterytargetCurrent * 10) / 2) preChargingTarget = (chargingInfo[subIndex]->EvBatterytargetCurrent * 10) / 2; } } if (reassignIndex != ELEMENT_NOT_FIND) { if (GetTimeoutMValue(&_max_time) <= 150) { //PRINTF_FUNC("set out (%d) value = %d******** 5 \n", reassignIndex, MIN_1A_CURRENT + preChargingTarget); // 閒置模塊升壓,另對剛分配近來的模塊,預上升電流值 (preChargingCur) PresentOutputVol(reassignIndex, (chargingInfo[groupIndex]->EvBatterytargetVoltage * 10), MIN_1A_CURRENT + preChargingTarget); Await(); } byte _ovCahrgingCur = 0; if (preChargingCur > PRE_CHARG_STEP_CUR) _ovCahrgingCur = PRE_CHARG_STEP_CUR; PresentOutputVol(groupIndex, (chargingInfo[groupIndex]->EvBatterytargetVoltage * 10), (chargingInfo[groupIndex]->EvBatterytargetCurrent * 10) - preChargingCur - _ovCahrgingCur); Await(); } if ((chargingInfo[groupIndex]->EvBatterytargetVoltage * 10) == 0) { bool isNeedToClosePower = false; for (byte index = 0; index < ShmPsuData->GroupCount; index++) { if (isStartOutputSwitch[index]) { isNeedToClosePower = true; } isStartOutputSwitch[index] = false; } if (isNeedToClosePower) { SwitchPower(SYSTEM_CMD, PSU_POWER_OFF); FlashLed(SYSTEM_CMD, PSU_FLASH_NORMAL); } } else { bool isNeedToOpenPower = false; for (byte index = 0; index < ShmPsuData->GroupCount; index++) { if (!isStartOutputSwitch[index]) { isNeedToOpenPower = true; } isStartOutputSwitch[index] = true; } if (isNeedToOpenPower) { SwitchPower(SYSTEM_CMD, PSU_POWER_ON); FlashLed(SYSTEM_CMD, PSU_FLASH_ON); } } if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_ADJUST_A_TO_M) { bool balanceVol = true; byte subIndex; for (subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++) { if (chargingInfo[subIndex]->SystemStatus == SYS_MODE_IDLE || chargingInfo[subIndex]->SystemStatus == SYS_MODE_FAULT || chargingInfo[subIndex]->SystemStatus == SYS_MODE_RESERVATION || chargingInfo[subIndex]->SystemStatus == SYS_MODE_COMPLETE || chargingInfo[subIndex]->SystemStatus == SYS_MODE_ALARM) { // 各群電壓接近平衡 if (((chargingInfo[subIndex]->PresentChargingVoltage * 10) < (chargingInfo[groupIndex]->PresentChargingVoltage * 10) - MIN_5V_VOLTAGE) || ((chargingInfo[subIndex]->PresentChargingVoltage * 10) < (chargingInfo[groupIndex]->EvBatterytargetVoltage * 10) - CHK_VOL_RANGE)) { balanceVol = false; } break; } } if (balanceVol) { // 閒置端與車端要求電壓接近 PRINTF_FUNC("======= Aver -> Max : switch on the Parallel relay. (Step 13) ======= \n"); ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_RELAY_A_TO_M; } else { int _tMax_1 = GetTimeoutMValue(&_max_time); if (_tMax_1 > 500 || _tMax_1 < 0) { PRINTF_FUNC("Ava To Max mode (12) : Gun_%d, PresentChargingVoltage = %f, PresentChargingVoltage_V = %f, EvBatterytargetVoltage = %f \n", subIndex, (chargingInfo[subIndex]->PresentChargingVoltage * 10), ((chargingInfo[groupIndex]->PresentChargingVoltage * 10) - MIN_5V_VOLTAGE), ((chargingInfo[groupIndex]->EvBatterytargetVoltage * 10) - CHK_VOL_RANGE)); GetTimespecMFunc(&_max_time); } } } else if(ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_WAITING) { int idleCurrent = 0; int chargingCurrent = 0; for (byte subIndex = 0; subIndex < ShmPsuData->GroupCount; subIndex++) { if (chargingInfo[subIndex]->SystemStatus == SYS_MODE_IDLE || chargingInfo[subIndex]->SystemStatus == SYS_MODE_RESERVATION || chargingInfo[subIndex]->SystemStatus == SYS_MODE_FAULT || chargingInfo[subIndex]->SystemStatus == SYS_MODE_MODE_REASSIGN_CHECK) idleCurrent = ShmPsuData->PsuGroup[subIndex].GroupPresentOutputCurrent; else { chargingCurrent = ShmPsuData->PsuGroup[subIndex].GroupPresentOutputCurrent; } } if (idleCurrent >= chargingCurrent - PRE_CHARG_RANGE) { PRINTF_FUNC("======= Aver -> Max : Charging mode = MAX. (Step 15) ======= \n"); ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_COMP; } else { int _tMax_2 = GetTimeoutMValue(&_max_time); if (_tMax_2 > 300 || _tMax_2 < 0) { GetTimespecMFunc(&_max_time); } } } } else { return false; } return true; } void SwitchOffPowerCheck(byte groupIndex) { _maxChargingStatus = _CHARGING_GUN_STATUS_STOP; for (byte index = 0; index < ShmPsuData->GroupCount; index++) { // 判斷另一把槍的狀態 if (index != groupIndex) { if ((chargingInfo[index]->SystemStatus >= SYS_MODE_PREPARE_FOR_EV && chargingInfo[index]->SystemStatus <= SYS_MODE_CHARGING) || (chargingInfo[index]->SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0 && chargingInfo[index]->SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1)) _maxChargingStatus = _CHARGING_GUN_STATUS_CHARGING; else _maxChargingStatus = _CHARGING_GUN_STATUS_STOP; } } } int main(void) { if(InitShareMemory() == FAIL) { #ifdef SystemLogMessage DEBUG_ERROR("InitShareMemory NG\n"); #endif if(ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory = 1; } sleep(5); return 0; } PRINTF_FUNC("InitShareMemory OK\n"); // register callback function RefreshStatus(&GetStatusCallback); RefreshModuleCount(&GetModuleCountCallback); RefreshAvailableCap(&GetAvailableCapCallback); RefreshFwVersion(&GetFwCallback); RefreshInputVol(&GetInputVoltageCallback); RefreshGetOutput(&GetPresentOutputCallback); RefreshMisInfo(&GetMisCallback); RefreshIavailable(&GetIavailableCallback); RefreshGetOutputF(&GetPresentOutputFCallback); // GetPresentOutputCallback & GetStatusCallback AutoMode_RefreshOutputAndTemp(&GetOutputAndTempCallback); // GetStatusCallback AutoMode_RefreshModuleStatus(&GetModuleStatusCallback); // GetInputVoltageCallback AutoMode_RefreshModuleInput(&GetModuleInputCallback); sleep(2); _gunCount = ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; // initial object InitialPsuData(); Initialization(); libInitialize = InitialCommunication(); byte isInitialComp = NO; if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES) { PRINTF_FUNC("Alter native mode. \n"); } //main loop while (libInitialize) { // 斷電狀態 if (ShmSysConfigAndInfo->SysInfo.AcContactorStatus == NO) { //一但 AC Off PSU 斷電全部的 PSU Group ID 會全部清 0 if (!isInitialComp) { ShmPsuData->Work_Step = INITIAL_START; psuCmdSeq = _PSU_CMD_STATUS; sleep(2); InitialPsuData(); isInitialComp = YES; } ShmDcCommonData->psuKeepCommunication = ShmDcCommonData->acContactSwitch; sleep(1); continue; } else { if (isInitialComp) GetTimespecFunc(&ShmDcCommonData->_psuComm_time); isInitialComp = NO; } // 自檢失敗 if (ShmPsuData->Work_Step == _NO_WORKING) { PRINTF_FUNC("== PSU == self test fail. \n"); sleep(5); } else if (ShmDcCommonData->rebootCount < 1) { int _time = GetTimeoutValue(&ShmDcCommonData->_psuComm_time); if (_time < 0) GetTimespecFunc(&ShmDcCommonData->_psuComm_time); if (_time > 30) { if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuComminicationErrWithCSU == NO) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuComminicationErrWithCSU = YES; ShmDcCommonData->rebootCount = 1; PRINTF_FUNC("Psu is gone, reset one time. \n"); } } } switch(ShmPsuData->Work_Step) { case INITIAL_START: { PRINTF_FUNC("== PSU == INITIAL_START \n"); GetTimespecMFunc(&_cmdSubPsuPriority_time); sleep(5); SwitchPower(SYSTEM_CMD, PSU_POWER_OFF); SetWalkInConfig(SYSTEM_CMD, NO, 0); for (byte index = 0; index < ShmPsuData->GroupCount; index++) { ShmPsuData->PsuGroup[index].GroupPresentPsuQuantity = 0; isStartOutputSwitch[index] = false; } ShmPsuData->Work_Step = GET_PSU_COUNT; } break; case GET_PSU_COUNT: { int time = GetTimeoutMValue(&_cmdSubPsuPriority_time); byte moduleCount = 0; if (time < 0) GetTimespecMFunc(&_cmdSubPsuPriority_time); // 發送取得目前全部模組數量 GetModuleCount(SYSTEM_CMD); if (time > 1000) { if (psuCmdSeq == _PSU_CMD_STATUS) { // 取得狀態 : 支援模塊不須按照順序功能 for (byte index = 0; index < ShmPsuData->GroupCount; index++) { GetStatus(index); } Await(); } else if (psuCmdSeq == _PSU_CMD_GETCOUNT) { // 分別取各群模組數量 for (byte index = 0; index < ShmPsuData->GroupCount; index++) { // 總和各群模組數量 moduleCount += ShmPsuData->PsuGroup[index].GroupPresentPsuQuantity; // 取各群模組數量 GetModuleCount(index); } PRINTF_FUNC("== PSU == Connector Count = %d, moduleCount = %d, sysCount = %d\n", ShmPsuData->GroupCount, moduleCount, ShmPsuData->SystemPresentPsuQuantity); // 判斷系統數量與各群數量一致 if(moduleCount == ShmPsuData->SystemPresentPsuQuantity && moduleCount > 0) { _delayCount = 8; if (ShmSysConfigAndInfo->SysInfo.BootingStatus == BOOTTING) { // 電樁在 Booting 的狀態 - 自檢 PRINTF_FUNC("== PSU == GET_SYS_CAP \n"); ShmPsuData->Work_Step = GET_SYS_CAP; } else { PRINTF_FUNC("== PSU == _WORK_CHARGING \n"); ShmPsuData->Work_Step = _WORK_CHARGING; } } } if (psuCmdSeq == _PSU_CMD_STATUS) psuCmdSeq = _PSU_CMD_GETCOUNT; else psuCmdSeq = _PSU_CMD_STATUS; GetTimespecMFunc(&_cmdSubPsuPriority_time); } } break; case GET_SYS_CAP: { int time = GetTimeoutMValue(&_cmdSubPsuPriority_time); if (time < 0) GetTimespecMFunc(&_cmdSubPsuPriority_time); if (time > 500) { bool isFinish = true; for (byte psuCount = 0; psuCount < ShmPsuData->SystemPresentPsuQuantity; psuCount++) { if (strcmp((char *)ShmPsuData->PsuVersion[psuCount].FwPrimaryVersion, "") == EQUAL || ShmPsuData->SystemAvailablePower <= 0 || ShmPsuData->SystemAvailableCurrent <= 0) { isFinish = false; break; } } if (!isFinish || _delayCount > 0) { for (byte index = 0; index < ShmPsuData->GroupCount; index++) { if (psuCmdSeq == _PSU_CMD_STATUS) { // 取得狀態 : 支援模塊不須按照順序功能 GetStatus(index); } else if (psuCmdSeq == _PSU_CMD_CAP) { _delayCount--; // 取系統總輸出能力 GetModuleCap(index); } else if (psuCmdSeq == _PSU_CMD_VERSION) { // 取版號 GetModuleVer(index); } } if (psuCmdSeq == _PSU_CMD_STATUS) psuCmdSeq = _PSU_CMD_CAP; else if (psuCmdSeq == _PSU_CMD_CAP) psuCmdSeq = _PSU_CMD_VERSION; else psuCmdSeq = _PSU_CMD_STATUS; } else { // 判斷系統輸出額定功率與電流 PRINTF_FUNC("SystemAvailableCurrent = %d, SystemAvailablePower = %d \n", ShmPsuData->SystemAvailableCurrent, ShmPsuData->SystemAvailablePower); PRINTF_FUNC("== PSU == BOOTING_COMPLETE \n"); ShmPsuData->Work_Step = BOOTING_COMPLETE; } GetTimespecMFunc(&_cmdSubPsuPriority_time); //GetTimespecFunc(&_log_time); } } break; case BOOTING_COMPLETE: { bool isSelfTestPass = true; for (byte groupIndex = 0; groupIndex < _gunCount; groupIndex++) { if (chargingInfo[groupIndex]->SystemStatus == SYS_MODE_BOOTING) { isSelfTestPass = false; } } if (isSelfTestPass) ShmPsuData->Work_Step = _WORK_CHARGING; sleep(1); } break; case _WORK_CHARGING: { int time = GetTimeoutMValue(&_cmdSubPsuPriority_time); //int _timebuf = 0; if (time < 0) GetTimespecMFunc(&_cmdSubPsuPriority_time); // 低 Priority 的指令 if (time > 1500) { PreCheckSmartChargingStep(); startModuleFlag = true; GetTimespecMFunc(&_cmdSubPsuPriority_time); } for (byte groupIndex = 0; groupIndex < _gunCount; groupIndex++) { if (psuCmdSeq == _PSU_CMD_CAP) { // 取系統總輸出能力 GetModuleCap(groupIndex); } else if (psuCmdSeq == _PSU_CMD_OUTPUT) { // 取各群輸出電壓電流 (float) GetModuleOutputF(groupIndex); } else if (psuCmdSeq == _PSU_CMD_IVAILIABLE) { // 取得模塊輸出額定電流能力 GetModuleIavailable(groupIndex); } else if (psuCmdSeq == _PSU_CMD_TEMP) { // 取得模塊溫度 GetDcTemperature(groupIndex); } } Await(); if (psuCmdSeq == _PSU_CMD_CAP) psuCmdSeq = _PSU_CMD_OUTPUT; else if (psuCmdSeq == _PSU_CMD_OUTPUT) psuCmdSeq = _PSU_CMD_IVAILIABLE; else if (psuCmdSeq == _PSU_CMD_IVAILIABLE) psuCmdSeq = _PSU_CMD_TEMP; else psuCmdSeq = _PSU_CMD_CAP; for (byte groupIndex = 0; groupIndex < _gunCount; groupIndex++) { // 針對各槍當前狀態,傳送需要回傳的資料指令 if (((chargingInfo[groupIndex]->SystemStatus >= SYS_MODE_PREPARE_FOR_EVSE && chargingInfo[groupIndex]->SystemStatus <= SYS_MODE_CHARGING) && chargingInfo[groupIndex]->RelayK1K2Status) || (chargingInfo[groupIndex]->SystemStatus >= SYS_MODE_PREPARE_FOR_EVSE && chargingInfo[groupIndex]->SystemStatus <= SYS_MODE_CHARGING && chargingInfo[groupIndex]->Type == _Type_GB) || (chargingInfo[groupIndex]->SystemStatus >= SYS_MODE_CCS_PRECHARGE_STEP0 && chargingInfo[groupIndex]->SystemStatus <= SYS_MODE_CCS_PRECHARGE_STEP1)) { // _timebuf = GetTimeoutValue(&_log_time); // if (_timebuf < 0) // GetTimespecFunc(&_log_time); // // if (_timebuf > 1) { OutputChargingLogFuncion(groupIndex); //GetTimespecFunc(&_log_time); } if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX) { if (!MaxToAverChargingProc(groupIndex)) { if(chargingInfo[groupIndex]->EvBatterytargetCurrent <= PSU_MIN_OUTPUT_CUR) chargingInfo[groupIndex]->EvBatterytargetCurrent = PSU_MIN_OUTPUT_CUR; PresentOutputVol(SYSTEM_CMD, (chargingInfo[groupIndex]->EvBatterytargetVoltage * 10), (chargingInfo[groupIndex]->EvBatterytargetCurrent * 10)); if ((chargingInfo[groupIndex]->EvBatterytargetVoltage * 10) == 0) { bool isNeedToClosePower = false; for (byte index = 0; index < ShmPsuData->GroupCount; index++) { if (isStartOutputSwitch[index]) { isNeedToClosePower = true; } isStartOutputSwitch[index] = false; } if (isNeedToClosePower) { SwitchPower(SYSTEM_CMD, PSU_POWER_OFF); FlashLed(SYSTEM_CMD, PSU_FLASH_NORMAL); } } else { { bool isNeedToOpenPower = false; for (byte index = 0; index < ShmPsuData->GroupCount; index++) { if (!isStartOutputSwitch[index]) { isNeedToOpenPower = true; } isStartOutputSwitch[index] = true; } if (isNeedToOpenPower || startModuleFlag) { SwitchPower(SYSTEM_CMD, PSU_POWER_ON); FlashLed(SYSTEM_CMD, PSU_FLASH_ON); } } } } } else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER) { if (!AverToMaxChargingProc(groupIndex)) { if (chargingInfo[groupIndex]->AvailableChargingCurrent > 0) { //PRINTF_FUNC("set out (%d) value = %f******** 7 \n", groupIndex, chargingInfo[groupIndex]->EvBatterytargetCurrent); if(chargingInfo[groupIndex]->EvBatterytargetCurrent <= PSU_MIN_OUTPUT_CUR) chargingInfo[groupIndex]->EvBatterytargetCurrent = PSU_MIN_OUTPUT_CUR; PresentOutputVol(groupIndex, (chargingInfo[groupIndex]->EvBatterytargetVoltage * 10), (chargingInfo[groupIndex]->EvBatterytargetCurrent * 10)); Await(); if ((chargingInfo[groupIndex]->EvBatterytargetVoltage * 10) == 0) { if (isStartOutputSwitch[groupIndex]) { isStartOutputSwitch[groupIndex] = false; SwitchPower(groupIndex, PSU_POWER_OFF); Await(); FlashLed(groupIndex, PSU_FLASH_NORMAL); Await(); } } else { // if (chargingInfo[groupIndex]->SystemStatus == SYS_MODE_PREPARE_FOR_EVSE) // { // if (startModuleFlag) // { // isStartOutputSwitch[groupIndex] = true; // SwitchSinglePower(ShmDcCommonData->connector[groupIndex][0], PSU_POWER_ON); // FlashSingleLed(ShmDcCommonData->connector[groupIndex][0], PSU_FLASH_ON); // } // } // else { if (!isStartOutputSwitch[groupIndex] || startModuleFlag) { isStartOutputSwitch[groupIndex] = true; SwitchPower(groupIndex, PSU_POWER_ON); Await(); FlashLed(groupIndex, PSU_FLASH_ON); Await(); } } } } } } } else if (chargingInfo[groupIndex]->SystemStatus >= SYS_MODE_TERMINATING && chargingInfo[groupIndex]->SystemStatus <= SYS_MODE_ALARM) { if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX) { SwitchOffPowerCheck(groupIndex); if (_maxChargingStatus == _CHARGING_GUN_STATUS_STOP) { bool isNeedToClosePower = false; for (byte index = 0; index < ShmPsuData->GroupCount; index++) { if (isStartOutputSwitch[index]) { isNeedToClosePower = true; } isStartOutputSwitch[index] = false; } if (isNeedToClosePower) { SwitchPower(SYSTEM_CMD, PSU_POWER_OFF); FlashLed(SYSTEM_CMD, PSU_FLASH_NORMAL); } if (chargingInfo[groupIndex]->SystemStatus == SYS_MODE_COMPLETE || chargingInfo[groupIndex]->SystemStatus == SYS_MODE_ALARM) { 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 == SYS_MODE_COMPLETE) { // 代表充電的槍依舊在充電,欲進入充電的槍取消充電了 if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_PREPARE_M_TO_A && ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A) { ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE; } } } else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER) { // if (!isReadyToCharging) // { // bool isNeedToClosePower = false; // for (byte index = 0; index < ShmPsuData->GroupCount; index++) // { // if (isStartOutputSwitch[index]) // { // isNeedToClosePower = true; // } // isStartOutputSwitch[index] = false; // } // // if (isNeedToClosePower) // { // SwitchPower(SYSTEM_CMD, PSU_POWER_OFF); // FlashLed(SYSTEM_CMD, PSU_FLASH_NORMAL); // } // } // else // { if (isStartOutputSwitch[groupIndex] && ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_NONE) { isStartOutputSwitch[groupIndex] = false; SwitchPower(groupIndex, PSU_POWER_OFF); Await(); FlashLed(groupIndex, PSU_FLASH_NORMAL); Await(); } //} if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_WAITING) ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_COMP; } } else if ((chargingInfo[groupIndex]->SystemStatus >= SYS_MODE_PREPARING && chargingInfo[groupIndex]->SystemStatus <= SYS_MODE_PREPARE_FOR_EV) && ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER) { //PRINTF_FUNC("%d ******** 7 \n", groupIndex); if (isStartOutputSwitch[groupIndex]) { isStartOutputSwitch[groupIndex] = false; SwitchPower(groupIndex, PSU_POWER_OFF); Await(); FlashLed(groupIndex, PSU_FLASH_NORMAL); Await(); } } } startModuleFlag = false; break; } case _ALATON_MODE: { // int time = GetTimeoutMValue ( & _cmdSubPsuPriority_time ); // // if (time < 0) // GetTimespecMFunc ( & _cmdSubPsuPriority_time ); // // // 低 Priority 的指令 // if (time > 1500) // { // PreCheckSmartChargingStep (); // startModuleFlag = true; // GetTimespecMFunc ( & _cmdSubPsuPriority_time ); // } // // for (byte groupIndex = 0; groupIndex < _gunCount; groupIndex ++) // { // if (psuCmdSeq == _PSU_CMD_CAP) // { // // 取系統總輸出能力 // GetModuleCap ( groupIndex ); // } // else if (psuCmdSeq == _PSU_CMD_OUTPUT) // { // // 取各群輸出電壓電流 (float) // GetModuleOutputF ( groupIndex ); // } // else if (psuCmdSeq == _PSU_CMD_IVAILIABLE) // { // // 取得模塊輸出額定電流能力 // GetModuleIavailable ( groupIndex ); // } // else if (psuCmdSeq == _PSU_CMD_TEMP) // { // // 取得模塊溫度 // GetDcTemperature ( groupIndex ); // } // } // // Await (); // // if (psuCmdSeq == _PSU_CMD_CAP) // psuCmdSeq = _PSU_CMD_OUTPUT; // else if (psuCmdSeq == _PSU_CMD_OUTPUT) // psuCmdSeq = _PSU_CMD_IVAILIABLE; // else if (psuCmdSeq == _PSU_CMD_IVAILIABLE) // psuCmdSeq = _PSU_CMD_TEMP; // else // psuCmdSeq = _PSU_CMD_CAP; // // for (byte psu = 0; psu < ShmPsuData->SystemPresentPsuQuantity; psu++) // { // if (psu == ShmDcCommonData->for_alston_test_1) // { // FlashSingleLed(psu, PSU_FLASH_NORMAL); // } // else // { // FlashSingleLed(psu, PSU_FLASH_ON); // } // } } break; case _TEST_MODE: { // 在測試模式中,保持與模塊的通訊 int time = GetTimeoutMValue(&_cmdSubPsuPriority_time); if (time < 0) GetTimespecMFunc(&_cmdSubPsuPriority_time); if (time > 1500) { for (byte index = 0; index < ShmPsuData->GroupCount; index++) { // 取系統總輸出能力 GetModuleCap(index); Await(); // 取各群輸出電壓電流 (float) GetModuleOutputF(index); Await(); } GetTimespecMFunc(&_cmdSubPsuPriority_time); } byte _switch = 0x00; if ((chargingInfo[0]->EvBatterytargetVoltage * 10) > 0 && (chargingInfo[0]->EvBatterytargetCurrent * 10) > 0) _switch = 0x01; for (byte _groupCount_1 = 0; _groupCount_1 < ShmDcCommonData->conn_1_count; _groupCount_1++) { SetDirModulePresentOutput(ShmDcCommonData->connector[0][_groupCount_1], (chargingInfo[0]->EvBatterytargetVoltage * 10), (chargingInfo[0]->EvBatterytargetCurrent * 10), _switch, _switch); Await(); } for (byte _groupCount_2 = 0; _groupCount_2 < ShmDcCommonData->conn_2_count; _groupCount_2++) { SetDirModulePresentOutput(ShmDcCommonData->connector[1][_groupCount_2], (chargingInfo[0]->EvBatterytargetVoltage * 10), (chargingInfo[0]->EvBatterytargetCurrent * 10), _switch, _switch); Await(); } } break; } usleep(20000); } return FAIL; }