#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 "../../define.h" #include "Config.h" #include #include #include "timeout.h" #define Debug #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 SYSFS_GPIO_DIR "/sys/class/gpio" unsigned char mask_table[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; int whileLoopTime = 10000; // 10 ms 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); #define DEBUG_INFO_1(format, args...) StoreLogMsg_1("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args) #define DEBUG_WARN_1(format, args...) StoreLogMsg_1("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args) #define DEBUG_ERROR_1(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]; byte _gunCount = 0; // 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"; byte autoReturnTimeoutFlag = 0x00; //================================================ // 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_1("Set SO_RCVTIMEO NG"); #endif } nbytes=40960; if (setsockopt(s0, SOL_SOCKET, SO_RCVBUF, &nbytes, sizeof(int)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR_1("Set SO_RCVBUF NG"); #endif } nbytes=40960; if (setsockopt(s0, SOL_SOCKET, SO_SNDBUF, &nbytes, sizeof(int)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR_1("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"; int InitComPort(byte id) { int fd; struct termios tios; if (id == 0x04) fd = open(priPortName, O_RDWR); if(fd<=0) { #ifdef SystemLogMessage DEBUG_ERROR_1("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 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); } void setChargerMode(byte gun_index, byte mode) { chargingInfo[gun_index]->SystemStatus = mode; } //========================================== // 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_1("[main]CreatShareMemory:shmget ShmSysConfigAndInfo NG \n"); #endif return 0; } else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR_1("[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_1("[main]CreatShareMemory:shmget ShmStatusCodeData NG \n"); #endif return 0; } else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR_1("[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_1("[main]CreatShareMemory:shmget ShmPsuData NG \n"); #endif return 0; } else if ((ShmPsuData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR_1("[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_1("[main]CreatShareMemory:shmget ShmCHAdeMOData NG \n"); #endif return 0; } else if ((ShmCHAdeMOData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR_1("[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_1("[main]CreatShareMemory:shmget ShmCcsData NG \n"); #endif return 0; } else if ((ShmCcsData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR_1("[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_1("[main]CreatShareMemory:shmget ShmPrimaryMcuData NG \n"); #endif return 0; } else if ((ShmPrimaryMcuData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR_1("[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_1("[main]CreatShareMemory:shmget ShmFanModuleData NG \n"); #endif return 0; } else if ((ShmFanModuleData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR_1("[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_1("[main]CreatShareMemory:shmget ShmRelayModuleData NG \n"); #endif return 0; } else if ((ShmRelayModuleData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR_1("[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_1("[main]CreatShareMemory:shmget ShmOCPP16Data NG \n"); #endif return 0; } else if ((ShmOCPP16Data = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR_1("[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->SysStopChargingAlarmCode.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 0 > /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 0 > /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_ERROR_1("[main]InitGPIO: Initial GPIO OK"); #endif } int LoadSysConfigAndInfo(struct SysConfigData *ptr) { int fd,wrd; struct SysConfigData *buf; byte *PtrBuf; unsigned int ChkSum, ChkSumOrg; if ((buf = malloc(sizeof(struct SysConfigData))) == NULL) { #ifdef SystemLogMessage DEBUG_ERROR_1("[main]LoadSysConfigAndInfo:malloc buffer NG,rebooting.."); #endif if (ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } memset(buf, 0, sizeof(struct SysConfigData)); fd = open("/dev/mtdblock10", O_RDWR); if (fd < 0) { free(buf); #ifdef SystemLogMessage DEBUG_ERROR_1("[main]LoadSysConfigAndInfo:open mtdblock10 NG,rebooting.."); #endif if (ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } wrd = read(fd, buf, sizeof(struct SysConfigData)); close(fd); if (wrd != (sizeof(struct SysConfigData))) { free(buf); #ifdef SystemLogMessage DEBUG_ERROR_1("[main]LoadSysConfigAndInfo: read SysConfigData data NG,rebooting.."); #endif if (ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } PtrBuf = (byte *) buf; ChkSum = 0; for (wrd = 0; wrd < (sizeof(struct SysConfigData) - 4); wrd++) { ChkSum += PtrBuf[wrd]; } ChkSumOrg = buf->Checksum; if (ChkSum != ChkSumOrg) { #ifdef SystemLogMessage DEBUG_ERROR_1("[main]LoadSysConfigAndInfo: Primary SysConfigData checksum NG, read backup"); #endif fd = open("/dev/mtdblock11", O_RDWR); if (fd < 0) { free(buf); #ifdef SystemLogMessage DEBUG_ERROR_1("[main]LoadSysConfigAndInfo: open mtdblock11 (backup) NG,rebooting.."); #endif if (ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } memset(buf, 0, sizeof(struct SysConfigData)); wrd = read(fd, buf, sizeof(struct SysConfigData)); close(fd); if (wrd != sizeof(struct SysConfigData)) { free(buf); #ifdef SystemLogMessage DEBUG_ERROR_1("[main]LoadSysConfigAndInfo: read backup SysConfigData data NG,rebooting.."); #endif if (ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } PtrBuf = (byte *) buf; ChkSum = 0; for (wrd = 0; wrd < (sizeof(struct SysConfigData) - 4); wrd++) { ChkSum += PtrBuf[wrd]; } ChkSumOrg = buf->Checksum; if (ChkSum != ChkSumOrg) { #ifdef SystemLogMessage DEBUG_ERROR_1("[main]LoadSysConfigAndInfo: backup SysConfigData checksum NG, read Factory default"); #endif fd = open("/dev/mtdblock12", O_RDWR); if (fd < 0) { free(buf); #ifdef SystemLogMessage DEBUG_ERROR_1("[main]LoadSysConfigAndInfo: open mtdblock12 (Factory default) NG,rebooting.."); #endif if (ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } memset(buf, 0, sizeof(struct SysConfigData)); wrd = read(fd, buf, sizeof(struct SysConfigData)); close(fd); if (wrd != sizeof(struct SysConfigData)) { free(buf); #ifdef SystemLogMessage DEBUG_ERROR_1("[main]LoadSysConfigAndInfo: read factory default SysConfigData data NG,rebooting.."); #endif if (ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } PtrBuf = (byte *) buf; ChkSum = 0; for (wrd = 0; wrd < (sizeof(struct SysConfigData) - 4); wrd++) { ChkSum += PtrBuf[wrd]; } ChkSumOrg = buf->Checksum; if (ChkSum != ChkSumOrg) { #ifdef SystemLogMessage DEBUG_ERROR_1("[main]LoadSysConfigAndInfo: factory default SysConfigData checksum NG, restore factory default"); #endif goto DefaultShm; } } } //load OK memcpy((struct SysConfigData *) ptr, (struct SysConfigData *) buf, sizeof(struct SysConfigData)); free(buf); #ifdef SystemLogMessage DEBUG_ERROR_1("[main]LoadSysConfigAndInfo: Load SysConfigData OK"); #endif return 1; DefaultShm: system("cd /root;./FactoryConfig"); system("sync"); sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); return FAIL; } 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 return; 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); //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.Eth0Interface.EthDhcpClient==0) system("/sbin/udhcpc -i eth0 -s /root/simple.script > /dev/null &"); #ifdef SystemLogMessage DEBUG_ERROR_1("[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; } int Initialization() { //InitGPIO(); //LoadSysConfigAndInfo(&ShmSysConfigAndInfo->SysConfig); //InitEthernet(); sprintf((char *)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomApn, "Internet"); sprintf((char *)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapId, " "); sprintf((char *)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapPwd, " "); // 初始化卡號驗證的 Flag ClearAuthorizedFlag(); // 初始化插槍驗證的 Flag ClearDetectPluginFlag(); // UART 2 for Rfid rfidFd = InitialRfidPort(); 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; for (byte count = 0; count < _gunCount; count++) { if (chargingInfo[count]->Type == _Type_Chademo) { ShmCHAdeMOData->evse[chargingInfo[count]->type_index].SelfTest_Comp = NO; } else if (chargingInfo[count]->Type == _Type_CCS) { if (ShmCcsData->CommProtocol == 0x01) { ShmCcsData->V2GMessage_DIN70121[chargingInfo[count]->type_index].SelfTest_Comp = NO; } } } #ifdef SystemLogMessage printf("Initialization OK \n"); #endif return PASS; } void SelfTestRun() { bool evInitFlag = false; StartSystemTimeoutDet(Timeout_SelftestChk); ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_VERSION; while (ShmSysConfigAndInfo->SysInfo.SelfTestSeq != _STEST_COMPLETE) { ChkPrimaryStatus(); if (ShmSysConfigAndInfo->SysStopChargingAlarmCode.Level == 2) { ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_FAIL; return; } if (_gunCount > 0) { if (ShmPsuData->Work_Step == _NO_WORKING) { ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_FAIL; break; } switch(ShmSysConfigAndInfo->SysInfo.SelfTestSeq) { case _STEST_VERSION: { if (strlen((char *)ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev) != 0 || ShmSysConfigAndInfo->SysInfo.RelayModuleFwRev[0] != '\0') { //printf("RB pass \n"); ShmRelayModuleData->SelfTest_Comp = YES; } //if (strlen((char *)ShmSysConfigAndInfo->SysInfo.FanModuleFwRev) != 0 || // ShmSysConfigAndInfo->SysInfo.FanModuleFwRev[0] != '\0') { //printf("Fan pass \n"); ShmFanModuleData->SelfTest_Comp = YES; } if (strlen((char *)ShmPrimaryMcuData->version) != 0 || ShmPrimaryMcuData->version[0] != '\0') { //printf("407 pass \n"); ShmPrimaryMcuData->SelfTest_Comp = YES; } // EV 小板 if (!evInitFlag) { evInitFlag = YES; for (byte index = 0; index < _gunCount; 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("chademo pass \n"); ShmCHAdeMOData->evse[chargingInfo[index]->type_index].SelfTest_Comp = YES; } else { printf("chademo fw lose...... \n"); evInitFlag = NO; } } else if (chargingInfo[index]->Type == _Type_CCS) { 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') { ShmCcsData->V2GMessage_DIN70121[chargingInfo[index]->type_index].SelfTest_Comp = YES; } else { printf("ccs fw lose \n"); 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("Communication board pass. \n"); } } break; case _STEST_PSU_DETECT: { // 此測試主要測試 PSU 對應是否為正確的火線上電壓 // 如果沒有 PSU 模組請 bypass if (ShmPsuData->Work_Step == _TEST_POWER_STEP || ShmPsuData->Work_Step == _TEST_COMPLETE) { ShmSysConfigAndInfo->SysInfo.SelfTestSeq = _STEST_PSU_CAP; } } break; case _STEST_PSU_CAP: { // 此測試是要確認當前總輸出能力 // 如果沒有 PSU 模組請 bypass if (ShmPsuData->Work_Step == _TEST_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/OcppBackend &"); //system("/root/Module_4g &"); //system("/root/Module_Wifi &"); //system("/root/Module_PsuComm &"); //system("/root/InfyPowerPsu_Comm &"); // 加入參數 // char str[64]; // memset(str, '\0', sizeof(65)); // sprintf(str, "/root/Module_EvComm %x &", (CHAdeMO_QUANTITY + CCS_QUANTITY)); // printf("%s \n", str); // system(str); return PASS; } int StoreUsrConfigData(struct SysConfigData *UsrData) { int fd,wrd; unsigned int i, Chk; byte *ptr; Chk = 0; ptr = (byte *) UsrData; for (i = 0; i < sizeof(struct SysConfigData) - 4; i++) { Chk += *(ptr + i); } UsrData->Checksum = Chk; fd = open("/dev/mtdblock10", O_RDWR); if (fd < 0) { #ifdef SystemLogMessage DEBUG_ERROR_1("[main]StoreUsrConfigData: open /dev/mtdblock10 NG"); #endif return 0; } wrd = write(fd, UsrData, sizeof(struct SysConfigData)); close(fd); if (wrd != (sizeof(struct SysConfigData))) { #ifdef SystemLogMessage DEBUG_ERROR_1("[main]StoreUsrConfigData: write /dev/mtdblock10 NG"); #endif return 0; } fd = open("/dev/mtdblock11", O_RDWR); if (fd < 0) { #ifdef SystemLogMessage DEBUG_ERROR_1("[main]StoreUsrConfigData: open /dev/mtdblock11(backup) NG"); #endif return 0; } wrd = write(fd, UsrData, sizeof(struct SysConfigData)); close(fd); if (wrd != (sizeof(struct SysConfigData))) { #ifdef SystemLogMessage DEBUG_ERROR_1("[main]StoreUsrConfigData: write /dev/mtdblock11(backup) NG"); #endif return 0; } return 1; } //=============================================== // Common Detect Chk - Stop Charging ? //=============================================== bool isEvBoardStopChargeFlag(byte gunIndex) { return chargingInfo[gunIndex]->StopChargeFlag; } //=============================================== // 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("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("gun locked none. \n"); return YES; } return NO; } //=============================================== // Callback //=============================================== void _AutoReturnTimeout() { if (ShmSysConfigAndInfo->SysInfo.PageIndex == _LCM_WAIT_FOR_PLUG) { ClearDetectPluginFlag(); } ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; // // for (byte i = 0; i < CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY; i++) // { // if (chargingInfo[i]->SystemStatus > S_IDLE) // { // switch(chargingInfo[i]->SystemStatus) // { // case S_PREPARNING: // case S_PREPARING_FOR_EV: // case S_PREPARING_FOR_EVSE: // { // ChangeLcmByIndex(i, _LCM_PRE_CHARGE); // } // break; // case S_CHARGING: // { // ChangeLcmByIndex(i, _LCM_CHARGING); // } // break; // case S_TERMINATING: // { // ChangeLcmByIndex(i, _LCM_COMPLETE); // } // break; // } // return; // } // } // if (!IsAuthorizingMode()) // ChangeLcmByIndex(255, _LCM_IDLE); } void _SelfTestTimeout() { if (ShmSysConfigAndInfo->SysInfo.BootingStatus != BOOT_COMPLETE) { for (byte gun_index = 0; gun_index < _gunCount; gun_index++) { setChargerMode(gun_index, MODE_ALARM); } ShmPsuData->Work_Step = _NO_WORKING; } } void _AuthorizedTimeout() { if(IsAuthorizingMode()) { printf("_AuthorizedTimeout \n"); ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_AUTHORIZ_FAIL; //ChangeLcmByIndex(_LCM_AUTHORIZ_FAIL); ClearAuthorizedFlag(); } } void _DetectPlugInTimeout() { if(isDetectPlugin()) { printf("_DetectPlugInTimeout \n"); ClearDetectPluginFlag(); } ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } void _DetectEvChargingEnableTimeout(byte gunIndex) { if (chargingInfo[gunIndex]->Type == _Type_Chademo) { if(!isEvGunLocked_chademo(gunIndex)) { printf("_DetectEvChargingEnableTimeout (chademo) \n"); ChargingTerminalProcess(gunIndex); _AutoReturnTimeout(); } } else if (chargingInfo[gunIndex]->Type == _Type_CCS) { if(!isEvGunLocked_ccs(gunIndex)) { printf("_DetectEvChargingEnableTimeout (ccs) \n"); ChargingTerminalProcess(gunIndex); _AutoReturnTimeout(); } } } void _DetectEvseChargingEnableTimeout(byte gunIndex) { printf("_DetectEvseChargingEnableTimeout (GFD timeout) \n"); if (chargingInfo[gunIndex]->GroundFaultStatus != GFD_PASS) { setChargerMode(gunIndex, MODE_IDLE); _AutoReturnTimeout(); } } void _PrepareTimeout(byte gunIndex) { printf("_PrechargeTimeout \n"); setChargerMode(gunIndex, MODE_IDLE); _AutoReturnTimeout(); } void _CompleteTimeout(byte gunIndex) { printf("_CompleteTimeout ====> %d \n", gunIndex); setChargerMode(gunIndex, MODE_IDLE); } void _CcsPrechargeTimeout(byte gunIndex) { printf("_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(strstr(buf2, "Accepted") != 0) return true; else { } return false; } void AuthorizingStart() { ShmOCPP16Data->SpMsg.bits.AuthorizeReq = YES; } void ClearAuthorizedFlag() { ShmOCPP16Data->SpMsg.bits.AuthorizeReq = NO; ShmOCPP16Data->SpMsg.bits.AuthorizeConf = NO; } bool isAuthorizedComplete() { if (ShmOCPP16Data->SpMsg.bits.AuthorizeConf == NO) return false; return true; } bool IsAuthorizingMode() { if(ShmOCPP16Data->SpMsg.bits.AuthorizeReq == NO) return false; return true; } byte GetCardNumber() { byte card_number[16]; if (strlen((char *)ShmSysConfigAndInfo->SysConfig.UserId) == 0) { if(getRequestCardSN(rfidFd, 0, card_number)) { //Get Card Number byte len = card_number[0]; char buf2[32] = ""; memcpy(buf2, (card_number + 1), len); memset(ShmSysConfigAndInfo->SysConfig.UserId, 0x0, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.UserId)); for (byte index = 0; index < len; index++) { sprintf((char *)ShmSysConfigAndInfo->SysConfig.UserId + (index * 2), "%02X", buf2[index]); } printf("card number = %s\n", ShmSysConfigAndInfo->SysConfig.UserId); return PASS; } } return FAIL; } //=============================================== // 掃描插槍狀況 //=============================================== void ClearDetectPluginFlag() { ShmSysConfigAndInfo->SysInfo.WaitForPlugit = NO; } void DetectPluginStart() { ShmSysConfigAndInfo->SysInfo.WaitForPlugit = YES; } bool isDetectPlugin() { if(ShmSysConfigAndInfo->SysInfo.WaitForPlugit == YES) return YES; return NO; } //=============================================== // EmergencyStop and Charging Stop //=============================================== void ChargingTerminalProcess(byte gunIndex) { setChargerMode(gunIndex, MODE_TERMINATING); } void StopChargingProcessByString(byte level, byte gun_index, char *string) { if (strlen((char *)ShmSysConfigAndInfo->SysStopChargingAlarmCode.StopCode[gun_index]) == 0 || level > ShmSysConfigAndInfo->SysStopChargingAlarmCode.Level) { memcpy(&ShmSysConfigAndInfo->SysStopChargingAlarmCode.StopCode[gun_index][0], string, 7); ShmSysConfigAndInfo->SysStopChargingAlarmCode.Level = level; } } void ReleaseChargingProcessByString(byte gun_index, char *code) { memcpy(&ShmSysConfigAndInfo->SysStopChargingAlarmCode.StopCode[gun_index][0], "", 7); ShmSysConfigAndInfo->SysStopChargingAlarmCode.Level = 0; } // 各小板的停止充電處理函式 void EmcOccureByString(byte index, char *code) { bool isStopCharger = false; if (strncmp(code, "012251", 6) == 0 || strncmp(code, "012252", 6) == 0 || strncmp(code, "012237", 6) == 0 || strncmp(code, "012238", 6) == 0) { isStopCharger = true; } if (isStopCharger) { for (byte gun = 0; gun < _gunCount; 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(2, gun, code); } } else { 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)) { ChargingTerminalProcess(index); } StopChargingProcessByString(2, index, code); } } void ReleaseEmsOccureByString(byte index, char *code) { bool isReleaseCharger = false; bool isTrigger = false; if (strncmp(code, "012251", 6) == 0 && ShmStatusCodeData->AlarmCode.AlarmEvents.bits.EmergencyStopTrip == YES) { isTrigger = true; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.EmergencyStopTrip = NO; isReleaseCharger = true; } else if (strncmp(code, "012252", 6) == 0 && ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DoorOpen == YES) { isTrigger = true; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DoorOpen = NO; isReleaseCharger = true; } else if (strncmp(code, "012237", 6) == 0 && ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SpdTrip == YES) { isTrigger = true; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SpdTrip = NO; isReleaseCharger = true; } else if (strncmp(code, "012238", 6) == 0 && ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MainPowerBreakerTrip == YES) { isTrigger = true; ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MainPowerBreakerTrip = NO; isReleaseCharger = true; } else if (strncmp(code, "023730", 6) == 0 && ShmStatusCodeData->InfoCode.InfoEvents.bits.ChademoChargerGetEmergencyStop == YES) { isTrigger = true; ShmStatusCodeData->InfoCode.InfoEvents.bits.ChademoChargerGetEmergencyStop = NO; } if (isTrigger) { if (isReleaseCharger) { for (byte gun = 0; gun < _gunCount; gun++) { ReleaseChargingProcessByString(gun, code); } } else { ReleaseChargingProcessByString(index, code); } } } //=============================================== // 確認硬體 (按鈕) 狀態 //=============================================== bool leftBtnPush = false; bool rightBtnPush = false; void ChkPrimaryStatus() { if (ShmPrimaryMcuData->InputDet.bits.EmergencyButton == ABNORMAL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.EmergencyStopTrip = YES; EmcOccureByString(0, "012251"); } else ReleaseEmsOccureByString(0, "012251"); if (ShmPrimaryMcuData->InputDet.bits.AcMainBreakerDetec == ABNORMAL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.MainPowerBreakerTrip = YES; EmcOccureByString(0, "012238"); } else ReleaseEmsOccureByString(0, "012238"); if (ShmPrimaryMcuData->InputDet.bits.SpdDetec == ABNORMAL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SpdTrip = YES; EmcOccureByString(0, "012237"); } else ReleaseEmsOccureByString(0, "012237"); if (ShmPrimaryMcuData->InputDet.bits.DoorOpen == ABNORMAL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.DoorOpen = YES; EmcOccureByString(0, "012252"); } else ReleaseEmsOccureByString(0, "012252"); if (ShmPrimaryMcuData->InputDet.bits.Button1 == BTN_PRESS && !leftBtnPush) { if(!leftBtnPush) { printf("left btn down............................... \n"); ShmSysConfigAndInfo->SysInfo.CurGunSelected = 0; switch(chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus) { case S_IDLE: { ShmSysConfigAndInfo->SysInfo.WaitForPlugit = 0x01; } break; case S_CHARGING: { // 停止充電 printf("To Stop = %d --------- \n", ShmSysConfigAndInfo->SysInfo.CurGunSelected); chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = 9; //ChargingTerminalProcess(ShmSysConfigAndInfo->SysInfo.CurGunSelected); } break; case S_COMPLETE: { // 回 IDLE printf("Back to IDLE = %d --------- \n", ShmSysConfigAndInfo->SysInfo.CurGunSelected); chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = 1; } break; } } leftBtnPush = true; // 左邊的選槍按鈕,只有在雙槍都在充電時候才有用 : 30KW 以下該按鈕無作用 } else if (ShmPrimaryMcuData->InputDet.bits.Button1 == BTN_RELEASE) { if(leftBtnPush) printf("left btn up............................... \n"); leftBtnPush = false; } if (ShmPrimaryMcuData->InputDet.bits.Button2 == BTN_PRESS && !rightBtnPush) { if(!rightBtnPush) { printf("right btn down............................... \n"); if (_gunCount > 1) { ShmSysConfigAndInfo->SysInfo.CurGunSelected = 1; switch(chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus) { case S_IDLE: { //ShmSysConfigAndInfo->SysInfo.WaitForPlugit = 0x01; } break; case S_CHARGING: { // 停止充電 printf("To Stop = %d --------- \n", ShmSysConfigAndInfo->SysInfo.CurGunSelected); //chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = 9; //ChargingTerminalProcess(ShmSysConfigAndInfo->SysInfo.CurGunSelected); } break; case S_COMPLETE: { // 回 IDLE printf("Back to IDLE = %d --------- \n", ShmSysConfigAndInfo->SysInfo.CurGunSelected); //chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus = 1; } break; } } } rightBtnPush = true; // 右邊的按鈕,只作用在當前頁面,當前頁面如果在可以回 Home 與 停止充電的狀態為可用 // switch(chargingInfo[ShmSysConfigAndInfo->SysInfo.CurGunSelected]->SystemStatus) // { // case S_IDLE: {}break; // case S_AUTHORIZING: {}break; // case S_PREPARING_FOR_EV: {}break; // case S_PREPARING_FOR_EVSE: {}break; // case S_CCS_PRECHARGE_ST0: {}break; // case S_CCS_PRECHARGE_ST1: {}break; // case S_CHARGING: // { // // 停止充電 // printf("Stop --------------------------------------------------- \n"); // //ChargingTerminalProcess(ShmSysConfigAndInfo->SysInfo.CurGunSelected); // } // break; // case S_COMPLETE: // { // //setChargerMode(ShmSysConfigAndInfo->SysInfo.CurGunSelected, MODE_IDLE); // } // break; // } } else if (ShmPrimaryMcuData->InputDet.bits.Button2 == BTN_RELEASE) { if(rightBtnPush) printf("right btn up............................... \n"); rightBtnPush = false; } } //=============================================== // 確認各小板偵測的錯誤狀況 //=============================================== void CheckErrorOccurStatus(byte index) { // 小板 if (chargingInfo[index]->Type == _Type_Chademo) { if (ShmStatusCodeData->InfoCode.InfoEvents.bits.ChademoChargerGetEmergencyStop == YES) EmcOccureByString(index, "023730"); else if (ShmStatusCodeData->FaultCode.FaultEvents.bits.ChademoOutputRelayDrivingFault == YES) EmcOccureByString(index, "011012"); else if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.ChademoGfdTrip == YES) EmcOccureByString(index, "012234"); } else if (chargingInfo[index]->Type == _Type_CCS) { if (ShmStatusCodeData->FaultCode.FaultEvents.bits.CcsOutputRelayDrivingFault == YES) EmcOccureByString(index, "011014"); else if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CcsGfdTrip == YES) EmcOccureByString(index, "012235"); } } //=============================================== // 確認 GPIO 狀態 //=============================================== 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 < _gunCount; i++) { if (chargingInfo[i]->slotsIndex == 1) { if (chargingInfo[i]->Type == _Type_Chademo) EmcOccureByString(i, "023730"); else if (chargingInfo[i]->Type == _Type_CCS) EmcOccureByString(i, "013627"); break; } } } break; case 27: { for(int i = 0; i < _gunCount; i++) { if (chargingInfo[i]->slotsIndex == 3) { if (chargingInfo[i]->Type == _Type_Chademo) EmcOccureByString(i, "023730"); else if (chargingInfo[i]->Type == _Type_CCS) EmcOccureByString(i, "013627"); break; } } } break; } } else { switch (pinIn[i]) { // 小板解除緊急停止 case 47: { for(int i = 0; i < _gunCount; i++) { if (chargingInfo[i]->slotsIndex == 1) { if (chargingInfo[i]->Type == _Type_Chademo) ReleaseEmsOccureByString(i, "023730"); else if (chargingInfo[i]->Type == _Type_CCS) ReleaseEmsOccureByString(i, "013627"); break; } } } break; case 27: { for (int i = 0; i < _gunCount; i++) { if (chargingInfo[i]->slotsIndex == 3) { if (chargingInfo[i]->Type == _Type_Chademo) ReleaseEmsOccureByString(i, "023730"); else if (chargingInfo[i]->Type == _Type_CCS) ReleaseEmsOccureByString(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 < _gunCount; i++) { // 二擇一 if (chargingInfo[i]->SystemStatus == S_CHARGING) { stopReq = i; } else if (chargingInfo[i]->SystemStatus == S_IDLE) { idleReq = true; } } // 有閒置的槍號,即可接受刷卡 if (idleReq || stopReq < _gunCount) { // 取卡號,假設 : 刷卡過了 if (strlen((char *)ShmSysConfigAndInfo->SysConfig.UserId) > 0) { if (stopReq < _gunCount) { char value[32]; memcpy(value, (unsigned char *)chargingInfo[stopReq]->CardNumber, ARRAY_SIZE(chargingInfo[stopReq]->CardNumber)); if (strcmp((char *)ShmSysConfigAndInfo->SysConfig.UserId, value) == EQUAL) { ChargingTerminalProcess(stopReq); strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); return; } } if (idleReq) { // LCM => Authorizing ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_AUTHORIZING; // 進入確認卡號狀態 AuthorizingStart(); // authorizing timer StartSystemTimeoutDet(Timeout_Authorizing); autoReturnTimeoutFlag = NO; } } } } else { // 確認驗證卡號完成沒 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; // 通過認證,開始確認當前要進入充電的槍號 DetectPluginStart(); } else { // LCM => Authorize fail ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_AUTHORIZ_FAIL; } ClearAuthorizedFlag(); } } } 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->SysStopChargingAlarmCode.Level == 0) { isCardScan = true; // 處理刷卡及驗證卡號的動作 UserScanFunction(); } 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; _chademoIndex++; _gunIndex++; } } break; case 'U': // CCS1 combo break; 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; chargingInfo[_gunIndex]->type_index = _ccsIndex; // 現階段預設為走 DIN70121 ShmCcsData->CommProtocol = 0x01; _ccsIndex++; _gunIndex++; } } break; case 'G': // GBT DC break; case 'D': // GBT DC x 2 break; } } bool CheckConnectorTypeStatus() { bool result = true; printf("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++; } _gunCount = _gunIndex; printf("_gunCount = %d \n", _gunCount); if (_gunCount == 0) result = false; // 偵測槍屬於哪個 slot : 可知道插在板上的Slot 0 或 1 是 Chademo 還是 CCS for (byte gunIndex = 0; gunIndex < _gunCount; 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) { 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 (_gunCount == 1) chargingInfo[gunIndex]->Evboard_id = 0x01; } else if (bd1_1_status == 1 && bd1_2_status == 0) { // 與硬體相同 type : CCS if (chargingInfo[gunIndex]->Type == _Type_CCS) { chargingInfo[gunIndex]->Evboard_id = 0x02; } if (_gunCount == 1) chargingInfo[gunIndex]->Evboard_id = 0x01; } printf("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"); } 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("Typed...%x \r\n", Type); switch (Type) { case 0x10000001: case 0x10000002: case 0x10000003: case 0x10000004: case 0x10000005: case 0x10000006: { // CSU_PRIMARY_CONTROLLER : 0x10000006 int fd = InitComPort(0x04); if (Upgrade_UART(fd, Type, 0x04, new_str, ShmSysConfigAndInfo->SysConfig.ModelName) == PASS) return PASS; else return FAIL; close(fd); } break; case 0x1000000B: { // CHAdeMO_BOARD : 0x1000000B for(byte index = 0; index < _gunCount; index++) { if (chargingInfo[index]->Type == _Type_Chademo) { int CanFd = InitCanBus(); if (CanFd > 0) { if (Upgrade_CAN(CanFd, Type, chargingInfo[index]->Evboard_id, new_str, ShmSysConfigAndInfo->SysConfig.ModelName) == PASS) { printf("Upgrad OK. \n"); return PASS; } else { printf("Upgrad Fail. \n"); return FAIL; } } else { printf("Upgrad FD fail. \n"); return FAIL; } } } break; } } } free(new_str); free(ptr); } } free(dir); closedir(d); return FAIL; } void CreateRfidFork() { pid_t rfidRecPid; rfidRecPid = fork(); if (rfidRecPid == 0) { while(true) { // 刷卡判斷 GetCardNumber(); usleep(100000); } } } void StartSystemTimeoutDet(unsigned char flag) { if (ShmSysConfigAndInfo->SysInfo.SystemTimeoutFlag != flag) { gettimeofday(&ShmSysConfigAndInfo->SysInfo.SystemTimeoutTimer, NULL); } ShmSysConfigAndInfo->SysInfo.SystemTimeoutFlag = flag; } void StopSystemTimeoutDet() { ShmSysConfigAndInfo->SysInfo.SystemTimeoutFlag = Timeout_None; } void StartGunInfoTimeoutDet(unsigned char gunIndex, unsigned char flag) { if (gunIndex < _gunCount) { if (chargingInfo[gunIndex]->TimeoutFlag != flag) { gettimeofday(&chargingInfo[gunIndex]->TimeoutTimer, NULL); } chargingInfo[gunIndex]->TimeoutFlag = flag; } } void StopGunInfoTimeoutDet(unsigned char gunIndex) { if (gunIndex < _gunCount) { chargingInfo[gunIndex]->TimeoutFlag = Timeout_None; } } void CreateTimeoutFork() { pid_t timeoutPid; timeoutPid = fork(); if (timeoutPid == 0) { while(true) { // 系統 switch(ShmSysConfigAndInfo->SysInfo.SystemTimeoutFlag) { case Timeout_SelftestChk: if (GetTimeoutValue(ShmSysConfigAndInfo->SysInfo.SystemTimeoutTimer) >= 60000000) { _SelfTestTimeout(); StopSystemTimeoutDet(); } break; case Timeout_Authorizing: if (GetTimeoutValue(ShmSysConfigAndInfo->SysInfo.SystemTimeoutTimer) >= 60000000) { _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; } // 各槍 for (byte gun_index = 0; gun_index < _gunCount; gun_index++) { 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) >= 60000000) { _DetectEvseChargingEnableTimeout(gun_index); StopGunInfoTimeoutDet(gun_index); } break; case Timeout_WaitforCompleteDet: if (GetTimeoutValue(chargingInfo[gun_index]->TimeoutTimer) >= 10000000) { _CompleteTimeout(gun_index); StopGunInfoTimeoutDet(gun_index); } break; case Timeout_ForCcsPrechargeDet: if (GetTimeoutValue(chargingInfo[gun_index]->TimeoutTimer) >= 60000000) { _CcsPrechargeTimeout(gun_index); StopGunInfoTimeoutDet(gun_index); } break; } } usleep(100000); } } } int main(void) { InitGPIO(); InitEthernet(); sleep(1); 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"); // //echo 1 > /sys/class/gpio/gpio110/value // // return 0; if(CreateShareMemory() == 0) { #ifdef SystemLogMessage DEBUG_ERROR_1("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"); } while(1) { printf("TelcomApn = %s \n", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomApn); printf("TeleConfigData TelcomIpAddress = %s \n", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomIpAddress); sleep(1); } // while(1) // { // printf("sys id = %s \n", ShmSysConfigAndInfo->SysConfig.SystemId); // printf("sys date = %s \n", ShmSysConfigAndInfo->SysConfig.SystemDateTime); // printf("Ac Phase Count = %d \n", ShmSysConfigAndInfo->SysConfig.AcPhaseCount); // printf("Factory Config = %d \n", ShmSysConfigAndInfo->SysInfo.FactoryConfiguration); // printf("Author mode = %d \n", ShmSysConfigAndInfo->SysConfig.AuthorisationMode); // printf("Default lang = %d \n", ShmSysConfigAndInfo->SysConfig.DefaultLanguage); // printf("Rfid CardNum Endian = %d \n", ShmSysConfigAndInfo->SysConfig.RfidCardNumEndian); // // printf("MaxChargingEnergy = %d \n", ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy); // printf("MaxChargingPower = %d \n", ShmSysConfigAndInfo->SysConfig.MaxChargingPower); // printf("MaxChargingCurrent = %d \n", ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent); // printf("MaxChargingDuration = %d \n", ShmSysConfigAndInfo->SysConfig.MaxChargingDuration); // printf("PhaseLossPolicy = %d \n", ShmSysConfigAndInfo->SysConfig.PhaseLossPolicy); // printf("CcsAuthentication = %d \n", ShmSysConfigAndInfo->SysConfig.AuthorisationMode); // printf("AcCcsChargingModel = %d \n", ShmSysConfigAndInfo->SysConfig.DefaultLanguage); // // printf("FtpServer = %s \n", ShmSysConfigAndInfo->SysConfig.FtpServer); // printf("Eth0DhcpClient = %d \n", ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthDhcpClient); // printf("Eth0IpAddress = %d \n", ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthDhcpClient); // printf("Eth0SubmaskAddress = %d \n", ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthDhcpClient); // printf("Eth0GatewayAddress = %d \n", ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthDhcpClient); // printf("Eth1DhcpClient = %d \n", ShmSysConfigAndInfo->SysConfig.Eth1Interface.EthDhcpClient); // printf("Eth1IpAddress = %d \n", ShmSysConfigAndInfo->SysConfig.Eth1Interface.EthDhcpClient); // printf("Eth1SubmaskAddress = %d \n", ShmSysConfigAndInfo->SysConfig.Eth1Interface.EthDhcpClient); // printf("Eth1GatewayAddress = %d \n", ShmSysConfigAndInfo->SysConfig.Eth1Interface.EthDhcpClient); // printf("WifiMode = %d \n", ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode); // printf("WifiSsid = %s \n", ShmSysConfigAndInfo->SysConfig.AthInterface.WifiSsid); // printf("WifiPassword = %s \n", ShmSysConfigAndInfo->SysConfig.AthInterface.WifiPassword); // printf("WifiDhcpServer = %d \n", ShmSysConfigAndInfo->SysConfig.AthInterface.WifiDhcpServer); // printf("WifiDhcpClient = %d \n", ShmSysConfigAndInfo->SysConfig.AthInterface.WifiDhcpClient); // printf("WifiIpAddress = %s \n", ShmSysConfigAndInfo->SysConfig.AthInterface.WifiIpAddress); // printf("WifiSubmaskAddress = %s \n", ShmSysConfigAndInfo->SysConfig.AthInterface.WifiSubmaskAddress); // printf("WifiGatewayAddress = %s \n", ShmSysConfigAndInfo->SysConfig.AthInterface.WifiGatewayAddress); // printf("TelcomApn = %d \n", ShmSysConfigAndInfo->SysConfig.DefaultLanguage); // printf("TelcomChapPapId = %s \n", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapId); // printf("TelcomChapPapPwd = %s \n", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomChapPapPwd); // printf("TelcomIpAddress = %s \n", ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomIpAddress); // // printf("BackendConnTimeout = %d \n", ShmSysConfigAndInfo->SysConfig.BackendConnTimeout); // printf("OfflinePolicy = %d \n", ShmSysConfigAndInfo->SysConfig.OfflinePolicy); // printf("OfflineMaxChargeEnergy = %d \n", ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeEnergy); // printf("OfflineMaxChargeDuration = %d \n", ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeDuration); // printf("OcppServerURL = %s \n", ShmSysConfigAndInfo->SysConfig.OcppServerURL); // printf("ChargeBoxId = %s \n", ShmSysConfigAndInfo->SysConfig.ChargeBoxId); // // sleep(3); // } printf("\n"); printf("CheckGunTypeFromHw....... \n"); CheckGunTypeFromHw(); char *moduleName = "DSYE601J0ET2PH"; memcpy(&ShmSysConfigAndInfo->SysConfig.ModelName, moduleName, strlen(moduleName)); if (!CheckConnectorTypeStatus()) { // Module Name 與硬體對應不正確 printf("Module Name & HW info none match. \n"); DEBUG_ERROR_1("Module Name & HW info none match. \n"); sleep(5); return 0; } printf("Module Name & HW info correct. Initialize.......\n"); Initialization(); printf("Spawn all Task. \n"); SpawnTask(); ChangeLcmByIndex(_LCM_INIT); CreateTimeoutFork(); printf("Self test. \n"); SelfTestRun(); StopSystemTimeoutDet(); if (ShmSysConfigAndInfo->SysInfo.SelfTestSeq == _STEST_FAIL) { for (byte gun_index = 0; gun_index < _gunCount; gun_index++) { setChargerMode(gun_index, MODE_ALARM); } ChangeLcmByIndex(_LCM_FIX); return FAIL; } else { for (byte gun_index = 0; gun_index < _gunCount; gun_index++) { setChargerMode(gun_index, MODE_IDLE); } } ChangeLcmByIndex(_LCM_IDLE); sleep(1); //***** 須新增的偵測 *****// // 1. Thernal - 控制風扇轉速 // 2. ouput fuse - 控制風扇轉速 CreateRfidFork(); // Main loop printf("Main Loop. \n"); for (;;) { ChkPrimaryStatus(); if (ShmSysConfigAndInfo->SysInfo.PageIndex == _LCM_IDLE) { //printf("ShmSysConfigAndInfo->SysInfo.FirmwareUpdate = %d \n", ShmSysConfigAndInfo->SysInfo.FirmwareUpdate); if (ShmSysConfigAndInfo->SysInfo.FirmwareUpdate == YES) { KillTask(); return FAIL; if (CheckUpdateProcess() == PASS) { printf("update complete. \n"); } else { printf("update fail. \n"); } ShmSysConfigAndInfo->SysInfo.FirmwareUpdate = NO; sleep(5); system("reboot -f"); } } // 讀卡邏輯 ScannerCardProcess(); for (byte gun_index = 0; gun_index < _gunCount; gun_index++) { CheckGpioInStatus(); CheckErrorOccurStatus(gun_index); switch(chargingInfo[gun_index]->SystemStatus) { case S_IDLE: { if (isModeChange(gun_index)) { printf("S_IDLE================================== %x \n", gun_index); chargingInfo[gun_index]->RemainChargingDuration = 0; chargingInfo[gun_index]->PresentChargedEnergy = 0; } if (ShmSysConfigAndInfo->SysStopChargingAlarmCode.Level == 2) { ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_FIX; ClearDetectPluginFlag(); } else { // 判斷是否有啟用檢查插槍 if(isDetectPlugin()) { // 卡號驗證成功後,等待充電槍插入充電車 if (chargingInfo[gun_index]->ConnectorPlugIn == YES) { ShmSysConfigAndInfo->SysInfo.CurGunSelected = gun_index; strcpy((char *)chargingInfo[gun_index]->CardNumber, (char *)ShmSysConfigAndInfo->SysConfig.UserId); // 當前操作的槍號,進入 Preparing setChargerMode(gun_index, MODE_REASSIGN_CHECK); ClearDetectPluginFlag(); ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_NONE; } else if (!isCardScan) { // LCM => Waiting for plugging ShmSysConfigAndInfo->SysInfo.SystemPage = _LCM_WAIT_FOR_PLUG; } } else { if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index) ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_IDLE; } } } break; case S_REASSIGN_CHECK: { if (isModeChange(gun_index)) { printf("S_REASSIGN_CHECK================================== %x \n", gun_index); StopSystemTimeoutDet(); } bool isRessign = false; if (_gunCount > 1) { for (byte index = 0; index < _gunCount; index++) { // 有其他槍已經分配好 psu 模塊 if (ShmSysConfigAndInfo->SysInfo.CurGunSelected != index && chargingInfo[index]->SystemStatus >= S_PREPARNING) { printf("=============Smart Charging============= Step 1 \n"); ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_PREPARE; 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("S_REASSIGN================================== %x \n", gun_index); } // 重新分配,此階段主要是讓已經在充電或者準備進入充電前的緩衝 // 此狀態下~ 控制權在於 PSU 及 EV小板 Process if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_NONE || ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_COMP) setChargerMode(gun_index, MODE_PRECHARGE); else if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_RELAY && ShmSysConfigAndInfo->SysInfo.BridgeRelayStatus == NO) { printf("=============Smart Charging : _REASSIGNED_COMP============= Step 6 \n"); ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_COMP; } if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index) ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_PRE_CHARGE; } break; case S_PREPARNING: { if (isModeChange(gun_index)) { printf("S_PREPARNING================================== %x \n", gun_index); ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE; StopGunInfoTimeoutDet(gun_index); StartGunInfoTimeoutDet(gun_index, Timeout_Preparing); } if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag != _REASSIGNED_NONE) ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE; // Precharge 三個流程 : 1 Precharge, 2 Preparing for ev, 3 Preparing for evse // Precharge : AC Contactor , Relay k1 k2 , PSU AddressAssignment, PSU GroupAvailablePower // Preparing for ev : 車端通訊流程 // Preparing for evse : PSU (output 500V, 2A), GFD Test //ShmSysConfigAndInfo->SysInfo.AcContactorStatus == YES && if (((ShmPsuData->SystemPresentPsuQuantity > 0 && ShmPsuData->PsuGroup[gun_index].GroupPresentPsuQuantity > 0 && ShmPsuData->PsuGroup[gun_index].GroupAvailablePower > 10) && chargingInfo[gun_index]->AvailableChargingPower > 10)) { setChargerMode(gun_index, MODE_PREPARE_FOR_EV); } if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index) ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_PRE_CHARGE; } break; case S_PREPARING_FOR_EV: // 等待車端的通訊 (EV 小板),待車端回報後,開始樁端的測試 { if (isModeChange(gun_index)) { printf("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) { // 檢查車端的 charging enable 是否為 1 if (isEvGunLocked_ccs(gun_index) == YES) { setChargerMode(gun_index, MODE_PREPARE_FOR_EVSE); } } if (isEvBoardStopChargeFlag(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("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); } } else if (chargingInfo[gun_index]->Type == _Type_CCS) { // 檢查樁端的 GFD 結果 if (chargingInfo[gun_index]->GroundFaultStatus == GFD_PASS) { setChargerMode(gun_index, MODE_CCS_PRECHARGE_STEP0); } } if (isEvBoardStopChargeFlag(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("S_CHARGING================================== %x \n", gun_index); StopGunInfoTimeoutDet(gun_index); ftime(&startChargingTime[gun_index]); } ftime(&endChargingTime[gun_index]); chargingInfo[gun_index]->RemainChargingDuration = DiffTimeb(startChargingTime[gun_index], endChargingTime[gun_index]); if (isEvBoardStopChargeFlag(gun_index) == YES) { // 板端要求停止 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 ("terminating......................... %x \n", gun_index); StopGunInfoTimeoutDet(gun_index); } if (chargingInfo[gun_index]->Type == _Type_Chademo) { // 非車端的停止 : 需等待小板送出停止指令,讓車端解除槍 if (isEvStopCharging_chademo(gun_index) == YES) { setChargerMode(gun_index, MODE_COMPLETE); } } else if (chargingInfo[gun_index]->Type == _Type_CCS) { // 非車端的停止 : 需等待小板送出停止指令,讓車端解除槍 if (isEvStopCharging_ccs(gun_index) == YES) { 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 ("complete......................... %x \n", gun_index); ftime(&endChargingTime[gun_index]); if (chargingInfo[gun_index]->RemainChargingDuration != 0) chargingInfo[gun_index]->RemainChargingDuration = DiffTimeb(startChargingTime[gun_index], endChargingTime[gun_index]); strcpy((char *)chargingInfo[gun_index]->CardNumber, ""); strcpy((char *)ShmSysConfigAndInfo->SysConfig.UserId, ""); StopGunInfoTimeoutDet(gun_index); // 測試智能分配,暫時先不要自動回 Idle //StartGunInfoTimeoutDet(gun_index, Timeout_WaitforCompleteDet); } if (ShmSysConfigAndInfo->SysInfo.CurGunSelected == gun_index) ShmSysConfigAndInfo->SysInfo.ConnectorPage = _LCM_COMPLETE; } break; case S_CCS_PRECHARGE_ST0: { if (isModeChange(gun_index)) { printf("CCS Precharge Processing 1....................%x \n", gun_index); StopGunInfoTimeoutDet(gun_index); StartGunInfoTimeoutDet(gun_index, Timeout_ForCcsPrechargeDet); } if (isEvBoardStopChargeFlag(gun_index) == YES) { // 板端要求停止 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("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("CCS Precharge Processing 2....................%x \n", gun_index); } if (isEvBoardStopChargeFlag(gun_index) == YES) { // 板端要求停止 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); usleep(whileLoopTime); } return FAIL; }