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[] = {
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;
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;
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;
}
{
struct dev_context *devc;
uint64_t tmp_u64;
- int trigger_pos;
double pos;
int idx;
}
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)
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))
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)),
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;
((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;
uint8_t ctlbase1;
uint8_t ctlbase2;
uint8_t ctltrig;
+ uint16_t ctltrig_pos;
uint8_t status;
uint8_t la_threshold;
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;
#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: */
#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)