Module_EvRxComm.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdint.h>
  4. #include <string.h>
  5. #include <fcntl.h>
  6. #include <unistd.h>
  7. #include <sys/stat.h>
  8. #include <linux/can.h>
  9. #include <linux/can/raw.h>
  10. #include "../Config.h"
  11. #include "../Log/log.h"
  12. #include "../Define/define.h"
  13. #include "../ShareMemory/shmMem.h"
  14. #include "Ev_Comm.h"
  15. #include "Module_EvComm.h"
  16. //------------------------------------------------------------------------------
  17. static struct SysConfigData *pSysConfig = NULL;
  18. static struct SysInfoData *pSysInfo = NULL;
  19. static struct WARNING_CODE_INFO *pSysWarning = NULL;
  20. static struct AlarmCodeData *pAlarmCode = NULL;
  21. static struct CHAdeMOData *ShmCHAdeMOData = NULL;
  22. static struct GBTData *ShmGBTData = NULL;
  23. static struct CcsData *ShmCcsData = NULL;
  24. static struct FanModuleData *ShmFanModuleData = NULL;
  25. static DcCommonInfo *ShmDcCommonData = NULL;
  26. struct StatusCodeData* ShmStatusCodeData;
  27. #define TempArraySize 10
  28. uint8_t TempArray_1[TempArraySize]={0};
  29. uint8_t TempArray_2[TempArraySize]={0};
  30. uint8_t ptemp_1 = 0;
  31. uint8_t ptemp_2 = 0;
  32. bool firstcircule = true;
  33. float EvTargetVolt[2] = { 0 };
  34. float EvTargetCur[2] = { 0 };
  35. //------------------------------------------------------------------------------
  36. extern bool AbnormalStopAnalysis(uint8_t gun_index, uint8_t *errCode);
  37. //------------------------------------------------------------------------------
  38. /*static uint8_t getMaxConnectTempAndChiller(uint8_t headTemp1, uint8_t headTemp2,
  39. uint8_t chillerTemp1, uint8_t chillerTemp2)
  40. {
  41. uint8_t i = 0;
  42. uint8_t tempSource[4] = {headTemp1, headTemp2, chillerTemp1, chillerTemp2};
  43. uint8_t maxTemp = 0;
  44. if (headTemp1 == UNDEFINED_TEMP &&
  45. headTemp2 == UNDEFINED_TEMP &&
  46. chillerTemp1 == UNDEFINED_TEMP &&
  47. chillerTemp2 == UNDEFINED_TEMP) {
  48. return UNDEFINED_TEMP;
  49. }
  50. //先取得第一個非UNDEFINED_TEMP的值
  51. for (i = 0; i < (sizeof(tempSource) / sizeof(uint8_t)); i++) {
  52. if (tempSource[i] != UNDEFINED_TEMP) {
  53. maxTemp = tempSource[i];
  54. break;
  55. }
  56. }
  57. //找最大的溫度值
  58. for (i = 0; i < (sizeof(tempSource) / sizeof(uint8_t)); i++) {
  59. if (tempSource[i] != UNDEFINED_TEMP) {
  60. if (maxTemp < tempSource[i]) {
  61. maxTemp = tempSource[i];
  62. }
  63. }
  64. }
  65. return maxTemp;
  66. }
  67. */
  68. static uint8_t getAvageTemp(uint8_t value,uint8_t gun)
  69. {
  70. uint16_t avagetemp = 0;
  71. int i;
  72. uint8_t ptr = 0;
  73. uint8_t *pArray;
  74. if(gun == 0) {
  75. pArray = &TempArray_1;
  76. ptr = ptemp_1;
  77. } else {
  78. pArray = &TempArray_2;
  79. ptr = ptemp_2;
  80. }
  81. pArray[ptr] = value;
  82. for(i=0;i<TempArraySize;i++)
  83. avagetemp+=pArray[i];
  84. if (firstcircule) {
  85. avagetemp/=(ptr+1);
  86. } else {
  87. avagetemp/=TempArraySize;
  88. }
  89. ptr++;
  90. if(ptr >= TempArraySize){
  91. ptr = 0;
  92. firstcircule = false;
  93. }
  94. if(gun == 0 )
  95. ptemp_1 = ptr;
  96. else
  97. ptemp_2 = ptr;
  98. if(avagetemp > TEMP_BOUNDARY)
  99. return UNDEFINED_TEMP;
  100. return avagetemp;
  101. }
  102. static uint8_t getMaxConnectTemp(uint8_t headTemp1, uint8_t headTemp2)
  103. {
  104. uint8_t maxTemp = 0;
  105. if (headTemp1 > TEMP_BOUNDARY &&
  106. headTemp2 > TEMP_BOUNDARY) {
  107. return UNDEFINED_TEMP;
  108. }
  109. if (headTemp1 <= TEMP_BOUNDARY) {
  110. maxTemp = headTemp1;
  111. }
  112. if (headTemp2 <= TEMP_BOUNDARY) {
  113. if (headTemp2 > maxTemp) {
  114. maxTemp = headTemp2;
  115. }
  116. }
  117. return maxTemp;
  118. }
  119. static float ReadAdcVolt(uint8_t AdcChannel)
  120. {
  121. //AIN0=CCS GUN Temp 1
  122. //AIN1=CCS GUN Temp 2
  123. //AIN2=CCS_Proximity/2
  124. //AIN3=pilot voltage
  125. int fd = -1;
  126. uint8_t str[64] = {0};
  127. uint8_t AdcValue[8] = {'\0'};
  128. if (AdcChannel > 7) {
  129. return -1;
  130. }
  131. sprintf((char *)str, "/sys/bus/iio/devices/iio\:device0/in_voltage%d_raw", AdcChannel);
  132. fd = open((char *)str, O_RDONLY);
  133. read(fd, AdcValue, 4);
  134. close(fd);
  135. return (1.8 * atoi((char *)&AdcValue[0])) / 4095;
  136. //return (1.8 * atoi((char *)&AdcValue)) / 4095;
  137. }
  138. static void getChillerTemperature(ChillerTemp *chillerTemp)
  139. {
  140. uint8_t i = 0;
  141. float adcVoltage = 0.0;
  142. ChillerTemp *pChillerTemp = (ChillerTemp *)chillerTemp;
  143. for (i = 0; i < 4; i++) {
  144. adcVoltage = 0.0;
  145. adcVoltage = ReadAdcVolt(i);
  146. if ((adcVoltage <= 0.9) && (adcVoltage >= 0.8)) { //0 ~ -40
  147. pChillerTemp->Temp[i] = ((adcVoltage - 0.908) * 500) + 60;
  148. //log_info("1 adcVoltage = %f", (adcVoltage - 0.9) * 500);
  149. } else if ((adcVoltage <= 1.07) && (adcVoltage > 0.9)) {
  150. pChillerTemp->Temp[i] = ((adcVoltage - 0.91) * 705.88) + 60;
  151. //log_info("2 adcVoltage = %f", (adcVoltage - 0.9) * 500);
  152. } else {
  153. pChillerTemp->Temp[i] = UNDEFINED_TEMP;
  154. }
  155. /*CcsConnectorTemp1 = ReadAdcVolt(i);
  156. if ((CcsConnectorTemp1 <= 0.9) && (CcsConnectorTemp1 >= 0.8)) { //0 ~ -40
  157. CcsConnectorTemp1 = (CcsConnectorTemp1 - 0.9) * 500;
  158. } else if ((CcsConnectorTemp1 <= 1.07) && (CcsConnectorTemp1 > 0.9)) {
  159. CcsConnectorTemp1 = (CcsConnectorTemp1 - 0.9) * 705.88;
  160. } else {
  161. CcsConnectorTemp1 = 195; //not available
  162. }
  163. CcsConnectorTemp |= ((unsigned int)(CcsConnectorTemp1 + 60) & 0xFF) << (i * 8); //0x00(-60)~0xFE(194)
  164. */
  165. }
  166. }
  167. static void AddrAssignment(uint8_t *data)
  168. {
  169. uint8_t target_number[8];
  170. uint8_t index = 0x00;
  171. struct ChargingInfoData *pDcChargingInfo = NULL;
  172. memcpy(target_number, data, sizeof(target_number));
  173. index = *(data + 4);
  174. if (pSysConfig->TotalConnectorCount == 1) {
  175. index = 0x01;
  176. }
  177. //if (CheckUniqNumber(index)) {
  178. pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(index - 1);
  179. //DS60-120 add
  180. if (pDcChargingInfo->Type == _Type_Chademo) {
  181. log_info("Set EV board info : (Chademo) TargetAddr = %d ", index);
  182. } else if (pDcChargingInfo->Type == _Type_CCS_2) {
  183. log_info("Set EV board info : (CCS) TargetAddr = %d ", index);
  184. } else if (pDcChargingInfo->Type == _Type_GB) {
  185. log_info("Set EV board info : (GB) TargetAddr = %d ", index);
  186. }
  187. //log_info("EV board id = %x ", index); //DS60-120 remove
  188. //log_info("target_number[0] = %x ", target_number[0]);
  189. //log_info("target_number[1] = %x ", target_number[1]);
  190. //log_info("target_number[2] = %x ", target_number[2]);
  191. //log_info("target_number[3] = %x ", target_number[3]);
  192. //log_info("target_number[4] = %x ", target_number[4]);
  193. log_info("SetTargetAddr = %d, type = %d ", index, pDcChargingInfo->Type);
  194. SetTargetAddr(target_number, index);
  195. //}
  196. }
  197. void CheckEvConnect(int gunIndex)
  198. {
  199. int isSameType = FALSE;
  200. int isDisconnect = FALSE;
  201. int gunType = _Type_CCS_2;
  202. struct ChargingInfoData* pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(gunIndex);
  203. struct InfoCodeData* pInfoCode = (struct InfoCodeData*)GetShmInfoCodeData();
  204. struct ChargingInfoData* pDcChargingInfo_0 = (struct ChargingInfoData*)GetDcChargingInfoData(0);
  205. struct ChargingInfoData* pDcChargingInfo_1 = (struct ChargingInfoData*)GetDcChargingInfoData(1);
  206. if (pDcChargingInfo_0->Type == pDcChargingInfo_1->Type) {
  207. isSameType = TRUE;
  208. isDisconnect = ShmDcCommonData->EVDisconnectFlag[0] | ShmDcCommonData->EVDisconnectFlag[1];
  209. gunType = pDcChargingInfo_0->Type;
  210. } else {
  211. isDisconnect = ShmDcCommonData->EVDisconnectFlag[gunIndex];
  212. gunType = pDcChargingInfo->Type;
  213. }
  214. //log_info("ShmDcCommonData->EVDisconnectFlag[%d]:%d", gunIndex, ShmDcCommonData->EVDisconnectFlag[gunIndex]);
  215. if (isDisconnect) {
  216. switch (gunType) {
  217. case _Type_Chademo:
  218. pInfoCode->InfoEvents.bits.ChademoEvCommFail = YES;
  219. break;
  220. case _Type_CCS_2:
  221. pInfoCode->InfoEvents.bits.CcsEvCommFail = YES;
  222. break;
  223. case _Type_GB:
  224. pInfoCode->InfoEvents.bits.GbEvCommFail = YES;
  225. break;
  226. }
  227. } else {
  228. switch (gunType) {
  229. case _Type_Chademo:
  230. pInfoCode->InfoEvents.bits.ChademoEvCommFail = NO;
  231. break;
  232. case _Type_CCS_2:
  233. pInfoCode->InfoEvents.bits.CcsEvCommFail = NO;
  234. break;
  235. case _Type_GB:
  236. pInfoCode->InfoEvents.bits.GbEvCommFail = NO;
  237. break;
  238. }
  239. }
  240. }
  241. void CANReceiver(int fd)
  242. {
  243. pid_t canRecPid;
  244. canRecPid = fork();
  245. if (canRecPid < 0) {
  246. log_error("Create CAN Bus receive task failed");
  247. return;
  248. }
  249. if (canRecPid == 0) {
  250. int isContinue = 1;
  251. int nbytes;
  252. int intCmd;
  253. uint8_t _index = 0;
  254. uint8_t recvID = 0;
  255. uint8_t targetGun = 0x00;
  256. uint8_t gunTypeIndex = 0;
  257. uint8_t ver[16] = {0};
  258. uint8_t printChillerTemp = NO;
  259. uint8_t printConnTemp = NO;
  260. uint8_t chillerTemp[2] = {0, 0};
  261. uint8_t maxChillerTemp = 0;
  262. uint8_t lastChillerTemp = 0;
  263. uint8_t maxConnTemp = 0;
  264. uint8_t lastConnTemp[2] = {0, 0};
  265. struct can_frame frame;
  266. ChillerTemp chiilerTemp = {0};
  267. time_t CCS_PlugoutTimer[2] = { 0 };
  268. struct ChargingInfoData *pDcChargingInfo = NULL;
  269. pSysConfig = (struct SysConfigData *)GetShmSysConfigData();
  270. pSysInfo = (struct SysInfoData *)GetShmSysInfoData();
  271. pSysWarning = (struct WARNING_CODE_INFO *)GetShmSysWarningInfo();
  272. pAlarmCode = (struct AlarmCodeData *)GetShmAlarmCodeData();
  273. ShmCHAdeMOData = (struct CHAdeMOData *)GetShmCHAdeMOData();
  274. ShmGBTData = (struct GBTData *)GetShmGBTData();
  275. ShmCcsData = (struct CcsData *)GetShmCcsData();
  276. ShmDcCommonData = (DcCommonInfo *)GetShmDcCommonData();
  277. ShmFanModuleData = (struct FanModuleData *)GetShmFanModuleData();
  278. ShmStatusCodeData = (struct StatusCodeData*)GetShmStatusCodeData();
  279. ShmDcCommonData->EVDisconnectTime[0] = time((time_t*)NULL);
  280. ShmDcCommonData->EVDisconnectTime[1] = time((time_t*)NULL);
  281. //log_info("Module_EvRXComm Child's PID is %d", getpid());
  282. int is_busy;
  283. CCS_PlugoutTimer[0] = time((time_t*)NULL);
  284. CCS_PlugoutTimer[1] = time((time_t*)NULL);
  285. while (isContinue) {
  286. memset(&frame, 0, sizeof(struct can_frame));
  287. for (_index = 0; _index < pSysConfig->TotalConnectorCount; _index++) {
  288. pDcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(_index);
  289. if (pSysInfo->SelfTestSeq == _STEST_COMPLETE && !ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemTaskLost) {
  290. // 檢查是否有收到EV小板訊號
  291. if ((time((time_t*)NULL) - ShmDcCommonData->EVDisconnectTime[_index]) > 5 &&
  292. !ShmDcCommonData->EVDisconnectFlag[_index] &&
  293. !pSysInfo->FirmwareUpdate && !ShmDcCommonData->DebugFlag) {
  294. ShmDcCommonData->EVDisconnectTime[_index] = time((time_t*)NULL);
  295. ShmDcCommonData->EVDisconnectFlag[_index] = TRUE;
  296. log_error("Lost ev board %d can bus data!!!!", _index);
  297. system("/sbin/ip link set can0 down");
  298. sleep(1);
  299. system("/sbin/ip link set can0 type can bitrate 500000 restart-ms 100");
  300. system("/sbin/ip link set can0 up");
  301. }
  302. } else {
  303. ShmDcCommonData->pGunInfo[targetGun].EVLoseTimer = time((time_t*)NULL);
  304. ShmDcCommonData->pGunInfo[targetGun].EVLoseFlag = FALSE;
  305. }
  306. CheckEvConnect(_index);
  307. }
  308. nbytes = read(fd, &frame, sizeof(struct can_frame));
  309. if (nbytes <= 0) {
  310. usleep(10000);
  311. continue;
  312. }
  313. recvID = 0;
  314. targetGun = 0x00;
  315. intCmd = (int) (frame.can_id & CAN_EFF_MASK);
  316. if (intCmd == ADDRESS_REQ) {
  317. //ShmDcCommonData->CcsVersion = _CCS_VERSION_CHECK_TAG_V013S0;
  318. AddrAssignment(frame.data);
  319. continue;
  320. }
  321. intCmd = (int) (frame.can_id & CAN_EFF_MASK & 0xFFFFFF00);
  322. recvID = ((uint8_t) (frame.can_id & 0x000000FF)); // 0x01 or 0x02
  323. for (_index = 0; _index < pSysConfig->TotalConnectorCount; _index++) { // 假設有找到回應的 Index
  324. pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(_index);
  325. //if (gun_count == 1 &&
  326. // _chargingData[_index]->Type == _Type_CCS_2 &&
  327. // ShmDcCommonData->CcsVersion == _CCS_VERSION_CHECK_TAG_V015S0) {
  328. // target -= 1;
  329. //}
  330. if (pDcChargingInfo->Evboard_id == recvID) {
  331. targetGun = _index;
  332. break;
  333. }
  334. }
  335. if ((targetGun < 0) || (targetGun >= CHAdeMO_QUANTITY + CCS_QUANTITY + GB_QUANTITY)) {
  336. log_info("EvComm (CANReceiver) : Target index = %x is < 0 or > QUANTITY ", targetGun);
  337. usleep(10000);
  338. continue;
  339. }
  340. //else if (gun_count == 1 && targetGun == 0 && findIndex == 1 &&
  341. // ShmDcCommonData->CcsVersion == _CCS_VERSION_CHECK_TAG_V015S0) {
  342. // // 這樣的條件下~ 也是單槍 CCS 舊版本的狀況 : 因為舊版 CCS 不會 timeout, then send request id
  343. // ShmDcCommonData->CcsVersion = _CCS_VERSION_CHECK_TAG_V013S0;
  344. //}
  345. if (intCmd == 256) {
  346. log_info("EvComm command = 256");
  347. usleep(10000);
  348. continue;
  349. }
  350. // Reset Connect Timer
  351. ShmDcCommonData->EVDisconnectTime[targetGun] = time((time_t*)NULL);
  352. ShmDcCommonData->EVDisconnectFlag[targetGun] = FALSE;
  353. pDcChargingInfo = (struct ChargingInfoData *)GetDcChargingInfoData(targetGun);
  354. gunTypeIndex = pDcChargingInfo->type_index;
  355. switch (intCmd) {
  356. case NOTIFICATION_EV_STATUS:
  357. if (pDcChargingInfo->ConnectorPlugIn != frame.data[0]) {
  358. if (frame.data[0] == PLUG) {
  359. log_info("Conn %d, Plugin. ", targetGun);
  360. pDcChargingInfo->isEVCCIDVerify = false;
  361. #ifdef DD360Audi
  362. if (pSysConfig->EVCCID_Authorize)
  363. pSysInfo->CurGunSelected = targetGun;
  364. #endif
  365. } else if (frame.data[0] == UNPLUG) {
  366. if (pDcChargingInfo->Type != _Type_CCS_2)
  367. log_info("Conn %d, Unplug. ", targetGun);
  368. strcpy( (char *) pDcChargingInfo->EVCCID, "");
  369. } else {
  370. log_info("Conn %d, None Check. (%d) ", targetGun, frame.data[0]);
  371. }
  372. /*
  373. if(pDcChargingInfo->RemoteStartFlag == YES) {
  374. pSysInfo->CurGunSelected = targetGun;
  375. }*/
  376. }
  377. pDcChargingInfo->PilotVoltage = frame.data[1];
  378. // CCS 小板確認Pilot Voltage != 0
  379. is_busy = FALSE;
  380. for (_index = 0; _index < pSysConfig->TotalConnectorCount; _index++) {
  381. struct ChargingInfoData* DcChargingInfo = (struct ChargingInfoData*)GetDcChargingInfoData(_index);
  382. if ((DcChargingInfo->SystemStatus >= S_AUTHORIZING && DcChargingInfo->SystemStatus <= S_PREPARING_FOR_EVSE) ||
  383. DcChargingInfo->SystemStatus == S_CCS_PRECHARGE_ST0 || DcChargingInfo->SystemStatus == S_CCS_PRECHARGE_ST1) {
  384. is_busy = TRUE;
  385. break;
  386. }
  387. }
  388. if (pDcChargingInfo->Type == _Type_CCS_2 && pDcChargingInfo->PilotVoltage != 0) {
  389. if (frame.data[0] == UNPLUG && pDcChargingInfo->ConnectorPlugIn != frame.data[0]) {
  390. log_info("Conn %d, Unplug. ", targetGun);
  391. if ((pDcChargingInfo->SystemStatus == S_COMPLETE || pDcChargingInfo->SystemStatus == S_ALARM) &&
  392. !is_busy){
  393. pSysInfo->CurGunSelected = targetGun;
  394. }
  395. }
  396. pDcChargingInfo->ConnectorPlugIn = frame.data[0];
  397. } else {
  398. if (frame.data[0] == UNPLUG && pDcChargingInfo->ConnectorPlugIn != frame.data[0]) {
  399. if ((pDcChargingInfo->SystemStatus == S_COMPLETE || pDcChargingInfo->SystemStatus == S_ALARM) &&
  400. !is_busy) {
  401. pSysInfo->CurGunSelected = targetGun;
  402. }
  403. }
  404. pDcChargingInfo->ConnectorPlugIn = frame.data[0];
  405. }
  406. //log_info("index = %d, ConnectorPlugIn = %x, data[0] = %x ",
  407. // targetGun,
  408. // pDcChargingInfo->ConnectorPlugIn,
  409. // frame.data[0]);
  410. //log_info("ConnectorPlugIn = %x ", (-120 + frame.data[1]) / 10);
  411. break;
  412. case ACK_EV_FW_VERSION:
  413. memset(ver, 0, sizeof(ver));
  414. if (pDcChargingInfo->Type == _Type_Chademo) {
  415. memcpy(ver, frame.data, frame.can_dlc);
  416. memcpy(ShmCHAdeMOData->evse[gunTypeIndex].version, ver, ARRAY_SIZE(ver));
  417. ShmCHAdeMOData->evse[gunTypeIndex].SelfTest_Comp = PASS;
  418. log_info("chademo ver. : %s", ShmCHAdeMOData->evse[gunTypeIndex].version);
  419. } else if (pDcChargingInfo->Type == _Type_GB) {
  420. memcpy(ver, frame.data, frame.can_dlc);
  421. memcpy(ShmGBTData->evse[gunTypeIndex].version, ver, ARRAY_SIZE(ver));
  422. ShmGBTData->evse[gunTypeIndex].SelfTest_Comp = PASS;
  423. log_info("gbt ver. : %s", ShmGBTData->evse[gunTypeIndex].version);
  424. } else if (pDcChargingInfo->Type == _Type_CCS_2) {
  425. if (ShmCcsData->CommProtocol == _CCS_COMM_V2GMessage_DIN70121) {
  426. memcpy(ver, frame.data, frame.can_dlc); //DS60-120 add
  427. //for (uint8_t _vCount = 0, _vPoint = 0; _vCount < frame.can_dlc; _vCount++) {//DS60-120 remove
  428. /*if (_vCount % 2 == 0 && _vCount != 0)
  429. {
  430. ver[_vCount + _vPoint] = 0x2E;
  431. _vPoint++;
  432. }*/
  433. //ver[_vCount + _vPoint] = frame.data[_vCount];
  434. //}
  435. memcpy(&ShmCcsData->V2GMessage_DIN70121[gunTypeIndex].version, ver, ARRAY_SIZE(ver));
  436. ShmCcsData->V2GMessage_DIN70121[gunTypeIndex].SelfTest_Comp = PASS;
  437. log_info("CCS FW = %s ", ShmCcsData->V2GMessage_DIN70121[gunTypeIndex].version);
  438. }
  439. }
  440. if (targetGun == 0) {
  441. memset(pSysInfo->Connector1FwRev,
  442. 0,
  443. sizeof(pSysInfo->Connector1FwRev));
  444. memcpy(pSysInfo->Connector1FwRev, ver, ARRAY_SIZE(ver));
  445. } else if (targetGun == 1) {
  446. memset(pSysInfo->Connector2FwRev,
  447. 0,
  448. sizeof(pSysInfo->Connector2FwRev));
  449. memcpy(pSysInfo->Connector2FwRev, ver, ARRAY_SIZE(ver));
  450. }
  451. break;
  452. case ACK_EV_HW_VERSION:
  453. //log_info("Get EV HW = %s ", frame.data);
  454. break;
  455. case ACK_GET_OUTPUT_REQ:
  456. //DS60-120 add
  457. if ((pDcChargingInfo->SystemStatus >= S_PREPARING_FOR_EV &&
  458. pDcChargingInfo->SystemStatus <= S_CHARGING) ||
  459. (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
  460. pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1)
  461. ) {
  462. if (pDcChargingInfo->EvBatteryStartSoc <= 0 &&
  463. pDcChargingInfo->SystemStatus >= S_PREPARING_FOR_EVSE) {
  464. pDcChargingInfo->EvBatteryStartSoc = frame.data[1];
  465. }
  466. if (frame.data[1] > pDcChargingInfo->EvBatterySoc) {
  467. pDcChargingInfo->EvBatterySoc = frame.data[1];
  468. log_info("Gun%d SOC:%d", targetGun, pDcChargingInfo->EvBatterySoc);
  469. }
  470. }
  471. //pDcChargingInfo->EvBatterySoc = frame.data[1]; //DS60-120 remove
  472. //Jerry add set voltage limit
  473. pDcChargingInfo->EvBatterytargetVoltage = (float)((frame.data[3] << 8) + frame.data[2]) / 10;
  474. if (pDcChargingInfo->EvBatterytargetVoltage > (GetMaxChargingVol(targetGun) * 0.1)) {
  475. pDcChargingInfo->EvBatterytargetVoltage = (GetMaxChargingVol(targetGun) * 0.1);
  476. }
  477. //printf("id = %d, EvBatterytargetVoltage = %.2f", targetGun, pDcChargingInfo->EvBatterytargetVoltage);
  478. //Jerry add set currency limit
  479. pDcChargingInfo->EvBatterytargetCurrent = (float)((frame.data[5] << 8) + frame.data[4]) / 10;
  480. if (pDcChargingInfo->EvBatterytargetCurrent > (GetMaxCharginigCur(targetGun) * 0.1)) {
  481. pDcChargingInfo->EvBatterytargetCurrent = (GetMaxCharginigCur(targetGun) * 0.1);
  482. }
  483. //printf("id = %d, EvBatterytargetCurrent = %.2f", targetGun, pDcChargingInfo->EvBatterytargetCurrent);
  484. pDcChargingInfo->RemainChargingDuration = ((short) frame.data[7] << 8) + (short) frame.data[6];
  485. //printf("RemainChargingDuration = %d", pDcChargingInfo->RemainChargingDuration);
  486. if (pDcChargingInfo->Type == _Type_Chademo) {
  487. if (ShmCHAdeMOData->ev[gunTypeIndex].PresentMsgFlowStatus != frame.data[0]) {
  488. log_info("Gun%d CHAdeMO board status = %d ", targetGun, ShmCHAdeMOData->ev[gunTypeIndex].PresentMsgFlowStatus);
  489. ShmCHAdeMOData->ev[gunTypeIndex].PresentMsgFlowStatus = frame.data[0];
  490. }
  491. ShmCHAdeMOData->ev[gunTypeIndex].EvDetection = frame.data[0];
  492. ShmCHAdeMOData->ev[gunTypeIndex].SOC = pDcChargingInfo->EvBatterySoc;
  493. ShmCHAdeMOData->ev[gunTypeIndex].TargetBatteryVoltage = (pDcChargingInfo->EvBatterytargetVoltage * 10);
  494. ShmCHAdeMOData->ev[gunTypeIndex].ChargingCurrentRequest = (pDcChargingInfo->EvBatterytargetCurrent * 10);
  495. } else if (pDcChargingInfo->Type == _Type_GB) {
  496. if (ShmGBTData->ev[gunTypeIndex].PresentMsgFlowStatus != frame.data[0]) {
  497. log_info("Gun%d GB Board status = %d ", targetGun, ShmGBTData->ev[pDcChargingInfo->type_index].PresentMsgFlowStatus);
  498. ShmGBTData->ev[gunTypeIndex].PresentMsgFlowStatus = frame.data[0];
  499. }
  500. ShmGBTData->ev[gunTypeIndex].PresentMsgFlowStatus = frame.data[0];
  501. ShmGBTData->ev[gunTypeIndex].EvDetection = frame.data[0];
  502. ShmGBTData->ev[gunTypeIndex].SOC = pDcChargingInfo->EvBatterySoc;
  503. ShmGBTData->ev[gunTypeIndex].TargetBatteryVoltage = (pDcChargingInfo->EvBatterytargetVoltage * 10);
  504. ShmGBTData->ev[gunTypeIndex].ChargingCurrentRequest = (pDcChargingInfo->EvBatterytargetCurrent * 10);
  505. } else if (pDcChargingInfo->Type == _Type_CCS_2) {
  506. if (ShmCcsData->CommProtocol == _CCS_COMM_V2GMessage_DIN70121) {
  507. if (ShmCcsData->V2GMessage_DIN70121[gunTypeIndex].PresentMsgFlowStatus != frame.data[0] && frame.data[0] != 0xFF) {
  508. log_info("Gun%d CCS board status = %d ", targetGun, ShmCcsData->V2GMessage_DIN70121[pDcChargingInfo->type_index].PresentMsgFlowStatus);
  509. ShmCcsData->V2GMessage_DIN70121[gunTypeIndex].PresentMsgFlowStatus = frame.data[0];
  510. }
  511. }
  512. }
  513. if (pDcChargingInfo->EvBatterytargetVoltage > (EvTargetVolt[targetGun] + 3) ||
  514. pDcChargingInfo->EvBatterytargetVoltage < (EvTargetVolt[targetGun] - 3) ||
  515. pDcChargingInfo->EvBatterytargetCurrent >(EvTargetCur[targetGun] + 1) ||
  516. pDcChargingInfo->EvBatterytargetCurrent < (EvTargetCur[targetGun] - 1)) {
  517. log_info("Gun%d Battery TargetVoltage = %.1f , TargetCurrent = %.1f",
  518. targetGun, pDcChargingInfo->EvBatterytargetVoltage, pDcChargingInfo->EvBatterytargetCurrent);
  519. EvTargetVolt[targetGun] = pDcChargingInfo->EvBatterytargetVoltage;
  520. EvTargetCur[targetGun] = pDcChargingInfo->EvBatterytargetCurrent;
  521. }
  522. //log_info("EvBatterytargetVoltage = %f ", pDcChargingInfo->EvBatterytargetVoltage);
  523. //log_info("EvBatterytargetCurrent = %f ", pDcChargingInfo->EvBatterytargetCurrent);
  524. //log_info("BatteryVoltage = %d ",
  525. // ShmCHAdeMOData->ev[_chargingData[target]->type_index].TargetBatteryVoltage);
  526. //log_info("CurrentRequest = %d ",
  527. // ShmCHAdeMOData->ev[_chargingData[target]->type_index].ChargingCurrentRequest);
  528. break;
  529. case ACK_GET_EV_BATTERY_INFO:
  530. //_chargingData[target].EvACorDCcharging = frame.data[0];
  531. //_chargingData[target]->TotalBatteryCap = ((float) frame.data[4] << 8) + (short) frame.data[3];
  532. pDcChargingInfo->EvBatteryMaxVoltage = ((float)(((uint16_t)frame.data[4] << 8) + (uint16_t)frame.data[3])) / 10;
  533. //_chargingData[target]->EvBatteryMaxCurrent = ((float) frame.data[4] << 8) + (short) frame.data[3];
  534. //_chargingData[target].MaxiBatteryCurrent = ((short) frame.data[6] << 8) + (short) frame.data[5];
  535. if (pDcChargingInfo->Type == _Type_Chademo) {
  536. ShmCHAdeMOData->ev[gunTypeIndex].TotalBatteryCapacity = ((uint16_t)frame.data[2] << 8) + (uint16_t)frame.data[1];
  537. ShmCHAdeMOData->ev[gunTypeIndex].MaxiBatteryVoltage = pDcChargingInfo->EvBatteryMaxVoltage;
  538. //log_info("EvBatteryMaxVoltage = %f ", _chargingData[target]->EvBatteryMaxVoltage);
  539. //log_info("TotalBatteryCapacity = %d ", ShmCHAdeMOData->ev[_chargingData[target]->type_index].TotalBatteryCapacity);
  540. //log_info("MaxiBatteryVoltage = %d ", ShmCHAdeMOData->ev[_chargingData[target]->type_index].MaxiBatteryVoltage);
  541. } else if (pDcChargingInfo->Type == _Type_GB) {
  542. ShmGBTData->ev[gunTypeIndex].TotalBatteryCapacity = ((uint16_t)frame.data[2] << 8) + (uint16_t)frame.data[1];
  543. ShmGBTData->ev[gunTypeIndex].MaxiBatteryVoltage = pDcChargingInfo->EvBatteryMaxVoltage;
  544. }
  545. //else if (pDcChargingInfo->Type == _Type_CCS_2) {
  546. //}
  547. break;
  548. case ACK_GET_MISCELLANEOUS_INFO:
  549. pDcChargingInfo->GunLocked = frame.data[0];
  550. pDcChargingInfo->PilotVoltage = ((float)(-120 + frame.data[3])) / 10;
  551. if (pDcChargingInfo->Type == _Type_Chademo) {
  552. ShmCHAdeMOData->evse[gunTypeIndex].ConnectorTemperatureP = frame.data[1];
  553. ShmCHAdeMOData->evse[gunTypeIndex].ConnectorTemperatureN = frame.data[2];
  554. ShmCHAdeMOData->evse[gunTypeIndex].EvboardStatus = frame.data[7];
  555. } else if (pDcChargingInfo->Type == _Type_GB) {
  556. ShmGBTData->evse[gunTypeIndex].ConnectorTemperatureP = frame.data[1];
  557. ShmGBTData->evse[gunTypeIndex].ConnectorTemperatureN = frame.data[2];
  558. ShmGBTData->evse[gunTypeIndex].EvboardStatus = frame.data[7];
  559. }
  560. /*else if (pDcChargingInfo->Type == _Type_CCS_2) {
  561. if (ShmCcsData->CommProtocol == _CCS_COMM_V2GMessage_DIN70121) {
  562. //ShmCcsData->V2GMessage_DIN70121[gunTypeIndex]. .ConnectorTemperatureP = frame.data[1];
  563. //ShmCcsData->V2GMessage_DIN70121[gunTypeIndex]. .ConnectorTemperatureN = frame.data[2];
  564. }
  565. }*/
  566. ShmDcCommonData->ConnectorTemp[gunTypeIndex][0] = frame.data[1];
  567. ShmDcCommonData->ConnectorTemp[gunTypeIndex][1] = frame.data[2];
  568. if (ShmDcCommonData->TestTemperature == YES) { //ReadCmdline test
  569. break;
  570. }
  571. printChillerTemp = NO;
  572. printConnTemp = NO;
  573. if (((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x80) >> 7) == YES) {
  574. getChillerTemperature(&chiilerTemp);
  575. memcpy((char *)ShmDcCommonData->SystemTemp, (char *)chiilerTemp.Temp, sizeof(ChillerTemp));
  576. chillerTemp[0] = getMaxConnectTemp(chiilerTemp.Temp[0], chiilerTemp.Temp[1]);
  577. chillerTemp[1] = getMaxConnectTemp(chiilerTemp.Temp[2], chiilerTemp.Temp[3]);
  578. maxChillerTemp = getMaxConnectTemp(chillerTemp[0], chillerTemp[1]);
  579. //if ((maxChillerTemp - 3) >= pDcChargingInfo->ChillerTemp) {
  580. // printChillerTemp = YES;
  581. //}
  582. if(maxChillerTemp > (lastChillerTemp + 2) || maxChillerTemp < (lastChillerTemp - 2))
  583. {
  584. lastChillerTemp = maxChillerTemp;
  585. printChillerTemp = YES;
  586. }
  587. pDcChargingInfo->ChillerTemp = maxChillerTemp;
  588. }
  589. // 避免EV小板Reset產生數值為零的情況
  590. if (ShmDcCommonData->ConnectorTemp[gunTypeIndex][0] != 0 && ShmDcCommonData->ConnectorTemp[gunTypeIndex][1] != 0) {
  591. maxConnTemp = getMaxConnectTemp(ShmDcCommonData->ConnectorTemp[gunTypeIndex][0], ShmDcCommonData->ConnectorTemp[gunTypeIndex][1]);
  592. //if ((maxConnTemp - 3) >= pDcChargingInfo->ConnectorTemp) {
  593. // printConnTemp = YES;
  594. //}
  595. maxConnTemp = getAvageTemp(maxConnTemp, targetGun);
  596. if (maxConnTemp > (lastConnTemp[targetGun] + 2) || maxConnTemp < (lastConnTemp[targetGun] - 2))
  597. {
  598. lastConnTemp[targetGun] = maxConnTemp;
  599. printConnTemp = YES;
  600. }
  601. pDcChargingInfo->ConnectorTemp = maxConnTemp;
  602. } else {
  603. /*
  604. log_info("Connector%d Tmep is zero:[%d,%d]", gunTypeIndex, ShmDcCommonData->ConnectorTemp[gunTypeIndex][0],
  605. ShmDcCommonData->ConnectorTemp[gunTypeIndex][1]);
  606. */
  607. }
  608. //紀錄槍頭和水冷機溫度, 在系統狀態變化或溫度大於150
  609. if ((ShmDcCommonData->SystemModeChange[targetGun] == YES) ||
  610. (printConnTemp == YES) ||
  611. (printChillerTemp == YES) //&&
  612. //(((pDcChargingInfo->ConnectorTemp >= GUN_OTP_VALUE) &&
  613. // (pDcChargingInfo->ConnectorTemp != UNDEFINED_TEMP)) ||
  614. // ((pDcChargingInfo->ChillerTemp >= GUN_OTP_VALUE) &&
  615. // (pDcChargingInfo->ChillerTemp != UNDEFINED_TEMP)))
  616. ) {
  617. ShmDcCommonData->SystemModeChange[targetGun] = NO;
  618. log_info("Gun%d max head temp = %d, chiller1 = [%d,%d], chiller2 = [%d,%d]",
  619. targetGun,
  620. pDcChargingInfo->ConnectorTemp,
  621. chiilerTemp.Temp[0],
  622. chiilerTemp.Temp[1],
  623. chiilerTemp.Temp[2],
  624. chiilerTemp.Temp[3]);
  625. }
  626. if (((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x80) >> 7) == YES) {
  627. //沒有水冷槍
  628. break;
  629. }
  630. if ((ShmDcCommonData->ChillerValve.MultiChillerGun & 0x7F) == 1) {
  631. //單一水冷槍,不需要切換水冷機油閥
  632. //ShmFanModuleData-> ? = YES; //尚未定義
  633. break;
  634. }
  635. //紀錄槍頭溫度
  636. if (pDcChargingInfo->ConnectorTemp != UNDEFINED_TEMP) {
  637. if (targetGun == 0) {
  638. ShmDcCommonData->ChillerValve.LeftTemp = pDcChargingInfo->ConnectorTemp;
  639. } else if (targetGun == 1) {
  640. ShmDcCommonData->ChillerValve.RightTemp = pDcChargingInfo->ConnectorTemp;
  641. }
  642. }
  643. //有兩把水冷槍,判斷兩把槍頭溫度,將水冷機節流閥導向溫度高的那一把槍
  644. if (ShmDcCommonData->ChillerValve.LeftTemp > ShmDcCommonData->ChillerValve.RightTemp) {
  645. //ShmFanModuleData->? = YES; //尚未定義
  646. } else {
  647. //ShmFanModuleData->? = NO; //尚未定義
  648. }
  649. //log_info("EvboardStatus = %x ",
  650. // ShmCHAdeMOData->evse[gunTypeIndex].EvboardStatus);
  651. //log_info("ConnectorPlug locked = %x ",
  652. // frame.data[0]);
  653. //log_info("PilotVoltage = %x ", (-120 + frame.data[3]) / 10);
  654. break;
  655. case ACK_EVSE_ISOLATION_STATUS:
  656. break;
  657. case ACK_EVSE_PRECHAGE_INFO:
  658. pDcChargingInfo->PrechargeStatus = frame.data[0];
  659. break;
  660. case NOTIFICATION_EV_STOP:
  661. // 車端要求停止
  662. if ((pDcChargingInfo->SystemStatus >= S_REASSIGN_CHECK && //DS60-120 add
  663. pDcChargingInfo->SystemStatus <= S_TERMINATING) ||
  664. (pDcChargingInfo->SystemStatus >= S_CCS_PRECHARGE_ST0 &&
  665. pDcChargingInfo->SystemStatus <= S_CCS_PRECHARGE_ST1)) {
  666. // frame.data[0] : 0x01 => normal stop, 0x02 => ev emergency stop
  667. log_info("----------------------------- (%d) NOTIFICATION_EV_STOP err level = %d -----------------------------",
  668. targetGun,
  669. frame.data[0]);
  670. if (frame.data[0] == 0x02) {
  671. if (AbnormalStopAnalysis(targetGun, frame.data + 1) == true) {
  672. pDcChargingInfo->StopChargeFlag = YES;
  673. } else {
  674. pDcChargingInfo->NormalStopChargeFlag = YES;
  675. }
  676. } else {
  677. AbnormalStopAnalysis(targetGun, frame.data + 1);
  678. pDcChargingInfo->NormalStopChargeFlag = YES;
  679. }
  680. }
  681. break;
  682. case ACK_EVCCID_REQ:
  683. if (frame.can_dlc > 0 && strcmp ( (char *)pDcChargingInfo->EVCCID, "" ) == EQUAL &&
  684. pDcChargingInfo->Type == _Type_CCS_2)
  685. {
  686. {
  687. memset (
  688. ShmCcsData->V2GMessage_DIN70121 [pDcChargingInfo->type_index].SessionSetupRequest.EVCCID,
  689. 0,
  690. sizeof(ShmCcsData->V2GMessage_DIN70121 [pDcChargingInfo->type_index].SessionSetupRequest.EVCCID) );
  691. memcpy (
  692. ShmCcsData->V2GMessage_DIN70121 [pDcChargingInfo->type_index].SessionSetupRequest.EVCCID,
  693. frame.data, frame.can_dlc );
  694. }
  695. sprintf ( (char *) pDcChargingInfo->EVCCID, "%.2x%.2x%.2x%.2x%.2x%.2x", frame.data [0],
  696. frame.data [1], frame.data [2], frame.data [3], frame.data [4], frame.data [5] );
  697. pDcChargingInfo->EVCCID [17] = '\0';
  698. log_info( "Gun %d->EVCCID = %s ", targetGun, pDcChargingInfo->EVCCID );
  699. }
  700. break;
  701. default:
  702. log_info("EV board = %d, Ack none defined. intCmd = %d ", targetGun, intCmd);
  703. break;
  704. }//switch
  705. usleep(10000);
  706. }//while
  707. }
  708. }