X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=hardware%2Fsysclk-lwla%2Fapi.c;h=a4346a012329c083349fd40a80831c1e504f02c9;hb=43cd4637285833706f8a404ca027bcf0ee75b9ae;hp=f94edcd697d6bb0388c3311a064d97f34e383eb2;hpb=e6e54bd2537ac423977f5574292f2cb987ce8629;p=libsigrok.git diff --git a/hardware/sysclk-lwla/api.c b/hardware/sysclk-lwla/api.c index f94edcd6..a4346a01 100644 --- a/hardware/sysclk-lwla/api.c +++ b/hardware/sysclk-lwla/api.c @@ -33,13 +33,21 @@ static const int32_t hwcaps[] = { SR_CONF_LOGIC_ANALYZER, SR_CONF_SAMPLERATE, SR_CONF_EXTERNAL_CLOCK, - SR_CONF_TRIGGER_TYPE, + SR_CONF_CLOCK_EDGE, + SR_CONF_TRIGGER_MATCH, SR_CONF_TRIGGER_SOURCE, SR_CONF_TRIGGER_SLOPE, SR_CONF_LIMIT_MSEC, SR_CONF_LIMIT_SAMPLES, }; +static const int32_t trigger_matches[] = { + SR_TRIGGER_ZERO, + SR_TRIGGER_ONE, + SR_TRIGGER_RISING, + SR_TRIGGER_FALLING, +}; + /* The hardware supports more samplerates than these, but these are the * options hardcoded into the vendor's Windows GUI. */ @@ -59,9 +67,9 @@ static const uint64_t samplerates[] = { static const char *const trigger_source_names[] = { "CH", "TRG" }; /* Names assigned to available trigger slope choices. Indices must - * match trigger_slope enum values. + * match the signal_edge enum values. */ -static const char *const trigger_slope_names[] = { "r", "f" }; +static const char *const signal_edge_names[] = { "r", "f" }; SR_PRIV struct sr_dev_driver sysclk_lwla_driver_info; static struct sr_dev_driver *const di = &sysclk_lwla_driver_info; @@ -71,21 +79,21 @@ static int init(struct sr_context *sr_ctx) return std_init(sr_ctx, di, LOG_PREFIX); } -static GSList *gen_probe_list(int num_probes) +static GSList *gen_channel_list(int num_channels) { GSList *list; - struct sr_probe *probe; + struct sr_channel *ch; int i; char name[8]; list = NULL; - for (i = num_probes; i > 0; --i) { - /* The LWLA series simply number probes from CH1 to CHxx. */ + for (i = num_channels; i > 0; --i) { + /* The LWLA series simply number channels from CH1 to CHxx. */ g_snprintf(name, sizeof(name), "CH%d", i); - probe = sr_probe_new(i - 1, SR_PROBE_LOGIC, TRUE, name); - list = g_slist_prepend(list, probe); + ch = sr_channel_new(i - 1, SR_CHANNEL_LOGIC, TRUE, name); + list = g_slist_prepend(list, ch); } return list; @@ -112,12 +120,12 @@ static struct sr_dev_inst *dev_inst_new(int device_index) return NULL; } - /* Enable all channels to match the default probe configuration. */ + /* Enable all channels to match the default channel configuration. */ devc->channel_mask = ALL_CHANNELS_MASK; devc->samplerate = DEFAULT_SAMPLERATE; sdi->priv = devc; - sdi->probes = gen_probe_list(NUM_PROBES); + sdi->channels = gen_channel_list(NUM_CHANNELS); return sdi; } @@ -234,30 +242,26 @@ static int dev_open(struct sr_dev_inst *sdi) static int dev_close(struct sr_dev_inst *sdi) { struct sr_usb_dev_inst *usb; - struct dev_context *devc; if (!di->priv) { sr_err("Driver was not initialized."); return SR_ERR; } - usb = sdi->conn; - devc = sdi->priv; - + usb = sdi->conn; if (!usb->devhdl) return SR_OK; - /* Trigger download of the shutdown bitstream. */ - devc->selected_clock_source = CLOCK_SOURCE_NONE; + sdi->status = SR_ST_INACTIVE; - if (lwla_set_clock_source(sdi) != SR_OK) + /* Trigger download of the shutdown bitstream. */ + if (lwla_set_clock_config(sdi) != SR_OK) sr_err("Unable to shut down device."); libusb_release_interface(usb->devhdl, USB_INTERFACE); libusb_close(usb->devhdl); usb->devhdl = NULL; - sdi->status = SR_ST_INACTIVE; return SR_OK; } @@ -268,12 +272,12 @@ static int cleanup(void) } static int config_get(int key, GVariant **data, const struct sr_dev_inst *sdi, - const struct sr_probe_group *probe_group) + const struct sr_channel_group *cg) { struct dev_context *devc; size_t idx; - (void)probe_group; + (void)cg; if (!sdi) return SR_ERR_ARG; @@ -291,8 +295,14 @@ static int config_get(int key, GVariant **data, const struct sr_dev_inst *sdi, *data = g_variant_new_uint64(devc->limit_samples); break; case SR_CONF_EXTERNAL_CLOCK: - *data = g_variant_new_boolean(devc->selected_clock_source - >= CLOCK_SOURCE_EXT_RISE); + *data = g_variant_new_boolean(devc->cfg_clock_source + == CLOCK_EXT_CLK); + break; + case SR_CONF_CLOCK_EDGE: + idx = devc->cfg_clock_edge; + if (idx >= G_N_ELEMENTS(signal_edge_names)) + return SR_ERR_BUG; + *data = g_variant_new_string(signal_edge_names[idx]); break; case SR_CONF_TRIGGER_SOURCE: idx = devc->cfg_trigger_source; @@ -302,9 +312,9 @@ static int config_get(int key, GVariant **data, const struct sr_dev_inst *sdi, break; case SR_CONF_TRIGGER_SLOPE: idx = devc->cfg_trigger_slope; - if (idx >= G_N_ELEMENTS(trigger_slope_names)) + if (idx >= G_N_ELEMENTS(signal_edge_names)) return SR_ERR_BUG; - *data = g_variant_new_string(trigger_slope_names[idx]); + *data = g_variant_new_string(signal_edge_names[idx]); break; default: return SR_ERR_NA; @@ -334,13 +344,13 @@ static int lookup_index(GVariant *value, const char *const *table, int len) } static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi, - const struct sr_probe_group *probe_group) + const struct sr_channel_group *cg) { uint64_t value; struct dev_context *devc; int idx; - (void)probe_group; + (void)cg; devc = sdi->priv; if (!devc) @@ -367,14 +377,15 @@ static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi, devc->limit_samples = value; break; case SR_CONF_EXTERNAL_CLOCK: - if (g_variant_get_boolean(data)) { - sr_info("Enabling external clock."); - /* TODO: Allow the external clock to be inverted */ - devc->selected_clock_source = CLOCK_SOURCE_EXT_RISE; - } else { - sr_info("Disabling external clock."); - devc->selected_clock_source = CLOCK_SOURCE_INT; - } + devc->cfg_clock_source = (g_variant_get_boolean(data)) + ? CLOCK_EXT_CLK : CLOCK_INTERNAL; + break; + case SR_CONF_CLOCK_EDGE: + idx = lookup_index(data, signal_edge_names, + G_N_ELEMENTS(signal_edge_names)); + if (idx < 0) + return SR_ERR_ARG; + devc->cfg_clock_edge = idx; break; case SR_CONF_TRIGGER_SOURCE: idx = lookup_index(data, trigger_source_names, @@ -384,8 +395,8 @@ static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi, devc->cfg_trigger_source = idx; break; case SR_CONF_TRIGGER_SLOPE: - idx = lookup_index(data, trigger_slope_names, - G_N_ELEMENTS(trigger_slope_names)); + idx = lookup_index(data, signal_edge_names, + G_N_ELEMENTS(signal_edge_names)); if (idx < 0) return SR_ERR_ARG; devc->cfg_trigger_slope = idx; @@ -397,66 +408,28 @@ static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi, return SR_OK; } -static int config_probe_set(const struct sr_dev_inst *sdi, - struct sr_probe *probe, unsigned int changes) +static int config_channel_set(const struct sr_dev_inst *sdi, + struct sr_channel *ch, unsigned int changes) { - uint64_t probe_bit; - uint64_t trigger_mask; - uint64_t trigger_values; - uint64_t trigger_edge_mask; + uint64_t channel_bit; struct dev_context *devc; devc = sdi->priv; if (!devc) return SR_ERR_DEV_CLOSED; - if (probe->index < 0 || probe->index >= NUM_PROBES) { - sr_err("Probe index %d out of range.", probe->index); + if (ch->index < 0 || ch->index >= NUM_CHANNELS) { + sr_err("Channel index %d out of range.", ch->index); return SR_ERR_BUG; } - probe_bit = (uint64_t)1 << probe->index; + channel_bit = (uint64_t)1 << ch->index; - if ((changes & SR_PROBE_SET_ENABLED) != 0) { - /* Enable or disable input channel for this probe. */ - if (probe->enabled) - devc->channel_mask |= probe_bit; + if ((changes & SR_CHANNEL_SET_ENABLED) != 0) { + /* Enable or disable input channel for this channel. */ + if (ch->enabled) + devc->channel_mask |= channel_bit; else - devc->channel_mask &= ~probe_bit; - } - - if ((changes & SR_PROBE_SET_TRIGGER) != 0) { - trigger_mask = devc->trigger_mask & ~probe_bit; - trigger_values = devc->trigger_values & ~probe_bit; - trigger_edge_mask = devc->trigger_edge_mask & ~probe_bit; - - if (probe->trigger && probe->trigger[0] != '\0') { - if (probe->trigger[1] != '\0') { - sr_warn("Trigger configuration \"%s\" with " - "multiple stages is not supported.", - probe->trigger); - return SR_ERR_ARG; - } - /* Enable trigger for this probe. */ - trigger_mask |= probe_bit; - - /* Configure edge mask and trigger value. */ - switch (probe->trigger[0]) { - case '1': trigger_values |= probe_bit; - case '0': break; - - case 'r': trigger_values |= probe_bit; - case 'f': trigger_edge_mask |= probe_bit; - break; - default: - sr_warn("Trigger type '%c' is not supported.", - probe->trigger[0]); - return SR_ERR_ARG; - } - } - /* Store validated trigger setup. */ - devc->trigger_mask = trigger_mask; - devc->trigger_values = trigger_values; - devc->trigger_edge_mask = trigger_edge_mask; + devc->channel_mask &= ~channel_bit; } return SR_OK; @@ -469,17 +442,17 @@ static int config_commit(const struct sr_dev_inst *sdi) return SR_ERR; } - return lwla_set_clock_source(sdi); + return lwla_set_clock_config(sdi); } static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, - const struct sr_probe_group *probe_group) + const struct sr_channel_group *cg) { GVariant *gvar; GVariantBuilder gvb; (void)sdi; - (void)probe_group; + (void)cg; switch (key) { case SR_CONF_SCAN_OPTIONS: @@ -498,16 +471,19 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, g_variant_builder_add(&gvb, "{sv}", "samplerates", gvar); *data = g_variant_builder_end(&gvb); break; - case SR_CONF_TRIGGER_TYPE: - *data = g_variant_new_string(TRIGGER_TYPES); + case SR_CONF_TRIGGER_MATCH: + *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32, + trigger_matches, ARRAY_SIZE(trigger_matches), + sizeof(int32_t)); break; case SR_CONF_TRIGGER_SOURCE: *data = g_variant_new_strv(trigger_source_names, G_N_ELEMENTS(trigger_source_names)); break; case SR_CONF_TRIGGER_SLOPE: - *data = g_variant_new_strv(trigger_slope_names, - G_N_ELEMENTS(trigger_slope_names)); + case SR_CONF_CLOCK_EDGE: + *data = g_variant_new_strv(signal_edge_names, + G_N_ELEMENTS(signal_edge_names)); break; default: return SR_ERR_NA; @@ -545,9 +521,10 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) sr_info("Starting acquisition."); devc->acquisition = acq; + lwla_convert_trigger(sdi); ret = lwla_setup_acquisition(sdi); if (ret != SR_OK) { - sr_err("Failed to set up aquisition."); + sr_err("Failed to set up acquisition."); devc->acquisition = NULL; lwla_free_acquisition_state(acq); return ret; @@ -555,12 +532,12 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) ret = lwla_start_acquisition(sdi); if (ret != SR_OK) { - sr_err("Failed to start aquisition."); + sr_err("Failed to start acquisition."); devc->acquisition = NULL; lwla_free_acquisition_state(acq); return ret; } - usb_source_add(drvc->sr_ctx, 100, &lwla_receive_data, + usb_source_add(sdi->session, drvc->sr_ctx, 100, &lwla_receive_data, (struct sr_dev_inst *)sdi); sr_info("Waiting for data."); @@ -596,7 +573,7 @@ SR_PRIV struct sr_dev_driver sysclk_lwla_driver_info = { .dev_clear = dev_clear, .config_get = config_get, .config_set = config_set, - .config_probe_set = config_probe_set, + .config_channel_set = config_channel_set, .config_commit = config_commit, .config_list = config_list, .dev_open = dev_open,