/*=========================================================================== Combined Charging System (CCS): SECC CsuComm.c initiated by Vern, Joseph (since 2019/07/19) =============================================================================*/ #include #include #include //#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //for pow #include #include #include "define.h" #include "CsuComm.h" #include "SeccComm.h" #include "exi_engine/api/api.h" #ifdef AWCCS #include "../main.h" #endif struct SysConfigAndInfo *ShmSysConfigAndInfo; struct StatusCodeData *ShmStatusCodeData; struct CcsData *ShmCcsData; struct InternalComm *ShmInternalComm; //struct InternalCommAC *ShmInternalCommAC; #ifdef AWCCS struct Charger *ShmCharger; #endif pid_t PID_CAN_Rx_Task; pid_t PID_CsuComm_Error_Monitor_Task; int FD_CAN_Socket; unsigned char buf_log_csucomm[SIZE_OF_LOG_BUFFER]; unsigned char buf_log_csucomm_fork1[SIZE_OF_LOG_BUFFER]; unsigned char buf_log_csucomm_fork2[SIZE_OF_LOG_BUFFER]; /*=========================================================================== FUNCTION: GetSysTime() DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void PrintTimeStamp() { //static time_t CurrentTime; //static struct tm *tm; static struct timeval tv; //CurrentTime = time(NULL); //tm = localtime(&CurrentTime); gettimeofday(&tv, NULL); // get microseconds, 10^-6 //printf("[%02d:%02d:%02d.%06d]", // tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec); DEBUG_PRINTF_CSUCOMM_DETAIL("[%05d.%06d]", tv.tv_sec, tv.tv_usec); } /*=========================================================================== FUNCTION: Check_V2G_Flow_Status DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ unsigned char Check_V2G_Flow_Status() { unsigned char result = 0; switch (ShmCcsData->CommProtocol) { case V2GT_MSG_PROTOCOL_DIN70121: //0 { result = ShmCcsData->V2GMessage_DIN70121.PresentMsgFlowStatus; break; } case V2GT_MSG_PROTOCOL_ISO15118_2014: //1 { result = ShmCcsData->V2GMessage_ISO15118_2014.PresentMsgFlowStatus; break; } case V2GT_MSG_PROTOCOL_ISO15118_2018: //2 { result = ShmCcsData->V2GMessage_ISO15118_2018.PresentMsgFlowStatus; break; } default: break; } return result; } /*=========================================================================== FUNCTION: StoreLogMsg DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ #if SAVE_SYS_LOG_MSG_CSUCOMM_SWITCH == ENABLE int StoreLogMsg2(unsigned char *DataString) { static unsigned char Buf[256*2]; static time_t CurrentTime; static struct tm *tm; static struct timeval tv; memset(Buf, 0, sizeof(Buf)); CurrentTime = time(NULL); tm = localtime(&CurrentTime); gettimeofday(&tv, NULL); // get microseconds, 10^-6 #ifdef AWCCS sprintf(Buf, "echo \"[%04d%02d%02d: %02d:%02d:%02d.%06d][CsuComm][%d][%02d]%s\" >> /Storage/SystemLog/[%04d.%02d]CCS-SystemLog", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec, EVCOMM_SYS_INFO.CpState, Check_V2G_Flow_Status(), DataString, tm->tm_year + 1900, tm->tm_mon + 1); #else sprintf(Buf, "echo \"[%04d%02d%02d: %02d:%02d:%02d.%06d][CsuComm][%d][%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, tv.tv_usec, EVCOMM_SYS_INFO.CpState, Check_V2G_Flow_Status(), DataString, tm->tm_year + 1900, tm->tm_mon + 1); #endif system(Buf); DEBUG_PRINTF_CSUCOMM_SYSTEM_LOG("[%02d:%02d:%02d.%06d][CsuComm][%d][%02d]%s \n", tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec, EVCOMM_SYS_INFO.CpState, Check_V2G_Flow_Status(), DataString); //Reset the buf_log_csucomm Buffer, i.e. DataString memset(buf_log_csucomm, 0, SIZE_OF_LOG_BUFFER); } #endif /*=========================================================================== FUNCTION: Array_Check_All_Zero DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: result: (1) TRUE: all zero (2) FALSE: not all zero GLOBAL VARIABLES: =============================================================================*/ int Array_Check_All_Zero(unsigned char *ptr, int size) { int result = TRUE; int i = 0; for (i = 0; i < size; i++) { if (ptr[i] != 0) { result = FALSE; break; } } return result; } /*=========================================================================== FUNCTION: Array_Compare_Identity DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: result = FALSE (not identical) result = TRUE (identical) GLOBAL VARIABLES: =============================================================================*/ int Array_Compare_Identity(unsigned char *ptrA, unsigned char *ptrB, int size) { int result = TRUE; int i = 0; for (i = 0; i < size; i++) { if (ptrA[i] != ptrB[i]) { result = FALSE; #if 0 sprintf(buf_log_evcomm, "[Array_Compare_Identity]%02X%02X%02X%02X%02X%02X,%02X%02X%02X%02X%02X%02X(%d)\n", ptrA[0], ptrA[1], ptrA[2], ptrA[3], ptrA[4], ptrA[5], ptrB[0], ptrB[1], ptrB[2], ptrB[3], ptrB[4], ptrB[5], result); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_evcomm); #endif break; } } return result; } /*=========================================================================== FUNCTION: CAN_Tx_MSG DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int CAN_Tx_MSG(int Fd, unsigned int MsgId, unsigned char SlaveAddress, unsigned char DataLength, unsigned char *SendData) { struct can_frame frame; unsigned int tmp = 0; int nbytes = 0; int i = 0; //Protection: To avoid unexpected length for CAN bus payload. if (DataLength > 8) { DataLength = 8; } memset(&frame, 0, sizeof(struct can_frame)); frame.can_id = 0x80000000 | CAN_SEND_DIRECTION | MsgId | SlaveAddress; //0x80000000: extension ID format frame.can_dlc = DataLength; memcpy(frame.data, SendData, DataLength); nbytes = write(Fd, &frame, sizeof(struct can_frame)); #if 0 DEBUG_PRINTF_CSUCOMM_DETAIL("[CsuComm][CAN_Tx_MSG] <%X> ", frame.can_id); for (i = 0; i < frame.can_dlc; i++) { DEBUG_PRINTF_CSUCOMM_DETAIL("%02X ", frame.data[i]); } DEBUG_PRINTF_CSUCOMM_DETAIL("(%d Bytes)\n", frame.can_dlc); #endif return nbytes; } /*=========================================================================== FUNCTION: Sniffer_Candump DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: 0: accept -1: invalid GLOBAL VARIABLES: =============================================================================*/ int Sniffer_Candump(char cmd) { #if (CANDUMP_PACKETS_SNIFFER_SWITCH == ENABLE) if (cmd == ENABLE) { SAVE_SYS_LOG_MSG_CSUCOMM("[candump]init"); system("cd /mnt/;rm -rf candump/"); system("cd /mnt/;mkdir candump"); SAVE_SYS_LOG_MSG_CSUCOMM("[candump]on"); system("cd /mnt/candump;candump -l can0 &"); return 0; } else if (cmd == DISABLE) { SAVE_SYS_LOG_MSG_CSUCOMM("[candump]off"); system("killall candump"); SAVE_SYS_LOG_MSG_CSUCOMM("[candump]save"); system("cd /;cp -rfv /mnt/candump /Storage/SystemLog/"); return 0; } else { sprintf(buf_log_csucomm, "[candump]unexpected cmd(%d)", cmd); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); return -1; } #endif } /*=========================================================================== FUNCTION: Checksum_Generator DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ unsigned char Checksum_Generator(unsigned int StartAdress, unsigned int length, unsigned char Data[]) { unsigned char checksum = 0x00; for(unsigned int i = 0; i < length; i++) { //DEBUG_INFO("value = %x \n", Data[StartAdress + i]); checksum ^= Data[StartAdress + i]; //DEBUG_INFO("checksum = %x \n", checksum); } return checksum; } /*=========================================================================== FUNCTION: CRC32_Generator DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ unsigned int CRC32_Generator(unsigned char *data, unsigned int length) { unsigned char i; unsigned int cnt = 0; unsigned int crc = 0xffffffff; // Initial value while(length--) { if(cnt > 33 && cnt < 48) { data++; } else { crc ^= *data++; // crc ^= *data; data++; for (i = 0; i < 8; ++i) { if (crc & 1) { crc = (crc >> 1) ^ 0xEDB88320;// 0xEDB88320= reverse 0x04C11DB7 } else { crc = (crc >> 1); } } } cnt++; } return ~crc; } /*=========================================================================== FUNCTION: Get_GPIO_Value DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int Get_GPIO_Value(unsigned int gpio) { int fd; char buf[32]; char ch; snprintf(buf, sizeof(buf), GPIO_SYS_DIR"/gpio%d/value", gpio); fd = open(buf, O_RDONLY); if (fd < 0) { perror("gpio/get-value"); return fd; } read(fd, &ch, 1); close(fd); if (ch != '0') { return 1; } else { return 0; } } /*=========================================================================== FUNCTION: DiffTimeb DESCRIPTION: 1. Data structure of timeb.h The header defines the timeb structure that includes at least the following members: - time_t time the seconds portion of the current time - unsigned short millitm the milliseconds portion of the current time - short timezone the local timezone in minutes west of Greenwich - short dstflag TRUE if Daylight Savings Time is in effect PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ double DiffTimeb(struct timeb ST, struct timeb ET) { //return milli-second double StartTime, EndTime; double t_diff; StartTime = ((double)ST.time)*1000 + (double)ST.millitm; EndTime = ((double)ET.time)*1000 + (double)ET.millitm; t_diff = EndTime - StartTime; //printf("%.02lf - %.02lf = %.02lf\n", EndTime, StartTime, t_diff); if (t_diff < 0) { #if 0 if (t_diff < -1000) //1000ms { sprintf(buf_log_csucomm, "[Warning]StartTime(%.02lf) > EndTime(%.02lf), d(%.02lf)", StartTime, EndTime, t_diff); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); } #endif return -1; } return t_diff; } /*=========================================================================== FUNCTION: DiffTimeb_CsuComm_fork1 DESCRIPTION: 1. fork1 PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ double DiffTimeb_CsuComm_fork1(struct timeb ST, struct timeb ET) { //return milli-second double StartTime, EndTime; double t_diff; StartTime = ((double)ST.time)*1000 + (double)ST.millitm; EndTime = ((double)ET.time)*1000 + (double)ET.millitm; t_diff = EndTime - StartTime; if (t_diff < 0) { #if 0 if (t_diff < -1000) //1000ms { sprintf(buf_log_csucomm_fork1, "[fork1][Warning]StartTime(%.02lf) > EndTime(%.02lf), d(%.02lf)", StartTime, EndTime, t_diff); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm_fork1); } #endif return -1; } return t_diff; } /*=========================================================================== FUNCTION: ShareMemory_Init DESCRIPTION Initialize all share memories. PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int ShareMemory_Init() { int MeterSMId; #ifdef AWCCS //[1/5] create ShmSysConfigAndInfo if((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), IPC_CREAT | 0777)) < 0) { SAVE_SYS_LOG_MSG_CSUCOMM("ShareMemory_Init:shmget ShmSysConfigAndInfo NG"); return 0; } else if((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *)-1) { SAVE_SYS_LOG_MSG_CSUCOMM("ShareMemory_Init:shmat ShmSysConfigAndInfo NG"); return 0; } memset(ShmSysConfigAndInfo, 0, sizeof(struct SysConfigAndInfo)); //[2/5] create ShmStatusCodeData if((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), IPC_CREAT |0777)) < 0) { SAVE_SYS_LOG_MSG_CSUCOMM("ShareMemory_Init:shmget ShmStatusCodeData NG"); return 0; } else if((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *)-1) { SAVE_SYS_LOG_MSG_CSUCOMM("ShareMemory_Init:shmat ShmStatusCodeData NG"); return 0; } memset(ShmStatusCodeData, 0, sizeof(struct StatusCodeData)); //[3/5] create ShmCcsData if((MeterSMId = shmget(ShmCcsCommKey, sizeof(struct CcsData), IPC_CREAT |0777)) < 0) { SAVE_SYS_LOG_MSG_CSUCOMM("ShareMemory_Init:shmget ShmCcsData NG"); return 0; } else if((ShmCcsData = shmat(MeterSMId, NULL, 0)) == (void *)-1) { SAVE_SYS_LOG_MSG_CSUCOMM("ShareMemory_Init:shmat ShmCcsData NG"); return 0; } memset(ShmCcsData, 0, sizeof(struct CcsData)); //[4/5] create ShmInternalComm if((MeterSMId = shmget(ShmInternalCommKey, sizeof(struct InternalComm), IPC_CREAT | 0777)) < 0) { SAVE_SYS_LOG_MSG_CSUCOMM("ShareMemory_Init:shmget ShmInternalComm NG"); return 0; } else if((ShmInternalComm = shmat(MeterSMId, NULL, 0)) == (void *)-1) { SAVE_SYS_LOG_MSG_CSUCOMM("ShareMemory_Init:shmat ShmInternalComm NG"); return 0; } memset(ShmInternalComm, 0, sizeof(struct InternalComm)); #if 0 //[5/5] create ShmInternalCommAC if((MeterSMId = shmget(ShmInternalCommACKey, sizeof(struct InternalCommAC), IPC_CREAT | 0777)) < 0) { SAVE_SYS_LOG_MSG_CSUCOMM("ShareMemory_Init:shmget ShmInternalCommAC NG"); return 0; } else if((ShmInternalCommAC = shmat(MeterSMId, NULL, 0)) == (void *)-1) { SAVE_SYS_LOG_MSG_CSUCOMM("ShareMemory_Init:shmat ShmInternalCommAC NG"); return 0; } //memset(ShmInternalCommAC, 0, sizeof(struct InternalCommAC)); #endif //creat ShmCharger if ((MeterSMId = shmget(ShmChargerKey, sizeof(struct Charger), 0777)) < 0) { SAVE_SYS_LOG_MSG_CSUCOMM("shmget ShmCharger NG\n"); return 0; } else if ((ShmCharger = shmat(MeterSMId, NULL, 0)) == (void *) -1) { SAVE_SYS_LOG_MSG_CSUCOMM("shmat ShmCharger NG\n"); return 0; } #else //[1/5] create ShmSysConfigAndInfo if((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), 0777)) < 0) { SAVE_SYS_LOG_MSG_CSUCOMM("ShareMemory_Init:shmget ShmSysConfigAndInfo NG"); return 0; } else if((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *)-1) { SAVE_SYS_LOG_MSG_CSUCOMM("ShareMemory_Init:shmat ShmSysConfigAndInfo NG"); return 0; } //[2/5] create ShmStatusCodeData if((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), 0777)) < 0) { SAVE_SYS_LOG_MSG_CSUCOMM("ShareMemory_Init:shmget ShmStatusCodeData NG"); return 0; } else if((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *)-1) { SAVE_SYS_LOG_MSG_CSUCOMM("ShareMemory_Init:shmat ShmStatusCodeData NG"); return 0; } //[3/5] create ShmCcsData if((MeterSMId = shmget(ShmCcsCommKey, sizeof(struct CcsData), 0777)) < 0) { SAVE_SYS_LOG_MSG_CSUCOMM("ShareMemory_Init:shmget ShmCcsData NG"); return 0; } else if((ShmCcsData = shmat(MeterSMId, NULL, 0)) == (void *)-1) { SAVE_SYS_LOG_MSG_CSUCOMM("ShareMemory_Init:shmat ShmCcsData NG"); return 0; } //[4/5] create ShmInternalComm if((MeterSMId = shmget(ShmInternalCommKey, sizeof(struct InternalComm), 0777)) < 0) { SAVE_SYS_LOG_MSG_CSUCOMM("ShareMemory_Init:shmget ShmInternalComm NG"); return 0; } else if((ShmInternalComm = shmat(MeterSMId, NULL, 0)) == (void *)-1) { SAVE_SYS_LOG_MSG_CSUCOMM("ShareMemory_Init:shmat ShmInternalComm NG"); return 0; } //memset(ShmInternalComm, 0, sizeof(struct InternalComm)); #endif return 1; } /*=========================================================================== FUNCTION: CANBus_Init DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int CANBus_Init() { int s0, nbytes; struct timeval tv; struct ifreq ifr0; struct sockaddr_can addr0; 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); if (s0 < 0) //added by Joseph (not full implemented) { SAVE_SYS_LOG_MSG_CSUCOMM("[ERROR] Fail on initializing CAN Bus socket"); } tv.tv_sec = 0; tv.tv_usec = 10000; if(setsockopt(s0, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)) < 0) { SAVE_SYS_LOG_MSG_CSUCOMM("CANBus_Init:Set SO_RCVTIMEO NG"); } nbytes = 40960; if(setsockopt(s0, SOL_SOCKET, SO_RCVBUF, &nbytes, sizeof(int)) < 0) { SAVE_SYS_LOG_MSG_CSUCOMM("CANBus_Init:Set SO_RCVBUF NG"); } nbytes = 40960; if(setsockopt(s0, SOL_SOCKET, SO_SNDBUF, &nbytes, sizeof(int)) < 0) { SAVE_SYS_LOG_MSG_CSUCOMM("CANBus_Init:Set SO_SNDBUF NG"); } 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; } /*=========================================================================== FUNCTION: Update_EVSE_INFO_to_SHMs DESCRIPTION: Updating all corresponding content in each Share Memory. 1. I_now 2. V_now 3. P_now 4. I_max 5. V_max 6. P_max PRE-CONDITION: INPUT: 1. ShmInternalComm OUTPUT: 1. ShmCcsData * PreChargeResponse * CurrentDemandResponse * WeldingDetectionResponse 2. ShmSysConfigAndInfo GLOBAL VARIABLES: =============================================================================*/ void Update_EVSE_INFO_to_SHMs() { int I_now = 0; //0.1A int V_now = 0; //0.1V int P_now = 0; //0.1KW int I_max = 0; //0.1A int V_max = 0; //0.1V int P_max = 0; //0.1KW //[CAUTION] Re-initializing process is necessary. (to-be implemented) //----------[1/7] Permission -------- if (ShmInternalComm->ChargingPermission_new != ShmInternalComm->ChargingPermission) { sprintf(buf_log_csucomm, "Permission: %d >> %d", ShmInternalComm->ChargingPermission, ShmInternalComm->ChargingPermission_new ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); ShmInternalComm->ChargingPermission_pre = ShmInternalComm->ChargingPermission; ShmInternalComm->ChargingPermission = ShmInternalComm->ChargingPermission_new; } // -------- [3/7] V_now -------- V_now = ShmInternalComm->PresentChargingVoltage; EVCOMM_SYS_INFO.PresentChargingVoltage = V_now / 10.0; //1V if (ShmInternalComm->PresentChargingVoltage_pre != ShmInternalComm->PresentChargingVoltage) { if (abs(ShmInternalComm->PresentChargingVoltage_pre - ShmInternalComm->PresentChargingVoltage) > 10) //10:1V { unsigned char state = 0; state = Check_V2G_Flow_Status(); if(state == CableCheckRequest || state == CableCheckResponse || //37, 38 state == PreChargeRequest || state == PreChargeResponse || //39, 40 state == CurrentDemandRequest || state == CurrentDemandResponse) //45, 46 { if ((ShmInternalComm->PresentChargingVoltage <= 600) || //600:60V (ShmInternalComm->PresentChargingVoltage >= 1500) //1500:150V ) { sprintf(buf_log_csucomm, "V_now(EVSE): %d >> %d (0.1V, DEC)", ShmInternalComm->PresentChargingVoltage_pre, ShmInternalComm->PresentChargingVoltage ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); } } else { sprintf(buf_log_csucomm, "V_now(EVSE): %d >> %d (0.1V, DEC)", ShmInternalComm->PresentChargingVoltage_pre, ShmInternalComm->PresentChargingVoltage ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); } } ShmInternalComm->PresentChargingVoltage_pre = ShmInternalComm->PresentChargingVoltage; } // -------- [2/7] I_now -------- I_now = ShmInternalComm->PresentChargingCurrent; EVCOMM_SYS_INFO.PresentChargingCurrent = I_now / 10.0; //1A if (ShmInternalComm->PresentChargingCurrent_pre != ShmInternalComm->PresentChargingCurrent) { if ((abs(ShmInternalComm->PresentChargingCurrent_pre - ShmInternalComm->PresentChargingCurrent) > 20)&& (ShmInternalComm->PresentChargingVoltage >= 100)) { //memset(buf_log_csucomm, 0, sizeof(buf_log_csucomm)); sprintf(buf_log_csucomm, "I_now(EVSE): %d >> %d (0.1A, DEC)", ShmInternalComm->PresentChargingCurrent_pre, ShmInternalComm->PresentChargingCurrent ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); } ShmInternalComm->PresentChargingCurrent_pre = ShmInternalComm->PresentChargingCurrent; } // -------- [4/7] P_now -------- ShmInternalComm->PresentChargingPower = (int)(((I_now/10) * (V_now/10)) / 100); //0.1KW P_now = ShmInternalComm->PresentChargingPower; EVCOMM_SYS_INFO.PresentChargingPower = P_now * 10.0; //1KW if (ShmInternalComm->PresentChargingPower_pre != ShmInternalComm->PresentChargingPower) { sprintf(buf_log_csucomm, "P_now(EVSE): %d >> %d (0.1KW, DEC)", ShmInternalComm->PresentChargingPower_pre, ShmInternalComm->PresentChargingPower); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); ShmInternalComm->PresentChargingPower_pre = ShmInternalComm->PresentChargingPower; } // -------- [5/7] I_max -------- I_max = ShmInternalComm->AvailableChargingCurrent; EVCOMM_SYS_INFO.AvailableChargingCurrent = I_max / 10.0; //1A if (ShmInternalComm->AvailableChargingCurrent_pre != ShmInternalComm->AvailableChargingCurrent) { sprintf(buf_log_csucomm, "I_max(EVSE): %d >> %d (0.1A, DEC)", ShmInternalComm->AvailableChargingCurrent_pre, ShmInternalComm->AvailableChargingCurrent); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); ShmInternalComm->AvailableChargingCurrent_pre = ShmInternalComm->AvailableChargingCurrent; } // -------- [6/7] V_max -------- V_max = ShmInternalComm->MaximumChargingVoltage; EVCOMM_SYS_INFO.MaximumChargingVoltage = V_max / 10.0; //1V if (ShmInternalComm->MaximumChargingVoltage_pre != ShmInternalComm->MaximumChargingVoltage) { sprintf(buf_log_csucomm, "V_max(EVSE): %d >> %d (0.1V, DEC)", ShmInternalComm->MaximumChargingVoltage_pre, ShmInternalComm->MaximumChargingVoltage ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); ShmInternalComm->MaximumChargingVoltage_pre = ShmInternalComm->MaximumChargingVoltage; } // -------- [7/7] P_max -------- P_max = ShmInternalComm->AvailableChargingPower; EVCOMM_SYS_INFO.AvailableChargingPower = P_max / 10.0; //1KW if (ShmInternalComm->AvailableChargingPower_pre != ShmInternalComm->AvailableChargingPower) { sprintf(buf_log_csucomm, "P_max(EVSE): %d >> %d (0.1KW, DEC)", ShmInternalComm->AvailableChargingPower_pre, ShmInternalComm->AvailableChargingPower); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); ShmInternalComm->AvailableChargingPower_pre = ShmInternalComm->AvailableChargingPower; } } /*=========================================================================== FUNCTION: Proc_EVBoardStatusRes DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int Proc_EVBoardStatusRes(int Fd) { int nbytes; unsigned char Buffer[8]; memset(Buffer, 0, sizeof(Buffer)); Buffer[0] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].ConnectorPlugIn; Buffer[1] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].CpState; /* if(strlen(ShmStatusCodeData->PresentStatusCode[0]) > 0) { memcpy(Buffer + 2, ShmStatusCodeData->PresentStatusCode[0], 6); } */ Buffer[2] = ShmStatusCodeData->PresentStatusCode[0][0]; Buffer[3] = ShmStatusCodeData->PresentStatusCode[0][1]; Buffer[4] = ShmStatusCodeData->PresentStatusCode[0][2]; Buffer[5] = ShmStatusCodeData->PresentStatusCode[0][3]; Buffer[6] = ShmStatusCodeData->PresentStatusCode[0][4]; Buffer[7] = ShmStatusCodeData->PresentStatusCode[0][5]; nbytes = CAN_Tx_MSG(Fd, CAN_CMD_EV_BOARD_STATUS, ShmInternalComm->SlaveAddress, 8, Buffer); CSUCOMMDC_TASK_FLAG.Send_EVBoardStatus = FALSE; return nbytes; } /*=========================================================================== FUNCTION: Proc_AddressAssignRes DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void Proc_AddressAssignRes(int Fd) { } /*=========================================================================== FUNCTION: Proc_AddressAssignReq DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void Proc_AddressAssignReq(struct can_frame *frame) { //[CAUTION] There should not be such message ID here. // A warning alarm should be recorded. DEBUG_PRINTF_CSUCOMM_DETAIL("[CsuComm][Proc_AddressAssignReq] Unexpected message of address assignment from CSU.\n"); ShmInternalComm->SlaveAddress = frame->can_id & 0x000000FF; CSUCOMMDC_TASK_FLAG.Got_AssignedAddress = TRUE; } /*=========================================================================== FUNCTION: Proc_GetFirmwareVersionRes DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int Proc_GetFirmwareVersionRes(int Fd) { int i = 0, j = 0, nbytes = 0; unsigned char str[FIRMWARE_VERSION_LENGTH + 1]; unsigned char buf[FIRMWARE_VERSION_LENGTH]; memset(buf, 0, sizeof(buf)); strcpy(str, FIRMWARE_VERSION); for(i = 0; i < FIRMWARE_VERSION_LENGTH + 3; i++) { if (str[i] != '_') { buf[j] = str[i]; j++; } } nbytes = CAN_Tx_MSG(Fd, CAN_CMD_GET_FW_VERSION, ShmInternalComm->SlaveAddress, FIRMWARE_VERSION_LENGTH, buf); CSUCOMMDC_TASK_FLAG.Got_FWVersionReq = FALSE; return nbytes; } /*=========================================================================== FUNCTION: Proc_GetFirmwareVersionReq DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void Proc_GetFirmwareVersionReq(struct can_frame *frame) { CSUCOMMDC_TASK_FLAG.Got_FWVersionReq = TRUE; } /*=========================================================================== FUNCTION: Proc_HardwareVersionRes DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int Proc_HardwareVersionRes(int Fd) { int i = 0, nbytes = 0; unsigned char str[HARDWARE_VERSION_LENGTH + 1]; unsigned char buf[HARDWARE_VERSION_LENGTH]; memset(buf, 0, sizeof(buf)); strcpy(str, HARDWARE_VERSION); for(i = 0; i < HARDWARE_VERSION_LENGTH; i++) { buf[i] = str[i]; } nbytes = CAN_Tx_MSG(Fd, CAN_CMD_GET_HW_VERSION, ShmInternalComm->SlaveAddress, HARDWARE_VERSION_LENGTH, buf); CSUCOMMDC_TASK_FLAG.Got_HWVersionReq = FALSE; return nbytes; } /*=========================================================================== FUNCTION: Proc_HardwareVersionReq DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void Proc_HardwareVersionReq(struct can_frame *frame) { CSUCOMMDC_TASK_FLAG.Got_HWVersionReq = TRUE; } /*=========================================================================== FUNCTION: Proc_GetMiscellaneousInfoRes DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int Proc_GetMiscellaneousInfoRes(int Fd) { //DEBUG_PRINTF_CSUCOMM_DETAIL("[CsuComm][Proc_GetMiscellaneousInfoRes] To-be implemented.\n"); int nbytes; unsigned char Buffer[8]; unsigned short TmpValue; memset(Buffer, 0, sizeof(Buffer)); Buffer[0] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].ConnectorLocked; Buffer[1] =ShmSysConfigAndInfo->SysInfo.CcsConnectorTemp&0xFF; Buffer[2] =(ShmSysConfigAndInfo->SysInfo.CcsConnectorTemp>>8)&0xFF; Buffer[3] = (unsigned char)(ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].CpVoltage * 10); Buffer[4] = ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].CpState; nbytes = CAN_Tx_MSG(Fd, CAN_CMD_GET_MISC_INFO, ShmInternalComm->SlaveAddress, 7, Buffer); CSUCOMMDC_TASK_FLAG.Got_MiscellaneousInfoReq = FALSE; return nbytes; } /*=========================================================================== FUNCTION: Proc_GetMiscellaneousInfoReq DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void Proc_GetMiscellaneousInfoReq(struct can_frame *frame) { CSUCOMMDC_TASK_FLAG.Got_MiscellaneousInfoReq = TRUE; } /*=========================================================================== FUNCTION: Proc_ChargingPermissionRes DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int Proc_ChargingPermissionRes(int Fd) { //Save into ShmCcsData //[1/2] Updating Parameters Update_EVSE_INFO_to_SHMs(); //[2/2] Check if SECC is in the End_Process or Initial stage if ((EVCOMM_SYS_INFO.End_Process_inused == TRUE) || (EVCOMM_SYS_INFO.QCA7K_SetKeyDone == FALSE)) { if (ShmInternalComm->ChargingPermission == TRUE) { //Update_ShmStatusCode(); //[To-Do] to be implemented //CCS_SECC_Not_Ready_For_Charging (023891) ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 2; ShmStatusCodeData->PresentStatusCode[0][2] = 3; ShmStatusCodeData->PresentStatusCode[0][3] = 8; ShmStatusCodeData->PresentStatusCode[0][4] = 9; ShmStatusCodeData->PresentStatusCode[0][5] = 1; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; //This Stop command will be delivered to CSU once SECC receives //one permission as TRUE command. } } CSUCOMMDC_TASK_FLAG.Got_ChargingPermission = FALSE; } /*=========================================================================== FUNCTION: Proc_ChargingPermissionReq DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void Proc_ChargingPermissionReq(struct can_frame *frame) { ShmInternalComm->ChargingPermission_new = frame->data[0]; ShmInternalComm->AvailableChargingPower = (unsigned int) ((frame->data[2] << 8) | frame->data[1]); ShmInternalComm->AvailableChargingCurrent = (unsigned int) ((frame->data[4] << 8) | frame->data[3]); ShmInternalComm->MaximumChargingVoltage = (unsigned int) ((frame->data[6] << 8) | frame->data[5]); ShmInternalComm->MaximumAllowedChargingTime = frame->data[7]; //0: unlimited, 0x01: 1 minutes ~ 0xFF: 255 minutes, resolution: 1 minute DEBUG_PRINTF_CSUCOMM_DETAIL("[CsuComm][CAN_Rx]\n\ \t - AvailableChargingPower = (%d, %02X, %02X)\n\ \t - AvailableChargingCurrent = (%d, %02X, %02X)\n\ \t - MaximumChargingVoltage = (%d, %02X, %02X)\n", ShmInternalComm->AvailableChargingPower, frame->data[2], frame->data[1], ShmInternalComm->AvailableChargingCurrent, frame->data[4], frame->data[3], ShmInternalComm->MaximumChargingVoltage, frame->data[6], frame->data[5] ); //Update Flag CSUCOMMDC_TASK_FLAG.Got_ChargingPermission = TRUE; } /*=========================================================================== FUNCTION: Proc_EVSEOutputStatusUpdateRes DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int Proc_EVSEOutputStatusUpdateRes(int Fd) { Update_EVSE_INFO_to_SHMs(); //Update Flag CSUCOMMDC_TASK_FLAG.Got_EVSEOutputStatus = FALSE; } /*=========================================================================== FUNCTION: Proc_EVSEOutputStatusUpdateReq DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void Proc_EVSEOutputStatusUpdateReq(struct can_frame *frame) { if(ShmInternalComm->SlaveAddress == 1) { ShmInternalComm->PresentChargingVoltage = ((unsigned int)frame->data[1] << 8 | frame->data[0]); ShmInternalComm->PresentChargingCurrent = ((unsigned int)frame->data[3] << 8 | frame->data[2]); } else { ShmInternalComm->PresentChargingVoltage = ((unsigned int)frame->data[5] << 8 | frame->data[4]); ShmInternalComm->PresentChargingCurrent = ((unsigned int)frame->data[7] << 8 | frame->data[6]); } //Update Flag CSUCOMMDC_TASK_FLAG.Got_EVSEOutputStatus = TRUE; } /*=========================================================================== FUNCTION: Proc_EVSECapacityUpdateRes DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int Proc_EVSECapacityUpdateRes(int Fd) { Update_EVSE_INFO_to_SHMs(); CSUCOMMDC_TASK_FLAG.Got_EnergyCapacity = FALSE; } /*=========================================================================== FUNCTION: Proc_EVSECapacityUpdateReq DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void Proc_EVSECapacityUpdateReq(struct can_frame *frame) { if(ShmInternalComm->SlaveAddress == 1) { ShmInternalComm->AvailableChargingPower = ((unsigned int)frame->data[1] << 8 | frame->data[0]); ShmInternalComm->AvailableChargingCurrent = ((unsigned int)frame->data[3] << 8 | frame->data[2]); } else { ShmInternalComm->AvailableChargingPower = ((unsigned int)frame->data[5] << 8 | frame->data[4]); ShmInternalComm->AvailableChargingCurrent = ((unsigned int)frame->data[7] << 8 | frame->data[6]); } //Update Flag CSUCOMMDC_TASK_FLAG.Got_EnergyCapacity = TRUE; } /*=========================================================================== FUNCTION: Proc_GetEVTargetRes DESCRIPTION: #define CAN_CMD_GET_EV_TARGET_INFO 0x00000900 PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int Proc_GetEVTargetRes(int Fd) { //DEBUG_PRINTF_CSUCOMM_DETAIL("[CsuComm][Proc_GetEVTargetRes] To-be implemented.\n"); int nbytes; unsigned char Buffer[8]; unsigned short TmpValue; static struct ChargingInfoData *sys; sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0]; memset(Buffer, 0, sizeof(Buffer)); Buffer[0] = Check_V2G_Flow_Status(); //[1/4] SOC if (sys->EvBatterySoc_pre != sys->EvBatterySoc) { //memset(buf_log_csucomm, 0, sizeof(buf_log_csucomm)); sprintf(buf_log_csucomm, "SOC = %d >> %d", sys->EvBatterySoc_pre, sys->EvBatterySoc ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); sys->EvBatterySoc_pre = sys->EvBatterySoc; } Buffer[1] = sys->EvBatterySoc; //printf("[CsuComm] V_ev_target = %.02f\n", sys->EvBatterytargetVoltage); //[2/4] EV Target Voltage if (sys->EvBatterytargetVoltage_pre != sys->EvBatterytargetVoltage) { //memset(buf_log_csucomm, 0, sizeof(buf_log_csucomm)); sprintf(buf_log_csucomm, "V_target = %.02f >> %.02f (1V, DEC)", sys->EvBatterytargetVoltage_pre, sys->EvBatterytargetVoltage ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); sys->EvBatterytargetVoltage_pre = sys->EvBatterytargetVoltage; } TmpValue = (unsigned short) (sys->EvBatterytargetVoltage * 10); memcpy(Buffer + 2, &TmpValue, 2); //[3/4] EV Target Current if (sys->EvBatterytargetCurrent_pre != sys->EvBatterytargetCurrent) { //memset(buf_log_csucomm, 0, sizeof(buf_log_csucomm)); sprintf(buf_log_csucomm, "I_target = %.02f >> %.02f (1A, DEC)", sys->EvBatterytargetCurrent_pre, sys->EvBatterytargetCurrent ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); sys->EvBatterytargetCurrent_pre = sys->EvBatterytargetCurrent; } TmpValue = (unsigned short) (sys->EvBatterytargetCurrent * 10); memcpy(Buffer + 4, &TmpValue, 2); //[4/4] Remaining Time TmpValue = (unsigned short) sys->RemainChargingDuration; memcpy(Buffer + 6, &TmpValue, 2); nbytes = CAN_Tx_MSG(Fd, CAN_CMD_GET_EV_TARGET_INFO, ShmInternalComm->SlaveAddress, 8, Buffer); CSUCOMMDC_TASK_FLAG.Got_EVTargetReq = FALSE; return nbytes; } /*=========================================================================== FUNCTION: Proc_GetEVTargetReq DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void Proc_GetEVTargetReq(struct can_frame *frame) { CSUCOMMDC_TASK_FLAG.Got_EVTargetReq = TRUE; } /*=========================================================================== FUNCTION: Proc_GetEVBatteryInfoRes DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int Proc_GetEVBatteryInfoRes(int Fd) { int nbytes; unsigned char Buffer[8]; unsigned short TmpValue; memset(Buffer, 0, sizeof(Buffer)); //[To-Do] Adding the consideration of ISO15118_2018 if((ShmCcsData->CommProtocol == V2GT_MSG_PROTOCOL_ISO15118_2014) && (ShmCcsData->V2GMessage_ISO15118_2014.ChargeParameterDiscoveryRequest.RequestedEnergyTransferMode <= 1)) { Buffer[0] = 1;//AC } else { Buffer[0] = 0;//DC } if(ShmCcsData->CommProtocol == V2GT_MSG_PROTOCOL_DIN70121) { //DIN70121 TmpValue = DIN70121PhyValDecode(ShmCcsData->V2GMessage_DIN70121.ChargeParameterDiscoveryRequest.DC_EVChargeParameter.EVEnergyCapacity) * 10; memcpy(Buffer + 1, &TmpValue, 2); TmpValue = DIN70121PhyValDecode(ShmCcsData->V2GMessage_DIN70121.ChargeParameterDiscoveryRequest.DC_EVChargeParameter.EVMaximumVoltageLimit) * 10; memcpy(Buffer + 3, &TmpValue, 2); TmpValue = DIN70121PhyValDecode(ShmCcsData->V2GMessage_DIN70121.ChargeParameterDiscoveryRequest.DC_EVChargeParameter.EVMaximumCurrentLimit) * 10; memcpy(Buffer + 5, &TmpValue, 2); } else if(ShmCcsData->CommProtocol == V2GT_MSG_PROTOCOL_ISO15118_2014) { //ISO15118_2014 if(Buffer[0] == 0) { //DC TmpValue = ISO151182014PhyValDecode(ShmCcsData->V2GMessage_ISO15118_2014.ChargeParameterDiscoveryRequest.DC_EVChargeParameter.EVEnergyCapacity) * 10; memcpy(Buffer + 1, &TmpValue, 2); TmpValue = ISO151182014PhyValDecode(ShmCcsData->V2GMessage_ISO15118_2014.ChargeParameterDiscoveryRequest.DC_EVChargeParameter.EVMaximumVoltageLimit) * 10; memcpy(Buffer + 3, &TmpValue, 2); TmpValue = ISO151182014PhyValDecode(ShmCcsData->V2GMessage_ISO15118_2014.ChargeParameterDiscoveryRequest.DC_EVChargeParameter.EVMaximumCurrentLimit) * 10; memcpy(Buffer + 5, &TmpValue, 2); } else { //AC TmpValue = ISO151182014PhyValDecode(ShmCcsData->V2GMessage_ISO15118_2014.ChargeParameterDiscoveryRequest.AC_EVChargeParameter.EAmount) * 10; memcpy(Buffer + 1, &TmpValue, 2); TmpValue = ISO151182014PhyValDecode(ShmCcsData->V2GMessage_ISO15118_2014.ChargeParameterDiscoveryRequest.AC_EVChargeParameter.EVMaxVoltage) * 10; memcpy(Buffer + 3, &TmpValue, 2); TmpValue = ISO151182014PhyValDecode(ShmCcsData->V2GMessage_ISO15118_2014.ChargeParameterDiscoveryRequest.AC_EVChargeParameter.EVMaxCurrent) * 10; memcpy(Buffer + 5, &TmpValue, 2); } } else if(ShmCcsData->CommProtocol == V2GT_MSG_PROTOCOL_ISO15118_2018) { //to be implemented } nbytes = CAN_Tx_MSG(Fd, CAN_CMD_GET_EV_BATTERY_INFO, ShmInternalComm->SlaveAddress, 7, Buffer); CSUCOMMDC_TASK_FLAG.Got_EVBatteryInfoReq = FALSE; return nbytes; } /*=========================================================================== FUNCTION: Proc_GetEVBatteryInfoReq DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void Proc_GetEVBatteryInfoReq() { CSUCOMMDC_TASK_FLAG.Got_EVBatteryInfoReq = TRUE; } /*=========================================================================== FUNCTION: Proc_IsolationStatusAnnounceRes DESCRIPTION: - ShmInternalComm->IsolationStatus: GFD_Invalid 0 //ongoing GFD_Valid 1 GFD_Warning 2 GFD_Fault 3 GFD_No_IMD 4 //for ISO 15118 PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int Proc_IsolationStatusAnnounceRes(int Fd) { DEBUG_PRINTF_CSUCOMM_DETAIL("[CsuComm][Proc_IsolationStatusAnnounceRes] %d (DEC, 0:ongoing, 1:valid, 2:warning/fault)\n", ShmInternalComm->IsolationStatus); if (ShmInternalComm->IsolationStatus_pre != ShmInternalComm->IsolationStatus) { //memset(buf_log_csucomm, 0, sizeof(buf_log_csucomm)); sprintf(buf_log_csucomm, "Isolation: %d >> %d", ShmInternalComm->IsolationStatus_pre, ShmInternalComm->IsolationStatus); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); ShmInternalComm->IsolationStatus_pre = ShmInternalComm->IsolationStatus; } //DC_EVSEStatus.EVSEIsolationStatus = dinisolationLevelType_Invalid; //0 (default) // dinisolationLevelType_Invalid = 0, // dinisolationLevelType_Valid = 1, (default) // dinisolationLevelType_Warning = 2, // dinisolationLevelType_Fault = 3 CSUCOMMDC_TASK_FLAG.Got_IsolationStatus = FALSE; } /*=========================================================================== FUNCTION: Proc_IsolationStatusAnnounceReq DESCRIPTION: - BYTE[0]: GFD_Invalid 0 //ongoing GFD_Valid 1 GFD_Warning 2 GFD_Fault 3 GFD_No_IMD 4 //for ISO 15118 PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void Proc_IsolationStatusAnnounceReq(struct can_frame *frame) { unsigned char gfd_rx = 0; gfd_rx = (unsigned char) frame->data[0]; if (gfd_rx >= GFD_Invalid && gfd_rx <= GFD_No_IMD) { //Transfer Parameter if (gfd_rx == GFD_Warning) { gfd_rx = GFD_Fault; } else if (gfd_rx == GFD_Fault) { gfd_rx = GFD_Warning; } else { //no modification. } ShmInternalComm->IsolationStatus = gfd_rx; EVCOMM_SYS_INFO.IsolationStatus = ShmInternalComm->IsolationStatus; CSUCOMMDC_TASK_FLAG.Got_IsolationStatus = TRUE; } else { sprintf(buf_log_csucomm, "[WARNING]unexpected isolation status(%d)", frame->data[0]); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); } } /*=========================================================================== FUNCTION: Proc_CCSConnectorTypeSetRes DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int Proc_CCSConnectorTypeSetRes(int Fd) { DEBUG_PRINTF_CSUCOMM_DETAIL("[CsuComm][Proc_CCSConnectorTypeSetRes] To-be implemented. (checking for PP or not)\n"); CSUCOMMDC_TASK_FLAG.Got_CCSConnectorReq = FALSE; } /*=========================================================================== FUNCTION: Proc_CCSConnectorTypeSetReq DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void Proc_CCSConnectorTypeSetReq(struct can_frame *frame) { ShmInternalComm->CCSConnectorType = (unsigned char) frame->data[0];//0x00 : CCS1, 0x01 : CCS2 CSUCOMMDC_TASK_FLAG.Got_CCSConnectorReq = TRUE; } /*=========================================================================== FUNCTION: Proc_RTCSetRes DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int Proc_RTCSetRes(int Fd) { int nbytes; unsigned char Buffer[1]; memset(Buffer, 0, sizeof(Buffer)); if (ShmInternalComm->RTC != 0) { //[CAUTION] updating RTC time only in IDLE mode //ShmInternalComm->RTC = 1575461829; sprintf(buf_log_csucomm, "[Proc_RTCSetRes] Got RTC Message: %lu (DEC)", ShmInternalComm->RTC); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); system("date"); SAVE_SYS_LOG_MSG_CSUCOMM("[Proc_RTCSetRes] RTC is updating..."); #if 1 time_t rtc_new; rtc_new = ShmInternalComm->RTC; //Epoch time stime(&rtc_new); ftime(&ShmInternalComm->Start_Time); ftime(&ShmInternalComm->End_Time); ftime(&ShmInternalComm->CAN_Rx_Timer_Start); ftime(&ShmInternalComm->CAN_Rx_Timer_End); #else //verified ok char buf[64]; sprintf(buf, "date +%%s -s @%u", ShmInternalComm->RTC); system(buf); ftime(&ShmInternalComm->Start_Time); ftime(&ShmInternalComm->End_Time); ftime(&ShmInternalComm->CAN_Rx_Timer_Start); ftime(&ShmInternalComm->CAN_Rx_Timer_End); #endif system("date"); SAVE_SYS_LOG_MSG_CSUCOMM("[Proc_RTCSetRes] RTC is updated.\n"); Buffer[0] = 1; //Accept } else { SAVE_SYS_LOG_MSG_CSUCOMM("[Proc_RTCSetRes] Reject.\n"); Buffer[0] = 0; //Reject } CSUCOMMDC_TASK_FLAG.Got_RTC = FALSE; nbytes = CAN_Tx_MSG(Fd, CAN_CMD_RTC_INFO, ShmInternalComm->SlaveAddress, 1, Buffer); return nbytes; } /*=========================================================================== FUNCTION: Proc_RTCSetReq DESCRIPTION: PRE-CONDITION: INPUT: 1. Epoch time OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void Proc_RTCSetReq(struct can_frame *frame) { //STEP 1: If the RTC time from CSU is older than CCS default time, ignore it. //(The RTC time of CSU might not be updated.) long int rtc_tmp = 0; memcpy(&rtc_tmp, &frame->data[0], 4); //Epoch time if (rtc_tmp < RTC_DEFAULT_TIME) { sprintf(buf_log_csucomm, "[WARNING] RTC time from CSU(%lu) is older than CCS(%lu): ignored", rtc_tmp, RTC_DEFAULT_TIME); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); return; } //STEP 2: Checking System State and Update RTC if (Check_V2G_Flow_Status() == IDLE && ShmInternalComm->DownloadImageInfo.active == FALSE && EVCOMM_SYS_INFO.End_Process_inused == FALSE) { #if 1 //4-Byte EPOCH TIME: CAN: BYTE_TIME[0] BYTE_TIME[1] BYTE_TIME[2] BYTE_TIME[3] memcpy(&ShmInternalComm->RTC, &frame->data[0], 4); //Epoch time #else //4-Byte EPOCH TIME: CAN: BYTE_TIME[3] BYTE_TIME[2] BYTE_TIME[1] BYTE_TIME[0] unsigned char rtc[4], tmp; memcpy(&rtc[0], &frame->data[0], 4); tmp = rtc[0]; rtc[0] = rtc[3]; rtc[3] = tmp; tmp = rtc[1]; rtc[1] = rtc[2]; rtc[2] = tmp; memcpy(&ShmInternalComm->RTC, &rtc[0], 4); //Epoch time #endif } else { ShmInternalComm->RTC = 0; } //printf("\n%X %X %X %X (%X)\n", frame->data[0], frame->data[1], frame->data[2], frame->data[3], ShmInternalComm->RTC); CSUCOMMDC_TASK_FLAG.Got_RTC = TRUE; } /*=========================================================================== FUNCTION: Proc_EVSEPrechargeInfoUpdateRes DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int Proc_EVSEPrechargeInfoUpdateRes(int Fd) { DEBUG_PRINTF_CSUCOMM_DETAIL("[CsuComm][Proc_EVSEPrechargeInfoUpdateRes]\n"); int nbytes; unsigned char Buffer[8]; unsigned short TmpValue; memset(Buffer, 0, sizeof(Buffer)); //Buffer[0] = TRUE; Buffer[0] = ShmInternalComm->EVSEPrechargeStatus; nbytes = CAN_Tx_MSG(Fd, CAN_CMD_EVSE_PRECHARGE_INFO, ShmInternalComm->SlaveAddress, 1, Buffer); CSUCOMMDC_TASK_FLAG.Got_EVSE_Precharge_Info = FALSE; return nbytes; } /*=========================================================================== FUNCTION: Proc_EVSEPrechargeInfoUpdateReq DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void Proc_EVSEPrechargeInfoUpdateReq(struct can_frame *frame) { static struct ChargingInfoData *sys; sys = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[0]; ShmInternalComm->EVSEPrechargeStatus = frame->data[0]; sys->EVSEPrechargeStatus = ShmInternalComm->EVSEPrechargeStatus; if (sys->EVSEPrechargeStatus_pre != sys->EVSEPrechargeStatus) { //memset(buf_log_csucomm, 0, sizeof(buf_log_csucomm)); sprintf(buf_log_csucomm, "Precharge Status: %d >> %d", sys->EVSEPrechargeStatus_pre, sys->EVSEPrechargeStatus ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); sys->EVSEPrechargeStatus_pre = sys->EVSEPrechargeStatus; } CSUCOMMDC_TASK_FLAG.Got_EVSE_Precharge_Info = TRUE; } /*=========================================================================== FUNCTION: Proc_EVCCIDRes DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int Proc_EVCCIDRes(int Fd) { DEBUG_PRINTF_CSUCOMM_DETAIL("[CsuComm][Proc_EVCCIDRes]\n"); int i = 0; int nbytes = 0; unsigned char Buffer[8]; /*+++ 20200707, vern, reduce 8 digital MAC from BMW i3 +++*/ memset(Buffer, 0, sizeof(Buffer)); if(EVCOMM_SYS_INFO.EVCCID_length>=8) { EVCOMM_SYS_INFO.EVCCID_length=8; if((EVCOMM_SYS_INFO.EVCCID[0]==0)&&(EVCOMM_SYS_INFO.EVCCID[1]==0)) memcpy(EVCOMM_SYS_INFO.EVCCID,EVCOMM_SYS_INFO.EVCCID+2,6); EVCOMM_SYS_INFO.EVCCID_length=6; } memcpy(Buffer,EVCOMM_SYS_INFO.EVCCID,EVCOMM_SYS_INFO.EVCCID_length); /*--- 20200707, vern, reduce 8 digital MAC from BMW i3 ---*/ nbytes = CAN_Tx_MSG(Fd, CAN_CMD_EVCCID_REQUEST, ShmInternalComm->SlaveAddress, EVCOMM_SYS_INFO.EVCCID_length, Buffer); CSUCOMMDC_TASK_FLAG.Got_EVCCID_Req = FALSE; return nbytes; } /*=========================================================================== FUNCTION: Proc_EVCCIDReq DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void Proc_EVCCIDReq(struct can_frame *frame) { CSUCOMMDC_TASK_FLAG.Got_EVCCID_Req = TRUE; } /*=========================================================================== FUNCTION: Proc_EVStopRes DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int Proc_EVStopRes(int Fd) { int nbytes; unsigned char Buffer[8]; memset(Buffer, 0, sizeof(Buffer)); /* if(strlen(ShmStatusCodeData->PresentStatusCode[0]) > 0) { memcpy(Buffer + 2, ShmStatusCodeData->PresentStatusCode[0], 6); } */ Buffer[1] = ShmStatusCodeData->PresentStatusCode[0][0]; Buffer[2] = ShmStatusCodeData->PresentStatusCode[0][1]; Buffer[3] = ShmStatusCodeData->PresentStatusCode[0][2]; Buffer[4] = ShmStatusCodeData->PresentStatusCode[0][3]; Buffer[5] = ShmStatusCodeData->PresentStatusCode[0][4]; Buffer[6] = ShmStatusCodeData->PresentStatusCode[0][5]; if(( Buffer[1]== 0)&&( Buffer[2]== 2)&&( Buffer[3]== 3)&&( Buffer[4]== 9)&&( Buffer[5]== 7)&&( Buffer[6]== 9)) CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = FALSE; else CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; if (CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency == TRUE) { Buffer[0] = EV_EMERGENCY_STOP; //2 } else { Buffer[0] = EV_NORMAL_STOP; //1 } nbytes = CAN_Tx_MSG(Fd, CAN_CMD_EV_STOP_EVENT, ShmInternalComm->SlaveAddress, 7, Buffer); //system("echo 1000000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle"); //for test only //system("echo 0 > /sys/class/gpio/gpio89/value"); //for test SAVE_SYS_LOG_MSG_CSUCOMM("[Proc_EVStopRes] Sending STOP Command to CSU"); CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = FALSE; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = FALSE; return nbytes; } /*=========================================================================== FUNCTION: Proc_EVSEStopRes DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int Proc_EVSEStopRes(int Fd) { if (EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_Shutdown && EVCOMM_SYS_INFO.DC_EVSEStatus != EVSE_EmergencyShutdown) { //The above considtion will let this debug message to print once //even though the CSU sends several continuous stop commands. sprintf(buf_log_csucomm, "[Proc_EVSEStopRes] CSU Requests for STOP (Stop by EVSE: %d)", ShmInternalComm->EVSEStopChargingReq.type); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); //Once the stop command is received by CCS, this CAN message cannot //resume it back to normal state unless the End_Process is completed. if (ShmInternalComm->EVSEStopChargingReq.type == 1) { EVCOMM_SYS_INFO.DC_EVSEStatus = EVSE_Shutdown; } else if (ShmInternalComm->EVSEStopChargingReq.type == 2) { EVCOMM_SYS_INFO.DC_EVSEStatus = EVSE_EmergencyShutdown; } else { EVCOMM_SYS_INFO.DC_EVSEStatus = EVSE_Ready; } } CSUCOMMDC_TASK_FLAG.Got_EVSEStopReq = FALSE; } /*=========================================================================== FUNCTION: Proc_EVSEStopReq DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void Proc_EVSEStopReq(struct can_frame *frame) { ShmInternalComm->EVSEStopChargingReq.type = frame->data[0]; memcpy(&ShmInternalComm->EVSEStopChargingReq.alarmcode, &frame->data[1], 6); CSUCOMMDC_TASK_FLAG.Got_EVSEStopReq = TRUE; } /*=========================================================================== FUNCTION: Check_DwnldImgParameter DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: 1. Parameter Validation (0: invalid, 1: valid) 2. final_canmsg_size 3. total_can_packets GLOBAL VARIABLES: =============================================================================*/ int Check_DwnldImgParameter() { int image_size = 0; //unit: byte int total_can_packets = 0; unsigned char block_quantity = 0; unsigned char block_size_KByte = 0; //unit: Kbytes unsigned char final_canmsg_size = 0; //1~7 image_size = ShmInternalComm->DownloadImageInfo.image_size; block_quantity = ShmInternalComm->DownloadImageInfo.block_quantity; block_size_KByte = ShmInternalComm->DownloadImageInfo.block_size_KByte; //Step 1: Caculate final_canmsg_size and total_can_packets final_canmsg_size = image_size % 8; //8: max of CAN bus payload total_can_packets = image_size / 8; if (final_canmsg_size != 0) { total_can_packets += 1; } ShmInternalComm->DownloadImageInfo.final_canmsg_size = final_canmsg_size; ShmInternalComm->DownloadImageInfo.total_can_packets = total_can_packets; DEBUG_PRINTF_CSUCOMM_DETAIL("[Check_DwnldImgParameter]\n"); DEBUG_PRINTF_CSUCOMM_DETAIL("\t - final_canmsg_size = %d (DEC)\n\ \t - total_can_packets = %d (DEC)\n\n", ShmInternalComm->DownloadImageInfo.final_canmsg_size, ShmInternalComm->DownloadImageInfo.total_can_packets ); //Step 2: Check Parameter Validation //if ((block_quantity * block_size_KByte * 1024) > image_size) //[CAUTION] To increase type ID, please modify this condition. if (ShmInternalComm->DownloadImageInfo.type <= IMAGE_TYPE_USER_CONFIGURATION) { return TRUE; } else { sprintf(buf_log_csucomm, "[Check_DwnldImgParameter] type(%d) is not allowed, yet.", ShmInternalComm->DownloadImageInfo.type ); SAVE_SYS_LOG_MSG_CSUCOMM("buf_log_csucomm"); return FALSE; } } /*=========================================================================== FUNCTION: Proc_DownloadImageRes DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int Proc_DownloadImageRes(int Fd) { int nbytes; unsigned char Buffer[1]; memset(Buffer, 0, sizeof(Buffer)); if (ShmInternalComm->DownloadImageInfo.active == TRUE) { //[VITAL] Closing unneccesary task to supoort rapid CAN data receving.. SAVE_SYS_LOG_MSG_CSUCOMM("[Proc_DownloadImageRes] closing SeccComm..."); system("killall SeccComm"); system("rm -f /Storage/tmp"); system("touch /Storage/tmp"); #if (FIRMWARE_VERSION_COMPILE_SETTING_RELEASE_MODE == DISABLE) { SAVE_SYS_LOG_MSG_CSUCOMM("[Proc_DownloadImageRes]sync..."); system("sync"); } #endif Buffer[0] = 1; //Accept } else { SAVE_SYS_LOG_MSG_CSUCOMM("[Proc_DownloadImageRes] Fail"); Buffer[0] = 0; //Reject //[To-be-implemented][TBD] Sending alarm code or not? } DEBUG_PRINTF_CSUCOMM_DETAIL("[Proc_DownloadImageRes] %d (DEC)\n", Buffer[0]); CSUCOMMDC_TASK_FLAG.Got_DownloadImageReq = FALSE; nbytes = CAN_Tx_MSG(Fd, CAN_CMD_DOWNLOAD_REQUEST, ShmInternalComm->SlaveAddress, 1, Buffer); return nbytes; } /*=========================================================================== FUNCTION: Proc_DownloadImageReq DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void Proc_DownloadImageReq(struct can_frame *frame) { if (Check_V2G_Flow_Status() == IDLE) { ShmInternalComm->DownloadImageInfo.type = frame->data[0]; memcpy(&ShmInternalComm->DownloadImageInfo.image_size, &frame->data[1], 4); ShmInternalComm->DownloadImageInfo.image_size_received = 0; ShmInternalComm->DownloadImageInfo.block_quantity = frame->data[5]; ShmInternalComm->DownloadImageInfo.block_sequence_number = 0; ShmInternalComm->DownloadImageInfo.block_size_KByte = frame->data[6]; ShmInternalComm->DownloadImageInfo.block_sequence_number = 0; ShmInternalComm->DownloadImageInfo.block_checksum = 0; ShmInternalComm->DownloadImageInfo.total_can_packets = 0; ShmInternalComm->DownloadImageInfo.image_rx_cnt = 0; ShmInternalComm->DownloadImageInfo.downlaod_percentage = 0; ShmInternalComm->DownloadImageInfo.downlaod_percentage_pre = 0; ShmInternalComm->DownloadImageInfo.active = FALSE; if (ShmInternalComm->DownloadImageInfo.image_size == 0) { SAVE_SYS_LOG_MSG_CSUCOMM("[Proc_DownloadImageReq][Warning] image_size cannot be 0\n"); } else if (ShmInternalComm->DownloadImageInfo.block_quantity == 0) { SAVE_SYS_LOG_MSG_CSUCOMM("[Proc_DownloadImageReq][Warning] block_quantity cannot be 0\n"); } else if (ShmInternalComm->DownloadImageInfo.block_size_KByte == 0) { SAVE_SYS_LOG_MSG_CSUCOMM("[Proc_DownloadImageReq][Warning] block_size_KByte cannot be 0\n"); } else if (Check_DwnldImgParameter() == FALSE) { sprintf(buf_log_csucomm, "[Proc_DownloadImageReq][Warning] nonlogical image_size(%d bytes, DEC), block_quantity(%d, DEC), block_size_KByte(%d, DEC)\n", ShmInternalComm->DownloadImageInfo.image_size, ShmInternalComm->DownloadImageInfo.block_quantity, ShmInternalComm->DownloadImageInfo.block_size_KByte ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); } else { ShmInternalComm->DownloadImageInfo.active = TRUE; } } else { ShmInternalComm->DownloadImageInfo.active = FALSE; sprintf(buf_log_csucomm, "[Proc_BlockTransferStartReq] PresentMsgFlowStatus (%d, DEC) is not in IDLE\n", Check_V2G_Flow_Status() ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); } SAVE_SYS_LOG_MSG_CSUCOMM("[Proc_DownloadImageReq] Got Request from CSU\n"); sprintf(buf_log_csucomm, "\t - type = %d (DEC)\n\ \t - image size = %d (DEC, bytes)\n\ \t - block quantity = %d (DEC)\n\ \t - block size = %d (DEC, KBytes)\n\n", ShmInternalComm->DownloadImageInfo.type, ShmInternalComm->DownloadImageInfo.image_size, ShmInternalComm->DownloadImageInfo.block_quantity, ShmInternalComm->DownloadImageInfo.block_size_KByte ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); CSUCOMMDC_TASK_FLAG.Got_DownloadImageReq = TRUE; } /*=========================================================================== FUNCTION: Proc_BlockTransferStartRes DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int Proc_BlockTransferStartRes(int Fd) { int nbytes; unsigned char Buffer[1]; memset(Buffer, 0, sizeof(Buffer)); if (ShmInternalComm->DownloadImageInfo.active == TRUE) { Buffer[0] = 1; //Accept } else { fclose(ShmInternalComm->DownloadImageInfo.file); Buffer[0] = 0; //Reject //[To-be-implemented][TBD] Sending alarm code or not? } DEBUG_PRINTF_CSUCOMM_DETAIL("[Proc_BlockTransferStartRes] %d (DEC)\n", Buffer[0]); nbytes = CAN_Tx_MSG(Fd, CAN_CMD_START_BLOCK_TRANSFER, ShmInternalComm->SlaveAddress, 1, Buffer); CSUCOMMDC_TASK_FLAG.Got_BlockTransferStartReq = FALSE; return nbytes; } /*=========================================================================== FUNCTION: Proc_BlockTransferStartReq DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void Proc_BlockTransferStartReq(struct can_frame *frame) { if (Check_V2G_Flow_Status() == IDLE) { ShmInternalComm->DownloadImageInfo.block_sequence_number += 1; //1~255 //Check the valid range (1 ~ 255) if (frame->data[0] >= 1 && frame->data[0] <= 255 && ShmInternalComm->DownloadImageInfo.block_sequence_number == frame->data[0] && ShmInternalComm->DownloadImageInfo.block_sequence_number >= 1 && ShmInternalComm->DownloadImageInfo.block_sequence_number <= 255 ) { ShmInternalComm->DownloadImageInfo.active = TRUE; } else { sprintf(buf_log_csucomm, "[Proc_BlockTransferStartReq][Warning] Unexpected block_sequence_number (%d, %d, DEC)\n", frame->data[0], ShmInternalComm->DownloadImageInfo.block_sequence_number ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); ShmInternalComm->DownloadImageInfo.active = FALSE; } ShmInternalComm->DownloadImageInfo.block_checksum = frame->data[1]; } else { ShmInternalComm->DownloadImageInfo.active = FALSE; sprintf(buf_log_csucomm, "[Proc_BlockTransferStartReq] PresentMsgFlowStatus (%d, DEC) is not in IDLE\n", Check_V2G_Flow_Status() ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); } DEBUG_PRINTF_CSUCOMM_DETAIL("\n[Proc_BlockTransferStartReq] Got Request from CSU\n"); sprintf(buf_log_csucomm, "\t - block_sequence_number = %d (DEC)\n\ \t - block_checksum = %02X (HEX, bytes)\n\n", ShmInternalComm->DownloadImageInfo.block_sequence_number, ShmInternalComm->DownloadImageInfo.block_checksum ); DEBUG_PRINTF_CSUCOMM_DETAIL(buf_log_csucomm); CSUCOMMDC_TASK_FLAG.Got_BlockTransferStartReq = TRUE; } /*=========================================================================== FUNCTION: Proc_DataTransferRes DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int Proc_DataTransferRes(int Fd) { //DEBUG_PRINTF_CSUCOMM_DETAIL("[CsuComm][Proc_DataTransferRes]\n"); //[To-be-implemented] Check Block Checksum, if fail, we should use this response to ask CSU to resend this block again. CSUCOMMDC_TASK_FLAG.Got_DataTransferReq = FALSE; } /*=========================================================================== FUNCTION: Proc_DataTransferReq DESCRIPTION: PRE-CONDITION: 1. The time interval between each CAN data should be 3ms at least to avoid data loss. INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void Proc_DataTransferReq(struct can_frame *frame) { if (Check_V2G_Flow_Status() == IDLE && ShmInternalComm->DownloadImageInfo.active == 1) { if ((ShmInternalComm->DownloadImageInfo.image_rx_cnt + frame->can_dlc) <= ShmInternalComm->DownloadImageInfo.image_size) { //Saving Data FILE *file; file = fopen("/Storage/tmp", "ab+"); int rlen = 0; DEBUG_PRINTF_CSUCOMM_DETAIL("[Proc_DataTransferReq] saving data... (%d bytes, DEC)\n", frame->can_dlc); //rlen = fwrite(&frame->data[0], sizeof(unsigned char), frame->can_dlc, ShmInternalComm->DownloadImageInfo.file); rlen = fwrite(&frame->data[0], sizeof(unsigned char), frame->can_dlc, file); if (rlen == frame->can_dlc) { fflush(ShmInternalComm->DownloadImageInfo.file); DEBUG_PRINTF_CSUCOMM_DETAIL("[Proc_DataTransferReq] fwrite: OK (rlen = %d)\n", rlen); ShmInternalComm->DownloadImageInfo.image_rx_cnt += frame->can_dlc; } else { DEBUG_PRINTF_CSUCOMM_DETAIL("[Proc_DataTransferReq] fwrite: FAIL (rlen = %d)\n", rlen); ShmInternalComm->DownloadImageInfo.active = FALSE; } fflush(file); fclose(file); DEBUG_PRINTF_CSUCOMM_DETAIL("\n", ShmInternalComm->DownloadImageInfo.image_rx_cnt); //Caculating the Download Percentage ShmInternalComm->DownloadImageInfo.downlaod_percentage = (ShmInternalComm->DownloadImageInfo.image_rx_cnt*100)/ShmInternalComm->DownloadImageInfo.image_size; if (ShmInternalComm->DownloadImageInfo.downlaod_percentage != ShmInternalComm->DownloadImageInfo.downlaod_percentage_pre) { sprintf(buf_log_csucomm, "[Proc_DataTransferReq] rx: %d\% (%d of %d bytes)\n", //showing the downlaod percentage ShmInternalComm->DownloadImageInfo.downlaod_percentage, ShmInternalComm->DownloadImageInfo.image_rx_cnt, ShmInternalComm->DownloadImageInfo.image_size ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); ShmInternalComm->DownloadImageInfo.downlaod_percentage_pre = ShmInternalComm->DownloadImageInfo.downlaod_percentage; } } else { ShmInternalComm->DownloadImageInfo.active = FALSE; SAVE_SYS_LOG_MSG_CSUCOMM("[Proc_BlockTransferStartReq] unexpected extra packets\n"); } } else { ShmInternalComm->DownloadImageInfo.active = FALSE; sprintf(buf_log_csucomm, "[Proc_BlockTransferStartReq] PresentMsgFlowStatus (%d, DEC) \ is not in IDLE or active flag (%d, DEC) is canceled\n", Check_V2G_Flow_Status(), ShmInternalComm->DownloadImageInfo.active ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); //Sending Stop Request to CSU to abort Data Transfer //CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; //[To-be-implemented] Adding corresponding alarm code } CSUCOMMDC_TASK_FLAG.Got_DataTransferReq = TRUE; } /*=========================================================================== FUNCTION: Proc_DownloadFinishRes DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int Proc_DownloadFinishRes(int Fd) { int nbytes; unsigned char Buffer[1]; memset(Buffer, 0, sizeof(Buffer)); //Step 1: Protection for receiving Firmware Update Req in non-IDLE mode if (Check_V2G_Flow_Status() != IDLE) { if (CSUCOMMDC_TASK_FLAG.FW_Update_Task_inused == FALSE) { SAVE_SYS_LOG_MSG_CSUCOMM("[Warning]FW update Req: ignored (only for idle mode)"); Buffer[0] = FAIL; nbytes = CAN_Tx_MSG(Fd, CAN_CMD_DOWNLOAD_FINISH, ShmInternalComm->SlaveAddress, 1, Buffer); if (nbytes > 0) { sprintf(buf_log_csucomm, "[Proc_DownloadFinishRes]Tx:ok(%d)", Buffer[0]); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); } else { sprintf(buf_log_csucomm, "[Proc_DownloadFinishRes]Tx:fail(%d)", nbytes); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); } return FAIL; } else if (CSUCOMMDC_TASK_FLAG.FW_Update_Task_inused == TRUE) { SAVE_SYS_LOG_MSG_CSUCOMM("[Warning]FW update Req: ignored (in used, already)"); //not sending response message, since it stands for end of update process. return FAIL; } else { sprintf(buf_log_csucomm, "[Warning]unexpected FW_Update_Task_inused value(%d)", CSUCOMMDC_TASK_FLAG.FW_Update_Task_inused ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); return FAIL; } } //Step 2: Execute the FW update task if (CSUCOMMDC_TASK_FLAG.FW_Update_Task_inused == FALSE) { CSUCOMMDC_TASK_FLAG.FW_Update_Task_inused = TRUE; //[VITAL] Closing unneccesary task to supoort rapid CAN data receving.. SAVE_SYS_LOG_MSG_CSUCOMM("[Proc_DownloadFinishRes] closing SeccComm..."); system("killall SeccComm"); system("cd /root;./FWUpdate -w &"); } //Step 3:Sending Response message with result once FW update is done. if (CSUCOMMDC_TASK_FLAG.FW_Update_Done == TRUE) { if (CSUCOMMDC_TASK_FLAG.FW_Update_result == PASS) { Buffer[0] = PASS; } else { Buffer[0] = FAIL; } nbytes = CAN_Tx_MSG(Fd, CAN_CMD_DOWNLOAD_FINISH, ShmInternalComm->SlaveAddress, 1, Buffer); if (nbytes > 0) { sprintf(buf_log_csucomm, "[Proc_DownloadFinishRes]Tx:ok(%d)", Buffer[0]); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); } else { sprintf(buf_log_csucomm, "[Proc_DownloadFinishRes]Tx:fail(%d)", nbytes); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); } sleep(2); //system("killall FWUpdate"); CSUCOMMDC_TASK_FLAG.Got_DownloadFinishReq = FALSE; Reboot_Process(); return nbytes; } } /*=========================================================================== FUNCTION: Proc_DownloadFinishReq DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void Proc_DownloadFinishReq(struct can_frame *frame) { CSUCOMMDC_TASK_FLAG.Got_DownloadFinishReq = TRUE; } /*=========================================================================== FUNCTION: PRINT_CAN_FRAME DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void PRINT_CAN_FRAME(struct can_frame *frame) { if (frame->can_dlc != 0) { int i = 0; DEBUG_PRINTF_CSUCOMM_DETAIL("[CsuComm] Got CAN Message: \n\ \t - Length: %d (Bytes, DEC)\n\ \t - ID: %08X\n\ \t - Payload: ", frame->can_dlc, frame->can_id ); for (i = 0; i< frame->can_dlc; i++) { DEBUG_PRINTF_CSUCOMM_DETAIL("%02X ", frame->data[i]); } DEBUG_PRINTF_CSUCOMM_DETAIL("\n"); } } /*=========================================================================== FUNCTION: CANRxTimeoutDetector DESCRIPTION: 1. fork1 PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int CANRxTimeoutHandler() { #if (CAN_RX_TIMEOUT_MECHANISM == ENABLE) //#if 1 if (CSUCOMMDC_TASK_FLAG.matched == TRUE && CSUCOMMDC_TASK_FLAG.CAN_Rx_Timeout == FALSE) { long int time_diff = 0; ftime(&ShmInternalComm->CAN_Rx_Timer_End); time_diff = DiffTimeb_CsuComm_fork1(ShmInternalComm->CAN_Rx_Timer_Start, ShmInternalComm->CAN_Rx_Timer_End); if(time_diff >= CSUCOMM_CAN_RX_TIMEOUT) //5 sec { sprintf(buf_log_csucomm_fork1, "[fork1][Rx]CAN timeout(%ld of %dms) => reboot", time_diff, CSUCOMM_CAN_RX_TIMEOUT ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm_fork1); //Reboot the CCS Board //Update_ShmStatusCode(); //CCS module communication fail (012248) ShmStatusCodeData->PresentStatusCode[0][0] = 0; ShmStatusCodeData->PresentStatusCode[0][1] = 1; ShmStatusCodeData->PresentStatusCode[0][2] = 2; ShmStatusCodeData->PresentStatusCode[0][3] = 2; ShmStatusCodeData->PresentStatusCode[0][4] = 4; ShmStatusCodeData->PresentStatusCode[0][5] = 8; CSUCOMMDC_TASK_FLAG.EV_Stop_Type_Emergency = TRUE; CSUCOMMDC_TASK_FLAG.Send_EVStopReq = TRUE; CSUCOMMDC_TASK_FLAG.CAN_Rx_Timeout = TRUE; Reboot_Process(); } } #endif } /*=========================================================================== FUNCTION: FWUpdateRebootDetector DESCRIPTION: 1. fork2 PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ /*int FWUpdateRebootHandler() { if (CSUCOMMDC_TASK_FLAG.FW_Update_Done == TRUE && CSUCOMMDC_TASK_FLAG.Got_DownloadFinishReq == FALSE && CSUCOMMDC_TASK_FLAG.FW_Update_Reboot_inused == FALSE) //wait for CAN Res msg to be sent. { CSUCOMMDC_TASK_FLAG.FW_Update_Reboot_inused = TRUE; sprintf(buf_log_csucomm_fork1, "[fork1]FW Update Done(%d) => End_Process", CSUCOMMDC_TASK_FLAG.Got_DownloadFinishReq); SAVE_SYS_LOG_MSG_EVCOMM(buf_log_csucomm_fork1); Reboot_Process(); } }*/ /*=========================================================================== FUNCTION: Error_Monitor_CsuComm DESCRIPTION: 1. fork1 PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void Error_Monitor_CsuComm() { pid_t tmp = 0; if(PID_CsuComm_Error_Monitor_Task == 0) { tmp = fork(); //fork1 if(tmp > 0) { PID_CsuComm_Error_Monitor_Task = tmp; sprintf(buf_log_csucomm_fork1, "[fork2][Error_Monitor]created(%d)", PID_CsuComm_Error_Monitor_Task); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm_fork1); #if 0 unsigned char buf[64]; memset(buf, 0, sizeof(buf)); sprintf(buf, "renice -20 -p %d", tmp); system(buf); #endif return; } } while(1) { //CAN comm. Timeout Detector CANRxTimeoutHandler(); usleep(1000); //Check for FW Update Reboot Request // FWUpdateRebootHandler(); } } /*=========================================================================== FUNCTION: CAN_Rx DESCRIPTION: 1. fork2 2. Receiving Task (indivitual process) PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void CAN_Rx(int fd) { pid_t tmp = 0; struct can_frame frame; int nbytes; if(PID_CAN_Rx_Task == 0) { tmp = fork(); //fork2 if(tmp > 0) { PID_CAN_Rx_Task = tmp; sprintf(buf_log_csucomm_fork2, "[fork2][Error_Monitor]created(%d)", PID_CAN_Rx_Task); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm_fork2); #if 0 unsigned char buf[64]; memset(buf, 0, sizeof(buf)); sprintf(buf, "renice -20 -p %d", tmp); system(buf); #endif return; } } ftime(&ShmInternalComm->CAN_Rx_Timer_Start); //ID is matched while(1) //Process after Matched { memset(&frame, 0, sizeof(struct can_frame)); nbytes = read(fd, &frame, sizeof(struct can_frame)); //For Test (Print Rx Messages) //PRINT_CAN_FRAME(&frame); //Filtering for legal CAN Rx Message if((frame.can_id == 0) || //Null CAN ID ((frame.can_id & 0x08000000) == 1) || //Direction (((frame.can_id & 0x000000FF) != ShmInternalComm->SlaveAddress) && ((frame.can_id & 0x000000FF) != 0))) //allow its SlaveAddress and Broadcasting Packetes (ID = 0x00) { continue; } //--------------------- Legal CAN Rx Message Zone ---------------------- //CAN comm. Timeout Detector ftime(&ShmInternalComm->CAN_Rx_Timer_Start); //Extracting and Parsing Legal CAN Message ID (1-Byte) switch(frame.can_id & 0x0000FF00) { case CAN_CMD_ADDRESS_ASSIGN: //0x00000200 { Proc_AddressAssignReq(&frame); break; } case CAN_CMD_GET_FW_VERSION: //0x00000400 { Proc_GetFirmwareVersionReq(&frame); break; } case CAN_CMD_GET_HW_VERSION: //0x00000500 { Proc_HardwareVersionReq(&frame); break; } case CAN_CMD_CHARGING_PERMISSION: //0x00000600 { Proc_ChargingPermissionReq(&frame); break; } case CAN_CMD_EVSE_OUTPUT_STATUS_ANNOUNCEMENT: //0x00000700 { Proc_EVSEOutputStatusUpdateReq(&frame); break; } case CAN_CMD_EVSE_CAPACITY_ANNOUNCEMENT: //0x00000800 { Proc_EVSECapacityUpdateReq(&frame); break; } case CAN_CMD_GET_EV_TARGET_INFO: //0x00000900 { Proc_GetEVTargetReq(&frame); break; } case CAN_CMD_GET_EV_BATTERY_INFO: //0x00000A00 { Proc_GetEVBatteryInfoReq(&frame); break; } case CAN_CMD_EVSE_STOP_EVENT: //0x00000C00 { Proc_EVSEStopReq(&frame); break; } case CAN_CMD_GET_MISC_INFO: //0x00000D00 { Proc_GetMiscellaneousInfoReq(&frame); break; } case CAN_CMD_DOWNLOAD_REQUEST: //0x00000E00 { //Proc_DownloadImageReq(&frame); break; } case CAN_CMD_START_BLOCK_TRANSFER: //0x00000F00 { //Proc_BlockTransferStartReq(&frame); break; } case CAN_CMD_DATA_TRANSFER: //0x00001000 { //Proc_DataTransferReq(&frame); break; } case CAN_CMD_DOWNLOAD_FINISH: //0x00001100 { Proc_DownloadFinishReq(&frame); break; } case CAN_CMD_ISOLATION_STATUS: //0x00001200 { Proc_IsolationStatusAnnounceReq(&frame); break; } case CAN_CMD_CCS_CONNECTOR_INFO: //0x00001300 { Proc_CCSConnectorTypeSetReq(&frame); break; } case CAN_CMD_RTC_INFO: //0x00001400 { Proc_RTCSetReq(&frame); break; } case CAN_CMD_EVSE_PRECHARGE_INFO: //0x00001500 { Proc_EVSEPrechargeInfoUpdateReq(&frame); break; } case CAN_CMD_EVCCID_REQUEST: { Proc_EVCCIDReq(&frame); break; } default: { sprintf(buf_log_csucomm_fork2, "[fork2][ERROR]Unexpected CAN Command ID: %d (DEC)", (frame.can_id & 0x0000FF00)); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm_fork2); break; } } } } /*=========================================================================== FUNCTION: Eth0_PortSetting DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int Eth0_PortSetting_Add(unsigned char addr) { SAVE_SYS_LOG_MSG_CSUCOMM("[Eth0_PortSetting_Add]start"); unsigned char cmd[128]; if ((addr >= 1) && (addr <= 20)) { addr = 20 + addr; //Step 0: shutdown eth0 #if 0 SAVE_SYS_LOG_MSG_CSUCOMM("[Eth0_PortSetting][eth0:0]down"); system("/sbin/ifconfig eth0:0 down"); sleep(1); #endif //Step 1: IP setting sprintf(buf_log_csucomm, "[Eth0_PortSetting_Add][eth0:0]IP >> 192.168.0.%d(up))", addr); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); sprintf(cmd, "/sbin/ifconfig eth0:0 192.168.0.%d netmask 255.255.255.0 up", addr); system(cmd); memset(cmd, 0, sizeof(cmd)); sleep(1); sprintf(buf_log_csucomm, "[Eth0_PortSetting_Add][eth0:0]done", addr); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); return PASS; } else { sprintf(buf_log_csucomm, "[Eth0_PortSetting_Add][Error]addr(%d) is out of range(1~20)", addr); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); return FAIL; } } /*=========================================================================== FUNCTION: Reboot_Process DESCRIPTION: 1. fork1 PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int Reboot_Process() { if (CSUCOMMDC_TASK_FLAG.Reboot_Process_inused == FALSE) { SAVE_SYS_LOG_MSG_CSUCOMM("[Reboot_Process]entered"); CSUCOMMDC_TASK_FLAG.Reboot_Process_inused = TRUE; #if (FIRMWARE_VERSION_COMPILE_SETTING_RELEASE_MODE == DISABLE) { SAVE_SYS_LOG_MSG_CSUCOMM("[Reboot_Process]sync..."); system("sync"); } #endif system("sleep 2"); system("cd /root;./reboot.sh"); } } /*=========================================================================== FUNCTION: CsuCommAC_GetCcsFirmwareVersion DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int CsuCommAC_GetCcsFirmwareVersion(unsigned char *buf) { int i = 0, j = 0, err = PASS, leng = 0; unsigned char str[FIRMWARE_VERSION_LENGTH + 1]; memset(buf, 0, sizeof(buf)); strcpy(str, FIRMWARE_VERSION); leng = FIRMWARE_VERSION_LENGTH + 3; if (sizeof(buf) < leng) { SAVE_SYS_LOG_MSG_CSUCOMM("[WARNING][CsuCommAC_GetCcsFirmwareVersion]ver size: too long"); leng = sizeof(buf); } for(i = 0; i < leng; i++) { if (str[i] != '_') { buf[j] = str[i]; j++; } } return err; } /*=========================================================================== FUNCTION: CsuCommAC_Init DESCRIPTION: 1. Set CCS FW Version PRE-CONDITION: 1. Share Memory should be initialized in advance. INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ /*int CsuCommAC_Init() { int err = PASS; CsuCommAC_GetCcsFirmwareVersion(CSUCOMMAC_SHM.CCSLibRev); memset(CSUCOMMAC_SHM.EVCCID, 0, sizeof(CSUCOMMAC_SHM.EVCCID)); CSUCOMMAC_SHM.PresentMsgFlowStatus = IDLE; CSUCOMMAC_SHM.ConnectorLockerStatus = FALSE; CSUCOMMAC_SHM.ConnectorTemperature1 = 0; CSUCOMMAC_SHM.ConnectorTemperature2 = 0; CSUCOMMAC_SHM.TotalBatteryCapacity = 0; CSUCOMMAC_SHM.BatteryMaximumVoltage = 0; CSUCOMMAC_SHM.BatteryMaximumCurrent = 0; CSUCOMMAC_SHM.CCSAlarmStatusCode = 0; CSUCOMMAC_SHM.PaymentOption = 0; CSUCOMMAC_SHM.EVSEMaxCurrent = 0; CSUCOMMAC_SHM.EVSEMinCurrent = 0; CSUCOMMAC_SHM.EVOperation = 0; CSUCOMMAC_SHM.EVChargeProgress = 0; CSUCOMMAC_SHM.CpSetPWMDuty = 0; CSUCOMMAC_SHM.CpSetStateE = 0; CSUCOMMAC_SHM.CcsHeartBeat = 0; return err; }*/ /*=========================================================================== FUNCTION: CsuCommAC_HeartBeat_Handler DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ /*int CsuCommAC_HeartBeat_Handler() { static unsigned int tmp = 0; if (tmp == 0) { tmp = time(NULL); } else { if ((time(NULL) - tmp) >= 1) //1 sec { CSUCOMMAC_SHM.CcsHeartBeat++; tmp = 0; //sprintf(buf_log_csucomm, "[CcsHeartBeat]%d", CSUCOMMAC_SHM.CcsHeartBeat); //SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); if (CSUCOMMAC_SHM.CcsHeartBeat >= 60) //timeout: 60 sec { sprintf(buf_log_csucomm, "[WARNING]CSU Comm: Fail(%d)", CSUCOMMAC_SHM.CcsHeartBeat); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); //[To-Do] Reboot or Send Error Code (TBD) } } } }*/ /*=========================================================================== FUNCTION: CsuCommAC_SHM_Rx_Update DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ #ifdef AWCCS int CsuCommAC_SHM_Rx_Update() { int gun_index=0; //[CAUTION] Re-initializing process is necessary. (to-be implemented) ShmCharger->gun_info[gun_index].acCcsInfo.PresentMsgFlowStatus=Check_V2G_Flow_Status(); ShmCharger->gun_info[gun_index].acCcsInfo.EVChargeProgress = ShmCcsData->V2GMessage_ISO15118_2014.PowerDeliveryRequest.ChargeProgress; ShmCharger->gun_info[gun_index].acCcsInfo.CpSetPWMDuty=ShmSysConfigAndInfo->SysInfo.CcsChargingData[0].CpDuty; //----------[1] Permission -------- // ShmInternalComm->ChargingPermission_new = (unsigned char) CSUCOMMAC_SHM.ChargingPermission; ShmInternalComm->ChargingPermission_new=ShmCharger->gun_info[gun_index].acCcsInfo.ChargingPermission; if (ShmInternalComm->ChargingPermission_new != ShmInternalComm->ChargingPermission) { sprintf(buf_log_csucomm, "Permission: %d >> %d", ShmInternalComm->ChargingPermission, ShmInternalComm->ChargingPermission_new ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); ShmInternalComm->ChargingPermission_pre = ShmInternalComm->ChargingPermission; ShmInternalComm->ChargingPermission = ShmInternalComm->ChargingPermission_new; } #if 1 // -------- [2] CpPresentPWMDuty -------- ShmInternalComm->AC_CpPresentPWMDuty = ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current; //unit: 1 sec. if (ShmInternalComm->AC_CpPresentPWMDuty_pre != ShmInternalComm->AC_CpPresentPWMDuty) { sprintf(buf_log_csucomm, "CP Duty(real): %d >> %d (1\%)", ShmInternalComm->AC_CpPresentPWMDuty_pre, ShmInternalComm->AC_CpPresentPWMDuty ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); ShmInternalComm->AC_CpPresentPWMDuty_pre = ShmInternalComm->AC_CpPresentPWMDuty; } #endif // -------- [3] CpPresentState -------- //ShmInternalComm->AC_CpPresentState = CSUCOMMAC_SHM.CpPresentState; //unit: 1 sec. ShmInternalComm->AC_CpPresentState=ShmCharger->gun_info[gun_index].acCcsInfo.CpPresentState; if (ShmInternalComm->AC_CpPresentState_pre != ShmInternalComm->AC_CpPresentState) { sprintf(buf_log_csucomm, "CP State: %d >> %d", ShmInternalComm->AC_CpPresentState_pre, ShmInternalComm->AC_CpPresentState ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); ShmInternalComm->AC_CpPresentState_pre = ShmInternalComm->AC_CpPresentState; } #if 0 // -------- [4] ChargingRemainTime -------- ShmInternalComm->AC_ChargingRemainTime = CSUCOMMAC_SHM.ChargingRemainTime; //unit: 1 sec. if (ShmInternalComm->AC_ChargingRemainTime_pre != ShmInternalComm->AC_ChargingRemainTime) { sprintf(buf_log_csucomm, "ChargingRemainTime: %d >> %d (1 sec)", ShmInternalComm->AC_ChargingRemainTime_pre, ShmInternalComm->AC_ChargingRemainTime ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); ShmInternalComm->AC_ChargingRemainTime_pre = ShmInternalComm->AC_ChargingRemainTime; } #endif // -------- [5] CSUAlarmStatusCode -------- //ShmInternalComm->AC_CSUAlarmStatusCode = CSUCOMMAC_SHM.CSUAlarmStatusCode; ShmInternalComm->AC_CSUAlarmStatusCode = ShmCharger->gun_info[gun_index].acCcsInfo.CSUAlarmStatusCode; if (ShmInternalComm->AC_CSUAlarmStatusCode_pre != ShmInternalComm->AC_CSUAlarmStatusCode) { sprintf(buf_log_csucomm, "CSUAlarmStatusCode: %X >> %X (1V)", ShmInternalComm->AC_CSUAlarmStatusCode_pre, ShmInternalComm->AC_CSUAlarmStatusCode ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); ShmInternalComm->AC_CSUAlarmStatusCode_pre = ShmInternalComm->AC_CSUAlarmStatusCode; } // -------- [6] MeterReadingValue -------- // ShmInternalComm->AC_MeterReadingValue = CSUCOMMAC_SHM.MeterReadingValue; //unit: 1WH ShmInternalComm->AC_MeterReadingValue=((float)ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/10.0); /* if (ShmInternalComm->AC_MeterReadingValue_pre != ShmInternalComm->AC_MeterReadingValue) { sprintf(buf_log_csucomm, "MeterReadingValue(Power): %.02f >> %.02f (1V)", ShmInternalComm->AC_MeterReadingValue_pre, ShmInternalComm->AC_MeterReadingValue ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); ShmInternalComm->AC_MeterReadingValue_pre = ShmInternalComm->AC_MeterReadingValue; }*/ // -------- [7] CpPositiveVoltage -------- //ShmInternalComm->AC_CpPositiveVoltage = CSUCOMMAC_SHM.CpPositiveVoltage; //unit: 1V ShmInternalComm->AC_CpPositiveVoltage=ShmCharger->gun_info[gun_index].acCcsInfo.CpPositiveVoltage; //the modification message will be logged via Check_CP_State_Update_fork1() in SeccComm task. if (abs(ShmInternalComm->AC_CpPositiveVoltage_pre - ShmInternalComm->AC_CpPositiveVoltage)>=0.5) { sprintf(buf_log_csucomm, "CP_P_V: %.02f >> %.02f (1V)", ShmInternalComm->AC_CpPositiveVoltage_pre, ShmInternalComm->AC_CpPositiveVoltage ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); ShmInternalComm->AC_CpPositiveVoltage_pre = ShmInternalComm->AC_CpPositiveVoltage; } // -------- [8] CpNegativeVoltage -------- //ShmInternalComm->AC_CpNegativeVoltage = CSUCOMMAC_SHM.CpNegativeVoltage; //unit: 1V ShmInternalComm->AC_CpNegativeVoltage = ShmCharger->gun_info[gun_index].acCcsInfo.CpNegativeVoltage; //unit: 1V if (abs(ShmInternalComm->AC_CpNegativeVoltage_pre - ShmInternalComm->AC_CpNegativeVoltage>=0.5)) { sprintf(buf_log_csucomm, "CP_N_V: - %.02f >> - %.02f (1V)", ShmInternalComm->AC_CpNegativeVoltage_pre, ShmInternalComm->AC_CpNegativeVoltage ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); ShmInternalComm->AC_CpNegativeVoltage_pre = ShmInternalComm->AC_CpNegativeVoltage; } // -------- [9] I_now: EVSEPresentCurrent[3] -------- // memcpy(ShmInternalComm->AC_EVSEPresentCurrent, CSUCOMMAC_SHM.EVSEPresentCurrent, 3); //unit: 1A //EVCOMM_SYS_INFO.PresentChargingCurrent = ShmInternalComm->AC_EVSEPresentCurrent[0]; //unit: 1A (using phase L) //ShmInternalComm->PresentChargingCurrent = (int)(ShmInternalComm->AC_EVSEPresentCurrent[0] * 10); //unit: 0.1A EVCOMM_SYS_INFO.PresentChargingCurrent = (float)ShmCharger->gun_info[gun_index].outputCurrent.L1N_L12[0]; //unit: 1A (using phase L) ShmInternalComm->PresentChargingCurrent = (float)ShmCharger->gun_info[gun_index].outputCurrent.L1N_L12[0] * 10; ShmInternalComm->AC_EVSEPresentCurrent[0] = (float)ShmCharger->gun_info[gun_index].outputCurrent.L1N_L12[0]; //L1 ShmInternalComm->AC_EVSEPresentCurrent[1] = (float)ShmCharger->gun_info[gun_index].outputCurrent.L2N_L23[0]; //L2 ShmInternalComm->AC_EVSEPresentCurrent[2] = (float)ShmCharger->gun_info[gun_index].outputCurrent.L3N_L31[0]; //L3 if ((ShmInternalComm->AC_EVSEPresentCurrent[0] != ShmInternalComm->AC_EVSEPresentCurrent[0]) || (ShmInternalComm->AC_EVSEPresentCurrent[1] != ShmInternalComm->AC_EVSEPresentCurrent[1]) || (ShmInternalComm->AC_EVSEPresentCurrent[2] != ShmInternalComm->AC_EVSEPresentCurrent[2]) ) { if ((abs(ShmInternalComm->AC_EVSEPresentCurrent_pre[0] - ShmInternalComm->AC_EVSEPresentCurrent[0]) > 10) || //10/;1A (abs(ShmInternalComm->AC_EVSEPresentCurrent_pre[1] - ShmInternalComm->AC_EVSEPresentCurrent[1]) > 10) || //10/;1A (abs(ShmInternalComm->AC_EVSEPresentCurrent_pre[2] - ShmInternalComm->AC_EVSEPresentCurrent[2]) > 10) //10/;1A ) { sprintf(buf_log_csucomm, "I_now(EVSE): (%.02f,%.02f,%.02f) >> (%.02f,%.02f,%.02f) (1A)", ShmInternalComm->AC_EVSEPresentCurrent_pre[0], ShmInternalComm->AC_EVSEPresentCurrent_pre[1], ShmInternalComm->AC_EVSEPresentCurrent_pre[2], ShmInternalComm->AC_EVSEPresentCurrent[0], ShmInternalComm->AC_EVSEPresentCurrent[1], ShmInternalComm->AC_EVSEPresentCurrent[2] ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); } ShmInternalComm->PresentChargingCurrent_pre = ShmInternalComm->PresentChargingCurrent; memcpy(ShmInternalComm->AC_EVSEPresentCurrent_pre, ShmInternalComm->AC_EVSEPresentCurrent, sizeof(ShmInternalComm->AC_EVSEPresentCurrent)); } //-------- [10] OutputRelayStatus -------- //ShmInternalComm->AC_OutputRelayStatus = CSUCOMMAC_SHM.OutputRelayStatus; //bool ShmInternalComm->AC_OutputRelayStatus= ShmCharger->gun_info[gun_index].acCcsInfo.OutputRelayStatus; if (ShmInternalComm->AC_OutputRelayStatus_pre != ShmInternalComm->AC_OutputRelayStatus) { sprintf(buf_log_csucomm, "RelayON: %d >> %d", ShmInternalComm->AC_OutputRelayStatus_pre, ShmInternalComm->AC_OutputRelayStatus ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); ShmInternalComm->AC_OutputRelayStatus_pre = ShmInternalComm->AC_OutputRelayStatus; } // -------- [11] GridVoltage (EVSENominalVoltage) -------- //EVCOMM_SYS_INFO.AC_EVSENominalVoltage = CSUCOMMAC_SHM.GridVoltage[0]; //unit: 1V //memcpy(ShmInternalComm->AC_GridVoltage, CSUCOMMAC_SHM.GridVoltage, 3); //unit: 1V EVCOMM_SYS_INFO.AC_EVSENominalVoltage = ShmCharger->gun_info[gun_index].acCcsInfo.GridVoltage[0] ; ShmInternalComm->AC_GridVoltage[0]=ShmCharger->gun_info[gun_index].acCcsInfo.GridVoltage[0]; ShmInternalComm->AC_GridVoltage[1]=ShmCharger->gun_info[gun_index].acCcsInfo.GridVoltage[1] ; ShmInternalComm->AC_GridVoltage[2]=ShmCharger->gun_info[gun_index].acCcsInfo.GridVoltage[2] ; if ((abs(ShmInternalComm->AC_GridVoltage_pre[0] - ShmInternalComm->AC_GridVoltage[0])>=10) || (abs(ShmInternalComm->AC_GridVoltage_pre[0] - ShmInternalComm->AC_GridVoltage[0])>=10) || (abs(ShmInternalComm->AC_GridVoltage_pre[0] - ShmInternalComm->AC_GridVoltage[0])>=10) ) { sprintf(buf_log_csucomm, "V_grid: (%.02f,%.02f,%.02f) >> (%.02f,%.02f,%.02f) (1V)", ShmInternalComm->AC_GridVoltage_pre[0], ShmInternalComm->AC_GridVoltage_pre[1], ShmInternalComm->AC_GridVoltage_pre[2], ShmInternalComm->AC_GridVoltage[0], ShmInternalComm->AC_GridVoltage[1], ShmInternalComm->AC_GridVoltage[2] ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); memcpy(ShmInternalComm->AC_GridVoltage_pre, ShmInternalComm->AC_GridVoltage, sizeof(ShmInternalComm->AC_GridVoltage)); } // -------- [12] V_now -------- if (ShmInternalComm->AC_OutputRelayStatus == ENABLE) { EVCOMM_SYS_INFO.PresentChargingVoltage = ShmInternalComm->AC_GridVoltage[0]; //unit: 1V (using phase 1) ShmInternalComm->PresentChargingVoltage = (int)(ShmInternalComm->AC_GridVoltage[0] * 10); //unit: 0.1V (using phase 1) } else { EVCOMM_SYS_INFO.PresentChargingVoltage = 0; ShmInternalComm->PresentChargingVoltage = 0; } if (ShmInternalComm->PresentChargingVoltage_pre != ShmInternalComm->PresentChargingVoltage) { if (abs(ShmInternalComm->PresentChargingVoltage_pre - ShmInternalComm->PresentChargingVoltage) >= 10) //10:1V { sprintf(buf_log_csucomm, "V_now(EVSE): %d >> %d (0.1V, DEC)", ShmInternalComm->PresentChargingVoltage_pre, ShmInternalComm->PresentChargingVoltage ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); } ShmInternalComm->PresentChargingVoltage_pre = ShmInternalComm->PresentChargingVoltage; } // -------- [13] P_now -------- EVCOMM_SYS_INFO.PresentChargingPower = (EVCOMM_SYS_INFO.PresentChargingVoltage * EVCOMM_SYS_INFO.PresentChargingCurrent)/1000; //1KW ShmInternalComm->PresentChargingPower = (int)(EVCOMM_SYS_INFO.PresentChargingPower * 10); //0.1KW if (ShmInternalComm->PresentChargingPower_pre != ShmInternalComm->PresentChargingPower) { sprintf(buf_log_csucomm, "P_now(EVSE): %d >> %d (0.1KW)", ShmInternalComm->PresentChargingPower_pre, ShmInternalComm->PresentChargingPower); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); ShmInternalComm->PresentChargingPower_pre = ShmInternalComm->PresentChargingPower; } // -------- [14] I_max (EVSE)-------- //EVCOMM_SYS_INFO.AvailableChargingCurrent = CSUCOMMAC_SHM.EVSEMaxCurrent; //unit: 1A //ShmInternalComm->AvailableChargingCurrent = (int)(CSUCOMMAC_SHM.EVSEMaxCurrent *10); //unit: 0.1A EVCOMM_SYS_INFO.AvailableChargingCurrent = ShmCharger->gun_info[gun_index].targetCurrent;; //unit: 1A ShmInternalComm->AvailableChargingCurrent = (int)(ShmCharger->gun_info[gun_index].targetCurrent*10); //unit: 0.1A ShmInternalComm->AC_EVSEMaxCurrent=ShmCharger->gun_info[gun_index].primaryMcuState.rating_current; if (ShmInternalComm->AvailableChargingCurrent_pre != ShmInternalComm->AvailableChargingCurrent) { sprintf(buf_log_csucomm, "I_max(EVSE): %d >> %d (0.1A)", ShmInternalComm->AvailableChargingCurrent_pre, ShmInternalComm->AvailableChargingCurrent); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); ShmInternalComm->AvailableChargingCurrent_pre = ShmInternalComm->AvailableChargingCurrent; } #if 0 // -------- [15] I_min (EVSE)-------- ShmInternalComm->AC_EVSEMinCurrent = CSUCOMMAC_SHM.EVSEMinCurrent; //unit: 1A if (ShmInternalComm->AC_EVSEMinCurrent_pre != ShmInternalComm->AC_EVSEMinCurrent) { sprintf(buf_log_csucomm, "I_min(EVSE): %.02f >> %.02f (1A)", ShmInternalComm->AC_EVSEMinCurrent_pre, ShmInternalComm->AC_EVSEMinCurrent); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); ShmInternalComm->AC_EVSEMinCurrent_pre = ShmInternalComm->AC_EVSEMinCurrent; } // -------- [16] V_max -------- //EVCOMM_SYS_INFO.MaximumChargingVoltage = CSUCOMMAC_SHM.GridVoltage[0]; //unit: 1V (using phase 1) //ShmInternalComm->MaximumChargingVoltage = (int)(CSUCOMMAC_SHM.GridVoltage[0] * 10); //unit: 0.1V (using phase 1) EVCOMM_SYS_INFO.MaximumChargingVoltage =ShmCharger->gun_info[gun_index].acCcsInfo.GridVoltage[0]; //unit: 1V (using phase 1) ShmInternalComm->MaximumChargingVoltage = (int)(ShmCharger->gun_info[gun_index].acCcsInfo.GridVoltage[0]* 10); //unit: 0.1V (using phase 1) if (ShmInternalComm->MaximumChargingVoltage_pre != ShmInternalComm->MaximumChargingVoltage) { sprintf(buf_log_csucomm, "V_max(EVSE): %d >> %d (0.1V, DEC)", ShmInternalComm->MaximumChargingVoltage_pre, ShmInternalComm->MaximumChargingVoltage ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); ShmInternalComm->MaximumChargingVoltage_pre = ShmInternalComm->MaximumChargingVoltage; } // -------- [17] P_max -------- ShmInternalComm->AC_AvailableChargingPower = CSUCOMMAC_SHM.AvailableChargingPower; //unit: 1KW EVCOMM_SYS_INFO.AvailableChargingPower = ShmInternalComm->AC_AvailableChargingPower; //1KW ShmInternalComm->AvailableChargingPower = (int)(ShmInternalComm->AC_AvailableChargingPower * 10); //unit: 0.1KW if (ShmInternalComm->AvailableChargingPower_pre != ShmInternalComm->AvailableChargingPower) { sprintf(buf_log_csucomm, "P_max(EVSE): %d >> %d (0.1KW)", ShmInternalComm->AvailableChargingPower_pre, ShmInternalComm->AvailableChargingPower); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); ShmInternalComm->AvailableChargingPower_pre = ShmInternalComm->AvailableChargingPower; } // -------- [18] EVSEID[40] -------- memcpy(ShmInternalComm->AC_EVSEID, CSUCOMMAC_SHM.EVSEID, 40); if (Array_Compare_Identity(ShmInternalComm->AC_EVSEID, CSUCOMMAC_SHM.EVSEID, 40) == FALSE) { sprintf(buf_log_csucomm, "EVSEID: [%02X %02X %02X %02X %02X %02X...] >> [%02X %02X %02X %02X %02X %02X...]", ShmInternalComm->AC_EVSEID_pre[0], ShmInternalComm->AC_EVSEID_pre[1], ShmInternalComm->AC_EVSEID_pre[2], ShmInternalComm->AC_EVSEID_pre[3], ShmInternalComm->AC_EVSEID_pre[4], ShmInternalComm->AC_EVSEID_pre[5], ShmInternalComm->AC_EVSEID[0], ShmInternalComm->AC_EVSEID[1], ShmInternalComm->AC_EVSEID[2], ShmInternalComm->AC_EVSEID[3], ShmInternalComm->AC_EVSEID[4], ShmInternalComm->AC_EVSEID[5] ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); memcpy(ShmInternalComm->AC_EVSEID_pre, ShmInternalComm->AC_EVSEID, 40); } #endif // -------- [19] MeterID[32] -------- if(strlen(ShmInternalComm->AC_MeterID)<=1) { // memcpy(ShmInternalComm->AC_MeterID, CSUCOMMAC_SHM.MeterID, 32); memset(ShmInternalComm->AC_MeterID, 0, sizeof(ShmInternalComm->AC_MeterID)); sprintf(ShmInternalComm->AC_MeterID,"%s_%s",ShmCharger->evseId.model_name,ShmCharger->evseId.serial_number); /* if (Array_Compare_Identity(ShmInternalComm->AC_MeterID, CSUCOMMAC_SHM.MeterID, 32) == FALSE) { sprintf(buf_log_csucomm, "MeterID: [%02X %02X %02X %02X %02X %02X...] >> [%02X %02X %02X %02X %02X %02X...]", ShmInternalComm->AC_MeterID_pre[0], ShmInternalComm->AC_MeterID_pre[1], ShmInternalComm->AC_MeterID_pre[2], ShmInternalComm->AC_MeterID_pre[3], ShmInternalComm->AC_MeterID_pre[4], ShmInternalComm->AC_MeterID_pre[5], ShmInternalComm->AC_MeterID[0], ShmInternalComm->AC_MeterID[1], ShmInternalComm->AC_MeterID[2], ShmInternalComm->AC_MeterID[3], ShmInternalComm->AC_MeterID[4], ShmInternalComm->AC_MeterID[5] ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); memcpy(ShmInternalComm->AC_MeterID_pre, ShmInternalComm->AC_MeterID_pre, 32); }*/ } // -------- [20] EVSEModelName[32] -------- if(strlen(ShmInternalComm->AC_EVSEModelName)<=1) { // memcpy(ShmInternalComm->AC_EVSEModelName, CSUCOMMAC_SHM.EVSEModelName, 32); memset(ShmInternalComm->AC_EVSEModelName, 0, sizeof(ShmInternalComm->AC_EVSEModelName)); strcpy(ShmInternalComm->AC_EVSEModelName,ShmCharger->evseId.model_name); /* if (Array_Compare_Identity(ShmInternalComm->AC_EVSEModelName, CSUCOMMAC_SHM.EVSEModelName, 32) == FALSE) { sprintf(buf_log_csucomm, "EVSEModelName: [%02X %02X %02X %02X %02X %02X...] >> [%02X %02X %02X %02X %02X %02X...]", ShmInternalComm->AC_EVSEModelName_pre[0], ShmInternalComm->AC_EVSEModelName_pre[1], ShmInternalComm->AC_EVSEModelName_pre[2], ShmInternalComm->AC_EVSEModelName_pre[3], ShmInternalComm->AC_EVSEModelName_pre[4], ShmInternalComm->AC_EVSEModelName_pre[5], ShmInternalComm->AC_EVSEModelName[0], ShmInternalComm->AC_EVSEModelName[1], ShmInternalComm->AC_EVSEModelName[2], ShmInternalComm->AC_EVSEModelName[3], ShmInternalComm->AC_EVSEModelName[4], ShmInternalComm->AC_EVSEModelName[5] ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); memcpy(ShmInternalComm->AC_EVSEModelName_pre, ShmInternalComm->AC_EVSEModelName_pre, 32); }*/ } #if 0 // -------- [21] BatteryChargeType -------- ShmInternalComm->AC_BatteryChargeType = CSUCOMMAC_SHM.BatteryChargeType; if (ShmInternalComm->AC_BatteryChargeType_pre != ShmInternalComm->AC_BatteryChargeType) { sprintf(buf_log_csucomm, "BatteryChargeType: %d >> %d", ShmInternalComm->AC_BatteryChargeType_pre, ShmInternalComm->AC_BatteryChargeType ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); ShmInternalComm->AC_BatteryChargeType_pre = ShmInternalComm->AC_BatteryChargeType; } #endif // -------- [21] RcdStatus -------- //ShmInternalComm->AC_RcdStatus = CSUCOMMAC_SHM.RcdStatus; ShmInternalComm->AC_RcdStatus=ShmCharger->gun_info[gun_index].otherAlarmCode.isACLeakage; if (ShmInternalComm->AC_RcdStatus_pre != ShmInternalComm->AC_RcdStatus) { sprintf(buf_log_csucomm, "RCDStatus: %d >> %d", ShmInternalComm->AC_RcdStatus_pre, ShmInternalComm->AC_RcdStatus ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); ShmInternalComm->AC_RcdStatus_pre = ShmInternalComm->AC_RcdStatus; } #if 0 // -------- [22] EVSENotification -------- ShmInternalComm->AC_EVSENotification = CSUCOMMAC_SHM.EVSENotification; if (ShmInternalComm->AC_EVSENotification_pre != ShmInternalComm->AC_EVSENotification) { sprintf(buf_log_csucomm, "AC_EVSENotification: %d >> %d", ShmInternalComm->AC_EVSENotification_pre, ShmInternalComm->AC_EVSENotification ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); ShmInternalComm->AC_EVSENotification_pre = ShmInternalComm->AC_EVSENotification; } #endif } #endif /*=========================================================================== FUNCTION: CsuCommAC_Error_Monitor DESCRIPTION: 1. fork1 PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ /*void CsuCommAC_Error_Monitor() { pid_t tmp = 0; if(PID_CsuComm_Error_Monitor_Task == 0) { tmp = fork(); //fork1 if(tmp > 0) { PID_CsuComm_Error_Monitor_Task = tmp; sprintf(buf_log_csucomm_fork1, "[fork2][Error_Monitor]created(%d)", PID_CsuComm_Error_Monitor_Task); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm_fork1); #if 0 unsigned char buf[64]; memset(buf, 0, sizeof(buf)); sprintf(buf, "renice -20 -p %d", tmp); system(buf); #endif return; } } while(1) { CsuCommAC_HeartBeat_Handler(); //timeout: 60s } }*/ /*=========================================================================== FUNCTION: CsuCommAC_Proc DESCRIPTION: PRE-CONDITION: 1. Share Memory should be initialized in advance. INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ #ifdef AWCCS int CsuCommAC_Proc() { //CsuCommAC_Init(); //CsuCommAC_Error_Monitor(); //fork1 while(1) { CsuCommAC_SHM_Rx_Update(); usleep(100000); } } #endif void CheckID() { unsigned char BoardId; unsigned char buf[64]; BoardId=(Get_GPIO_Value(GPIO_2_23_AM_IO_1) + 1) & 0x000000FF;//auto detect GPIO if(ShmInternalComm->SlaveAddress == BoardId) return; memset(buf,0,sizeof(buf)); sprintf(buf,"SlaveAddress from %d to %d\n",ShmInternalComm->SlaveAddress,BoardId); ShmInternalComm->SlaveAddress = BoardId; SAVE_SYS_LOG_MSG_CSUCOMM(buf); CSUCOMMDC_TASK_FLAG.matched = TRUE; //Changing the eth0 to 192.168.1.20 + ID #if (DYNAMIC_ETH0_IP_MECHANISM == ENABLE) Eth0_PortSetting_Add(ShmInternalComm->SlaveAddress); #endif } /*=========================================================================== FUNCTION: main DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: 1. PID_CAN_Rx_Task =============================================================================*/ int main(int argc, char *argv[]) { // ======== [STEP 1/5] Initialize Share Memory ======== if(ShareMemory_Init() == 0) { SAVE_SYS_LOG_MSG_CSUCOMM("[main]ShareMemory_Init NG"); if(ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory = 1; } sleep(5); return 0; } #if ((CCS_ENERGY_TRANSFER_MODE == MODE_AC_SINGLE_PHASE_CORE) || (CCS_ENERGY_TRANSFER_MODE == MODE_AC_THREE_PHASE_CORE)) { sprintf(buf_log_csucomm, "========= CCS: AC (%d)=========", CCS_ENERGY_TRANSFER_MODE ); SAVE_SYS_LOG_MSG_CSUCOMM(buf_log_csucomm); CsuCommAC_Proc(); while (1) { //null } } #endif int FD_CAN_Socket; //Socket File Descriptor struct can_frame frame; unsigned int value_random; unsigned char can_tx_payload[8]; // ======== [STEP 2/5] Initialize CAN BUS ======== FD_CAN_Socket = CANBus_Init(); ShmInternalComm->FD_CAN_Socket = FD_CAN_Socket; PID_CAN_Rx_Task = 0; ShmInternalComm->SlaveAddress = 0xFF; //unmatched CSUCOMMDC_TASK_FLAG.matched = FALSE; //Sniffering CAN packets Sniffer_Candump(ENABLE); Error_Monitor_CsuComm(); //fork1 #if 0 //disable ID assignmemt ftime(&ShmInternalComm->Start_Time); srandom(ShmInternalComm->Start_Time.millitm); value_random = random(); value_random &= 0xFFFFFF00; value_random |= 0x000000CC; //adding a specific header for identification of CCS. // ======== [STEP 3/5] Request for A Slave Address ======== while(ShmInternalComm->SlaveAddress == 0xFF) { ftime(&ShmInternalComm->Start_Time); // srandom(ShmInternalComm->Start_Time.millitm); // value_random = random(); // value_random &= 0xFFFFFF00; // value_random |= 0x000000CC; //adding a specific header for identification of CCS. DEBUG_PRINTF_CSUCOMM_DETAIL("[CsuComm][main] value_random = %08X (4 Bytes, HEX)\n", value_random); memset(can_tx_payload, 0, sizeof(can_tx_payload)); memcpy(can_tx_payload, &value_random, sizeof(int)); //for test #if (CAN_RAMDOM_MATCHING_ID_MECHANISM == DISABLE) value_random = 0xC3B2A1CC; memset(can_tx_payload, 0, sizeof(can_tx_payload)); memcpy(can_tx_payload, &value_random, sizeof(int)); //can_tx_payload[0] = 0xA1; //can_tx_payload[1] = 0xB2; //can_tx_payload[2] = 0xC3; //can_tx_payload[3] = 0xD4; DEBUG_PRINTF_CSUCOMM_DETAIL("[CsuComm][main] replaced random number = %02X %02X %02X %02X (4 Bytes, HEX)\n", can_tx_payload[0], can_tx_payload[1], can_tx_payload[2], can_tx_payload[3], can_tx_payload[4]); #endif can_tx_payload[4] = Get_GPIO_Value(GPIO_2_23_AM_IO_1) + 1; //auto detect GPIO //can_tx_payload[4] = 0x01; //(to be implemented: auto detect GPIO) //0x01:connector 1 //0x02:connector 2 CAN_Tx_MSG(FD_CAN_Socket, CAN_CMD_ADDRESS_REQUEST, ShmInternalComm->SlaveAddress, 5, can_tx_payload); ftime(&ShmInternalComm->End_Time); //Here is the process after sending the CAN message (t = 0 to t = 100ms) while(DiffTimeb(ShmInternalComm->Start_Time, ShmInternalComm->End_Time) < 1000)//resend interval: 1000ms { unsigned int value_random_return = 0; //4 Bytes memset(&frame, 0, sizeof(struct can_frame)); read(FD_CAN_Socket, &frame, sizeof(struct can_frame)); ftime(&ShmInternalComm->End_Time); PRINT_CAN_FRAME(&frame); if( (frame.can_id == 0) || //all zero (frame.can_id & 0x08000000) || //to avoid incoreect DIRECTION bit ((frame.can_id & 0x0000FF00) != CAN_CMD_ADDRESS_ASSIGN) || //the 1st command ID from Master should be 0x02 (frame.can_dlc != 5)) //payload length should be only 5 bytes. { continue; } memcpy(&value_random_return, frame.data, sizeof(int)); //only copy the previous 4 bytes DEBUG_PRINTF_CSUCOMM_DETAIL("[CsuComm][main] ori = %X, return = %X (HEX)\n", value_random, value_random_return); if(value_random_return == value_random) { //Getting a legal Slave Address, successfully. ShmInternalComm->SlaveAddress = frame.can_id & 0x000000FF; CSUCOMMDC_TASK_FLAG.matched = TRUE; #if (SAVE_SYS_LOG_MSG_CSUCOMM_SWITCH == ENABLE) { SAVE_SYS_LOG_MSG_CSUCOMM("Matched"); } #endif DEBUG_PRINTF_CSUCOMM_DETAIL("[CsuComm][main] ShmInternalComm->SlaveAddres = %02X (1 Byte, HEX)\t(Matched NOW.)\n", ShmInternalComm->SlaveAddress); //Changing the eth0 to 192.168.1.20 + ID #if (DYNAMIC_ETH0_IP_MECHANISM == ENABLE) Eth0_PortSetting_Add(ShmInternalComm->SlaveAddress); #endif break; } } } #else sleep(5); CheckID(); #endif // ======== [STEP 4/5] CAN RX ======== CAN_Rx(FD_CAN_Socket); //precondition: matched already //Here is a indivitual process/task which is dealing with all CAN message and commands. // ======== [STEP 5/5] CAN TX ======== //main loop ftime(&ShmInternalComm->Start_Time); while(1) { /* //CAN_CMD_ADDRESS_REQUEST 0x00000100 if (CSUCOMMDC_TASK_FLAG.matched == TRUE) { //Proc_Match(FD_CAN_Socket); //CSUCOMMDC_TASK_FLAG.matched = FALSE; } //CAN_CMD_ADDRESS_ASSIGN 0x00000200 if (CSUCOMMDC_TASK_FLAG.Got_AssignedAddress == TRUE) { //Proc_AddressAssignRes(FD_CAN_Socket); CSUCOMMDC_TASK_FLAG.Got_AssignedAddress = FALSE; } */ //====================================================================== // CAN_CMD_EV_BOARD_STATUS 0x00000300 ftime(&ShmInternalComm->End_Time); if(DiffTimeb(ShmInternalComm->Start_Time, ShmInternalComm->End_Time) >= 1000) //ori = 1000ms { //Interval = 1000ms CSUCOMMDC_TASK_FLAG.Send_EVBoardStatus = TRUE; CheckID(); } if (CSUCOMMDC_TASK_FLAG.Send_EVBoardStatus == TRUE) { //Tx Interval = 1000ms Proc_EVBoardStatusRes(FD_CAN_Socket); ftime(&ShmInternalComm->Start_Time); } // CAN_CMD_GET_FW_VERSION 0x00000400 if(CSUCOMMDC_TASK_FLAG.Got_FWVersionReq == TRUE) { Proc_GetFirmwareVersionRes(FD_CAN_Socket); } // CAN_CMD_GET_HW_VERSION 0x00000500 if(CSUCOMMDC_TASK_FLAG.Got_HWVersionReq == TRUE) { Proc_HardwareVersionRes(FD_CAN_Socket); } //CAN_CMD_CHARGING_PERMISSION 0x00000600 if (CSUCOMMDC_TASK_FLAG.Got_ChargingPermission == TRUE) { Proc_ChargingPermissionRes(FD_CAN_Socket); //need real-time response } // CAN_CMD_EVSE_OUTPUT_STATUS_ANNOUNCEMENT 0x00000700 if(CSUCOMMDC_TASK_FLAG.Got_EVSEOutputStatus == TRUE) { Proc_EVSEOutputStatusUpdateRes(FD_CAN_Socket); //need real-time response } // CAN_CMD_EVSE_CAPACITY_ANNOUNCEMENT 0x00000800 if (CSUCOMMDC_TASK_FLAG.Got_EnergyCapacity == TRUE) { Proc_EVSECapacityUpdateRes(FD_CAN_Socket); //need real-time response } // CAN_CMD_GET_EV_TARGET_INFO 0x00000900 if(CSUCOMMDC_TASK_FLAG.Got_EVTargetReq == TRUE) { Proc_GetEVTargetRes(FD_CAN_Socket); } // CAN_CMD_GET_EV_BATTERY_INFO 0x00000A00 if(CSUCOMMDC_TASK_FLAG.Got_EVBatteryInfoReq == TRUE) { Proc_GetEVBatteryInfoRes(FD_CAN_Socket); } //#define CAN_CMD_EV_STOP_EVENT 0x00000B00 if (CSUCOMMDC_TASK_FLAG.Send_EVStopReq == TRUE) //The Request is from SeccComm { Proc_EVStopRes(FD_CAN_Socket); } //#define CAN_CMD_EVSE_STOP_EVENT 0x00000C00 if (CSUCOMMDC_TASK_FLAG.Got_EVSEStopReq == TRUE) { Proc_EVSEStopRes(FD_CAN_Socket); } //#define CAN_CMD_GET_MISC_INFO 0x00000D00 if(CSUCOMMDC_TASK_FLAG.Got_MiscellaneousInfoReq == TRUE) { Proc_GetMiscellaneousInfoRes(FD_CAN_Socket); } //#define CAN_CMD_DOWNLOAD_REQUEST 0x00000E00 if (CSUCOMMDC_TASK_FLAG.Got_DownloadImageReq == TRUE) { Proc_DownloadImageRes(FD_CAN_Socket); } //#define CAN_CMD_START_BLOCK_TRANSFER 0x00000F00 if (CSUCOMMDC_TASK_FLAG.Got_BlockTransferStartReq == TRUE) { Proc_BlockTransferStartRes(FD_CAN_Socket); } // CAN_CMD_DATA_TRANSFER 0x00001000 if(CSUCOMMDC_TASK_FLAG.Got_DataTransferReq == TRUE) { Proc_DataTransferRes(FD_CAN_Socket); } //CAN_CMD_DOWNLOAD_FINISH 0x00001100 if (CSUCOMMDC_TASK_FLAG.Got_DownloadFinishReq == TRUE) { Proc_DownloadFinishRes(FD_CAN_Socket); } // CAN_CMD_ISOLATION_STATUS 0x00001200 if (CSUCOMMDC_TASK_FLAG.Got_IsolationStatus == TRUE) { Proc_IsolationStatusAnnounceRes(FD_CAN_Socket); } // CAN_CMD_CCS_CONNECTOR_INFO 0x00001300 if (CSUCOMMDC_TASK_FLAG.Got_CCSConnectorReq == TRUE) { Proc_CCSConnectorTypeSetRes(FD_CAN_Socket); //to-do } // CAN_CMD_RTC_INFO 0x00001400 if (CSUCOMMDC_TASK_FLAG.Got_RTC == TRUE) { Proc_RTCSetRes(FD_CAN_Socket); //to-do } //CAN_CMD_EVSE_PRECHARGE_INFO //0x00001500 if (CSUCOMMDC_TASK_FLAG.Got_EVSE_Precharge_Info == TRUE) { Proc_EVSEPrechargeInfoUpdateRes(FD_CAN_Socket); } //CAN_CMD_EVCCID_REQUEST //0x00001600 if (CSUCOMMDC_TASK_FLAG.Got_EVCCID_Req == TRUE) { Proc_EVCCIDRes(FD_CAN_Socket); } usleep(1000); } EndProcess: if(PID_CAN_Rx_Task > 0) { char Buf[32]; memset(Buf, 0, 32); sprintf(Buf, "kill %d", PID_CAN_Rx_Task); system(Buf); } close(FD_CAN_Socket); 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"); system("/sbin/ip link set can0 down"); system("killall CsuComm"); }