diff --git a/.gitignore b/.gitignore index c53d6607..05a0f9bc 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ /m4/libtool.m4 /m4/lt*.m4 /build +/inst # Editor/IDE cruft *.kate-swp diff --git a/src/hardware/ikalogic-scanaquad/api.c b/src/hardware/ikalogic-scanaquad/api.c index 9b0b954a..de2c9a38 100644 --- a/src/hardware/ikalogic-scanaquad/api.c +++ b/src/hardware/ikalogic-scanaquad/api.c @@ -36,26 +36,48 @@ static const uint32_t drvopts[] = { }; static const uint32_t devopts[] = { - // * pattern mode: how? - // * LIMIT_FRAMES vs LIMIT_SAMPLES? - // * VOLTAGE_THRESHSOLD vs LOGIC_THRESHOLD - // * VOLTAGE/VOLTAGE_TARGET: max? - // * triggers: TRIGGER_SLOPE vs TRIGGER_SOURCE vs TRIGGER_MATCH vs TRIGGER_LEVEL vs TRIGGER_PATTERN - // * TRIGGER_SLOPE: probably dV/dt thing? so not applicable here - // * OUTPUT_FREQUENCY used in PATTERN_MODE? - // * DATALOG: effect? - //SR_CONF_CONN | SR_CONF_GET, // TODO: ??? SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST, SR_CONF_CAPTURE_RATIO | SR_CONF_GET | SR_CONF_SET, - //SR_CONF_PATTERN_MODE | SR_CONF_GET | SR_CONF_SET, // TODO: idk how this works - //SR_CONF_BUFFERSIZE | SR_CONF_GET | SR_CONF_SET, // TODO: ??? - //SR_CONF_LOGIC_THRESHOLD | SR_CONFIG_GET | SR_CONFIG_SET | SR_CONFIG_LIST, // TODO: or VOLTAGE_THRESHOLD? - /* TODO: LOGIC_THRESHOLD_CUSTOM ? does the hw support this? */ - //SR_CONF_OUTPUT_FREQUENCY | SR_CONFIG_GET | SR_CONFIG_SET | SR_CONFIG_LIST, // TODO: is this used?? SR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET, SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET, - /*SR_CONF_LIMIT_FRAMES | SR_CONF_GET | SR_CONF_SET, "frame is a single capture" -> don't use */ - //SR_CONF_DATALOG // TODO: ???? + SR_CONF_VOLTAGE_THRESHOLD | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST, + SR_CONF_LOGIC_THRESHOLD | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST, + SR_CONF_LOGIC_THRESHOLD_CUSTOM | SR_CONF_GET | SR_CONF_SET, + + /* "frame is a single capture" -> don't use here, not applicable */ + /*SR_CONF_LIMIT_FRAMES | SR_CONF_GET | SR_CONF_SET,*/ + + /* + * TODO: + * * CAPTURE_RATIO: units?: int 0..100 + * * LIMIT_MSEC: units?: milliseconds + * * LIMIT_SAMPLES: units?: samples + * * SAMPLERATE: "overdrive" to 200 MHz on SQ50 possible??? yes! + * + * * VOLTAGE_THRESHOLD vs LOGIC_THRESHOLD? LOGIC_THRESHOLD_CUSTOM: ??? + * * VOLTAGE_THRESHOLD: 2 double values, custom selection? + * * LOGIC_THRESHOLD: selection of (max value) voltages + * * LOGIC_THRESHOLD_CUSTOM: custom ^ + * * see kingst-la2016/api.c + * * VOLTAGE, VOLTAGE_TARGET: ??? + * * not applicable here + * * except maybe VOLTAGE_TARGET is, for PATTERN_MODE? + * * BUFFERSIZE: ??? + * * DATALOG: ??? + * * PATTERN_MODE: ??? + * * string of a pattern name?? so uuuh, fuck (-> filename of blob to upload?) + * * OUTPUT_FREQUENCY: ??? (used in PATTERN_MODE instead of SAMPLERATE?) + * * not applicable here, for analog stuff only + * * CONN: ??? + * * if you need to specify eg. a serial port. not really applicable here + * (need to scan by vid:pid) + * + * * trigger stuff aaa (TRIGGER_SOURCE, TRIGGER_MATCH, TRIGGER_LEVEL, TRIGGER_PATTERN) + * * TRIGGER_SOURCE: probably not useful + * * TRIGGER_MATCH: on what can we match? (hi, lo, rise, fall) -> LIST only + * * TRIGGER_LEVEL: seems to be an analog thing, not applicable here + * * TRIGGER_PATTERN: freeform string + */ }; static const char *channel_names[] = { @@ -65,10 +87,22 @@ static const char *channel_names[] = { static const uint64_t samplerates[] = { /* TODO: can this be an arbitrary value? at least the settings * blob makes it look like it can */ + /* also, looks like the SQ50 can totally do 100 and 200 MHz... */ + SR_MHZ(200), SR_MHZ(100), SR_MHZ(50), SR_MHZ(25), SR_MHZ(10), SR_MHZ(5), SR_MHZ(1), SR_KHZ(500), SR_KHZ(250), SR_KHZ(100), SR_KHZ(50), SR_KHZ(10) }; +static const char *thresholds[] = { + "1.8V", // 0x46 0x1e | 1.8 0.8 ~44% + "2.8V", // 0x6e 0x2c | 2.8 1.1 ~40% + "3.3V", // 0x81 0x46 | 3.3 1.8 ~55% + "3.6V", // 0x8d 0x4f | 3.6 2.0 ~55% + "5V" , // 0xc4 0x72 | 5.0 2.9 ~58% + "5VTTL",// 0xc3 0x3b | 5.0 1.5 + "User" // VOLTAGE_THRESHOLD == LOGIC_THRESHOLD_CUSTOM (?) +}; + static uint64_t dc_samples_to_msec(struct dev_context *dc, uint64_t samples) { float msec_per_sample = 1.0f / ((float)dc->samplerate * 0.001f); @@ -84,8 +118,6 @@ static uint64_t dc_msec_to_samples(struct dev_context *dc, uint64_t msec) static int dev_clear(const struct sr_dev_driver *di) { - sr_err("clear"); - return std_dev_clear_with_callback(di, (std_dev_clear_callback)sq_destroy); } @@ -100,8 +132,6 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options) (void)options; - sr_err("scan"); - if (!(ft = ftdi_new())) { sr_err("Failed to initialize libftdi."); return NULL; @@ -228,8 +258,6 @@ static int dev_open(struct sr_dev_inst *sdi) struct dev_context *dc; int rv; - sr_err("open"); - dc = sdi->priv; if (!dc || !dc->ft) return SR_ERR_BUG; @@ -273,23 +301,21 @@ static int dev_close(struct sr_dev_inst *sdi) return SR_OK; } -/* FIXME: "Exception: invalid argument" when launching pulseview? - * maybe because of something in the config stuff?*/ - static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi, const struct sr_channel_group *cg) { struct dev_context *dc; + double rnded; int rv; dc = sdi->priv; (void)cg; - sr_err("get"); - if (!dc) return SR_ERR_BUG; + rnded = (int)(dc->voltage.thresh * 10.0 / 39.2) * 0.1; + rv = SR_OK; switch (key) { case SR_CONF_SAMPLERATE: @@ -304,6 +330,15 @@ static int config_get(uint32_t key, GVariant **data, case SR_CONF_CAPTURE_RATIO: *data = g_variant_new_uint64(dc->capture_ratio); break; + case SR_CONF_VOLTAGE_THRESHOLD: + *data = std_gvar_tuple_double(rnded, rnded + 0.1); + break; + case SR_CONF_LOGIC_THRESHOLD: + *data = g_variant_new_string(thresholds[dc->voltage_idx]); + break; + case SR_CONF_LOGIC_THRESHOLD_CUSTOM: + *data = g_variant_new_double(rnded); + break; default: sr_err("%s no conf key %u", __func__, key); rv = SR_ERR_NA; @@ -317,30 +352,50 @@ static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi, const struct sr_channel_group *cg) { struct dev_context *dc; + double volt, vlo, vhi; int rv; dc = sdi->priv; (void)cg; - sr_err("set"); - if (!dc) return SR_ERR_BUG; + if (key == SR_CONF_LOGIC_THRESHOLD_CUSTOM) + volt = g_variant_get_double(data); + rv = SR_OK; switch (key) { case SR_CONF_SAMPLERATE: dc->samplerate = g_variant_get_uint64(data); break; case SR_CONF_LIMIT_MSEC: + /*printf("msec = %lu\n", g_variant_get_uint64(data));*/ dc->limit_samples = dc_msec_to_samples(dc, g_variant_get_uint64(data)); break; case SR_CONF_LIMIT_SAMPLES: + /*printf("samples = %lu\n", g_variant_get_uint64(data));*/ dc->limit_samples = g_variant_get_uint64(data); break; case SR_CONF_CAPTURE_RATIO: + /*printf("ratio = %lu\n", g_variant_get_uint64(data));*/ dc->capture_ratio = g_variant_get_uint64(data); break; + case SR_CONF_VOLTAGE_THRESHOLD: + g_variant_get(data, "(dd)", &vlo, &vhi); + volt = 0.5 * (vlo + vhi); + /* fallthru! */ + case SR_CONF_LOGIC_THRESHOLD_CUSTOM: + /* in the LOGIC_THRESHOLD_CUSTOM case: see 'if' stmt before switch */ + dc->voltage_idx = 6; /* user */ + dc->voltage.thresh = (int)(volt * 39.2); + /* emulate vendor software values in a shitty way. not 100% exact but + * oh well. */ + dc->voltage.level = (dc->voltage.thresh < 0x30) + ? (int)(volt * 39.2 / 0.40) + : (int)(volt * 39.2 / 0.55); + /*printf("voltage: %02x %02x\n", dc->voltage.level, dc->voltage.thresh);*/ + break; default: sr_err("%s no conf key %u", __func__, key); rv = SR_ERR_NA; @@ -355,8 +410,6 @@ static int config_list(uint32_t key, GVariant **data, { int rv; - sr_err("list"); - rv = SR_OK; switch (key) { case SR_CONF_DEVICE_OPTIONS: @@ -364,6 +417,12 @@ static int config_list(uint32_t key, GVariant **data, case SR_CONF_SAMPLERATE: *data = std_gvar_samplerates(ARRAY_AND_SIZE(samplerates)); break; + case SR_CONF_VOLTAGE_THRESHOLD: + *data = std_gvar_min_max_step_thresholds(0.8, 2.9, 0.1); + break; + case SR_CONF_LOGIC_THRESHOLD: + *data = g_variant_new_strv(thresholds, ARRAY_SIZE(thresholds)); + break; default: sr_err("%s no conf key %u", __func__, key); rv = SR_ERR_NA; @@ -380,8 +439,6 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) dc = sdi->priv; - sr_err("start"); - if (!dc || !dc->ft) return SR_ERR_BUG; rv = scanaquad_acquisition_start(dc); @@ -413,7 +470,7 @@ static int dev_acquisition_stop(struct sr_dev_inst *sdi) static struct sr_dev_driver ikalogic_scanaquad_driver_info = { .name = "ikalogic-scanaquad", - .longname = "Ikalogic ScanaQuad", + .longname = "IKALOGIC ScanaQuad", .api_version = 1, .init = std_init, .cleanup = std_cleanup, diff --git a/src/hardware/ikalogic-scanaquad/protocol.c b/src/hardware/ikalogic-scanaquad/protocol.c index 6ee01abd..fc002106 100644 --- a/src/hardware/ikalogic-scanaquad/protocol.c +++ b/src/hardware/ikalogic-scanaquad/protocol.c @@ -32,8 +32,10 @@ SR_PRIV struct dev_context *sq_new(struct ftdi_context *ft) /* some sensible defaults */ dc->samplerate = SR_MHZ(25); - dc->capture_ratio = 0; - dc->voltage = 3.3f; + dc->capture_ratio = 10; + dc->voltage.level = 0x81; /* 3.3v */ + dc->voltage.thresh = 0x46; /* 1.8v (3.3v cmos thresh- */ + dc->voltage_idx = 2; /* "3.3V" */ return dc; } @@ -575,21 +577,22 @@ SR_PRIV int scanaquad_apply_current_settings(struct dev_context *dc, gboolean pa * * no triggers * * set to capture mode(?) */ + uint64_t samplim; uint32_t ms1, ms2, ms3; struct sq_app_settings sett; /* clockfreq == 100000 / samplerate_kHz */ sett.clockfreq = (uint16_t)((100000uLL*1000) / dc->samplerate); - sett.voltage[0] = /*floorf(dc->voltage * 39.2f);*/0x81; - sett.voltage[1] = passive ? 0x4b : 0x46; /* FIXME: 0x46: hardcoded for 3.3V */ + sett.voltage[0] = dc->voltage.level; + sett.voltage[1] = passive ? 0x4b : dc->voltage.thresh; sett.chanoutmap = 0x0f; /* TODO: hardcoded: all inputs */ - /* TODO: limit_msec, limit_samples, capture_ratio */ /* TODO: more than just capture mode */ - ms1 = dc->memsize_max; - ms2 = dc->memsize_max; - /* capture_ratio is currently fixed at 10%... */ - ms3 = (uint32_t)(dc->memsize_max * (1 - 0.10f)); + samplim = dc->limit_samples / 4; + /* TODO: switch to override this check */ + ms1 = (samplim > dc->memsize_max) ? dc->memsize_max : samplim; + ms2 = (samplim > dc->memsize_max) ? dc->memsize_max : samplim; + ms3 = (uint32_t)(dc->memsize_max * (1 - dc->capture_ratio * 0.01)); sett.memsetting1[0] = (ms1>> 0) & 0xff; sett.memsetting1[1] = (ms1>> 8) & 0xff; diff --git a/src/hardware/ikalogic-scanaquad/protocol.h b/src/hardware/ikalogic-scanaquad/protocol.h index 070865cf..a3f9fdff 100644 --- a/src/hardware/ikalogic-scanaquad/protocol.h +++ b/src/hardware/ikalogic-scanaquad/protocol.h @@ -37,14 +37,20 @@ * https://git.lain.faith/BLAHAJ/sq50-re/wiki */ +struct voltage_setting { + uint8_t level; + uint8_t thresh; +}; + struct dev_context { struct ftdi_context *ft; /* settings for next capture */ uint64_t samplerate; uint64_t limit_samples; /* samples */ - uint64_t capture_ratio; /* 0..100? MAYBE? */ - float voltage; + uint64_t capture_ratio; /* 0..100 */ + struct voltage_setting voltage; + int16_t voltage_idx; uint32_t trig_instant;