MotorControlModuleSDFM_TMS3.../Projects/EFC_Application/UMLibrary/driver/ModbusAnalogWideValue.cpp

144 lines
3.3 KiB
C++

/*
* ModbusAnalogWideValue.cpp
*
* Created on: 17 àïð. 2023 ã.
* Author: titov
*/
#include "ModbusAnalogWideValue.hh"
#include <cstring>
#include <math.h>
bool driver::modbus::ModbusAnalogWideValue::extract() {
using namespace std;
float value = tech_value.get();
if( isnan(value) )
memcpy( data, &nan_out_of_range, sizeof(uint32_t) );
else {
float temp = value * read_coeff + read_offset;
if( temp < down_limit || temp > up_limit ) {
memcpy( data, &nan_out_of_range, sizeof(uint32_t) );
} else {
if( format_signed ) {
int32_t signed_reg = rintf(temp);
memcpy( data, &signed_reg, sizeof(int32_t) );
} else {
uint32_t unsigned_input = rintf(temp);
memcpy( data, &unsigned_input, sizeof(uint32_t) );
}
}
}
return true;
}
bool driver::modbus::ModbusAnalogWideValue::update() {
if( format_signed ) {
int32_t signed_input;
memcpy( &signed_input, data, sizeof(int32_t) );
if( signed_input >= down_limit and signed_input <= up_limit ) {
tech_value.set( signed_input * write_coeff + write_offset );
return true;
} else
return false;
} else {
uint32_t unsigned_input;
memcpy( &unsigned_input, data, sizeof(uint32_t) );
if( unsigned_input >= down_limit and unsigned_input <= up_limit ) {
tech_value.set( unsigned_input * write_coeff + write_offset );
return true;
} else
return false;
}
}
driver::modbus::ModbusAnalogWideValue::Status driver::modbus::ModbusAnalogWideValue::PartShower::read(
uint16_t & reg ) {
if( self.extract() ) {
reg = *data;
return Done;
} else
return Failure;
}
driver::modbus::ModbusAnalogWideValue::Status driver::modbus::ModbusAnalogWideValue::PartShower::write(
uint16_t reg ) {
*data = reg;
return Done;
}
driver::modbus::ModbusAnalogWideValue::PartUpdater::Status driver::modbus::ModbusAnalogWideValue::PartUpdater::read(
uint16_t & reg ) {
reg = *data;
return Done;
}
driver::modbus::ModbusAnalogWideValue::PartUpdater::Status driver::modbus::ModbusAnalogWideValue::PartUpdater::write(
uint16_t reg ) {
return *data = reg, self.update() ? Done : Failure;
}
driver::modbus::ModbusAnalogWideValue::ModbusAnalogWideValue(
systemic::IValueType<float> &value, float write_coeff,
float write_offset, float read_coeff, float read_offset, bool sign,
float up_limit, float down_limit, uint32_t nan_register,
WordSequence sequnece) : tech_value(value),
format_signed(sign), nan_out_of_range(nan_register),
down_limit(down_limit), up_limit(up_limit),
write_coeff(write_coeff), write_offset(write_offset), read_coeff(read_coeff), read_offset(read_offset),
one( *this, sequnece == LowFirstHighSecond ? &data[1] : &data[0] ),
two( *this, sequnece == HighFirstLowSecond ? &data[1] : &data[0] ) {}
driver::modbus::IModBusDispatch & driver::modbus::ModbusAnalogWideValue::first() {
return one;
}
driver::modbus::IModBusDispatch & driver::modbus::ModbusAnalogWideValue::second() {
return two;
}