in IndustrialDeviceController/Software/HighLevelApp/drivers/modbus/modbus.c [549:651]
static err_code decode_point(modbus_device_t *modbus, modbus_point_t *mp, uint16_t *regs, double *value)
{
// parse data
switch (mp->data_type) {
case TYPE_BIT: {
if ((mp->reg_type == INPUT_REGISTER) || (mp->reg_type == HOLDING_REGISTER)) {
uint8_t bit_offset = mp->bit_offset;
*value = (regs[0] & (1 << bit_offset)) ? 1 : 0;
} else if ((mp->reg_type == COIL) || (mp->reg_type == DISCRETE_INPUT)) {
*value = regs[0] ? 1 : 0;
}
*value -= mp->value_offset;
break;
}
case TYPE_BYTE: {
uint8_t rv = (regs[0] >> mp->bit_offset) & 0xFF;
*value = (double)(rv - mp->value_offset);
break;
}
case TYPE_INT16: {
int16_t rv = regs[0];
*value = ((double)rv - mp->value_offset);
break;
}
case TYPE_UINT16: {
uint16_t rv = regs[0];
*value = ((double)rv - mp->value_offset);
break;
}
case TYPE_UINT32_BE: {
uint32_t rv = (regs[0] << 16) + regs[1];
*value = ((double)rv - mp->value_offset);
break;
}
case TYPE_UINT32_LE: {
uint32_t rv = (regs[1] << 16) + regs[0];
*value = ((double)rv - mp->value_offset);
break;
}
case TYPE_INT32_BE: {
int32_t rv = ((regs[0]) << 16) + regs[1];
*value = ((double)rv - mp->value_offset);
break;
}
case TYPE_INT32_LE: {
int32_t rv = ((regs[1]) << 16) + regs[0];
*value = ((double)rv - mp->value_offset);
break;
}
case TYPE_FLOAT_BE: {
uint32_t u32 = (regs[0] << 16) + regs[1];
float rv = *((float *)&u32);
*value = ((double)rv - mp->value_offset);
break;
}
case TYPE_FLOAT_LE: {
uint32_t u32 = (regs[1] << 16) + regs[0];
float rv = *((float *)&u32);
*value = ((double)rv - mp->value_offset);
break;
}
case TYPE_INT64_BE: {
int64_t rv = regs[0];
rv = (rv << 16) + regs[1];
rv = (rv << 16) + regs[2];
rv = (rv << 16) + regs[3];
*value = rv - mp->value_offset;
break;
}
case TYPE_INT64_LE: {
int64_t rv = regs[3];
rv = (rv << 16) + regs[2];
rv = (rv << 16) + regs[1];
rv = (rv << 16) + regs[0];
*value = rv - mp->value_offset;
break;
}
default:
return DEVICE_E_INVALID;
}
if (!is_double_equal(mp->scale, 1)) {
*value /= mp->scale;
// If value is -0, set to be 0
if (is_double_equal(*value, -0))
*value = 0;
}
return DEVICE_OK;
}