static err_code encode_point()

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;
}