X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Fasix-sigma%2Fapi.c;h=c9b787e73ac8ac2976468cd81e3982a630931d08;hb=53012da658ae94b245240c8a3e115723eede4c7d;hp=a102b03b32d6ef672175eda65ede82cebef43c11;hpb=43376f3324cddd257a0260b06d9db8180c35fdf3;p=libsigrok.git diff --git a/src/hardware/asix-sigma/api.c b/src/hardware/asix-sigma/api.c index a102b03b..c9b787e7 100644 --- a/src/hardware/asix-sigma/api.c +++ b/src/hardware/asix-sigma/api.c @@ -19,10 +19,6 @@ * along with this program. If not, see . */ -/* - * ASIX SIGMA/SIGMA2 logic analyzer driver - */ - #include #include "protocol.h" @@ -42,23 +38,31 @@ static const uint32_t drvopts[] = { static const uint32_t devopts[] = { SR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET, - SR_CONF_LIMIT_SAMPLES | SR_CONF_SET, + SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET, SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST, +#if ASIX_SIGMA_WITH_TRIGGER SR_CONF_TRIGGER_MATCH | SR_CONF_LIST, SR_CONF_CAPTURE_RATIO | SR_CONF_GET | SR_CONF_SET, +#endif }; +#if ASIX_SIGMA_WITH_TRIGGER static const int32_t trigger_matches[] = { SR_TRIGGER_ZERO, SR_TRIGGER_ONE, SR_TRIGGER_RISING, SR_TRIGGER_FALLING, }; +#endif +static void clear_helper(struct dev_context *devc) +{ + ftdi_deinit(&devc->ftdic); +} static int dev_clear(const struct sr_dev_driver *di) { - return std_dev_clear(di, sigma_clear_helper); + return std_dev_clear_with_callback(di, (std_dev_clear_callback)clear_helper); } static GSList *scan(struct sr_dev_driver *di, GSList *options) @@ -77,8 +81,6 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options) ftdi_init(&devc->ftdic); - /* Look for SIGMAs. */ - if ((ret = ftdi_usb_find_all(&devc->ftdic, &devlist, USB_VENDOR, USB_PRODUCT)) <= 0) { if (ret < 0) @@ -100,15 +102,14 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options) sr_info("Found ASIX SIGMA - Serial: %s", serial_txt); devc->cur_samplerate = samplerates[0]; - devc->period_ps = 0; devc->limit_msec = 0; + devc->limit_samples = 0; devc->cur_firmware = -1; devc->num_channels = 0; devc->samples_per_event = 0; devc->capture_ratio = 50; devc->use_triggers = 0; - /* Register SIGMA device. */ sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INITIALIZING; sdi->vendor = g_strdup(USB_VENDOR_NAME); @@ -119,7 +120,6 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options) sdi->priv = devc; - /* We will open the device again when we need it. */ ftdi_list_free(&devlist); return std_scan_complete(di, g_slist_append(NULL, sdi)); @@ -137,18 +137,13 @@ static int dev_open(struct sr_dev_inst *sdi) devc = sdi->priv; - /* Make sure it's an ASIX SIGMA. */ if ((ret = ftdi_usb_open_desc(&devc->ftdic, - USB_VENDOR, USB_PRODUCT, USB_DESCRIPTION, NULL)) < 0) { - - sr_err("ftdi_usb_open failed: %s", - ftdi_get_error_string(&devc->ftdic)); - - return 0; + USB_VENDOR, USB_PRODUCT, USB_DESCRIPTION, NULL)) < 0) { + sr_err("Failed to open device (%d): %s.", + ret, ftdi_get_error_string(&devc->ftdic)); + return SR_ERR; } - sdi->status = SR_ST_ACTIVE; - return SR_OK; } @@ -158,13 +153,7 @@ static int dev_close(struct sr_dev_inst *sdi) devc = sdi->priv; - /* TODO */ - if (sdi->status == SR_ST_ACTIVE) - ftdi_usb_close(&devc->ftdic); - - sdi->status = SR_ST_INACTIVE; - - return SR_OK; + return (ftdi_usb_close(&devc->ftdic) == 0) ? SR_OK : SR_ERR; } static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi, @@ -185,9 +174,14 @@ static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *s case SR_CONF_LIMIT_MSEC: *data = g_variant_new_uint64(devc->limit_msec); break; + case SR_CONF_LIMIT_SAMPLES: + *data = g_variant_new_uint64(devc->limit_samples); + break; +#if ASIX_SIGMA_WITH_TRIGGER case SR_CONF_CAPTURE_RATIO: *data = g_variant_new_uint64(devc->capture_ratio); break; +#endif default: return SR_ERR_NA; } @@ -204,9 +198,6 @@ static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sd (void)cg; - if (sdi->status != SR_ST_ACTIVE) - return SR_ERR_DEV_CLOSED; - devc = sdi->priv; ret = SR_OK; @@ -223,15 +214,17 @@ static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sd break; case SR_CONF_LIMIT_SAMPLES: tmp = g_variant_get_uint64(data); - devc->limit_msec = tmp * 1000 / devc->cur_samplerate; + devc->limit_samples = tmp; + devc->limit_msec = sigma_limit_samples_to_msec(devc, tmp); break; +#if ASIX_SIGMA_WITH_TRIGGER case SR_CONF_CAPTURE_RATIO: tmp = g_variant_get_uint64(data); - if (tmp <= 100) - devc->capture_ratio = tmp; - else - ret = SR_ERR; + if (tmp > 100) + return SR_ERR; + devc->capture_ratio = tmp; break; +#endif default: ret = SR_ERR_NA; } @@ -242,32 +235,17 @@ static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sd static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi, const struct sr_channel_group *cg) { - GVariant *gvar; - GVariantBuilder gvb; - - (void)cg; - switch (key) { case SR_CONF_DEVICE_OPTIONS: - if (!sdi) - *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, - drvopts, ARRAY_SIZE(drvopts), sizeof(uint32_t)); - else - *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32, - devopts, ARRAY_SIZE(devopts), sizeof(uint32_t)); - break; + return STD_CONFIG_LIST(key, data, sdi, cg, NULL, drvopts, devopts); case SR_CONF_SAMPLERATE: - g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}")); - gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates, - SAMPLERATES_COUNT, sizeof(uint64_t)); - g_variant_builder_add(&gvb, "{sv}", "samplerates", gvar); - *data = g_variant_builder_end(&gvb); + *data = std_gvar_samplerates(samplerates, samplerates_count); break; +#if ASIX_SIGMA_WITH_TRIGGER case SR_CONF_TRIGGER_MATCH: - *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32, - trigger_matches, ARRAY_SIZE(trigger_matches), - sizeof(int32_t)); + *data = std_gvar_array_i32(ARRAY_AND_SIZE(trigger_matches)); break; +#endif default: return SR_ERR_NA; } @@ -279,13 +257,13 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) { struct dev_context *devc; struct clockselect_50 clockselect; - int frac, triggerpin, ret; - uint8_t triggerselect = 0; + int triggerpin, ret; + uint8_t triggerselect; struct triggerinout triggerinout_conf; struct triggerlut lut; - - if (sdi->status != SR_ST_ACTIVE) - return SR_ERR_DEV_CLOSED; + uint8_t regval; + uint8_t clock_bytes[sizeof(clockselect)]; + size_t clock_idx; devc = sdi->priv; @@ -303,8 +281,9 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) /* Enter trigger programming mode. */ sigma_set_register(WRITE_TRIGGER_SELECT1, 0x20, devc); - /* 100 and 200 MHz mode. */ + triggerselect = 0; if (devc->cur_samplerate >= SR_MHZ(100)) { + /* 100 and 200 MHz mode. */ sigma_set_register(WRITE_TRIGGER_SELECT1, 0x81, devc); /* Find which pin to trigger on from mask. */ @@ -320,8 +299,8 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) if (devc->trigger.fallingmask) triggerselect |= 1 << 3; - /* All other modes. */ } else if (devc->cur_samplerate <= SR_MHZ(50)) { + /* All other modes. */ sigma_build_basic_trigger(&lut, devc); sigma_write_trigger_lut(&lut, devc); @@ -342,37 +321,45 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) sigma_set_register(WRITE_TRIGGER_SELECT1, triggerselect, devc); /* Set clock select register. */ - if (devc->cur_samplerate == SR_MHZ(200)) + clockselect.async = 0; + clockselect.fraction = 1 - 1; /* Divider 1. */ + clockselect.disabled_channels = 0x0000; /* All channels enabled. */ + if (devc->cur_samplerate == SR_MHZ(200)) { /* Enable 4 channels. */ - sigma_set_register(WRITE_CLOCK_SELECT, 0xf0, devc); - else if (devc->cur_samplerate == SR_MHZ(100)) + clockselect.disabled_channels = 0xf0ff; + } else if (devc->cur_samplerate == SR_MHZ(100)) { /* Enable 8 channels. */ - sigma_set_register(WRITE_CLOCK_SELECT, 0x00, devc); - else { + clockselect.disabled_channels = 0x00ff; + } else { /* - * 50 MHz mode (or fraction thereof). Any fraction down to - * 50 MHz / 256 can be used, but is not supported by sigrok API. + * 50 MHz mode, or fraction thereof. The 50MHz reference + * can get divided by any integer in the range 1 to 256. + * Divider minus 1 gets written to the hardware. + * (The driver lists a discrete set of sample rates, but + * all of them fit the above description.) */ - frac = SR_MHZ(50) / devc->cur_samplerate - 1; - - clockselect.async = 0; - clockselect.fraction = frac; - clockselect.disabled_channels = 0; - - sigma_write_register(WRITE_CLOCK_SELECT, - (uint8_t *) &clockselect, - sizeof(clockselect), devc); + clockselect.fraction = SR_MHZ(50) / devc->cur_samplerate - 1; } + clock_idx = 0; + clock_bytes[clock_idx++] = clockselect.async; + clock_bytes[clock_idx++] = clockselect.fraction; + clock_bytes[clock_idx++] = clockselect.disabled_channels & 0xff; + clock_bytes[clock_idx++] = clockselect.disabled_channels >> 8; + sigma_write_register(WRITE_CLOCK_SELECT, clock_bytes, clock_idx, devc); /* Setup maximum post trigger time. */ sigma_set_register(WRITE_POST_TRIGGER, (devc->capture_ratio * 255) / 100, devc); /* Start acqusition. */ - gettimeofday(&devc->start_tv, 0); - sigma_set_register(WRITE_MODE, 0x0d, devc); - - std_session_send_df_header(sdi, LOG_PREFIX); + devc->start_time = g_get_monotonic_time(); + regval = WMR_TRGRES | WMR_SDRAMWRITEEN; +#if ASIX_SIGMA_WITH_TRIGGER + regval |= WMR_TRGEN; +#endif + sigma_set_register(WRITE_MODE, regval, devc); + + std_session_send_df_header(sdi); /* Add capture source. */ sr_session_source_add(sdi->session, -1, 0, 10, sigma_receive_data, (void *)sdi);