diff --git a/include/libsigrok/libsigrok.h b/include/libsigrok/libsigrok.h index ad01ffc2..6ab0ea2c 100644 --- a/include/libsigrok/libsigrok.h +++ b/include/libsigrok/libsigrok.h @@ -983,6 +983,9 @@ enum sr_configkey { /** Under-voltage condition active. */ SR_CONF_UNDER_VOLTAGE_CONDITION_ACTIVE, + /** Under-voltage condition threshold. */ + SR_CONF_UNDER_VOLTAGE_CONDITION_THRESHOLD, + /** Trigger level. */ SR_CONF_TRIGGER_LEVEL, diff --git a/src/hardware/arachnid-labs-re-load-pro/api.c b/src/hardware/arachnid-labs-re-load-pro/api.c index d24076e5..1b7b8698 100644 --- a/src/hardware/arachnid-labs-re-load-pro/api.c +++ b/src/hardware/arachnid-labs-re-load-pro/api.c @@ -54,6 +54,7 @@ static const uint32_t devopts_cg[] = { SR_CONF_OVER_TEMPERATURE_PROTECTION_ACTIVE | SR_CONF_GET, SR_CONF_UNDER_VOLTAGE_CONDITION | SR_CONF_GET, SR_CONF_UNDER_VOLTAGE_CONDITION_ACTIVE | SR_CONF_GET, + SR_CONF_UNDER_VOLTAGE_CONDITION_THRESHOLD | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST, }; static GSList *scan(struct sr_dev_driver *di, GSList *options) @@ -174,6 +175,9 @@ static int config_list(uint32_t key, GVariant **data, case SR_CONF_CURRENT_LIMIT: *data = std_gvar_min_max_step(0.0, 6.0, 0.001); break; + case SR_CONF_UNDER_VOLTAGE_CONDITION_THRESHOLD: + *data = std_gvar_min_max_step(0.0, 60.0, 0.001); + break; default: return SR_ERR_NA; } @@ -235,11 +239,20 @@ static int config_get(uint32_t key, GVariant **data, *data = g_variant_new_boolean(devc->otp_active); break; case SR_CONF_UNDER_VOLTAGE_CONDITION: - *data = g_variant_new_boolean(TRUE); /* Always on. */ + if (reloadpro_get_under_voltage_threshold(sdi, &fvalue) == SR_OK) { + if (fvalue == .0) + *data = g_variant_new_boolean(FALSE); + else + *data = g_variant_new_boolean(TRUE); + } break; case SR_CONF_UNDER_VOLTAGE_CONDITION_ACTIVE: *data = g_variant_new_boolean(devc->uvc_active); break; + case SR_CONF_UNDER_VOLTAGE_CONDITION_THRESHOLD: + if (reloadpro_get_under_voltage_threshold(sdi, &fvalue) == SR_OK) + *data = g_variant_new_double(fvalue); + break; default: return SR_ERR_NA; } @@ -264,6 +277,9 @@ static int config_set(uint32_t key, GVariant *data, return reloadpro_set_on_off(sdi, g_variant_get_boolean(data)); case SR_CONF_CURRENT_LIMIT: return reloadpro_set_current_limit(sdi, g_variant_get_double(data)); + case SR_CONF_UNDER_VOLTAGE_CONDITION_THRESHOLD: + return reloadpro_set_under_voltage_threshold(sdi, + g_variant_get_double(data)); default: return SR_ERR_NA; } diff --git a/src/hardware/arachnid-labs-re-load-pro/protocol.c b/src/hardware/arachnid-labs-re-load-pro/protocol.c index e704b16f..31c51581 100644 --- a/src/hardware/arachnid-labs-re-load-pro/protocol.c +++ b/src/hardware/arachnid-labs-re-load-pro/protocol.c @@ -80,7 +80,7 @@ SR_PRIV int reloadpro_set_current_limit(const struct sr_dev_inst *sdi, /* Hardware expects current in mA, integer (0..6000). */ ma = (int)round(current * 1000); - sr_err("Setting current limit to %f A (%d mA).", current, ma); + sr_spew("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) { @@ -108,6 +108,35 @@ SR_PRIV int reloadpro_set_on_off(const struct sr_dev_inst *sdi, gboolean on) return SR_OK; } +SR_PRIV int reloadpro_set_under_voltage_threshold(const struct sr_dev_inst *sdi, + float voltage) +{ + int ret, mv; + char buf[100]; + char *cmd; + + if (voltage < 0 || voltage > 60) { + sr_err("The under voltage threshold must be 0-60 V (was %f V).", + voltage); + return SR_ERR_ARG; + } + + /* Hardware expects voltage in mV, integer (0..60000). */ + mv = (int)round(voltage * 1000); + + sr_spew("Setting under voltage threshold to %f V (%d mV).", voltage, mv); + + cmd = g_strdup_printf("uvlo %d\n", mv); + if ((ret = send_cmd(sdi, cmd, (char *)&buf, sizeof(buf))) < 0) { + sr_err("Error sending under voltage threshold 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) { @@ -130,6 +159,28 @@ SR_PRIV int reloadpro_get_current_limit(const struct sr_dev_inst *sdi, return SR_OK; } +SR_PRIV int reloadpro_get_under_voltage_threshold(const struct sr_dev_inst *sdi, + float *voltage) +{ + int ret; + char buf[100]; + struct dev_context *devc; + + devc = sdi->priv; + + if ((ret = send_cmd(sdi, "uvlo\n", (char *)&buf, sizeof(buf))) < 0) { + sr_err("Error sending under voltage threshold query: %d.", ret); + return SR_ERR; + } + + if (!devc->acquisition_running) { + /* Hardware sends voltage in mV, integer (0..60000). */ + *voltage = g_ascii_strtod(buf + 5, NULL) / 1000; + } + + return SR_OK; +} + SR_PRIV int reloadpro_get_voltage_current(const struct sr_dev_inst *sdi, float *voltage, float *current) { @@ -227,6 +278,23 @@ static void handle_packet(const struct sr_dev_inst *sdi) return; } + if (g_str_has_prefix((const char *)devc->buf, "uvlo ")) { + tokens = g_strsplit((const char *)devc->buf, " ", 2); + voltage = g_ascii_strtod(tokens[1], NULL) / 1000; + g_strfreev(tokens); + if (voltage == .0) { + send_config_update_key(sdi, SR_CONF_UNDER_VOLTAGE_CONDITION, + g_variant_new_boolean(FALSE)); + } else { + send_config_update_key(sdi, SR_CONF_UNDER_VOLTAGE_CONDITION, + g_variant_new_boolean(TRUE)); + send_config_update_key(sdi, + SR_CONF_UNDER_VOLTAGE_CONDITION_THRESHOLD, + g_variant_new_double(voltage)); + } + return; + } + if (!g_str_has_prefix((const char *)devc->buf, "read ")) { sr_dbg("Unknown packet: '%s'.", devc->buf); return; diff --git a/src/hardware/arachnid-labs-re-load-pro/protocol.h b/src/hardware/arachnid-labs-re-load-pro/protocol.h index 225ee1c2..ac6061a5 100644 --- a/src/hardware/arachnid-labs-re-load-pro/protocol.h +++ b/src/hardware/arachnid-labs-re-load-pro/protocol.h @@ -41,8 +41,12 @@ struct dev_context { SR_PRIV int reloadpro_set_current_limit(const struct sr_dev_inst *sdi, float current); SR_PRIV int reloadpro_set_on_off(const struct sr_dev_inst *sdi, gboolean on); +SR_PRIV int reloadpro_set_under_voltage_threshold(const struct sr_dev_inst *sdi, + float voltage); SR_PRIV int reloadpro_get_current_limit(const struct sr_dev_inst *sdi, float *current); +SR_PRIV int reloadpro_get_under_voltage_threshold(const struct sr_dev_inst *sdi, + float *voltage); 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); diff --git a/src/hwdriver.c b/src/hwdriver.c index c81a87a1..f5b5b257 100644 --- a/src/hwdriver.c +++ b/src/hwdriver.c @@ -177,6 +177,8 @@ static struct sr_key_info sr_key_info_config[] = { "Under-voltage condition", NULL}, {SR_CONF_UNDER_VOLTAGE_CONDITION_ACTIVE, SR_T_BOOL, "uvc_active", "Under-voltage condition active", NULL}, + {SR_CONF_UNDER_VOLTAGE_CONDITION_THRESHOLD, SR_T_FLOAT, "uvc_threshold", + "Under-voltage condition threshold", NULL}, {SR_CONF_TRIGGER_LEVEL, SR_T_FLOAT, "triggerlevel", "Trigger level", NULL},