X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Frdtech-dps%2Fprotocol.c;h=65f40ab9297ad681117a06d9f99f2c489bf7c750;hb=78b07caf11588ffeffee672e4925640d1f178a99;hp=f01e5742542ea336033d3b789b48f3f762400f9a;hpb=7c0891b0b82049b4cc3c0dd70b8483d037dab36f;p=libsigrok.git diff --git a/src/hardware/rdtech-dps/protocol.c b/src/hardware/rdtech-dps/protocol.c index f01e5742..65f40ab9 100644 --- a/src/hardware/rdtech-dps/protocol.c +++ b/src/hardware/rdtech-dps/protocol.c @@ -21,6 +21,21 @@ #include #include "protocol.h" +SR_PRIV int rdtech_dps_read_holding_registers(struct sr_modbus_dev_inst *modbus, + int address, int nb_registers, uint16_t *registers) +{ + int i, ret; + + i = 0; + do { + ret = sr_modbus_read_holding_registers(modbus, + address, nb_registers, registers); + ++i; + } while (ret != SR_OK && i < 3); + + return ret; +} + SR_PRIV int rdtech_dps_get_reg(const struct sr_dev_inst *sdi, uint16_t address, uint16_t *value) { @@ -33,7 +48,7 @@ SR_PRIV int rdtech_dps_get_reg(const struct sr_dev_inst *sdi, modbus = sdi->conn; g_mutex_lock(&devc->rw_mutex); - ret = sr_modbus_read_holding_registers(modbus, address, 1, registers); + ret = rdtech_dps_read_holding_registers(modbus, address, 1, registers); g_mutex_unlock(&devc->rw_mutex); *value = RB16(registers + 0); return ret; @@ -67,7 +82,7 @@ SR_PRIV int rdtech_dps_get_model_version(struct sr_modbus_dev_inst *modbus, * No mutex here, because there is no sr_dev_inst when this function * is called. */ - ret = sr_modbus_read_holding_registers(modbus, REG_MODEL, 2, registers); + ret = rdtech_dps_read_holding_registers(modbus, REG_MODEL, 2, registers); if (ret == SR_OK) { *model = RB16(registers + 0); *version = RB16(registers + 1); @@ -77,7 +92,8 @@ SR_PRIV int rdtech_dps_get_model_version(struct sr_modbus_dev_inst *modbus, } 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) + float value, enum sr_mq mq, enum sr_mqflag mqflags, + enum sr_unit unit, int digits) { struct sr_datafeed_packet packet; struct sr_datafeed_analog analog; @@ -90,8 +106,8 @@ static void send_value(const struct sr_dev_inst *sdi, struct sr_channel *ch, analog.num_samples = 1; analog.data = &value; analog.meaning->mq = mq; + analog.meaning->mqflags = mqflags; analog.meaning->unit = unit; - analog.meaning->mqflags = SR_MQFLAG_DC; packet.type = SR_DF_ANALOG; packet.payload = &analog; @@ -104,8 +120,7 @@ SR_PRIV int rdtech_dps_receive_data(int fd, int revents, void *cb_data) struct sr_dev_inst *sdi; struct dev_context *devc; struct sr_modbus_dev_inst *modbus; - struct sr_datafeed_packet packet; - uint16_t registers[3]; + uint16_t registers[8]; int ret; (void)fd; @@ -118,25 +133,54 @@ SR_PRIV int rdtech_dps_receive_data(int fd, int revents, void *cb_data) devc = sdi->priv; g_mutex_lock(&devc->rw_mutex); - ret = sr_modbus_read_holding_registers(modbus, REG_UOUT, 3, registers); + /* + * Using the libsigrok function here, because it doesn't matter if the + * reading fails. It will be done again in the next acquision cycle anyways. + */ + ret = sr_modbus_read_holding_registers(modbus, REG_UOUT, 8, registers); g_mutex_unlock(&devc->rw_mutex); if (ret == SR_OK) { - packet.type = SR_DF_FRAME_BEGIN; - sr_session_send(sdi, &packet); + /* Send channel values */ + std_session_send_df_frame_begin(sdi); send_value(sdi, sdi->channels->data, - RB16(registers + 0) / 100.0f, - SR_MQ_VOLTAGE, SR_UNIT_VOLT, 3); + RB16(registers + 0) / devc->voltage_multiplier, + SR_MQ_VOLTAGE, SR_MQFLAG_DC, SR_UNIT_VOLT, + devc->model->voltage_digits); send_value(sdi, sdi->channels->next->data, - RB16(registers + 1) / 1000.0f, - SR_MQ_CURRENT, SR_UNIT_AMPERE, 4); + RB16(registers + 1) / devc->current_multiplier, + SR_MQ_CURRENT, SR_MQFLAG_DC, SR_UNIT_AMPERE, + devc->model->current_digits); send_value(sdi, sdi->channels->next->next->data, RB16(registers + 2) / 100.0f, - SR_MQ_POWER, SR_UNIT_WATT, 3); + SR_MQ_POWER, 0, SR_UNIT_WATT, 2); + + std_session_send_df_frame_end(sdi); + + /* Check for state changes */ + if (devc->actual_ovp_state != (RB16(registers + 5) == STATE_OVP)) { + devc->actual_ovp_state = RB16(registers + 5) == STATE_OVP; + sr_session_send_meta(sdi, SR_CONF_OVER_VOLTAGE_PROTECTION_ACTIVE, + g_variant_new_boolean(devc->actual_ovp_state)); + } + if (devc->actual_ocp_state != (RB16(registers + 5) == STATE_OCP)) { + devc->actual_ocp_state = RB16(registers + 5) == STATE_OCP; + sr_session_send_meta(sdi, SR_CONF_OVER_CURRENT_PROTECTION_ACTIVE, + g_variant_new_boolean(devc->actual_ocp_state)); + } + if (devc->actual_regulation_state != RB16(registers + 6)) { + devc->actual_regulation_state = RB16(registers + 6); + sr_session_send_meta(sdi, SR_CONF_REGULATION, + g_variant_new_string( + devc->actual_regulation_state == MODE_CC ? "CC" : "CV")); + } + if (devc->actual_output_state != RB16(registers + 7)) { + devc->actual_output_state = RB16(registers + 7); + sr_session_send_meta(sdi, SR_CONF_ENABLED, + g_variant_new_boolean(devc->actual_output_state)); + } - packet.type = SR_DF_FRAME_END; - sr_session_send(sdi, &packet); sr_sw_limits_update_samples_read(&devc->limits, 1); }