static const uint32_t devopts[] = {
SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET,
SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
- SR_CONF_TRIGGER_SLOPE | SR_CONF_SET,
+ 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,
};
static const uint32_t devopts_cg_analog[] = {
SR_CONF_COUPLING | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
+ SR_CONF_TRIGGER_SLOPE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
+};
+
+static const uint32_t devopts_cg_digital[] = {
+ SR_CONF_TRIGGER_SLOPE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
};
static const char *coupling[] = {
SR_HZ(100),
};
-static const char *trigger_slopes[2] = {
- "r", "f",
+static const char *trigger_sources[] = {
+ "DSO", "LA", // "SPI", "I2C",
+};
+
+enum {
+ TRIGGER_SOURCE_DSO = 0,
+ TRIGGER_SOURCE_LA,
+ // TRIGGER_SOURCE_SPI,
+ // TRIGGER_SOURCE_I2C,
+};
+
+static const char *dso_trigger_slopes[] = {
+ "Rising", "Falling",
+};
+
+static const char *la_trigger_slopes[] = {
+ "F->T", "T->F",
+};
+
+enum {
+ TRIGGER_SLOPE_RISING = 0,
+ TRIGGER_SLOPE_FALLING,
+ TRIGGER_SLOPE_F_T = 0,
+ TRIGGER_SLOPE_T_F,
+};
+
+static const int32_t trigger_matches[] = {
+ SR_TRIGGER_ZERO,
+ SR_TRIGGER_ONE,
};
+static void mso_update_trigger_slope(struct dev_context *devc)
+{
+ switch (devc->trigger_source) {
+ case TRIGGER_SOURCE_DSO:
+ switch (devc->dso_trigger_slope) {
+ case TRIGGER_SLOPE_RISING:
+ TRIG_UPDATE_EDGE(devc->ctltrig, TRIG_EDGE_RISING);
+ break;
+ case TRIGGER_SLOPE_FALLING:
+ TRIG_UPDATE_EDGE(devc->ctltrig, TRIG_EDGE_FALLING);
+ break;
+ }
+ break;
+ case TRIGGER_SOURCE_LA:
+ switch (devc->la_trigger_slope) {
+ case TRIGGER_SLOPE_F_T:
+ TRIG_UPDATE_EDGE(devc->ctltrig, TRIG_EDGE_F_T);
+ break;
+ case TRIGGER_SLOPE_T_F:
+ TRIG_UPDATE_EDGE(devc->ctltrig, TRIG_EDGE_T_F);
+ break;
+ }
+ break;
+ }
+}
+
static GSList* scan_handle_port(GSList *devices, struct sp_port *port)
{
int usb_vid, usb_pid;
char *vendor, *product, *serial_num;
struct dev_context *devc;
struct sr_dev_inst *sdi;
- int chtype;
unsigned int i;
char hwrev[32];
struct sr_channel_group *cg;
}
sprintf(hwrev, "r%d", devc->hwrev);
devc->ctlbase1 = BIT_CTL1_ADC_ENABLE;
+ TRIG_UPDATE_OUT(devc->ctltrig, TRIG_OUT_TRIGGER);
+ TRIG_UPDATE_SRC(devc->ctltrig, TRIG_SRC_DSO);
+ mso_update_trigger_slope(devc);
devc->coupling = coupling[0];
devc->cur_rate = SR_KHZ(10);
devc->dso_probe_attn = 10;
return SR_ERR_NA;
*data = g_variant_new_string(devc->coupling);
break;
+ case SR_CONF_TRIGGER_SOURCE:
+ *data = g_variant_new_string(trigger_sources[devc->trigger_source]);
+ break;
+ case SR_CONF_TRIGGER_SLOPE:
+ if (cg_is_analog(cg))
+ *data = g_variant_new_string(dso_trigger_slopes[devc->dso_trigger_slope]);
+ else if (cg_is_digital(cg))
+ *data = g_variant_new_string(la_trigger_slopes[devc->la_trigger_slope]);
+ else
+ return SR_ERR_NA;
+ break;
default:
return SR_ERR_NA;
}
{
struct dev_context *devc;
uint64_t num_samples;
- const char *slope;
int trigger_pos;
double pos;
int idx;
break;
case SR_CONF_CAPTURE_RATIO:
break;
- case SR_CONF_TRIGGER_SLOPE:
- if ((idx = std_str_idx(data, ARRAY_AND_SIZE(trigger_slopes))) < 0)
+ case SR_CONF_TRIGGER_SOURCE:
+ idx = std_str_idx(data, ARRAY_AND_SIZE(trigger_sources));
+ if (idx < 0)
return SR_ERR_ARG;
- devc->trigger_slope = idx;
+ devc->trigger_source = idx;
+ switch (idx) {
+ case TRIGGER_SOURCE_DSO:
+ TRIG_UPDATE_SRC(devc->ctltrig, TRIG_SRC_DSO);
+ break;
+ case TRIGGER_SOURCE_LA:
+ TRIG_UPDATE_SRC(devc->ctltrig, TRIG_SRC_LA);
+ break;
+ }
+ mso_update_trigger_slope(devc);
+ break;
+ case SR_CONF_TRIGGER_SLOPE:
+ if (cg_is_analog(cg)) {
+ idx = std_str_idx(data, ARRAY_AND_SIZE(dso_trigger_slopes));
+ if (idx < 0)
+ return SR_ERR_ARG;
+ devc->dso_trigger_slope = idx;
+ } else if (cg_is_digital(cg)) {
+ idx = std_str_idx(data, ARRAY_AND_SIZE(la_trigger_slopes));
+ if (idx < 0)
+ return SR_ERR_ARG;
+ devc->la_trigger_slope = idx;
+ } else {
+ return SR_ERR_NA;
+ }
+ mso_update_trigger_slope(devc);
break;
case SR_CONF_HORIZ_TRIGGERPOS:
pos = g_variant_get_double(data);
else if (cg_is_analog(cg))
*data = std_gvar_array_u32(ARRAY_AND_SIZE(devopts_cg_analog));
else if (cg_is_digital(cg))
- *data = std_gvar_array_u32(NULL, 0);
+ *data = std_gvar_array_u32(ARRAY_AND_SIZE(devopts_cg_digital));
else
return SR_ERR_NA;
break;
return SR_ERR_NA;
*data = g_variant_new_strv(ARRAY_AND_SIZE(coupling));
break;
+ case SR_CONF_TRIGGER_SOURCE:
+ *data = g_variant_new_strv(ARRAY_AND_SIZE(trigger_sources));
+ break;
+ case SR_CONF_TRIGGER_SLOPE:
+ if (cg_is_analog(cg))
+ *data = g_variant_new_strv(ARRAY_AND_SIZE(dso_trigger_slopes));
+ else if (cg_is_digital(cg))
+ *data = g_variant_new_strv(ARRAY_AND_SIZE(la_trigger_slopes));
+ else
+ return SR_ERR_NA;
+ break;
+ case SR_CONF_TRIGGER_MATCH:
+ *data = std_gvar_array_i32(ARRAY_AND_SIZE(trigger_matches));
+ break;
default:
return SR_ERR_NA;
}
// Use 0x200 temporary value till we can properly calculate it.
threshold_value = 0x200;
- uint8_t trigger_config = 0;
-
- if (devc->trigger_slope)
- trigger_config |= 0x04; //Trigger on falling edge
-
- switch (devc->trigger_outsrc) {
- case 1:
- trigger_config |= 0x00; //Trigger pulse output
- break;
- case 2:
- trigger_config |= 0x08; //PWM DAC from the pattern generator buffer
- break;
- case 3:
- trigger_config |= 0x18; //White noise
- break;
- }
-
- switch (devc->trigger_chan) {
- case 0:
- trigger_config |= 0x00; //DSO level trigger //b00000000
- break;
- case 1:
- trigger_config |= 0x20; //DSO level trigger & width < trigger_width
- break;
- case 2:
- trigger_config |= 0x40; //DSO level trigger & width >= trigger_width
- break;
- case 3:
- trigger_config |= 0x60; //LA combination trigger
- break;
- }
-
- //Last bit of trigger config reg 4 needs to be 1 for trigger enable,
- //otherwise the trigger is not enabled
- if (devc->use_trigger)
- trigger_config |= 0x80;
+ TRIG_UPDATE_THRESH_MSB(devc->ctltrig, threshold_value);
uint16_t ops[] = {
- mso_trans(3, threshold_value & 0xff),
+ mso_trans(REG_TRIG_THRESH, threshold_value & 0xff),
//The trigger_config also holds the 2 MSB bits from the threshold value
- mso_trans(4, trigger_config | ((threshold_value >> 8) & 0x03)),
- mso_trans(5, devc->la_trigger),
- mso_trans(6, devc->la_trigger_mask),
+ 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]),
SR_PRIV int mso_configure_channels(const struct sr_dev_inst *sdi)
{
struct dev_context *devc;
- struct sr_channel *ch;
- GSList *l;
- char *tc;
+ struct sr_trigger *trigger;
+ struct sr_trigger_stage *stage;
+ struct sr_trigger_match *match;
+ uint8_t channel_bit;
+ GSList *l, *m;
devc = sdi->priv;
devc->la_trigger = 0x00; //The value of the LA byte that generates a trigger event (in that mode).
devc->dso_trigger_voltage = 3;
devc->dso_probe_attn = 1;
- devc->trigger_outsrc = 0;
- //devc->trigger_chan = 3; //LA combination trigger
- devc->trigger_chan = 0; // DSO trigger
- devc->use_trigger = FALSE;
-
- /*
- for (l = sdi->channels; l; l = l->next) {
- ch = (struct sr_channel *)l->data;
- if (ch->enabled == FALSE)
- continue;
-
- int channel_bit = 1 << (ch->index);
- if (!(ch->trigger))
- continue;
-
- devc->use_trigger = TRUE;
- //Configure trigger mask and value.
- for (tc = ch->trigger; *tc; tc++) {
+ trigger = sr_session_trigger_get(sdi->session);
+ if (!trigger)
+ return SR_OK;
+ for (l = trigger->stages; l; l = l->next) {
+ stage = l->data;
+ for (m = stage->matches; m; m = m->next) {
+ match = m->data;
+ if (!match->channel->enabled)
+ /* Ignore disabled channels with a trigger. */
+ continue;
+ channel_bit = 1 << match->channel->index;
devc->la_trigger_mask &= ~channel_bit;
- if (*tc == '1')
+ if (match->match == SR_TRIGGER_ONE)
devc->la_trigger |= channel_bit;
}
}
- */
return SR_OK;
}
#define cg_is_digital(cg) (cg && cg->name[0] == 'L')
#define cg_is_analog(cg) (cg && cg->name[0] == 'D')
-enum trigger_slopes {
- SLOPE_POSITIVE = 0,
- SLOPE_NEGATIVE,
-};
-
/* Structure for the pattern generator state */
struct mso_patgen {
/* Pattern generator clock config */
/* register cache */
uint8_t ctlbase1;
uint8_t ctlbase2;
+ uint8_t ctltrig;
uint8_t status;
uint8_t la_threshold;
uint64_t cur_rate;
const char *coupling;
uint8_t dso_probe_attn;
- int8_t use_trigger;
- uint8_t trigger_chan;
- uint8_t trigger_slope;
+ 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 dso_trigger_voltage;
/* bank 0 registers */
#define REG_BUFFER 1
#define REG_STATUS 2
+#define REG_TRIG_THRESH 3
+#define REG_TRIG 4
+#define REG_TRIG_LA_VAL 5
+#define REG_TRIG_LA_MASK 6
#define REG_CLKRATE1 9
#define REG_CLKRATE2 10
#define REG_DAC1 12
BIT_STATUS_OK = 1 << 5,
};
+/* bits - REG_TRIG */
+enum {
+ TRIG_THRESH_MSB_MASK = 3 << 0,
+
+ TRIG_EDGE_RISING = 0 << 2,
+ TRIG_EDGE_FALLING = 1 << 2,
+ TRIG_EDGE_T_F = 0 << 2,
+ TRIG_EDGE_F_T = 1 << 2,
+ TRIG_EDGE_MASK = 1 << 2,
+
+ TRIG_OUT_TRIGGER = 0 << 3,
+ TRIG_OUT_PG = 1 << 3,
+ TRIG_OUT_NOISE = 3 << 3,
+ TRIG_OUT_MASK = 3 << 3,
+
+ TRIG_SRC_DSO = 0 << 5,
+ TRIG_SRC_DSO_PULSE_GE = 1 << 5,
+ TRIG_SRC_DSO_PULSE_LT = 2 << 5,
+ TRIG_SRC_SPI = 4 << 5,
+ TRIG_SRC_I2C = 5 << 5,
+ TRIG_SRC_LA = 7 << 5,
+ TRIG_SRC_MASK = 7 << 5,
+};
+#define TRIG_UPDATE_MASK(reg, val, mask) reg = (((reg) & ~(mask)) | ((val) & (mask)))
+#define TRIG_UPDATE_THRESH_MSB(reg, val) TRIG_UPDATE_MASK((reg), (val) >> 8, TRIG_THRESH_MSB_MASK)
+#define TRIG_UPDATE_EDGE(reg, val) TRIG_UPDATE_MASK((reg), (val), TRIG_EDGE_MASK)
+#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_CTL1 */
#define BIT_CTL1_RESETFSM (1 << 0)
#define BIT_CTL1_ARM (1 << 1)