]> sigrok.org Git - libsigrok.git/commitdiff
arachnid-labs-re-load-pro: Add initial driver.
authorUwe Hermann <redacted>
Wed, 30 Dec 2015 17:44:40 +0000 (18:44 +0100)
committerUwe Hermann <redacted>
Mon, 8 Feb 2016 14:02:29 +0000 (15:02 +0100)
src/hardware/arachnid-labs-re-load-pro/api.c
src/hardware/arachnid-labs-re-load-pro/protocol.c
src/hardware/arachnid-labs-re-load-pro/protocol.h

index 99241c19b487c81b058f8d79d76e15773da8e123..bf6917e78ae240ccd646f075e2505ebebbd14410 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the libsigrok project.
  *
- * Copyright (C) 2015 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2015-2016 Uwe Hermann <uwe@hermann-uwe.de>
  *
  * 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
  */
 
 #include <config.h>
+#include <string.h>
 #include "protocol.h"
 
+#define SERIALCOMM "115200/8n1"
+
+#define CMD_VERSION "version\r\n"
+#define CMD_MONITOR "monitor 200\r\n"
+
+static const uint32_t scanopts[] = {
+       SR_CONF_CONN,
+       SR_CONF_SERIALCOMM,
+};
+
+static const uint32_t drvopts[] = {
+       SR_CONF_ELECTRONIC_LOAD,
+};
+
+static const uint32_t devopts[] = {
+       SR_CONF_CONTINUOUS | SR_CONF_SET,
+       SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET,
+       SR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET,
+};
+
+static const uint32_t devopts_cg[] = {
+       SR_CONF_ENABLED | SR_CONF_GET,
+       SR_CONF_REGULATION | SR_CONF_GET,
+       SR_CONF_VOLTAGE | SR_CONF_GET,
+       SR_CONF_CURRENT | SR_CONF_GET,
+       SR_CONF_CURRENT_LIMIT | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
+       SR_CONF_OVER_VOLTAGE_PROTECTION_ENABLED | SR_CONF_GET,
+       SR_CONF_OVER_CURRENT_PROTECTION_ENABLED | SR_CONF_GET,
+       SR_CONF_OVER_TEMPERATURE_PROTECTION | SR_CONF_GET,
+       SR_CONF_OVER_TEMPERATURE_PROTECTION_ACTIVE | SR_CONF_GET,
+};
+
 SR_PRIV struct sr_dev_driver arachnid_labs_re_load_pro_driver_info;
 
 static int init(struct sr_dev_driver *di, struct sr_context *sr_ctx)
@@ -30,15 +63,94 @@ static int init(struct sr_dev_driver *di, struct sr_context *sr_ctx)
 
 static GSList *scan(struct sr_dev_driver *di, GSList *options)
 {
+       struct sr_dev_inst *sdi;
        struct drv_context *drvc;
-       GSList *devices;
-
-       (void)options;
+       struct dev_context *devc;
+       struct sr_config *src;
+       struct sr_serial_dev_inst *serial;
+       struct sr_channel_group *cg;
+       struct sr_channel *ch;
+       GSList *l, *devices;
+       int ret, len;
+       const char *conn, *serialcomm;
+       char buf[100];
+       char *bufptr;
 
        devices = NULL;
        drvc = di->context;
        drvc->instances = NULL;
 
+       conn = serialcomm = NULL;
+       for (l = options; l; l = l->next) {
+               src = l->data;
+               switch (src->key) {
+               case SR_CONF_CONN:
+                       conn = g_variant_get_string(src->data, NULL);
+                       break;
+               case SR_CONF_SERIALCOMM:
+                       serialcomm = g_variant_get_string(src->data, NULL);
+                       break;
+               }
+       }
+       if (!conn)
+               return NULL;
+       if (!serialcomm)
+               serialcomm = SERIALCOMM;
+
+       serial = sr_serial_dev_inst_new(conn, serialcomm);
+
+       if (serial_open(serial, SERIAL_RDWR) != SR_OK)
+               return NULL;
+
+       serial_flush(serial);
+
+       if (serial_write_blocking(serial, CMD_VERSION,
+                       strlen(CMD_VERSION), serial_timeout(serial,
+                       strlen(CMD_VERSION))) < (int)strlen(CMD_VERSION)) {
+               sr_dbg("Unable to write while probing for hardware.");
+               serial_close(serial);
+               return NULL;
+       }
+
+       memset(buf, 0, sizeof(buf));
+       bufptr = buf;
+       len = sizeof(buf);
+       ret = serial_readline(serial, &bufptr, &len, 3000);
+
+       if (ret < 0 || len < 9 || strncmp((const char *)&buf, "version ", 8)) {
+               sr_dbg("Unable to probe version number.");
+               serial_close(serial);
+               return NULL;
+       }
+
+       sdi = g_malloc0(sizeof(struct sr_dev_inst));
+       sdi->status = SR_ST_ACTIVE;
+       sdi->vendor = g_strdup("Arachnid Labs");
+       sdi->model = g_strdup("Re:load Pro");
+       sdi->version = g_strdup(buf + 8);
+       sdi->driver = &arachnid_labs_re_load_pro_driver_info;
+       sdi->inst_type = SR_INST_SERIAL;
+       sdi->conn = serial;
+
+       cg = g_malloc0(sizeof(struct sr_channel_group));
+       cg->name = g_strdup("1");
+       sdi->channel_groups = g_slist_append(sdi->channel_groups, cg);
+
+       ch = sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "V");
+       cg->channels = g_slist_append(cg->channels, ch);
+
+       ch = sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "I");
+       cg->channels = g_slist_append(cg->channels, ch);
+
+       devc = g_malloc0(sizeof(struct dev_context));
+       sdi->priv = devc;
+       drvc->instances = g_slist_append(drvc->instances, sdi);
+       devices = g_slist_append(devices, sdi);
+
+       serial_close(serial);
+       if (!devices)
+               sr_serial_dev_inst_free(serial);
+
        return devices;
 }
 
@@ -52,40 +164,126 @@ static int dev_clear(const struct sr_dev_driver *di)
        return std_dev_clear(di, NULL);
 }
 
-static int dev_open(struct sr_dev_inst *sdi)
+static int cleanup(const struct sr_dev_driver *di)
 {
-       (void)sdi;
-
-       sdi->status = SR_ST_ACTIVE;
-
-       return SR_OK;
+       return dev_clear(di);
 }
 
-static int dev_close(struct sr_dev_inst *sdi)
+static int config_list(uint32_t key, GVariant **data,
+       const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
 {
-       (void)sdi;
+       GVariantBuilder gvb;
+       int ret;
 
-       sdi->status = SR_ST_INACTIVE;
+       /* Always available. */
+       if (key == SR_CONF_SCAN_OPTIONS) {
+               *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
+                       scanopts, ARRAY_SIZE(scanopts), sizeof(uint32_t));
+               return SR_OK;
+       }
 
-       return SR_OK;
-}
+       if (key == SR_CONF_DEVICE_OPTIONS && !sdi) {
+               *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
+                       drvopts, ARRAY_SIZE(drvopts), sizeof(uint32_t));
+               return SR_OK;
+       }
 
-static int cleanup(const struct sr_dev_driver *di)
-{
-       return dev_clear(di);
+       if (!sdi)
+               return SR_ERR_ARG;
+
+       ret = SR_OK;
+
+       if (!cg) {
+               /* No channel group: global options. */
+               switch (key) {
+               case SR_CONF_DEVICE_OPTIONS:
+                       *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
+                               devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
+                       break;
+               default:
+                       return SR_ERR_NA;
+               }
+       } else {
+               switch (key) {
+               case SR_CONF_DEVICE_OPTIONS:
+                       *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
+                               devopts_cg, ARRAY_SIZE(devopts_cg), sizeof(uint32_t));
+                       break;
+               case SR_CONF_CURRENT_LIMIT:
+                       g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
+                       /* Min, max, step. */
+                       g_variant_builder_add_value(&gvb, g_variant_new_double(0.0));
+                       g_variant_builder_add_value(&gvb, g_variant_new_double(6.0));
+                       g_variant_builder_add_value(&gvb, g_variant_new_double(0.001)); /* 1mA steps */
+                       *data = g_variant_builder_end(&gvb);
+                       break;
+               default:
+                       return SR_ERR_NA;
+               }
+       }
+
+       return ret;
 }
 
 static int config_get(uint32_t key, GVariant **data,
        const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
 {
+       struct dev_context *devc;
        int ret;
+       float fvalue;
 
-       (void)sdi;
-       (void)data;
        (void)cg;
 
+       devc = sdi->priv;
+
+       /*
+        * These features/keys are not supported by the hardware:
+        *  - SR_CONF_OVER_VOLTAGE_PROTECTION_ACTIVE
+        *  - SR_CONF_OVER_VOLTAGE_PROTECTION_THRESHOLD
+        *  - SR_CONF_OVER_CURRENT_PROTECTION_ACTIVE
+        *  - SR_CONF_OVER_CURRENT_PROTECTION_THRESHOLD
+        */
+
        ret = SR_OK;
        switch (key) {
+       case SR_CONF_LIMIT_SAMPLES:
+               *data = g_variant_new_uint64(devc->limit_samples);
+               break;
+       case SR_CONF_LIMIT_MSEC:
+               *data = g_variant_new_uint64(devc->limit_msec);
+               break;
+       case SR_CONF_ENABLED:
+               *data = g_variant_new_boolean(TRUE); /* Always on. */
+               break;
+       case SR_CONF_REGULATION:
+               *data = g_variant_new_string("CC"); /* Always CC mode. */
+               break;
+       case SR_CONF_VOLTAGE:
+               if (reloadpro_get_voltage_current(sdi, &fvalue, NULL) < 0)
+                       return SR_ERR;
+               *data = g_variant_new_double(fvalue);
+               break;
+       case SR_CONF_CURRENT:
+               if (reloadpro_get_voltage_current(sdi, NULL, &fvalue) < 0)
+                       return SR_ERR;
+               *data = g_variant_new_double(fvalue);
+               break;
+       case SR_CONF_CURRENT_LIMIT:
+               if (reloadpro_get_current_limit(sdi, &fvalue) == SR_OK)
+                       *data = g_variant_new_double(fvalue);
+               break;
+       case SR_CONF_OVER_VOLTAGE_PROTECTION_ENABLED:
+               *data = g_variant_new_boolean(TRUE); /* Always on. */
+               break;
+       case SR_CONF_OVER_CURRENT_PROTECTION_ENABLED:
+               *data = g_variant_new_boolean(TRUE); /* Always on. */
+               break;
+       case SR_CONF_OVER_TEMPERATURE_PROTECTION:
+               *data = g_variant_new_boolean(TRUE); /* Always on. */
+               break;
+       case SR_CONF_OVER_TEMPERATURE_PROTECTION_ACTIVE:
+               *data = g_variant_new_boolean(devc->otp_active);
+               break;
        default:
                return SR_ERR_NA;
        }
@@ -96,16 +294,28 @@ static int config_get(uint32_t key, GVariant **data,
 static int config_set(uint32_t key, GVariant *data,
        const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
 {
+       struct dev_context *devc;
        int ret;
 
-       (void)data;
        (void)cg;
 
        if (sdi->status != SR_ST_ACTIVE)
                return SR_ERR_DEV_CLOSED;
 
+       devc = sdi->priv;
+
        ret = SR_OK;
        switch (key) {
+       case SR_CONF_LIMIT_SAMPLES:
+               devc->limit_samples = g_variant_get_uint64(data);
+               break;
+       case SR_CONF_LIMIT_MSEC:
+               devc->limit_msec = g_variant_get_uint64(data);
+               break;
+       case SR_CONF_CURRENT_LIMIT:
+               ret = reloadpro_set_current_limit(sdi,
+                       g_variant_get_double(data));
+               break;
        default:
                ret = SR_ERR_NA;
        }
@@ -113,43 +323,47 @@ static int config_set(uint32_t key, GVariant *data,
        return ret;
 }
 
-static int config_list(uint32_t key, GVariant **data,
-       const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
+static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
 {
        int ret;
+       struct dev_context *devc;
+       struct sr_serial_dev_inst *serial;
 
-       (void)sdi;
-       (void)data;
-       (void)cg;
+       (void)cb_data;
 
-       ret = SR_OK;
-       switch (key) {
-       default:
-               return SR_ERR_NA;
+       if (sdi->status != SR_ST_ACTIVE)
+               return SR_ERR_DEV_CLOSED;
+
+       devc = sdi->priv;
+
+       serial = sdi->conn;
+
+       /* Send the 'monitor <ms>' command (doesn't have a reply). */
+       if ((ret = serial_write_blocking(serial, CMD_MONITOR,
+                       strlen(CMD_MONITOR), serial_timeout(serial,
+                       strlen(CMD_MONITOR)))) < (int)strlen(CMD_MONITOR)) {
+               sr_err("Unable to send 'monitor' command: %d.", ret);
+               return SR_ERR;
        }
 
-       return ret;
-}
+       /* Poll every 100ms, or whenever some data comes in. */
+       serial_source_add(sdi->session, serial, G_IO_IN, 100,
+                         reloadpro_receive_data, (void *)sdi);
 
-static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
-{
-       (void)sdi;
-       (void)cb_data;
+       std_session_send_df_header(cb_data, LOG_PREFIX);
 
-       if (sdi->status != SR_ST_ACTIVE)
-               return SR_ERR_DEV_CLOSED;
+       memset(devc->buf, 0, RELOADPRO_BUFSIZE);
+       devc->buflen = 0;
+       devc->num_samples = 0;
+       devc->starttime = g_get_monotonic_time();
 
        return SR_OK;
 }
 
 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
 {
-       (void)cb_data;
-
-       if (sdi->status != SR_ST_ACTIVE)
-               return SR_ERR_DEV_CLOSED;
-
-       return SR_OK;
+       return std_serial_dev_acquisition_stop(sdi, cb_data,
+               std_serial_dev_close, sdi->conn, LOG_PREFIX);
 }
 
 SR_PRIV struct sr_dev_driver arachnid_labs_re_load_pro_driver_info = {
@@ -164,8 +378,8 @@ SR_PRIV struct sr_dev_driver arachnid_labs_re_load_pro_driver_info = {
        .config_get = config_get,
        .config_set = config_set,
        .config_list = config_list,
-       .dev_open = dev_open,
-       .dev_close = dev_close,
+       .dev_open = std_serial_dev_open,
+       .dev_close = std_serial_dev_close,
        .dev_acquisition_start = dev_acquisition_start,
        .dev_acquisition_stop = dev_acquisition_stop,
        .context = NULL,
index b8f498b82f5ee54c5a7f8cef2eb1f214c309c0a8..8bc8935246e7b1f69959c68828f2ca3749382c01 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the libsigrok project.
  *
- * Copyright (C) 2015 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2015-2016 Uwe Hermann <uwe@hermann-uwe.de>
  *
  * 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
  */
 
 #include <config.h>
+#include <string.h>
 #include "protocol.h"
 
-SR_PRIV int arachnid_labs_re_load_pro_receive_data(int fd, int revents, void *cb_data)
+#define READ_TIMEOUT_MS 1000
+
+static int send_cmd(const struct sr_dev_inst *sdi, const char *cmd,
+               char *replybuf, int replybufsize)
+{
+       char *bufptr;
+       int len, ret;
+       struct sr_serial_dev_inst *serial;
+
+       serial = sdi->conn;
+
+       /* Send the command (blocking, with timeout). */
+       if ((ret = serial_write_blocking(serial, cmd,
+                       strlen(cmd), serial_timeout(serial,
+                       strlen(cmd)))) < (int)strlen(cmd)) {
+               sr_err("Unable to send command.");
+               return SR_ERR;
+       }
+
+       /* Read the reply (blocking, with timeout). */
+       memset(replybuf, 0, replybufsize);
+       bufptr = replybuf;
+       len = replybufsize;
+       ret = serial_readline(serial, &bufptr, &len, READ_TIMEOUT_MS);
+
+       /* If we got 0 characters (possibly one \r or \n), retry once. */
+       if (len == 0) {
+               len = replybufsize;
+               ret = serial_readline(serial, &bufptr, &len, READ_TIMEOUT_MS);
+       }
+
+       if (g_str_has_prefix((const char *)&bufptr, "err ")) {
+               sr_err("Device replied with an error: '%s'.", bufptr);
+               return SR_ERR;
+       }
+
+       return ret;
+}
+
+SR_PRIV int reloadpro_set_current_limit(const struct sr_dev_inst *sdi,
+                                       float current)
+{
+       int ret, ma;
+       char buf[100];
+       char *cmd;
+
+       if (current < 0 || current > 6) {
+               sr_err("The current limit must be 0-6 A (was %f A).", current);
+               return SR_ERR_ARG;
+       }
+
+       /* Hardware expects current in mA, integer (0..6000). */
+       ma = (int)(current * 1000);
+
+       sr_err("Setting current limit to %f A (%d mA).", current, ma);
+
+       cmd = g_strdup_printf("set %d\n", ma);
+       if ((ret = send_cmd(sdi, cmd, (char *)&buf, sizeof(buf))) < 0) {
+               sr_err("Error sending current limit command: %d.", ret);
+               g_free(cmd);
+               return SR_ERR;
+       }
+       g_free(cmd);
+
+       return SR_OK;
+}
+
+SR_PRIV int reloadpro_get_current_limit(const struct sr_dev_inst *sdi,
+                                       float *current)
+{
+       int ret;
+       char buf[100];
+
+       if ((ret = send_cmd(sdi, "set\n", (char *)&buf, sizeof(buf))) < 0) {
+               sr_err("Error sending current limit query: %d.", ret);
+               return SR_ERR;
+       }
+
+       /* Hardware sends current in mA, integer (0..6000). */
+       *current = g_ascii_strtod(buf + 4, NULL) / 1000;
+
+       return SR_OK;
+}
+
+SR_PRIV int reloadpro_get_voltage_current(const struct sr_dev_inst *sdi,
+               float *voltage, float *current)
+{
+       int ret;
+       char buf[100];
+       char **tokens;
+
+       if ((ret = send_cmd(sdi, "read\n", (char *)&buf, sizeof(buf))) < 0) {
+               sr_err("Error sending voltage/current query: %d.", ret);
+               return SR_ERR;
+       }
+
+       /* Reply: "read <current> <voltage>". */
+       tokens = g_strsplit((const char *)&buf, " ", 3);
+       if (voltage)
+               *voltage = g_ascii_strtod(tokens[2], NULL) / 1000;
+       if (current)
+               *current = g_ascii_strtod(tokens[1], NULL) / 1000;
+       g_strfreev(tokens);
+
+       return SR_OK;
+}
+
+static void handle_packet(const struct sr_dev_inst *sdi)
 {
-       const struct sr_dev_inst *sdi;
+       float voltage, current;
+       struct sr_datafeed_packet packet;
+       struct sr_datafeed_analog_old analog;
        struct dev_context *devc;
+       char **tokens;
+       GSList *l;
+
+       devc = sdi->priv;
+
+       if (g_str_has_prefix((const char *)devc->buf, "overtemp")) {
+               sr_dbg("Overtemperature condition!");
+               devc->otp_active = TRUE;
+               return;
+       }
+
+       if (!g_str_has_prefix((const char *)devc->buf, "read ")) {
+               sr_dbg("Unknown packet: '%s'.", devc->buf);
+               return;
+       }
+
+       tokens = g_strsplit((const char *)devc->buf, " ", 3);
+       voltage = g_ascii_strtod(tokens[2], NULL) / 1000;
+       current = g_ascii_strtod(tokens[1], NULL) / 1000;
+       g_strfreev(tokens);
+
+       memset(&analog, 0, sizeof(struct sr_datafeed_analog_old));
+
+       /* Begin frame. */
+       packet.type = SR_DF_FRAME_BEGIN;
+       sr_session_send(sdi, &packet);
+
+       packet.type = SR_DF_ANALOG_OLD;
+       packet.payload = &analog;
+       analog.num_samples = 1;
+
+       /* Voltage */
+       l = g_slist_copy(sdi->channels);
+       l = g_slist_remove_link(l, g_slist_nth(l, 1));
+       analog.channels = l;
+       analog.mq = SR_MQ_VOLTAGE;
+       analog.mqflags = SR_MQFLAG_DC;
+       analog.unit = SR_UNIT_VOLT;
+       analog.data = &voltage;
+       sr_session_send(sdi, &packet);
+       g_slist_free(l);
+
+       /* Current */
+       l = g_slist_copy(sdi->channels);
+       l = g_slist_remove_link(l, g_slist_nth(l, 0));
+       analog.channels = l;
+       analog.mq = SR_MQ_CURRENT;
+       analog.mqflags = SR_MQFLAG_DC;
+       analog.unit = SR_UNIT_AMPERE;
+       analog.data = &current;
+       sr_session_send(sdi, &packet);
+       g_slist_free(l);
+
+       /* End frame. */
+       packet.type = SR_DF_FRAME_END;
+       sr_session_send(sdi, &packet);
+
+       devc->num_samples++;
+}
+
+static void handle_new_data(const struct sr_dev_inst *sdi)
+{
+       int len;
+       struct dev_context *devc;
+       struct sr_serial_dev_inst *serial;
+
+       devc = sdi->priv;
+       serial = sdi->conn;
+
+       /* Try to get as much data as the buffer can hold. */
+       len = RELOADPRO_BUFSIZE - devc->buflen;
+       len = serial_read_nonblocking(serial, devc->buf + devc->buflen, len);
+       if (len == 0)
+               return; /* No new bytes, nothing to do. */
+       if (len < 0) {
+               sr_err("Serial port read error: %d.", len);
+               return;
+       }
+       devc->buflen += len;
+
+       if (g_str_has_suffix((const char *)devc->buf, "\n")) {
+               handle_packet(sdi);
+               memset(devc->buf, 0, RELOADPRO_BUFSIZE);
+               devc->buflen = 0;
+       }
+}
+
+SR_PRIV int reloadpro_receive_data(int fd, int revents, void *cb_data)
+{
+       struct sr_dev_inst *sdi;
+       struct dev_context *devc;
+       int64_t t;
 
        (void)fd;
 
-       if (!(sdi = cb_data))
+       sdi = cb_data;
+       devc = sdi->priv;
+
+       if (revents != G_IO_IN)
                return TRUE;
 
-       if (!(devc = sdi->priv))
+       handle_new_data(sdi);
+
+       if (devc->limit_samples && (devc->num_samples >= devc->limit_samples)) {
+               sr_info("Requested number of samples reached.");
+               sdi->driver->dev_acquisition_stop(sdi, cb_data);
                return TRUE;
+       }
 
-       if (revents == G_IO_IN) {
+       if (devc->limit_msec) {
+               t = (g_get_monotonic_time() - devc->starttime) / 1000;
+               if (t > (int64_t)devc->limit_msec) {
+                       sr_info("Requested time limit reached.");
+                       sdi->driver->dev_acquisition_stop(sdi, cb_data);
+                       return TRUE;
+               }
        }
 
        return TRUE;
index f5c137865d7a8e27f4b62f96648191f5a9523c23..25ceff58d8317f026975730c5351af0891a8f490 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the libsigrok project.
  *
- * Copyright (C) 2015 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2015-2016 Uwe Hermann <uwe@hermann-uwe.de>
  *
  * 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
 #include <libsigrok/libsigrok.h>
 #include "libsigrok-internal.h"
 
-#define LOG_PREFIX "arachnid-labs-re-load-pro"
+#define LOG_PREFIX "re-load-pro"
+
+#define RELOADPRO_BUFSIZE 100
 
 /** Private, per-device-instance driver context. */
 struct dev_context {
+       uint64_t limit_samples;
+       uint64_t limit_msec;
+       uint64_t num_samples;
+       int64_t starttime;
+       uint8_t buf[RELOADPRO_BUFSIZE];
+       int buflen;
+       gboolean otp_active;
 };
 
+SR_PRIV int reloadpro_set_current_limit(const struct sr_dev_inst *sdi,
+               float current);
+SR_PRIV int reloadpro_get_current_limit(const struct sr_dev_inst *sdi,
+               float *current);
+SR_PRIV int reloadpro_get_voltage_current(const struct sr_dev_inst *sdi,
+               float *voltage, float *current);
 SR_PRIV int reloadpro_receive_data(int fd, int revents, void *cb_data);
 
 #endif