X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Fmaynuo-m97%2Fprotocol.c;h=7782d48f794b280c1c9bfc0957bb8089b2c521ee;hb=b02bb45f4cf6378520e5a5b82ff39013cfa270b6;hp=e6bc0294f393a5b927d28feb2a2a61b66a98d9f5;hpb=e1ccfb191062d13b98bb7536d162a044e0758678;p=libsigrok.git
diff --git a/src/hardware/maynuo-m97/protocol.c b/src/hardware/maynuo-m97/protocol.c
index e6bc0294..7782d48f 100644
--- a/src/hardware/maynuo-m97/protocol.c
+++ b/src/hardware/maynuo-m97/protocol.c
@@ -17,24 +17,185 @@
* along with this program. If not, see .
*/
+#include
#include "protocol.h"
+SR_PRIV int maynuo_m97_get_bit(struct sr_modbus_dev_inst *modbus,
+ enum maynuo_m97_coil address, int *value)
+{
+ uint8_t coil;
+ int ret = sr_modbus_read_coils(modbus, address, 1, &coil);
+ *value = coil & 1;
+ return ret;
+}
+
+SR_PRIV int maynuo_m97_set_bit(struct sr_modbus_dev_inst *modbus,
+ enum maynuo_m97_coil address, int value)
+{
+ return sr_modbus_write_coil(modbus, address, value);
+}
+
+SR_PRIV int maynuo_m97_get_float(struct sr_modbus_dev_inst *modbus,
+ enum maynuo_m97_register address, float *value)
+{
+ uint16_t registers[2];
+ int ret = sr_modbus_read_holding_registers(modbus, address, 2, registers);
+ if (ret == SR_OK)
+ *value = RBFL(registers);
+ return ret;
+}
+
+SR_PRIV int maynuo_m97_set_float(struct sr_modbus_dev_inst *modbus,
+ enum maynuo_m97_register address, float value)
+{
+ uint16_t registers[2];
+ WBFL(registers, value);
+ return sr_modbus_write_multiple_registers(modbus, address, 2, registers);
+}
+
+
+static int maynuo_m97_cmd(struct sr_modbus_dev_inst *modbus,
+ enum maynuo_m97_mode cmd)
+{
+ uint16_t registers[1];
+ WB16(registers, cmd);
+ return sr_modbus_write_multiple_registers(modbus, CMD, 1, registers);
+}
+
+SR_PRIV int maynuo_m97_get_mode(struct sr_modbus_dev_inst *modbus,
+ enum maynuo_m97_mode *mode)
+{
+ uint16_t registers[1];
+ int ret;
+ ret = sr_modbus_read_holding_registers(modbus, SETMODE, 1, registers);
+ *mode = RB16(registers) & 0xFF;
+ return ret;
+}
+
+SR_PRIV int maynuo_m97_set_mode(struct sr_modbus_dev_inst *modbus,
+ enum maynuo_m97_mode mode)
+{
+ return maynuo_m97_cmd(modbus, mode);
+}
+
+SR_PRIV int maynuo_m97_set_input(struct sr_modbus_dev_inst *modbus, int enable)
+{
+ enum maynuo_m97_mode mode;
+ int ret;
+ if ((ret = maynuo_m97_get_mode(modbus, &mode)) != SR_OK)
+ return ret;
+ if ((ret = maynuo_m97_cmd(modbus, enable ? INPUT_ON : INPUT_OFF)) != SR_OK)
+ return ret;
+ return maynuo_m97_set_mode(modbus, mode);
+}
+
+SR_PRIV int maynuo_m97_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, MODEL, 2, registers);
+ *model = RB16(registers+0);
+ *version = RB16(registers+1);
+ return ret;
+}
+
+
+SR_PRIV const char *maynuo_m97_mode_to_str(enum maynuo_m97_mode mode)
+{
+ switch (mode) {
+ case CC: return "CC";
+ case CV: return "CV";
+ case CW: return "CP";
+ case CR: return "CR";
+ case CC_SOFT_START: return "CC Soft Start";
+ case DYNAMIC: return "Dynamic";
+ case SHORT_CIRCUIT: return "Short Circuit";
+ case LIST: return "List Mode";
+ case CC_L_AND_UL: return "CC Loading and Unloading";
+ case CV_L_AND_UL: return "CV Loading and Unloading";
+ case CW_L_AND_UL: return "CP Loading and Unloading";
+ case CR_L_AND_UL: return "CR Loading and Unloading";
+ case CC_TO_CV: return "CC + CV";
+ case CR_TO_CV: return "CR + CV";
+ case BATTERY_TEST: return "Battery Test";
+ case CV_SOFT_START: return "CV Soft Start";
+ default: return "UNKNOWN";
+ }
+}
+
+
+static void maynuo_m97_session_send_value(const struct sr_dev_inst *sdi, struct sr_channel *ch, float value, enum sr_mq mq, enum sr_unit unit)
+{
+ struct sr_datafeed_packet packet;
+ struct sr_datafeed_analog_old analog;
+
+ analog.channels = g_slist_append(NULL, ch);
+ analog.num_samples = 1;
+ analog.data = &value;
+ analog.mq = mq;
+ analog.unit = unit;
+ analog.mqflags = SR_MQFLAG_DC;
+
+ packet.type = SR_DF_ANALOG_OLD;
+ packet.payload = &analog;
+ sr_session_send(sdi, &packet);
+ g_slist_free(analog.channels);
+}
+
+SR_PRIV int maynuo_m97_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, U, 4, NULL)) == SR_OK)
+ devc->expecting_registers = 4;
+ return ret;
+}
+
SR_PRIV int maynuo_m97_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[4];
(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, 4, registers) == SR_OK) {
+ packet.type = SR_DF_FRAME_BEGIN;
+ sr_session_send(sdi, &packet);
+
+ maynuo_m97_session_send_value(sdi, sdi->channels->data,
+ RBFL(registers + 0),
+ SR_MQ_VOLTAGE, SR_UNIT_VOLT);
+ maynuo_m97_session_send_value(sdi, sdi->channels->next->data,
+ RBFL(registers + 2),
+ SR_MQ_CURRENT, SR_UNIT_AMPERE);
- 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)) {
+ sdi->driver->dev_acquisition_stop(sdi);
+ return TRUE;
}
+ maynuo_m97_capture_start(sdi);
return TRUE;
}