]> sigrok.org Git - libsigrok.git/commitdiff
link-mso19: Setup triggers to basic working state
authorPaul Kasemir <redacted>
Wed, 9 Dec 2020 08:05:47 +0000 (01:05 -0700)
committerSoeren Apel <redacted>
Wed, 16 Oct 2024 22:08:24 +0000 (00:08 +0200)
src/hardware/link-mso19/api.c
src/hardware/link-mso19/protocol.c
src/hardware/link-mso19/protocol.h

index d2d266100245ff55e12d6e9b24159fb5af27594a..f0fbd32920fa4d67ba19db06527412e5f617959d 100644 (file)
@@ -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;
        }
index cdb94e3ea706af9a0536870225c6aceff2dbd565..4a8d5713b408823afa0519526ab4d696ba143517 100644 (file)
@@ -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;
 }
index 51e8c79efb2b5debf58993fd30aa1cc196374f8e..5d1cb64879a876ab1526252dd4d8f5684cb1ea66 100644 (file)
 #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)