#include "Module_PsuComm.h" #define ARRAY_SIZE(A) (sizeof(A) / sizeof(A[0])) #define PASS 1 #define FAIL -1 #define YES 1 #define NO 0 #define DERATING 10 #define SELF_TEST 0 struct SysConfigAndInfo *ShmSysConfigAndInfo; struct StatusCodeData *ShmStatusCodeData; struct PsuData *ShmPsuData; void trim(char *s); int mystrcmp(char *p1,char *p2); void substr(char *dest, const char* src, unsigned int start, unsigned int cnt); void split(char **arr, char *str, const char *del); bool libInitialize = false; byte gun_count = CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY; byte getAvailableCapOffset = 5; byte deratingKeepCount = 0; float carReqVol = 0; float carReqCur = 0; float evseOutVol = 0; float evseOutCur = 0; int cmdDelayTime = 20000; void PRINTF_FUNC(char *string, ...); int StoreLogMsg(const char *fmt, ...); #define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, __FILE__, __LINE__, __FUNCTION__, ##args) #define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args) #define DEBUG_ERROR(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, __FILE__, __LINE__, __FUNCTION__, ##args) unsigned long GetTimeoutValue(struct timeval _sour_time); unsigned long GetTimeoutValue(struct timeval _sour_time) { struct timeval _end_time; gettimeofday(&_end_time, NULL); return 1000000 * (_end_time.tv_sec - _sour_time.tv_sec) + _end_time.tv_usec - _sour_time.tv_usec; } int StoreLogMsg(const char *fmt, ...) { char Buf[4096+256]; char buffer[4096]; time_t CurrentTime; struct tm *tm; va_list args; va_start(args, fmt); int rc = vsnprintf(buffer, sizeof(buffer), fmt, args); va_end(args); memset(Buf,0,sizeof(Buf)); CurrentTime = time(NULL); tm=localtime(&CurrentTime); sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec, buffer, tm->tm_year+1900,tm->tm_mon+1); system(Buf); return rc; } int DiffTimeb(struct timeb ST, struct timeb ET) { //return milli-second unsigned int StartTime,StopTime; StartTime=(unsigned int)ST.time; StopTime=(unsigned int)ET.time; return (StopTime-StartTime)*1000+ET.millitm-ST.millitm; } void PRINTF_FUNC(char *string, ...) { if (DEBUG) { va_list args; char buffer[4096]; va_start(args, string); vsnprintf(buffer, sizeof(buffer), string, args); va_end(args); printf("%s \n", buffer); } } //================================= // Common routine //================================= char* getTimeString(void) { char *result=malloc(21); time_t timep; struct tm *p; time(&timep); p=gmtime(&timep); sprintf(result, "[%04d-%02d-%02d %02d:%02d:%02d]", (1900+p->tm_year), (1+p->tm_mon), p->tm_mday, p->tm_hour, p->tm_hour, p->tm_sec); return result; } void trim(char *s) { int i=0, j, k, l=0; while((s[i]==' ')||(s[i]=='\t')||(s[i]=='\n')) i++; j = strlen(s)-1; while((s[j]==' ')||(s[j]=='\t')||(s[j]=='\n')) j--; if(i==0 && j==strlen(s)-1) { } else if(i==0) s[j+1] = '\0'; else { for(k=i; k<=j; k++) s[l++] = s[k]; s[l] = '\0'; } } int mystrcmp(char *p1,char *p2) { while(*p1==*p2) { if(*p1=='\0' || *p2=='\0') break; p1++; p2++; } if(*p1=='\0' && *p2=='\0') return(PASS); else return(FAIL); } void substr(char *dest, const char* src, unsigned int start, unsigned int cnt) { strncpy(dest, src + start, cnt); dest[cnt] = 0; } void split(char **arr, char *str, const char *del) { char *s = strtok(str, del); while(s != NULL) { *arr++ = s; s = strtok(NULL, del); } } //================================= // ReAssigned PSU Function //================================= void ReAssignedResource() { int index = 0; struct PsuModuleData PsuModule[ShmPsuData->SystemPresentPsuQuantity]; for (byte i = 0; i < 4; i++) { for(byte psuCount = 0; psuCount < ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity; psuCount++) { memcpy(&PsuModule[index], &ShmPsuData->PsuGroup[i].PsuModule[psuCount], sizeof(struct PsuModuleData)); index++; } ShmPsuData->PsuGroup[i].GroupPresentPsuQuantity = 0; } for(int i = 0; i < ShmPsuData->SystemPresentPsuQuantity; i++) { byte group = PsuModule[i].FireWireIndex; memcpy(&ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity], &PsuModule[i], sizeof(struct PsuModuleData)); PRINTF_FUNC("ReAssignedResource : PhysicalID = %d, Address = %d, group = %d \n", ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].PhysicalID, ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].Address, group); // printf("ReAssignedResource : PhysicalID = %d, Address = %d, group = %d \n", // ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].PhysicalID, // ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].Address, // group); PsuAddressAssignment(ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].PhysicalID, group); ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity++; } } //================================= // Save data to share memory Function //================================= bool FindChargingInfoData(byte target, struct ChargingInfoData **chargingData) { for (byte index = 0; index < CHAdeMO_QUANTITY; index++) { if (ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index].Index == target) { chargingData[target] = &ShmSysConfigAndInfo->SysInfo.ChademoChargingData[index]; return true; } } for (byte index = 0; index < CCS_QUANTITY; index++) { if (ShmSysConfigAndInfo->SysInfo.CcsChargingData[index].Index == target) { chargingData[target] = &ShmSysConfigAndInfo->SysInfo.CcsChargingData[index]; return true; } } for (byte index = 0; index < GB_QUANTITY; index++) { if (ShmSysConfigAndInfo->SysInfo.GbChargingData[index].Index == target) { chargingData[target] = &ShmSysConfigAndInfo->SysInfo.GbChargingData[index]; return true; } } return false; } //================================= // Alarm code mapping to share memory Function //================================= // �ˬd Byte ���Y�� Bit ���� // _byte : �����ܪ� byte // _bit : �� byte ���ĴX�� bit unsigned char mask_table[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; unsigned char DetectBitValue(unsigned char _byte, unsigned char _bit) { return ( _byte & mask_table[_bit] ) != 0x00; } void AbnormalStopAnalysis(byte gun_index, int errCode) { for (char i = 0; i < 3; i++) { unsigned char byteIndex = (errCode >> (8 * i)) & 0xff; for (char bitIndex = 0; bitIndex < 8; bitIndex++) { if(DetectBitValue(byteIndex , bitIndex) == 1) { switch(byteIndex) { case 0: { if (bitIndex == 0) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuOutputShortCircuit = YES; else if (bitIndex == 5) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = YES; } break; case 1: { if (bitIndex == 1) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFailureAlarm = YES; else if (bitIndex == 2) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuProtectionAlarm = YES; else if (bitIndex == 3) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFailureAlarm = YES; else if (bitIndex == 4) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCriticalPointOTP = YES; else if (bitIndex == 5) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = YES; } break; case 2: { if (bitIndex == 1) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDuplicateID = YES; if (bitIndex == 2) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuThreePhaseOnputImbalance = YES; else if (bitIndex == 3) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuThreePhaseInputInadequate = YES; else if (bitIndex == 4) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuThreePhaseInputInadequate = YES; else if (bitIndex == 5) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputUVP = YES; else if (bitIndex == 6) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputOVP = YES; } break; } } else { switch (byteIndex) { case 0: { if (bitIndex == 0) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuOutputShortCircuit = NO; else if (bitIndex == 5) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = NO; } break; case 1: { if (bitIndex == 1) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFailureAlarm = NO; else if (bitIndex == 2) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuProtectionAlarm = NO; else if (bitIndex == 3) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFailureAlarm = NO; else if (bitIndex == 4) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCriticalPointOTP = NO; else if (bitIndex == 5) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = NO; } break; case 2: { if (bitIndex == 1) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDuplicateID = NO; if (bitIndex == 2) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuThreePhaseOnputImbalance = NO; else if (bitIndex == 3) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuThreePhaseInputInadequate = NO; else if (bitIndex == 4) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuThreePhaseInputInadequate = NO; else if (bitIndex == 5) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputUVP = NO; else if (bitIndex == 6) ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputOVP = NO; } break; } } } } } //================================= // Callback Function //================================= void GetPsuRequestCallback(byte phy_id, char *serial_number) { if (ShmSysConfigAndInfo->SysInfo.AcContactorStatus == NO) return; // ********************** �C���e�q��A�ݧP�_�n��Ҧ����Ҷ����t����� Group ********************** byte group = 0; if(ShmSysConfigAndInfo->SysInfo.BootingStatus == BOOTTING || gun_count == 1) { // ��l�ƪ��A�A�h���������t��P�Ӹs group = 0; } else { group = ShmSysConfigAndInfo->SysInfo.CurGunSelected; } bool isNewPsu = true; for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++) { if (ShmPsuData->PsuGroup[group].PsuModule[index].PhysicalID == phy_id && strncmp((char *)ShmPsuData->PsuGroup[group].PsuModule[index].SerialNumber, serial_number, 7) == 0) { isNewPsu = false; } } if (isNewPsu) { ShmPsuData->SystemPresentPsuQuantity++; PRINTF_FUNC("get psu********Membar = %d, group = %d \n", ShmPsuData->SystemPresentPsuQuantity, group); if (ShmPsuData->Work_Step >= _TEST_LINE_STEP && ShmPsuData->Work_Step <= _TEST_COMPLETE) { // �w�g�i�J���u�W�����Ұʧ@ //ShmPsuData->NeedBackTest = YES; } else if (ShmPsuData->Work_Step == _WORK_CHARGING) { // �@���i�J���u�A���t�@�Ӥ��|�Ψ쪺���ӼҶ� group++; } ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].Address = ShmPsuData->SystemPresentPsuQuantity; ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].PhysicalID = phy_id; ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].AssignID = (group >> 6) + ShmPsuData->SystemPresentPsuQuantity; strcpy((char *)ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].SerialNumber, serial_number); ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity++; byte isFind = false; for (byte index = 0; index < conn_1_count; index++) { PRINTF_FUNC("connector_1[%d] = %d, phy_id = %d \n", index, connector_1[index], phy_id); if (connector_1[index] == phy_id) { isFind = true; ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].FireWireIndex = 0; break; } } if (!isFind) { for (byte index = 0; index < conn_2_count; index++) { PRINTF_FUNC("connector_2[%d] = %d, phy_id = %d \n", index, connector_2[index], phy_id); if (connector_2[index] == phy_id) { isFind = true; ShmPsuData->PsuGroup[group].PsuModule[ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity].FireWireIndex = 1; break; } } } //PsuAddressAssignment(phy_id, serial_number, ShmPsuData->SystemPresentPsuQuantity, group); PsuAddressAssignment(phy_id, group); if (ShmPsuData->Work_Step != _WORK_CHARGING) { ShmPsuData->GroupCount = group + 1; } } } void SaveStatusCallback(byte group, byte address, char cri_temp1, int alarm) { //EVSE for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++) { if (ShmPsuData->PsuGroup[group].PsuModule[index].PhysicalID == address) { ShmPsuData->PsuGroup[group].PsuModule[index].CriticalTemp1 = cri_temp1; ShmPsuData->PsuGroup[group].PsuModule[index].AlarmCode = alarm; AbnormalStopAnalysis(group, alarm); break; } } } //�ҲդT�V��J�q�� void SavePresentInputVoltageCallback(byte address, unsigned short vol1, unsigned short vol2, unsigned short vol3) { //EVSE //search group for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++) { for (byte index = 0; index < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; index++) { //search id if (ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PhysicalID == address) { //update module msg ShmPsuData->PsuGroup[groupIndex].PsuModule[index].InputVoltageL1 = vol1; ShmPsuData->PsuGroup[groupIndex].PsuModule[index].InputVoltageL2 = vol2; ShmPsuData->PsuGroup[groupIndex].PsuModule[index].InputVoltageL3 = vol3; break; } } } } // �Ҷ���X���q���q�y void SavePresentOutputCallback(byte address, unsigned short out_vol, unsigned short out_cur) { unsigned short outputVol = 0; unsigned short outputCur = 0; unsigned short group = 0; bool isChange = false; // PSU for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++) { for (int index = 0; index < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; index++) { if (ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PhysicalID == address) { //�p�G�^�����Ҳդ��O ver1.09 ���ϥμҲտ�X�q�� /* if(InfyPwrModelVerIs109 == 0) { ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PresentOutputVoltage = out_vol; } */ ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PresentOutputVoltage = out_vol; ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PresentOutputCurrent = out_cur; for (int loop = 0; loop < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; loop++) { //update voltage if (ShmPsuData->PsuGroup[groupIndex].PsuModule[loop].PresentOutputVoltage > outputVol) { outputVol = ShmPsuData->PsuGroup[groupIndex].PsuModule[loop].PresentOutputVoltage; } //update total current outputCur += ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PresentOutputCurrent; group = groupIndex; isChange = true; } } /* if (ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputVoltage > outputVol) outputVol = ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputVoltage; outputCur += ShmPsuData->PsuGroup[group].PsuModule[index].PresentOutputCurrent; */ } } if (isChange) { // PSU Group // �q�� ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage = outputVol; // �q�y ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent = outputCur; //EVSE - �j�ݪ���X�q�� chargingInfo[group]->PresentChargingVoltage = ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage; //EVSE - �j�ݪ���X�q�y chargingInfo[group]->PresentChargingCurrent = ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent; } //printf("GroupPresentOutputVoltage = %d \n", ShmPsuData->PsuGroup[group].GroupPresentOutputVoltage); //printf("GroupPresentOutputCurrent = %d \n", ShmPsuData->PsuGroup[group].GroupPresentOutputCurrent); } //PSU able_power = KW (��� 0.1) exp. 300 = 30kw //PSU able_cur = A (��� 0.1) exp. 400 = 40A void SaveAvailableCapCallback(byte address, unsigned short maxv, unsigned short minv, unsigned short able_cur, unsigned short able_power) { unsigned int power = 0; unsigned int current = 0; unsigned int power_derating = 0; unsigned int current_derating = 0; unsigned int group = 0; bool isChange = false; //bool sameGroup = false; //search group //printf("GroupCount = %d \n", ShmPsuData->GroupCount); for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++) { //printf("GroupPresentPsuQuantity = %d \n", ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity); for (int index = 0; index < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; index++) { //search group-id //printf("PhysicalID = %d, address = %d \n", ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PhysicalID, address); if (ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PhysicalID == address) { //����s�ӼҲո�T ShmPsuData->PsuGroup[groupIndex].PsuModule[index].AvailablePower = able_power; //�q���b 150V �ɨϥ��B�w�q�y if(ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PresentOutputVoltage < 1500) { ShmPsuData->PsuGroup[groupIndex].PsuModule[index].AvailableCurrent = able_cur; } //�p�G�^�����Ҳդ��O ver1.09 �� �� (�p�G�^�����ҲլO ver1.09 �����^���i��X�q�y���~�h�ϥ��B�w����i��X�q�y) /* if(InfyPwrModelVerIs109 == 0 || (InfyPwrModelVerIs109 == 1 && ShmPsuData->PsuGroup[groupIndex].PsuModule[index].AvailableCurrent == 0)) { ShmPsuData->PsuGroup[groupIndex].PsuModule[index].AvailableCurrent = able_cur; } */ //�ӹ������Ҳոs���s�p���`�X for (int loop = 0; loop < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; loop++) { // ���� // if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_GET_NEW_CAP && // ShmSysConfigAndInfo->SysInfo.ReAssignedFlag < _REASSIGNED_COMP) // { // if (ShmPsuData->PsuGroup[group].PsuModule[index].FireWireIndex == group) // { // power_derating += ShmPsuData->PsuGroup[group].PsuModule[index].AvailablePower; // current_derating += ShmPsuData->PsuGroup[group].PsuModule[index].AvailableCurrent; // } // } power += ShmPsuData->PsuGroup[groupIndex].PsuModule[loop].AvailablePower; current += ShmPsuData->PsuGroup[groupIndex].PsuModule[loop].AvailableCurrent; group = groupIndex; isChange = true; } } } } if (current_derating == 0) { current_derating = current; } if (power_derating == 0) { power_derating = power; } if (isChange) { // PSU Group // Available Power ShmPsuData->PsuGroup[group].GroupAvailablePower = power; // Available Current ShmPsuData->PsuGroup[group].GroupAvailableCurrent = current; chargingInfo[group]->MaximumChargingVoltage = maxv; chargingInfo[group]->AvailableChargingCurrent = ShmPsuData->PsuGroup[group].GroupAvailableCurrent; chargingInfo[group]->AvailableChargingPower = ShmPsuData->PsuGroup[group].GroupAvailablePower; chargingInfo[group]->DeratingChargingCurrent = current_derating; chargingInfo[group]->DeratingChargingPower = power_derating; PRINTF_FUNC("group = %d, AvailableChargingCurrent = %f, GroupAvailablePower = %f, DeratingChargingCurrent = %f, DeratingChargingPower = %f \n", group, chargingInfo[group]->AvailableChargingCurrent, chargingInfo[group]->AvailableChargingPower, chargingInfo[group]->DeratingChargingCurrent, chargingInfo[group]->DeratingChargingPower); } } void GetBarCodeCallback(byte address, char *serial_number , unsigned short module_ver) { //EVSE for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++) { for (byte index = 0; index < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; index++) { if (ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PhysicalID == address) { ShmPsuData->PsuGroup[groupIndex].PsuModule[index].FwVersion[0] = (module_ver >> 8) & 0xFF; ShmPsuData->PsuGroup[groupIndex].PsuModule[index].FwVersion[1] = (module_ver) & 0xFF; //strcpy((char *)ShmPsuData->PsuGroup[groupIndex].PsuModule[ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity].SerialNumber, serial_number); } } } } void GetMiscInfoCallback(byte address, unsigned short CmdType , unsigned int value) { //EVSE for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++) { for (byte index = 0; index < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; index++) { if (ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PhysicalID == address) { if(CmdType == MISC_REQCMD_DC_BOARD_TMP){ //�ƭȥ��B�z ShmPsuData->PsuGroup[groupIndex].PsuModule[index].CriticalTemp2 = (byte)value; }else if(CmdType == MISC_REQCMD_PFC_BOARD_TMP){ //�ƭȥ��B�z ShmPsuData->PsuGroup[groupIndex].PsuModule[index].CriticalTemp3 = (byte)value; }else if(CmdType == MISC_REQCMD_FAN_SPEED){ //�ƭȥ��B�z ShmPsuData->PsuGroup[groupIndex].PsuModule[index].FanSpeed_1 = (unsigned short)value; } } } } //�ȩw�p�G���^ misc �N�{�w�^������ 1.9 �� //InfyPwrModelVerIs109 = 1; //printf("Get Misc : %d \n",InfyPwrModelVerIs109); } void SaveHardwareVersion(byte group, byte address, int hw_ver) { //EVSE for (byte index = 0; index < ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity; index++) { if (ShmPsuData->PsuGroup[group].PsuModule[index].Address == address) { ShmPsuData->PsuGroup[group].PsuModule[index].FwVersion[0] = (hw_ver >> 24) & 0xFF; ShmPsuData->PsuGroup[group].PsuModule[index].FwVersion[1] = (hw_ver >> 16) & 0xFF; ShmPsuData->PsuGroup[group].PsuModule[index].FwVersion[2] = (hw_ver >> 8) & 0xFF; ShmPsuData->PsuGroup[group].PsuModule[index].FwVersion[3] = hw_ver & 0xFF; break; } } } //Vext �ҲդG�����q�� //Iavail �Ҳեثe�]���Ҧ]�����u����X�q�y void SavePresentModeleVextIavailCallback(byte address, unsigned short Vext, unsigned short Iavail) { //EVSE //search group for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++) { for (byte index = 0; index < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; index++) { //search id if (ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PhysicalID == address) { //update module msg //ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PresentOutputVoltage = Vext; // if(ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PresentOutputVoltage >= 1500) { ShmPsuData->PsuGroup[groupIndex].PsuModule[index].AvailableCurrent = Iavail; } //printf("Vext = %d I = %d \n", Vext,Iavail); break; } } } } void GetOutputPowerSwitchStatusCallback(byte address, unsigned char value) { for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++) { for (byte index = 0; index < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; index++) { if (ShmPsuData->PsuGroup[groupIndex].PsuModule[index].PhysicalID == address) { //printf("PowerSwitch = %d, group = %d, address = %d \n", value, group, address); if(value){ ShmPsuData->PsuGroup[groupIndex].PsuModule[index].OutputPowerSwitch = 0x00; }else{ ShmPsuData->PsuGroup[groupIndex].PsuModule[index].OutputPowerSwitch = 0x01; } break; } } } } //========================================== // Init all share memory //========================================== int InitShareMemory() { int result = PASS; int MeterSMId; //creat ShmSysConfigAndInfo if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), 0777)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR("shmget ShmSysConfigAndInfo NG %d \n"); #endif result = FAIL; } else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR("shmat ShmSysConfigAndInfo NG \n"); #endif result = FAIL; } else {} //creat ShmStatusCodeData if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), 0777)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR("shmget ShmStatusCodeData NG \n"); #endif result = FAIL; } else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR("shmat ShmStatusCodeData NG \n"); #endif result = FAIL; } else {} //creat ShmPsuData if ((MeterSMId = shmget(ShmPsuKey, sizeof(struct PsuData), 0777)) < 0) { #ifdef SystemLogMessage DEBUG_ERROR("shmget ShmPsuData NG \n"); #endif result = FAIL; } else if ((ShmPsuData = shmat(MeterSMId, NULL, 0)) == (void *) -1) { #ifdef SystemLogMessage DEBUG_ERROR("shmat ShmPsuData NG \n"); #endif result = FAIL; } memset(ShmPsuData,0,sizeof(struct PsuData)); return result; } //================================================ // Main process //================================================ void InitialPsuData() { ShmPsuData->SystemPresentPsuQuantity = 0; for (byte _groupCount = 0; _groupCount < ARRAY_SIZE(ShmPsuData->PsuGroup); _groupCount++) { ShmPsuData->PsuGroup[_groupCount].GroupPresentPsuQuantity = 0; ShmPsuData->PsuGroup[_groupCount].GroupAvailablePower = 0; ShmPsuData->PsuGroup[_groupCount].GroupAvailableCurrent = 0; } ShmPsuData->Work_Step = _INIT_PSU_STATUS; } void Initialization() { bool isPass = false; while(!isPass) { isPass = true; for (byte _index = 0; _index < _gunCount; _index++) { if (!FindChargingInfoData(_index, &chargingInfo[0])) { DEBUG_ERROR("EvComm (main) : FindChargingInfoData false \n"); isPass = false; break; } } } conn_1_count = sizeof(connector_1)/sizeof(connector_1[0]); conn_2_count = sizeof(connector_2)/sizeof(connector_2[0]); } int main(void) { PRINTF_FUNC("Psu Task boot .... \n"); if(InitShareMemory() == FAIL) { #ifdef SystemLogMessage DEBUG_ERROR("InitShareMemory NG\n"); #endif if(ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory = 1; } sleep(5); return 0; } PRINTF_FUNC("InitShareMemory OK\n"); // register callback function GetPsuAddressReq(&GetPsuRequestCallback); RefreshSerialNumber(&GetBarCodeCallback); RefreshVextAndIavail(&SavePresentModeleVextIavailCallback); RefreshMiscInfo(&GetMiscInfoCallback); RefreshStatus(&SaveStatusCallback); RefreshInputVol(&SavePresentInputVoltageCallback); RefreshGetOutput(&SavePresentOutputCallback); RefreshAvailableCap(&SaveAvailableCapCallback); RefreshOutputPowerSwitch(&GetOutputPowerSwitchStatusCallback); // initial object InitialPsuData(); Initialization(); libInitialize = InitialCommunication(); byte priorityLow = 1; byte isInitialComp = NO; //main loop while (libInitialize) { // �_�q���A if (ShmSysConfigAndInfo->SysInfo.AcContactorStatus == NO) { //�@�� AC Off PSU �_�q������ PSU Group ID �|�����M 0 if (!isInitialComp) { InitialPsuData(); ShmPsuData->Work_Step = ASSIGN_START; isInitialComp = YES; } sleep(1); continue; } else isInitialComp = NO; // update psu fw req // if(psu update req ?) // { // // continue; // } // ���˥��� if (ShmPsuData->Work_Step == _NO_WORKING) { PRINTF_FUNC("== PSU == self test fail. \n"); sleep(5); } switch(ShmPsuData->Work_Step) { case ASSIGN_START: { PRINTF_FUNC("== PSU == ASSIGN_COMP \n"); sleep(5); gettimeofday(&_id_assign_time, NULL); ShmPsuData->Work_Step = ASSIGN_COMP; } break; case ASSIGN_COMP: { if (priorityLow == 1) { //�p�G�٥����o�Ҳռƶq if(ShmPsuData->SystemPresentPsuQuantity == 0) { EnableDipAddrMode(); usleep(cmdDelayTime); //�o�e���o�ثe�����Ҳռƶq (�^�����}�����������Ҳդ��۳q�T) RequestModuleTotalMumbert(); usleep(cmdDelayTime); } //�v���o�Ҳռƶq (�ثe�٥����t�s�թҥH���ϥιw�] 0) else { for (byte psuIndex = 0; psuIndex < ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity; psuIndex++) { //get status GetStatus(0, NONE_CARE_ADDRESS); usleep(cmdDelayTime); //get barcode & ver GetSerialNumber(0, NONE_CARE_ADDRESS); usleep(cmdDelayTime); GetMiscInfo(0, NONE_CARE_ADDRESS, MISC_REQCMD_DC_BOARD_TMP); usleep(cmdDelayTime); GetMiscInfo(0, NONE_CARE_ADDRESS, MISC_REQCMD_PFC_BOARD_TMP); usleep(cmdDelayTime); GetMiscInfo(0, NONE_CARE_ADDRESS, MISC_REQCMD_PFC_BOARD_TMP); usleep(cmdDelayTime); } } //printf("Get Misc2 : %d \n",InfyPwrModelVerIs109); } priorityLow >= 20 ? priorityLow = 1 : priorityLow++; // ���� 10 �� if (GetTimeoutValue(_id_assign_time) >= 10000000) { ShmPsuData->Work_Step = ENABLE_POW; PRINTF_FUNC("INFYPWR Num = %d \n", ShmPsuData->SystemPresentPsuQuantity); PRINTF_FUNC("== PSU == ENABLE_POW \n"); } } break; case ENABLE_POW: { if (ShmSysConfigAndInfo->SysInfo.BootingStatus == BOOTTING) { // �q�Φb Booting �����A - ���� PRINTF_FUNC("== PSU == _TEST_LINE_STEP \n"); ShmPsuData->Work_Step = _TEST_LINE_STEP; } else { PRINTF_FUNC("== PSU == _WORK_CHARGING \n"); ShmPsuData->Work_Step = _WORK_CHARGING; gettimeofday(&_workModePriority_time, NULL); } } break; case _TEST_LINE_STEP: { PRINTF_FUNC("cur total psu count = %d \n", ShmPsuData->SystemPresentPsuQuantity); if (ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity <= 0) { sleep(1); // ��ܿ��~ ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuNoResource = YES; continue; } ShmPsuData->Work_Step = _TEST_POWER_STEP; } break; case _TEST_POWER_STEP: { if(!_chkTotalCapStart) { _chkTotalCapStart = true; gettimeofday(&_chk_cap_time, NULL); } // ��l�ơB�����Ҧ����Ҷ� //EnableOutputPower(0, NONE_CARE_ADDRESS, SWITCH_OFF); for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++) { GetStatus(groupIndex, NONE_CARE_ADDRESS); usleep(cmdDelayTime); } for (byte psuCount = 0; psuCount < ShmPsuData->SystemPresentPsuQuantity; psuCount++) { GetAvailableCap(psuCount, NONE_CARE_ADDRESS, 0); } usleep(cmdDelayTime); if (GetTimeoutValue(_chk_cap_time) >= 2000000) { PRINTF_FUNC("AvailableChargingCurrent = %f, AvailableChargingPower = %f \n", chargingInfo[0]->AvailableChargingCurrent, chargingInfo[0]->AvailableChargingPower); for (byte index = 0; index < ShmPsuData->PsuGroup[0].GroupPresentPsuQuantity; index++) { PRINTF_FUNC("index = %d, fire index = %d, phy addr = %d \n", index, recordPsuData[index]._fire_index, recordPsuData[index]._phy_addr); } PRINTF_FUNC("== PSU == TEST_COMPLETE \n"); ShmPsuData->Work_Step = _TEST_COMPLETE; } } break; case _TEST_COMPLETE: { priorityLow = 1; sleep(1); } break; case _WORK_CHARGING: { int time = GetTimeoutValue(_workModePriority_time) / 1000; //printf("GroupCount = %d \n", ShmPsuData->GroupCount); //printf("cur total psu count = %d \n", ShmPsuData->SystemPresentPsuQuantity); // ������t : �ˬd�Ӻj�O�_���Ҷ����ΡA���h�L�����s���t�����i�J�R�q if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_PREPARE) { if (ShmPsuData->PsuGroup[ShmSysConfigAndInfo->SysInfo.CurGunSelected].GroupPresentPsuQuantity > 0) { PRINTF_FUNC("=============Smart Charging : _REASSIGNED_NONE============= Step 0 \n"); ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_NONE; } else { PRINTF_FUNC("=============Smart Charging : _REASSIGNED_GET_NEW_CAP============= Step 2 \n"); ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_GET_NEW_CAP; } } if (time > 1000) { for (byte psuCount = 0; psuCount < ShmPsuData->GroupCount; psuCount++) { GetAvailableCap(psuCount, NONE_CARE_ADDRESS, 0); } usleep(cmdDelayTime); } for (byte groupIndex = 0; groupIndex < ShmPsuData->GroupCount; groupIndex++) { if (time > 1000) { GetStatus(groupIndex, NONE_CARE_ADDRESS); usleep(cmdDelayTime); /* GetMiscInfo(SET_GROUP_CMD, 0, MISC_REQCMD_DC_BOARD_TMP); usleep(cmdDelayTime); GetMiscInfo(SET_GROUP_CMD, 0, MISC_REQCMD_PFC_BOARD_TMP); usleep(cmdDelayTime); GetMiscInfo(SET_GROUP_CMD, 0, MISC_REQCMD_PFC_BOARD_TMP); usleep(cmdDelayTime); */ // if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_GET_NEW_CAP) // { // if (groupIndex != ShmSysConfigAndInfo->SysInfo.CurGunSelected) // { // if (chargingInfo[groupIndex]->SystemStatus >= S_CHARGING && chargingInfo[groupIndex]->SystemStatus <= S_COMPLETE) // { // if (chargingInfo[groupIndex]->DeratingChargingCurrent < chargingInfo[groupIndex]->AvailableChargingCurrent) // { // // ���ݻݨD�q�y���C�ܭ������q�y // PRINTF_FUNC("Smart Charging : index = %d, EvBatterytargetCurrent = %f, DeratingChargingCurrent = %f \n", // groupIndex, chargingInfo[groupIndex]->EvBatterytargetCurrent, chargingInfo[groupIndex]->DeratingChargingCurrent); // // if ((chargingInfo[groupIndex]->EvBatterytargetCurrent <= chargingInfo[groupIndex]->DeratingChargingCurrent) || // deratingKeepCount >= DERATING) // { // // ���ݭ������� // PRINTF_FUNC("=============Smart Charging : _REASSIGNED_MAIN============= Step 3 \n"); // ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_MAIN; // } // else // { // deratingKeepCount++; // } // } // } // } // } // else // deratingKeepCount = 0; // // if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_MAIN) // { // PRINTF_FUNC("=============Smart Charging : _REASSIGNED_ADJUST============= Step 4 \n"); // //���s���t�Ҳ� // ReAssignedResource(); // gettimeofday(&_derating_time, NULL); // ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_ADJUST; // } gettimeofday(&_workModePriority_time, NULL); } GetPresentOutput(groupIndex, NONE_CARE_ADDRESS); usleep(cmdDelayTime); //GetVextAndIavail(SET_MODULE_CMD, 0); if (chargingInfo[groupIndex]->EvBatterytargetVoltage > 0 && carReqVol != chargingInfo[groupIndex]->EvBatterytargetVoltage) { carReqVol = chargingInfo[groupIndex]->EvBatterytargetVoltage; DEBUG_INFO("ev need vol = %f \n", chargingInfo[groupIndex]->EvBatterytargetVoltage); } if (chargingInfo[groupIndex]->EvBatterytargetCurrent > 0 && carReqCur != chargingInfo[groupIndex]->EvBatterytargetCurrent) { carReqCur = chargingInfo[groupIndex]->EvBatterytargetCurrent; DEBUG_INFO("ev need cur = %f \n", chargingInfo[groupIndex]->EvBatterytargetCurrent); } if (chargingInfo[groupIndex]->FireChargingVoltage > 0 && evseOutVol != chargingInfo[groupIndex]->FireChargingVoltage) { evseOutVol = chargingInfo[groupIndex]->FireChargingVoltage; PRINTF_FUNC("groupIndex = %d, evse output vol = %f \n", groupIndex, chargingInfo[groupIndex]->FireChargingVoltage); } if (chargingInfo[groupIndex]->PresentChargingCurrent > 0 && evseOutCur != chargingInfo[groupIndex]->PresentChargingCurrent) { evseOutCur = chargingInfo[groupIndex]->PresentChargingCurrent; PRINTF_FUNC("groupIndex = %d, evse output cur = %f \n", groupIndex, chargingInfo[groupIndex]->PresentChargingCurrent); } // �w��U�j���e���A�A�ǰe�ݭn�^�Ǫ���ƫ��O if (((chargingInfo[groupIndex]->SystemStatus >= S_PREPARING_FOR_EVSE && chargingInfo[groupIndex]->SystemStatus <= S_CHARGING) && chargingInfo[groupIndex]->RelayK1K2Status) || chargingInfo[groupIndex]->SystemStatus == S_REASSIGN || (chargingInfo[groupIndex]->SystemStatus >= S_CCS_PRECHARGE_ST0 && chargingInfo[groupIndex]->SystemStatus <= S_CCS_PRECHARGE_ST1)) { if (ShmPsuData->PsuGroup[groupIndex].GroupAvailableCurrent > 0) { // if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_ADJUST && // ShmSysConfigAndInfo->SysInfo.ReAssignedFlag < _REASSIGNED_COMP ) // { // // �p�G���ݭn�D���q�y�W�L�����A�h�H�����q�y���D // if (chargingInfo[groupIndex]->EvBatterytargetCurrent >= chargingInfo[groupIndex]->DeratingChargingCurrent) // { // chargingInfo[groupIndex]->EvBatterytargetCurrent = chargingInfo[groupIndex]->DeratingChargingCurrent; // } // // if (ShmSysConfigAndInfo->SysInfo.ReAssignedFlag == _REASSIGNED_ADJUST) // { // deratingTime = GetTimeoutValue(_derating_time) / 1000; // if (deratingTime > 3000) // { // deratingTime = 0; // PRINTF_FUNC("=============Smart Charging : _REASSIGNED_RELAY============= Step 5 \n"); // ShmSysConfigAndInfo->SysInfo.ReAssignedFlag = _REASSIGNED_RELAY; // } // // for(int i = 0; i < ShmPsuData->PsuGroup[groupIndex].GroupPresentPsuQuantity; i++) // { // PRINTF_FUNC("*********_REASSIGNED_ADJUST : groupIndex = %d, outputCur = %d, outputVol = %d \n", // groupIndex, // ShmPsuData->PsuGroup[groupIndex].PsuModule[i].PresentOutputCurrent, // ShmPsuData->PsuGroup[groupIndex].PsuModule[i].PresentOutputVoltage); // } // } // // // �ӥR�q�j���ؼйq���P�ؼйq�y // SetPresentOutput(groupIndex, NONE_CARE_ADDRESS, // chargingInfo[groupIndex]->EvBatterytargetVoltage, // chargingInfo[groupIndex]->EvBatterytargetCurrent, // chargingInfo[groupIndex]->DeratingChargingCurrent); // usleep(cmdDelayTime); // } // else { // �ӥR�q�j���ؼйq���P�ؼйq�y SetPresentOutput(groupIndex, NONE_CARE_ADDRESS, chargingInfo[groupIndex]->EvBatterytargetVoltage, chargingInfo[groupIndex]->EvBatterytargetCurrent, chargingInfo[groupIndex]->AvailableChargingCurrent); usleep(cmdDelayTime); } } if (chargingInfo[groupIndex]->EvBatterytargetVoltage == 0) { EnableOutputPower(groupIndex, NONE_CARE_ADDRESS, SWITCH_OFF); usleep(cmdDelayTime); EnableGreenLedFlash(groupIndex , NONE_CARE_ADDRESS , SWITCH_OFF); usleep(cmdDelayTime); } else { EnableOutputPower(groupIndex, NONE_CARE_ADDRESS, SWITCH_ON); usleep(cmdDelayTime); EnableGreenLedFlash(groupIndex , NONE_CARE_ADDRESS, SWITCH_ON); usleep(cmdDelayTime); } } else if (chargingInfo[groupIndex]->SystemStatus >= S_TERMINATING && chargingInfo[groupIndex]->SystemStatus <= S_COMPLETE) { SetPresentOutput(groupIndex, NONE_CARE_ADDRESS, ZERO_VOL, ZERO_CUR, chargingInfo[groupIndex]->AvailableChargingCurrent); usleep(cmdDelayTime); EnableGreenLedFlash(groupIndex , NONE_CARE_ADDRESS , SWITCH_OFF); usleep(cmdDelayTime); EnableOutputPower(groupIndex, NONE_CARE_ADDRESS, SWITCH_OFF); usleep(cmdDelayTime); } } priorityLow >= 200 ? priorityLow = 1 : priorityLow++; break; } } } return FAIL; }