in IndustrialDeviceController/Software/HighLevelApp/drivers/modbus/modbus.c [438:539]
static err_code encode_point(modbus_device_t *modbus, modbus_point_t *mp, const char *str_value, uint16_t *reg)
{
switch (mp->data_type) {
case TYPE_BIT: {
// default to 0
uint8_t value = strtol(str_value, NULL, 10);
if (mp->reg_type == COIL) {
reg[0] = value ? 1 : 0;
} else if (mp->reg_type == HOLDING_REGISTER) {
int bit_offset = mp->bit_offset;
if (value) {
reg[0] |= 1 << bit_offset;
}
else {
reg[0] &= ~(1 << bit_offset);
}
}
break;
}
case TYPE_BYTE: {
uint8_t value = strtod(str_value, NULL) * mp->scale + mp->value_offset;
if (mp->reg_type == HOLDING_REGISTER) {
for (int i = mp->bit_offset; i < mp->bit_offset + 8; i++) {
if (value & (1 << (i - mp->bit_offset))) {
reg[0] |= 1 << i;
}
else {
reg[0] &= ~(1 << i);
}
}
}
break;
}
case TYPE_INT16:
case TYPE_UINT16: {
reg[0] = strtod(str_value, NULL) * mp->scale + mp->value_offset;
break;
}
case TYPE_INT32_BE:
case TYPE_UINT32_BE: {
uint32_t value = strtod(str_value, NULL) * mp->scale + mp->value_offset;
reg[0] = (value >> 16);
reg[1] = value & 0xFFFF;
break;
}
case TYPE_INT32_LE:
case TYPE_UINT32_LE: {
uint32_t value = strtod(str_value, NULL) * mp->scale + mp->value_offset;
reg[1] = (value >> 16);
reg[0] = value & 0xFFFF;
break;
}
case TYPE_FLOAT_BE: {
float value_f = strtof(str_value, NULL) * mp->scale + mp->value_offset;
uint32_t value_u32 = *((uint32_t *)&value_f);
reg[0] = (value_u32 >> 16);
reg[1] = value_u32 & 0xFFFF;
break;
}
case TYPE_FLOAT_LE: {
float value_f = strtof(str_value, NULL) * mp->scale + mp->value_offset;
uint32_t value_u32 = *((uint32_t *)&value_f);
reg[1] = (value_u32 >> 16);
reg[0] = value_u32 & 0xFFFF;
break;
}
case TYPE_INT64_BE: {
int64_t rv = 0;
if (mp->scale != 1) {
rv = strtod(str_value, NULL) * mp->scale + mp->value_offset;
}
else {
rv = strtoll(str_value, NULL, 10) + mp->value_offset;
}
reg[0] = (rv >> 48) & 0xFFFF;
reg[1] = (rv >> 32) & 0xFFFF;
reg[2] = (rv >> 16) & 0xFFFF;
reg[3] = rv & 0xFFFF;
break;
}
case TYPE_INT64_LE: {
int64_t rv = 0;
if (mp->scale != 1) {
rv = strtod(str_value, NULL) * mp->scale + mp->value_offset;
}
else {
rv = strtoll(str_value, NULL, 10) + mp->value_offset;
}
reg[3] = (rv >> 48) & 0xFFFF;
reg[2] = (rv >> 32) & 0xFFFF;
reg[1] = (rv >> 16) & 0xFFFF;
reg[0] = rv & 0xFFFF;
break;
}
default:
return DEVICE_E_PROTOCOL;
}
return DEVICE_OK;
}