#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /*標準輸入輸出定義*/ #include /*標準函數庫定義*/ #include /*Unix 標準函數定義*/ #include /*檔控制定義*/ #include /*PPSIX 終端控制定義*/ #include /*錯誤號定義*/ #include #include #include #include #include #include #include #include "../../define.h" #include "Config.h" #include #include #include "timeout.h" #define ARRAY_SIZE(A) (sizeof(A) / sizeof(A[0])) #define PASS 1 #define FAIL -1 #define BUFFER_SIZE 128 #define YES 1 #define NO 0 #define NORMAL 0 #define ABNORMAL 1 #define EQUAL 0 #define BTN_RELEASE 0 #define BTN_PRESS 1 #define MAX_BUF 64 #define MtdBlockSize 0x600000 #define SYSFS_GPIO_DIR "/sys/class/gpio" #define UPGRADE_FAN 0x02 #define UPGRADE_RB 0x03 #define UPGRADE_PRI 0x04 #define SYSTEM_MIN_VOL 1500 char *valid_Internet[2] = {"8.8.8.8", "180.76.76.76"}; unsigned char mask_table[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; int whileLoopTime = 10000; // 10 ms int wtdFd = -1; bool IsAuthorizingMode(); void ClearAuthorizedFlag(); bool isDetectPlugin(); void ClearDetectPluginFlag(); int mystrcmp(unsigned char *p1, unsigned char *p2); unsigned char DetectBitValue(unsigned char _byte, unsigned char _bit); void SetBitValue(unsigned char *_byte, unsigned char _bit, unsigned char value); void ChargingTerminalProcess(byte gunIndex); void ChkPrimaryStatus(); void StartSystemTimeoutDet(unsigned char flag); void StopSystemTimeoutDet(); void StartGunInfoTimeoutDet(unsigned char gunIndex, unsigned char flag); void StopGunInfoTimeoutDet(unsigned char gunIndex); int StoreLogMsg_1(const char *fmt, ...); unsigned long GetTimeoutValue(struct timeval _sour_time); void gpio_set_value(unsigned int gpio, unsigned int value); void PRINTF_FUNC(char *string, ...); #define DEBUG_INFO_MSG(format, args...) StoreLogMsg_1("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args) #define DEBUG_WARN_MSG(format, args...) StoreLogMsg_1("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args) #define DEBUG_ERROR_MSG(format, args...) StoreLogMsg_1("[%s:%d][%s][Error] "format, __FILE__, __LINE__, __FUNCTION__, ##args) struct SysConfigAndInfo *ShmSysConfigAndInfo; struct StatusCodeData *ShmStatusCodeData; struct PsuData *ShmPsuData; struct CHAdeMOData *ShmCHAdeMOData; struct CcsData *ShmCcsData; struct PrimaryMcuData *ShmPrimaryMcuData; struct FanModuleData *ShmFanModuleData; struct RelayModuleData *ShmRelayModuleData; struct OCPP16Data *ShmOCPP16Data; struct ChargingInfoData *chargingInfo[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY]; struct timeb startChargingTime[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY]; struct timeb endChargingTime[CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY]; // for initial index to check EV board type is correct byte _gunIndex = 0; byte _chademoIndex = 0; byte _ccsIndex = 0; byte _gb_Index = 0; byte bd0_1_status = 0; byte bd0_2_status = 0; byte bd1_1_status = 0; byte bd1_2_status = 0; bool isCardScan = false; int rfidFd = -1; char* rfidPortName = "/dev/ttyS2"; //================================================ // initial can-bus //================================================ int InitCanBus() { int s0,nbytes; struct timeval tv; struct ifreq ifr0; struct sockaddr_can addr0; system("/sbin/ip link set can0 down"); system("/sbin/ip link set can0 type can bitrate 500000 restart-ms 100"); system("/sbin/ip link set can0 up"); s0 = socket(PF_CAN, SOCK_RAW, CAN_RAW); tv.tv_sec = 0; tv.tv_usec = 10000; if (setsockopt(s0, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("Set SO_RCVTIMEO NG"); #endif } nbytes=40960; if (setsockopt(s0, SOL_SOCKET, SO_RCVBUF, &nbytes, sizeof(int)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("Set SO_RCVBUF NG"); #endif } nbytes=40960; if (setsockopt(s0, SOL_SOCKET, SO_SNDBUF, &nbytes, sizeof(int)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("Set SO_SNDBUF NG"); #endif } strcpy(ifr0.ifr_name, "can0" ); ioctl(s0, SIOCGIFINDEX, &ifr0); /* ifr.ifr_ifindex gets filled with that device's index */ addr0.can_family = AF_CAN; addr0.can_ifindex = ifr0.ifr_ifindex; bind(s0, (struct sockaddr *)&addr0, sizeof(addr0)); return s0; } //================================================ // initial uart port //================================================ char *_priPortName = "/dev/ttyS1"; char *_485PortName = "/dev/ttyS5"; int InitComPort(byte target) { int fd; struct termios tios; if(target == UPGRADE_PRI) fd = open(_priPortName, O_RDWR); else if (target == UPGRADE_FAN || target == UPGRADE_RB) fd = open(_485PortName, O_RDWR); if(fd<=0) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("open 407 Communication port NG \n"); #endif return -1; } ioctl (fd, TCGETS, &tios); tios.c_cflag = B115200| CS8 | CLOCAL | CREAD; tios.c_lflag = 0; tios.c_iflag = 0; tios.c_oflag = 0; tios.c_cc[VMIN]=0; tios.c_cc[VTIME]=(unsigned char)1; tios.c_lflag=0; tcflush(fd, TCIFLUSH); ioctl (fd, TCSETS, &tios); return fd; } //================================= // Common routine //================================= int InitWatchDog() { int fd; system("/usr/bin/fuser -k /dev/watchdog"); sleep(1); system("echo V > /dev/watchdog"); sleep(1); fd=open("/dev/watchdog", O_RDWR); if(fd<=0) { DEBUG_ERROR_MSG("System watch dog initial fail.\r\n"); } return fd; } int StoreLogMsg_1(const char *fmt, ...) { char Buf[4096+256]; char buffer[4096]; time_t CurrentTime; struct tm *tm; 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); sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec, buffer, tm->tm_year+1900,tm->tm_mon+1); system(Buf); return rc; } unsigned long GetTimeoutValue(struct timeval _sour_time) { struct timeval _end_time; gettimeofday(&_end_time, NULL); return 1000000 * (_end_time.tv_sec - _sour_time.tv_sec) + _end_time.tv_usec - _sour_time.tv_usec; } int mystrcmp(unsigned char *p1, unsigned char *p2) { while(*p1==*p2) { if(*p1=='\0' || *p2=='\0') break; p1++; p2++; } if(*p1=='\0' && *p2=='\0') return(PASS); else return(FAIL); } int DiffTimeb(struct timeb ST, struct timeb ET) { //return milli-second unsigned int StartTime,StopTime; StartTime=(unsigned int)ST.time; StopTime=(unsigned int)ET.time; //return (StopTime-StartTime)*1000+ET.millitm-ST.millitm; return (StopTime-StartTime); } bool CheckTimeOut(struct timeb ST) { struct timeb ET; unsigned int StartTime, StopTime; ftime(&ET); StartTime = (unsigned int) ST.time; StopTime = (unsigned int) ET.time; return (StopTime > StartTime)? YES : NO; } void setChargerMode(byte gun_index, byte mode) { chargingInfo[gun_index]->SystemStatus = mode; } void PRINTF_FUNC(char *string, ...) { va_list args; char buffer[4096]; va_start(args, string); vsnprintf(buffer, sizeof(buffer), string, args); va_end(args); if (DEBUG) printf("%s \n", buffer); else DEBUG_INFO_MSG("%s \n", buffer); } //========================================== // Check interface status //========================================== int isInterfaceUp(const char *interface) { int result = FAIL; FILE *fp; char cmd[256]; char buf[512]; strcpy(cmd, "ifconfig"); fp = popen(cmd, "r"); if(fp != NULL) { while(fgets(buf, sizeof(buf), fp) != NULL) { if(strstr(buf, interface) > 0) { result = PASS; } } } pclose(fp); return result; } //================================= // Create all share memory //================================= int CreateShareMemory() { int MeterSMId; if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), IPC_CREAT | 0777)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("[main]CreatShareMemory:shmget ShmSysConfigAndInfo NG \n"); #endif return 0; } else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("[main]CreatShareMemory:shmat ShmSysConfigAndInfo NG \n"); #endif return 0; } memset(ShmSysConfigAndInfo, 0, sizeof(struct SysConfigAndInfo)); if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), IPC_CREAT | 0777)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("[main]CreatShareMemory:shmget ShmStatusCodeData NG \n"); #endif return 0; } else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("[main]CreatShareMemory:shmat ShmStatusCodeData NG \n"); #endif return 0; } memset(ShmStatusCodeData, 0, sizeof(struct StatusCodeData)); //creat ShmPsuData if ((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData), IPC_CREAT | 0777)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("[main]CreatShareMemory:shmget ShmPsuData NG \n"); #endif return 0; } else if ((ShmPsuData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("[main]CreatShareMemory:shmat ShmPsuData NG \n"); #endif return 0; } memset(ShmPsuData, 0, sizeof(struct PsuData)); if(CHAdeMO_QUANTITY > 0) { if ((MeterSMId = shmget(ShmCHAdeMOCommKey, sizeof(struct CHAdeMOData), IPC_CREAT | 0777)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("[main]CreatShareMemory:shmget ShmCHAdeMOData NG \n"); #endif return 0; } else if ((ShmCHAdeMOData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("[main]CreatShareMemory:shmat ShmCHAdeMOData NG \n"); #endif return 0; } memset(ShmCHAdeMOData, 0, sizeof(struct CHAdeMOData)); } //creat ShmCcsData if(CCS_QUANTITY > 0) { if ((MeterSMId = shmget(ShmCcsCommKey, sizeof(struct CcsData), IPC_CREAT | 0777)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("[main]CreatShareMemory:shmget ShmCcsData NG \n"); #endif return 0; } else if ((ShmCcsData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("[main]CreatShareMemory:shmat ShmCcsData NG \n"); #endif return 0; } memset(ShmCcsData, 0, sizeof(struct CcsData)); } //creat ShmPrimaryMcuData if ((MeterSMId = shmget(ShmPrimaryMcuKey, sizeof(struct PrimaryMcuData), IPC_CREAT | 0777)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("[main]CreatShareMemory:shmget ShmPrimaryMcuData NG \n"); #endif return 0; } else if ((ShmPrimaryMcuData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("[main]CreatShareMemory:shmat ShmPrimaryMcuData NG \n"); #endif return 0; } memset(ShmPrimaryMcuData, 0, sizeof(struct PrimaryMcuData)); //creat ShmFanModuleData if ((MeterSMId = shmget(ShmFanBdKey, sizeof(struct FanModuleData), IPC_CREAT | 0777)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("[main]CreatShareMemory:shmget ShmFanModuleData NG \n"); #endif return 0; } else if ((ShmFanModuleData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("[main]CreatShareMemory:shmat ShmFanModuleData NG \n"); #endif return 0; } memset(ShmFanModuleData, 0, sizeof(struct FanModuleData)); //creat ShmRelayModuleData if ((MeterSMId = shmget(ShmRelayBdKey, sizeof(struct RelayModuleData), IPC_CREAT | 0777)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("[main]CreatShareMemory:shmget ShmRelayModuleData NG \n"); #endif return 0; } else if ((ShmRelayModuleData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("[main]CreatShareMemory:shmat ShmRelayModuleData NG \n"); #endif return 0; } memset(ShmRelayModuleData, 0, sizeof(struct RelayModuleData)); //creat ShmOCPP16Data if ((MeterSMId = shmget(ShmOcppModuleKey, sizeof(struct OCPP16Data), IPC_CREAT | 0777)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("[main]CreatShareMemory:shmget ShmOCPP16Data NG \n"); #endif return 0; } else if ((ShmOCPP16Data = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("[main]CreatShareMemory:shmat ShmOCPP16Data NG \n"); #endif return 0; } // memset(ShmOCPP16Data,0,sizeof(struct OCPP16Data)); return 1; } //================================= // LCM Page //================================= void ChangeLcmByIndex(byte page_index) { if (ShmSysConfigAndInfo->SysWarningInfo.Level != 2 || page_index == _LCM_COMPLETE || page_index == _LCM_FIX) { ShmSysConfigAndInfo->SysInfo.PageIndex = page_index; } } //====================================================== // Peripheral initial //====================================================== void InitGPIO() { /*****************0~3, 4 bank, bank x 32+ num*********************/ /***************************************************************/ /*************** GPIO 0 ***************************************/ /***************************************************************/ /* GPMC_AD8 => GPIO0_22 *//*ID BD1_1*/ system("echo 22 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio22/direction"); /* GPMC_AD9 => GPIO0_23 *//*ID BD1_2*/ system("echo 23 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio23/direction"); /* GPMC_AD10 => GPIO0_26 *//*IO BD1_1*/ system("echo 26 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio26/direction"); system("echo 1 > /sys/class/gpio/gpio26/value"); /* GPMC_AD11 => GPIO0_27 *//*IO BD1_2*/ system("echo 27 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio27/direction"); /* RMII1_REF_CLK => GPIO0_29 *//*USB 0 OCP detection*/ system("echo 29 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio29/direction"); /*XDMA_EVENT_INTR0 => GPIO0_19 *//*AM_RFID_RST*/ system("echo 19 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio19/direction"); system("echo 1 > /sys/class/gpio/gpio19/value"); /*XDMA_EVENT_INTR1 => GPIO0_20 *//*AM_RFID_ICC*/ system("echo 20 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio20/direction"); /***************************************************************/ /*************** GPIO 1 ***************************************/ /***************************************************************/ /* GPMC_AD12 => GPIO1_12 *//*ID BD2_1*/ system("echo 44 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio44/direction"); /* GPMC_AD13 => GPIO1_13 *//*ID BD2_2*/ system("echo 45 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio45/direction"); /* GPMC_AD14 => GPIO1_14 *//*IO BD2_1*/ system("echo 46 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio46/direction"); system("echo 0 > /sys/class/gpio/gpio46/value"); /* GPMC_AD15 => GPIO1_15 *//*IO BD2_2*/ system("echo 47 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio47/direction"); /***************************************************************/ /*************** GPIO 2 ***************************************/ /***************************************************************/ /*LCD_AC_BIAS_EN => GPIO2_25*//*RS-485 for module DE control*/ system("echo 89 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio89/direction"); system("echo 1 > /sys/class/gpio/gpio89/value"); /*LCD_HSYNC => GPIO2_23*//*RS-485 for module RE control*/ system("echo 87 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio87/direction"); system("echo 0 > /sys/class/gpio/gpio87/value"); /*LCD_PCLK => GPIO2_24*//*CCS communication board 1 proximity*/ system("echo 88 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio88/direction"); /*LCD_VSYNC => GPIO2_22*//*CCS communication board 2 proximity*/ system("echo 86 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio86/direction"); /***************************************************************/ /*************** GPIO 3 ***************************************/ /***************************************************************/ /*MCASP0_FSX => GPIO3_15*//*Emergency Stop button detect*/ system("echo 111 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio111/direction"); /*MCASP0_ACLKR => GPIO3_18*//*USB1 OCP detect*/ system("echo 114 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio114/direction"); /*MCASP0_AHCLKR => GPIO3_17*//*Emergency IO for AM3352 and STM32F407*/ system("echo 113 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio113/direction"); /*MCASP0_ACLKX => GPIO3_14*//*Ethernet PHY reset*/ system("echo 110 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio110/direction"); system("echo 0 > /sys/class/gpio/gpio110/value"); /* MCASP0_FSR => GPIO3_19 *//*SMR Enable control_1 for Pskill_1*/ system("echo 115 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio115/direction"); system("echo 0 > /sys/class/gpio/gpio115/value"); /* MCASP0_AXR0 => GPIO3_16 *//*CSU board function OK indicator.*/ system("echo 112 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio112/direction"); system("echo 1 > /sys/class/gpio/gpio112/value"); /* MCASP0_AXR1 => GPIO3_20 *//*SMR Enable control_2 for Pskill_2*/ system("echo 116 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio116/direction"); system("echo 0 > /sys/class/gpio/gpio116/value"); #ifdef SystemLogMessage DEBUG_INFO_MSG("[main]InitGPIO: Initial GPIO OK"); #endif } int LoadSysConfigAndInfo(struct SysConfigData *ptr) { int fd,wrd; unsigned char *buf; unsigned int ChkSum,ChkSumOrg; if((buf=malloc(MtdBlockSize))==NULL) { DEBUG_ERROR_MSG("malloc buffer NG,rebooting..\r\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 //================================================ fd = open("/dev/mtdblock10", O_RDWR); if (fd < 0) { free(buf); DEBUG_ERROR_MSG("open mtdblock10 NG,rebooting..\r\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=0;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=0;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=0;wrd 0) { //sscanf(buf, "%*s%*s%*s%*s%*s%*s%s", tmp); if(strstr(buf,"100%") != NULL) { } else { result = PASS; } //DEBUG_INFO("%s",buf); //DEBUG_INFO("%s\n",tmp); } } } pclose(fp); } return result; } void InitEthernet() { char tmpbuf[256]; // /sbin/ifconfig eth0 192.168.1.10 netmask 255.255.255.0 down system("echo 1 > /sys/class/gpio/gpio110/value");//reset PHY sleep(2); //Init Eth0 for internet memset(tmpbuf,0,256); sprintf(tmpbuf,"/sbin/ifconfig eth0 %s netmask %s up", ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthIpAddress, ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthSubmaskAddress); system(tmpbuf); memset(tmpbuf,0,256); sprintf(tmpbuf,"route add default gw %s eth0 ", ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthGatewayAddress); system(tmpbuf); //system("ifconfig lo up"); //Init Eth1 for administrator tool memset(tmpbuf,0,256); sprintf(tmpbuf,"/sbin/ifconfig eth1 %s netmask %s up", ShmSysConfigAndInfo->SysConfig.Eth1Interface.EthIpAddress, ShmSysConfigAndInfo->SysConfig.Eth1Interface.EthSubmaskAddress); system(tmpbuf); //Run DHCP client if enabled system("killall udhcpc"); system("rm -rf /etc/resolv.conf"); system("echo nameserver 8.8.8.8 > /etc/resolv.conf"); //Google DNS server system("echo nameserver 180.76.76.76 > /etc/resolv.conf"); //Baidu DNS server if(ShmSysConfigAndInfo->SysConfig.Eth1Interface.EthDhcpClient == 0) system("/sbin/udhcpc -i eth0 -s /root/dhcp_script/eth0.script > /dev/null &"); pid_t pid = fork(); uint8_t cnt_pingDNS_Fail; if(pid == 0) { for(;;) { if(isReachableInternet() == PASS) { ShmSysConfigAndInfo->SysInfo.InternetConn = YES; ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet= NO; cnt_pingDNS_Fail = 0; } else { if(++cnt_pingDNS_Fail > 3) { ShmSysConfigAndInfo->SysInfo.InternetConn = NO; //ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet= YES; } } sleep(5); } } #ifdef SystemLogMessage DEBUG_INFO_MSG("[main]InitEthernet: Initial Ethernet OK"); #endif } int InitialRfidPort() { int uartO2 = open(rfidPortName, O_RDWR); struct termios tios; if (uartO2 != FAIL) { ioctl (uartO2, TCGETS, &tios); tios.c_cflag = B19200 | CS8 | CLOCAL | CREAD; tios.c_lflag = 0; tios.c_iflag = 0; tios.c_oflag = 0; tios.c_cc[VMIN] = 0; tios.c_cc[VTIME] = (unsigned char) 1; tios.c_lflag = 0; tcflush(uartO2, TCIFLUSH); ioctl(uartO2, TCSETS, &tios); } if (uartO2 < 0) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RfidModuleCommFail = 1; } return uartO2; } void GetMacAddress() { for (byte index = 0; index < 2; index++) { int fd; struct ifreq ifr; char tarEth[5]; char Mac[18]; sprintf(tarEth,"eth%d",index); fd = socket(AF_INET, SOCK_DGRAM, 0); ifr.ifr_addr.sa_family = AF_INET; strncpy(ifr.ifr_name, tarEth, IFNAMSIZ - 1); ioctl(fd, SIOCGIFHWADDR, &ifr); close(fd); sprintf(Mac, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", ifr.ifr_hwaddr.sa_data[0], ifr.ifr_hwaddr.sa_data[1], ifr.ifr_hwaddr.sa_data[2], ifr.ifr_hwaddr.sa_data[3], ifr.ifr_hwaddr.sa_data[4], ifr.ifr_hwaddr.sa_data[5]); if (index == 0) strcpy((char *) ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthMacAddress, Mac); else strcpy((char *) ShmSysConfigAndInfo->SysConfig.Eth1Interface.EthMacAddress, Mac); } } void InitialShareMemoryInfo() { FILE *fp; char cmd[512]; char buf[512]; sprintf((char *)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomApn, "Internet"); sprintf((char *)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapId, " "); sprintf((char *)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapPwd, " "); ShmSysConfigAndInfo->SysInfo.FactoryConfiguration = 0; ShmSysConfigAndInfo->SysInfo.InputVoltageR = 0; ShmSysConfigAndInfo->SysInfo.InputVoltageS = 0; ShmSysConfigAndInfo->SysInfo.InputVoltageT = 0; ShmSysConfigAndInfo->SysInfo.SystemFanRotaSpeed = 0; ShmSysConfigAndInfo->SysInfo.PsuFanRotaSpeed = 0; ShmSysConfigAndInfo->SysInfo.AuxPower5V = 0; ShmSysConfigAndInfo->SysInfo.AuxPower12V = 0; ShmSysConfigAndInfo->SysInfo.AuxPower24V = 0; ShmSysConfigAndInfo->SysInfo.AuxPower48V = 0; sprintf((char *)ShmSysConfigAndInfo->SysInfo.CsuHwRev, "REV:5.0"); memcpy(ShmSysConfigAndInfo->SysInfo.CsuBootLoadFwRev, ShmSysConfigAndInfo->SysConfig.CsuBootLoadFwRev, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.CsuBootLoadFwRev)); sprintf(cmd, "/bin/uname -r"); fp = popen(cmd, "r"); if(fp == NULL) sprintf((char*)ShmSysConfigAndInfo->SysInfo.CsuKernelFwRev, "Unknown version"); else { while(fgets(buf, sizeof(buf), fp) != NULL) { strcpy((char*)ShmSysConfigAndInfo->SysInfo.CsuKernelFwRev, buf); } } // 雙槍 CCS + Chademo //sprintf((char *) ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, "D0.01.04.20.03.00"); // 移動 CCS sprintf((char *) ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, "D0.01.02.20.04.01"); sprintf((char *) ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev, " "); sprintf((char *) ShmSysConfigAndInfo->SysInfo.LcmHwRev, " "); sprintf((char *) ShmSysConfigAndInfo->SysInfo.LcmFwRev, " "); sprintf((char *) ShmSysConfigAndInfo->SysInfo.PsuHwRev, " "); sprintf((char *) ShmSysConfigAndInfo->SysInfo.PsuPrimFwRev, " "); sprintf((char *) ShmSysConfigAndInfo->SysInfo.PsuSecFwRev, " "); sprintf((char *) ShmSysConfigAndInfo->SysInfo.AuxPwrHwRev, " "); sprintf((char *) ShmSysConfigAndInfo->SysInfo.AuxPwrFwRev, " "); sprintf((char *) ShmSysConfigAndInfo->SysInfo.FanModuleHwRev, " "); sprintf((char *) ShmSysConfigAndInfo->SysInfo.FanModuleFwRev, " "); sprintf((char *) ShmSysConfigAndInfo->SysInfo.RelayModuleHwRev, " "); sprintf((char *) ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev, " "); sprintf((char *) ShmSysConfigAndInfo->SysInfo.TelcomModemFwRev, " "); ShmSysConfigAndInfo->SysInfo.SystemAmbientTemp = 0; ShmSysConfigAndInfo->SysInfo.SystemCriticalTemp = 0; ShmSysConfigAndInfo->SysInfo.PsuAmbientTemp = 0; ShmSysConfigAndInfo->SysInfo.CcsConnectorTemp = 0; ShmSysConfigAndInfo->SysInfo.InternetConn = 0; ShmSysConfigAndInfo->SysInfo.OcppConnStatus = 0; ShmSysConfigAndInfo->SysInfo.OrderCharging = FAIL; strcpy((char *) ShmSysConfigAndInfo->SysConfig.UserId, ""); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RelayboardStestFail = NO; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FanboardStestFail = NO; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PrimaryStestFail = NO; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.ChademoboardStestFail = NO; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CCSboardStestFail = NO; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.AcContactStestFail = NO; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuModuleStestFail = NO; memset(ShmSysConfigAndInfo->SysInfo.FanModuleFwRev, 0, ARRAY_SIZE(ShmSysConfigAndInfo->SysInfo.FanModuleFwRev)); memset(ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev, 0, ARRAY_SIZE(ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev)); ShmPrimaryMcuData->SelfTest_Comp = NO; ShmRelayModuleData->SelfTest_Comp = NO; ShmFanModuleData->SelfTest_Comp = NO; ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; ShmSysConfigAndInfo->SysInfo.MainChargingMode = _MAIN_CHARGING_MODE_MAX; ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE; ShmFanModuleData->TestFanSpeed = 0; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.ModelNameNoneMatchStestFail = NO; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuNoResource = NO; } int Initialization() { // 初始化卡號驗證的 Flag ClearAuthorizedFlag(); // 初始化插槍驗證的 Flag ClearDetectPluginFlag(); // UART 2 for Rfid rfidFd = InitialRfidPort(); int pinOut[2] = { 115, 116 }; for (byte count = 0; count < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; count++) { if (chargingInfo[count]->Type == _Type_Chademo) { gpio_set_value(pinOut[count], 0x01); ShmCHAdeMOData->evse[chargingInfo[count]->type_index].SelfTest_Comp = NO; } else if (chargingInfo[count]->Type == _Type_CCS_2) { if (ShmCcsData->CommProtocol == 0x01) { if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount == 1) gpio_set_value(pinOut[1], 0x00); else gpio_set_value(pinOut[count], 0x00); ShmCcsData->V2GMessage_DIN70121[chargingInfo[count]->type_index].SelfTest_Comp = NO; } } strcpy((char *)ShmOCPP16Data->StatusNotification[count].ErrorCode, "NoError"); } PRINTF_FUNC("Initialization OK \n"); return PASS; } bool InitialSystemDefaultConfig() { bool result = true; LoadSysConfigAndInfo(&ShmSysConfigAndInfo->SysConfig); InitGPIO(); InitEthernet(); GetMacAddress(); // system("echo 1 > /sys/class/gpio/gpio110/value"); //reset PHY // sleep(3); // system("/sbin/ifconfig eth0 192.168.1.10 netmask 255.255.255.0 down"); // sleep(1); // system("/sbin/ifconfig eth0 192.168.1.10 netmask 255.255.255.0 up"); return result; } void DisplaySelfTestFailReason() { // RB、FB、407、EV 小板中有些板子無回應 if (ShmRelayModuleData->SelfTest_Comp == NO) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.RelayboardStestFail = YES; } if (ShmFanModuleData->SelfTest_Comp == NO) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FanboardStestFail = YES; } if (ShmPrimaryMcuData->SelfTest_Comp == NO) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PrimaryStestFail = YES; } for (byte index = 0; index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; index++) { if (chargingInfo[index]->Type == _Type_Chademo) { if (ShmCHAdeMOData->evse[chargingInfo[index]->type_index].SelfTest_Comp == NO) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.ChademoboardStestFail = YES; } } else if (chargingInfo[index]->Type == _Type_CCS_2) { if (ShmCcsData->CommProtocol == 0x01) { if (ShmCcsData->V2GMessage_DIN70121[chargingInfo[index]->type_index].SelfTest_Comp == NO) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CCSboardStestFail = YES; } } } } if (ShmSysConfigAndInfo->SysInfo.AcContactorStatus == NO) { // AC Contact 未搭上 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.AcContactStestFail = YES; } else { // PSU 通訊問題 ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuModuleStestFail = YES; } } void SelfTestRun() { bool evInitFlag = false; StartSystemTimeoutDet(Timeout_SelftestChk); ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_VERSION; while (ShmSysConfigAndInfo->SysInfo.SelfTestSeq != _STEST_COMPLETE) { ChkPrimaryStatus(); if (ShmSysConfigAndInfo->SysWarningInfo.Level == 2) { ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_FAIL; return; } if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount > 0) { if (ShmPsuData->Work_Step == _NO_WORKING || ShmSysConfigAndInfo->SysInfo.SelfTestSeq == _STEST_FAIL) { ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_FAIL; return; } switch(ShmSysConfigAndInfo->SysInfo.SelfTestSeq) { case _STEST_VERSION: { if (strlen((char *)ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev) != 0 || ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev[0] != '\0') { //PRINTF_FUNC("RB pass \n"); ShmRelayModuleData->SelfTest_Comp = YES; } if (strlen((char *)ShmSysConfigAndInfo->SysInfo.FanModuleFwRev) != 0 || ShmSysConfigAndInfo->SysInfo.FanModuleFwRev[0] != '\0') { //PRINTF_FUNC("Fan pass \n"); ShmFanModuleData->SelfTest_Comp = YES; } if (strlen((char *)ShmPrimaryMcuData->version) != 0 || ShmPrimaryMcuData->version[0] != '\0') { //PRINTF_FUNC("407 pass \n"); ShmPrimaryMcuData->SelfTest_Comp = YES; } // EV 小板 if (!evInitFlag) { evInitFlag = YES; for (byte index = 0; index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; index++) { if (chargingInfo[index]->Type == _Type_Chademo) { if (strlen((char *)ShmCHAdeMOData->evse[chargingInfo[index]->type_index].version) != 0 || ShmCHAdeMOData->evse[chargingInfo[index]->type_index].version[0] != '\0') { //PRINTF_FUNC("chademo pass \n"); ShmCHAdeMOData->evse[chargingInfo[index]->type_index].SelfTest_Comp = YES; } else { //PRINTF_FUNC("chademo fw lose...... %s \n", ShmCHAdeMOData->evse[chargingInfo[index]->type_index].version); evInitFlag = NO; } } else if (chargingInfo[index]->Type == _Type_CCS_2) { if (ShmCcsData->CommProtocol == 0x01) { if (strlen((char *)ShmCcsData->V2GMessage_DIN70121[chargingInfo[index]->type_index].version) != 0 || ShmCcsData->V2GMessage_DIN70121[chargingInfo[index]->type_index].version[0] != '\0') { //PRINTF_FUNC("ccs fw = %s \n", ShmCcsData->V2GMessage_DIN70121[chargingInfo[index]->type_index].version); ShmCcsData->V2GMessage_DIN70121[chargingInfo[index]->type_index].SelfTest_Comp = YES; } else { //PRINTF_FUNC("ccs fw lose...... %s \n", ShmCcsData->V2GMessage_DIN70121[chargingInfo[index]->type_index].version); evInitFlag = NO; } } } } } if (ShmFanModuleData->SelfTest_Comp && ShmRelayModuleData->SelfTest_Comp && ShmPrimaryMcuData->SelfTest_Comp && evInitFlag) { ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_AC_CONTACTOR; } } break; case _STEST_AC_CONTACTOR: { //ShmPsuData->Work_Step = _TEST_COMPLETE; // 因為 30KW 以下沒有 Relay feedback 功能,所以暫時先直接跳過 if (ShmSysConfigAndInfo->SysInfo.AcContactorStatus == YES) { ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_PSU_DETECT; PRINTF_FUNC("Communication board pass. \n"); } } break; case _STEST_PSU_DETECT: { if (ShmPsuData->Work_Step >= GET_SYS_CAP) { ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_PSU_CAP; } } break; case _STEST_PSU_CAP: { // 此測試是要確認當前總輸出能力 // 如果沒有 PSU 模組請 bypass if (ShmPsuData->Work_Step == BOOTING_COMPLETE) { sleep(1); ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_COMPLETE; ShmSysConfigAndInfo->SysInfo.BootingStatus = BOOT_COMPLETE; } } break; } } else break; usleep(100000); } } int SpawnTask() { system("/root/Module_EventLogging &"); system("/root/Module_PrimaryComm &"); system("/root/Module_EvComm &"); system("/root/Module_LcmControl &"); system("/root/Module_InternalComm &"); system("/root/Module_PsuComm &"); system("/root/Module_Modbus &"); if(strcmp((char *)ShmSysConfigAndInfo->SysConfig.OcppServerURL, "") != EQUAL && strcmp((char *)ShmSysConfigAndInfo->SysConfig.ChargeBoxId, "") != EQUAL) { system("/root/OcppBackend &"); } if(ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'T') { system("/root/Module_4g &"); } else if(ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'W') { system("/root/Module_Wifi &"); } return PASS; } 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; i 0) { wrd=write(fd, BufTmp, MtdBlockSize); close(fd); if(wrd >= MtdBlockSize) { fd = open("/dev/mtdblock11", O_RDWR); if (fd > 0) { wrd=write(fd, BufTmp, MtdBlockSize); close(fd); if(wrd < MtdBlockSize) { DEBUG_ERROR_MSG("write /dev/mtdblock11(backup) NG\r\n"); result = FAIL; } } else { DEBUG_ERROR_MSG("open /dev/mtdblock11(backup) NG\r\n"); result = FAIL; } } else { DEBUG_ERROR_MSG("write /dev/mtdblock10 NG\r\n"); result = FAIL; } } else { DEBUG_ERROR_MSG("open /dev/mtdblock10 NG\r\n"); result = FAIL; } } else { DEBUG_ERROR_MSG("alloc BlockSize NG\r\n"); result = FAIL; } if(BufTmp != NULL) free(BufTmp); return result; } //=============================================== // Common Detect Chk - Stop Charging ? //=============================================== bool isEvBoardStopChargeFlag(byte gunIndex) { return chargingInfo[gunIndex]->StopChargeFlag; } //=============================================== // 掃描插槍狀況 //=============================================== void ClearDetectPluginFlag() { ShmSysConfigAndInfo->SysInfo.WaitForPlugit = NO; } void DetectPluginStart() { ShmSysConfigAndInfo->SysInfo.WaitForPlugit = YES; } bool isDetectPlugin() { if(ShmSysConfigAndInfo->SysInfo.WaitForPlugit == YES) return YES; return NO; } //=============================================== // Common Detect Chk - Chademo //=============================================== bool isEvGunLocked_chademo(byte gunIndex) { return (DetectBitValue(chargingInfo[gunIndex]->GunLocked , 0) == 0)? NO : YES; } bool isEvContactorWelding_chademo(byte gunIndex) { return DetectBitValue(ShmCHAdeMOData->ev[chargingInfo[gunIndex]->type_index].EvDetection, 3); } bool isEvStopReq_chademo(byte gunIndex) { return DetectBitValue(ShmCHAdeMOData->ev[chargingInfo[gunIndex]->type_index].EvDetection, 4); } bool isEvStopCharging_chademo(byte gunIndex) { if (isEvGunLocked_chademo(gunIndex) == NO) { // 無鎖槍 = 停止 PRINTF_FUNC("gun locked none. \n"); return YES; } return NO; } byte isPrechargeStatus_chademo(byte gunIndex) { byte result = 0x00; result = ShmCHAdeMOData->ev[chargingInfo[gunIndex]->type_index].PresentMsgFlowStatus; return result; } //=============================================== // Common Detect Chk - CCS //=============================================== bool isEvGunLocked_ccs(byte gunIndex) { return (DetectBitValue(chargingInfo[gunIndex]->GunLocked , 0) == 0)? NO : YES; } byte isPrechargeStatus_ccs(byte gunIndex) { byte result = 0x00; if (ShmCcsData->CommProtocol == 0x01) { result = ShmCcsData->V2GMessage_DIN70121[chargingInfo[gunIndex]->type_index].PresentMsgFlowStatus; } return result; } bool isEvStopCharging_ccs(byte gunIndex) { if (isEvGunLocked_ccs(gunIndex) == NO) { // 無鎖槍 = 停止 PRINTF_FUNC("gun locked none. \n"); return YES; } return NO; } //=============================================== // Callback //=============================================== void DisplayChargingInfo() { PRINTF_FUNC("*********** DisplayChargingInfo *********** \n"); for (byte i = ShmSysConfigAndInfo->SysConfig.TotalConnectorCount - 1; i >= 0; i--) { if (chargingInfo[i]->SystemStatus != S_IDLE) { ShmSysConfigAndInfo->SysInfo.CurGunSelected = i; break; } } usleep(50000); ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } void _AutoReturnTimeout() { PRINTF_FUNC("*********** _AutoReturnTimeout *********** \n"); if (ShmSysConfigAndInfo->SysInfo.PageIndex == _LCM_WAIT_FOR_PLUG) { ClearDetectPluginFlag(); } else if (ShmSysConfigAndInfo->SysInfo.PageIndex == _LCM_AUTHORIZ_COMP) { DetectPluginStart(); } usleep(50000); ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } void _SelfTestTimeout() { if (ShmSysConfigAndInfo->SysInfo.BootingStatus != BOOT_COMPLETE) { for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index++) { setChargerMode(gun_index, MODE_ALARM); } } ShmPsuData->Work_Step = _NO_WORKING; ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_FAIL; PRINTF_FUNC("Self test timeout. \n"); } void _AuthorizedTimeout() { if(IsAuthorizingMode()) { PRINTF_FUNC("*********** _AuthorizedTimeout *********** \n"); isCardScan = false; ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_AUTHORIZ_FAIL; //ChangeLcmByIndex(_LCM_AUTHORIZ_FAIL); strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); ClearAuthorizedFlag(); } } void _DetectPlugInTimeout() { PRINTF_FUNC("*********** _DetectPlugInTimeout *********** \n"); strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); ClearDetectPluginFlag(); usleep(50000); ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } void _DetectEvChargingEnableTimeout(byte gunIndex) { if (chargingInfo[gunIndex]->Type == _Type_Chademo) { if(!isEvGunLocked_chademo(gunIndex)) { PRINTF_FUNC("*********** _DetectEvChargingEnableTimeout (chademo) ***********\n"); ChargingTerminalProcess(gunIndex); _AutoReturnTimeout(); } } else if (chargingInfo[gunIndex]->Type == _Type_CCS_2) { if(!isEvGunLocked_ccs(gunIndex)) { PRINTF_FUNC("*********** _DetectEvChargingEnableTimeout (ccs) ***********\n"); ChargingTerminalProcess(gunIndex); _AutoReturnTimeout(); } } } void _DetectEvseChargingEnableTimeout(byte gunIndex) { PRINTF_FUNC("*********** _DetectEvseChargingEnableTimeout (GFD timeout) ***********\n"); //if (chargingInfo[gunIndex]->GroundFaultStatus != GFD_PASS) { setChargerMode(gunIndex, MODE_IDLE); _AutoReturnTimeout(); } } void _PrepareTimeout(byte gunIndex) { PRINTF_FUNC("*********** _PrechargeTimeout ***********\n"); setChargerMode(gunIndex, MODE_IDLE); ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuNoResource = NO; _AutoReturnTimeout(); } void _CcsPrechargeTimeout(byte gunIndex) { PRINTF_FUNC("*********** _CcsPrechargeTimeout ***********\n"); setChargerMode(gunIndex, MODE_IDLE); } //=============================================== // 取得卡號與卡號驗證 //=============================================== bool canStartCharging() { char buf2[16] = ""; memset(buf2, 0, ARRAY_SIZE(buf2)); for (byte index = 0; index < strlen((char *)ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status); index++) { sprintf(buf2 + (index - 1) * 2, "%02X", ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status[index]); } sprintf(buf2, "%s", ShmOCPP16Data->Authorize.ResponseIdTagInfo.Status); // 因為無法得知實際的長度,所以只能用搜尋的方式 if(strcmp(buf2, "Accepted") == EQUAL) return true; else { } return false; } void AuthorizingStart() { ShmOCPP16Data->SpMsg.bits.AuthorizeReq = YES; ShmSysConfigAndInfo->SysInfo.AuthorizeFlag = YES; } void ClearAuthorizedFlag() { ShmOCPP16Data->SpMsg.bits.AuthorizeReq = NO; ShmOCPP16Data->SpMsg.bits.AuthorizeConf = NO; ShmSysConfigAndInfo->SysInfo.AuthorizeFlag = NO; } bool isAuthorizedComplete() { if (ShmOCPP16Data->SpMsg.bits.AuthorizeConf == NO) return false; return true; } bool IsAuthorizingMode() { if(ShmSysConfigAndInfo->SysInfo.AuthorizeFlag == NO) return false; return true; } //=============================================== // 紀錄 Alarm Code //=============================================== void RecordAlarmCode(char *code) { if (strcmp(code, "012234") == 0) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.ChademoGfdTrip = YES; if (strcmp(code, "012235") == 0) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CcsGfdTrip = YES; if (strcmp(code, "012288") == 0) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CcsOutputUVPFail = YES; if (strcmp(code, "012289") == 0) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.ChademoOutputUVPFail = YES; } void ReleaseAlarmCode(byte gunIndex) { if (chargingInfo[gunIndex]->Type == _Type_Chademo) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.ChademoGfdTrip = NO; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.ChademoOutputUVPFail = NO; } else if (chargingInfo[gunIndex]->Type == _Type_CCS_2) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CcsGfdTrip = NO; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CcsOutputUVPFail = NO; } } //=============================================== // EmergencyStop and Charging Stop //=============================================== void ChargingTerminalProcess(byte gunIndex) { setChargerMode(gunIndex, MODE_TERMINATING); } void StopChargingProcessByString(byte level) { if (level > ShmSysConfigAndInfo->SysWarningInfo.Level) { ShmSysConfigAndInfo->SysWarningInfo.Level = level; } } void ReleaseChargingProcessByString(byte level) { if (level >= ShmSysConfigAndInfo->SysWarningInfo.Level) ShmSysConfigAndInfo->SysWarningInfo.Level = 0; } // 一般錯誤停止充電處理函式 void BoardErrOccurByString(byte index, char *code) { byte level = 1; if ((chargingInfo[index]->SystemStatus > S_IDLE && chargingInfo[index]->SystemStatus < S_TERMINATING) || (chargingInfo[index]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[index]->SystemStatus <= S_CCS_PRECHARGE_ST1)) { if (strncmp(code, "023730", 6) == EQUAL && ShmStatusCodeData->InfoCode.InfoEvents.bits.ChademoChargerGetEmergencyStop == NO) { ShmStatusCodeData->InfoCode.InfoEvents.bits.ChademoChargerGetEmergencyStop = YES; } ChargingTerminalProcess(index); } StopChargingProcessByString(level); } // 急停狀況的停止充電處理函式 void EmcOccureByString(char *code) { byte level = 2; // 嚴重的急停有四種 : EMC 按鈕、Mainbreak、Dooropen、SPD Trip // 其錯誤等級為 2 if (strncmp(code, "012251", 6) == EQUAL || strncmp(code, "012252", 6) == EQUAL || strncmp(code, "012237", 6) == EQUAL || strncmp(code, "012238", 6) == EQUAL) { for (byte gun = 0; gun < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun++) { if ((chargingInfo[gun]->SystemStatus > S_IDLE && chargingInfo[gun]->SystemStatus < S_TERMINATING) || (chargingInfo[gun]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[gun]->SystemStatus <= S_CCS_PRECHARGE_ST1)) { ChargingTerminalProcess(gun); } StopChargingProcessByString(level); } } } void ReleaseBoardErrOccurByString(byte index, char *code) { bool isTrigger = false; byte level = 1; if (strncmp(code, "023730", 6) == 0 && ShmStatusCodeData->InfoCode.InfoEvents.bits.ChademoChargerGetEmergencyStop == YES) { isTrigger = true; ShmStatusCodeData->InfoCode.InfoEvents.bits.ChademoChargerGetEmergencyStop = NO; } if (isTrigger) { ReleaseChargingProcessByString(level); } } void ReleaseEmsOccureByString(byte index, char *code) { bool isTrigger = false; byte level = 2; if (strncmp(code, "012251", 6) == 0 && ShmStatusCodeData->AlarmCode.AlarmEvents.bits.EmergencyStopTrip == YES) { isTrigger = true; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.EmergencyStopTrip = NO; } else if (strncmp(code, "012252", 6) == 0 && ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DoorOpen == YES) { isTrigger = true; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DoorOpen = NO; } else if (strncmp(code, "012237", 6) == 0 && ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SpdTrip == YES) { isTrigger = true; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SpdTrip = NO; } else if (strncmp(code, "012238", 6) == 0 && ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MainPowerBreakerTrip == YES) { isTrigger = true; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MainPowerBreakerTrip = NO; } if (isTrigger) { ReleaseChargingProcessByString(level); } } //=============================================== // 確認硬體 (按鈕) 狀態 //=============================================== bool leftBtnPush = false; bool rightBtnPush = false; void ChkPrimaryStatus() { if (ShmPrimaryMcuData->InputDet.bits.EmergencyButton == ABNORMAL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.EmergencyStopTrip = YES; EmcOccureByString("012251"); } else ReleaseEmsOccureByString(0, "012251"); if (ShmPrimaryMcuData->InputDet.bits.AcMainBreakerDetec == ABNORMAL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MainPowerBreakerTrip = YES; EmcOccureByString("012238"); } else ReleaseEmsOccureByString(0, "012238"); if (ShmPrimaryMcuData->InputDet.bits.SpdDetec == ABNORMAL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SpdTrip = YES; EmcOccureByString("012237"); } else ReleaseEmsOccureByString(0, "012237"); if (ShmPrimaryMcuData->InputDet.bits.DoorOpen == ABNORMAL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DoorOpen = YES; EmcOccureByString("012252"); } else ReleaseEmsOccureByString(0, "012252"); if (ShmPrimaryMcuData->InputDet.bits.Button1 == BTN_PRESS && !leftBtnPush) { if(!leftBtnPush) { leftBtnPush = true; PRINTF_FUNC("left btn down............................... \n"); if (ShmSysConfigAndInfo->SysInfo.CurGunSelected + 1 < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount) ShmSysConfigAndInfo->SysInfo.CurGunSelected += 1; else ShmSysConfigAndInfo->SysInfo.CurGunSelected = 0; } // 左邊的選槍按鈕,只有在雙槍都在充電時候才有用 : 30KW 以下該按鈕無作用 } else if (ShmPrimaryMcuData->InputDet.bits.Button1 == BTN_RELEASE) { if(leftBtnPush) { leftBtnPush = false; PRINTF_FUNC("left btn up............................... \n"); } } if (ShmPrimaryMcuData->InputDet.bits.Button2 == BTN_PRESS && !rightBtnPush) { if(!rightBtnPush) { rightBtnPush = true; PRINTF_FUNC("right btn down............................... %d \n", ShmSysConfigAndInfo->SysInfo.CurGunSelected); switch(chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus) { case S_IDLE: { if(isDetectPlugin()) { _DetectPlugInTimeout(); StopSystemTimeoutDet(); } } break; case S_PREPARNING: case S_PREPARING_FOR_EV: case S_PREPARING_FOR_EVSE: case S_CCS_PRECHARGE_ST0: case S_CCS_PRECHARGE_ST1: { // 取消充電 ChargingTerminalProcess(ShmSysConfigAndInfo->SysInfo.CurGunSelected); } break; case S_CHARGING: { if (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == _SYS_AUTHORIZE_FREE) { // 停止充電 ChargingTerminalProcess(ShmSysConfigAndInfo->SysInfo.CurGunSelected); } } break; case S_COMPLETE: { // 回 IDLE //PRINTF_FUNC("right btn down.................S_COMPLETE \n"); //chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = S_IDLE; } break; } } } else if (ShmPrimaryMcuData->InputDet.bits.Button2 == BTN_RELEASE) { if(rightBtnPush) { rightBtnPush = false; PRINTF_FUNC("right btn up............................... \n"); } } } //=============================================== // 確認各小板偵測的錯誤狀況 //=============================================== void CheckErrorOccurStatus(byte index) { // 小板 if (chargingInfo[index]->Type == _Type_Chademo) { if (ShmStatusCodeData->FaultCode.FaultEvents.bits.ChademoOutputRelayDrivingFault == YES) BoardErrOccurByString(index, "011012"); else if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.ChademoGfdTrip == YES) BoardErrOccurByString(index, "012234"); } else if (chargingInfo[index]->Type == _Type_CCS_2) { if (ShmStatusCodeData->FaultCode.FaultEvents.bits.CcsOutputRelayDrivingFault == YES) BoardErrOccurByString(index, "011014"); else if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CcsGfdTrip == YES) BoardErrOccurByString(index, "012235"); } // RB if (ShmSysConfigAndInfo->SysConfig.PhaseLossPolicy == YES) { if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP == YES || ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP == YES || ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP == YES) { if (ShmSysConfigAndInfo->SysWarningInfo.ExtraErrProcess == _EXTRA_ERR_PROCESS_NONE) { ShmSysConfigAndInfo->SysWarningInfo.ExtraErrProcess = _EXTRA_ERR_PROCESS_INUVP; StopChargingProcessByString(2); } } else { if (ShmSysConfigAndInfo->SysWarningInfo.ExtraErrProcess == _EXTRA_ERR_PROCESS_INUVP) { ShmSysConfigAndInfo->SysWarningInfo.ExtraErrProcess = _EXTRA_ERR_PROCESS_NONE; ReleaseChargingProcessByString(2); } } } } //=============================================== // 確認 GPIO 狀態 //=============================================== void gpio_set_value(unsigned int gpio, unsigned int value) { int fd; char buf[MAX_BUF]; snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio); fd = open(buf, O_WRONLY); if (fd < 0) { perror("gpio/set-value"); return; } if (value) write(fd, "1", 2); else write(fd, "0", 2); close(fd); } int gpio_get_value(unsigned int gpio, unsigned int *value) { int fd; char buf[MAX_BUF]; char ch; snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio); fd = open(buf, O_RDONLY); if (fd < 0) { perror("gpio/get-value"); return fd; } read(fd, &ch, 1); if (ch != '0') { *value = 1; } else { *value = 0; } close(fd); return 0; } void CheckGunTypeFromHw() { int pinIn[4] = { 22, 23, 44, 45 }; unsigned int gpioValue = 0; for (int i = 0; i < ARRAY_SIZE(pinIn); i++) { gpio_get_value(pinIn[i], &gpioValue); { switch (pinIn[i]) { case 22: bd1_1_status = gpioValue; break; case 23: bd1_2_status = gpioValue; break; case 44: bd0_1_status = gpioValue; break; case 45: bd0_2_status = gpioValue; break; } } } } void CheckGpioInStatus() { int pinIn[2] = { 27, 47 }; unsigned int gpioValue = 0; for (int i = 0; i < ARRAY_SIZE(pinIn); i++) { gpio_get_value(pinIn[i], &gpioValue); if (gpioValue == 0x01) { switch(pinIn[i]) { // 小板緊急停止 case 47: { for(int i = 0; i < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; i++) { if (chargingInfo[i]->slotsIndex == 1) { if (chargingInfo[i]->Type == _Type_Chademo) BoardErrOccurByString(i, "023730"); else if (chargingInfo[i]->Type == _Type_CCS_2) BoardErrOccurByString(i, "013627"); break; } } } break; case 27: { for(int i = 0; i < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; i++) { if (chargingInfo[i]->slotsIndex == 3) { if (chargingInfo[i]->Type == _Type_Chademo) BoardErrOccurByString(i, "023730"); else if (chargingInfo[i]->Type == _Type_CCS_2) BoardErrOccurByString(i, "013627"); break; } } } break; } } else { switch (pinIn[i]) { // 小板解除緊急停止 case 47: { for(int i = 0; i < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; i++) { if (chargingInfo[i]->slotsIndex == 1) { if (chargingInfo[i]->Type == _Type_Chademo) ReleaseBoardErrOccurByString(i, "023730"); else if (chargingInfo[i]->Type == _Type_CCS_2) ReleaseBoardErrOccurByString(i, "013627"); break; } } } break; case 27: { for (int i = 0; i < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; i++) { if (chargingInfo[i]->slotsIndex == 3) { if (chargingInfo[i]->Type == _Type_Chademo) ReleaseBoardErrOccurByString(i, "023730"); else if (chargingInfo[i]->Type == _Type_CCS_2) ReleaseBoardErrOccurByString(i, "013627"); break; } } } break; } } } } //=============================================== // Main process //=============================================== // 檢查 Byte 中某個 Bit 的值 // _byte : 欲改變的 byte // _bit : 該 byte 的第幾個 bit unsigned char DetectBitValue(unsigned char _byte, unsigned char _bit) { return ( _byte & mask_table[_bit] ) != 0x00; } // 設定 Byte 中某個 Bit的值 // _byte : 欲改變的 byte // _bit : 該 byte 的第幾個 bit // value : 修改的值為 0 or 1 void SetBitValue(unsigned char *_byte, unsigned char _bit, unsigned char value) { if(value == 1) *_byte |= (1 << _bit); else if (value == 0) *_byte ^= (1 << _bit); } void UserScanFunction() { bool idleReq = false; unsigned char stopReq = 255; // 當前非驗證的狀態 if(!IsAuthorizingMode()) { // 先判斷現在是否可以提供刷卡 // 1. 如果當前沒有槍是閒置狀態,則無提供刷卡功能 // 2. 停止充電 for (byte i = 0; i < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; i++) { // 二擇一 if (ShmSysConfigAndInfo->SysInfo.PageIndex == _LCM_FIX || (chargingInfo[i]->SystemStatus >= S_AUTHORIZING && chargingInfo[i]->SystemStatus <= S_PREPARNING) || (chargingInfo[i]->SystemStatus >= S_TERMINATING && chargingInfo[i]->SystemStatus < S_COMPLETE)) { strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); return; } if (chargingInfo[i]->SystemStatus == S_CHARGING) { stopReq = i; } else if (chargingInfo[i]->SystemStatus == S_IDLE && chargingInfo[i]->IsAvailable == YES) { idleReq = true; } } if (strlen((char *)ShmSysConfigAndInfo->SysConfig.UserId) > 0) { if (stopReq < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount && chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus == S_CHARGING) { char value[32]; PRINTF_FUNC("stop charging \n"); PRINTF_FUNC("index = %d, card number = %s, UserId = %s \n", ShmSysConfigAndInfo->SysInfo.CurGunSelected, chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->StartUserId, ShmSysConfigAndInfo->SysConfig.UserId); memcpy(value, (unsigned char *)chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->StartUserId, ARRAY_SIZE(chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->StartUserId)); if (strcmp((char *)ShmSysConfigAndInfo->SysConfig.UserId, value) == EQUAL) { ChargingTerminalProcess(ShmSysConfigAndInfo->SysInfo.CurGunSelected); } strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); } else if (chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus == S_COMPLETE) { strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); } else if (idleReq) { if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount > 1 && stopReq != 255 && ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES) { idleReq = false; strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); } else { PRINTF_FUNC("// LCM => Authorizing \n"); // LCM => Authorizing ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_AUTHORIZING; // 進入確認卡號狀態 AuthorizingStart(); } } else { strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); } } } } unsigned char isModeChange(unsigned char gun_index) { unsigned char result = NO; if(chargingInfo[gun_index]->SystemStatus != chargingInfo[gun_index]->PreviousSystemStatus) { result = YES; chargingInfo[gun_index]->PreviousSystemStatus = chargingInfo[gun_index]->SystemStatus; } return result; } void ScannerCardProcess() { if (!isDetectPlugin() && !isCardScan && ShmSysConfigAndInfo->SysWarningInfo.Level == 0 && ShmSysConfigAndInfo->SysConfig.AuthorisationMode == _SYS_AUTHORIZE_OCPP) { isCardScan = true; // 處理刷卡及驗證卡號的動作 UserScanFunction(); } if (ShmSysConfigAndInfo->SysInfo.PageIndex == _LCM_AUTHORIZING) { StartSystemTimeoutDet(Timeout_Authorizing); // 確認驗證卡號完成沒 if (isAuthorizedComplete() || ShmSysConfigAndInfo->SysConfig.OfflinePolicy == _OFFLINE_POLICY_FREE_CHARGING) { StopSystemTimeoutDet(); // 判斷後台回覆狀態 if(canStartCharging() || ShmSysConfigAndInfo->SysConfig.OfflinePolicy == _OFFLINE_POLICY_FREE_CHARGING) { // LCM => Authorize complete ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_AUTHORIZ_COMP; } else { // LCM => Authorize fail ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_AUTHORIZ_FAIL; } ClearAuthorizedFlag(); } else if (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == _OFFLINE_POLICY_LOCAL_LIST) { // 白名單驗證 for (int i = 0; i < 10; i++) { if (strcmp((char *)ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[i], "") != EQUAL) { if (strcmp((char *)ShmSysConfigAndInfo->SysConfig.LocalWhiteCard[i], (char *)ShmSysConfigAndInfo->SysConfig.UserId) == EQUAL) { ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_AUTHORIZ_COMP; ClearAuthorizedFlag(); break; } } } } } else if (ShmSysConfigAndInfo->SysInfo.PageIndex == _LCM_AUTHORIZ_FAIL) { StartSystemTimeoutDet(Timeout_VerifyFail); isCardScan = false; } else if(ShmSysConfigAndInfo->SysInfo.PageIndex == _LCM_AUTHORIZ_COMP) { StartSystemTimeoutDet(Timeout_VerifyComp); } else if(ShmSysConfigAndInfo->SysInfo.PageIndex == _LCM_WAIT_FOR_PLUG) { StartSystemTimeoutDet(Timeout_WaitPlug); } else isCardScan = false; } void AddGunInfoByConnector(byte typeValue, byte slots) { switch (typeValue) { case '0': // none break; case '1': // IEC 62196-2 Type 1/SAE J1772 Plug break; case '2': // IEC 62196-2 Type 1/SAE J1772 Socket break; case '3': // IEC 62196-2 Type 2 Plug break; case '4': // IEC 62196-2 Type 2 Socket break; case '5': // GB/T AC Plug break; case '6': // GB/T AC Socket break; case 'J': // CHAdeMO { if (CHAdeMO_QUANTITY > _chademoIndex) { chargingInfo[_gunIndex] = &ShmSysConfigAndInfo->SysInfo.ChademoChargingData[_chademoIndex]; chargingInfo[_gunIndex]->Index = _gunIndex; chargingInfo[_gunIndex]->slotsIndex = slots; chargingInfo[_gunIndex]->SystemStatus = S_BOOTING; chargingInfo[_gunIndex]->Type = _Type_Chademo; chargingInfo[_gunIndex]->type_index = _chademoIndex; chargingInfo[_gunIndex]->IsAvailable = YES; _chademoIndex++; _gunIndex++; } } break; case 'U': // CCS1 combo case 'E': // CCS2 combo { if (CCS_QUANTITY > _ccsIndex) { chargingInfo[_gunIndex] = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[_ccsIndex]; chargingInfo[_gunIndex]->Index = _gunIndex; chargingInfo[_gunIndex]->slotsIndex = slots; chargingInfo[_gunIndex]->SystemStatus = S_BOOTING; chargingInfo[_gunIndex]->Type = _Type_CCS_2; chargingInfo[_gunIndex]->type_index = _ccsIndex; chargingInfo[_gunIndex]->IsAvailable = YES; // 現階段預設為走 DIN70121 ShmCcsData->CommProtocol = 0x01; _ccsIndex++; _gunIndex++; } } break; case 'G': // GBT DC { if (GB_QUANTITY > _gb_Index) { chargingInfo[_gunIndex] = &ShmSysConfigAndInfo->SysInfo.GbChargingData[_gb_Index]; chargingInfo[_gunIndex]->Index = _gunIndex; chargingInfo[_gunIndex]->slotsIndex = slots; chargingInfo[_gunIndex]->SystemStatus = S_BOOTING; chargingInfo[_gunIndex]->Type = _Type_GB; chargingInfo[_gunIndex]->type_index = _gb_Index; chargingInfo[_gunIndex]->IsAvailable = YES; _gb_Index++; _gunIndex++; } } break; case 'D': // GBT DC x 2 break; } } bool CheckConnectorTypeStatus() { bool result = true; PRINTF_FUNC("bd0_1_status = %d, bd0_2_status = %d, bd1_1_status = %d, bd1_2_status = %d \n", bd0_1_status, bd0_2_status, bd1_1_status, bd1_2_status); if (strlen((char *) ShmSysConfigAndInfo->SysConfig.ModelName) >= 9) { byte slots = 1; for (byte typeIndex = 7; typeIndex <= 9; typeIndex++) { AddGunInfoByConnector(ShmSysConfigAndInfo->SysConfig.ModelName[typeIndex], slots); slots++; } ShmSysConfigAndInfo->SysConfig.TotalConnectorCount = _gunIndex; PRINTF_FUNC("_gunCount = %d \n", ShmSysConfigAndInfo->SysConfig.TotalConnectorCount); if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount == 0) result = false; // 偵測槍屬於哪個 slot : 可知道插在板上的Slot 0 或 1 是 Chademo 還是 CCS for (byte gunIndex = 0; gunIndex < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gunIndex++) { if (bd0_1_status == 0 && bd0_2_status == 1) { // 與硬體相同 type : Chademo if (chargingInfo[gunIndex]->Type == _Type_Chademo) { chargingInfo[gunIndex]->Evboard_id = 0x01; } } else if (bd0_1_status == 1 && bd0_2_status == 0) { // 與硬體相同 type : CCS if (chargingInfo[gunIndex]->Type == _Type_CCS_2) { chargingInfo[gunIndex]->Evboard_id = 0x01; } } if (bd1_1_status == 0 && bd1_2_status == 1) { // 與硬體相同 type : Chademo if (chargingInfo[gunIndex]->Type == _Type_Chademo) { chargingInfo[gunIndex]->Evboard_id = 0x02; } if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount == 1) chargingInfo[gunIndex]->Evboard_id = 0x01; } else if (bd1_1_status == 1 && bd1_2_status == 0) { // 與硬體相同 type : CCS if (chargingInfo[gunIndex]->Type == _Type_CCS_2) { chargingInfo[gunIndex]->Evboard_id = 0x02; } if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount == 1) chargingInfo[gunIndex]->Evboard_id = 0x01; } PRINTF_FUNC("index = %d, Type = %d, Evboard_id = %d \n", gunIndex, chargingInfo[gunIndex]->Type, chargingInfo[gunIndex]->Evboard_id); if (chargingInfo[gunIndex]->Evboard_id == 0x00) result = false; } } else { // Module Name 不正確 - 告警 result = false; } return result; } void KillTask() { ChangeLcmByIndex(_LCM_FIX); system("killall Module_EventLogging"); system("killall Module_PrimaryComm"); system("killall Module_EvComm"); system("killall Module_LcmControl"); system("killall Module_InternalComm"); system("killall Module_PsuComm"); system("killall OcppBackend &"); system("killall Module_4g &"); system("killall Module_Wifi &"); } char CheckUpdateProcess() { DIR *d; struct dirent *dir; d = opendir("/mnt/"); if (d) { long int MaxLen=48*1024*1024, ImageLen = 0; while ((dir = readdir(d)) != NULL) { char *new_str; new_str = malloc(strlen("/mnt/")+strlen(dir->d_name)+1); new_str[0] = '\0'; strcat(new_str, "/mnt/"); strcat(new_str, dir->d_name); int fd = open(new_str, O_RDONLY); if (fd < 0) { return FAIL; } unsigned char *ptr = malloc(MaxLen); //-48 is take out the header memset(ptr, 0xFF, MaxLen); //-48 is take out the header //get the image length ImageLen = read(fd, ptr, MaxLen); if (ImageLen > 20) { unsigned int Type = (((unsigned int)ptr[16])<<24 | ((unsigned int)ptr[17])<<16 | ((unsigned int)ptr[18])<<8 | ((unsigned int)ptr[19])); PRINTF_FUNC("Typed...%x \r\n", Type); switch (Type) { case 0x10000001: case 0x10000002: case 0x10000003: case 0x10000004: case 0x10000005: { if (Upgrade_Flash(Type, new_str, ShmSysConfigAndInfo->SysConfig.ModelName) == PASS) return PASS; else return FAIL; } break; case 0x10000007: case 0x10000008: case 0x10000009: case 0x1000000A: { } break; case 0x10000006: case 0x1000000D: case 0x1000000E: { // CSU_PRIMARY_CONTROLLER : 0x10000006 byte target = 0x00; if (Type == 0x10000006) target = UPGRADE_PRI; else if (Type == 0x1000000D) target = UPGRADE_RB; else if (Type == 0x1000000E) target = UPGRADE_FAN; int fd = InitComPort(target); if (Upgrade_UART(fd, Type, target, new_str, ShmSysConfigAndInfo->SysConfig.ModelName) == PASS) return PASS; else return FAIL; close(fd); } break; case 0x1000000B: case 0x1000000C: { // CHAdeMO_BOARD : 0x1000000B bool isPass = true; int CanFd = InitCanBus(); if (CanFd > 0) { for(byte index = 0; index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; index++) { if (!isPass) break; if (Type == 0x1000000B && chargingInfo[index]->Type == _Type_Chademo) { if (Upgrade_CAN(CanFd, Type, chargingInfo[index]->Evboard_id, new_str, ShmSysConfigAndInfo->SysConfig.ModelName) != PASS) { PRINTF_FUNC("Upgrad Fail. \n"); isPass = false; } } else if ((Type == 0x10000007 || Type == 0x10000008 || Type == 0x10000009 || Type == 0x1000000A) && chargingInfo[index]->Type == _Type_CCS_2) { if (Upgrade_CAN(CanFd, Type, chargingInfo[index]->Evboard_id, new_str, ShmSysConfigAndInfo->SysConfig.ModelName) != PASS) { PRINTF_FUNC("Upgrad Fail. \n"); isPass = false; } } } } else { PRINTF_FUNC("Upgrad FD fail. \n"); isPass = false; } return isPass; break; } } } free(new_str); free(ptr); } } free(dir); closedir(d); return FAIL; } void CreateRfidFork() { pid_t rfidRecPid; rfidRecPid = fork(); if (rfidRecPid == 0) { while(true) { // 刷卡判斷 RFID rfid; if (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == _OFFLINE_POLICY_NO_CHARGING) {} else if(getRequestCardSN(rfidFd, 0, &rfid)) { PRINTF_FUNC("Get Card.. \n"); if (strlen((char *)ShmSysConfigAndInfo->SysConfig.UserId) == 0) { if (ShmSysConfigAndInfo->SysConfig.RfidCardNumEndian == RFID_ENDIAN_LITTLE) { switch (rfid.snType) { case RFID_SN_TYPE_6BYTE: sprintf((char *) ShmSysConfigAndInfo->SysConfig.UserId, "%02X%02X%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3], rfid.currentCard[4], rfid.currentCard[5]); break; case RFID_SN_TYPE_7BYTE: sprintf((char *) ShmSysConfigAndInfo->SysConfig.UserId, "%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3], rfid.currentCard[4], rfid.currentCard[5], rfid.currentCard[6]); break; case RFID_SN_TYPE_10BYTE: sprintf((char *) ShmSysConfigAndInfo->SysConfig.UserId, "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3], rfid.currentCard[4], rfid.currentCard[5], rfid.currentCard[6], rfid.currentCard[7], rfid.currentCard[8], rfid.currentCard[9]); break; case RFID_SN_TYPE_4BYTE: sprintf((char *) ShmSysConfigAndInfo->SysConfig.UserId, "%02X%02X%02X%02X", rfid.currentCard[0], rfid.currentCard[1], rfid.currentCard[2], rfid.currentCard[3]); break; } } else if (ShmSysConfigAndInfo->SysConfig.RfidCardNumEndian == RFID_ENDIAN_BIG) { switch (rfid.snType) { case RFID_SN_TYPE_6BYTE: sprintf((char *) ShmSysConfigAndInfo->SysConfig.UserId, "%02X%02X%02X%02X%02X%02X", rfid.currentCard[5], rfid.currentCard[4], rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; case RFID_SN_TYPE_7BYTE: sprintf((char *) ShmSysConfigAndInfo->SysConfig.UserId, "%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[6], rfid.currentCard[5], rfid.currentCard[4], rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; case RFID_SN_TYPE_10BYTE: sprintf((char *) ShmSysConfigAndInfo->SysConfig.UserId, "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", rfid.currentCard[9], rfid.currentCard[8], rfid.currentCard[7], rfid.currentCard[6], rfid.currentCard[5], rfid.currentCard[4], rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; case RFID_SN_TYPE_4BYTE: sprintf((char *) ShmSysConfigAndInfo->SysConfig.UserId, "%02X%02X%02X%02X", rfid.currentCard[3], rfid.currentCard[2], rfid.currentCard[1], rfid.currentCard[0]); break; } } PRINTF_FUNC("card number = %s\n", ShmSysConfigAndInfo->SysConfig.UserId); } } sleep(1); } } } void StartSystemTimeoutDet(unsigned char flag) { if (ShmSysConfigAndInfo->SysInfo.SystemTimeoutFlag != flag) { gettimeofday(&ShmSysConfigAndInfo->SysInfo.SystemTimeoutTimer, NULL); } ShmSysConfigAndInfo->SysInfo.SystemTimeoutFlag = flag; } void StopSystemTimeoutDet() { gettimeofday(&ShmSysConfigAndInfo->SysInfo.SystemTimeoutTimer, NULL); ShmSysConfigAndInfo->SysInfo.SystemTimeoutFlag = Timeout_None; } void StartGunInfoTimeoutDet(unsigned char gunIndex, unsigned char flag) { if (gunIndex < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount) { if (chargingInfo[gunIndex]->TimeoutFlag != flag) { gettimeofday(&chargingInfo[gunIndex]->TimeoutTimer, NULL); } chargingInfo[gunIndex]->TimeoutFlag = flag; } } void StopGunInfoTimeoutDet(unsigned char gunIndex) { if (gunIndex < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount) { chargingInfo[gunIndex]->TimeoutFlag = Timeout_None; } } void CreateTimeoutFork() { pid_t timeoutPid; timeoutPid = fork(); if (timeoutPid > 0) { while(true) { //printf("Timeout ***********SystemTimeoutFlag = %d, ********\n", ShmSysConfigAndInfo->SysInfo.SystemTimeoutFlag); // 系統 switch(ShmSysConfigAndInfo->SysInfo.SystemTimeoutFlag) { case Timeout_SelftestChk: if (GetTimeoutValue(ShmSysConfigAndInfo->SysInfo.SystemTimeoutTimer) >= 40000000) { _SelfTestTimeout(); StopSystemTimeoutDet(); } break; case Timeout_Authorizing: if (GetTimeoutValue(ShmSysConfigAndInfo->SysInfo.SystemTimeoutTimer) >= 30000000) { _AuthorizedTimeout(); StopSystemTimeoutDet(); } break; case Timeout_VerifyFail: if (GetTimeoutValue(ShmSysConfigAndInfo->SysInfo.SystemTimeoutTimer) >= 3000000) { _AutoReturnTimeout(); StopSystemTimeoutDet(); } break; case Timeout_VerifyComp: if (GetTimeoutValue(ShmSysConfigAndInfo->SysInfo.SystemTimeoutTimer) >= 3000000) { _AutoReturnTimeout(); StopSystemTimeoutDet(); } break; case Timeout_WaitPlug: if (GetTimeoutValue(ShmSysConfigAndInfo->SysInfo.SystemTimeoutTimer) >= 40000000) { _DetectPlugInTimeout(); StopSystemTimeoutDet(); } break; case Timeout_ReturnToChargingGunDet: { if (GetTimeoutValue(ShmSysConfigAndInfo->SysInfo.SystemTimeoutTimer) >= 30000000) { DisplayChargingInfo(); StopSystemTimeoutDet(); } } break; } // 各槍 for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index++) { //printf("Timeout ***********TimeoutFlag = %d, ********\n", chargingInfo[gun_index]->TimeoutFlag); switch(chargingInfo[gun_index]->TimeoutFlag) { case Timeout_Preparing: { if (GetTimeoutValue(chargingInfo[gun_index]->TimeoutTimer) >= 30000000) { _PrepareTimeout(gun_index); StopGunInfoTimeoutDet(gun_index); } } break; case Timeout_EvChargingDet: { if (GetTimeoutValue(chargingInfo[gun_index]->TimeoutTimer) >= 120000000) { _DetectEvChargingEnableTimeout(gun_index); StopGunInfoTimeoutDet(gun_index); } } break; case Timeout_EvseChargingDet: { if (GetTimeoutValue(chargingInfo[gun_index]->TimeoutTimer) >= 30000000) { _DetectEvseChargingEnableTimeout(gun_index); StopGunInfoTimeoutDet(gun_index); } } break; case Timeout_EvseCompleteDet: { if (GetTimeoutValue(chargingInfo[gun_index]->TimeoutTimer) >= 10000000) { StopGunInfoTimeoutDet(gun_index); } } break; case Timeout_ForCcsPrechargeDet: { if (GetTimeoutValue(chargingInfo[gun_index]->TimeoutTimer) >= 60000000) { _CcsPrechargeTimeout(gun_index); StopGunInfoTimeoutDet(gun_index); } } break; } } sleep(1); } } } void GetSystemTime() { struct timeb csuTime; struct tm *tmCSU; ftime(&csuTime); tmCSU = localtime(&csuTime.time); PRINTF_FUNC("Time : %04d-%02d-%02d %02d:%02d:%02d \n", tmCSU->tm_year + 1900, tmCSU->tm_mon + 1, tmCSU->tm_mday, tmCSU->tm_hour, tmCSU->tm_min, tmCSU->tm_sec); // byte date[14]; // // // //sprintf(&date, "%d", ); // // date[0] = '0' + ((tmCSU->tm_year + 1900) / 1000 % 10); // date[0] = (tmCSU->tm_year + 1900) / 1000 % 10; // date[1] = (tmCSU->tm_year + 1900) / 100 % 10; // date[2] = (tmCSU->tm_year + 1900) / 10 % 10; // date[3] = (tmCSU->tm_year + 1900) / 1 % 10; // // date[4] = (tmCSU->tm_mon + 1) / 10 % 10; // date[5] = (tmCSU->tm_mon + 1) / 1 % 10; // // date[6] = (tmCSU->tm_mday) / 10 % 10; // date[7] = (tmCSU->tm_mday) / 1 % 10; // // date[8] = (tmCSU->tm_hour) / 10 % 10; // date[9] = (tmCSU->tm_hour) / 1 % 10; // // date[10] = (tmCSU->tm_min) / 10 % 10; // date[11] = (tmCSU->tm_min) / 1 % 10; // // date[12] = (tmCSU->tm_sec) / 10 % 10; // date[13] = (tmCSU->tm_sec) / 1 % 10; // PRINTF_FUNC("%x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x \n", date[0], date[1], date[2], date[3], // date[4], date[5], date[6], date[7], // date[8], date[9], date[10], date[11], // date[12], date[13]); } void CheckFactoryConfigFunction() { if(ShmSysConfigAndInfo->SysInfo.FactoryConfiguration) { system("cd /root;./FactoryConfig -m"); system("sync"); sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } } void CheckFwUpdateFunction() { //PRINTF_FUNC("ShmSysConfigAndInfo->SysInfo.FirmwareUpdate = %d \n", ShmSysConfigAndInfo->SysInfo.FirmwareUpdate); if (ShmSysConfigAndInfo->SysInfo.FirmwareUpdate == YES) { DEBUG_INFO_MSG("ftp : update start. \n"); KillTask(); if (CheckUpdateProcess() == PASS) DEBUG_INFO_MSG("ftp : update complete. \n"); else DEBUG_INFO_MSG("ftp : update fail. \n"); ShmSysConfigAndInfo->SysInfo.FirmwareUpdate = NO; sleep(5); system("reboot -f"); } else if(ShmOCPP16Data->MsMsg.bits.UpdateFirmwareReq == YES) { ShmOCPP16Data->MsMsg.bits.UpdateFirmwareReq = NO; } else if (strcmp((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, "Downloaded") == EQUAL) { DEBUG_INFO_MSG("Backend : update start. \n"); strcpy((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, ""); strcpy((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, "Installing"); KillTask(); if (CheckUpdateProcess() == PASS) { DEBUG_INFO_MSG("Backend : update complete. \n"); strcpy((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, ""); strcpy((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, "Installed"); } else { DEBUG_INFO_MSG("Backend : update fail. \n"); strcpy((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, ""); strcpy((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, "InstallationFailed"); } ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = YES; sleep(5); system("reboot -f"); } else if (strcmp((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, "DownloadFailed") == EQUAL) { DEBUG_ERROR_MSG("Backend to download file fail. \n"); strcpy((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, ""); strcpy((char *)ShmOCPP16Data->FirmwareStatusNotification.Status, "InstallationFailed"); ShmOCPP16Data->SpMsg.bits.FirmwareStatusNotificationReq = YES; } } //=============================================== // Check reservation date is expired //=============================================== int isReservationExpired(unsigned char gun_index) { int result = NO; struct tm expiredDate; struct timeb expiredTime; if (sscanf((char*) ShmOCPP16Data->ReserveNow[gun_index].ExpiryDate, "%4d-%2d-%2dT%2d:%2d:%2d", &expiredDate.tm_year, &expiredDate.tm_mon, &expiredDate.tm_mday, &expiredDate.tm_hour, &expiredDate.tm_min, &expiredDate.tm_sec) == 6) { expiredDate.tm_year -= 1900; expiredDate.tm_mon -= 1; expiredTime.time = mktime(&expiredDate); if (!CheckTimeOut(expiredTime)) { result = YES; } } return result; } //=============================================== // OCPP //=============================================== void CheckOcppStatus() { if (ShmOCPP16Data->SpMsg.bits.BootNotificationConf == YES) { ShmSysConfigAndInfo->SysInfo.OcppConnStatus = YES; ShmOCPP16Data->SpMsg.bits.BootNotificationConf = NO; } if (ShmOCPP16Data->MsMsg.bits.ResetReq == YES) { ShmOCPP16Data->MsMsg.bits.ResetReq = NO; if(strcmp((char *)ShmOCPP16Data->Reset.Type, "Hard") == EQUAL) { DEBUG_ERROR_MSG("****** Hard Reboot ****** \n"); sleep(3); system("reboot -f"); } else if (strcmp((char *)ShmOCPP16Data->Reset.Type, "Soft") == EQUAL) { DEBUG_ERROR_MSG("****** Soft Reboot ****** \n"); sleep(3); KillTask(); system("/usr/bin/run_evse_restart.sh"); } } } void OcppStartTransation(byte gunIndex) { if(strcmp((char *)chargingInfo[gunIndex]->StartUserId, "") == EQUAL) strcpy((char *)ShmOCPP16Data->StartTransaction[gunIndex].IdTag, (char *)ShmOCPP16Data->StartTransaction[gunIndex].IdTag); else strcpy((char *)ShmOCPP16Data->StartTransaction[gunIndex].IdTag, (char *)chargingInfo[gunIndex]->StartUserId); PRINTF_FUNC("IdTag = %s \n", ShmOCPP16Data->StartTransaction[gunIndex].IdTag); ShmOCPP16Data->CpMsg.bits[gunIndex].StartTransactionReq = YES; } void OcppStopTransation(byte gunIndex) { if(strcmp((char *)chargingInfo[gunIndex]->StartUserId, "") == EQUAL) strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].IdTag, (char *)ShmOCPP16Data->StopTransaction[gunIndex].IdTag); else strcpy((char *)ShmOCPP16Data->StopTransaction[gunIndex].IdTag, (char *)chargingInfo[gunIndex]->StartUserId); PRINTF_FUNC("IdTag = %s \n", ShmOCPP16Data->StopTransaction[gunIndex].IdTag); ShmOCPP16Data->CpMsg.bits[gunIndex].StopTransactionReq = YES; } bool OcppRemoteStop(byte gunIndex) { bool result = ShmOCPP16Data->CsMsg.bits[gunIndex].RemoteStopTransactionReq; if (ShmOCPP16Data->CsMsg.bits[gunIndex].RemoteStopTransactionReq == YES) ShmOCPP16Data->CsMsg.bits[gunIndex].RemoteStopTransactionReq = NO; return result; } void OcppRemoteStartChk() { if (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == _OFFLINE_POLICY_NO_CHARGING) {} else if(!isDetectPlugin()) { for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index++) { if ((chargingInfo[gun_index]->SystemStatus == S_IDLE || chargingInfo[gun_index]->SystemStatus == S_RESERVATION)&& ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStartTransactionReq == YES) { ShmSysConfigAndInfo->SysInfo.OrderCharging = gun_index; ShmOCPP16Data->CsMsg.bits[gun_index].RemoteStartTransactionReq = NO; DetectPluginStart(); break; } } } } void ChkOcppStatus(byte gunIndex) { if (chargingInfo[gunIndex]->SystemStatus == S_IDLE && ShmOCPP16Data->CsMsg.bits[gunIndex].ReserveNowReq == YES) { ShmOCPP16Data->CsMsg.bits[gunIndex].ReserveNowReq = NO; if (isReservationExpired(gunIndex)) { PRINTF_FUNC("***************ChkOcppStatus : OcppReservedStatus******************** \n"); DEBUG_ERROR_MSG("***************ChkOcppStatus : OcppReservedStatus******************** \n"); chargingInfo[gunIndex]->ReservationId = ShmOCPP16Data->ReserveNow[gunIndex].ReservationId; chargingInfo[gunIndex]->SystemStatus = S_RESERVATION; } } if (chargingInfo[gunIndex]->SystemStatus == S_RESERVATION && ShmOCPP16Data->CsMsg.bits[gunIndex].CancelReservationReq == YES) { ShmOCPP16Data->CsMsg.bits[gunIndex].CancelReservationReq = NO; if (isReservationExpired(gunIndex)) { PRINTF_FUNC("***************ChkOcppStatus : Cancel OcppReservedStatus******************** \n"); DEBUG_ERROR_MSG("***************ChkOcppStatus : Cancel OcppReservedStatus******************** \n"); chargingInfo[gunIndex]->ReservationId = 0; chargingInfo[gunIndex]->SystemStatus = S_IDLE; } } if (ShmOCPP16Data->CsMsg.bits[gunIndex].ChangeAvailabilityReq == YES) { PRINTF_FUNC("***************ChkOcppStatus : OcppChangeAvailability******************** \n"); DEBUG_ERROR_MSG("***************ChkOcppStatus : OcppChangeAvailability******************** \n"); ShmOCPP16Data->CsMsg.bits[gunIndex].ChangeAvailabilityReq = NO; if(strcmp((char *)ShmOCPP16Data->ChangeAvailability[gunIndex].Type, "Operative") == EQUAL) chargingInfo[gunIndex]->IsAvailable = YES; else if (strcmp((char *)ShmOCPP16Data->ChangeAvailability[gunIndex].Type, "Inoperative") == EQUAL) chargingInfo[gunIndex]->IsAvailable = NO; } } bool CheckBackendChargingTimeout(byte gunIndex) { bool result = false; if (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == _SYS_AUTHORIZE_OCPP) { if (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration > 0) { if (chargingInfo[gunIndex]->RemainChargingDuration > (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration * 60)) result = true; } } else if (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == _SYS_AUTHORIZE_FREE) { // 隨插即充電的要看 offline if (ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeDuration > 0) { if (chargingInfo[gunIndex]->RemainChargingDuration > (ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeDuration * 60)) result = true; } } return result; } bool CheckBackendChargingEnergy(byte gunIndex) { bool result = false; if (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == _SYS_AUTHORIZE_OCPP) { if (ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy > 0) { if (chargingInfo[gunIndex]->PresentChargedEnergy > ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy) result = true; } } else if (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == _SYS_AUTHORIZE_FREE) { // 隨插即充電的要看 offline if (ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeEnergy > 0) { if (chargingInfo[gunIndex]->PresentChargedEnergy > (ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeEnergy)) result = true; } } return result; } //=============================================== // Config process //=============================================== void AddPlugInTimes(byte gunIndex) { if (chargingInfo[gunIndex]->Type == _Type_Chademo) ShmSysConfigAndInfo->SysConfig.ChademoPlugInTimes += 1; else if(chargingInfo[gunIndex]->Type == _Type_CCS_2) ShmSysConfigAndInfo->SysConfig.Ccs2PlugInTimes += 1; else if(chargingInfo[gunIndex]->Type == _Type_GB) ShmSysConfigAndInfo->SysConfig.GbPlugInTimes += 1; } void ChangeStartOrStopDateTime(byte isStart, byte gunIndex) { char cmdBuf[32]; struct timeb csuTime; struct tm *tmCSU; ftime(&csuTime); tmCSU = localtime(&csuTime.time); sprintf(cmdBuf, "%04d-%02d-%02d %02d:%02d:%02d", tmCSU->tm_year + 1900, tmCSU->tm_mon + 1, tmCSU->tm_mday, tmCSU->tm_hour, tmCSU->tm_min, tmCSU->tm_sec); if (isStart) strcpy((char *)chargingInfo[gunIndex]->StartDateTime, cmdBuf); else strcpy((char *)chargingInfo[gunIndex]->StopDateTime, cmdBuf); } void zipLogFiles() { const char* logPath = "/Storage/SystemLog"; // 獲取目錄 DIR* pDir = opendir(logPath); if (pDir != NULL) { struct timeb csuTime; struct tm *tmCSU; ftime(&csuTime); tmCSU = localtime(&csuTime.time); // PRINTF_FUNC("Time : %04d-%02d-%02d %02d:%02d:%02d \n", tmCSU->tm_year + 1900, // tmCSU->tm_mon + 1, tmCSU->tm_mday, tmCSU->tm_hour, tmCSU->tm_min, // tmCSU->tm_sec); // Read items inside the folder struct dirent* pEntry = NULL; while ((pEntry = readdir(pDir)) != NULL) { if (strcmp(pEntry->d_name, ".") != 0 && strcmp(pEntry->d_name, "..") != 0 && strncmp(pEntry->d_name, "[", 1) == 0 && strstr(pEntry->d_name, "tar") < 0) { char yearC[5]; unsigned short year = 0; char monthC[3]; unsigned short month = 0; yearC[4] = '\0'; strncpy(yearC, pEntry->d_name + 1, 4); monthC[2] = '\0'; strncpy(monthC, pEntry->d_name + 6, 2); year = atoi(yearC); month = atoi(monthC); if (year != 0) { if (year < tmCSU->tm_year + 1900 || (year >= tmCSU->tm_year + 1900 && month < tmCSU->tm_mon + 1)) { DEBUG_INFO_MSG("tar file name : %s \n", pEntry->d_name); char file[256]; memset(file, 0x00, sizeof(file)); strcat(file, "tar zcvf "); strcat(file, logPath); strncat(file, "/", 1); strcat(file, pEntry->d_name); strcat(file, ".tar"); strncat(file, " ", 1); strcat(file, logPath); strncat(file, "/", 1); strcat(file, pEntry->d_name); PRINTF_FUNC("zip = %s \n", file); system(file); } } } } } // Close folder closedir(pDir); } void CheckModelName() { // 黑白機 ? if(strcmp((char *)ShmSysConfigAndInfo->SysConfig.ModelName, "DWWU301J0UT1PH") == EQUAL || strcmp((char *)ShmSysConfigAndInfo->SysConfig.ModelName, "DWYE301J0ET1PH") == EQUAL) ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf = YES; else ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf = NO; } void StopProcessingLoop() { for (;;) { CheckFactoryConfigFunction(); CheckFwUpdateFunction(); sleep(1); } } void CreateWatchdog() { if (DEBUG == NO) { wtdFd = InitWatchDog(); if (wtdFd < 0) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1; } } int Upgrade_CCS(int canfd, unsigned int Type,unsigned char TargetAddr) { int result = FAIL; unsigned int DataLength = 0; // if(CAN_Download_REQ(canfd, TargetAddr, DataLength) == PASS) // { // // } return result; // long int MaxLen=48*1024*1024, ImageLen=0; // unsigned int ImageCRC=0, DataLength=0; // // fd = open(SourcePath, O_RDONLY); // if(fd < 0) // { // DEBUG_ERROR("UpdateRootfs NG - can not open rootfs\n"); // return result; // } // // unsigned char *ptr = malloc(MaxLen); // memset(ptr,0xFF,MaxLen); // // //get the image length // ImageLen = read(fd,ptr,MaxLen); // close(fd); // //read out the header // int i; // int isModelNameOK = PASS; // for(i=0;i<16;i++) { // if(ModelName[i] != ptr[i]){ // isModelNameOK = FAIL; // } // } // // if(isModelNameOK == FAIL) // { // DEBUG_ERROR("Model name mismatch...\n"); // return result; // } // else // { // // check if the firmware type is correct // if(Type == (((unsigned int)ptr[16])<<24 | ((unsigned int)ptr[17])<<16 | ((unsigned int)ptr[18])<<8 | ((unsigned int)ptr[19]))) // { // if((ImageLen-48) == (((unsigned int)ptr[20])<<24 | ((unsigned int)ptr[21])<<16 | ((unsigned int)ptr[22])<<8 | ((unsigned int)ptr[23]))) // { // DataLength = ImageLen-48; // // // get CRC in the header // ImageCRC = ((unsigned int)ptr[34])<<24 | ((unsigned int)ptr[35])<<16 | ((unsigned int)ptr[36])<<8 | ((unsigned int)ptr[37]); // // // calculate the image CRC // DEBUG_INFO("CRC32 in image: 0x%08X\r\n",ImageCRC); // DEBUG_INFO("CRC32 by calculation: 0x%08X\r\n",crc32(ptr,ImageLen)); // if(crc32(ptr,ImageLen) == ImageCRC) // { // unsigned int Checksum[16]; // // for(int i=0;i<16;i++) // { // Checksum[i] = Checksum_Cal(i * 24576, 24576, ptr + 48); // } // // if(CAN_Download_REQ(canfd, TargetAddr, DataLength) == PASS) // { // for(int block = 1; block <= 16; block++) // { // if(CAN_Start_BLK_Trans(canfd, TargetAddr, block, Checksum[block - 1]) == PASS) // { // for(int times = 0; times < 3072; times++) // { // CAN_Data_Trans(canfd, TargetAddr, ((block - 1) * 24576 + times * 8), ptr + 48); // } // DEBUG_INFO(" \r\n\r\n"); // } // else // { // free(ptr); // return result; // } // } // // if (CAN_Download_FIN(canfd, TargetAddr) == PASS) // result = PASS; // } // else // DEBUG_ERROR("CANBUS upgrade request failed.\n"); // } // else // DEBUG_ERROR("Firmware image CRC32 mismatch.\r\n"); // } // else // DEBUG_ERROR("Firmware image length mismatch.\r\n"); // } // else // DEBUG_ERROR("Firmware image type mismatch.\r\n"); // // } // free(ptr); // return result; } int main(void) { // Upgrade_CCS(1,1,1); // return 0; if(CreateShareMemory() == 0) { #ifdef SystemLogMessage DEBUG_ERROR_MSG("CreatShareMemory NG \n"); #endif if(ShmStatusCodeData!=NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory = 1; } return 0; sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } PRINTF_FUNC("\n"); PRINTF_FUNC("Initial SystemConfig and Info.......\n"); if (!InitialSystemDefaultConfig()) { DEBUG_ERROR_MSG("InitialSystemDefaultConfig NG \n"); StopProcessingLoop(); } PRINTF_FUNC("CheckConnectorTypeStatus. \n"); CheckGunTypeFromHw(); PRINTF_FUNC("InitialShareMemoryInfo & Initialization. \n"); InitialShareMemoryInfo(); PRINTF_FUNC("CheckModelName. \n"); ChangeLcmByIndex(_LCM_INIT); CheckModelName(); if (!CheckConnectorTypeStatus()) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.ModelNameNoneMatchStestFail = YES; ChangeLcmByIndex(_LCM_FIX); // Module Name 與硬體對應不正確 PRINTF_FUNC("Module Name & HW info none match. \n"); DEBUG_ERROR_MSG("Module Name & HW info none match. \n"); sleep(3); KillTask(); StopProcessingLoop(); } Initialization(); PRINTF_FUNC("Spawn all Task. \n"); SpawnTask(); PRINTF_FUNC("Module Name & HW info correct. Initialize.......\n"); CreateTimeoutFork(); PRINTF_FUNC("Self test. \n"); SelfTestRun(); StopSystemTimeoutDet(); PRINTF_FUNC("SelfTestSeq = %d, Work_Step = %d \n", ShmSysConfigAndInfo->SysInfo.SelfTestSeq, ShmPsuData->Work_Step); if (ShmSysConfigAndInfo->SysInfo.SelfTestSeq == _STEST_FAIL || ShmPsuData->Work_Step == _NO_WORKING) { DisplaySelfTestFailReason(); for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index++) { setChargerMode(gun_index, MODE_ALARM); } ChangeLcmByIndex(_LCM_FIX); StopProcessingLoop(); } else { for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index++) { setChargerMode(gun_index, MODE_IDLE); } } ChangeLcmByIndex(_LCM_IDLE); sleep(1); //***** 須新增的偵測 *****// // 1. Thernal - 控制風扇轉速 // 2. ouput fuse - 控制風扇轉速 CreateRfidFork(); // Create Watchdog CreateWatchdog(); // Main loop PRINTF_FUNC("Main Loop. \n"); for (;;) { CheckOcppStatus(); ChkPrimaryStatus(); if ((ShmSysConfigAndInfo->SysInfo.PageIndex == _LCM_IDLE || ShmSysConfigAndInfo->SysInfo.PageIndex == _LCM_FIX)&& ShmSysConfigAndInfo->SysInfo.SystemTimeoutFlag != Timeout_ReturnToChargingGunDet) { CheckFactoryConfigFunction(); CheckFwUpdateFunction(); } // OCPP 邏輯 OcppRemoteStartChk(); // 讀卡邏輯 ScannerCardProcess(); for (byte gun_index = 0; gun_index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; gun_index++) { CheckGpioInStatus(); CheckErrorOccurStatus(gun_index); ChkOcppStatus(gun_index); //PRINTF_FUNC("index = %d, ErrorCode = %s \n", gun_index, ShmOCPP16Data->StatusNotification[gun_index].ErrorCode); switch(chargingInfo[gun_index]->SystemStatus) { case S_IDLE: case S_RESERVATION: { if (chargingInfo[gun_index]->SystemStatus == S_IDLE && isModeChange(gun_index)) { PRINTF_FUNC("S_IDLE================================== %x \n", gun_index); chargingInfo[gun_index]->RemainChargingDuration = 0; chargingInfo[gun_index]->PresentChargedEnergy = 0; } else if (chargingInfo[gun_index]->SystemStatus == S_RESERVATION && isModeChange(gun_index)) { PRINTF_FUNC("S_RESERVATION....................%x \n", gun_index); ShmOCPP16Data->CsMsg.bits[gun_index].ReserveNowConf = YES; } if (ShmSysConfigAndInfo->SysWarningInfo.Level == 2) { if (gun_index == ShmSysConfigAndInfo->SysInfo.CurGunSelected) { ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_FIX; } ClearDetectPluginFlag(); } else if (ShmSysConfigAndInfo->SysConfig.OfflinePolicy == _OFFLINE_POLICY_NO_CHARGING) {/* 不給充電 */} else { if (ShmSysConfigAndInfo->SysInfo.SystemPage == _LCM_FIX) { ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER) { if (ShmSysConfigAndInfo->SysInfo.AcContactorStatus == YES) { // 均充 -> 最大充 if (ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus == NO) { if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_NONE) { PRINTF_FUNC("=============Smart Charging============= Step 11 \n"); ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_PREPARE_A_TO_M; } } else if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag != _REASSIGNED_COMP && ShmSysConfigAndInfo->SysInfo.ReAssignedFlag != _REASSIGNED_WAITING) { PRINTF_FUNC("=============Smart Charging============= Step 14 \n"); ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_WAITING; } else if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_COMP) { ShmSysConfigAndInfo->SysInfo.MainChargingMode = _MAIN_CHARGING_MODE_MAX; ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE; } } else { ShmSysConfigAndInfo->SysInfo.MainChargingMode = _MAIN_CHARGING_MODE_MAX; ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE; } } { // Idle 正常程序起點 // 判斷是否有啟用檢查插槍 if(isDetectPlugin()) { // 卡號驗證成功後,等待充電槍插入充電車 if ((ShmSysConfigAndInfo->SysInfo.OrderCharging != FAIL && ShmSysConfigAndInfo->SysInfo.OrderCharging < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount)) { if (chargingInfo[(unsigned char)ShmSysConfigAndInfo->SysInfo.OrderCharging]->ConnectorPlugIn == YES && chargingInfo[gun_index]->IsAvailable) { PRINTF_FUNC("-----------------1----------------- %d \n", ShmSysConfigAndInfo->SysInfo.OrderCharging); ShmSysConfigAndInfo->SysInfo.CurGunSelected = ShmSysConfigAndInfo->SysInfo.OrderCharging; AddPlugInTimes(ShmSysConfigAndInfo->SysInfo.OrderCharging); setChargerMode(ShmSysConfigAndInfo->SysInfo.OrderCharging, MODE_REASSIGN_CHECK); ClearDetectPluginFlag(); continue; } } else { if (chargingInfo[gun_index]->ConnectorPlugIn == YES && chargingInfo[gun_index]->IsAvailable && chargingInfo[gun_index]->SystemStatus == S_IDLE) { PRINTF_FUNC("-----------------2----------------- \n"); ShmSysConfigAndInfo->SysInfo.CurGunSelected = gun_index; AddPlugInTimes(gun_index); strcpy((char *)chargingInfo[gun_index]->StartUserId, (char *)ShmSysConfigAndInfo->SysConfig.UserId); PRINTF_FUNC("index = %d, CardNumber = %s \n", gun_index, chargingInfo[gun_index]->StartUserId); strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); // 當前操作的槍號,進入 Preparing setChargerMode(gun_index, MODE_REASSIGN_CHECK); ClearDetectPluginFlag(); continue; } } if (!isCardScan) { // LCM => Waiting for plugging ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_WAIT_FOR_PLUG; } } else if (chargingInfo[gun_index]->SystemStatus == S_RESERVATION) { if (!isReservationExpired(gun_index)) { chargingInfo[gun_index]->SystemStatus = S_IDLE; } } else if (ShmSysConfigAndInfo->SysConfig.AuthorisationMode == _SYS_AUTHORIZE_FREE && (chargingInfo[gun_index]->ConnectorPlugIn == YES && chargingInfo[gun_index]->IsAvailable)) { PRINTF_FUNC("-----------------3----------------- \n"); ShmSysConfigAndInfo->SysInfo.CurGunSelected = gun_index; AddPlugInTimes(gun_index); setChargerMode(gun_index, MODE_REASSIGN_CHECK); ClearDetectPluginFlag(); continue; } else { if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index) ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_IDLE; if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount > 1 && ShmSysConfigAndInfo->SysInfo.PageIndex != _LCM_AUTHORIZING && ShmSysConfigAndInfo->SysInfo.PageIndex != _LCM_AUTHORIZ_FAIL && ShmSysConfigAndInfo->SysInfo.PageIndex != _LCM_AUTHORIZ_COMP && ShmSysConfigAndInfo->SysInfo.PageIndex != _LCM_WAIT_FOR_PLUG) { for (byte count = 0; count < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; count++) { if (count != ShmSysConfigAndInfo->SysInfo.CurGunSelected) { if ((chargingInfo[count]->SystemStatus >= S_REASSIGN_CHECK && chargingInfo[count]->SystemStatus <= S_COMPLETE) || (chargingInfo[count]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[count]->SystemStatus <= S_CCS_PRECHARGE_ST1) ) { StartSystemTimeoutDet(Timeout_ReturnToChargingGunDet); } else { StopSystemTimeoutDet(); } } } } } } // Idle 正常程序終點 } ReleaseAlarmCode(gun_index); } break; case S_REASSIGN_CHECK: { if (isModeChange(gun_index)) { PRINTF_FUNC("S_REASSIGN_CHECK================================== %x \n", gun_index); ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; if (ShmSysConfigAndInfo->SysInfo.OrderCharging != FAIL) ShmSysConfigAndInfo->SysInfo.OrderCharging = FAIL; StopSystemTimeoutDet(); } bool isRessign = false; if (ShmSysConfigAndInfo->SysConfig.TotalConnectorCount > 1 && ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == NO) { if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX) { for (byte index = 0; index < ShmSysConfigAndInfo->SysConfig.TotalConnectorCount; index++) { // 有其他槍已經分配好 psu 模塊 if (ShmSysConfigAndInfo->SysInfo.CurGunSelected != index && chargingInfo[index]->SystemStatus >= S_PREPARNING) { PRINTF_FUNC("=============Smart Charging============= Step 1 \n"); ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_PREPARE_M_TO_A; isRessign = true; break; } } } } if (isRessign) setChargerMode(gun_index, MODE_REASSIGN); else setChargerMode(gun_index, MODE_PRECHARGE); } break; case S_REASSIGN: { if (isModeChange(gun_index)) { PRINTF_FUNC("S_REASSIGN================================== %x \n", gun_index); } // 重新分配,此階段主要是讓已經在充電或者準備進入充電前的緩衝 // 此狀態下~ 控制權在於 PSU 及 EV小板 Process if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_NONE || ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_AVER) setChargerMode(gun_index, MODE_PRECHARGE); else if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_RELAY_M_TO_A && ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus == NO) { PRINTF_FUNC("=============Smart Charging : _REASSIGNED_COMP============= Step 6 \n"); ShmSysConfigAndInfo->SysInfo.MainChargingMode = _MAIN_CHARGING_MODE_AVER; } //PRINTF_FUNC("CurGunSelected = %d, gun_index = %d \n", ShmSysConfigAndInfo->SysInfo.CurGunSelected, gun_index); if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index) ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_PRE_CHARGE; } break; case S_PREPARNING: { if (isModeChange(gun_index)) { PRINTF_FUNC("S_PREPARNING================================== %x \n", gun_index); StopGunInfoTimeoutDet(gun_index); StartGunInfoTimeoutDet(gun_index, Timeout_Preparing); } if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag != _REASSIGNED_NONE) ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE; // if (((ShmPsuData->SystemPresentPsuQuantity > 0 && // ShmPsuData->PsuGroup[gun_index].GroupPresentPsuQuantity > 0 && // ShmPsuData->PsuGroup[gun_index].GroupAvailablePower > 10) && // chargingInfo[gun_index]->AvailableChargingPower > 10)) if (ShmPsuData->SystemPresentPsuQuantity > 0 && ShmPsuData->SystemAvailablePower > 10) { setChargerMode(gun_index, MODE_PREPARE_FOR_EV); } if (isEvBoardStopChargeFlag(gun_index) == YES || OcppRemoteStop(gun_index) == YES) { // 板端或後臺要求停止 ChargingTerminalProcess(gun_index); } if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index) ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_PRE_CHARGE; } break; case S_PREPARING_FOR_EV: // 等待車端的通訊 (EV 小板),待車端回報後,開始樁端的測試 { if (isModeChange(gun_index)) { PRINTF_FUNC("S_PREPARING_FOR_EV================================== %x \n", gun_index); strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); StopGunInfoTimeoutDet(gun_index); StartGunInfoTimeoutDet(gun_index, Timeout_EvChargingDet); } if (chargingInfo[gun_index]->Type == _Type_Chademo) { // 檢查車端的槍鎖是否為鎖上 if (isEvGunLocked_chademo(gun_index) == YES) { setChargerMode(gun_index, MODE_PREPARE_FOR_EVSE); } } else if (chargingInfo[gun_index]->Type == _Type_CCS_2) { // 檢查車端的 charging enable 是否為 1 if (isEvGunLocked_ccs(gun_index) == YES) { setChargerMode(gun_index, MODE_PREPARE_FOR_EVSE); } } if (isEvBoardStopChargeFlag(gun_index) == YES || OcppRemoteStop(gun_index) == YES) { // 板端或後臺要求停止 ChargingTerminalProcess(gun_index); } // LCM => Pre-charging if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index) ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_PRE_CHARGE; } break; case S_PREPARING_FOR_EVSE: // 等待 RB 通訊及測試,並將狀態回報, CSU 確認 Pass 後,開始進入充電 { if (isModeChange(gun_index)) { PRINTF_FUNC("S_PREPARING_FOR_EVSE================================== %x \n", gun_index); StopGunInfoTimeoutDet(gun_index); StartGunInfoTimeoutDet(gun_index, Timeout_EvseChargingDet); } if (chargingInfo[gun_index]->Type == _Type_Chademo) { // 檢查樁端的 GFD 結果 if (isPrechargeStatus_chademo(gun_index) > 5 && isPrechargeStatus_chademo(gun_index) < 8) { // 當前操作的槍號,進入 Charging setChargerMode(gun_index, MODE_CHARGING); } if (chargingInfo[gun_index]->GroundFaultStatus == GFD_FAIL) { // GFD 錯誤停止 RecordAlarmCode("012234"); } } else if (chargingInfo[gun_index]->Type == _Type_CCS_2) { // 檢查樁端的 GFD 結果 if (chargingInfo[gun_index]->GroundFaultStatus == GFD_PASS) { setChargerMode(gun_index, MODE_CCS_PRECHARGE_STEP0); } if (chargingInfo[gun_index]->GroundFaultStatus == GFD_FAIL) { // GFD 錯誤停止 RecordAlarmCode("012235"); } } if (isEvBoardStopChargeFlag(gun_index) == YES || chargingInfo[gun_index]->GroundFaultStatus == GFD_FAIL || OcppRemoteStop(gun_index) == YES) { // 板端或後臺要求停止 ChargingTerminalProcess(gun_index); } // LCM => Pre-charging if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index) ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_PRE_CHARGE; } break; case S_CHARGING: // 剛進入充電狀態,等待 EV 小板要求的輸出電流後開始輸出 { if (isModeChange(gun_index)) { PRINTF_FUNC("S_CHARGING================================== %x \n", gun_index); StopGunInfoTimeoutDet(gun_index); ftime(&startChargingTime[gun_index]); ChangeStartOrStopDateTime(YES, gun_index); OcppStartTransation(gun_index); } ftime(&endChargingTime[gun_index]); chargingInfo[gun_index]->RemainChargingDuration = DiffTimeb(startChargingTime[gun_index], endChargingTime[gun_index]); if (chargingInfo[gun_index]->Type == _Type_Chademo) { if (chargingInfo[gun_index]->GroundFaultStatus == GFD_FAIL) { // GFD 錯誤停止 RecordAlarmCode("012234"); } else if ((chargingInfo[gun_index]->EvBatterytargetVoltage > 0 && chargingInfo[gun_index]->EvBatterytargetVoltage < SYSTEM_MIN_VOL) || (chargingInfo[gun_index]->RemainChargingDuration >= 10 && chargingInfo[gun_index]->PresentChargingVoltage < SYSTEM_MIN_VOL)) { // UVP RecordAlarmCode("012289"); } } else if (chargingInfo[gun_index]->Type == _Type_CCS_2) { if (chargingInfo[gun_index]->GroundFaultStatus == GFD_FAIL) { // GFD 錯誤停止 RecordAlarmCode("012235"); } else if ((chargingInfo[gun_index]->EvBatterytargetVoltage > 0 && chargingInfo[gun_index]->EvBatterytargetVoltage < SYSTEM_MIN_VOL) || (chargingInfo[gun_index]->RemainChargingDuration >= 10 && chargingInfo[gun_index]->PresentChargingVoltage < SYSTEM_MIN_VOL)) { // UVP RecordAlarmCode("012288"); } } if (isEvBoardStopChargeFlag(gun_index) || chargingInfo[gun_index]->GroundFaultStatus == GFD_FAIL || OcppRemoteStop(gun_index) || CheckBackendChargingTimeout(gun_index) || CheckBackendChargingEnergy(gun_index) || (chargingInfo[gun_index]->EvBatterytargetVoltage > 0 && chargingInfo[gun_index]->EvBatterytargetVoltage < SYSTEM_MIN_VOL) || (chargingInfo[gun_index]->RemainChargingDuration >= 10 && chargingInfo[gun_index]->PresentChargingVoltage < SYSTEM_MIN_VOL)) { // 板端或後臺要求停止 ChargingTerminalProcess(gun_index); } // LCM => Charging if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index) ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_CHARGING; } break; case S_TERMINATING: { if (isModeChange(gun_index)) { PRINTF_FUNC ("terminating......................... %x \n", gun_index); StopGunInfoTimeoutDet(gun_index); } if (chargingInfo[gun_index]->Type == _Type_Chademo) { // 非車端的停止 : 需等待小板送出停止指令,讓車端解除槍 if (isEvStopCharging_chademo(gun_index) == YES || isPrechargeStatus_chademo(gun_index) <= 0) { setChargerMode(gun_index, MODE_COMPLETE); } } else if (chargingInfo[gun_index]->Type == _Type_CCS_2) { // 非車端的停止 : 需等待小板送出停止指令,讓車端解除槍 if (isEvStopCharging_ccs(gun_index) == YES && (isPrechargeStatus_ccs(gun_index) >= 53 || isPrechargeStatus_ccs(gun_index) == 0 || isPrechargeStatus_ccs(gun_index) == 13 || isPrechargeStatus_ccs(gun_index) == 14)) { setChargerMode(gun_index, MODE_COMPLETE); } } if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index) ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_COMPLETE; } break; case S_COMPLETE: { if (isModeChange(gun_index)) { PRINTF_FUNC ("complete......................... %x \n", gun_index); OcppStopTransation(gun_index); ftime(&endChargingTime[gun_index]); if (chargingInfo[gun_index]->RemainChargingDuration != 0) chargingInfo[gun_index]->RemainChargingDuration = DiffTimeb(startChargingTime[gun_index], endChargingTime[gun_index]); StopGunInfoTimeoutDet(gun_index); StartGunInfoTimeoutDet(gun_index, Timeout_EvseCompleteDet); ChangeStartOrStopDateTime(NO, gun_index); } if(chargingInfo[gun_index]->ConnectorPlugIn == NO && GetTimeoutValue(chargingInfo[gun_index]->TimeoutTimer) >= 10000000) { setChargerMode(gun_index, MODE_IDLE); } if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index) ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_COMPLETE; } break; case S_CCS_PRECHARGE_ST0: { if (isModeChange(gun_index)) { PRINTF_FUNC("CCS Precharge Processing 1....................%x \n", gun_index); StopGunInfoTimeoutDet(gun_index); StartGunInfoTimeoutDet(gun_index, Timeout_ForCcsPrechargeDet); } if (chargingInfo[gun_index]->GroundFaultStatus == GFD_FAIL) { // GFD 錯誤停止 RecordAlarmCode("012235"); } if (isEvBoardStopChargeFlag(gun_index) == YES || chargingInfo[gun_index]->GroundFaultStatus == GFD_FAIL) { // 板端要求停止 ChargingTerminalProcess(gun_index); } // 等待 EV 小板 (CCS) 通知可以開始 Precharge // 切換 D+ Relay to Precharge Relay if (isPrechargeStatus_ccs(gun_index) == 39 || isPrechargeStatus_ccs(gun_index) == 40) { if (chargingInfo[gun_index]->RelayKPK2Status == YES && chargingInfo[gun_index]->PrechargeStatus != PRECHARGE_READY) //if (chargingInfo[gun_index]->PrechargeStatus != PRECHARGE_PRERELAY_PASS) { PRINTF_FUNC("Send precharge ready 1..........%x, status = %d \n", gun_index, isPrechargeStatus_ccs(gun_index)); chargingInfo[gun_index]->PrechargeStatus = PRECHARGE_READY; } } else if (isPrechargeStatus_ccs(gun_index) == 45 || isPrechargeStatus_ccs(gun_index) == 46) { setChargerMode(gun_index, MODE_CCS_PRECHARGE_STEP1); } break; } case S_CCS_PRECHARGE_ST1: { if (isModeChange(gun_index)) { PRINTF_FUNC("CCS Precharge Processing 2....................%x \n", gun_index); } if (chargingInfo[gun_index]->GroundFaultStatus == GFD_FAIL) { // GFD 錯誤停止 RecordAlarmCode("012235"); } if (isEvBoardStopChargeFlag(gun_index) == YES || chargingInfo[gun_index]->GroundFaultStatus == GFD_FAIL) { // 板端要求停止 ChargingTerminalProcess(gun_index); } // 等待小板通知進入充電 // 切換 D+ Relay to Precharge Relay if (chargingInfo[gun_index]->RelayK1K2Status == YES) { chargingInfo[gun_index]->PrechargeStatus = PRECHARGE_READY; setChargerMode(gun_index, MODE_CHARGING); } break; } } } if (ShmSysConfigAndInfo->SysInfo.SystemPage != _LCM_NONE) { ChangeLcmByIndex(ShmSysConfigAndInfo->SysInfo.SystemPage); } else { ChangeLcmByIndex(ShmSysConfigAndInfo->SysInfo.ConnectorPage); } write(wtdFd, "a", 1); usleep(whileLoopTime); } return FAIL; }