SR_CONF_SAMPLERATE,
SR_CONF_EXTERNAL_CLOCK,
SR_CONF_TRIGGER_TYPE,
+ SR_CONF_LIMIT_MSEC,
SR_CONF_LIMIT_SAMPLES,
};
case SR_CONF_SAMPLERATE:
*data = g_variant_new_uint64(devc->samplerate);
break;
+ 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;
static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi,
const struct sr_probe_group *probe_group)
{
+ uint64_t value;
struct dev_context *devc;
- uint64_t rate;
(void)probe_group;
switch (key) {
case SR_CONF_SAMPLERATE:
- rate = g_variant_get_uint64(data);
- sr_info("Setting samplerate %" G_GUINT64_FORMAT, rate);
- if (rate > samplerates[0]
- || rate < samplerates[G_N_ELEMENTS(samplerates) - 1])
+ value = g_variant_get_uint64(data);
+ sr_info("Setting samplerate %" PRIu64, value);
+ if (value < samplerates[G_N_ELEMENTS(samplerates) - 1]
+ || value > samplerates[0])
return SR_ERR_SAMPLERATE;
- devc->samplerate = rate;
+ devc->samplerate = value;
+ break;
+ case SR_CONF_LIMIT_MSEC:
+ value = g_variant_get_uint64(data);
+ if (value > MAX_LIMIT_MSEC)
+ return SR_ERR_ARG;
+ devc->limit_msec = value;
break;
case SR_CONF_LIMIT_SAMPLES:
- devc->limit_samples = g_variant_get_uint64(data);
+ value = g_variant_get_uint64(data);
+ if (value > MAX_LIMIT_SAMPLES)
+ return SR_ERR_ARG;
+ devc->limit_samples = value;
break;
case SR_CONF_EXTERNAL_CLOCK:
if (g_variant_get_boolean(data)) {
static int capture_setup(const struct sr_dev_inst *sdi)
{
struct dev_context *devc;
+ struct acquisition_state *acq;
uint64_t divider_count;
uint64_t memory_limit;
uint16_t command[3 + 10*4];
devc = sdi->priv;
+ acq = devc->acquisition;
command[0] = LWLA_WORD(CMD_CAP_SETUP);
command[1] = LWLA_WORD(0); /* address */
* 100 MHz. At the highest samplerate of 125 MHz the clock divider
* is bypassed.
*/
- if (devc->cur_clock_source == CLOCK_SOURCE_INT
- && devc->samplerate > 0
- && devc->samplerate < SR_MHZ(100))
+ if (!acq->bypass_clockdiv && devc->samplerate > 0)
divider_count = SR_MHZ(100) / devc->samplerate - 1;
else
divider_count = 0;
acq->sample = 0;
acq->run_len = 0;
- acq->captured_samples = 0;
- acq->transferred_samples = 0;
+ acq->samples_done = 0;
/* For some reason, the start address is 4 rather than 0. */
acq->mem_addr_done = 4;
static void process_capture_status(const struct sr_dev_inst *sdi)
{
uint64_t duration;
- uint64_t timescale;
struct dev_context *devc;
struct acquisition_state *acq;
acq->capture_flags = LWLA_READ32(&acq->xfer_buf_in[16])
& STATUS_FLAG_MASK;
- /* The 125 MHz setting is special, and uses the same timebase
- * for the duration field as the 100 MHz setting.
+ /* The LWLA1034 runs at 125 MHz if the clock divider is bypassed.
+ * However, the time base used for the duration is apparently not
+ * adjusted for this "boost" mode. Whereas normally the duration
+ * unit is 1 ms, it is 0.8 ms when the clock divider is bypassed.
+ * As 0.8 = 100 MHz / 125 MHz, it seems that the internal cycle
+ * counter period is the same as at the 100 MHz setting.
*/
- timescale = MIN(devc->samplerate, SR_MHZ(100));
- acq->captured_samples = duration * timescale / 1000;
+ if (acq->bypass_clockdiv)
+ acq->duration_now = duration * 4 / 5;
+ else
+ acq->duration_now = duration;
- sr_spew("Captured %lu words, %" PRIu64 " samples, flags 0x%02X",
- (unsigned long)acq->mem_addr_fill,
- acq->captured_samples, acq->capture_flags);
+ sr_spew("Captured %zu words, %" PRIu64 " ms, flags 0x%02X",
+ acq->mem_addr_fill, acq->duration_now, acq->capture_flags);
- if (acq->captured_samples >= devc->limit_samples) {
+ if (acq->duration_now >= acq->duration_max) {
issue_stop_capture(sdi);
return;
}
devc = sdi->priv;
acq = devc->acquisition;
- if (acq->transferred_samples >= devc->limit_samples)
+ if (acq->samples_done >= acq->samples_max)
return TRUE;
packet.type = SR_DF_LOGIC;
last = FALSE;
/* Cut the packet short if necessary. */
- if (acq->transferred_samples + samples >= devc->limit_samples) {
- samples = devc->limit_samples - acq->transferred_samples;
+ if (acq->samples_done + samples >= acq->samples_max) {
+ samples = acq->samples_max - acq->samples_done;
logic.length = samples * UNIT_SIZE;
last = TRUE;
}
- acq->transferred_samples += samples;
+ acq->samples_done += samples;
acq->out_offset = 0;
/* Send off logic datafeed packet. */
acq = devc->acquisition;
if (acq->mem_addr_done >= acq->mem_addr_stop
- || acq->transferred_samples >= devc->limit_samples)
+ || acq->samples_done >= acq->samples_max)
return SR_OK;
in_words_left = MIN(acq->mem_addr_stop - acq->mem_addr_done,
case STATE_READ_RESPONSE:
if (process_sample_data(sdi) == SR_OK
&& acq->mem_addr_next < acq->mem_addr_stop
- && acq->transferred_samples < devc->limit_samples)
+ && acq->samples_done < acq->samples_max)
request_read_mem(sdi);
else
issue_read_end(sdi);
{
struct dev_context *devc;
struct sr_usb_dev_inst *usb;
+ struct acquisition_state *acq;
struct regval_pair regvals[7];
int ret;
- gboolean bypass;
devc = sdi->priv;
usb = sdi->conn;
+ acq = devc->acquisition;
+
+ /* By default, run virtually unlimited. */
+ acq->duration_max = (devc->limit_msec > 0)
+ ? devc->limit_msec : MAX_LIMIT_MSEC;
+ acq->samples_max = (devc->limit_samples > 0)
+ ? devc->limit_samples : MAX_LIMIT_SAMPLES;
+
+ switch (devc->cur_clock_source) {
+ case CLOCK_SOURCE_INT:
+ if (devc->samplerate == 0)
+ return SR_ERR_BUG;
+ /* At 125 MHz, the clock divider is bypassed. */
+ acq->bypass_clockdiv = (devc->samplerate > SR_MHZ(100));
+
+ /* If only one of the limits is set, derive the other one. */
+ if (devc->limit_msec == 0 && devc->limit_samples > 0)
+ acq->duration_max = devc->limit_samples
+ * 1000 / devc->samplerate + 1;
+ else if (devc->limit_samples == 0 && devc->limit_msec > 0)
+ acq->samples_max = devc->limit_msec
+ * devc->samplerate / 1000;
+ break;
+ case CLOCK_SOURCE_EXT_FALL:
+ case CLOCK_SOURCE_EXT_RISE:
+ acq->bypass_clockdiv = TRUE;
+ break;
+ default:
+ sr_err("No valid clock source has been configured.");
+ return SR_ERR;
+ }
regvals[0].reg = REG_MEM_CTRL2;
regvals[0].val = 2;
regvals[5].reg = REG_CMD_CTRL1;
regvals[5].val = 0;
- switch (devc->cur_clock_source) {
- case CLOCK_SOURCE_INT:
- bypass = (devc->samplerate > SR_MHZ(100));
- break;
- case CLOCK_SOURCE_EXT_FALL:
- case CLOCK_SOURCE_EXT_RISE:
- bypass = TRUE;
- break;
- default:
- bypass = FALSE;
- break;
- }
regvals[6].reg = REG_DIV_BYPASS;
- regvals[6].val = bypass;
+ regvals[6].val = acq->bypass_clockdiv;
ret = lwla_write_regs(usb, regvals, G_N_ELEMENTS(regvals));
if (ret != SR_OK)
usb = sdi->conn;
acq = devc->acquisition;
+ acq->duration_now = 0;
+
libusb_fill_bulk_transfer(acq->xfer_out, usb->devhdl, EP_COMMAND,
(unsigned char *)acq->xfer_buf_out, 0,
&receive_transfer_out,
*/
#define DEFAULT_SAMPLERATE SR_MHZ(125)
+/** Maximum configurable sample count limit.
+ */
+#define MAX_LIMIT_SAMPLES (UINT64_C(1) << 48)
+
+/** Maximum configurable capture duration in milliseconds.
+ */
+#define MAX_LIMIT_MSEC (UINT64_C(1) << 32)
+
/** LWLA clock sources.
*/
enum clock_source {
uint64_t sample;
uint64_t run_len;
- /** Number of samples acquired so far. */
- uint64_t captured_samples;
+ /** Maximum number of samples to process. */
+ uint64_t samples_max;
/** Number of samples sent to the session bus. */
- uint64_t transferred_samples;
+ uint64_t samples_done;
+
+ /** Maximum duration of capture, in milliseconds. */
+ uint64_t duration_max;
+ /** Running capture duration since trigger event. */
+ uint64_t duration_now;
/** Capture memory fill level. */
size_t mem_addr_fill;
enum rle_state rle;
+ /** Whether to bypass the clock divider. */
+ gboolean bypass_clockdiv;
+
/* Payload data buffers for outgoing and incoming transfers. */
uint16_t xfer_buf_out[MAX_ACQ_SEND_WORDS];
uint16_t xfer_buf_in[MAX_ACQ_RECV_WORDS];
/** The samplerate selected by the user. */
uint64_t samplerate;
+ /** The maximimum sampling duration, in milliseconds. */
+ uint64_t limit_msec;
+
/** The maximimum number of samples to acquire. */
uint64_t limit_samples;