]> sigrok.org Git - libsigrok.git/commitdiff
link-mso19: Add offset config option
authorPaul Kasemir <redacted>
Sun, 27 Dec 2020 04:28:10 +0000 (21:28 -0700)
committerSoeren Apel <redacted>
Wed, 16 Oct 2024 22:08:40 +0000 (00:08 +0200)
src/hardware/link-mso19/api.c
src/hardware/link-mso19/protocol.c
src/hardware/link-mso19/protocol.h

index 8ede55075514e6ae1ce87f4ce571ca3165792279..b6217718ef83233426b08c241788d6cc38117802 100644 (file)
@@ -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;
 
index 538d00b80d96051729ee955758d3d1bfe3906baa..299e6f0012ce4fae7b29b62cbdc8cef3b433173b 100644 (file)
@@ -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);
        }
index db37f6da268636a79d2e8649e44c545f242b0900..ec710bd8f93bf711e52d564b69ead3c495f37ed0 100644 (file)
@@ -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,
 };