/* * PhGroup_PsuCommObj.c * * Created on: 2022年02月22日 * Author: 8274 */ #include "PhGroup_PsuCommObj.h" #define ARRAY_SIZE(A) (sizeof(A) / sizeof(A[0])) #define NO 0 #define YES 1 #define DEBUG_LIB 1 void PRINTF_LIB_FUNC(char *string, ...); float IEEE_754_to_float(const byte raw[4]); //================================================ // Private function //================================================ void PRINTF_LIB_FUNC(char *string, ...) { if (DEBUG_LIB) { va_list args; char buffer[4096]; va_start(args, string); vsnprintf(buffer, sizeof(buffer), string, args); va_end(args); printf("%s \n", buffer); } } float IEEE_754_to_float(const byte raw[4]) { float fValue = 0; byte *pbyte = (byte *)&fValue; *(pbyte + 0) = raw[3]; *(pbyte + 1) = raw[2]; *(pbyte + 2) = raw[1]; *(pbyte + 3) = raw[0]; return fValue; } //================================================ // Callback function //================================================ void RefreshPsuIndex(int (*func)(byte group, byte address)) { return_psuIndex = func; } void RefreshGroup(void *func) { return_group = func; } void RefreshInfyPwrAlarmFlag(void *func) { return_infy_pwr_alarm_flag = func; } void RefreshPhPwrAlarmFlag(void *func) { return_ph_pwr_alarm_flag = func; } void RefreshAlarmStatus(void *func) { return_alarm_status = func; } void RefreshAmbient(void *func) { return_ambient = func; } void RefreshModuleCount(void *func) { return_module_count = func; } void RefreshSysModuleCount(void *func) { return_sys_module_count = func; } void RefreshAvailableCap(void *func) { return_available_cap = func; } void RefreshFwDcVersion(void *func) { return_fw_dc_version = func; } void RefreshFwPfcVersion(void *func) { return_fw_pfc_version = func; } void RefreshInputVol(void *func) { return_input_vol = func; } void RefreshInputCur(void *func) { return_input_cur = func; } void RefreshGetOutput(void *func) { return_get_output = func; } void RefreshGetOutputF(void *func) { return_get_output_float = func; } void RefreshGetModuleOutput(void *func) { return_module_output = func; } void RefreshGetErrorRecord(void *func) { return_error_record = func; } void RefreshFanSpeedInfo(void *func) { return_fan_speed = func; } void RefreshInletTemp(void *func) { return_inlet_temp = func; } void RefreshExletTemp(void *func) { return_exlet_temp = func; } void RefreshOutletTemp(void *func) { return_outlet_temp = func; } void RefreshOtherTemp(void *func) { return_other_temp = func; } void RefreshIavailable(void *func) { return_iavail_info = func; } void AutoMode_RefreshOutputAndTemp(void *func) { return_output_temp = func; } void AutoMode_RefreshModuleStatus(void *func) { return_module_status = func; } void AutoMode_RefreshModuleInput(void *func) { return_module_input = func; } //================================================ // CANBUS initialization //================================================ int InitCanBus() { int s0,nbytes; struct timeval tv; struct ifreq ifr0; struct sockaddr_can addr0; struct can_filter rfilter[2]; 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_LIB_FUNC("Set SO_RCVTIMEO NG"); #endif } nbytes=40960; if (setsockopt(s0, SOL_SOCKET, SO_RCVBUF, &nbytes, sizeof(int)) < 0) { #ifdef SystemLogMessage PRINTF_LIB_FUNC("Set SO_RCVBUF NG"); #endif } nbytes=40960; if (setsockopt(s0, SOL_SOCKET, SO_SNDBUF, &nbytes, sizeof(int)) < 0) { #ifdef SystemLogMessage PRINTF_LIB_FUNC("Set SO_SNDBUF NG"); #endif } nbytes=40960; //DIR_GrpMaster_to_CSU rfilter[0].can_id = 0xE000; rfilter[0].can_mask = 0xE000; //DIR_Slave_to_CSU rfilter[1].can_id = 0xD000; rfilter[1].can_mask = 0xD000; if (setsockopt(s0, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter)) < 0) { #ifdef SystemLogMessage PRINTF_LIB_FUNC("Set SOL_CAN_RAW 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; } void ReceiveDataFromCanBus() //onedollar:可加入err handling(讀取can id的CAN_ERR_FLAG,若有err,繼續由can id其他位看是什麼錯誤) { int nbytes; struct can_frame frame; PH_PwrFrame *PH_PwrFrameMsg; byte group_PSU, slv_address, length; unsigned short full_address = 0; while(1) { memset(&frame, 0, sizeof(struct can_frame)); nbytes = read(CanFd, &frame, sizeof(struct can_frame)); if (nbytes > 0) { PH_PwrFrameMsg = (PH_PwrFrame *)&frame.can_id; length = frame.can_dlc; group_PSU = PH_PwrFrameMsg->PHBits.SlaveGroup; slv_address = PH_PwrFrameMsg->PHBits.SlaveAddress; full_address = (group_PSU << GroupAdd_Position) | slv_address; switch(PH_PwrFrameMsg->PHBits.MessageID) { // 0x09 case (PH_PSU_RCmd_GetPresentOutput + PH_PSU_Ack_Msg): { byte vol[2], cur[2], maxCur[2]; memcpy(vol, frame.data, 2); memcpy(cur, frame.data + 2, 2); memcpy(maxCur, frame.data + 4, 2); // _Vol unit: 1V // _Cur unit: 1A float _Vol = ((frame.data[0] << 8) + frame.data[1]) * 0.1; float _Cur = ((frame.data[2] << 8) + frame.data[3]) * 0.1; //[GetModuleOutputF] & [GetMouleIavailable] if(PH_PwrFrameMsg->PHBits.DIR == DIR_GrpMaster_to_CSU) { return_get_output_float(group_PSU, _Vol, _Cur); } //[GetMouleIavailable] if(PH_PwrFrameMsg->PHBits.DIR == DIR_Slave_to_CSU) { // Iavail unit: 0.1A // Vext unit: 0.1V unsigned short iAvailCur = (frame.data[4] << 8) + frame.data[5]; unsigned short vextVol = (frame.data[0] << 8) + frame.data[1]; int psuIndex = 0; psuIndex = return_psuIndex(group_PSU, slv_address - 1); return_iavail_info(psuIndex, iAvailCur, vextVol); return_module_output(psuIndex, _Vol, _Cur); return_alarm_status(psuIndex, PH_PwrFrameMsg->PHBits.Status); } } break; // 0x03 case (PH_PSU_RCmd_GetGroupModuleCount + PH_PSU_Ack_Msg): { byte count = frame.data[0]; return_module_count(group_PSU, count, true); } break; // 0x04 case (PH_PSU_RCmd_GetAlarmFault + PH_PSU_Ack_Msg): { unsigned int alarm_0 = 0, alarm_1 = 0; if(length >= 8) { alarm_1 = (frame.data[0] << 24) | (frame.data[1] << 16) | (frame.data[2] << 8) | frame.data[3]; alarm_0 = (frame.data[4] << 24) | (frame.data[5] << 16) | (frame.data[6] << 8) | frame.data[7]; } int psuIndex = 0; psuIndex = return_psuIndex(group_PSU, slv_address - 1); return_group(group_PSU, psuIndex, full_address); return_ph_pwr_alarm_flag(psuIndex, PH_PwrFrameMsg->PHBits.Status, alarm_1, alarm_0); short maxVol = 9500; //950V short minVol = 1500; //150V short maxCur = 1000; //100A short totalPow = 300; //30kW return_available_cap(psuIndex, maxVol, minVol, maxCur, totalPow); } break; // 0x05 case (PH_PSU_RCmd_GetModuleVersion + PH_PSU_Ack_Msg): { //[GetModuleVer] byte type = 0; char strVer[6]; unsigned short fwVer = 0; type = frame.data[0]; memset(strVer, 0x00, sizeof(strVer)); memcpy(strVer, &frame.data[1], sizeof(strVer) - 1); fwVer = (frame.data[6] << 8) | frame.data[7]; int psuIndex = 0; psuIndex = return_psuIndex(group_PSU, slv_address - 1); char version[32]; memset(version, 0x00, sizeof(version)); if(type == PH_FW_DD_App) { sprintf(version, "%s_%d.%02d", strVer, (fwVer / 100), (fwVer % 100)); return_fw_dc_version(psuIndex, version); } if(type == PH_FW_PFC_App) { sprintf(version, "%s%d.%02d", strVer, (fwVer / 100), (fwVer % 100)); return_fw_pfc_version(psuIndex, version); } } break; //case (PSU_RCmd_SysOutputVolCur): //APP沒有使用到 //case (PSU_RCmd_ModuleBarcode): //APP沒有使用到 // 0x06 case (PH_PSU_RCmd_GetTemperature + PH_PSU_Ack_Msg): { //[GetDcTemperature] and [GetPfcTemperature] char temp[8]; memset(temp, 0xFF, sizeof(temp)); for(int i = 0; i < length; i++) { temp[i] = (char)frame.data[i]; } int psuIndex = 0; psuIndex = return_psuIndex(group_PSU, slv_address - 1); // temp[0]: ambient // temp[1]: reserve // temp[2]: dd in 1 // temp[3]: dd in 2 // temp[4]: liquid in // temp[5]: dd out 1 // temp[6]: dd out 2 // temp[7]: liquid out return_ambient(psuIndex, temp[0]); return_inlet_temp(psuIndex, temp[4]); return_outlet_temp(psuIndex, temp[7]); return_other_temp(psuIndex, temp[2], temp[3], temp[5], temp[6]); } break; // 0x07 case (PH_PSU_RCmd_GetACInputVoltage + PH_PSU_Ack_Msg): { unsigned short voltage_L1 = 0, voltage_L2 = 0, voltage_L3 = 0; voltage_L1 = (frame.data[1] << 8) | frame.data[2]; voltage_L2 = (frame.data[3] << 8) | frame.data[4]; voltage_L3 = (frame.data[5] << 8) | frame.data[6]; int psuIndex = 0; psuIndex = return_psuIndex(group_PSU, slv_address - 1); return_input_vol(psuIndex, voltage_L1, voltage_L2, voltage_L3); } break; // 0x08 case (PH_PSU_RCmd_GetACInputCurrent + PH_PSU_Ack_Msg): { // unit: 0.1A unsigned short current_L1 = 0, current_L2 = 0, current_L3 = 0; current_L1 = (frame.data[0] << 8) | frame.data[1]; current_L2 = (frame.data[2] << 8) | frame.data[3]; current_L3 = (frame.data[4] << 8) | frame.data[5]; int psuIndex = 0; psuIndex = return_psuIndex(group_PSU, slv_address - 1); return_input_cur(psuIndex, current_L1, current_L2, current_L3); } break; case (PH_PSU_RCmd_GetErrorRecord + PH_PSU_Ack_Msg): { byte countdown = 0; byte error_record[7]; countdown = frame.data[0]; memcpy(error_record, &frame.data[1], sizeof(error_record)); int psuIndex = 0; psuIndex = return_psuIndex(group_PSU, slv_address - 1); return_error_record(psuIndex, countdown, error_record); } break; } } else usleep(10000); } } //================================================ // Private Function //================================================ void SendCmdToPsu(int cmd, byte *dataPH, byte dataLen) { PH_PwrFrame PwrFrameMsg; struct can_frame frame; //設定 CANBSU 2.0B 長封包(Extended ID) PwrFrameMsg.PwrMessage = cmd | CAN_EFF_FLAG; frame.can_id = PwrFrameMsg.PwrMessage; frame.can_dlc = dataLen; memset(frame.data, 0x00, sizeof(frame.data)); if(dataLen > 0) { memcpy(frame.data, dataPH, dataLen); } write(CanFd, &frame, sizeof(struct can_frame)); //onedollar:可加入偵錯機制(發送byte數檢驗) /* // 群命令才 delay if (PwrFrameMsg.PHBits.SlaveGroup == PH_ADD_BROADCAST) usleep(CMD_DELAY_TIME); */ usleep(CMD_DELAY_TIME); } void SetPowerOnOff(byte group, byte slv_address, byte DIR, byte value) { byte dataPH = value; //0xA1 ON //0x00 OFF PH_PwrFrame PwrFrameMsg; PwrFrameMsg.PwrMessage = 0; PwrFrameMsg.PHBits.MessageID = PH_PSU_WCmd_ModulePowerOnOff; PwrFrameMsg.PHBits.SlaveAddress = slv_address; PwrFrameMsg.PHBits.SlaveGroup = group; PwrFrameMsg.PHBits.DIR = DIR; SendCmdToPsu(PwrFrameMsg.PwrMessage, &dataPH, 1); } void SetOutput(byte group, byte slv_address, byte DIR, int voltage, int current) { byte dataPH[4] = {0}; PH_PwrFrame PwrFrameMsg; PwrFrameMsg.PwrMessage = 0; PwrFrameMsg.PHBits.MessageID = PH_PSU_WCmd_SetOutputCommand; dataPH[0] = ((voltage >> 8) & 0xFF); dataPH[1] = (voltage & 0xFF); dataPH[2] = ((current >> 8) & 0xFF); dataPH[3] = (current & 0xFF); PwrFrameMsg.PHBits.SlaveAddress = slv_address; PwrFrameMsg.PHBits.SlaveGroup = group; PwrFrameMsg.PHBits.DIR = DIR; SendCmdToPsu(PwrFrameMsg.PwrMessage, dataPH, sizeof(dataPH)); } // voltage unit: 0.1V void GetModuleIavailable(byte group, unsigned short voltage) { byte data[2] = {0}; PH_PwrFrame PwrFrameMsg; PwrFrameMsg.PwrMessage = 0; PwrFrameMsg.PHBits.MessageID = PH_PSU_RCmd_GetPresentOutput; PwrFrameMsg.PHBits.SlaveGroup = group; PwrFrameMsg.PHBits.SlaveAddress = ALL_Slave; PwrFrameMsg.PHBits.DIR = DIR_CSU_to_Slave; data[0] = (voltage >> 8) & 0xFF; data[1] = voltage & 0xFF; SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data)); } pid_t InitialCommunication(void) { CanFd = InitCanBus(); if(CanFd < 0) { return false; } recFork = fork(); if(recFork == 0) { ReceiveDataFromCanBus(); return 0; } return recFork; } //================================================ // API Function //================================================ void SwitchPower(byte group, byte value) { //對群控制,DIR_CSU_to_GrpMaster,僅需指定group SetPowerOnOff(group, 0, DIR_CSU_to_GrpMaster, value); } void SinglePsuPower(byte full_address, byte value) { //對單控制,DIR_CSU_to_Slave,需指定group + slv_address byte group = (full_address >> GroupAdd_Position) & ALL_Group; byte slv_address = full_address & ALL_Slave; SetPowerOnOff(group, slv_address, DIR_CSU_to_Slave, value); } void SwitchPower_On(byte group) { SwitchPower(group, PH_PSU_POWER_ON); } void SwitchPower_Off(byte group) { SwitchPower(group, PH_PSU_POWER_OFF); } void SinglePsuPower_On(byte address) { SinglePsuPower(address, PH_PSU_POWER_ON); } void SinglePsuPower_Off(byte address) { SinglePsuPower(address, PH_PSU_POWER_OFF); } void SleepMode(byte group, byte value) { // no function } void FlashLed(byte group, byte value) { // no function } void SingleFlashLed(byte address, byte value) { // no function } void FlashLed_Static(byte group) { FlashLed(group, 0); } void FlashLed_Blinking(byte group) { FlashLed(group, 1); } void SingleFlashLed_Static(byte address) { SingleFlashLed(address, 0); } void SingleFlashLed_Blinking(byte address) { SingleFlashLed(address, 1); } void PresentOutputVol(byte group, int voltage, int current_percent) { //電流命令需換成最大電流之百分比,兩種方式: //(1) API輸入參數多一個Max Current,由此Func內換算百分比 //(2) API輸入參數改為current_percent,APP端算出百分比後輸入 SetOutput(group, 0, DIR_CSU_to_GrpMaster, voltage, current_percent); } void SingleOutputVol(byte full_address, int voltage, int current_percent) { byte group = (full_address >> GroupAdd_Position) & ALL_Group; byte slv_address = full_address & ALL_Slave; SetOutput(group, slv_address, DIR_CSU_to_GrpMaster, voltage, current_percent); } void FanNoiseInfo(byte group, byte value) { // no function } void SetWalkInConfig(byte group, byte enable, byte sec) { // no function } void SetDirModulePresentOutput(byte group, int voltage, int current, byte _switch, byte _interRelay) { // no function } void SetDipSwitchMode() { // no function } void UnlockPsuAlarm(byte full_address) { byte group = (full_address >> GroupAdd_Position) & ALL_Group; byte slv_address = full_address & ALL_Slave; byte dataPH = PUS_UNLOCK_CMD; PH_PwrFrame PwrFrameMsg; PwrFrameMsg.PwrMessage = 0; PwrFrameMsg.PHBits.MessageID = PH_PSU_WCmd_UnlockPsuCommand; PwrFrameMsg.PHBits.SlaveGroup = group; PwrFrameMsg.PHBits.SlaveAddress = slv_address; PwrFrameMsg.PHBits.DIR = DIR_CSU_to_Slave; SendCmdToPsu(PwrFrameMsg.PwrMessage, &dataPH, 1); } /**********************************************************************************/ /*** ***/ /*** Get ***/ /*** ***/ /**********************************************************************************/ // 0x04 void GetStatus(byte group) { PH_PwrFrame PwrFrameMsg; PwrFrameMsg.PwrMessage = 0; PwrFrameMsg.PHBits.MessageID = PH_PSU_RCmd_GetAlarmFault; PwrFrameMsg.PHBits.SlaveGroup = group; PwrFrameMsg.PHBits.SlaveAddress = ALL_Slave; PwrFrameMsg.PHBits.DIR = DIR_CSU_to_Slave; SendCmdToPsu(PwrFrameMsg.PwrMessage, 0, 0); } void GetFanSpeed(byte group) { } // 0x06 void GetDcTemperature(byte group) { PH_PwrFrame PwrFrameMsg; PwrFrameMsg.PwrMessage = 0; PwrFrameMsg.PHBits.MessageID = PH_PSU_RCmd_GetTemperature; PwrFrameMsg.PHBits.SlaveGroup = group; PwrFrameMsg.PHBits.SlaveAddress = ALL_Slave; PwrFrameMsg.PHBits.DIR = DIR_CSU_to_Slave; SendCmdToPsu(PwrFrameMsg.PwrMessage, 0, 0); } // 0x06 void GetPfcTemperature(byte group) { PH_PwrFrame PwrFrameMsg; PwrFrameMsg.PwrMessage = 0; PwrFrameMsg.PHBits.MessageID = PH_PSU_RCmd_GetTemperature; PwrFrameMsg.PHBits.SlaveGroup = group; PwrFrameMsg.PHBits.SlaveAddress = ALL_Slave; PwrFrameMsg.PHBits.DIR = DIR_CSU_to_Slave; SendCmdToPsu(PwrFrameMsg.PwrMessage, 0, 0); } // 0x03 void GetModuleCount(byte group) { PH_PwrFrame PwrFrameMsg; PwrFrameMsg.PwrMessage = 0; PwrFrameMsg.PHBits.MessageID = PH_PSU_RCmd_GetGroupModuleCount; PwrFrameMsg.PHBits.SlaveGroup = group; PwrFrameMsg.PHBits.DIR = DIR_CSU_to_GrpMaster; SendCmdToPsu(PwrFrameMsg.PwrMessage, 0, 0); } void GetSysModuleCount(void) { } // 0x05 void GetModuleVer(byte group, byte type) { byte dataPH = 0; PH_PwrFrame PwrFrameMsg; PwrFrameMsg.PwrMessage = 0; PwrFrameMsg.PHBits.MessageID = PH_PSU_RCmd_GetModuleVersion; PwrFrameMsg.PHBits.SlaveGroup = group; PwrFrameMsg.PHBits.SlaveAddress = ALL_Slave; PwrFrameMsg.PHBits.DIR = DIR_CSU_to_Slave; //DD FW ver. 0x01 //PFC FW ver. 0x02 //DD Bootloader ver. 0x03 //PFC Bootloader ver. 0x04 dataPH = type; SendCmdToPsu(PwrFrameMsg.PwrMessage, &dataPH, 1); } void GetAllModuleVer(byte group) { GetModuleVer(group, PH_FW_DD_App); GetModuleVer(group, PH_FW_PFC_App); } // 0x04 void GetModuleCap(byte group) { PH_PwrFrame PwrFrameMsg; PwrFrameMsg.PwrMessage = 0; PwrFrameMsg.PHBits.MessageID = PH_PSU_RCmd_GetAlarmFault; PwrFrameMsg.PHBits.SlaveGroup = group; PwrFrameMsg.PHBits.SlaveAddress = ALL_Slave; PwrFrameMsg.PHBits.DIR = DIR_CSU_to_Slave; SendCmdToPsu(PwrFrameMsg.PwrMessage, 0, 0); } void GetModuleBarCode(byte group) { // no function } // 0x07 void GetModuleInputVol(byte group) { PH_PwrFrame PwrFrameMsg; PwrFrameMsg.PwrMessage = 0; PwrFrameMsg.PHBits.MessageID = PH_PSU_RCmd_GetACInputVoltage; PwrFrameMsg.PHBits.SlaveGroup = group; PwrFrameMsg.PHBits.SlaveAddress = ALL_Slave; PwrFrameMsg.PHBits.DIR = DIR_CSU_to_Slave; SendCmdToPsu(PwrFrameMsg.PwrMessage, 0, 0); } // 0x08 void GetModuleInputCur(byte group) { PH_PwrFrame PwrFrameMsg; PwrFrameMsg.PwrMessage = 0; PwrFrameMsg.PHBits.MessageID = PH_PSU_RCmd_GetACInputCurrent; PwrFrameMsg.PHBits.SlaveGroup = group; PwrFrameMsg.PHBits.SlaveAddress = ALL_Slave; PwrFrameMsg.PHBits.DIR = DIR_CSU_to_Slave; SendCmdToPsu(PwrFrameMsg.PwrMessage, 0, 0); } void GetModuleOutput(byte group) //APP未使用此 { byte dataPH[2] = {0}; PH_PwrFrame PwrFrameMsg; PwrFrameMsg.PwrMessage = 0; PwrFrameMsg.PHBits.MessageID = PH_PSU_RCmd_GetPresentOutput; PwrFrameMsg.PHBits.SlaveGroup = group; PwrFrameMsg.PHBits.SlaveAddress = 0; PwrFrameMsg.PHBits.DIR = DIR_CSU_to_GrpMaster; SendCmdToPsu(PwrFrameMsg.PwrMessage, dataPH, sizeof(dataPH)); } void GetModuleOutputF(byte group) { byte dataPH[2] = {0}; PH_PwrFrame PwrFrameMsg; PwrFrameMsg.PwrMessage = 0; PwrFrameMsg.PHBits.MessageID = PH_PSU_RCmd_GetPresentOutput; PwrFrameMsg.PHBits.SlaveGroup = group; PwrFrameMsg.PHBits.SlaveAddress = 0; PwrFrameMsg.PHBits.DIR = DIR_CSU_to_GrpMaster; SendCmdToPsu(PwrFrameMsg.PwrMessage, dataPH, sizeof(dataPH)); } void GetErrorRecord(byte group) { PH_PwrFrame PwrFrameMsg; PwrFrameMsg.PwrMessage = 0; PwrFrameMsg.PHBits.MessageID = PH_PSU_RCmd_GetErrorRecord; PwrFrameMsg.PHBits.SlaveGroup = group; PwrFrameMsg.PHBits.SlaveAddress = ALL_Slave; PwrFrameMsg.PHBits.DIR = DIR_CSU_to_Slave; SendCmdToPsu(PwrFrameMsg.PwrMessage, 0, 0); } /**********************************************************************************/ /*** ***/ /*** Upgrate ***/ /*** ***/ /**********************************************************************************/ void ChangePsuBaudrate(short baudrate) { }