#include "protocol.h"
/*
- * The ASIX Sigma supports arbitrary integer frequency divider in
- * the 50MHz mode. The divider is in range 1...256 , allowing for
- * very precise sampling rate selection. This driver supports only
- * a subset of the sampling rates.
+ * The ASIX SIGMA hardware supports fixed 200MHz and 100MHz sample rates
+ * (by means of separate firmware images). As well as 50MHz divided by
+ * an integer divider in the 1..256 range (by the "typical" firmware).
+ * Which translates to a strict lower boundary of around 195kHz.
+ *
+ * This driver "suggests" a subset of the available rates by listing a
+ * few discrete values, while setter routines accept any user specified
+ * rate that is supported by the hardware.
*/
SR_PRIV const uint64_t samplerates[] = {
- SR_KHZ(200), /* div=250 */
- SR_KHZ(250), /* div=200 */
- SR_KHZ(500), /* div=100 */
- SR_MHZ(1), /* div=50 */
- SR_MHZ(5), /* div=10 */
- SR_MHZ(10), /* div=5 */
- SR_MHZ(25), /* div=2 */
- SR_MHZ(50), /* div=1 */
- SR_MHZ(100), /* Special FW needed */
- SR_MHZ(200), /* Special FW needed */
+ /* 50MHz and integer divider. 1/2/5 steps (where possible). */
+ SR_KHZ(200), SR_KHZ(500),
+ SR_MHZ(1), SR_MHZ(2), SR_MHZ(5),
+ SR_MHZ(10), SR_MHZ(25), SR_MHZ(50),
+ /* 100MHz/200MHz, fixed rates in special firmware. */
+ SR_MHZ(100), SR_MHZ(200),
};
SR_PRIV const size_t samplerates_count = ARRAY_SIZE(samplerates);
static const char *firmware_files[] = {
- "asix-sigma-50.fw", /* Up to 50MHz sample rate, 8bit divider. */
- "asix-sigma-100.fw", /* 100MHz sample rate, fixed. */
- "asix-sigma-200.fw", /* 200MHz sample rate, fixed. */
- "asix-sigma-50sync.fw", /* Synchronous clock from external pin. */
- "asix-sigma-phasor.fw", /* Frequency counter. */
+ [SIGMA_FW_50MHZ] = "asix-sigma-50.fw", /* 50MHz, 8bit divider. */
+ [SIGMA_FW_100MHZ] = "asix-sigma-100.fw", /* 100MHz, fixed. */
+ [SIGMA_FW_200MHZ] = "asix-sigma-200.fw", /* 200MHz, fixed. */
+ [SIGMA_FW_SYNC] = "asix-sigma-50sync.fw", /* Sync from external pin. */
+ [SIGMA_FW_FREQ] = "asix-sigma-phasor.fw", /* Frequency counter. */
};
#define SIGMA_FIRMWARE_SIZE_LIMIT (256 * 1024)
-static int sigma_read(void *buf, size_t size, struct dev_context *devc)
+static int sigma_read(struct dev_context *devc, void *buf, size_t size)
{
int ret;
ret = ftdi_read_data(&devc->ftdic, (unsigned char *)buf, size);
if (ret < 0) {
sr_err("ftdi_read_data failed: %s",
- ftdi_get_error_string(&devc->ftdic));
+ ftdi_get_error_string(&devc->ftdic));
}
return ret;
}
-static int sigma_write(void *buf, size_t size, struct dev_context *devc)
+static int sigma_write(struct dev_context *devc, void *buf, size_t size)
{
int ret;
ret = ftdi_write_data(&devc->ftdic, (unsigned char *)buf, size);
if (ret < 0)
sr_err("ftdi_write_data failed: %s",
- ftdi_get_error_string(&devc->ftdic));
+ ftdi_get_error_string(&devc->ftdic));
else if ((size_t) ret != size)
sr_err("ftdi_write_data did not complete write.");
* NOTE: We chose the buffer size to be large enough to hold any write to the
* device. We still print a message just in case.
*/
-SR_PRIV int sigma_write_register(uint8_t reg, uint8_t *data, size_t len,
- struct dev_context *devc)
+SR_PRIV int sigma_write_register(struct dev_context *devc,
+ uint8_t reg, uint8_t *data, size_t len)
{
size_t i;
uint8_t buf[80];
int idx = 0;
if ((2 * len + 2) > sizeof(buf)) {
- sr_err("Attempted to write %zu bytes, but buffer is too small.",
- len);
+ sr_err("Write buffer too small to write %zu bytes.", len);
return SR_ERR_BUG;
}
buf[idx++] = REG_DATA_HIGH_WRITE | (data[i] >> 4);
}
- return sigma_write(buf, idx, devc);
+ return sigma_write(devc, buf, idx);
}
-SR_PRIV int sigma_set_register(uint8_t reg, uint8_t value, struct dev_context *devc)
+SR_PRIV int sigma_set_register(struct dev_context *devc,
+ uint8_t reg, uint8_t value)
{
- return sigma_write_register(reg, &value, 1, devc);
+ return sigma_write_register(devc, reg, &value, sizeof(value));
}
-static int sigma_read_register(uint8_t reg, uint8_t *data, size_t len,
- struct dev_context *devc)
+static int sigma_read_register(struct dev_context *devc,
+ uint8_t reg, uint8_t *data, size_t len)
{
uint8_t buf[3];
buf[1] = REG_ADDR_HIGH | (reg >> 4);
buf[2] = REG_READ_ADDR;
- sigma_write(buf, sizeof(buf), devc);
+ sigma_write(devc, buf, sizeof(buf));
- return sigma_read(data, len, devc);
+ return sigma_read(devc, data, len);
}
-static int sigma_read_pos(uint32_t *stoppos, uint32_t *triggerpos,
- struct dev_context *devc)
+static int sigma_read_pos(struct dev_context *devc,
+ uint32_t *stoppos, uint32_t *triggerpos)
{
/*
* Read 6 registers starting at trigger position LSB.
};
uint8_t result[6];
- sigma_write(buf, sizeof(buf), devc);
+ sigma_write(devc, buf, sizeof(buf));
- sigma_read(result, sizeof(result), devc);
+ sigma_read(devc, result, sizeof(result));
*triggerpos = result[0] | (result[1] << 8) | (result[2] << 16);
*stoppos = result[3] | (result[4] << 8) | (result[5] << 16);
return 1;
}
-static int sigma_read_dram(uint16_t startchunk, size_t numchunks,
- uint8_t *data, struct dev_context *devc)
+static int sigma_read_dram(struct dev_context *devc,
+ uint16_t startchunk, size_t numchunks, uint8_t *data)
{
uint8_t buf[4096];
int idx;
idx = 0;
buf[idx++] = startchunk >> 8;
buf[idx++] = startchunk & 0xff;
- sigma_write_register(WRITE_MEMROW, buf, idx, devc);
+ sigma_write_register(devc, WRITE_MEMROW, buf, idx);
/*
* Access DRAM content. Fetch from DRAM to FPGA's internal RAM,
if (!is_last)
buf[idx++] = REG_DRAM_WAIT_ACK;
}
- sigma_write(buf, idx, devc);
+ sigma_write(devc, buf, idx);
- return sigma_read(data, numchunks * ROW_LENGTH_BYTES, devc);
+ return sigma_read(devc, data, numchunks * ROW_LENGTH_BYTES);
}
/* Upload trigger look-up tables to Sigma. */
-SR_PRIV int sigma_write_trigger_lut(struct triggerlut *lut, struct dev_context *devc)
+SR_PRIV int sigma_write_trigger_lut(struct dev_context *devc,
+ struct triggerlut *lut)
{
int i;
uint8_t tmp[2];
if (lut->m1d[3] & bit)
tmp[1] |= 0x80;
- sigma_write_register(WRITE_TRIGGER_SELECT, tmp, sizeof(tmp),
- devc);
- sigma_set_register(WRITE_TRIGGER_SELECT2, 0x30 | i, devc);
+ sigma_write_register(devc, WRITE_TRIGGER_SELECT,
+ tmp, sizeof(tmp));
+ sigma_set_register(devc, WRITE_TRIGGER_SELECT2, 0x30 | i);
}
/* Send the parameters */
- sigma_write_register(WRITE_TRIGGER_SELECT, (uint8_t *) &lut->params,
- sizeof(lut->params), devc);
+ sigma_write_register(devc, WRITE_TRIGGER_SELECT,
+ (uint8_t *)&lut->params, sizeof(lut->params));
return SR_OK;
}
/*
* Initiate slave serial mode for configuration download. Which is done
* by pulsing PROG_B and sensing INIT_B. Make sure CCLK is idle before
- * initiating the configuration download. Run a "suicide sequence" first
- * to terminate the regular FPGA operation before reconfiguration.
+ * initiating the configuration download.
+ *
+ * Run a "suicide sequence" first to terminate the regular FPGA operation
+ * before reconfiguration. The FTDI cable is single channel, and shares
+ * pins which are used for data communication in FIFO mode with pins that
+ * are used for FPGA configuration in bitbang mode. Hardware defaults for
+ * unconfigured hardware, and runtime conditions after FPGA configuration
+ * need to cooperate such that re-configuration of the FPGA can start.
*/
-static int sigma_fpga_init_bitbang(struct dev_context *devc)
+static int sigma_fpga_init_bitbang_once(struct dev_context *devc)
{
uint8_t suicide[] = {
BB_PIN_D7 | BB_PIN_D2,
uint8_t data;
/* Section 2. part 1), do the FPGA suicide. */
- sigma_write(suicide, sizeof(suicide), devc);
- sigma_write(suicide, sizeof(suicide), devc);
- sigma_write(suicide, sizeof(suicide), devc);
- sigma_write(suicide, sizeof(suicide), devc);
+ sigma_write(devc, suicide, sizeof(suicide));
+ sigma_write(devc, suicide, sizeof(suicide));
+ sigma_write(devc, suicide, sizeof(suicide));
+ sigma_write(devc, suicide, sizeof(suicide));
+ g_usleep(10 * 1000);
/* Section 2. part 2), pulse PROG. */
- sigma_write(init_array, sizeof(init_array), devc);
+ sigma_write(devc, init_array, sizeof(init_array));
+ g_usleep(10 * 1000);
ftdi_usb_purge_buffers(&devc->ftdic);
/* Wait until the FPGA asserts INIT_B. */
retries = 10;
while (retries--) {
- ret = sigma_read(&data, 1, devc);
+ ret = sigma_read(devc, &data, 1);
if (ret < 0)
return ret;
if (data & BB_PIN_INIT)
return SR_ERR_TIMEOUT;
}
+/*
+ * This is belt and braces. Re-run the bitbang initiation sequence a few
+ * times should first attempts fail. Failure is rare but can happen (was
+ * observed during driver development).
+ */
+static int sigma_fpga_init_bitbang(struct dev_context *devc)
+{
+ size_t retries;
+ int ret;
+
+ retries = 10;
+ while (retries--) {
+ ret = sigma_fpga_init_bitbang_once(devc);
+ if (ret == SR_OK)
+ return ret;
+ if (ret != SR_ERR_TIMEOUT)
+ return ret;
+ }
+ return ret;
+}
+
/*
* Configure the FPGA for logic-analyzer mode.
*/
uint8_t mode_regval = WMR_SDRAMINIT;
uint8_t logic_mode_start[] = {
/* Read ID register. */
- REG_ADDR_LOW | (READ_ID & 0xf),
+ REG_ADDR_LOW | (READ_ID & 0xf),
REG_ADDR_HIGH | (READ_ID >> 4),
REG_READ_ADDR,
* Send the command sequence which contains 3 READ requests.
* Expect to see the corresponding 3 response bytes.
*/
- sigma_write(logic_mode_start, sizeof(logic_mode_start), devc);
- ret = sigma_read(result, ARRAY_SIZE(result), devc);
+ sigma_write(devc, logic_mode_start, sizeof(logic_mode_start));
+ ret = sigma_read(devc, result, ARRAY_SIZE(result));
if (ret != ARRAY_SIZE(result))
goto err;
if (result[0] != 0xa6 || result[1] != 0x55 || result[2] != 0xaa)
* by the caller of this function.
*/
static int sigma_fw_2_bitbang(struct sr_context *ctx, const char *name,
- uint8_t **bb_cmd, gsize *bb_cmd_size)
+ uint8_t **bb_cmd, gsize *bb_cmd_size)
{
uint8_t *firmware;
size_t file_size;
return SR_OK;
}
-static int upload_firmware(struct sr_context *ctx,
- int firmware_idx, struct dev_context *devc)
+static int upload_firmware(struct sr_context *ctx, struct dev_context *devc,
+ enum sigma_firmware_idx firmware_idx)
{
int ret;
unsigned char *buf;
size_t buf_size;
const char *firmware;
- /* Avoid downloading the same firmware multiple times. */
+ /* Check for valid firmware file selection. */
+ if (firmware_idx >= ARRAY_SIZE(firmware_files))
+ return SR_ERR_ARG;
firmware = firmware_files[firmware_idx];
- if (devc->cur_firmware == firmware_idx) {
+ if (!firmware || !*firmware)
+ return SR_ERR_ARG;
+
+ /* Avoid downloading the same firmware multiple times. */
+ if (devc->firmware_idx == firmware_idx) {
sr_info("Not uploading firmware file '%s' again.", firmware);
return SR_OK;
}
+ devc->state.state = SIGMA_CONFIG;
+
/* Set the cable to bitbang mode. */
ret = ftdi_set_bitmode(&devc->ftdic, BB_PINMASK, BITMODE_BITBANG);
if (ret < 0) {
sr_err("ftdi_set_bitmode failed: %s",
- ftdi_get_error_string(&devc->ftdic));
+ ftdi_get_error_string(&devc->ftdic));
return SR_ERR;
}
ret = ftdi_set_baudrate(&devc->ftdic, BB_BITRATE);
if (ret < 0) {
sr_err("ftdi_set_baudrate failed: %s",
- ftdi_get_error_string(&devc->ftdic));
+ ftdi_get_error_string(&devc->ftdic));
return SR_ERR;
}
/* Prepare wire format of the firmware image. */
ret = sigma_fw_2_bitbang(ctx, firmware, &buf, &buf_size);
if (ret != SR_OK) {
- sr_err("An error occurred while reading the firmware: %s",
- firmware);
+ sr_err("Could not prepare file %s for download.", firmware);
return ret;
}
/* Write the FPGA netlist to the cable. */
sr_info("Uploading firmware file '%s'.", firmware);
- sigma_write(buf, buf_size, devc);
+ sigma_write(devc, buf, buf_size);
g_free(buf);
ret = ftdi_set_bitmode(&devc->ftdic, 0, BITMODE_RESET);
if (ret < 0) {
sr_err("ftdi_set_bitmode failed: %s",
- ftdi_get_error_string(&devc->ftdic));
+ ftdi_get_error_string(&devc->ftdic));
return SR_ERR;
}
ftdi_usb_purge_buffers(&devc->ftdic);
- while (sigma_read(&pins, 1, devc) == 1)
+ while (sigma_read(devc, &pins, 1) == 1)
;
/* Initialize the FPGA for logic-analyzer mode. */
return ret;
/* Keep track of successful firmware download completion. */
- devc->cur_firmware = firmware_idx;
+ devc->state.state = SIGMA_IDLE;
+ devc->firmware_idx = firmware_idx;
sr_info("Firmware uploaded.");
return SR_OK;
}
/*
- * Sigma doesn't support limiting the number of samples, so we have to
- * translate the number and the samplerate to an elapsed time.
+ * The driver supports user specified time or sample count limits. The
+ * device's hardware supports neither, and hardware compression prevents
+ * reliable detection of "fill levels" (currently reached sample counts)
+ * from register values during acquisition. That's why the driver needs
+ * to apply some heuristics:
+ *
+ * - The (optional) sample count limit and the (normalized) samplerate
+ * get mapped to an estimated duration for these samples' acquisition.
+ * - The (optional) time limit gets checked as well. The lesser of the
+ * two limits will terminate the data acquisition phase. The exact
+ * sample count limit gets enforced in session feed submission paths.
+ * - Some slack needs to be given to account for hardware pipelines as
+ * well as late storage of last chunks after compression thresholds
+ * are tripped. The resulting data set will span at least the caller
+ * specified period of time, which shall be perfectly acceptable.
*
- * In addition we need to ensure that the last data cluster has passed
- * the hardware pipeline, and became available to the PC side. With RLE
- * compression up to 327ms could pass before another cluster accumulates
- * at 200kHz samplerate when input pins don't change.
+ * With RLE compression active, up to 64K sample periods can pass before
+ * a cluster accumulates. Which translates to 327ms at 200kHz. Add two
+ * times that period for good measure, one is not enough to flush the
+ * hardware pipeline (observation from an earlier experiment).
*/
-SR_PRIV uint64_t sigma_limit_samples_to_msec(const struct dev_context *devc,
- uint64_t limit_samples)
+SR_PRIV int sigma_set_acquire_timeout(struct dev_context *devc)
{
- uint64_t limit_msec;
+ int ret;
+ GVariant *data;
+ uint64_t user_count, user_msecs;
uint64_t worst_cluster_time_ms;
+ uint64_t count_msecs, acquire_msecs;
- limit_msec = limit_samples * 1000 / devc->cur_samplerate;
- worst_cluster_time_ms = 65536 * 1000 / devc->cur_samplerate;
- /*
- * One cluster time is not enough to flush pipeline when sampling
- * grounded pins with 1 sample limit at 200kHz. Hence the 2* fix.
- */
- return limit_msec + 2 * worst_cluster_time_ms;
+ sr_sw_limits_init(&devc->acq_limits);
+
+ /* Get sample count limit, convert to msecs. */
+ ret = sr_sw_limits_config_get(&devc->cfg_limits,
+ SR_CONF_LIMIT_SAMPLES, &data);
+ if (ret != SR_OK)
+ return ret;
+ user_count = g_variant_get_uint64(data);
+ g_variant_unref(data);
+ count_msecs = 0;
+ if (user_count)
+ count_msecs = 1000 * user_count / devc->samplerate + 1;
+
+ /* Get time limit, which is in msecs. */
+ ret = sr_sw_limits_config_get(&devc->cfg_limits,
+ SR_CONF_LIMIT_MSEC, &data);
+ if (ret != SR_OK)
+ return ret;
+ user_msecs = g_variant_get_uint64(data);
+ g_variant_unref(data);
+
+ /* Get the lesser of them, with both being optional. */
+ acquire_msecs = ~0ull;
+ if (user_count && count_msecs < acquire_msecs)
+ acquire_msecs = count_msecs;
+ if (user_msecs && user_msecs < acquire_msecs)
+ acquire_msecs = user_msecs;
+ if (acquire_msecs == ~0ull)
+ return SR_OK;
+
+ /* Add some slack, and use that timeout for acquisition. */
+ worst_cluster_time_ms = 1000 * 65536 / devc->samplerate;
+ acquire_msecs += 2 * worst_cluster_time_ms;
+ data = g_variant_new_uint64(acquire_msecs);
+ ret = sr_sw_limits_config_set(&devc->acq_limits,
+ SR_CONF_LIMIT_MSEC, data);
+ g_variant_unref(data);
+ if (ret != SR_OK)
+ return ret;
+
+ sr_sw_limits_acquisition_start(&devc->acq_limits);
+ return SR_OK;
}
-SR_PRIV int sigma_set_samplerate(const struct sr_dev_inst *sdi, uint64_t samplerate)
+/*
+ * Check whether a caller specified samplerate matches the device's
+ * hardware constraints (can be used for acquisition). Optionally yield
+ * a value that approximates the original spec.
+ *
+ * This routine assumes that input specs are in the 200kHz to 200MHz
+ * range of supported rates, and callers typically want to normalize a
+ * given value to the hardware capabilities. Values in the 50MHz range
+ * get rounded up by default, to avoid a more expensive check for the
+ * closest match, while higher sampling rate is always desirable during
+ * measurement. Input specs which exactly match hardware capabilities
+ * remain unaffected. Because 100/200MHz rates also limit the number of
+ * available channels, they are not suggested by this routine, instead
+ * callers need to pick them consciously.
+ */
+SR_PRIV int sigma_normalize_samplerate(uint64_t want_rate, uint64_t *have_rate)
+{
+ uint64_t div, rate;
+
+ /* Accept exact matches for 100/200MHz. */
+ if (want_rate == SR_MHZ(200) || want_rate == SR_MHZ(100)) {
+ if (have_rate)
+ *have_rate = want_rate;
+ return SR_OK;
+ }
+
+ /* Accept 200kHz to 50MHz range, and map to near value. */
+ if (want_rate >= SR_KHZ(200) && want_rate <= SR_MHZ(50)) {
+ div = SR_MHZ(50) / want_rate;
+ rate = SR_MHZ(50) / div;
+ if (have_rate)
+ *have_rate = rate;
+ return SR_OK;
+ }
+
+ return SR_ERR_ARG;
+}
+
+SR_PRIV int sigma_set_samplerate(const struct sr_dev_inst *sdi)
{
struct dev_context *devc;
struct drv_context *drvc;
- size_t i;
+ uint64_t samplerate;
int ret;
int num_channels;
devc = sdi->priv;
drvc = sdi->driver->context;
- ret = SR_OK;
- /* Reject rates that are not in the list of supported rates. */
- for (i = 0; i < samplerates_count; i++) {
- if (samplerates[i] == samplerate)
- break;
- }
- if (i >= samplerates_count || samplerates[i] == 0)
- return SR_ERR_SAMPLERATE;
+ /* Accept any caller specified rate which the hardware supports. */
+ ret = sigma_normalize_samplerate(devc->samplerate, &samplerate);
+ if (ret != SR_OK)
+ return ret;
/*
* Depending on the samplerates of 200/100/50- MHz, specific
*/
num_channels = devc->num_channels;
if (samplerate <= SR_MHZ(50)) {
- ret = upload_firmware(drvc->sr_ctx, 0, devc);
+ ret = upload_firmware(drvc->sr_ctx, devc, SIGMA_FW_50MHZ);
num_channels = 16;
} else if (samplerate == SR_MHZ(100)) {
- ret = upload_firmware(drvc->sr_ctx, 1, devc);
+ ret = upload_firmware(drvc->sr_ctx, devc, SIGMA_FW_100MHZ);
num_channels = 8;
} else if (samplerate == SR_MHZ(200)) {
- ret = upload_firmware(drvc->sr_ctx, 2, devc);
+ ret = upload_firmware(drvc->sr_ctx, devc, SIGMA_FW_200MHZ);
num_channels = 4;
}
/*
- * Derive the sample period from the sample rate as well as the
- * number of samples that the device will communicate within
- * an "event" (memory organization internal to the device).
+ * The samplerate affects the number of available logic channels
+ * as well as a sample memory layout detail (the number of samples
+ * which the device will communicate within an "event").
*/
if (ret == SR_OK) {
devc->num_channels = num_channels;
- devc->cur_samplerate = samplerate;
devc->samples_per_event = 16 / devc->num_channels;
- devc->state.state = SIGMA_IDLE;
- }
-
- /*
- * Support for "limit_samples" is implemented by stopping
- * acquisition after a corresponding period of time.
- * Re-calculate that period of time, in case the limit is
- * set first and the samplerate gets (re-)configured later.
- */
- if (ret == SR_OK && devc->limit_samples) {
- uint64_t msecs;
- msecs = sigma_limit_samples_to_msec(devc, devc->limit_samples);
- devc->limit_msec = msecs;
}
return ret;
struct sr_dev_inst *sdi;
struct sr_datafeed_packet packet;
struct sr_datafeed_logic logic;
- struct sr_sw_limits limit_samples;
};
static int alloc_submit_buffer(struct sr_dev_inst *sdi)
if (!buffer->sample_data)
return SR_ERR_MALLOC;
buffer->write_pointer = buffer->sample_data;
- sr_sw_limits_init(&buffer->limit_samples);
+ sr_sw_limits_init(&devc->feed_limits);
buffer->sdi = sdi;
memset(&buffer->logic, 0, sizeof(buffer->logic));
return SR_OK;
}
-static int setup_submit_buffer(struct dev_context *devc)
+static int setup_submit_limit(struct dev_context *devc)
{
- struct submit_buffer *buffer;
+ struct sr_sw_limits *limits;
int ret;
GVariant *data;
uint64_t total;
- buffer = devc->buffer;
+ limits = &devc->feed_limits;
+
+ ret = sr_sw_limits_config_get(&devc->cfg_limits,
+ SR_CONF_LIMIT_SAMPLES, &data);
+ if (ret != SR_OK)
+ return ret;
+ total = g_variant_get_uint64(data);
+ g_variant_unref(data);
- total = devc->limit_samples;
+ sr_sw_limits_init(limits);
if (total) {
data = g_variant_new_uint64(total);
- ret = sr_sw_limits_config_set(&buffer->limit_samples,
+ ret = sr_sw_limits_config_set(limits,
SR_CONF_LIMIT_SAMPLES, data);
g_variant_unref(data);
if (ret != SR_OK)
return ret;
}
- sr_sw_limits_acquisition_start(&buffer->limit_samples);
+ sr_sw_limits_acquisition_start(limits);
return SR_OK;
}
uint16_t sample, size_t count)
{
struct submit_buffer *buffer;
+ struct sr_sw_limits *limits;
int ret;
buffer = devc->buffer;
- if (sr_sw_limits_check(&buffer->limit_samples))
+ limits = &devc->feed_limits;
+ if (sr_sw_limits_check(limits))
count = 0;
/*
if (ret != SR_OK)
return ret;
}
- sr_sw_limits_update_samples_read(&buffer->limit_samples, 1);
- if (sr_sw_limits_check(&buffer->limit_samples))
+ sr_sw_limits_update_samples_read(limits, 1);
+ if (sr_sw_limits_check(limits))
break;
}
stage = l->data;
for (m = stage->matches; m; m = m->next) {
match = m->data;
+ /* Ignore disabled channels with a trigger. */
if (!match->channel->enabled)
- /* Ignore disabled channels with a trigger. */
continue;
channelbit = 1 << (match->channel->index);
- if (devc->cur_samplerate >= SR_MHZ(100)) {
+ if (devc->samplerate >= SR_MHZ(100)) {
/* Fast trigger support. */
if (trigger_set) {
sr_err("Only a single pin trigger is "
- "supported in 100 and 200MHz mode.");
+ "supported in 100 and 200MHz mode.");
return SR_ERR;
}
if (match->match == SR_TRIGGER_FALLING)
devc->trigger.risingmask |= channelbit;
else {
sr_err("Only rising/falling trigger is "
- "supported in 100 and 200MHz mode.");
+ "supported in 100 and 200MHz mode.");
return SR_ERR;
}
* does not permit ORed triggers.
*/
if (trigger_set > 1) {
- sr_err("Only 1 rising/falling trigger "
- "is supported.");
+ sr_err("Only 1 rising/falling trigger is supported.");
return SR_ERR;
}
}
/* Software trigger to determine exact trigger position. */
static int get_trigger_offset(uint8_t *samples, uint16_t last_sample,
- struct sigma_trigger *t)
+ struct sigma_trigger *t)
{
int i;
uint16_t sample = 0;
tsdiff = ts - ss->lastts;
if (tsdiff > 0) {
size_t count;
+ sample = ss->lastsample;
count = tsdiff * devc->samples_per_event;
- (void)check_and_submit_sample(devc, ss->lastsample, count, FALSE);
+ (void)check_and_submit_sample(devc, sample, count, FALSE);
}
ss->lastts = ts + EVENTS_PER_CLUSTER;
sample = 0;
for (i = 0; i < events_in_cluster; i++) {
item16 = sigma_dram_cluster_data(dram_cluster, i);
- if (devc->cur_samplerate == SR_MHZ(200)) {
+ if (devc->samplerate == SR_MHZ(200)) {
sample = sigma_deinterlace_200mhz_data(item16, 0);
check_and_submit_sample(devc, sample, 1, triggered);
sample = sigma_deinterlace_200mhz_data(item16, 1);
check_and_submit_sample(devc, sample, 1, triggered);
sample = sigma_deinterlace_200mhz_data(item16, 3);
check_and_submit_sample(devc, sample, 1, triggered);
- } else if (devc->cur_samplerate == SR_MHZ(100)) {
+ } else if (devc->samplerate == SR_MHZ(100)) {
sample = sigma_deinterlace_100mhz_data(item16, 0);
check_and_submit_sample(devc, sample, 1, triggered);
sample = sigma_deinterlace_100mhz_data(item16, 1);
/* Check if trigger is in this chunk. */
if (trigger_event < EVENTS_PER_ROW) {
- if (devc->cur_samplerate <= SR_MHZ(50)) {
+ if (devc->samplerate <= SR_MHZ(50)) {
trigger_event -= MIN(EVENTS_PER_CLUSTER - 1,
trigger_event);
}
* clusters to DRAM regardless of whether pin state changes) and
* raise the POSTTRIGGERED flag.
*/
- sigma_set_register(WRITE_MODE, WMR_FORCESTOP | WMR_SDRAMWRITEEN, devc);
+ sigma_set_register(devc, WRITE_MODE, WMR_FORCESTOP | WMR_SDRAMWRITEEN);
do {
- if (sigma_read_register(READ_MODE, &modestatus, 1, devc) != 1) {
+ if (sigma_read_register(devc, READ_MODE, &modestatus, 1) != 1) {
sr_err("failed while waiting for RMR_POSTTRIGGERED bit");
return FALSE;
}
} while (!(modestatus & RMR_POSTTRIGGERED));
/* Set SDRAM Read Enable. */
- sigma_set_register(WRITE_MODE, WMR_SDRAMREADEN, devc);
+ sigma_set_register(devc, WRITE_MODE, WMR_SDRAMREADEN);
/* Get the current position. */
- sigma_read_pos(&stoppos, &triggerpos, devc);
+ sigma_read_pos(devc, &stoppos, &triggerpos);
/* Check if trigger has fired. */
- if (sigma_read_register(READ_MODE, &modestatus, 1, devc) != 1) {
+ if (sigma_read_register(devc, READ_MODE, &modestatus, 1) != 1) {
sr_err("failed to read READ_MODE register");
return FALSE;
}
trg_event = triggerpos & 0x1ff;
}
- devc->sent_samples = 0;
-
/*
* Determine how many "DRAM lines" of 1024 bytes each we need to
* retrieve from the Sigma hardware, so that we have a complete
ret = alloc_submit_buffer(sdi);
if (ret != SR_OK)
return FALSE;
- ret = setup_submit_buffer(devc);
+ ret = setup_submit_limit(devc);
if (ret != SR_OK)
return FALSE;
dl_lines_done = 0;
dl_line = dl_first_line + dl_lines_done;
dl_line %= ROW_COUNT;
- bufsz = sigma_read_dram(dl_line, dl_lines_curr,
- (uint8_t *)dram_line, devc);
+ bufsz = sigma_read_dram(devc, dl_line, dl_lines_curr,
+ (uint8_t *)dram_line);
/* TODO: Check bufsz. For now, just avoid compiler warnings. */
(void)bufsz;
static int sigma_capture_mode(struct sr_dev_inst *sdi)
{
struct dev_context *devc;
- uint64_t running_msec;
- uint64_t current_time;
devc = sdi->priv;
-
- /*
- * Check if the selected sampling duration passed. Sample count
- * limits are covered by this enforced timeout as well.
- */
- current_time = g_get_monotonic_time();
- running_msec = (current_time - devc->start_time) / 1000;
- if (running_msec >= devc->limit_msec)
+ if (sr_sw_limits_check(&devc->acq_limits))
return download_capture(sdi);
return TRUE;
/* Add a logical function to LUT mask. */
static void add_trigger_function(enum triggerop oper, enum triggerfunc func,
- int index, int neg, uint16_t *mask)
+ int index, int neg, uint16_t *mask)
{
int i, j;
int x[2][2], tmp, a, b, aset, bset, rset;
* simple pin change and state triggers. Only two transitions (rise/fall) can be
* set at any time, but a full mask and value can be set (0/1).
*/
-SR_PRIV int sigma_build_basic_trigger(struct triggerlut *lut, struct dev_context *devc)
+SR_PRIV int sigma_build_basic_trigger(struct dev_context *devc,
+ struct triggerlut *lut)
{
int i,j;
uint16_t masks[2] = { 0, 0 };