SR_PRIV int zp_set_samplerate(struct dev_context *devc, uint64_t samplerate) { int i; for (i = 0; ARRAY_SIZE(samplerates_200); i++) if (samplerate == samplerates_200[i]) break; if (i == ARRAY_SIZE(samplerates_200) || samplerate > devc->max_samplerate) { sr_err("Unsupported samplerate: %" PRIu64 "Hz.", samplerate); return SR_ERR_ARG; } sr_info("Setting samplerate to %" PRIu64 "Hz.", samplerate); if (samplerate >= SR_MHZ(1)) analyzer_set_freq(samplerate / SR_MHZ(1), FREQ_SCALE_MHZ); else if (samplerate >= SR_KHZ(1)) analyzer_set_freq(samplerate / SR_KHZ(1), FREQ_SCALE_KHZ); else analyzer_set_freq(samplerate, FREQ_SCALE_HZ); devc->cur_samplerate = samplerate; return SR_OK; }
END_TEST START_TEST(test_khz) { test_samplerate(1000, "1 kHz"); test_samplerate(99000, "99 kHz"); test_samplerate(225000, "225 kHz"); test_samplerate(1234, "1.234 kHz"); test_samplerate(12345, "12.345 kHz"); test_samplerate(123456, "123.456 kHz"); test_samplerate(1034, "1.034 kHz"); test_samplerate(1004, "1.004 kHz"); test_samplerate(1230, "1.23 kHz"); /* Again, but now using SR_KHZ(). */ test_samplerate(SR_KHZ(1), "1 kHz"); test_samplerate(SR_KHZ(99), "99 kHz"); test_samplerate(SR_KHZ(225), "225 kHz"); test_samplerate(SR_KHZ(1.234), "1.234 kHz"); test_samplerate(SR_KHZ(12.345), "12.345 kHz"); test_samplerate(SR_KHZ(123.456), "123.456 kHz"); test_samplerate(SR_KHZ(1.204), "1.204 kHz"); test_samplerate(SR_KHZ(1.034), "1.034 kHz"); test_samplerate(SR_KHZ(1.004), "1.004 kHz"); test_samplerate(SR_KHZ(1.230), "1.23 kHz"); }
static int set_samplerate(struct sr_dev_inst *sdi, uint64_t samplerate) { struct context *ctx; if (!sdi) { sr_err("zp: %s: sdi was NULL", __func__); return SR_ERR_ARG; } if (!(ctx = sdi->priv)) { sr_err("zp: %s: sdi->priv was NULL", __func__); return SR_ERR_ARG; } sr_info("zp: Setting samplerate to %" PRIu64 "Hz.", samplerate); if (samplerate > SR_MHZ(1)) analyzer_set_freq(samplerate / SR_MHZ(1), FREQ_SCALE_MHZ); else if (samplerate > SR_KHZ(1)) analyzer_set_freq(samplerate / SR_KHZ(1), FREQ_SCALE_KHZ); else analyzer_set_freq(samplerate, FREQ_SCALE_HZ); ctx->cur_samplerate = samplerate; return SR_OK; }
/** * Convert a "natural" string representation of a size value to uint64_t. * * E.g. a value of "3k" or "3 K" would be converted to 3000, a value * of "15M" would be converted to 15000000. * * Value representations other than decimal (such as hex or octal) are not * supported. Only 'k' (kilo), 'm' (mega), 'g' (giga) suffixes are supported. * Spaces (but not other whitespace) between value and suffix are allowed. * * @param sizestring A string containing a (decimal) size value. * @param size Pointer to uint64_t which will contain the string's size value. * * @return SR_OK upon success, SR_ERR upon errors. * * @since 0.1.0 */ SR_API int sr_parse_sizestring(const char *sizestring, uint64_t *size) { uint64_t multiplier; int done; double frac_part; char *s; *size = strtoull(sizestring, &s, 10); multiplier = 0; frac_part = 0; done = FALSE; while (s && *s && multiplier == 0 && !done) { switch (*s) { case ' ': break; case '.': frac_part = g_ascii_strtod(s, &s); break; case 'k': case 'K': multiplier = SR_KHZ(1); break; case 'm': case 'M': multiplier = SR_MHZ(1); break; case 'g': case 'G': multiplier = SR_GHZ(1); break; case 't': case 'T': multiplier = SR_GHZ(1000); break; case 'p': case 'P': multiplier = SR_GHZ(1000 * 1000); break; case 'e': case 'E': multiplier = SR_GHZ(1000 * 1000 * 1000); break; default: done = TRUE; s--; } s++; } if (multiplier > 0) { *size *= multiplier; *size += frac_part * multiplier; } else { *size += frac_part; } if (s && *s && g_ascii_strcasecmp(s, "Hz")) return SR_ERR; return SR_OK; }
/** * Convert a numeric value value to its "natural" string representation * in SI units. * * E.g. a value of 3000000, with units set to "W", would be converted * to "3 MW", 20000 to "20 kW", 31500 would become "31.5 kW". * * @param x The value to convert. * @param unit The unit to append to the string, or NULL if the string * has no units. * * @return A newly allocated string representation of the samplerate value, * or NULL upon errors. The caller is responsible to g_free() the * memory. * * @since 0.2.0 */ SR_API char *sr_si_string_u64(uint64_t x, const char *unit) { uint8_t i; uint64_t quot, divisor[] = { SR_HZ(1), SR_KHZ(1), SR_MHZ(1), SR_GHZ(1), SR_GHZ(1000), SR_GHZ(1000 * 1000), SR_GHZ(1000 * 1000 * 1000), }; const char *p, prefix[] = "\0kMGTPE"; char fmt[16], fract[20] = "", *f; if (!unit) unit = ""; for (i = 0; (quot = x / divisor[i]) >= 1000; i++); if (i) { sprintf(fmt, ".%%0%d"PRIu64, i * 3); f = fract + sprintf(fract, fmt, x % divisor[i]) - 1; while (f >= fract && strchr("0.", *f)) *f-- = 0; } p = prefix + i; return g_strdup_printf("%" PRIu64 "%s %.1s%s", quot, fract, p, unit); }
/** * Convert a numeric frequency value to the "natural" string representation * of its period. * * E.g. a value of 3000000 would be converted to "3 us", 20000 to "50 ms". * * @param frequency The frequency in Hz. * * @return A newly allocated string representation of the frequency value, * or NULL upon errors. The caller is responsible to g_free() the * memory. * * @since 0.1.0 */ SR_API char *sr_period_string(uint64_t frequency) { char *o; int r; /* Allocate enough for a uint64_t as string + " ms". */ o = g_malloc0(30 + 1); if (frequency >= SR_GHZ(1)) r = snprintf(o, 30, "%" PRIu64 " ns", frequency / 1000000000); else if (frequency >= SR_MHZ(1)) r = snprintf(o, 30, "%" PRIu64 " us", frequency / 1000000); else if (frequency >= SR_KHZ(1)) r = snprintf(o, 30, "%" PRIu64 " ms", frequency / 1000); else r = snprintf(o, 30, "%" PRIu64 " s", frequency); if (r < 0) { /* Something went wrong... */ g_free(o); return NULL; } return o; }
/** * Convert a numeric period value to the "natural" string representation * of its period value. * * The period is specified as a rational number's numerator and denominator. * * E.g. a pair of (1, 5) would be converted to "200 ms", (10, 100) to "100 ms". * * @param v_p The period numerator. * @param v_q The period denominator. * * @return A newly allocated string representation of the period value, * or NULL upon errors. The caller is responsible to g_free() the * memory. * * @since 0.5.0 */ SR_API char *sr_period_string(uint64_t v_p, uint64_t v_q) { double freq, v; int prec; freq = 1 / ((double)v_p / v_q); if (freq > SR_GHZ(1)) { v = (double)v_p / v_q * 1000000000000.0; prec = ((v - (uint64_t)v) < FLT_MIN) ? 0 : 3; return g_strdup_printf("%.*f ps", prec, v); } else if (freq > SR_MHZ(1)) { v = (double)v_p / v_q * 1000000000.0; prec = ((v - (uint64_t)v) < FLT_MIN) ? 0 : 3; return g_strdup_printf("%.*f ns", prec, v); } else if (freq > SR_KHZ(1)) { v = (double)v_p / v_q * 1000000.0; prec = ((v - (uint64_t)v) < FLT_MIN) ? 0 : 3; return g_strdup_printf("%.*f us", prec, v); } else if (freq > 1) { v = (double)v_p / v_q * 1000.0; prec = ((v - (uint64_t)v) < FLT_MIN) ? 0 : 3; return g_strdup_printf("%.*f ms", prec, v); } else { v = (double)v_p / v_q; prec = ((v - (uint64_t)v) < FLT_MIN) ? 0 : 3; return g_strdup_printf("%.*f s", prec, v); } }
/** * Convert a numeric value value to its "natural" string representation. * in SI units * * E.g. a value of 3000000, with units set to "W", would be converted * to "3 MW", 20000 to "20 kW", 31500 would become "31.5 kW". * * @param x The value to convert. * @param unit The unit to append to the string, or NULL if the string * has no units. * * @return A g_try_malloc()ed string representation of the samplerate value, * or NULL upon errors. The caller is responsible to g_free() the * memory. */ SR_API char *sr_si_string_u64(uint64_t x, const char *unit) { if (unit == NULL) unit = ""; if ((x >= SR_GHZ(1)) && (x % SR_GHZ(1) == 0)) { return g_strdup_printf("%" PRIu64 " G%s", x / SR_GHZ(1), unit); } else if ((x >= SR_GHZ(1)) && (x % SR_GHZ(1) != 0)) { return g_strdup_printf("%" PRIu64 ".%" PRIu64 " G%s", x / SR_GHZ(1), x % SR_GHZ(1), unit); } else if ((x >= SR_MHZ(1)) && (x % SR_MHZ(1) == 0)) { return g_strdup_printf("%" PRIu64 " M%s", x / SR_MHZ(1), unit); } else if ((x >= SR_MHZ(1)) && (x % SR_MHZ(1) != 0)) { return g_strdup_printf("%" PRIu64 ".%" PRIu64 " M%s", x / SR_MHZ(1), x % SR_MHZ(1), unit); } else if ((x >= SR_KHZ(1)) && (x % SR_KHZ(1) == 0)) { return g_strdup_printf("%" PRIu64 " k%s", x / SR_KHZ(1), unit); } else if ((x >= SR_KHZ(1)) && (x % SR_KHZ(1) != 0)) { return g_strdup_printf("%" PRIu64 ".%" PRIu64 " K%s", x / SR_KHZ(1), x % SR_KHZ(1), unit); } else { return g_strdup_printf("%" PRIu64 " %s", x, unit); } sr_err("%s: Error creating SI units string.", __func__); return NULL; }
static GSList *scan(GSList *options) { struct sr_dev_inst *sdi; struct sr_probe *probe; struct drv_context *drvc; struct dev_context *devc; GSList *devices; int i; (void)options; drvc = di->priv; devices = NULL; sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, DEMONAME, NULL, NULL); if (!sdi) { sr_err("Device instance creation failed."); return NULL; } sdi->driver = di; for (i = 0; probe_names[i]; i++) { if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, probe_names[i]))) return NULL; sdi->probes = g_slist_append(sdi->probes, probe); } devices = g_slist_append(devices, sdi); drvc->instances = g_slist_append(drvc->instances, sdi); if (!(devc = g_try_malloc(sizeof(struct dev_context)))) { sr_err("Device context malloc failed."); return NULL; } devc->sdi = sdi; devc->cur_samplerate = SR_KHZ(200); devc->limit_samples = 0; devc->limit_msec = 0; devc->sample_generator = PATTERN_SIGROK; sdi->priv = devc; return devices; }
END_TEST /* * Check whether setting a samplerate works. * * Additionally, this also checks whether SR_CONF_SAMPLERATE can be both * set and read back properly. */ #if 0 START_TEST(test_config_get_set_samplerate) { /* * Note: This currently only works for the demo driver. * For other drivers, a scan is needed and the respective * hardware must be attached to the host running the testsuite. */ srtest_check_samplerate(sr_ctx, "demo", SR_KHZ(19)); }
/** * Convert a "natural" string representation of a size value to uint64_t. * * E.g. a value of "3k" or "3 K" would be converted to 3000, a value * of "15M" would be converted to 15000000. * * Value representations other than decimal (such as hex or octal) are not * supported. Only 'k' (kilo), 'm' (mega), 'g' (giga) suffixes are supported. * Spaces (but not other whitespace) between value and suffix are allowed. * * @param sizestring A string containing a (decimal) size value. * @param size Pointer to uint64_t which will contain the string's size value. * * @return SR_OK upon success, SR_ERR upon errors. */ SR_API int sr_parse_sizestring(const char *sizestring, uint64_t *size) { int multiplier, done; char *s; *size = strtoull(sizestring, &s, 10); multiplier = 0; done = FALSE; while (s && *s && multiplier == 0 && !done) { switch (*s) { case ' ': break; case 'k': case 'K': multiplier = SR_KHZ(1); break; case 'm': case 'M': multiplier = SR_MHZ(1); break; case 'g': case 'G': multiplier = SR_GHZ(1); break; default: done = TRUE; s--; } s++; } if (multiplier > 0) *size *= multiplier; if (*s && strcasecmp(s, "Hz")) return SR_ERR; return SR_OK; }
"D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", NULL, }; SR_PRIV struct sr_dev_driver zeroplus_logic_cube_driver_info; static struct sr_dev_driver *di = &zeroplus_logic_cube_driver_info; /* * The hardware supports more samplerates than these, but these are the * options hardcoded into the vendor's Windows GUI. */ static const uint64_t samplerates_100[] = { SR_HZ(100), SR_HZ(500), SR_KHZ(1), SR_KHZ(5), SR_KHZ(25), SR_KHZ(50), SR_KHZ(100), SR_KHZ(200), SR_KHZ(400), SR_KHZ(800), SR_MHZ(1), SR_MHZ(10), SR_MHZ(25), SR_MHZ(50), SR_MHZ(80), SR_MHZ(100), };
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; struct triggerinout triggerinout_conf; struct triggerlut lut; if (sdi->status != SR_ST_ACTIVE) return SR_ERR_DEV_CLOSED; devc = sdi->priv; if (sigma_convert_trigger(sdi) != SR_OK) { sr_err("Failed to configure triggers."); return SR_ERR; } /* If the samplerate has not been set, default to 200 kHz. */ if (devc->cur_firmware == -1) { if ((ret = sigma_set_samplerate(sdi, SR_KHZ(200))) != SR_OK) return ret; } /* Enter trigger programming mode. */ sigma_set_register(WRITE_TRIGGER_SELECT1, 0x20, devc); /* 100 and 200 MHz mode. */ if (devc->cur_samplerate >= SR_MHZ(100)) { sigma_set_register(WRITE_TRIGGER_SELECT1, 0x81, devc); /* Find which pin to trigger on from mask. */ for (triggerpin = 0; triggerpin < 8; triggerpin++) if ((devc->trigger.risingmask | devc->trigger.fallingmask) & (1 << triggerpin)) break; /* Set trigger pin and light LED on trigger. */ triggerselect = (1 << LEDSEL1) | (triggerpin & 0x7); /* Default rising edge. */ if (devc->trigger.fallingmask) triggerselect |= 1 << 3; /* All other modes. */ } else if (devc->cur_samplerate <= SR_MHZ(50)) { sigma_build_basic_trigger(&lut, devc); sigma_write_trigger_lut(&lut, devc); triggerselect = (1 << LEDSEL1) | (1 << LEDSEL0); } /* Setup trigger in and out pins to default values. */ memset(&triggerinout_conf, 0, sizeof(struct triggerinout)); triggerinout_conf.trgout_bytrigger = 1; triggerinout_conf.trgout_enable = 1; sigma_write_register(WRITE_TRIGGER_OPTION, (uint8_t *) &triggerinout_conf, sizeof(struct triggerinout), devc); /* Go back to normal mode. */ sigma_set_register(WRITE_TRIGGER_SELECT1, triggerselect, devc); /* Set clock select register. */ 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)) /* Enable 8 channels. */ sigma_set_register(WRITE_CLOCK_SELECT, 0x00, devc); else { /* * 50 MHz mode (or fraction thereof). Any fraction down to * 50 MHz / 256 can be used, but is not supported by sigrok API. */ 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); } /* 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); /* Add capture source. */ sr_session_source_add(sdi->session, -1, 0, 10, sigma_receive_data, (void *)sdi); devc->state.state = SIGMA_CAPTURE; return SR_OK; }
static const char *channel_names[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", }; static const struct { enum voltage_range range; gdouble low; gdouble high; } volt_thresholds[] = { { VOLTAGE_RANGE_18_33_V, 0.7, 1.4 }, { VOLTAGE_RANGE_5_V, 1.4, 3.6 }, }; static const uint64_t samplerates[] = { SR_KHZ(500), SR_MHZ(1), SR_MHZ(2), SR_MHZ(4), SR_MHZ(5), SR_MHZ(8), SR_MHZ(10), SR_KHZ(12500), SR_MHZ(16), SR_MHZ(25), SR_MHZ(32), SR_MHZ(40), SR_MHZ(80), SR_MHZ(100), };
static GSList *scan(GSList *options) { struct drv_context *drvc; struct dev_context *devc; struct sr_dev_inst *sdi; struct sr_channel *ch; struct sr_channel_group *cg; struct sr_config *src; struct analog_gen *ag; GSList *devices, *l; int num_logic_channels, num_analog_channels, pattern, i; char channel_name[16]; drvc = di->priv; num_logic_channels = DEFAULT_NUM_LOGIC_CHANNELS; num_analog_channels = DEFAULT_NUM_ANALOG_CHANNELS; for (l = options; l; l = l->next) { src = l->data; switch (src->key) { case SR_CONF_NUM_LOGIC_CHANNELS: num_logic_channels = g_variant_get_int32(src->data); break; case SR_CONF_NUM_ANALOG_CHANNELS: num_analog_channels = g_variant_get_int32(src->data); break; } } devices = NULL; sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, "Demo device", NULL, NULL); if (!sdi) { sr_err("Device instance creation failed."); return NULL; } sdi->driver = di; if (!(devc = g_try_malloc(sizeof(struct dev_context)))) { sr_err("Device context malloc failed."); return NULL; } devc->cur_samplerate = SR_KHZ(200); devc->limit_samples = 0; devc->limit_msec = 0; devc->step = 0; devc->num_logic_channels = num_logic_channels; devc->logic_unitsize = (devc->num_logic_channels + 7) / 8; devc->logic_pattern = PATTERN_SIGROK; devc->num_analog_channels = num_analog_channels; devc->analog_channel_groups = NULL; /* Logic channels, all in one channel group. */ if (!(cg = g_try_malloc(sizeof(struct sr_channel_group)))) return NULL; cg->name = g_strdup("Logic"); cg->channels = NULL; cg->priv = NULL; for (i = 0; i < num_logic_channels; i++) { sprintf(channel_name, "D%d", i); if (!(ch = sr_channel_new(i, SR_CHANNEL_LOGIC, TRUE, channel_name))) return NULL; sdi->channels = g_slist_append(sdi->channels, ch); cg->channels = g_slist_append(cg->channels, ch); } sdi->channel_groups = g_slist_append(NULL, cg); /* Analog channels, channel groups and pattern generators. */ pattern = 0; for (i = 0; i < num_analog_channels; i++) { sprintf(channel_name, "A%d", i); if (!(ch = sr_channel_new(i + num_logic_channels, SR_CHANNEL_ANALOG, TRUE, channel_name))) return NULL; sdi->channels = g_slist_append(sdi->channels, ch); /* Every analog channel gets its own channel group. */ if (!(cg = g_try_malloc(sizeof(struct sr_channel_group)))) return NULL; cg->name = g_strdup(channel_name); cg->channels = g_slist_append(NULL, ch); /* Every channel group gets a generator struct. */ if (!(ag = g_try_malloc(sizeof(struct analog_gen)))) return NULL; ag->packet.channels = cg->channels; ag->packet.mq = 0; ag->packet.mqflags = 0; ag->packet.unit = SR_UNIT_VOLT; ag->packet.data = ag->pattern_data; ag->pattern = pattern; cg->priv = ag; sdi->channel_groups = g_slist_append(sdi->channel_groups, cg); devc->analog_channel_groups = g_slist_append(devc->analog_channel_groups, cg); if (++pattern == ARRAY_SIZE(analog_pattern_str)) pattern = 0; } sdi->priv = devc; devices = g_slist_append(devices, sdi); drvc->instances = g_slist_append(drvc->instances, sdi); return devices; }
SR_CONF_LIMIT_FRAMES | SR_CONF_GET | SR_CONF_SET, SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST, SR_CONF_TRIGGER_SOURCE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST, SR_CONF_TRIGGER_SLOPE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST, SR_CONF_BUFFERSIZE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST, }; static const uint32_t cgopts[] = { SR_CONF_VDIV | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST, SR_CONF_COUPLING | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST, SR_CONF_PROBE_FACTOR | SR_CONF_GET | SR_CONF_SET, }; static const uint64_t samplerates[] = { SR_MHZ(100), SR_MHZ(50), SR_MHZ(25), SR_MHZ(20), SR_MHZ(10), SR_MHZ(5), SR_KHZ(2500), SR_MHZ(2), SR_MHZ(1), SR_KHZ(500), SR_KHZ(250), SR_KHZ(200), SR_KHZ(100), SR_KHZ(50), SR_KHZ(25), SR_KHZ(20), SR_KHZ(10), SR_KHZ(5), SR_HZ(2500), SR_KHZ(2), SR_KHZ(1), SR_HZ(500), SR_HZ(250), SR_HZ(200), SR_HZ(100), SR_HZ(50), SR_HZ(25), SR_HZ(20) }; /* must be in sync with readout_steps[] in protocol.c */ static const uint64_t buffersizes[] = { 2 * 500, 3 * 500, 4 * 500, 5 * 500, 6 * 500, 7 * 500, 8 * 500, 9 * 500, 10 * 500, 12 * 500 - 2, 14 * 500 - 2, 16 * 500 - 2, 18 * 500 - 2, 20 * 500 - 2, 10240 - 2 };
SR_CONF_CAPTURE_RATIO | SR_CONF_GET | SR_CONF_SET, SR_CONF_TRIGGER_MATCH | SR_CONF_LIST, }; static const int32_t trigger_matches[] = { SR_TRIGGER_ZERO, SR_TRIGGER_ONE, SR_TRIGGER_RISING, SR_TRIGGER_FALLING, SR_TRIGGER_EDGE, }; static const uint64_t samplerates[] = { SR_HZ(1000), SR_HZ(2500), SR_KHZ(5), SR_KHZ(10), SR_KHZ(25), SR_KHZ(50), SR_KHZ(100), SR_KHZ(250), SR_KHZ(500), SR_KHZ(1000), SR_KHZ(2500), SR_MHZ(5), SR_MHZ(10), SR_MHZ(25), SR_MHZ(50), SR_MHZ(100), SR_MHZ(250), SR_MHZ(500),
SR_CONF_CONN | SR_CONF_GET, SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST, SR_CONF_TRIGGER_MATCH | SR_CONF_LIST, SR_CONF_CAPTURE_RATIO | SR_CONF_GET | SR_CONF_SET, }; static const int32_t trigger_matches[] = { SR_TRIGGER_ZERO, SR_TRIGGER_ONE, SR_TRIGGER_RISING, SR_TRIGGER_FALLING, SR_TRIGGER_EDGE, }; static const uint64_t samplerates[] = { SR_KHZ(20), SR_KHZ(25), SR_KHZ(50), SR_KHZ(100), SR_KHZ(200), SR_KHZ(250), SR_KHZ(500), SR_MHZ(1), SR_MHZ(2), SR_MHZ(3), SR_MHZ(4), SR_MHZ(6), SR_MHZ(8), SR_MHZ(12), SR_MHZ(16), SR_MHZ(24),
}; static uint8_t pattern_sigrok[] = { 0x4c, 0x92, 0x92, 0x92, 0x64, 0x00, 0x00, 0x00, 0x82, 0xfe, 0xfe, 0x82, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x82, 0x82, 0x92, 0x74, 0x00, 0x00, 0x00, 0xfe, 0x12, 0x12, 0x32, 0xcc, 0x00, 0x00, 0x00, 0x7c, 0x82, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0xfe, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; /* List of struct sr_device_instance, maintained by opendev()/closedev(). */ static GSList *device_instances = NULL; static uint64_t cur_samplerate = SR_KHZ(200); static uint64_t period_ps = 5000000; static uint64_t limit_samples = 0; static uint64_t limit_msec = 0; static int default_pattern = PATTERN_SIGROK; static GThread *my_thread; static int thread_running; static void hw_stop_acquisition(int device_index, gpointer session_data); static int hw_init(const char *deviceinfo) { struct sr_device_instance *sdi; /* Avoid compiler warnings. */ (void)deviceinfo;
{ 0x04b4, 0x8613, 0x0925, 0x3881, "Cypress", "FX2", NULL, 16 }, { 0, 0, 0, 0, 0, 0, 0, 0 } }; static int capabilities[] = { SR_HWCAP_LOGIC_ANALYZER, SR_HWCAP_SAMPLERATE, /* These are really implemented in the driver, not the hardware. */ SR_HWCAP_LIMIT_SAMPLES, SR_HWCAP_CONTINUOUS, 0, }; static uint64_t supported_samplerates[] = { SR_KHZ(200), SR_KHZ(250), SR_KHZ(500), SR_MHZ(1), SR_MHZ(2), SR_MHZ(4), SR_MHZ(8), SR_MHZ(12), SR_MHZ(16), SR_MHZ(24), 0, }; static struct sr_samplerates samplerates = { SR_KHZ(200), SR_MHZ(24),
-49, -46, 36, 16, 29, 23, -30, -3, 28, -2, -6, 46, 43, 50, -42, 30, 48, -50, -38, -30, 7, -36, -20, -24, -10, -34, -24, 3, -48, 46, -11, 22, 19, 28, 39, -49, -31, 34, 2, -29, 9, 35, 8, 10, 38, 30, 17, 48, -3, -6, -28, 46, -19, 18, -43, -9, -31, -32, -41, 16, -10, 46, -4, 4, -32, -43, -45, -39, -33, 28, 24, -17, -43, 42, -7, 36, -44, -5, 9, 39, 17, -40, 12, 16, -42, -1, 2, -9, 50, -8, 27, 27, 14, 8, -18, 12, -8, 26, -8, 12, -35, 49, 35, 2, -26, -24, -31, 33, 15, -47, 34, 46, -1, -12, 14, 32, -25, -31, -35, -18, -48, -21, -5, 1, -27, -14, 12, 49, -11, 33, 31, 35, -36, 19, 20, 44, 29, -48, 14, -43, 1, 30, -12, 44, 20, 49, 29, -43, 42, 30, -34, 24, 20, -40, 33, -12, 13, -45, 45, -24, -41, 36, -8, 46, 47, -34, 28, -39, 7, -32, 38, -27, 28, -3, -8, 43, -37, -24, 6, 3, }; static const uint64_t samplerates[] = { SR_HZ(100), SR_HZ(200), SR_HZ(500), SR_KHZ(1), SR_KHZ(2), SR_KHZ(5), SR_KHZ(10), SR_KHZ(20), SR_KHZ(50), SR_KHZ(100), SR_KHZ(200), SR_KHZ(500), SR_MHZ(1), SR_MHZ(2), SR_MHZ(5), SR_MHZ(10), SR_MHZ(20), SR_MHZ(50), SR_MHZ(100),
static GSList *scan(struct sr_dev_driver *di, GSList *options) { struct dev_context *devc; struct sr_dev_inst *sdi; struct sr_channel *ch; struct sr_channel_group *cg, *acg; struct sr_config *src; struct analog_gen *ag; GSList *l; int num_logic_channels, num_analog_channels, pattern, i; char channel_name[16]; num_logic_channels = DEFAULT_NUM_LOGIC_CHANNELS; num_analog_channels = DEFAULT_NUM_ANALOG_CHANNELS; for (l = options; l; l = l->next) { src = l->data; switch (src->key) { case SR_CONF_NUM_LOGIC_CHANNELS: num_logic_channels = g_variant_get_int32(src->data); break; case SR_CONF_NUM_ANALOG_CHANNELS: num_analog_channels = g_variant_get_int32(src->data); break; } } sdi = g_malloc0(sizeof(struct sr_dev_inst)); sdi->status = SR_ST_INACTIVE; sdi->model = g_strdup("Demo device"); devc = g_malloc0(sizeof(struct dev_context)); devc->cur_samplerate = SR_KHZ(200); devc->num_logic_channels = num_logic_channels; devc->logic_unitsize = (devc->num_logic_channels + 7) / 8; devc->logic_pattern = PATTERN_SIGROK; devc->num_analog_channels = num_analog_channels; if (num_logic_channels > 0) { /* Logic channels, all in one channel group. */ cg = g_malloc0(sizeof(struct sr_channel_group)); cg->name = g_strdup("Logic"); for (i = 0; i < num_logic_channels; i++) { sprintf(channel_name, "D%d", i); ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE, channel_name); cg->channels = g_slist_append(cg->channels, ch); } sdi->channel_groups = g_slist_append(NULL, cg); } /* Analog channels, channel groups and pattern generators. */ if (num_analog_channels > 0) { pattern = 0; /* An "Analog" channel group with all analog channels in it. */ acg = g_malloc0(sizeof(struct sr_channel_group)); acg->name = g_strdup("Analog"); sdi->channel_groups = g_slist_append(sdi->channel_groups, acg); devc->ch_ag = g_hash_table_new(g_direct_hash, g_direct_equal); for (i = 0; i < num_analog_channels; i++) { snprintf(channel_name, 16, "A%d", i); ch = sr_channel_new(sdi, i + num_logic_channels, SR_CHANNEL_ANALOG, TRUE, channel_name); acg->channels = g_slist_append(acg->channels, ch); /* Every analog channel gets its own channel group as well. */ cg = g_malloc0(sizeof(struct sr_channel_group)); cg->name = g_strdup(channel_name); cg->channels = g_slist_append(NULL, ch); sdi->channel_groups = g_slist_append(sdi->channel_groups, cg); /* Every channel gets a generator struct. */ ag = g_malloc(sizeof(struct analog_gen)); ag->amplitude = DEFAULT_ANALOG_AMPLITUDE; sr_analog_init(&ag->packet, &ag->encoding, &ag->meaning, &ag->spec, 2); ag->packet.meaning->channels = cg->channels; ag->packet.meaning->mq = 0; ag->packet.meaning->mqflags = 0; ag->packet.meaning->unit = SR_UNIT_VOLT; ag->packet.data = ag->pattern_data; ag->pattern = pattern; ag->avg_val = 0.0f; ag->num_avgs = 0; g_hash_table_insert(devc->ch_ag, ch, ag); if (++pattern == ARRAY_SIZE(analog_pattern_str)) pattern = 0; } } sdi->priv = devc; return std_scan_complete(di, g_slist_append(NULL, sdi)); }