From: Paul Kasemir Date: Wed, 9 Dec 2020 08:05:47 +0000 (-0700) Subject: link-mso19: Setup triggers to basic working state X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=8ec496f6d13e3cd7b35f9924052535244c1bb7a9;p=libsigrok.git link-mso19: Setup triggers to basic working state --- diff --git a/src/hardware/link-mso19/api.c b/src/hardware/link-mso19/api.c index d2d26610..f0fbd329 100644 --- a/src/hardware/link-mso19/api.c +++ b/src/hardware/link-mso19/api.c @@ -35,13 +35,19 @@ static const uint32_t drvopts[] = { 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[] = { @@ -54,10 +60,63 @@ static const uint64_t samplerates[] = { 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; @@ -65,7 +124,6 @@ static GSList* scan_handle_port(GSList *devices, struct sp_port *port) 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; @@ -97,6 +155,9 @@ static GSList* scan_handle_port(GSList *devices, struct sp_port *port) } 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; @@ -232,6 +293,17 @@ static int config_get(uint32_t key, GVariant **data, 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; } @@ -244,7 +316,6 @@ static int config_set(uint32_t key, GVariant *data, { struct dev_context *devc; uint64_t num_samples; - const char *slope; int trigger_pos; double pos; int idx; @@ -265,10 +336,36 @@ static int config_set(uint32_t key, GVariant *data, 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); @@ -305,7 +402,7 @@ static int config_list(uint32_t key, GVariant **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; @@ -317,6 +414,20 @@ static int config_list(uint32_t key, GVariant **data, 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; } diff --git a/src/hardware/link-mso19/protocol.c b/src/hardware/link-mso19/protocol.c index cdb94e3e..4a8d5713 100644 --- a/src/hardware/link-mso19/protocol.c +++ b/src/hardware/link-mso19/protocol.c @@ -80,49 +80,14 @@ SR_PRIV int mso_configure_trigger(const struct sr_dev_inst *sdi) // 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]), @@ -452,9 +417,11 @@ SR_PRIV int mso_receive_data(int fd, int revents, void *cb_data) 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; @@ -462,30 +429,22 @@ SR_PRIV int mso_configure_channels(const struct sr_dev_inst *sdi) 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; } diff --git a/src/hardware/link-mso19/protocol.h b/src/hardware/link-mso19/protocol.h index 51e8c79e..5d1cb648 100644 --- a/src/hardware/link-mso19/protocol.h +++ b/src/hardware/link-mso19/protocol.h @@ -41,11 +41,6 @@ #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 */ @@ -92,17 +87,18 @@ struct dev_context { /* 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; @@ -138,6 +134,10 @@ SR_PRIV void stop_acquisition(const struct sr_dev_inst *sdi); /* 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 @@ -163,6 +163,35 @@ enum { 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)