basic config options (WIP)

This commit is contained in:
Triss 2021-06-27 04:32:32 +02:00
parent 243b525727
commit 19a7aa375a
4 changed files with 112 additions and 45 deletions

1
.gitignore vendored
View File

@ -9,6 +9,7 @@
/m4/libtool.m4 /m4/libtool.m4
/m4/lt*.m4 /m4/lt*.m4
/build /build
/inst
# Editor/IDE cruft # Editor/IDE cruft
*.kate-swp *.kate-swp

View File

@ -36,26 +36,48 @@ static const uint32_t drvopts[] = {
}; };
static const uint32_t devopts[] = { 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_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
SR_CONF_CAPTURE_RATIO | SR_CONF_GET | SR_CONF_SET, 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_MSEC | SR_CONF_GET | SR_CONF_SET,
SR_CONF_LIMIT_SAMPLES | 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_VOLTAGE_THRESHOLD | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
//SR_CONF_DATALOG // TODO: ???? 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[] = { static const char *channel_names[] = {
@ -65,10 +87,22 @@ static const char *channel_names[] = {
static const uint64_t samplerates[] = { static const uint64_t samplerates[] = {
/* TODO: can this be an arbitrary value? at least the settings /* TODO: can this be an arbitrary value? at least the settings
* blob makes it look like it can */ * 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_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) 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) 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); 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) 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); 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; (void)options;
sr_err("scan");
if (!(ft = ftdi_new())) { if (!(ft = ftdi_new())) {
sr_err("Failed to initialize libftdi."); sr_err("Failed to initialize libftdi.");
return NULL; return NULL;
@ -228,8 +258,6 @@ static int dev_open(struct sr_dev_inst *sdi)
struct dev_context *dc; struct dev_context *dc;
int rv; int rv;
sr_err("open");
dc = sdi->priv; dc = sdi->priv;
if (!dc || !dc->ft) return SR_ERR_BUG; if (!dc || !dc->ft) return SR_ERR_BUG;
@ -273,23 +301,21 @@ static int dev_close(struct sr_dev_inst *sdi)
return SR_OK; 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, static int config_get(uint32_t key, GVariant **data,
const struct sr_dev_inst *sdi, const struct sr_channel_group *cg) const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
{ {
struct dev_context *dc; struct dev_context *dc;
double rnded;
int rv; int rv;
dc = sdi->priv; dc = sdi->priv;
(void)cg; (void)cg;
sr_err("get");
if (!dc) return SR_ERR_BUG; if (!dc) return SR_ERR_BUG;
rnded = (int)(dc->voltage.thresh * 10.0 / 39.2) * 0.1;
rv = SR_OK; rv = SR_OK;
switch (key) { switch (key) {
case SR_CONF_SAMPLERATE: case SR_CONF_SAMPLERATE:
@ -304,6 +330,15 @@ static int config_get(uint32_t key, GVariant **data,
case SR_CONF_CAPTURE_RATIO: case SR_CONF_CAPTURE_RATIO:
*data = g_variant_new_uint64(dc->capture_ratio); *data = g_variant_new_uint64(dc->capture_ratio);
break; 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: default:
sr_err("%s no conf key %u", __func__, key); sr_err("%s no conf key %u", __func__, key);
rv = SR_ERR_NA; 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) const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
{ {
struct dev_context *dc; struct dev_context *dc;
double volt, vlo, vhi;
int rv; int rv;
dc = sdi->priv; dc = sdi->priv;
(void)cg; (void)cg;
sr_err("set");
if (!dc) return SR_ERR_BUG; if (!dc) return SR_ERR_BUG;
if (key == SR_CONF_LOGIC_THRESHOLD_CUSTOM)
volt = g_variant_get_double(data);
rv = SR_OK; rv = SR_OK;
switch (key) { switch (key) {
case SR_CONF_SAMPLERATE: case SR_CONF_SAMPLERATE:
dc->samplerate = g_variant_get_uint64(data); dc->samplerate = g_variant_get_uint64(data);
break; break;
case SR_CONF_LIMIT_MSEC: 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)); dc->limit_samples = dc_msec_to_samples(dc, g_variant_get_uint64(data));
break; break;
case SR_CONF_LIMIT_SAMPLES: case SR_CONF_LIMIT_SAMPLES:
/*printf("samples = %lu\n", g_variant_get_uint64(data));*/
dc->limit_samples = g_variant_get_uint64(data); dc->limit_samples = g_variant_get_uint64(data);
break; break;
case SR_CONF_CAPTURE_RATIO: case SR_CONF_CAPTURE_RATIO:
/*printf("ratio = %lu\n", g_variant_get_uint64(data));*/
dc->capture_ratio = g_variant_get_uint64(data); dc->capture_ratio = g_variant_get_uint64(data);
break; 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: default:
sr_err("%s no conf key %u", __func__, key); sr_err("%s no conf key %u", __func__, key);
rv = SR_ERR_NA; rv = SR_ERR_NA;
@ -355,8 +410,6 @@ static int config_list(uint32_t key, GVariant **data,
{ {
int rv; int rv;
sr_err("list");
rv = SR_OK; rv = SR_OK;
switch (key) { switch (key) {
case SR_CONF_DEVICE_OPTIONS: case SR_CONF_DEVICE_OPTIONS:
@ -364,6 +417,12 @@ static int config_list(uint32_t key, GVariant **data,
case SR_CONF_SAMPLERATE: case SR_CONF_SAMPLERATE:
*data = std_gvar_samplerates(ARRAY_AND_SIZE(samplerates)); *data = std_gvar_samplerates(ARRAY_AND_SIZE(samplerates));
break; 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: default:
sr_err("%s no conf key %u", __func__, key); sr_err("%s no conf key %u", __func__, key);
rv = SR_ERR_NA; rv = SR_ERR_NA;
@ -380,8 +439,6 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
dc = sdi->priv; dc = sdi->priv;
sr_err("start");
if (!dc || !dc->ft) return SR_ERR_BUG; if (!dc || !dc->ft) return SR_ERR_BUG;
rv = scanaquad_acquisition_start(dc); 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 = { static struct sr_dev_driver ikalogic_scanaquad_driver_info = {
.name = "ikalogic-scanaquad", .name = "ikalogic-scanaquad",
.longname = "Ikalogic ScanaQuad", .longname = "IKALOGIC ScanaQuad",
.api_version = 1, .api_version = 1,
.init = std_init, .init = std_init,
.cleanup = std_cleanup, .cleanup = std_cleanup,

View File

@ -32,8 +32,10 @@ SR_PRIV struct dev_context *sq_new(struct ftdi_context *ft)
/* some sensible defaults */ /* some sensible defaults */
dc->samplerate = SR_MHZ(25); dc->samplerate = SR_MHZ(25);
dc->capture_ratio = 0; dc->capture_ratio = 10;
dc->voltage = 3.3f; dc->voltage.level = 0x81; /* 3.3v */
dc->voltage.thresh = 0x46; /* 1.8v (3.3v cmos thresh- */
dc->voltage_idx = 2; /* "3.3V" */
return dc; return dc;
} }
@ -575,21 +577,22 @@ SR_PRIV int scanaquad_apply_current_settings(struct dev_context *dc, gboolean pa
* * no triggers * * no triggers
* * set to capture mode(?) */ * * set to capture mode(?) */
uint64_t samplim;
uint32_t ms1, ms2, ms3; uint32_t ms1, ms2, ms3;
struct sq_app_settings sett; struct sq_app_settings sett;
/* clockfreq == 100000 / samplerate_kHz */ /* clockfreq == 100000 / samplerate_kHz */
sett.clockfreq = (uint16_t)((100000uLL*1000) / dc->samplerate); sett.clockfreq = (uint16_t)((100000uLL*1000) / dc->samplerate);
sett.voltage[0] = /*floorf(dc->voltage * 39.2f);*/0x81; sett.voltage[0] = dc->voltage.level;
sett.voltage[1] = passive ? 0x4b : 0x46; /* FIXME: 0x46: hardcoded for 3.3V */ sett.voltage[1] = passive ? 0x4b : dc->voltage.thresh;
sett.chanoutmap = 0x0f; /* TODO: hardcoded: all inputs */ sett.chanoutmap = 0x0f; /* TODO: hardcoded: all inputs */
/* TODO: limit_msec, limit_samples, capture_ratio */
/* TODO: more than just capture mode */ /* TODO: more than just capture mode */
ms1 = dc->memsize_max; samplim = dc->limit_samples / 4;
ms2 = dc->memsize_max; /* TODO: switch to override this check */
/* capture_ratio is currently fixed at 10%... */ ms1 = (samplim > dc->memsize_max) ? dc->memsize_max : samplim;
ms3 = (uint32_t)(dc->memsize_max * (1 - 0.10f)); 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[0] = (ms1>> 0) & 0xff;
sett.memsetting1[1] = (ms1>> 8) & 0xff; sett.memsetting1[1] = (ms1>> 8) & 0xff;

View File

@ -37,14 +37,20 @@
* https://git.lain.faith/BLAHAJ/sq50-re/wiki * https://git.lain.faith/BLAHAJ/sq50-re/wiki
*/ */
struct voltage_setting {
uint8_t level;
uint8_t thresh;
};
struct dev_context { struct dev_context {
struct ftdi_context *ft; struct ftdi_context *ft;
/* settings for next capture */ /* settings for next capture */
uint64_t samplerate; uint64_t samplerate;
uint64_t limit_samples; /* samples */ uint64_t limit_samples; /* samples */
uint64_t capture_ratio; /* 0..100? MAYBE? */ uint64_t capture_ratio; /* 0..100 */
float voltage; struct voltage_setting voltage;
int16_t voltage_idx;
uint32_t trig_instant; uint32_t trig_instant;