From: Paul Kasemir Date: Sun, 27 Dec 2020 04:28:10 +0000 (-0700) Subject: link-mso19: Add offset config option X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=753992b575a2897fb76354bd07fe7293182ece15;p=libsigrok.git link-mso19: Add offset config option --- diff --git a/src/hardware/link-mso19/api.c b/src/hardware/link-mso19/api.c index 8ede5507..b6217718 100644 --- a/src/hardware/link-mso19/api.c +++ b/src/hardware/link-mso19/api.c @@ -45,6 +45,7 @@ static const uint32_t devopts_cg_analog[] = { SR_CONF_TRIGGER_SLOPE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST, SR_CONF_TRIGGER_LEVEL | SR_CONF_GET | SR_CONF_SET, SR_CONF_PROBE_FACTOR | SR_CONF_GET | SR_CONF_SET, + SR_CONF_OFFSET | SR_CONF_GET | SR_CONF_SET, }; static const uint32_t devopts_cg_digital[] = { @@ -141,8 +142,12 @@ static void mso_update_trigger_slope(struct dev_context *devc) static void mso_limit_trigger_level(struct dev_context *devc) { double max_level = 2.0 * devc->dso_probe_factor; - if (devc->dso_trigger_level < -max_level) { - devc->dso_trigger_adjusted = -max_level; + double min_level = -max_level; + max_level -= devc->dso_offset_adjusted; + min_level -= devc->dso_offset_adjusted; + + if (devc->dso_trigger_level < min_level) { + devc->dso_trigger_adjusted = min_level; } else if (devc->dso_trigger_level > max_level) { devc->dso_trigger_adjusted = max_level; } else if (devc->dso_trigger_level != devc->dso_trigger_adjusted){ @@ -182,6 +187,22 @@ static void mso_update_logic_threshold_value(struct dev_context *devc) devc->logic_threshold_value = logic_threshold_values[devc->logic_threshold]; } +static void mso_update_offset_value(struct dev_context *devc) +{ + double scaled_value = devc->dso_offset / devc->dso_probe_factor; + double limited_value = MIN(2.0, MAX(-2.0, scaled_value)); + int value = devc->dac_offset - (limited_value / devc->offset_vbit); + value = MIN(DAC_DSO_VALUE_MASK, MAX(0, value)); + devc->dso_offset_value = value; + devc->dso_offset_adjusted = (devc->dac_offset - value) * + devc->dso_probe_factor * devc->offset_vbit; + if (limited_value != scaled_value) { + sr_info("Adjusted dso offset to %f", devc->dso_offset_adjusted); + } + mso_limit_trigger_level(devc); + +} + static GSList* scan_handle_port(GSList *devices, struct sp_port *port) { int usb_vid, usb_pid; @@ -231,6 +252,7 @@ static GSList* scan_handle_port(GSList *devices, struct sp_port *port) devc->limit_samples = MSO_NUM_SAMPLES; devc->logic_threshold = ARRAY_SIZE(logic_thresholds) - 1; // 3.3V/5V mso_update_logic_threshold_value(devc); + mso_update_offset_value(devc); devc->protocol_trigger.spimode = 0; for (i = 0; i < ARRAY_SIZE(devc->protocol_trigger.word); i++) { @@ -383,6 +405,11 @@ static int config_get(uint32_t key, GVariant **data, return SR_ERR_ARG; *data = g_variant_new_double(devc->dso_trigger_level); break; + case SR_CONF_OFFSET: + if (!cg_is_analog(cg)) + return SR_ERR_ARG; + *data = g_variant_new_double(devc->dso_offset); + break; case SR_CONF_HORIZ_TRIGGERPOS: *data = g_variant_new_double(devc->horiz_triggerpos); break; @@ -457,6 +484,12 @@ static int config_set(uint32_t key, GVariant *data, devc->dso_trigger_level = g_variant_get_double(data); mso_limit_trigger_level(devc); break; + case SR_CONF_OFFSET: + if (!cg_is_analog(cg)) + return SR_ERR_ARG; + devc->dso_offset = g_variant_get_double(data); + mso_update_offset_value(devc); + break; case SR_CONF_HORIZ_TRIGGERPOS: pos = g_variant_get_double(data); // Negative position equates to trigger holdoff in the program @@ -482,7 +515,7 @@ static int config_set(uint32_t key, GVariant *data, if (!tmp_u64) return SR_ERR_ARG; devc->dso_probe_factor = tmp_u64; - mso_limit_trigger_level(devc); + mso_update_offset_value(devc); break; case SR_CONF_LOGIC_THRESHOLD: if (!cg_is_digital(cg)) @@ -577,7 +610,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) return ret; /* set dac offset */ - ret = mso_dac_out(sdi, DAC_SELECT_DSO | devc->dac_offset); + ret = mso_dac_out(sdi, DAC_SELECT_DSO | devc->dso_offset_value); if (ret != SR_OK) return ret; diff --git a/src/hardware/link-mso19/protocol.c b/src/hardware/link-mso19/protocol.c index 538d00b8..299e6f00 100644 --- a/src/hardware/link-mso19/protocol.c +++ b/src/hardware/link-mso19/protocol.c @@ -169,7 +169,7 @@ SR_PRIV int mso_dac_out(const struct sr_dev_inst *sdi, uint16_t val) SR_PRIV uint16_t mso_calc_trigger_threshold(struct dev_context *devc) { return (uint16_t) (0x200 - - ((devc->dso_trigger_adjusted / devc->dso_probe_factor) / + (((devc->dso_trigger_adjusted + devc->dso_offset_adjusted) / devc->dso_probe_factor) / devc->vbit)); } @@ -199,7 +199,7 @@ SR_PRIV int mso_parse_serial(const char *iSerial, const char *iProduct, u3 = 500; devc->vbit = ((double)u1) / 10000.0 / 1000.0; devc->dac_offset = u2; - devc->offset_range = u3; + devc->offset_vbit = 3.0 / u3; devc->hwmodel = u4; devc->hwrev = u5; @@ -379,7 +379,8 @@ SR_PRIV int mso_receive_data(int fd, int revents, void *cb_data) analog_out[i] = (devc->buffer[i * 3] & 0x3f) | ((devc->buffer[i * 3 + 1] & 0xf) << 6); analog_out[i] = (512.0 - analog_out[i]) * devc->vbit - * devc->dso_probe_factor; + * devc->dso_probe_factor + - devc->dso_offset_adjusted; logic_out[i] = ((devc->buffer[i * 3 + 1] & 0x30) >> 4) | ((devc->buffer[i * 3 + 2] & 0x3f) << 2); } diff --git a/src/hardware/link-mso19/protocol.h b/src/hardware/link-mso19/protocol.h index db37f6da..ec710bd8 100644 --- a/src/hardware/link-mso19/protocol.h +++ b/src/hardware/link-mso19/protocol.h @@ -80,7 +80,7 @@ struct dev_context { /* calibration */ double vbit; uint16_t dac_offset; - uint16_t offset_range; + double offset_vbit; uint64_t limit_samples; uint64_t num_samples; @@ -105,6 +105,9 @@ struct dev_context { double horiz_triggerpos; double dso_trigger_level; double dso_trigger_adjusted; + double dso_offset; + double dso_offset_adjusted; + uint16_t dso_offset_value; uint16_t dso_trigger_width; struct mso_prototrig protocol_trigger; uint16_t buffer_n; @@ -207,6 +210,7 @@ enum { /* bits - REG_DAC */ enum { + DAC_DSO_VALUE_MASK = 0xfff, DAC_SELECT_DSO = 0 << 15, DAC_SELECT_LA = 1 << 15, };