Phihong_PsuCommObj.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. /*
  2. * Phihong_PsuCommObj.c
  3. *
  4. * Created on: 2019年7月2日
  5. * Author: 7564
  6. */
  7. #include "Phihong_PsuCommObj.h"
  8. struct Current_cmd_Proc Psu_cmd={
  9. 0,
  10. 0x02000200,
  11. 0x01000300,
  12. 0x01000400,
  13. 0x01000500,
  14. 0x01000600,
  15. 0x01000700,
  16. 0x01000800,
  17. 0x01000900,
  18. 0x02000A00,
  19. 0x02000B00,
  20. 0x01000C00,
  21. 0x02000F00,
  22. 0x02001000,
  23. 0x02001100,
  24. 0x02001200,
  25. 0x01001300,
  26. 0x02001400,
  27. 0x01001500,
  28. 0x01001600,
  29. 0x02001700,
  30. 0x01001800,
  31. 0x01001900,
  32. 0x01001A00,
  33. 0x02001B00,
  34. 0x0E001C00,
  35. };
  36. //================================================
  37. // Callback function
  38. //================================================
  39. void GetPsuAddressReq(void *func)
  40. {
  41. get_psu_addr_req = func;
  42. }
  43. void RefreshStatus(void *func)
  44. {
  45. return_status = func;
  46. }
  47. void RefreshFWVersion(void *func)
  48. {
  49. return_fw_version = func;
  50. }
  51. void RefreshFanSpeed(void *func)
  52. {
  53. return_fan_speed = func;
  54. }
  55. void RefreshTemp(void *func)
  56. {
  57. return_temp = func;
  58. }
  59. void RefreshInputVol(void *func)
  60. {
  61. return_input_vol = func;
  62. }
  63. void RefreshGetOutput(void *func)
  64. {
  65. return_get_output = func;
  66. }
  67. void RefreshInputCur(void *func)
  68. {
  69. return_input_cur = func;
  70. }
  71. void RefreshHWVersion(void *func)
  72. {
  73. //return_hw_version = func;
  74. }
  75. void RefreshAvailableCap(void *func)
  76. {
  77. return_available_cap = func;
  78. }
  79. void RefreshAlarmNotify(void *func)
  80. {
  81. return_alarm_code = func;
  82. }
  83. void RefreshFaultNotify(void *func)
  84. {
  85. return_fault_code = func;
  86. }
  87. void RefreshStatusNotify(void *func)
  88. {
  89. return_status_code = func;
  90. }
  91. void RefreshSerialNumber(void *func)
  92. {
  93. return_get_serial_number = func;
  94. }
  95. void RefreshOutputPowerSwitch(void *func)
  96. {
  97. return_output_pow_switch = func;
  98. }
  99. //================================================
  100. // CANBUS initialization
  101. //================================================
  102. int InitCanBus()
  103. {
  104. int s0,nbytes;
  105. struct timeval tv;
  106. struct ifreq ifr0;
  107. struct sockaddr_can addr0;
  108. system("/sbin/ip link set can1 down");
  109. system("/sbin/ip link set can1 type can bitrate 500000 restart-ms 100");
  110. system("/sbin/ip link set can1 up");
  111. s0 = socket(PF_CAN, SOCK_RAW, CAN_RAW);
  112. tv.tv_sec = 0;
  113. tv.tv_usec = 10000;
  114. if (setsockopt(s0, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)) < 0)
  115. {
  116. #ifdef SystemLogMessage
  117. printf("Set SO_RCVTIMEO NG");
  118. #endif
  119. }
  120. nbytes=40960;
  121. if (setsockopt(s0, SOL_SOCKET, SO_RCVBUF, &nbytes, sizeof(int)) < 0)
  122. {
  123. #ifdef SystemLogMessage
  124. printf("Set SO_RCVBUF NG");
  125. #endif
  126. }
  127. nbytes=40960;
  128. if (setsockopt(s0, SOL_SOCKET, SO_SNDBUF, &nbytes, sizeof(int)) < 0)
  129. {
  130. #ifdef SystemLogMessage
  131. printf("Set SO_SNDBUF NG");
  132. #endif
  133. }
  134. strcpy(ifr0.ifr_name, "can1" );
  135. ioctl(s0, SIOCGIFINDEX, &ifr0); /* ifr.ifr_ifindex gets filled with that device's index */
  136. addr0.can_family = AF_CAN;
  137. addr0.can_ifindex = ifr0.ifr_ifindex;
  138. bind(s0, (struct sockaddr *)&addr0, sizeof(addr0));
  139. return s0;
  140. }
  141. //================================================
  142. // Receive Cmd from canbus
  143. //================================================
  144. void ReceiveDataFromCanBus()
  145. {
  146. int nbytes;
  147. struct can_frame frame;
  148. int intCmd;
  149. byte target, group, address;
  150. while(1)
  151. {
  152. memset(&frame, 0, sizeof(struct can_frame));
  153. nbytes = read(CanFd, &frame, sizeof(struct can_frame));
  154. if (nbytes > 0)
  155. {
  156. frame.can_id = frame.can_id & CAN_EFF_MASK;
  157. intCmd = (int) (frame.can_id & 0xFFFFFF00);
  158. target = (byte) (frame.can_id & 0x000000FF);
  159. group = (byte) (target >> 6);
  160. address = (byte) (target & 0x3F);
  161. switch (intCmd)
  162. {
  163. case ADDRESS_REQ:
  164. {
  165. byte phy_addr;
  166. char sn[7];
  167. phy_addr = frame.data[0];
  168. memcpy(sn, (char *)frame.data + 1, 7);
  169. get_psu_addr_req(phy_addr, sn);
  170. }
  171. break;
  172. case ACK_ADDRESS_ASSINGMENT:
  173. { }
  174. break;
  175. case ACK_STATUS:
  176. {
  177. return_status(group, address,
  178. ((int) frame.data[3] << 24) + ((int) frame.data[2] << 16) + ((int) frame.data[1] << 8) + (int) frame.data[0],
  179. ((int) frame.data[7] << 24) + ((int) frame.data[6] << 16) + ((int) frame.data[5] << 8) + (int) frame.data[4]);
  180. }
  181. break;
  182. case ACK_FIRMWARE_VERSION:
  183. {
  184. return_fw_version(group, address, frame.data[0], frame.data[1], frame.data + 2);
  185. }
  186. break;
  187. case ACK_FAN_SPEED:
  188. {
  189. return_fan_speed(group, address,
  190. ((short) frame.data[1] << 8) + (short) frame.data[0],
  191. ((short) frame.data[3] << 8) + (short) frame.data[2],
  192. ((short) frame.data[5] << 8) + (short) frame.data[4],
  193. ((short) frame.data[7] << 8) + (short) frame.data[6]);
  194. }
  195. break;
  196. case ACK_TEMPERATURE:
  197. {
  198. return_temp(group, address,
  199. frame.data[0],
  200. frame.data[1],
  201. frame.data[2],
  202. frame.data[3],
  203. frame.data[4],
  204. frame.data[5],
  205. frame.data[6]);
  206. }
  207. break;
  208. case ACK_PRESENT_INPUT_VOLTAGE:
  209. {
  210. return_input_vol(group, address,
  211. frame.data[0],
  212. ((short) frame.data[2] << 8) + (short) frame.data[1],
  213. ((short) frame.data[4] << 8) + (short) frame.data[3],
  214. ((short) frame.data[6] << 8) + (short) frame.data[5]);
  215. }
  216. break;
  217. case ACK_GET_PRESENT_OUTPUT:
  218. {
  219. return_get_output(group, address,
  220. (((short) frame.data[1] << 8) + (short) frame.data[0]),
  221. (((short) frame.data[3] << 8) + (short) frame.data[2]));
  222. }
  223. break;
  224. case ACK_GET_SERIAL_NUMBER:
  225. {
  226. return_get_serial_number(group, address, frame.data[0], frame.data + 1);
  227. }
  228. break;
  229. case ACK_COOLING_WATER_TEMP:
  230. {
  231. }
  232. break;
  233. case ACK_PRESENT_INPUT_CURRENT:
  234. {
  235. return_input_cur(group, address,
  236. (((short) frame.data[1] << 8) + (short) frame.data[0]),
  237. (((short) frame.data[3] << 8) + (short) frame.data[2]),
  238. (((short) frame.data[5] << 8) + (short) frame.data[4]));
  239. }
  240. break;
  241. case ACK_HARDWARE_VERSION:
  242. {
  243. }
  244. break;
  245. case ACK_PFC_OUTPUT_SWITCH:
  246. case ACK_LOG_SIZE:
  247. case ACK_LOG_BLOCK_CHECKSUM:
  248. case ACK_LOG_BLOCK_DATA:
  249. case ACK_CUSTOM_INFO_TRANSFER_SWITCH:
  250. case ACK_SET_FAN_SPEED:
  251. break;
  252. case ACK_AVAILABLE_CAP:
  253. {
  254. return_available_cap(group, address,
  255. (((short) frame.data[1] << 8) + (short) frame.data[0]),
  256. (((short) frame.data[3] << 8) + (short) frame.data[2]));
  257. }
  258. break;
  259. case ACK_OUTPUT_POWER_SWITCH:
  260. {
  261. return_output_pow_switch(group, address, frame.data[0]);
  262. }
  263. break;
  264. case ACK_SET_PRESENT_OUTPUT:
  265. {
  266. }
  267. break;
  268. case ACK_UPGRADE_REQ:
  269. {
  270. }
  271. break;
  272. case ACK_START_BLOCK_TRANS:
  273. {
  274. }
  275. break;
  276. case ACK_UPGRADE_FINISH:
  277. {
  278. }
  279. break;
  280. case CUSTOM_LOG_INFO:
  281. {
  282. }
  283. break;
  284. case ALARM_NOTIFICATION:
  285. {
  286. return_alarm_code(group, address, frame.data);
  287. }
  288. break;
  289. case FAULT_NOTIFICATION:
  290. {
  291. return_fault_code(group, address,
  292. ((int) frame.data[3] << 24) + ((int) frame.data[2] << 16) + ((int) frame.data[1] << 8) + (int) frame.data[0]);
  293. }
  294. break;
  295. case STATUS_NOTIFICATION:
  296. {
  297. return_status_code(group, address,
  298. frame.data[0],
  299. ((short) frame.data[2] << 8) + (short) frame.data[1],
  300. ((short) frame.data[4] << 8) + (short) frame.data[3]);
  301. }
  302. break;
  303. }
  304. }
  305. else
  306. {
  307. }
  308. usleep(10000);
  309. }
  310. }
  311. //================================================
  312. // Private Function
  313. //================================================
  314. int PackageIdCmd(int cmd)
  315. {
  316. return cmd | 0x80000000;
  317. }
  318. void SendCmdToPsu(int cmd, byte *data, byte dataLen)
  319. {
  320. struct can_frame frame;
  321. frame.can_id = cmd;
  322. frame.can_dlc = dataLen;
  323. memcpy(frame.data, data, dataLen);
  324. write(CanFd, &frame, sizeof(struct can_frame));
  325. }
  326. //================================================
  327. // API Function
  328. //================================================
  329. bool InitialCommunication()
  330. {
  331. CanFd = InitCanBus();
  332. if(CanFd < 0)
  333. {
  334. printf("Init can bus fail.\n");
  335. return false;
  336. }
  337. recFork = fork();
  338. if(recFork > 0)
  339. {
  340. ReceiveDataFromCanBus();
  341. }
  342. else if(recFork > 0)
  343. {
  344. printf("fork fail\n");
  345. }
  346. return true;
  347. }
  348. void PsuAddressAssignment(byte phy_addr, char *serial_number, byte real_addr, byte group)
  349. {
  350. int cmd = PackageIdCmd(Psu_cmd._address_assignment);
  351. byte data[8];
  352. data[0] = (group << 6) + real_addr;
  353. memcpy(data + 1, serial_number, 7);
  354. SendCmdToPsu(cmd, data, sizeof(data));
  355. }
  356. void GetStatus(byte group, byte address)
  357. {
  358. //printf("PSU_C_DLL : GetStatus. group = %x, address = %x \n", group, address);
  359. int cmd = PackageIdCmd(Psu_cmd._get_status + (group << 6) + address);
  360. byte data[8];
  361. memset(data, 0x00, ARRAY_SIZE(data));
  362. SendCmdToPsu(cmd, data, sizeof(data));
  363. }
  364. void GetFwVersion(byte group, byte address, byte type)
  365. {
  366. //printf("PSU_C_DLL : GetFwVersion. group = %x, address = %x \n", group, address);
  367. int cmd = PackageIdCmd(Psu_cmd._get_fw_ver + (group << 6) + address);
  368. byte data[8];
  369. memset(data, 0x00, ARRAY_SIZE(data));
  370. data[0] = type;
  371. SendCmdToPsu(cmd, data, sizeof(data));
  372. }
  373. void GetSerialNumber(byte group, byte address)
  374. {
  375. //printf("PSU_C_DLL : GetSerialNumber. group = %x, address = %x \n", group, address);
  376. int cmd = PackageIdCmd(Psu_cmd._get_serial_number + (group << 6) + address);
  377. byte data[8];
  378. memset(data, 0x00, ARRAY_SIZE(data));
  379. SendCmdToPsu(cmd, data, sizeof(data));
  380. }
  381. void GetFanSpeed(byte group, byte address)
  382. {
  383. //printf("PSU_C_DLL : GetFanSpeed. group = %x, address = %x \n", group, address);
  384. int cmd = PackageIdCmd(Psu_cmd._get_fan_speed + (group << 6) + address);
  385. byte data[8];
  386. memset(data, 0x00, ARRAY_SIZE(data));
  387. SendCmdToPsu(cmd, data, sizeof(data));
  388. }
  389. void GetTemperature(byte group, byte address)
  390. {
  391. //printf("PSU_C_DLL : GetTemperature. group = %x, address = %x \n", group, address);
  392. int cmd = PackageIdCmd(Psu_cmd._get_temperature + (group << 6) + address);
  393. byte data[8];
  394. memset(data, 0x00, ARRAY_SIZE(data));
  395. SendCmdToPsu(cmd, data, sizeof(data));
  396. }
  397. void GetPresentInputVol(byte group, byte address)
  398. {
  399. //printf("PSU_C_DLL : GetPresentInputVol. group = %x, address = %x \n", group, address);
  400. int cmd = PackageIdCmd(Psu_cmd._get_present_input_vol + (group << 6) + address);
  401. byte data[8];
  402. memset(data, 0x00, ARRAY_SIZE(data));
  403. SendCmdToPsu(cmd, data, sizeof(data));
  404. }
  405. void GetPresentOutput(byte group, byte address)
  406. {
  407. //printf("PSU_C_DLL : GetPresentOutput. group = %x, address = %x \n", group, address);
  408. int cmd = PackageIdCmd(Psu_cmd._get_present_output + (group << 6) + address);
  409. byte data[8];
  410. memset(data, 0x00, ARRAY_SIZE(data));
  411. SendCmdToPsu(cmd, data, sizeof(data));
  412. }
  413. void GetPresentInputCurrent(byte group, byte address)
  414. {
  415. //printf("PSU_C_DLL : GetPresentInputCurrent. group = %x, address = %x \n", group, address);
  416. int cmd = PackageIdCmd(Psu_cmd._get_presnet_input_cur + (group << 6) + address);
  417. byte data[8];
  418. memset(data, 0x00, ARRAY_SIZE(data));
  419. SendCmdToPsu(cmd, data, sizeof(data));
  420. }
  421. void GetAvailableCap(byte group, byte address, short _outputVol)
  422. {
  423. //printf("PSU_C_DLL : GetAvailableCap. group = %x, address = %x \n", group, address);
  424. int cmd = PackageIdCmd(Psu_cmd._get_available_cap + (group << 6) + address);
  425. byte data[8];
  426. memset(data, 0x00, ARRAY_SIZE(data));
  427. data[0] = _outputVol & 0xff;
  428. data[1] = (_outputVol >> 8) & 0xff;
  429. SendCmdToPsu(cmd, data, sizeof(data));
  430. }
  431. void SetPresentOutput(byte group, byte address, short vol, short cur, unsigned short AvailableCur, byte derating)
  432. {
  433. //printf("PSU_C_DLL : SetPresentOutput. group = %x, address = %x \n", group, address);
  434. int cmd = PackageIdCmd(Psu_cmd._set_present_output + (group << 6) + address);
  435. byte data[8];
  436. // 電壓
  437. data[0] = vol & 0xff;
  438. data[1] = (vol >> 8) & 0xff;
  439. // 電流 (%) : 先算出總能夠輸出的電流當 100 %, 在與現在的希望輸出的電流比對,比出來的值為希望模塊輸出電流的比率
  440. if (cur >= AvailableCur)
  441. cur = AvailableCur;
  442. short percent = ((float) cur / AvailableCur) * 10000;
  443. data[2] = percent & 0xff;
  444. data[3] = (percent >> 8) & 0xff;
  445. data[4] = derating;
  446. printf("vol = %d, tot_Amp = %d, need_cur = %d, percent = %d \n", vol, AvailableCur, cur, percent);
  447. SendCmdToPsu(cmd, data, sizeof(data));
  448. }
  449. void EnableOutputPower(byte group, byte address, byte value)
  450. {
  451. int cmd = PackageIdCmd(Psu_cmd._switch_output_pow + (group << 6) + address);
  452. byte data[8];
  453. //printf("cmd = %x \n", cmd);
  454. data[0] = value;
  455. SendCmdToPsu(cmd, data, sizeof(data));
  456. }