123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525 |
- /*
- * Phihong_PsuCommObj.c
- *
- * Created on: 2019年7月2日
- * Author: 7564
- */
- #include "Phihong_PsuCommObj.h"
- struct Current_cmd_Proc Psu_cmd={
- 0,
- 0x02000200,
- 0x01000300,
- 0x01000400,
- 0x01000500,
- 0x01000600,
- 0x01000700,
- 0x01000800,
- 0x01000900,
- 0x02000A00,
- 0x02000B00,
- 0x01000C00,
- 0x02000F00,
- 0x02001000,
- 0x02001100,
- 0x02001200,
- 0x01001300,
- 0x02001400,
- 0x01001500,
- 0x01001600,
- 0x02001700,
- 0x01001800,
- 0x01001900,
- 0x01001A00,
- 0x02001B00,
- 0x0E001C00,
- };
- //================================================
- // Callback function
- //================================================
- void GetPsuAddressReq(void *func)
- {
- get_psu_addr_req = func;
- }
- void RefreshStatus(void *func)
- {
- return_status = func;
- }
- void RefreshFWVersion(void *func)
- {
- return_fw_version = func;
- }
- void RefreshFanSpeed(void *func)
- {
- return_fan_speed = func;
- }
- void RefreshTemp(void *func)
- {
- return_temp = func;
- }
- void RefreshInputVol(void *func)
- {
- return_input_vol = func;
- }
- void RefreshGetOutput(void *func)
- {
- return_get_output = func;
- }
- void RefreshInputCur(void *func)
- {
- return_input_cur = func;
- }
- void RefreshHWVersion(void *func)
- {
- //return_hw_version = func;
- }
- void RefreshAvailableCap(void *func)
- {
- return_available_cap = func;
- }
- void RefreshAlarmNotify(void *func)
- {
- return_alarm_code = func;
- }
- void RefreshFaultNotify(void *func)
- {
- return_fault_code = func;
- }
- void RefreshStatusNotify(void *func)
- {
- return_status_code = func;
- }
- void RefreshSerialNumber(void *func)
- {
- return_get_serial_number = func;
- }
- void RefreshOutputPowerSwitch(void *func)
- {
- return_output_pow_switch = func;
- }
- //================================================
- // CANBUS initialization
- //================================================
- int InitCanBus()
- {
- int s0,nbytes;
- struct timeval tv;
- struct ifreq ifr0;
- struct sockaddr_can addr0;
- system("/sbin/ip link set can1 down");
- system("/sbin/ip link set can1 type can bitrate 500000 restart-ms 100");
- system("/sbin/ip link set can1 up");
- s0 = socket(PF_CAN, SOCK_RAW, CAN_RAW);
- tv.tv_sec = 0;
- tv.tv_usec = 10000;
- if (setsockopt(s0, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)) < 0)
- {
- #ifdef SystemLogMessage
- printf("Set SO_RCVTIMEO NG");
- #endif
- }
- nbytes=40960;
- if (setsockopt(s0, SOL_SOCKET, SO_RCVBUF, &nbytes, sizeof(int)) < 0)
- {
- #ifdef SystemLogMessage
- printf("Set SO_RCVBUF NG");
- #endif
- }
- nbytes=40960;
- if (setsockopt(s0, SOL_SOCKET, SO_SNDBUF, &nbytes, sizeof(int)) < 0)
- {
- #ifdef SystemLogMessage
- printf("Set SO_SNDBUF NG");
- #endif
- }
- strcpy(ifr0.ifr_name, "can1" );
- 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;
- }
- //================================================
- // Receive Cmd from canbus
- //================================================
- void ReceiveDataFromCanBus()
- {
- int nbytes;
- struct can_frame frame;
- int intCmd;
- byte target, group, address;
- while(1)
- {
- memset(&frame, 0, sizeof(struct can_frame));
- nbytes = read(CanFd, &frame, sizeof(struct can_frame));
- if (nbytes > 0)
- {
- frame.can_id = frame.can_id & CAN_EFF_MASK;
- intCmd = (int) (frame.can_id & 0xFFFFFF00);
- target = (byte) (frame.can_id & 0x000000FF);
- group = (byte) (target >> 6);
- address = (byte) (target & 0x3F);
- switch (intCmd)
- {
- case ADDRESS_REQ:
- {
- byte phy_addr;
- char sn[7];
- phy_addr = frame.data[0];
- memcpy(sn, (char *)frame.data + 1, 7);
- get_psu_addr_req(phy_addr, sn);
- }
- break;
- case ACK_ADDRESS_ASSINGMENT:
- { }
- break;
- case ACK_STATUS:
- {
- return_status(group, address,
- ((int) frame.data[3] << 24) + ((int) frame.data[2] << 16) + ((int) frame.data[1] << 8) + (int) frame.data[0],
- ((int) frame.data[7] << 24) + ((int) frame.data[6] << 16) + ((int) frame.data[5] << 8) + (int) frame.data[4]);
- }
- break;
- case ACK_FIRMWARE_VERSION:
- {
- return_fw_version(group, address, frame.data[0], frame.data[1], frame.data + 2);
- }
- break;
- case ACK_FAN_SPEED:
- {
- return_fan_speed(group, address,
- ((short) frame.data[1] << 8) + (short) frame.data[0],
- ((short) frame.data[3] << 8) + (short) frame.data[2],
- ((short) frame.data[5] << 8) + (short) frame.data[4],
- ((short) frame.data[7] << 8) + (short) frame.data[6]);
- }
- break;
- case ACK_TEMPERATURE:
- {
- return_temp(group, address,
- frame.data[0],
- frame.data[1],
- frame.data[2],
- frame.data[3],
- frame.data[4],
- frame.data[5],
- frame.data[6]);
- }
- break;
- case ACK_PRESENT_INPUT_VOLTAGE:
- {
- return_input_vol(group, address,
- frame.data[0],
- ((short) frame.data[2] << 8) + (short) frame.data[1],
- ((short) frame.data[4] << 8) + (short) frame.data[3],
- ((short) frame.data[6] << 8) + (short) frame.data[5]);
- }
- break;
- case ACK_GET_PRESENT_OUTPUT:
- {
- return_get_output(group, address,
- (((short) frame.data[1] << 8) + (short) frame.data[0]),
- (((short) frame.data[3] << 8) + (short) frame.data[2]));
- }
- break;
- case ACK_GET_SERIAL_NUMBER:
- {
- return_get_serial_number(group, address, frame.data[0], frame.data + 1);
- }
- break;
- case ACK_COOLING_WATER_TEMP:
- {
- }
- break;
- case ACK_PRESENT_INPUT_CURRENT:
- {
- return_input_cur(group, address,
- (((short) frame.data[1] << 8) + (short) frame.data[0]),
- (((short) frame.data[3] << 8) + (short) frame.data[2]),
- (((short) frame.data[5] << 8) + (short) frame.data[4]));
- }
- break;
- case ACK_HARDWARE_VERSION:
- {
- }
- break;
- case ACK_PFC_OUTPUT_SWITCH:
- case ACK_LOG_SIZE:
- case ACK_LOG_BLOCK_CHECKSUM:
- case ACK_LOG_BLOCK_DATA:
- case ACK_CUSTOM_INFO_TRANSFER_SWITCH:
- case ACK_SET_FAN_SPEED:
- break;
- case ACK_AVAILABLE_CAP:
- {
- return_available_cap(group, address,
- (((short) frame.data[1] << 8) + (short) frame.data[0]),
- (((short) frame.data[3] << 8) + (short) frame.data[2]));
- }
- break;
- case ACK_OUTPUT_POWER_SWITCH:
- {
- return_output_pow_switch(group, address, frame.data[0]);
- }
- break;
- case ACK_SET_PRESENT_OUTPUT:
- {
- }
- break;
- case ACK_UPGRADE_REQ:
- {
- }
- break;
- case ACK_START_BLOCK_TRANS:
- {
- }
- break;
- case ACK_UPGRADE_FINISH:
- {
- }
- break;
- case CUSTOM_LOG_INFO:
- {
- }
- break;
- case ALARM_NOTIFICATION:
- {
- return_alarm_code(group, address, frame.data);
- }
- break;
- case FAULT_NOTIFICATION:
- {
- return_fault_code(group, address,
- ((int) frame.data[3] << 24) + ((int) frame.data[2] << 16) + ((int) frame.data[1] << 8) + (int) frame.data[0]);
- }
- break;
- case STATUS_NOTIFICATION:
- {
- return_status_code(group, address,
- frame.data[0],
- ((short) frame.data[2] << 8) + (short) frame.data[1],
- ((short) frame.data[4] << 8) + (short) frame.data[3]);
- }
- break;
- }
- }
- else
- {
- }
- usleep(10000);
- }
- }
- //================================================
- // Private Function
- //================================================
- int PackageIdCmd(int cmd)
- {
- return cmd | 0x80000000;
- }
- void SendCmdToPsu(int cmd, byte *data, byte dataLen)
- {
- struct can_frame frame;
- frame.can_id = cmd;
- frame.can_dlc = dataLen;
- memcpy(frame.data, data, dataLen);
- write(CanFd, &frame, sizeof(struct can_frame));
- }
- //================================================
- // API Function
- //================================================
- bool InitialCommunication()
- {
- CanFd = InitCanBus();
- if(CanFd < 0)
- {
- printf("Init can bus fail.\n");
- return false;
- }
- recFork = fork();
- if(recFork > 0)
- {
- ReceiveDataFromCanBus();
- }
- else if(recFork > 0)
- {
- printf("fork fail\n");
- }
- return true;
- }
- void PsuAddressAssignment(byte phy_addr, char *serial_number, byte real_addr, byte group)
- {
- int cmd = PackageIdCmd(Psu_cmd._address_assignment);
- byte data[8];
- data[0] = (group << 6) + real_addr;
- memcpy(data + 1, serial_number, 7);
- SendCmdToPsu(cmd, data, sizeof(data));
- }
- void GetStatus(byte group, byte address)
- {
- //printf("PSU_C_DLL : GetStatus. group = %x, address = %x \n", group, address);
- int cmd = PackageIdCmd(Psu_cmd._get_status + (group << 6) + address);
- byte data[8];
- memset(data, 0x00, ARRAY_SIZE(data));
- SendCmdToPsu(cmd, data, sizeof(data));
- }
- void GetFwVersion(byte group, byte address, byte type)
- {
- //printf("PSU_C_DLL : GetFwVersion. group = %x, address = %x \n", group, address);
- int cmd = PackageIdCmd(Psu_cmd._get_fw_ver + (group << 6) + address);
- byte data[8];
- memset(data, 0x00, ARRAY_SIZE(data));
- data[0] = type;
- SendCmdToPsu(cmd, data, sizeof(data));
- }
- void GetSerialNumber(byte group, byte address)
- {
- //printf("PSU_C_DLL : GetSerialNumber. group = %x, address = %x \n", group, address);
- int cmd = PackageIdCmd(Psu_cmd._get_serial_number + (group << 6) + address);
- byte data[8];
- memset(data, 0x00, ARRAY_SIZE(data));
- SendCmdToPsu(cmd, data, sizeof(data));
- }
- void GetFanSpeed(byte group, byte address)
- {
- //printf("PSU_C_DLL : GetFanSpeed. group = %x, address = %x \n", group, address);
- int cmd = PackageIdCmd(Psu_cmd._get_fan_speed + (group << 6) + address);
- byte data[8];
- memset(data, 0x00, ARRAY_SIZE(data));
- SendCmdToPsu(cmd, data, sizeof(data));
- }
- void GetTemperature(byte group, byte address)
- {
- //printf("PSU_C_DLL : GetTemperature. group = %x, address = %x \n", group, address);
- int cmd = PackageIdCmd(Psu_cmd._get_temperature + (group << 6) + address);
- byte data[8];
- memset(data, 0x00, ARRAY_SIZE(data));
- SendCmdToPsu(cmd, data, sizeof(data));
- }
- void GetPresentInputVol(byte group, byte address)
- {
- //printf("PSU_C_DLL : GetPresentInputVol. group = %x, address = %x \n", group, address);
- int cmd = PackageIdCmd(Psu_cmd._get_present_input_vol + (group << 6) + address);
- byte data[8];
- memset(data, 0x00, ARRAY_SIZE(data));
- SendCmdToPsu(cmd, data, sizeof(data));
- }
- void GetPresentOutput(byte group, byte address)
- {
- //printf("PSU_C_DLL : GetPresentOutput. group = %x, address = %x \n", group, address);
- int cmd = PackageIdCmd(Psu_cmd._get_present_output + (group << 6) + address);
- byte data[8];
- memset(data, 0x00, ARRAY_SIZE(data));
- SendCmdToPsu(cmd, data, sizeof(data));
- }
- void GetPresentInputCurrent(byte group, byte address)
- {
- //printf("PSU_C_DLL : GetPresentInputCurrent. group = %x, address = %x \n", group, address);
- int cmd = PackageIdCmd(Psu_cmd._get_presnet_input_cur + (group << 6) + address);
- byte data[8];
- memset(data, 0x00, ARRAY_SIZE(data));
- SendCmdToPsu(cmd, data, sizeof(data));
- }
- void GetAvailableCap(byte group, byte address, short _outputVol)
- {
- //printf("PSU_C_DLL : GetAvailableCap. group = %x, address = %x \n", group, address);
- int cmd = PackageIdCmd(Psu_cmd._get_available_cap + (group << 6) + address);
- byte data[8];
- memset(data, 0x00, ARRAY_SIZE(data));
- data[0] = _outputVol & 0xff;
- data[1] = (_outputVol >> 8) & 0xff;
- SendCmdToPsu(cmd, data, sizeof(data));
- }
- void SetPresentOutput(byte group, byte address, short vol, short cur, unsigned short AvailableCur, byte derating)
- {
- //printf("PSU_C_DLL : SetPresentOutput. group = %x, address = %x \n", group, address);
- int cmd = PackageIdCmd(Psu_cmd._set_present_output + (group << 6) + address);
- byte data[8];
- // 電壓
- data[0] = vol & 0xff;
- data[1] = (vol >> 8) & 0xff;
- // 電流 (%) : 先算出總能夠輸出的電流當 100 %, 在與現在的希望輸出的電流比對,比出來的值為希望模塊輸出電流的比率
- if (cur >= AvailableCur)
- cur = AvailableCur;
- short percent = ((float) cur / AvailableCur) * 10000;
- data[2] = percent & 0xff;
- data[3] = (percent >> 8) & 0xff;
- data[4] = derating;
- printf("vol = %d, tot_Amp = %d, need_cur = %d, percent = %d \n", vol, AvailableCur, cur, percent);
- SendCmdToPsu(cmd, data, sizeof(data));
- }
- void EnableOutputPower(byte group, byte address, byte value)
- {
- int cmd = PackageIdCmd(Psu_cmd._switch_output_pow + (group << 6) + address);
- byte data[8];
- //printf("cmd = %x \n", cmd);
- data[0] = value;
- SendCmdToPsu(cmd, data, sizeof(data));
- }
|