X-Git-Url: https://sigrok.org/gitweb/?p=libsigrok.git;a=blobdiff_plain;f=src%2Fhardware%2Frdtech-dps%2Fprotocol.c;fp=src%2Fhardware%2Frdtech-dps%2Fprotocol.c;h=4df1a7012b80e9ca864311b5d171a36fca06aa89;hp=05b0e06b9a019330aa22af4455d26483dc2bac79;hb=69b05583955761d24c86cf1f46c1d1dba8c6176c;hpb=0549416e36730bb455068fd6a68b856d817fb087 diff --git a/src/hardware/rdtech-dps/protocol.c b/src/hardware/rdtech-dps/protocol.c index 05b0e06b..4df1a701 100644 --- a/src/hardware/rdtech-dps/protocol.c +++ b/src/hardware/rdtech-dps/protocol.c @@ -20,22 +20,116 @@ #include #include "protocol.h" +SR_PRIV int rdtech_dps_get_reg(struct sr_modbus_dev_inst *modbus, + uint16_t address, uint16_t *value) +{ + uint16_t registers[1]; + int ret = sr_modbus_read_holding_registers(modbus, address, 1, registers); + *value = RB16(registers + 0); + return ret; +} + +SR_PRIV int rdtech_dps_set_reg(struct sr_modbus_dev_inst *modbus, + uint16_t address, uint16_t value) +{ + uint16_t registers[1]; + WB16(registers, value); + return sr_modbus_write_multiple_registers(modbus, address, 1, registers); +} + +SR_PRIV int rdtech_dps_get_model_version(struct sr_modbus_dev_inst *modbus, + uint16_t *model, uint16_t *version) +{ + uint16_t registers[2]; + int ret; + ret = sr_modbus_read_holding_registers(modbus, REG_MODEL, 2, registers); + if (ret == SR_OK) { + *model = RB16(registers + 0); + *version = RB16(registers + 1); + sr_info("RDTech PSU model: %d version: %d", *model, *version); + } + return ret; +} + +static void send_value(const struct sr_dev_inst *sdi, struct sr_channel *ch, + float value, enum sr_mq mq, enum sr_unit unit, int digits) +{ + struct sr_datafeed_packet packet; + struct sr_datafeed_analog analog; + struct sr_analog_encoding encoding; + struct sr_analog_meaning meaning; + struct sr_analog_spec spec; + + sr_analog_init(&analog, &encoding, &meaning, &spec, digits); + analog.meaning->channels = g_slist_append(NULL, ch); + analog.num_samples = 1; + analog.data = &value; + analog.meaning->mq = mq; + analog.meaning->unit = unit; + analog.meaning->mqflags = SR_MQFLAG_DC; + + packet.type = SR_DF_ANALOG; + packet.payload = &analog; + sr_session_send(sdi, &packet); + g_slist_free(analog.meaning->channels); +} + +SR_PRIV int rdtech_dps_capture_start(const struct sr_dev_inst *sdi) +{ + struct dev_context *devc; + struct sr_modbus_dev_inst *modbus; + int ret; + + modbus = sdi->conn; + devc = sdi->priv; + + if ((ret = sr_modbus_read_holding_registers(modbus, REG_UOUT, 3, NULL)) == SR_OK) + devc->expecting_registers = 2; + return ret; +} + SR_PRIV int rdtech_dps_receive_data(int fd, int revents, void *cb_data) { - const struct sr_dev_inst *sdi; + struct sr_dev_inst *sdi; struct dev_context *devc; + struct sr_modbus_dev_inst *modbus; + struct sr_datafeed_packet packet; + uint16_t registers[3]; (void)fd; + (void)revents; if (!(sdi = cb_data)) return TRUE; - if (!(devc = sdi->priv)) - return TRUE; + modbus = sdi->conn; + devc = sdi->priv; + + devc->expecting_registers = 0; + if (sr_modbus_read_holding_registers(modbus, -1, 3, registers) == SR_OK) { + packet.type = SR_DF_FRAME_BEGIN; + sr_session_send(sdi, &packet); + + send_value(sdi, sdi->channels->data, + RB16(registers + 0) / 100.0f, + SR_MQ_VOLTAGE, SR_UNIT_VOLT, 3); + send_value(sdi, sdi->channels->next->data, + RB16(registers + 1) / 1000.0f, + SR_MQ_CURRENT, SR_UNIT_AMPERE, 4); + send_value(sdi, sdi->channels->next->next->data, + RB16(registers + 2) / 100.0f, + SR_MQ_POWER, SR_UNIT_WATT, 3); - if (revents == G_IO_IN) { - /* TODO */ + packet.type = SR_DF_FRAME_END; + sr_session_send(sdi, &packet); + sr_sw_limits_update_samples_read(&devc->limits, 1); + } + + if (sr_sw_limits_check(&devc->limits)) { + sr_dev_acquisition_stop(sdi); + return TRUE; } + rdtech_dps_capture_start(sdi); return TRUE; }