/* * Module_Dispenser.c * * Created on: 2021/10/26 * Author: folus */ #include "Module_Dispenser.h" //========================== // Timeout constant define //========================== #define TIMEOUT_SPEC_HANDSHAKING 180 #define TIMEOUT_SPEC_AUTH 15 #define TIMEOUT_SPEC_HANDSHAKING_LED 185 #define TIMEOUT_SPEC_REFRESH_CHARGING_INFO 30 #define TIMEOUT_SPEC_PROFILE_PREPARE 60 #define TIMEOUT_SPEC_BS_HLC_HANDSHAKE 60 #define TIMEOUT_SPEC_EV_READY 30 #define TIMEOUT_SPEC_CCS_HEARTBEAT_COUNT_RESET 10 #define TIMEOUT_SPEC_CCS_HANDSHAKE 120 #define TIMEOUT_SPEC_PWN_CHANGE 5 #define TIMEOUT_SPEC_POWERSAVING_LCD 120 #define TIMEOUT_SPEC_POWERSAVING_RFID 120 #define TIMEOUT_SPEC_POWERSAVING_METER 120 #define TIMEOUT_SPEC_POWERSAVING_LED_STATUS 120 #define TIMEOUT_SPEC_CEHCK_POWER_CONSUMPTION 15 #define is_error(ptr) ((unsigned long)ptr > (unsigned long)-4000L) #define ARRAY_SIZE(A) (sizeof(A) / sizeof(A[0])) #define PASS 1 #define FAIL -1 #define YES 1 #define NO 0 #define ON 1 #define OFF 0 #define MtdBlockSize 0x300000 struct SysConfigAndInfo *ShmSysConfigAndInfo; struct StatusCodeData *ShmStatusCodeData; struct PrimaryMcuData *ShmPrimaryMcuData; struct DISPENSER *ShmDispenser; struct timespec startTime[TMR_IDX_CNT]; struct timespec startChargingTime; struct timespec endChargingTime; struct SysConfigData SysConfigOrg; /* * * @param dest * @param src * @param start * @param cnt */ void substr(char *dest, const char* src, unsigned int start, unsigned int cnt) { strncpy(dest, src + start, cnt); dest[cnt] = 0; } /* * * @param fmt * @return */ int StoreLogMsg(const char *fmt, ...) { char Buf[4096+256]; char buffer[4096]; time_t CurrentTime; struct tm *tm; struct timeval tv; va_list args; va_start(args, fmt); int rc = vsnprintf(buffer, sizeof(buffer), fmt, args); va_end(args); memset(Buf,0,sizeof(Buf)); CurrentTime = time(NULL); tm=localtime(&CurrentTime); gettimeofday(&tv, NULL); // get microseconds, 10^-6 sprintf(Buf,"echo -n \"[%04d.%02d.%02d %02d:%02d:%02d.%06ld]%s\" >> /Storage/SystemLog/[%04d.%02d]DispenserLog", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec, buffer, tm->tm_year+1900,tm->tm_mon+1); #ifdef SystemLogMessage system(Buf); #endif #ifdef ConsloePrintLog printf("[%04d.%02d.%02d %02d:%02d:%02d.%06ld]%s", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec, buffer); #endif return rc; } /* * * @param timer */ void refreshStartTimer(struct timespec *timer) { clock_gettime(CLOCK_MONOTONIC, timer); } /* * * @param clk * @return */ int getDiffSecNow(struct timespec timer) { struct timespec timerNow; clock_gettime(CLOCK_MONOTONIC, &timerNow); return (int)((((unsigned long)(timerNow.tv_sec - timer.tv_sec) * 1000) + ((unsigned long)((timerNow.tv_nsec / 1000000) - (timer.tv_nsec / 1000000))))/1000); } /* * * @param start * @param end * @return */ int getDiffSecBetween(struct timespec start, struct timespec end) { return (int)((((unsigned long)(end.tv_sec - start.tv_sec) * 1000) + ((unsigned long)((end.tv_nsec / 1000000) - (start.tv_nsec / 1000000))))/1000); } /* * * @param result */ void getDateTimeString(char* result) { time_t CurrentTime; struct tm *tm; CurrentTime = time(NULL); tm=localtime(&CurrentTime); sprintf(result, "%04d.%02d.%02d %02d:%02d:%02d", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec); } /* * * @param mode * @return */ char* getSystemModeName(unsigned char mode) { char* result; switch(mode) { case SYS_MODE_BOOTING: result = "booting"; break; case SYS_MODE_IDLE: result = "idle"; break; case SYS_MODE_AUTHORIZING: result = "authorizing"; break; case SYS_MODE_PREPARING: result = "preparing"; break; case SYS_MODE_CHARGING: result = "charging"; break; case SYS_MODE_TERMINATING: result = "terminating"; break; case SYS_MODE_COMPLETE: result = "complete"; break; case SYS_MODE_ALARM: result = "alarm"; break; case SYS_MODE_FAULT: result = "fault"; break; case SYS_MODE_MAINTAIN: result = "maintain"; break; case SYS_MODE_RESERVATION: result = "reservation"; break; case SYS_MODE_BOOKING: result = "booking"; break; case SYS_MODE_DEBUG: result = "debug"; break; case SYS_MODE_UPDATE: result = "upgrade"; break; default: result = "unknown"; break; } return result; } /* * * @param ptr * @return */ int LoadSysConfigAndInfo(struct SysConfigData *ptr) { int fd,wrd; unsigned char *buf; unsigned int ChkSum,ChkSumOrg; if((buf=malloc(MtdBlockSize))==NULL) { DEBUG_ERROR("malloc buffer NG,rebooting..\n"); if(ShmStatusCodeData!=NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed=1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } memset(buf, 0, MtdBlockSize); //================================================ // Load configuration from mtdblock10 //================================================ system("nanddump /dev/mtd10 -f /mnt/EvseConfig.bin"); fd = open("/mnt/EvseConfig.bin", O_RDWR); if (fd < 0) { free(buf); DEBUG_ERROR("open mtdblock10 NG,rebooting..\n"); if(ShmStatusCodeData!=NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed=1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } wrd=read(fd, buf, MtdBlockSize); close(fd); if(wrdAlarmCode.AlarmEvents.bits.CsuInitFailed=1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } ChkSum=0; for(wrd=ARRAY_SIZE(ptr->CsuBootLoadFwRev);wrdModelName,buf+(ARRAY_SIZE(ptr->CsuBootLoadFwRev)),ARRAY_SIZE(ptr->ModelName)); memcpy(&ptr->SerialNumber,buf+(ARRAY_SIZE(ptr->CsuBootLoadFwRev)+ARRAY_SIZE(ptr->ModelName)+ARRAY_SIZE(ptr->AcModelName)),ARRAY_SIZE(ptr->SerialNumber)); //================================================ // Load configuration from mtdblock11 //================================================ if(ChkSum!=ChkSumOrg) { DEBUG_ERROR("Primary SysConfigData checksum NG, read backup\n"); system("nanddump /dev/mtd11 -f /mnt/EvseConfig.bin"); fd = open("/mnt/EvseConfig.bin", O_RDWR); if (fd < 0) { free(buf); DEBUG_ERROR("open mtdblock11 (backup) NG,rebooting..\n"); if(ShmStatusCodeData!=NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed=1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } memset(buf, 0, MtdBlockSize); wrd=read(fd, buf,MtdBlockSize); close(fd); if(wrdAlarmCode.AlarmEvents.bits.CsuInitFailed=1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } ChkSum=0; for(wrd=ARRAY_SIZE(ptr->CsuBootLoadFwRev);wrdAlarmCode.AlarmEvents.bits.CsuInitFailed=1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } memset(buf, 0, MtdBlockSize); wrd=read(fd, buf,MtdBlockSize); close(fd); if(wrdAlarmCode.AlarmEvents.bits.CsuInitFailed=1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } ChkSum=0; for(wrd=ARRAY_SIZE(ptr->CsuBootLoadFwRev);wrdCsuBootLoadFwRev)), &ptr->ModelName, ARRAY_SIZE(ptr->ModelName)); memcpy(buf+(ARRAY_SIZE(ptr->CsuBootLoadFwRev)+ARRAY_SIZE(ptr->ModelName)+ARRAY_SIZE(ptr->AcModelName)), &ptr->SerialNumber, ARRAY_SIZE(ptr->SerialNumber)); if(ChkSum!=ChkSumOrg) { DEBUG_WARN("factory default SysConfigData checksum NG, restore factory default\n"); free(buf); system("cd /root;./Module_FactoryConfig -m"); system("rm -f /Storage/OCPP/OCPPConfiguration"); system("sync"); sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); return FAIL; } } } //load OK memcpy((struct SysConfigData *)ptr,buf,sizeof(struct SysConfigData)); free(buf); system("rm -f /mnt/EvseConfig.bin"); // SysConfig in flash is empty (0xffffffff) if((strlen((char*)ShmSysConfigAndInfo->SysConfig.ModelName) > ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.ModelName)) || (strlen((char*)ShmSysConfigAndInfo->SysConfig.SerialNumber) > ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SerialNumber)) || (strlen((char*)ShmSysConfigAndInfo->SysConfig.SystemId) > ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SystemId)) || (ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthDhcpClient == 0xff)) { if(strlen((char*)ShmSysConfigAndInfo->SysConfig.ModelName) > ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.ModelName)) { memset(ShmSysConfigAndInfo->SysConfig.ModelName, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.ModelName)); } if(strlen((char*)ShmSysConfigAndInfo->SysConfig.SerialNumber) > ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SerialNumber)) { memset(ShmSysConfigAndInfo->SysConfig.SerialNumber, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SerialNumber)); } if(strlen((char*)ShmSysConfigAndInfo->SysConfig.SystemId) > ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SystemId)) { memset(ShmSysConfigAndInfo->SysConfig.SystemId, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SystemId)); } if(ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthDhcpClient == 0xff) { DEBUG_INFO("Ethernet dhcp config is null.\n"); } if(strlen((char*)ShmSysConfigAndInfo->SysConfig.ModelName) == 0x00) { DEBUG_INFO("Model name over length.\n"); } if(strlen((char*)ShmSysConfigAndInfo->SysConfig.SerialNumber) == 0x00) { DEBUG_INFO("Model serial number over length.\n"); } if(strlen((char*)ShmSysConfigAndInfo->SysConfig.SystemId) == 0x00) { DEBUG_INFO("SystemId over length.\n"); } system("cd /root;./Module_FactoryConfig -m"); sleep(3); system("/usr/bin/run_evse_restart.sh"); } DEBUG_INFO("Load SysConfigData OK\n"); return PASS; } /* * * @param UsrData * @return */ int StoreUsrConfigData(struct SysConfigData *UsrData) { int result = PASS; int fd,wrd; unsigned int i,Chk; unsigned char *ptr, *BufTmp; Chk=0; ptr=(unsigned char *)UsrData; if((BufTmp=malloc(MtdBlockSize))!=NULL) { memset(BufTmp,0,MtdBlockSize); memcpy(BufTmp,ptr,sizeof(struct SysConfigData)); for(i=0;igun_info.SystemStatus == mode)?YES:NO); } /* * * @param gun_index * @return */ unsigned char isModeChange() { unsigned char result = NO; if(!isMode(ShmDispenser->gun_info.PreviousSystemStatus)) { result = YES; ShmDispenser->gun_info.PreviousSystemStatus = ShmDispenser->gun_info.SystemStatus; } return result; } /* * * @param gun_index * @param mode */ void setChargerMode(unsigned char mode) { ShmDispenser->gun_info.PreviousSystemStatus = ShmDispenser->gun_info.SystemStatus; ShmDispenser->gun_info.SystemStatus = mode; DEBUG_INFO("System mode switch from %s to %s\n", getSystemModeName(ShmDispenser->gun_info.PreviousSystemStatus), getSystemModeName(ShmDispenser->gun_info.SystemStatus)); } /* * * @return */ int getRequest() { return ShmDispenser->gun_info.legacyRequest.isLegacyRequest; } /* * * @param gun_index * @return */ int getRelay() { return ShmDispenser->gun_info.legacyRequest.isRelayOn; } /* * * @param gun_index * @return */ int presentChargedEnergyClear() { int result = FAIL; ShmDispenser->gun_info.PresentChargedEnergy = 0; memset(ShmDispenser->gun_info.presentChargedEnergyPeriod, 0x00, ARRAY_SIZE(ShmDispenser->gun_info.presentChargedEnergyPeriod)*sizeof(float)); result = PASS; return result; } /* * * @param gun_index * @return */ float presentChargedEnergyTotal() { float result = 0.0f; for(int idx=0;idxgun_info.presentChargedEnergyPeriod);idx++) { result += ShmDispenser->gun_info.presentChargedEnergyPeriod[idx]; } return result; } /* * * @param gun_index * @return */ int presentChargedEnergyUpdate() { int result = FAIL; time_t CurrentTime; struct tm *tm; CurrentTime = time(NULL); tm=localtime(&CurrentTime); if(ShmDispenser->ConfigData.AcPhaseCount==1) { // Resolution: 0.0001 kwh ShmDispenser->gun_info.presentChargedEnergyPeriod[tm->tm_hour] += (((float)(ShmDispenser->gun_info.powerConsumptionTotal.power_consumption - ShmDispenser->gun_info.powerConsumptionTotal.power_consumption_at_start))/10000.0) - presentChargedEnergyTotal(); } else { // Resolution: 0.0001 kwh ShmDispenser->gun_info.presentChargedEnergyPeriod[tm->tm_hour] += ((((float)(ShmDispenser->gun_info.powerConsumption[0].power_consumption - ShmDispenser->gun_info.powerConsumption[0].power_consumption_at_start))/10000.0) + (((float)(ShmDispenser->gun_info.powerConsumption[1].power_consumption - ShmDispenser->gun_info.powerConsumption[1].power_consumption_at_start))/10000.0) + (((float)(ShmDispenser->gun_info.powerConsumption[2].power_consumption - ShmDispenser->gun_info.powerConsumption[2].power_consumption_at_start))/10000.0)) - presentChargedEnergyTotal(); } ShmDispenser->gun_info.PresentChargedEnergy = presentChargedEnergyTotal(); return result; } /* * Init all share memory * @return */ int InitShareMemory() { int result = PASS; int MeterSMId; //Initial ShmSysConfigAndInfo if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), 0777)) < 0) { DEBUG_ERROR("shmget ShmSysConfigAndInfo NG\n"); result = FAIL; } else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmSysConfigAndInfo NG\n"); result = FAIL; } else {} //Initial ShmStatusCodeData if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), 0777)) < 0) { DEBUG_ERROR("shmget ShmStatusCodeData NG\n"); result = FAIL; } else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmStatusCodeData NG\n"); result = FAIL; } else {} //Initial ShmSDispenser if ((MeterSMId = shmget(ShmDispenserKey, sizeof(struct DISPENSER), 0777)) < 0) { DEBUG_ERROR("shmget ShmSDispenser NG\n"); result = FAIL; } else if ((ShmDispenser = shmat(MeterSMId, NULL, 0)) == (void *) -1) { DEBUG_ERROR("shmat ShmSDispenser NG\n"); result = FAIL; } return result; } /* * Upgrade firmware * @return */ int upgrade_check() { int result = PASS; int fd; DIR *dir; struct dirent *file; char cmd[512]; long int MaxLen=48*1024*1024; if ((dir = opendir ("/mnt")) != NULL) { /* print all the files and directories within directory */ while ((file = readdir (dir)) != NULL) { if((strlen(file->d_name)>2)) { // Wait for MCU upgrade finish. while(ShmDispenser->gun_info.mcuFlag.isMcuUpgradeReq)sleep(1); memset(&ShmDispenser->fwUpgradeInfo, 0xFF, sizeof(Fw_Upgrade_Info)); DEBUG_INFO("New firmware file: %s\n", file->d_name); sprintf(ShmDispenser->fwUpgradeInfo.location, "/mnt/%s", file->d_name); if((fd=open(ShmDispenser->fwUpgradeInfo.location, O_RDONLY)) >= 0) { unsigned char *ptr = malloc(MaxLen); //-48 is take out the header memset(ptr, 0xFF, MaxLen); //-48 is take out the header read(fd, ptr, MaxLen); close(fd); ShmDispenser->fwUpgradeInfo.fwType = ((ptr[0x13]<<0) | (ptr[0x12]<<8) | (ptr[0x11]<<16) | (ptr[0x10]<<24)); substr(ShmDispenser->fwUpgradeInfo.modelName, (char *)ptr, 0, 0x10); DEBUG_INFO("New firmware type: %X\n", ShmDispenser->fwUpgradeInfo.fwType); DEBUG_INFO("New firmware model name: %s, %s\n", ShmDispenser->fwUpgradeInfo.modelName, ShmDispenser->ConfigData.ModelName); if((ShmDispenser->fwUpgradeInfo.modelName[0] == ShmDispenser->ConfigData.ModelName[0]) && (ShmDispenser->fwUpgradeInfo.modelName[1] == ShmDispenser->ConfigData.ModelName[1]) && (ShmDispenser->fwUpgradeInfo.modelName[7] == ShmDispenser->ConfigData.ModelName[7]) && (ShmDispenser->fwUpgradeInfo.modelName[8] == ShmDispenser->ConfigData.ModelName[8]) && (ShmDispenser->fwUpgradeInfo.modelName[9] == ShmDispenser->ConfigData.ModelName[9]) && (ShmDispenser->fwUpgradeInfo.modelName[11] == ShmDispenser->ConfigData.ModelName[11]) && (ShmDispenser->fwUpgradeInfo.modelName[12] == ShmDispenser->ConfigData.ModelName[12]) && (ShmDispenser->fwUpgradeInfo.modelName[13] == ShmDispenser->ConfigData.ModelName[13]) && (ShmDispenser->fwUpgradeInfo.fwType>0)) { switch(ShmDispenser->fwUpgradeInfo.fwType) { case CSU_MLO: case CSU_BOOTLOADER: case CSU_KERNEL_CONFIGURATION: case CSU_KERNEL_IMAGE: case CSU_ROOT_FILE_SYSTEM: case CSU_USER_CONFIGURATION: case CSU_PRIMARY_CONTROLLER: if(Upgrade_Flash(ShmDispenser->fwUpgradeInfo.fwType, ShmDispenser->fwUpgradeInfo.location, ShmDispenser->fwUpgradeInfo.modelName) != PASS) { result = FAIL; } else { if(ShmDispenser->fwUpgradeInfo.fwType == CSU_USER_CONFIGURATION) { DEBUG_INFO("Restore model name & serial number.\n"); memcpy(&SysConfigOrg, &ShmDispenser->ConfigData, sizeof(struct SysConfigData)); if(LoadSysConfigAndInfo(&ShmSysConfigAndInfo->SysConfig) != PASS) { DEBUG_INFO("Re-load configuration fail.\n"); result = FAIL; } else { memcpy(&ShmSysConfigAndInfo->SysConfig.ModelName, &SysConfigOrg.ModelName, ARRAY_SIZE(SysConfigOrg.ModelName)); memcpy(&ShmSysConfigAndInfo->SysConfig.SerialNumber, &SysConfigOrg.SerialNumber, ARRAY_SIZE(SysConfigOrg.SerialNumber)); memcpy(&ShmSysConfigAndInfo->SysConfig.SystemId, &SysConfigOrg.SystemId, ARRAY_SIZE(SysConfigOrg.SystemId)); if(StoreUsrConfigData(&ShmSysConfigAndInfo->SysConfig) != PASS) { DEBUG_INFO("Re-write configuration fail.\n"); result = FAIL; } else DEBUG_INFO("Re-write configuration OK.\n"); } } } sprintf(cmd, "yes|rm %s", ShmDispenser->fwUpgradeInfo.location); system(cmd); break; case AC_WALLMOUNT_CONTROLLER: ShmDispenser->gun_info.mcuFlag.isMcuUpgradeReq = ON; sleep(10); break; default: result = FAIL; DEBUG_WARN("Image file is unknown type.\n"); sprintf(cmd, "yes|rm %s", ShmDispenser->fwUpgradeInfo.location); system(cmd); break; } } else { result = FAIL; DEBUG_ERROR("Model name and Firmware type error.\n"); sprintf(cmd, "yes|rm %s", ShmDispenser->fwUpgradeInfo.location); system(cmd); } free(ptr); } else { result = FAIL; DEBUG_ERROR("New firmware open error.\n"); } } else { if(strlen(file->d_name) >= 3) { result = FAIL; DEBUG_ERROR("File name error.\n"); } else { DEBUG_ERROR("Searching file.\n"); } } } closedir (dir); } else { result = FAIL; DEBUG_ERROR("/mnt does not valid.\n"); } return result; } /* * * @return */ int main(void) { // Initial share memory if(InitShareMemory() == FAIL) { DEBUG_ERROR("InitShareMemory NG\n"); if(ShmStatusCodeData!=NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory=ON; } sleep(5); return 0; } ShmDispenser->gun_info.PreviousSystemStatus = 0xff; ShmDispenser->gun_info.primaryMcuState.rotatory_switch = 0xff; ShmDispenser->gun_info.mcuResetRequest.isMcuResetRequest = ON; ShmDispenser->gun_info.isSetBreatheLedTiming = OFF; ShmDispenser->gun_info.isSetLedBrightness = OFF; DEBUG_INFO("Module_Dispenser initialized...\n"); for(;;) { //========================================== // Check initialization "PASS" or "FAIL" //========================================== if(ShmDispenser->gun_info.SystemStatus != SYS_MODE_BOOTING) { // Alarm event check if((ShmDispenser->gun_info.primaryMcuAlarm.InputAlarmCode > 0)) { if(ShmDispenser->gun_info.SystemStatus != SYS_MODE_ALARM) { if(ShmDispenser->gun_info.SystemStatus != SYS_MODE_UPDATE) { setChargerMode(SYS_MODE_ALARM); } } } } //========================================== // Switch operative //========================================== if(ShmDispenser->gun_info.isOperactive) { if(isMode(SYS_MODE_MAINTAIN)) { setChargerMode(SYS_MODE_IDLE); } } else { if(isMode(SYS_MODE_IDLE)) { setChargerMode(SYS_MODE_MAINTAIN); } } //========================================== // Upgrade check //========================================== if(ShmDispenser->gun_info.isUpgradeReq && !ShmDispenser->gun_info.isUpgradeEnd) { if((ShmDispenser->gun_info.SystemStatus == SYS_MODE_IDLE) || (ShmDispenser->gun_info.SystemStatus == SYS_MODE_ALARM)) { if((ShmDispenser->gun_info.isUpgradePASS = upgrade_check()) == PASS) { DEBUG_INFO("Upgrade process pass.\n"); } else { DEBUG_ERROR("Upgrade process fail.\n"); } ShmDispenser->gun_info.isUpgradeEnd = ON; } } //========================================== // Gun process //========================================== switch(ShmDispenser->gun_info.SystemStatus) { case SYS_MODE_BOOTING: if(isModeChange()) {} if(ShmDispenser->gun_info.mcuFlag.isReadFwVerPass && ShmDispenser->gun_info.mcuFlag.isSetModelNamePass && ShmDispenser->gun_info.mcuFlag.isSetSerialNumberPass) { // Set max current to rating current ShmDispenser->gun_info.primaryMcuCp_Pwn_Duty.max_current = ShmDispenser->gun_info.primaryMcuState.rating_current; // If rotate switch equal zero, the system needs to change Debug mode if(ShmDispenser->gun_info.primaryMcuState.rotatory_switch == 0) setChargerMode(SYS_MODE_DEBUG); else setChargerMode(SYS_MODE_IDLE); } break; case SYS_MODE_IDLE: if(isModeChange()) { ShmDispenser->gun_info.isGunPlugged = NO; ShmDispenser->gun_info.systemAlarmCode.SystemAlarmCode = 0x00; ShmDispenser->gun_info.PresentChargedDuration = 0; presentChargedEnergyClear(); ShmDispenser->gun_info.targetCurrent = 0xFF; ShmDispenser->gun_info.ccsHandshakeState = HANDSHAKE_IDLE; ShmDispenser->gun_info.chargingMode = CHARGING_MODE_BS; ShmDispenser->gun_info.isDoEvReadyOnce = OFF; ShmDispenser->gun_info.primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_100; ShmDispenser->gun_info.mcuFlag.isSetCpPwmDuty = ON; } if(ShmDispenser->gun_info.legacyRequest.isLegacyRequest) { ShmDispenser->gun_info.isGunPlugged = NO; ShmDispenser->gun_info.mcuFlag.isSetCpPwmDuty = YES; if(ShmDispenser->isCcsEnable) { ShmDispenser->gun_info.primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_5; } else { ShmDispenser->gun_info.primaryMcuCp_Pwn_Duty.max_current = (ShmDispenser->gun_info.targetCurrent==0?CCS_PWM_DUTY_100:ShmDispenser->gun_info.targetCurrent); } ShmDispenser->gun_info.mcuFlag.isSetCpPwmDuty = YES; setChargerMode(SYS_MODE_AUTHORIZING); } else {} break; case SYS_MODE_AUTHORIZING: if(isModeChange()) {} setChargerMode(SYS_MODE_PREPARING); break; case SYS_MODE_PREPARING: if(isModeChange()) { refreshStartTimer(&startTime[TMR_IDX_HANDSHAKING]); if(ShmDispenser->isCcsEnable) { ShmDispenser->gun_info.ccsHandshakeState = HANDSHAKE_DUTY_5; } else { ShmDispenser->gun_info.ccsHandshakeState = HANDSHAKE_CP_STATE_E; ShmDispenser->gun_info.chargingMode = CHARGING_MODE_BS; } } // If control pilot detect Bx, skip watch dog time out. if((ShmDispenser->gun_info.primaryMcuState.cp_state == CP_STATE_B) || (ShmDispenser->gun_info.primaryMcuState.cp_state == CP_STATE_C)) { ShmDispenser->gun_info.isGunPlugged = YES; switch(ShmDispenser->gun_info.ccsHandshakeState) { case HANDSHAKE_DUTY_5: //Let CCS task start to negotiate ShmDispenser->gun_info.acCcsInfo.ChargingPermission = ON; ShmDispenser->gun_info.acCcsInfo.EVSENotification = NOTIFICATION_NONE; // Set CCS 5% PWM duty if(ShmDispenser->gun_info.acCcsInfo.CpSetPWMDuty == CCS_PWM_DUTY_5) { ShmDispenser->gun_info.primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_5; ShmDispenser->gun_info.mcuFlag.isSetCpPwmDuty = ON; ShmDispenser->gun_info.ccsHandshakeState = HANDSHAKE_DUTY_5_CHECK; DEBUG_INFO("ccsHandshakeState = HANDSHAKE_DUTY_5_CHECK\n"); } break; case HANDSHAKE_DUTY_5_CHECK: if((ShmDispenser->gun_info.mcuFlag.isSetCpPwmDuty == OFF)) { //2 secs timeout refreshStartTimer(&startTime[TMR_IDX_BS_HLC_HANDSHAKE]); DEBUG_INFO("HLC slac handshake start.\n"); ShmDispenser->gun_info.ccsHandshakeState = HANDSHAKE_CCS; DEBUG_INFO("ccsHandshakeState = HANDSHAKE_CCS\n"); } break; case HANDSHAKE_CCS: //CCS handshake timeout if(getDiffSecNow(startTime[TMR_IDX_BS_HLC_HANDSHAKE]) > TIMEOUT_SPEC_BS_HLC_HANDSHAKE) { ShmDispenser->gun_info.acCcsInfo.ChargingPermission = OFF; ShmDispenser->gun_info.acCcsInfo.EVSENotification = NOTIFICATION_STOP; DEBUG_INFO("HLC %d secs slac handshake timeout.\n", TIMEOUT_SPEC_BS_HLC_HANDSHAKE); if(ShmDispenser->isCcsEnable) { DEBUG_INFO("TIMEOUT_SPEC_BS_HLC_HANDSHAKE.\n"); ShmDispenser->gun_info.acCcsInfo.ChargingPermission = OFF; ShmDispenser->gun_info.primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_CP_STATE_F; ShmDispenser->gun_info.mcuFlag.isSetCpPwmDuty = ON; ShmDispenser->gun_info.ccsHandshakeState = HANDSHAKE_CP_STATE_E; ShmDispenser->gun_info.chargingMode = CHARGING_MODE_BS; break; } else { ShmDispenser->gun_info.acCcsInfo.ChargingPermission = OFF; ShmDispenser->gun_info.acCcsInfo.EVSENotification = NOTIFICATION_STOP; DEBUG_INFO("BS/HLC %d secs handshake timeout.\n", TIMEOUT_SPEC_BS_HLC_HANDSHAKE); } } if((ShmDispenser->gun_info.acCcsInfo.ChargingPermission == OFF) && (ShmDispenser->gun_info.acCcsInfo.CpSetPWMDuty != CCS_PWM_DUTY_5)) { DEBUG_INFO("Wait CCS give up negotiagting.\n"); ShmDispenser->gun_info.primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_CP_STATE_F; ShmDispenser->gun_info.mcuFlag.isSetCpPwmDuty = ON; ShmDispenser->gun_info.ccsHandshakeState = HANDSHAKE_CP_STATE_E; ShmDispenser->gun_info.chargingMode = CHARGING_MODE_BS; } //CCS status check if((16 <= ShmDispenser->gun_info.acCcsInfo.PresentMsgFlowStatus) && (ShmDispenser->gun_info.acCcsInfo.PresentMsgFlowStatus < 253)) { //change PWM duty to BS if((ShmDispenser->gun_info.mcuFlag.isSetCpPwmDuty == OFF)&&(ShmDispenser->gun_info.primaryMcuCp_Pwn_Duty.max_current!=CCS_PWM_DUTY_5)) { ShmDispenser->gun_info.primaryMcuCp_Pwn_Duty.max_current =CCS_PWM_DUTY_5; ShmDispenser->gun_info.mcuFlag.isSetCpPwmDuty = ON; DEBUG_INFO("ccsHandshakeState = HANDSHAKE_CCS (set 5% duty)\n"); } refreshStartTimer(&startTime[TMR_IDX_HANDSHAKING]); } if((37 < ShmDispenser->gun_info.acCcsInfo.PresentMsgFlowStatus) && (ShmDispenser->gun_info.acCcsInfo.PresentMsgFlowStatus < 49)) { //chang PWM duty to BS if((ShmDispenser->gun_info.mcuFlag.isSetCpPwmDuty == OFF)&&(ShmDispenser->gun_info.primaryMcuCp_Pwn_Duty.max_current!=CCS_PWM_DUTY_5)) { ShmDispenser->gun_info.primaryMcuCp_Pwn_Duty.max_current =CCS_PWM_DUTY_5; ShmDispenser->gun_info.mcuFlag.isSetCpPwmDuty = ON; } ShmDispenser->gun_info.chargingMode = CHARGING_MODE_HLC; ShmDispenser->gun_info.ccsHandshakeState = HANDSHAKE_HLC_MODE; DEBUG_INFO("ccsHandshakeState = HANDSHAKE_HLC_MODE\n"); } else if((54 < ShmDispenser->gun_info.acCcsInfo.PresentMsgFlowStatus) && (ShmDispenser->gun_info.acCcsInfo.PresentMsgFlowStatus <= 255)) { DEBUG_INFO("ccsHandshakeState = CHARGING_MODE_BS, CCS terminated\n"); ShmDispenser->gun_info.acCcsInfo.ChargingPermission = OFF; ShmDispenser->gun_info.primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_CP_STATE_F; ShmDispenser->gun_info.mcuFlag.isSetCpPwmDuty = ON; ShmDispenser->gun_info.ccsHandshakeState = HANDSHAKE_CP_STATE_E; ShmDispenser->gun_info.chargingMode = CHARGING_MODE_BS; } break; case HANDSHAKE_CP_STATE_E: if(ShmDispenser->gun_info.mcuFlag.isSetCpPwmDuty == OFF) { if(ShmDispenser->isCcsEnable) { DEBUG_INFO("Change to CP STATE E for 4 secs.\n"); //CP STATE E for 4 secs sleep(4); } //restore normal CP PWM duty // Determine max charging current to MCU DEBUG_INFO("Determine max charging current to MCU.\n"); ShmDispenser->gun_info.primaryMcuCp_Pwn_Duty.max_current = (ShmDispenser->gun_info.targetCurrent==0?CCS_PWM_DUTY_100:ShmDispenser->gun_info.targetCurrent); ShmDispenser->gun_info.mcuFlag.isSetCpPwmDuty = YES; ShmDispenser->gun_info.ccsHandshakeState = HANDSHAKE_SET_MAX_CURRENT; refreshStartTimer(&startTime[TMR_IDX_BS_HLC_HANDSHAKE]); } break; case HANDSHAKE_SET_MAX_CURRENT: if(ShmDispenser->gun_info.mcuFlag.isSetCpPwmDuty == OFF) { ShmDispenser->gun_info.ccsHandshakeState = HANDSHAKE_BS_MODE; DEBUG_INFO("Enter BS Mode charging.\n"); //for EV READY 30 secs didn't start charging to STATE E refreshStartTimer(&startTime[TMR_IDX_HANDSHAKING]); } break; case HANDSHAKE_BS_MODE: refreshStartTimer(&startTime[TMR_IDX_HANDSHAKING]); presentChargedEnergyClear(); getDateTimeString((char*)ShmDispenser->gun_info.StartDateTime); ShmDispenser->gun_info.powerConsumptionTotal.power_consumption_at_start = ShmDispenser->gun_info.powerConsumptionTotal.power_consumption; ShmDispenser->gun_info.powerConsumption[0].power_consumption_at_start = ShmDispenser->gun_info.powerConsumption[0].power_consumption; ShmDispenser->gun_info.powerConsumption[1].power_consumption_at_start = ShmDispenser->gun_info.powerConsumption[1].power_consumption; ShmDispenser->gun_info.powerConsumption[2].power_consumption_at_start = ShmDispenser->gun_info.powerConsumption[2].power_consumption; refreshStartTimer(&startChargingTime); setChargerMode(SYS_MODE_CHARGING); //EV READY CHECK /* if((DiffTimebWithNow(startTime[gun_index][TMR_IDX_BS_HLC_HANDSHAKE]) > TIMEOUT_SPEC_EV_READY) && (ShmCharger->gun_info[gun_index].isEvReady2StateE == OFF)) { if(ShmCharger->gun_info[gun_index].isDoEvReadyOnce == OFF) { DEBUG_INFO("EV READY STATE E 4sec.\n"); ShmCharger->gun_info[gun_index].isEvReady2StateE = ON; ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_CP_STATE_E; ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; ShmCharger->gun_info[gun_index].evReadyState = EV_READY_STAT_E; } } if(ShmCharger->gun_info[gun_index].isEvReady2StateE == ON) { switch(ShmCharger->gun_info[gun_index].evReadyState) { case EV_READY_STAT_E: if(ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty == OFF) { sleep(4); ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_100; ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; ShmCharger->gun_info[gun_index].evReadyState = EV_READY_STAT_C; } break; case EV_READY_STAT_C: if(ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty == OFF) { usleep(500000); DEBUG_INFO("EV READY Determine max charging current to MCU.\n"); if(ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent == 0) { ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmCharger->gun_info[gun_index].primaryMcuState.rating_current)?ShmCharger->gun_info[gun_index].primaryMcuState.rating_current:ShmCharger->gun_info[gun_index].targetCurrent); if(ShmCharger->gun_info[gun_index].targetCurrent != ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current) { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmCharger->gun_info[gun_index].primaryMcuState.rating_current)?ShmCharger->gun_info[gun_index].primaryMcuState.rating_current:ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; } } else { ShmCharger->gun_info[gun_index].targetCurrent = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent)?ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent:ShmCharger->gun_info[gun_index].targetCurrent); if(ShmCharger->gun_info[gun_index].targetCurrent != ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current) { ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ((ShmCharger->gun_info[gun_index].targetCurrent > ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent)?ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent:ShmCharger->gun_info[gun_index].targetCurrent); ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; } } ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON; ShmCharger->gun_info[gun_index].evReadyState = EV_READY_SET_MAX_CURRENT; } break; case EV_READY_SET_MAX_CURRENT: if(ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty == OFF) { ShmCharger->gun_info[gun_index].isEvReady2StateE = OFF; ShmCharger->gun_info[gun_index].isDoEvReadyOnce = ON; } break; default: break; } }*/ break; case HANDSHAKE_HLC_MODE: if(ShmDispenser->gun_info.acCcsInfo.EVChargeProgress == HLC_START_MODE)//powerDelivery { ShmDispenser->gun_info.isCCSStartTransation = ON; } if((ShmDispenser->gun_info.isCCSStartTransation == ON)) { presentChargedEnergyClear(); getDateTimeString((char*)ShmDispenser->gun_info.StartDateTime); ShmDispenser->gun_info.powerConsumptionTotal.power_consumption_at_start = ShmDispenser->gun_info.powerConsumptionTotal.power_consumption; ShmDispenser->gun_info.powerConsumption[0].power_consumption_at_start = ShmDispenser->gun_info.powerConsumption[0].power_consumption; ShmDispenser->gun_info.powerConsumption[1].power_consumption_at_start = ShmDispenser->gun_info.powerConsumption[1].power_consumption; ShmDispenser->gun_info.powerConsumption[2].power_consumption_at_start = ShmDispenser->gun_info.powerConsumption[2].power_consumption; ShmDispenser->gun_info.isCCSStartTransation = OFF; setChargerMode(SYS_MODE_CHARGING); refreshStartTimer(&startChargingTime); refreshStartTimer(&startTime[TMR_IDX_CCS_HEARTBEAT_COUNT_RESET]); } //120 sec timeout if(getDiffSecNow(startTime[TMR_IDX_HANDSHAKING]) > TIMEOUT_SPEC_CCS_HANDSHAKE) { if(getDiffSecNow(startTime[TMR_IDX_HANDSHAKING]) > TIMEOUT_SPEC_CCS_HANDSHAKE+5) { DEBUG_INFO("CCS 120 secs handshake timeout, change to BS Mode...\n"); //Cancel CCS task negotiating ShmDispenser->gun_info.acCcsInfo.ChargingPermission = OFF; ShmDispenser->gun_info.acCcsInfo.EVSENotification = NOTIFICATION_STOP; //ShmDispenser->gun_info.isCCSWaitChangeDuty = ON; if((ShmDispenser->gun_info.acCcsInfo.ChargingPermission == OFF) && (ShmDispenser->gun_info.acCcsInfo.CpSetPWMDuty != CCS_PWM_DUTY_5)) { DEBUG_INFO("Wait CCS give up negotiagting.\n"); ShmDispenser->gun_info.primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_CP_STATE_F; ShmDispenser->gun_info.mcuFlag.isSetCpPwmDuty = ON; ShmDispenser->gun_info.ccsHandshakeState = HANDSHAKE_CP_STATE_E; ShmDispenser->gun_info.chargingMode = CHARGING_MODE_BS; } } } break; default: break; } } else if(ShmDispenser->gun_info.primaryMcuState.socket_e.isSocketEMode) { DEBUG_INFO("Enter Socket-E Mode charging.\n"); ShmDispenser->gun_info.chargingMode = CHARGING_MODE_SOCKETE; refreshStartTimer(&startChargingTime); setChargerMode(SYS_MODE_CHARGING); } // Unplug charging gun to Idle mode if((ShmDispenser->gun_info.primaryMcuState.cp_state == CP_STATE_A) && (ShmDispenser->gun_info.isGunPlugged == YES)) { DEBUG_INFO("Charging gun is plugged before.\n"); //Cancel CCS task negotiating ShmDispenser->gun_info.acCcsInfo.ChargingPermission = OFF; ShmDispenser->gun_info.acCcsInfo.EVSENotification = NOTIFICATION_STOP; ShmDispenser->gun_info.isCCSWaitChangeDuty = ON; } if(getDiffSecNow(startTime[TMR_IDX_HANDSHAKING]) > ShmDispenser->timeoutSpec.Present_Timeout_Spec) { if(getDiffSecNow(startTime[TMR_IDX_HANDSHAKING]) > (ShmDispenser->timeoutSpec.Present_Timeout_Spec+5)) { DEBUG_INFO("Handshaking timeout...\n"); //Cancel CCS task negotiating ShmDispenser->gun_info.acCcsInfo.ChargingPermission = OFF; ShmDispenser->gun_info.acCcsInfo.EVSENotification = NOTIFICATION_STOP; ShmDispenser->gun_info.isCCSWaitChangeDuty = ON; } } if(((ShmDispenser->gun_info.isCCSWaitChangeDuty == ON) && ShmDispenser->gun_info.acCcsInfo.CpSetPWMDuty != CCS_PWM_DUTY_5) || !ShmDispenser->gun_info.legacyRequest.isLegacyRequest) { ShmDispenser->gun_info.primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_100; ShmDispenser->gun_info.mcuFlag.isSetCpPwmDuty = ON; ShmDispenser->gun_info.isCCSWaitChangeDuty = OFF; setChargerMode(SYS_MODE_IDLE); } break; case SYS_MODE_CHARGING: if(isModeChange()) { refreshStartTimer(&startTime[TMR_IDX_REFRESH_CHARGING_INFO]); refreshStartTimer(&startTime[TMR_IDX_PROFILE_PREPARE]); refreshStartTimer(&startTime[TMR_IDX_PWN_CHANGE]); ShmDispenser->gun_info.isChargerStopByCondition = NO; ShmDispenser->gun_info.resultAuthorization = DEFAULT_RFID; } //if time up, clear CCS MSG count if((ShmDispenser->gun_info.chargingMode == CHARGING_MODE_HLC) && (getDiffSecNow(startTime[TMR_IDX_CCS_HEARTBEAT_COUNT_RESET]) > TIMEOUT_SPEC_CCS_HEARTBEAT_COUNT_RESET)) { refreshStartTimer(&startTime[TMR_IDX_CCS_HEARTBEAT_COUNT_RESET]); } if(!ShmDispenser->gun_info.legacyRequest.isLegacyRequest || ((ShmDispenser->gun_info.chargingMode != CHARGING_MODE_SOCKETE) && ShmDispenser->gun_info.primaryMcuState.cp_state != CP_STATE_C) || ((ShmDispenser->gun_info.chargingMode == CHARGING_MODE_SOCKETE) && !ShmDispenser->gun_info.primaryMcuState.socket_e.isSocketEPinOn) || ((ShmDispenser->gun_info.chargingMode == CHARGING_MODE_HLC) && (ShmDispenser->gun_info.acCcsInfo.EVChargeProgress == HLC_STOP_MODE)) || ((ShmDispenser->gun_info.chargingMode == CHARGING_MODE_HLC) && ShmDispenser->gun_info.acCcsInfo.EVChargeProgress == HLC_RENEGOTIATE_MODE) || ((ShmDispenser->gun_info.chargingMode == CHARGING_MODE_HLC) && ShmDispenser->gun_info.acCcsInfo.EVChargeProgress == HLC_STANDBY_MODE) || ((ShmDispenser->gun_info.chargingMode == CHARGING_MODE_HLC) && ((49 <= ShmDispenser->gun_info.acCcsInfo.PresentMsgFlowStatus) && (ShmDispenser->gun_info.acCcsInfo.PresentMsgFlowStatus <= 255)))) { setChargerMode(SYS_MODE_TERMINATING); //setRelay(gun_index, OFF); } else { // Charging session info calculation refreshStartTimer(&endChargingTime); ShmDispenser->gun_info.PresentChargedDuration = getDiffSecBetween(startChargingTime, endChargingTime); presentChargedEnergyUpdate(); // Determine max charging current to MCU if(ShmDispenser->gun_info.chargingMode == CHARGING_MODE_BS) { if(getDiffSecNow(startTime[TMR_IDX_PWN_CHANGE]) > TIMEOUT_SPEC_PWN_CHANGE) { ShmDispenser->gun_info.primaryMcuCp_Pwn_Duty.max_current = (ShmDispenser->gun_info.targetCurrent==0?CCS_PWM_DUTY_100:ShmDispenser->gun_info.targetCurrent); ShmDispenser->gun_info.mcuFlag.isSetCpPwmDuty = YES; refreshStartTimer(&startTime[TMR_IDX_PWN_CHANGE]); } } else if(ShmDispenser->gun_info.chargingMode == CHARGING_MODE_HLC) { ShmDispenser->gun_info.acCcsInfo.EVSEMaxCurrent = (float)((ShmDispenser->gun_info.targetCurrent > ShmDispenser->gun_info.primaryMcuState.rating_current)?ShmDispenser->gun_info.primaryMcuState.rating_current:ShmDispenser->gun_info.targetCurrent); } // Debug information if(getDiffSecNow(startTime[TMR_IDX_REFRESH_CHARGING_INFO]) > TIMEOUT_SPEC_REFRESH_CHARGING_INFO) { DEBUG_INFO("==================================================\n"); DEBUG_INFO("gun_info.primaryMcuCp_Pwn_Duty.max_current: %d\n", ShmDispenser->gun_info.primaryMcuCp_Pwn_Duty.max_current); DEBUG_INFO("gun_info.targetCurrent: %d\n", ShmDispenser->gun_info.targetCurrent); DEBUG_INFO("==================================================\n"); refreshStartTimer(&startTime[TMR_IDX_REFRESH_CHARGING_INFO]); getDateTimeString((char*)ShmDispenser->gun_info.StopDateTime); } } break; case SYS_MODE_TERMINATING: if(isModeChange()) { getDateTimeString((char*)ShmDispenser->gun_info.StopDateTime); } refreshStartTimer(&endChargingTime); if(ShmDispenser->gun_info.PresentChargedDuration != 0) { ShmDispenser->gun_info.PresentChargedDuration = getDiffSecBetween(startChargingTime, endChargingTime); } // End authorize pass if(!ShmDispenser->gun_info.legacyRequest.isLegacyRequest || ((ShmDispenser->gun_info.chargingMode != CHARGING_MODE_SOCKETE) && (ShmDispenser->gun_info.primaryMcuState.cp_state == CP_STATE_A)) || ((ShmDispenser->gun_info.chargingMode == CHARGING_MODE_SOCKETE) && !ShmDispenser->gun_info.primaryMcuState.socket_e.isSocketEPinOn) || ((ShmDispenser->gun_info.chargingMode == CHARGING_MODE_HLC) && (ShmDispenser->gun_info.acCcsInfo.EVChargeProgress == HLC_STOP_MODE))) { if(ShmDispenser->gun_info.chargingMode == CHARGING_MODE_BS) { ShmDispenser->gun_info.primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_100; ShmDispenser->gun_info.mcuFlag.isSetCpPwmDuty = ON; sleep(1); setChargerMode(SYS_MODE_COMPLETE); } else if(ShmDispenser->gun_info.chargingMode == CHARGING_MODE_HLC) { //setChargerMode(gun_index, SYS_MODE_COMPLETE); //Cancel CCS task negotiating ShmDispenser->gun_info.acCcsInfo.ChargingPermission = OFF; ShmDispenser->gun_info.acCcsInfo.EVSENotification = NOTIFICATION_STOP; ShmDispenser->gun_info.isCCSWaitChangeDuty = ON; } else { setChargerMode(SYS_MODE_COMPLETE); } } else { // Debug information if(getDiffSecNow(startTime[TMR_IDX_REFRESH_CHARGING_INFO]) > TIMEOUT_SPEC_REFRESH_CHARGING_INFO) { DEBUG_INFO("==================================================\n"); DEBUG_INFO("gun_info.primaryMcuCp_Pwn_Duty.max_current: %d\n", ShmDispenser->gun_info.primaryMcuCp_Pwn_Duty.max_current); DEBUG_INFO("gun_info.targetCurrent: %d\n", ShmDispenser->gun_info.targetCurrent); DEBUG_INFO("==================================================\n"); refreshStartTimer(&startTime[TMR_IDX_REFRESH_CHARGING_INFO]); } if(getDiffSecNow(startTime[TMR_IDX_PWN_CHANGE]) > TIMEOUT_SPEC_PWN_CHANGE) { ShmDispenser->gun_info.primaryMcuCp_Pwn_Duty.max_current = (ShmDispenser->gun_info.targetCurrent==0?CCS_PWM_DUTY_100:ShmDispenser->gun_info.targetCurrent); ShmDispenser->gun_info.mcuFlag.isSetCpPwmDuty = YES; refreshStartTimer(&startTime[TMR_IDX_PWN_CHANGE]); } if(ShmDispenser->gun_info.legacyRequest.isLegacyRequest && (((ShmDispenser->gun_info.chargingMode != CHARGING_MODE_SOCKETE) && (ShmDispenser->gun_info.primaryMcuState.cp_state == CP_STATE_C)) || ((ShmDispenser->gun_info.chargingMode == CHARGING_MODE_SOCKETE) && ShmDispenser->gun_info.primaryMcuState.socket_e.isSocketEPinOn)) && (((ShmDispenser->gun_info.chargingMode == CHARGING_MODE_HLC) && (ShmDispenser->gun_info.acCcsInfo.EVChargeProgress == HLC_START_MODE)) || (ShmDispenser->gun_info.chargingMode == CHARGING_MODE_BS)) ) { setChargerMode(SYS_MODE_CHARGING); } } if((ShmDispenser->gun_info.chargingMode == CHARGING_MODE_HLC) && (ShmDispenser->gun_info.isCCSWaitChangeDuty == ON) && (ShmDispenser->gun_info.acCcsInfo.CpSetPWMDuty == CCS_PWM_DUTY_100)) { DEBUG_INFO("Set PWM duty 100%% go to SYS_MODE_TERMINATING.\n"); ShmDispenser->gun_info.primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_100; ShmDispenser->gun_info.mcuFlag.isSetCpPwmDuty = ON; ShmDispenser->gun_info.isCCSWaitChangeDuty = OFF; setChargerMode( SYS_MODE_COMPLETE); } break; case SYS_MODE_COMPLETE: if(isModeChange()) {} if(((ShmDispenser->gun_info.chargingMode != CHARGING_MODE_SOCKETE) && (ShmDispenser->gun_info.primaryMcuState.cp_state == CP_STATE_A)) || ((ShmDispenser->gun_info.chargingMode == CHARGING_MODE_SOCKETE) && (!ShmDispenser->gun_info.primaryMcuState.socket_e.isSocketEPinOn))) { setChargerMode(SYS_MODE_IDLE); } break; case SYS_MODE_ALARM: if((ShmDispenser->gun_info.systemAlarmCode.SystemAlarmCode == 0)) { if((ShmDispenser->gun_info.PreviousSystemStatus == SYS_MODE_CHARGING) || (ShmDispenser->gun_info.PreviousSystemStatus == SYS_MODE_TERMINATING)) { setChargerMode(ShmDispenser->gun_info.PreviousSystemStatus); } else { setChargerMode(SYS_MODE_IDLE); } } break; case SYS_MODE_FAULT: if(isModeChange()) {} break; case SYS_MODE_MAINTAIN: if(isModeChange()) {} if(ShmDispenser->gun_info.isOperactive) { DEBUG_INFO("Connector change to operactive.\n"); setChargerMode(SYS_MODE_IDLE); } break; case SYS_MODE_UPDATE: if(isModeChange()) {} break; case SYS_MODE_DEBUG: if(isModeChange()) {} break; } usleep(100000); } return -1; }