From: Paul Kasemir Date: Fri, 18 Dec 2020 07:42:07 +0000 (-0700) Subject: link-mso19: Fixup horiz_triggerpos and add trigger location X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=f1b1ea3c9712b4b3c023ec2eb86ce33623f0d26a;p=libsigrok.git link-mso19: Fixup horiz_triggerpos and add trigger location --- diff --git a/src/hardware/link-mso19/api.c b/src/hardware/link-mso19/api.c index ffcc4496..9636aea4 100644 --- a/src/hardware/link-mso19/api.c +++ b/src/hardware/link-mso19/api.c @@ -37,8 +37,7 @@ static const uint32_t devopts[] = { SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST, SR_CONF_TRIGGER_SOURCE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST, SR_CONF_TRIGGER_MATCH | SR_CONF_LIST, - SR_CONF_HORIZ_TRIGGERPOS | SR_CONF_SET, - SR_CONF_CAPTURE_RATIO | SR_CONF_SET, + SR_CONF_HORIZ_TRIGGERPOS | SR_CONF_GET | SR_CONF_SET, }; static const uint32_t devopts_cg_analog[] = { @@ -134,6 +133,30 @@ static void mso_limit_trigger_level(struct dev_context *devc) sr_info("Adjusted dso trigger level to %f", devc->dso_trigger_adjusted); } +static void mso_update_trigger_pos(struct dev_context *devc) +{ + int pos = (devc->horiz_triggerpos * MSO_NUM_SAMPLES) + 0.5; + uint16_t sign_bit = TRIG_POS_IS_POSITIVE; + if (pos < 0) { + pos = -pos; + sign_bit = TRIG_POS_IS_NEGATIVE; + if (pos < (MSO_NUM_SAMPLES + 10)) { + // Program doesn't allow these holdoff values, but they + // sometimes work, so just warn about stability. + sr_warn("Trigger holdoff > -1.011 may be unstable %f", devc->horiz_triggerpos); + } + } else if (pos >= MSO_NUM_SAMPLES) { + pos = MSO_NUM_SAMPLES - 1; + } else if (pos < 10) { + // Program never runs trigger less than 10. It sometimes fails + // to trigger properly if less than 10. + sr_warn("Trigger position < .01 may be unstable %f", devc->horiz_triggerpos); + } + devc->ctltrig_pos = pos & TRIG_POS_VALUE_MASK; + if (devc->ctltrig_pos) + devc->ctltrig_pos |= sign_bit; +} + static GSList* scan_handle_port(GSList *devices, struct sp_port *port) { int usb_vid, usb_pid; @@ -175,6 +198,8 @@ static GSList* scan_handle_port(GSList *devices, struct sp_port *port) TRIG_UPDATE_OUT(devc->ctltrig, TRIG_OUT_TRIGGER); TRIG_UPDATE_SRC(devc->ctltrig, TRIG_SRC_DSO); mso_update_trigger_slope(devc); + devc->horiz_triggerpos = 0.5; + mso_update_trigger_pos(devc); devc->coupling = coupling[0]; devc->cur_rate = SR_KHZ(10); devc->dso_probe_factor = 10; @@ -331,6 +356,9 @@ 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_HORIZ_TRIGGERPOS: + *data = g_variant_new_double(devc->horiz_triggerpos); + break; default: return SR_ERR_NA; } @@ -343,7 +371,6 @@ static int config_set(uint32_t key, GVariant *data, { struct dev_context *devc; uint64_t tmp_u64; - int trigger_pos; double pos; int idx; @@ -361,8 +388,6 @@ static int config_set(uint32_t key, GVariant *data, } devc->limit_samples = tmp_u64; break; - case SR_CONF_CAPTURE_RATIO: - break; case SR_CONF_TRIGGER_SOURCE: idx = std_str_idx(data, ARRAY_AND_SIZE(trigger_sources)); if (idx < 0) @@ -402,12 +427,13 @@ static int config_set(uint32_t key, GVariant *data, break; case SR_CONF_HORIZ_TRIGGERPOS: pos = g_variant_get_double(data); - if (pos < 0 || pos > 255) { - sr_err("Trigger position (%f) should be between 0 and 255.", pos); + // Negative position equates to trigger holdoff in the program + if (pos < -10.0 || pos > 1.0) { + sr_err("Trigger position (%f) should be between -10.0 and 1.0", pos); return SR_ERR_ARG; } - trigger_pos = (int)pos; - devc->trigger_holdoff[0] = trigger_pos & 0xff; + devc->horiz_triggerpos = pos; + mso_update_trigger_pos(devc); break; case SR_CONF_COUPLING: if (!cg_is_analog(cg)) diff --git a/src/hardware/link-mso19/protocol.c b/src/hardware/link-mso19/protocol.c index 27186655..c2fdf5c5 100644 --- a/src/hardware/link-mso19/protocol.c +++ b/src/hardware/link-mso19/protocol.c @@ -86,10 +86,10 @@ SR_PRIV int mso_configure_trigger(const struct sr_dev_inst *sdi) mso_trans(REG_TRIG, devc->ctltrig), mso_trans(REG_TRIG_LA_VAL, devc->la_trigger), mso_trans(REG_TRIG_LA_MASK, devc->la_trigger_mask), - mso_trans(7, devc->trigger_holdoff[0]), - mso_trans(8, devc->trigger_holdoff[1]), + mso_trans(REG_TRIG_POS_LSB, devc->ctltrig_pos & 0xff), + mso_trans(REG_TRIG_POS_MSB, (devc->ctltrig_pos >> 8) & 0xff), - mso_trans(11, + mso_trans(REG_TRIG_WIDTH, devc->dso_trigger_width / SR_HZ_TO_NS(devc->cur_rate)), @@ -327,6 +327,8 @@ SR_PRIV int mso_receive_data(int fd, int revents, void *cb_data) struct sr_dev_inst *sdi; struct dev_context *devc; int i; + int trigger_sample; + int pre_samples, post_samples; uint8_t in[MSO_NUM_SAMPLES]; size_t s; @@ -382,24 +384,55 @@ SR_PRIV int mso_receive_data(int fd, int revents, void *cb_data) ((devc->buffer[i * 3 + 2] & 0x3f) << 2); } - packet.type = SR_DF_LOGIC; - packet.payload = &logic; - logic.length = MSO_NUM_SAMPLES; - logic.unitsize = 1; - logic.data = logic_out; - sr_session_send(sdi, &packet); + if (devc->ctltrig_pos & TRIG_POS_IS_NEGATIVE) { + trigger_sample = -1; + pre_samples = MSO_NUM_SAMPLES; + } else { + trigger_sample = devc->ctltrig_pos & TRIG_POS_VALUE_MASK; + pre_samples = MIN(trigger_sample, MSO_NUM_SAMPLES); + } + + logic.unitsize = sizeof(*logic_out); sr_analog_init(&analog, &encoding, &meaning, &spec, 3); analog.meaning->channels = g_slist_append(NULL, g_slist_nth_data(sdi->channels, 0)); - analog.num_samples = MSO_NUM_SAMPLES; - analog.data = analog_out; analog.meaning->mq = SR_MQ_VOLTAGE; analog.meaning->unit = SR_UNIT_VOLT; analog.meaning->mqflags = SR_MQFLAG_DC; - packet.type = SR_DF_ANALOG; - packet.payload = &analog; - sr_session_send(sdi, &packet); + if (pre_samples > 0) { + packet.type = SR_DF_LOGIC; + packet.payload = &logic; + logic.length = pre_samples * sizeof(*logic_out); + logic.data = logic_out; + sr_session_send(sdi, &packet); + + packet.type = SR_DF_ANALOG; + packet.payload = &analog; + analog.num_samples = pre_samples; + analog.data = analog_out; + sr_session_send(sdi, &packet); + } + + if (pre_samples == trigger_sample) { + std_session_send_df_trigger(sdi); + } + + post_samples = MSO_NUM_SAMPLES - pre_samples; + + if (post_samples > 0) { + packet.type = SR_DF_LOGIC; + packet.payload = &logic; + logic.length = post_samples * sizeof(*logic_out); + logic.data = logic_out + pre_samples; + sr_session_send(sdi, &packet); + + packet.type = SR_DF_ANALOG; + packet.payload = &analog; + analog.num_samples = post_samples; + analog.data = analog_out + pre_samples; + sr_session_send(sdi, &packet); + } g_slist_free(analog.meaning->channels); devc->num_samples += MSO_NUM_SAMPLES; diff --git a/src/hardware/link-mso19/protocol.h b/src/hardware/link-mso19/protocol.h index f6d714d5..0c50ab85 100644 --- a/src/hardware/link-mso19/protocol.h +++ b/src/hardware/link-mso19/protocol.h @@ -88,6 +88,7 @@ struct dev_context { uint8_t ctlbase1; uint8_t ctlbase2; uint8_t ctltrig; + uint16_t ctltrig_pos; uint8_t status; uint8_t la_threshold; @@ -97,10 +98,10 @@ struct dev_context { uint8_t trigger_source; uint8_t dso_trigger_slope; uint8_t trigger_outsrc; - uint8_t trigger_holdoff[2]; uint8_t la_trigger_slope; uint8_t la_trigger; uint8_t la_trigger_mask; + double horiz_triggerpos; double dso_trigger_level; double dso_trigger_adjusted; uint16_t dso_trigger_width; @@ -139,8 +140,11 @@ SR_PRIV void stop_acquisition(const struct sr_dev_inst *sdi); #define REG_TRIG 4 #define REG_TRIG_LA_VAL 5 #define REG_TRIG_LA_MASK 6 +#define REG_TRIG_POS_LSB 7 +#define REG_TRIG_POS_MSB 8 #define REG_CLKRATE1 9 #define REG_CLKRATE2 10 +#define REG_TRIG_WIDTH 11 #define REG_DAC1 12 #define REG_DAC2 13 /* possibly bank agnostic: */ @@ -193,6 +197,13 @@ enum { #define TRIG_UPDATE_OUT(reg, val) TRIG_UPDATE_MASK((reg), (val), TRIG_OUT_MASK) #define TRIG_UPDATE_SRC(reg, val) TRIG_UPDATE_MASK((reg), (val), TRIG_SRC_MASK) +/* bits - REG_TRIG_POS_MSB */ +enum { + TRIG_POS_VALUE_MASK = 0x7fff, + TRIG_POS_IS_POSITIVE = 0 << 15, + TRIG_POS_IS_NEGATIVE = 1 << 15, +}; + /* bits - REG_CTL1 */ #define BIT_CTL1_RESETFSM (1 << 0) #define BIT_CTL1_ARM (1 << 1)