X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Frdtech-dps%2Fprotocol.c;h=fe34b25700184fef2bb0428838a9c76e83eee235;hb=aff2094193c7ed0c040ff69d6e6de9c7f2b9d53e;hp=4df1a7012b80e9ca864311b5d171a36fca06aa89;hpb=69b05583955761d24c86cf1f46c1d1dba8c6176c;p=libsigrok.git diff --git a/src/hardware/rdtech-dps/protocol.c b/src/hardware/rdtech-dps/protocol.c index 4df1a701..fe34b257 100644 --- a/src/hardware/rdtech-dps/protocol.c +++ b/src/hardware/rdtech-dps/protocol.c @@ -2,6 +2,7 @@ * This file is part of the libsigrok project. * * Copyright (C) 2018 James Churchill + * Copyright (C) 2019 Frank Stettner * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,21 +21,55 @@ #include #include "protocol.h" -SR_PRIV int rdtech_dps_get_reg(struct sr_modbus_dev_inst *modbus, +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) { + struct dev_context *devc; + struct sr_modbus_dev_inst *modbus; uint16_t registers[1]; - int ret = sr_modbus_read_holding_registers(modbus, address, 1, registers); + int ret; + + devc = sdi->priv; + modbus = sdi->conn; + + g_mutex_lock(&devc->rw_mutex); + ret = rdtech_dps_read_holding_registers(modbus, address, 1, registers); + g_mutex_unlock(&devc->rw_mutex); *value = RB16(registers + 0); return ret; } -SR_PRIV int rdtech_dps_set_reg(struct sr_modbus_dev_inst *modbus, +SR_PRIV int rdtech_dps_set_reg(const struct sr_dev_inst *sdi, uint16_t address, uint16_t value) { + struct dev_context *devc; + struct sr_modbus_dev_inst *modbus; uint16_t registers[1]; + int ret; + + devc = sdi->priv; + modbus = sdi->conn; + WB16(registers, value); - return sr_modbus_write_multiple_registers(modbus, address, 1, registers); + g_mutex_lock(&devc->rw_mutex); + ret = sr_modbus_write_multiple_registers(modbus, address, 1, registers); + g_mutex_unlock(&devc->rw_mutex); + return ret; } SR_PRIV int rdtech_dps_get_model_version(struct sr_modbus_dev_inst *modbus, @@ -42,7 +77,12 @@ SR_PRIV int rdtech_dps_get_model_version(struct sr_modbus_dev_inst *modbus, { uint16_t registers[2]; int ret; - ret = sr_modbus_read_holding_registers(modbus, REG_MODEL, 2, registers); + + /* + * No mutex here, because there is no sr_dev_inst when this function + * is called. + */ + ret = rdtech_dps_read_holding_registers(modbus, REG_MODEL, 2, registers); if (ret == SR_OK) { *model = RB16(registers + 0); *version = RB16(registers + 1); @@ -52,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; @@ -65,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; @@ -74,20 +115,6 @@ static void send_value(const struct sr_dev_inst *sdi, struct sr_channel *ch, 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) { struct sr_dev_inst *sdi; @@ -95,6 +122,7 @@ SR_PRIV int rdtech_dps_receive_data(int fd, int revents, void *cb_data) struct sr_modbus_dev_inst *modbus; struct sr_datafeed_packet packet; uint16_t registers[3]; + int ret; (void)fd; (void)revents; @@ -105,20 +133,27 @@ SR_PRIV int rdtech_dps_receive_data(int fd, int revents, void *cb_data) modbus = sdi->conn; devc = sdi->priv; - devc->expecting_registers = 0; - if (sr_modbus_read_holding_registers(modbus, -1, 3, registers) == SR_OK) { + g_mutex_lock(&devc->rw_mutex); + /* + * 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, 3, registers); + g_mutex_unlock(&devc->rw_mutex); + + if (ret == 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); + SR_MQ_VOLTAGE, SR_MQFLAG_DC, SR_UNIT_VOLT, 3); send_value(sdi, sdi->channels->next->data, RB16(registers + 1) / 1000.0f, - SR_MQ_CURRENT, SR_UNIT_AMPERE, 4); + SR_MQ_CURRENT, SR_MQFLAG_DC, SR_UNIT_AMPERE, 4); 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, 3); packet.type = SR_DF_FRAME_END; sr_session_send(sdi, &packet); @@ -130,6 +165,5 @@ SR_PRIV int rdtech_dps_receive_data(int fd, int revents, void *cb_data) return TRUE; } - rdtech_dps_capture_start(sdi); return TRUE; }