*/
#include <config.h>
-#include <assert.h>
#include <math.h>
+#include <stdbool.h>
#include <glib.h>
#include <glib/gstdio.h>
#include "protocol.h"
uint8_t sample_delay_l;
};
-struct dslogic_fpga_config {
+struct fpga_config {
uint32_t sync;
uint16_t mode_header;
/*
* Get the session trigger and configure the FPGA structure
* accordingly.
+ * @return @c true if any triggers are enabled, @c false otherwise.
*/
-static void set_trigger(const struct sr_dev_inst *sdi,
- struct dslogic_fpga_config *cfg)
+static bool set_trigger(const struct sr_dev_inst *sdi, struct fpga_config *cfg)
{
struct sr_trigger *trigger;
struct sr_trigger_stage *stage;
cfg->ch_en = enabled_channel_mask(sdi);
- cfg->trig_mask0[0] = 0xffff;
- cfg->trig_mask1[0] = 0xffff;
-
- cfg->trig_value0[0] = 0;
- cfg->trig_value1[0] = 0;
-
- cfg->trig_edge0[0] = 0;
- cfg->trig_edge1[0] = 0;
-
- cfg->trig_logic0[0] = 2;
- cfg->trig_logic1[0] = 2;
-
- cfg->trig_count[0] = 0;
-
- cfg->trig_glb = num_enabled_channels << 4;
-
- for (i = 1; i < NUM_TRIGGER_STAGES; i++) {
+ for (i = 0; i < NUM_TRIGGER_STAGES; i++) {
cfg->trig_mask0[i] = 0xffff;
cfg->trig_mask1[i] = 0xffff;
cfg->trig_value0[i] = 0;
if (!(trigger = sr_session_trigger_get(sdi->session))) {
sr_dbg("No session trigger found");
- return;
+ return false;
}
for (l = trigger->stages; l; l = l->next) {
}
}
- cfg->trig_glb |= num_trigger_stages;
+ cfg->trig_glb = (num_enabled_channels << 4) | (num_trigger_stages - 1);
+
+ return num_trigger_stages != 0;
}
static int fpga_configure(const struct sr_dev_inst *sdi)
{
- struct dev_context *devc;
- struct sr_usb_dev_inst *usb;
+ const struct dev_context *const devc = sdi->priv;
+ const struct sr_usb_dev_inst *const usb = sdi->conn;
uint8_t c[3];
- struct dslogic_fpga_config cfg;
- uint16_t v16;
- uint32_t v32;
+ struct fpga_config cfg;
+ uint16_t mode = 0;
+ uint32_t divider;
int transferred, len, ret;
sr_dbg("Configuring FPGA.");
- usb = sdi->conn;
- devc = sdi->priv;
-
WL32(&cfg.sync, DS_CFG_START);
WL16(&cfg.mode_header, DS_CFG_MODE);
WL16(&cfg.divider_header, DS_CFG_DIVIDER);
WL32(&cfg.end_sync, DS_CFG_END);
/* Pass in the length of a fixed-size struct. Really. */
- len = sizeof(struct dslogic_fpga_config) / 2;
+ len = sizeof(struct fpga_config) / 2;
c[0] = len & 0xff;
c[1] = (len >> 8) & 0xff;
c[2] = (len >> 16) & 0xff;
return SR_ERR;
}
- v16 = 0x0000;
+ if (set_trigger(sdi, &cfg))
+ mode |= DS_MODE_TRIG_EN;
if (devc->mode == DS_OP_INTERNAL_TEST)
- v16 = DS_MODE_INT_TEST;
+ mode |= DS_MODE_INT_TEST;
else if (devc->mode == DS_OP_EXTERNAL_TEST)
- v16 = DS_MODE_EXT_TEST;
+ mode |= DS_MODE_EXT_TEST;
else if (devc->mode == DS_OP_LOOPBACK_TEST)
- v16 = DS_MODE_LPB_TEST;
+ mode |= DS_MODE_LPB_TEST;
if (devc->cur_samplerate == DS_MAX_LOGIC_SAMPLERATE * 2)
- v16 |= DS_MODE_HALF_MODE;
+ mode |= DS_MODE_HALF_MODE;
else if (devc->cur_samplerate == DS_MAX_LOGIC_SAMPLERATE * 4)
- v16 |= DS_MODE_QUAR_MODE;
+ mode |= DS_MODE_QUAR_MODE;
if (devc->continuous_mode)
- v16 |= DS_MODE_STREAM_MODE;
+ mode |= DS_MODE_STREAM_MODE;
if (devc->external_clock) {
- v16 |= DS_MODE_CLK_TYPE;
+ mode |= DS_MODE_CLK_TYPE;
if (devc->clock_edge == DS_EDGE_FALLING)
- v16 |= DS_MODE_CLK_EDGE;
+ mode |= DS_MODE_CLK_EDGE;
}
if (devc->limit_samples > DS_MAX_LOGIC_DEPTH *
ceil(devc->cur_samplerate * 1.0 / DS_MAX_LOGIC_SAMPLERATE)
/* Enable RLE for long captures.
* Without this, captured data present errors.
*/
- v16 |= DS_MODE_RLE_MODE;
+ mode |= DS_MODE_RLE_MODE;
}
- WL16(&cfg.mode, v16);
- v32 = ceil(DS_MAX_LOGIC_SAMPLERATE * 1.0 / devc->cur_samplerate);
- WL32(&cfg.divider, v32);
+ WL16(&cfg.mode, mode);
+ divider = ceil(DS_MAX_LOGIC_SAMPLERATE * 1.0 / devc->cur_samplerate);
+ WL32(&cfg.divider, divider);
/* Number of 16-sample units. */
WL32(&cfg.count, devc->limit_samples / 16);
- set_trigger(sdi, &cfg);
-
- len = sizeof(struct dslogic_fpga_config);
+ len = sizeof(struct fpga_config);
ret = libusb_bulk_transfer(usb->devhdl, 2 | LIBUSB_ENDPOINT_OUT,
(unsigned char *)&cfg, len, &transferred, USB_TIMEOUT);
if (ret < 0 || transferred != len) {
struct dev_context *devc;
struct drv_context *drvc;
struct version_info vi;
- int ret, i, device_count;
+ int ret = SR_ERR, i, device_count;
uint8_t revid;
char connection_id[64];
devc = sdi->priv;
usb = sdi->conn;
- if (sdi->status == SR_ST_ACTIVE)
- /* Device is already in use. */
- return SR_ERR;
-
device_count = libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist);
if (device_count < 0) {
sr_err("Failed to get device list: %s.",
if ((sdi->status == SR_ST_INITIALIZING) ||
(sdi->status == SR_ST_INACTIVE)) {
- /*
- * Check device by its physical USB bus/port address.
- */
- usb_get_port_path(devlist[i], connection_id, sizeof(connection_id));
+ /* Check device by its physical USB bus/port address. */
+ if (usb_get_port_path(devlist[i], connection_id, sizeof(connection_id)) < 0)
+ continue;
+
if (strcmp(sdi->connection_id, connection_id))
/* This is not the one. */
continue;
} else {
sr_err("Failed to open device: %s.",
libusb_error_name(ret));
+ ret = SR_ERR;
break;
}
if ((ret = libusb_detach_kernel_driver(usb->devhdl, USB_INTERFACE)) < 0) {
sr_err("Failed to detach kernel driver: %s.",
libusb_error_name(ret));
- return SR_ERR;
+ ret = SR_ERR;
+ break;
}
}
}
sr_err("Expected firmware version %d.x, "
"got %d.%d.", DSLOGIC_REQUIRED_VERSION_MAJOR,
vi.major, vi.minor);
+ ret = SR_ERR;
break;
}
- sdi->status = SR_ST_ACTIVE;
sr_info("Opened device on %d.%d (logical) / %s (physical), "
"interface %d, firmware %d.%d.",
usb->bus, usb->address, connection_id,
sr_info("Detected REVID=%d, it's a Cypress CY7C68013%s.",
revid, (revid != 1) ? " (FX2)" : "A (FX2LP)");
+ ret = SR_OK;
+
break;
}
- libusb_free_device_list(devlist, 1);
- if (sdi->status != SR_ST_ACTIVE)
- return SR_ERR;
+ libusb_free_device_list(devlist, 1);
- return SR_OK;
+ return ret;
}
SR_PRIV struct dev_context *dslogic_dev_new(void)
for (int bit = 0; bit != 64; bit++) {
const uint64_t *word_ptr = src_ptr;
sample = 0;
- for (size_t channel = 0; channel != channel_count;
+ for (unsigned int channel = 0; channel != 16;
channel++) {
- if ((channel_mask & (1 << channel)) &&
- (*word_ptr++ & (1ULL << bit)))
+ const uint16_t m = channel_mask >> channel;
+ if (!m)
+ break;
+ if ((m & 1) && ((*word_ptr++ >> bit) & UINT64_C(1)))
sample |= 1 << channel;
}
*dst_ptr++ = sample;
*
* Hopefully in future it will be possible to pass the data on as-is.
*/
- assert(transfer->actual_length % (DSLOGIC_ATOMIC_BYTES * channel_count) == 0);
+ if (transfer->actual_length % (DSLOGIC_ATOMIC_BYTES * channel_count) != 0)
+ sr_err("Invalid transfer length!");
deinterleave_buffer(transfer->buffer, transfer->actual_length,
devc->deinterleave_buffer, channel_count, channel_mask);
*/
const size_t block_size = enabled_channel_count(sdi) * 512;
const size_t s = 10 * to_bytes_per_ms(sdi);
+ if (!block_size)
+ return s;
return ((s + block_size - 1) / block_size) * block_size;
}
} else if (transfer->status == LIBUSB_TRANSFER_COMPLETED
&& transfer->actual_length == sizeof(struct dslogic_trigger_pos)) {
tpos = (struct dslogic_trigger_pos *)transfer->buffer;
- sr_info("tpos real_pos %d ram_saddr %d cnt %d", tpos->real_pos,
- tpos->ram_saddr, tpos->remain_cnt);
+ sr_info("tpos real_pos %d ram_saddr %d cnt_h %d cnt_l %d", tpos->real_pos,
+ tpos->ram_saddr, tpos->remain_cnt_h, tpos->remain_cnt_l);
devc->trigger_pos = tpos->real_pos;
g_free(tpos);
start_transfers(sdi);
struct libusb_transfer *transfer;
int ret;
- if (sdi->status != SR_ST_ACTIVE)
- return SR_ERR_DEV_CLOSED;
-
di = sdi->driver;
drvc = di->context;
devc = sdi->priv;