X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Fsaleae-logic16%2Fprotocol.c;h=a3dc0900f04fb8d6f63967ae592fc12b9ff336d4;hb=b7a3d79e46b520e799239475b282247f4f13a386;hp=9e5806e0ae4c89c620121e158b345753d38022dd;hpb=974fb0fffaffb0b2d1437ee280e4308a252741a0;p=libsigrok.git
diff --git a/src/hardware/saleae-logic16/protocol.c b/src/hardware/saleae-logic16/protocol.c
index 9e5806e0..a3dc0900 100644
--- a/src/hardware/saleae-logic16/protocol.c
+++ b/src/hardware/saleae-logic16/protocol.c
@@ -19,8 +19,7 @@
* along with this program. If not, see .
*/
-#include "protocol.h"
-
+#include
#include
#include
#include
@@ -28,18 +27,15 @@
#include
#include
#include
-#include "libsigrok.h"
+#include
#include "libsigrok-internal.h"
+#include "protocol.h"
-#define FPGA_FIRMWARE_18 FIRMWARE_DIR"/saleae-logic16-fpga-18.bitstream"
-#define FPGA_FIRMWARE_33 FIRMWARE_DIR"/saleae-logic16-fpga-33.bitstream"
+#define FPGA_FIRMWARE_18 "saleae-logic16-fpga-18.bitstream"
+#define FPGA_FIRMWARE_33 "saleae-logic16-fpga-33.bitstream"
#define MAX_SAMPLE_RATE SR_MHZ(100)
-#define MAX_4CH_SAMPLE_RATE SR_MHZ(50)
-#define MAX_7CH_SAMPLE_RATE SR_MHZ(40)
-#define MAX_8CH_SAMPLE_RATE SR_MHZ(32)
-#define MAX_10CH_SAMPLE_RATE SR_MHZ(25)
-#define MAX_13CH_SAMPLE_RATE SR_MHZ(16)
+#define MAX_SAMPLE_RATE_X_CH SR_MHZ(300)
#define BASE_CLOCK_0_FREQ SR_MHZ(100)
#define BASE_CLOCK_1_FREQ SR_MHZ(160)
@@ -66,6 +62,101 @@
#define MAX_EMPTY_TRANSFERS 64
+/* Register mappings for old and new bitstream versions */
+
+enum fpga_register_id {
+ FPGA_REGISTER_VERSION,
+ FPGA_REGISTER_STATUS_CONTROL,
+ FPGA_REGISTER_CHANNEL_SELECT_LOW,
+ FPGA_REGISTER_CHANNEL_SELECT_HIGH,
+ FPGA_REGISTER_SAMPLE_RATE_DIVISOR,
+ FPGA_REGISTER_LED_BRIGHTNESS,
+ FPGA_REGISTER_PRIMER_DATA1,
+ FPGA_REGISTER_PRIMER_CONTROL,
+ FPGA_REGISTER_MODE,
+ FPGA_REGISTER_PRIMER_DATA2,
+ FPGA_REGISTER_MAX = FPGA_REGISTER_PRIMER_DATA2
+};
+
+enum fpga_status_control_bit {
+ FPGA_STATUS_CONTROL_BIT_RUNNING,
+ FPGA_STATUS_CONTROL_BIT_UPDATE,
+ FPGA_STATUS_CONTROL_BIT_UNKNOWN1,
+ FPGA_STATUS_CONTROL_BIT_OVERFLOW,
+ FPGA_STATUS_CONTROL_BIT_UNKNOWN2,
+ FPGA_STATUS_CONTROL_BIT_MAX = FPGA_STATUS_CONTROL_BIT_UNKNOWN2
+};
+
+enum fpga_mode_bit {
+ FPGA_MODE_BIT_CLOCK,
+ FPGA_MODE_BIT_UNKNOWN1,
+ FPGA_MODE_BIT_UNKNOWN2,
+ FPGA_MODE_BIT_MAX = FPGA_MODE_BIT_UNKNOWN2
+};
+
+static const uint8_t fpga_register_map_old[FPGA_REGISTER_MAX + 1] = {
+ [FPGA_REGISTER_VERSION] = 0,
+ [FPGA_REGISTER_STATUS_CONTROL] = 1,
+ [FPGA_REGISTER_CHANNEL_SELECT_LOW] = 2,
+ [FPGA_REGISTER_CHANNEL_SELECT_HIGH] = 3,
+ [FPGA_REGISTER_SAMPLE_RATE_DIVISOR] = 4,
+ [FPGA_REGISTER_LED_BRIGHTNESS] = 5,
+ [FPGA_REGISTER_PRIMER_DATA1] = 6,
+ [FPGA_REGISTER_PRIMER_CONTROL] = 7,
+ [FPGA_REGISTER_MODE] = 10,
+ [FPGA_REGISTER_PRIMER_DATA2] = 12,
+};
+
+static const uint8_t fpga_register_map_new[FPGA_REGISTER_MAX + 1] = {
+ [FPGA_REGISTER_VERSION] = 7,
+ [FPGA_REGISTER_STATUS_CONTROL] = 15,
+ [FPGA_REGISTER_CHANNEL_SELECT_LOW] = 1,
+ [FPGA_REGISTER_CHANNEL_SELECT_HIGH] = 6,
+ [FPGA_REGISTER_SAMPLE_RATE_DIVISOR] = 11,
+ [FPGA_REGISTER_LED_BRIGHTNESS] = 5,
+ [FPGA_REGISTER_PRIMER_DATA1] = 14,
+ [FPGA_REGISTER_PRIMER_CONTROL] = 2,
+ [FPGA_REGISTER_MODE] = 4,
+ [FPGA_REGISTER_PRIMER_DATA2] = 3,
+};
+
+static const uint8_t fpga_status_control_bit_map_old[FPGA_STATUS_CONTROL_BIT_MAX + 1] = {
+ [FPGA_STATUS_CONTROL_BIT_RUNNING] = 0x01,
+ [FPGA_STATUS_CONTROL_BIT_UPDATE] = 0x02,
+ [FPGA_STATUS_CONTROL_BIT_UNKNOWN1] = 0x08,
+ [FPGA_STATUS_CONTROL_BIT_OVERFLOW] = 0x20,
+ [FPGA_STATUS_CONTROL_BIT_UNKNOWN2] = 0x40,
+};
+
+static const uint8_t fpga_status_control_bit_map_new[FPGA_STATUS_CONTROL_BIT_MAX + 1] = {
+ [FPGA_STATUS_CONTROL_BIT_RUNNING] = 0x20,
+ [FPGA_STATUS_CONTROL_BIT_UPDATE] = 0x08,
+ [FPGA_STATUS_CONTROL_BIT_UNKNOWN1] = 0x10,
+ [FPGA_STATUS_CONTROL_BIT_OVERFLOW] = 0x01,
+ [FPGA_STATUS_CONTROL_BIT_UNKNOWN2] = 0x04,
+};
+
+static const uint8_t fpga_mode_bit_map_old[FPGA_MODE_BIT_MAX + 1] = {
+ [FPGA_MODE_BIT_CLOCK] = 0x01,
+ [FPGA_MODE_BIT_UNKNOWN1] = 0x40,
+ [FPGA_MODE_BIT_UNKNOWN2] = 0x80,
+};
+
+static const uint8_t fpga_mode_bit_map_new[FPGA_MODE_BIT_MAX + 1] = {
+ [FPGA_MODE_BIT_CLOCK] = 0x04,
+ [FPGA_MODE_BIT_UNKNOWN1] = 0x80,
+ [FPGA_MODE_BIT_UNKNOWN2] = 0x01,
+};
+
+#define FPGA_REG(x) \
+ (devc->fpga_register_map[FPGA_REGISTER_ ## x])
+
+#define FPGA_STATUS_CONTROL(x) \
+ (devc->fpga_status_control_bit_map[FPGA_STATUS_CONTROL_BIT_ ## x])
+
+#define FPGA_MODE(x) \
+ (devc->fpga_mode_bit_map[FPGA_MODE_BIT_ ## x])
+
static void encrypt(uint8_t *dest, const uint8_t *src, uint8_t cnt)
{
uint8_t state1 = 0x9b, state2 = 0x54;
@@ -107,7 +198,7 @@ static int do_ep1_command(const struct sr_dev_inst *sdi,
usb = sdi->conn;
if (cmd_len < 1 || cmd_len > 64 || reply_len > 64 ||
- command == NULL || (reply_len > 0 && reply == NULL))
+ !command || (reply_len > 0 && !reply))
return SR_ERR_ARG;
encrypt(buf, command, cmd_len);
@@ -120,7 +211,7 @@ static int do_ep1_command(const struct sr_dev_inst *sdi,
}
if (xfer != cmd_len) {
sr_dbg("Failed to send EP1 command 0x%02x: incorrect length "
- "%d != %d.", xfer, cmd_len);
+ "%d != %d.", command[0], xfer, cmd_len);
return SR_ERR;
}
@@ -136,7 +227,7 @@ static int do_ep1_command(const struct sr_dev_inst *sdi,
}
if (xfer != reply_len) {
sr_dbg("Failed to receive reply to EP1 command 0x%02x: "
- "incorrect length %d != %d.", xfer, reply_len);
+ "incorrect length %d != %d.", command[0], xfer, reply_len);
return SR_ERR;
}
@@ -165,7 +256,7 @@ static int upload_led_table(const struct sr_dev_inst *sdi,
uint8_t chunk, command[64];
int ret;
- if (cnt < 1 || cnt + offset > 64 || table == NULL)
+ if (cnt < 1 || cnt + offset > 64 || !table)
return SR_ERR_ARG;
while (cnt > 0) {
@@ -248,32 +339,76 @@ static uint8_t map_eeprom_data(uint8_t v)
return (((v ^ 0x80) + 0x44) ^ 0xd5) + 0x69;
}
+static int setup_register_mapping(const struct sr_dev_inst *sdi)
+{
+ struct dev_context *devc;
+ int ret;
+
+ devc = sdi->priv;
+
+ if (devc->fpga_variant != FPGA_VARIANT_MCUPRO) {
+ uint8_t reg0, reg7;
+
+ /*
+ * Check for newer bitstream version by polling the
+ * version register at the old and new location.
+ */
+
+ if ((ret = read_fpga_register(sdi, 0 /* No mapping */, ®0)) != SR_OK)
+ return ret;
+
+ if ((ret = read_fpga_register(sdi, 7 /* No mapping */, ®7)) != SR_OK)
+ return ret;
+
+ if (reg0 == 0 && reg7 > 0x10) {
+ sr_info("Original Saleae Logic16 using new bitstream.");
+ devc->fpga_variant = FPGA_VARIANT_ORIGINAL_NEW_BITSTREAM;
+ } else {
+ sr_info("Original Saleae Logic16 using old bitstream.");
+ devc->fpga_variant = FPGA_VARIANT_ORIGINAL;
+ }
+ }
+
+ if (devc->fpga_variant == FPGA_VARIANT_ORIGINAL_NEW_BITSTREAM) {
+ devc->fpga_register_map = fpga_register_map_new;
+ devc->fpga_status_control_bit_map = fpga_status_control_bit_map_new;
+ devc->fpga_mode_bit_map = fpga_mode_bit_map_new;
+ } else {
+ devc->fpga_register_map = fpga_register_map_old;
+ devc->fpga_status_control_bit_map = fpga_status_control_bit_map_old;
+ devc->fpga_mode_bit_map = fpga_mode_bit_map_old;
+ }
+
+ return SR_OK;
+}
+
static int prime_fpga(const struct sr_dev_inst *sdi)
{
+ struct dev_context *devc = sdi->priv;
uint8_t eeprom_data[16];
- uint8_t old_reg_10, version;
+ uint8_t old_mode_reg, version;
uint8_t regs[8][2] = {
- {10, 0x00},
- {10, 0x40},
- {12, 0},
- {10, 0xc0},
- {10, 0x40},
- {6, 0},
- {7, 1},
- {7, 0}
+ {FPGA_REG(MODE), 0x00},
+ {FPGA_REG(MODE), FPGA_MODE(UNKNOWN1)},
+ {FPGA_REG(PRIMER_DATA2), 0},
+ {FPGA_REG(MODE), FPGA_MODE(UNKNOWN1) | FPGA_MODE(UNKNOWN2)},
+ {FPGA_REG(MODE), FPGA_MODE(UNKNOWN1)},
+ {FPGA_REG(PRIMER_DATA1), 0},
+ {FPGA_REG(PRIMER_CONTROL), 1},
+ {FPGA_REG(PRIMER_CONTROL), 0}
};
int i, ret;
if ((ret = read_eeprom(sdi, 16, 16, eeprom_data)) != SR_OK)
return ret;
- if ((ret = read_fpga_register(sdi, 10, &old_reg_10)) != SR_OK)
+ if ((ret = read_fpga_register(sdi, FPGA_REG(MODE), &old_mode_reg)) != SR_OK)
return ret;
- regs[0][1] = (old_reg_10 &= 0x7f);
- regs[1][1] |= old_reg_10;
- regs[3][1] |= old_reg_10;
- regs[4][1] |= old_reg_10;
+ regs[0][1] = (old_mode_reg &= ~FPGA_MODE(UNKNOWN2));
+ regs[1][1] |= old_mode_reg;
+ regs[3][1] |= old_mode_reg;
+ regs[4][1] |= old_mode_reg;
for (i = 0; i < 16; i++) {
regs[2][1] = eeprom_data[i];
@@ -286,13 +421,13 @@ static int prime_fpga(const struct sr_dev_inst *sdi)
return ret;
}
- if ((ret = write_fpga_register(sdi, 10, old_reg_10)) != SR_OK)
+ if ((ret = write_fpga_register(sdi, FPGA_REG(MODE), old_mode_reg)) != SR_OK)
return ret;
- if ((ret = read_fpga_register(sdi, 0, &version)) != SR_OK)
+ if ((ret = read_fpga_register(sdi, FPGA_REG(VERSION), &version)) != SR_OK)
return ret;
- if (version != 0x10 && version != 0x40 && version != 0x41) {
+ if (version != 0x10 && version != 0x13 && version != 0x40 && version != 0x41) {
sr_err("Unsupported FPGA version: 0x%02x.", version);
return SR_ERR;
}
@@ -308,7 +443,7 @@ static void make_heartbeat(uint8_t *table, int len)
len >>= 3;
for (i = 0; i < 2; i++)
for (j = 0; j < len; j++)
- *table++ = sin(j * M_PI / len) * 255;
+ *table++ = sin(j * G_PI / len) * 255;
}
static int configure_led(const struct sr_dev_inst *sdi)
@@ -326,67 +461,75 @@ static int configure_led(const struct sr_dev_inst *sdi)
static int upload_fpga_bitstream(const struct sr_dev_inst *sdi,
enum voltage_range vrange)
{
+ uint64_t sum;
+ struct sr_resource bitstream;
struct dev_context *devc;
- int offset, chunksize, ret;
- const char *filename;
- uint8_t len, buf[256 * 62], command[64];
- FILE *fw;
+ struct drv_context *drvc;
+ const char *name;
+ ssize_t chunksize;
+ int ret;
+ uint8_t command[64];
devc = sdi->priv;
+ drvc = sdi->driver->context;
if (devc->cur_voltage_range == vrange)
return SR_OK;
- if (devc->fpga_variant == FPGA_VARIANT_ORIGINAL) {
+ if (devc->fpga_variant != FPGA_VARIANT_MCUPRO) {
switch (vrange) {
case VOLTAGE_RANGE_18_33_V:
- filename = FPGA_FIRMWARE_18;
+ name = FPGA_FIRMWARE_18;
break;
case VOLTAGE_RANGE_5_V:
- filename = FPGA_FIRMWARE_33;
+ name = FPGA_FIRMWARE_33;
break;
default:
sr_err("Unsupported voltage range.");
return SR_ERR;
}
- sr_info("Uploading FPGA bitstream at %s.", filename);
- if ((fw = g_fopen(filename, "rb")) == NULL) {
- sr_err("Unable to open bitstream file %s for reading: %s.",
- filename, strerror(errno));
- return SR_ERR;
- }
+ sr_info("Uploading FPGA bitstream '%s'.", name);
+ ret = sr_resource_open(drvc->sr_ctx, &bitstream,
+ SR_RESOURCE_FIRMWARE, name);
+ if (ret != SR_OK)
+ return ret;
- buf[0] = COMMAND_FPGA_UPLOAD_INIT;
- if ((ret = do_ep1_command(sdi, buf, 1, NULL, 0)) != SR_OK) {
- fclose(fw);
+ command[0] = COMMAND_FPGA_UPLOAD_INIT;
+ if ((ret = do_ep1_command(sdi, command, 1, NULL, 0)) != SR_OK) {
+ sr_resource_close(drvc->sr_ctx, &bitstream);
return ret;
}
+ sum = 0;
while (1) {
- chunksize = fread(buf, 1, sizeof(buf), fw);
+ chunksize = sr_resource_read(drvc->sr_ctx, &bitstream,
+ &command[2], sizeof(command) - 2);
+ if (chunksize < 0) {
+ sr_resource_close(drvc->sr_ctx, &bitstream);
+ return SR_ERR;
+ }
if (chunksize == 0)
break;
-
- for (offset = 0; offset < chunksize; offset += 62) {
- len = (offset + 62 > chunksize ?
- chunksize - offset : 62);
- command[0] = COMMAND_FPGA_UPLOAD_SEND_DATA;
- command[1] = len;
- memcpy(command + 2, buf + offset, len);
- ret = do_ep1_command(sdi, command, len + 2, NULL, 0);
- if (ret != SR_OK) {
- fclose(fw);
- return ret;
- }
+ command[0] = COMMAND_FPGA_UPLOAD_SEND_DATA;
+ command[1] = chunksize;
+
+ ret = do_ep1_command(sdi, command, chunksize + 2,
+ NULL, 0);
+ if (ret != SR_OK) {
+ sr_resource_close(drvc->sr_ctx, &bitstream);
+ return ret;
}
-
- sr_info("Uploaded %d bytes.", chunksize);
+ sum += chunksize;
}
- fclose(fw);
- sr_info("FPGA bitstream upload done.");
+ sr_resource_close(drvc->sr_ctx, &bitstream);
+ sr_info("FPGA bitstream upload (%" PRIu64 " bytes) done.", sum);
}
+ /* This needs to be called before accessing any FPGA registers. */
+ if ((ret = setup_register_mapping(sdi)) != SR_OK)
+ return ret;
+
if ((ret = prime_fpga(sdi)) != SR_OK)
return ret;
@@ -422,7 +565,7 @@ static int abort_acquisition_sync(const struct sr_dev_inst *sdi)
SR_PRIV int logic16_setup_acquisition(const struct sr_dev_inst *sdi,
uint64_t samplerate, uint16_t channels)
{
- uint8_t clock_select, reg1, reg10;
+ uint8_t clock_select, sta_con_reg, mode_reg;
uint64_t div;
int i, ret, nchan = 0;
struct dev_context *devc;
@@ -449,11 +592,7 @@ SR_PRIV int logic16_setup_acquisition(const struct sr_dev_inst *sdi,
if (channels & (1U << i))
nchan++;
- if ((nchan >= 13 && samplerate > MAX_13CH_SAMPLE_RATE) ||
- (nchan >= 10 && samplerate > MAX_10CH_SAMPLE_RATE) ||
- (nchan >= 8 && samplerate > MAX_8CH_SAMPLE_RATE) ||
- (nchan >= 7 && samplerate > MAX_7CH_SAMPLE_RATE) ||
- (nchan >= 4 && samplerate > MAX_4CH_SAMPLE_RATE)) {
+ if (nchan * samplerate > MAX_SAMPLE_RATE_X_CH) {
sr_err("Unable to sample at %" PRIu64 "Hz "
"with this many channels.", samplerate);
return SR_ERR;
@@ -463,52 +602,52 @@ SR_PRIV int logic16_setup_acquisition(const struct sr_dev_inst *sdi,
if (ret != SR_OK)
return ret;
- if ((ret = read_fpga_register(sdi, 1, ®1)) != SR_OK)
+ if ((ret = read_fpga_register(sdi, FPGA_REG(STATUS_CONTROL), &sta_con_reg)) != SR_OK)
return ret;
/* Ignore FIFO overflow on previous capture */
- reg1 &= ~0x20;
+ sta_con_reg &= ~FPGA_STATUS_CONTROL(OVERFLOW);
- if (devc->fpga_variant == FPGA_VARIANT_ORIGINAL && reg1 != 0x08) {
- sr_dbg("Invalid state at acquisition setup register 1: 0x%02x != 0x08. "
- "Proceeding anyway.", reg1);
+ if (devc->fpga_variant != FPGA_VARIANT_MCUPRO && sta_con_reg != FPGA_STATUS_CONTROL(UNKNOWN1)) {
+ sr_dbg("Invalid state at acquisition setup register 1: 0x%02x != 0x%02x. "
+ "Proceeding anyway.", sta_con_reg, FPGA_STATUS_CONTROL(UNKNOWN1));
}
- if ((ret = write_fpga_register(sdi, 1, 0x40)) != SR_OK)
+ if ((ret = write_fpga_register(sdi, FPGA_REG(STATUS_CONTROL), FPGA_STATUS_CONTROL(UNKNOWN2))) != SR_OK)
return ret;
- if ((ret = write_fpga_register(sdi, 10, clock_select)) != SR_OK)
+ if ((ret = write_fpga_register(sdi, FPGA_REG(MODE), (clock_select? FPGA_MODE(CLOCK) : 0))) != SR_OK)
return ret;
- if ((ret = write_fpga_register(sdi, 4, (uint8_t)(div - 1))) != SR_OK)
+ if ((ret = write_fpga_register(sdi, FPGA_REG(SAMPLE_RATE_DIVISOR), (uint8_t)(div - 1))) != SR_OK)
return ret;
- if ((ret = write_fpga_register(sdi, 2, (uint8_t)(channels & 0xff))) != SR_OK)
+ if ((ret = write_fpga_register(sdi, FPGA_REG(CHANNEL_SELECT_LOW), (uint8_t)(channels & 0xff))) != SR_OK)
return ret;
- if ((ret = write_fpga_register(sdi, 3, (uint8_t)(channels >> 8))) != SR_OK)
+ if ((ret = write_fpga_register(sdi, FPGA_REG(CHANNEL_SELECT_HIGH), (uint8_t)(channels >> 8))) != SR_OK)
return ret;
- if ((ret = write_fpga_register(sdi, 1, 0x42)) != SR_OK)
+ if ((ret = write_fpga_register(sdi, FPGA_REG(STATUS_CONTROL), FPGA_STATUS_CONTROL(UNKNOWN2) | FPGA_STATUS_CONTROL(UPDATE))) != SR_OK)
return ret;
- if ((ret = write_fpga_register(sdi, 1, 0x40)) != SR_OK)
+ if ((ret = write_fpga_register(sdi, FPGA_REG(STATUS_CONTROL), FPGA_STATUS_CONTROL(UNKNOWN2))) != SR_OK)
return ret;
- if ((ret = read_fpga_register(sdi, 1, ®1)) != SR_OK)
+ if ((ret = read_fpga_register(sdi, FPGA_REG(STATUS_CONTROL), &sta_con_reg)) != SR_OK)
return ret;
- if (devc->fpga_variant == FPGA_VARIANT_ORIGINAL && reg1 != 0x48) {
- sr_dbg("Invalid state at acquisition setup register 1: 0x%02x != 0x48. "
- "Proceeding anyway.", reg1);
+ if (devc->fpga_variant != FPGA_VARIANT_MCUPRO && sta_con_reg != (FPGA_STATUS_CONTROL(UNKNOWN2) | FPGA_STATUS_CONTROL(UNKNOWN1))) {
+ sr_dbg("Invalid state at acquisition setup register 1: 0x%02x != 0x%02x. "
+ "Proceeding anyway.", sta_con_reg, FPGA_STATUS_CONTROL(UNKNOWN2) | FPGA_STATUS_CONTROL(UNKNOWN1));
}
- if ((ret = read_fpga_register(sdi, 10, ®10)) != SR_OK)
+ if ((ret = read_fpga_register(sdi, FPGA_REG(MODE), &mode_reg)) != SR_OK)
return ret;
- if (devc->fpga_variant == FPGA_VARIANT_ORIGINAL && reg10 != clock_select) {
+ if (devc->fpga_variant != FPGA_VARIANT_MCUPRO && mode_reg != (clock_select? FPGA_MODE(CLOCK) : 0)) {
sr_dbg("Invalid state at acquisition setup register 10: 0x%02x != 0x%02x. "
- "Proceeding anyway.", reg10, clock_select);
+ "Proceeding anyway.", mode_reg, (clock_select? FPGA_MODE(CLOCK) : 0));
}
return SR_OK;
@@ -520,11 +659,14 @@ SR_PRIV int logic16_start_acquisition(const struct sr_dev_inst *sdi)
COMMAND_START_ACQUISITION,
};
int ret;
+ struct dev_context *devc;
+
+ devc = sdi->priv;
if ((ret = do_ep1_command(sdi, command, 1, NULL, 0)) != SR_OK)
return ret;
- return write_fpga_register(sdi, 1, 0x41);
+ return write_fpga_register(sdi, FPGA_REG(STATUS_CONTROL), FPGA_STATUS_CONTROL(UNKNOWN2) | FPGA_STATUS_CONTROL(RUNNING));
}
SR_PRIV int logic16_abort_acquisition(const struct sr_dev_inst *sdi)
@@ -533,7 +675,7 @@ SR_PRIV int logic16_abort_acquisition(const struct sr_dev_inst *sdi)
COMMAND_ABORT_ACQUISITION_ASYNC,
};
int ret;
- uint8_t reg1, reg8, reg9;
+ uint8_t sta_con_reg;
struct dev_context *devc;
devc = sdi->priv;
@@ -541,24 +683,29 @@ SR_PRIV int logic16_abort_acquisition(const struct sr_dev_inst *sdi)
if ((ret = do_ep1_command(sdi, command, 1, NULL, 0)) != SR_OK)
return ret;
- if ((ret = write_fpga_register(sdi, 1, 0x00)) != SR_OK)
+ if ((ret = write_fpga_register(sdi, FPGA_REG(STATUS_CONTROL), 0x00)) != SR_OK)
return ret;
- if ((ret = read_fpga_register(sdi, 1, ®1)) != SR_OK)
+ if ((ret = read_fpga_register(sdi, FPGA_REG(STATUS_CONTROL), &sta_con_reg)) != SR_OK)
return ret;
- if (devc->fpga_variant == FPGA_VARIANT_ORIGINAL && (reg1 & ~0x20) != 0x08) {
- sr_dbg("Invalid state at acquisition stop: 0x%02x != 0x08.", reg1 & ~0x20);
+ if (devc->fpga_variant != FPGA_VARIANT_MCUPRO && (sta_con_reg & ~FPGA_STATUS_CONTROL(OVERFLOW)) != FPGA_STATUS_CONTROL(UNKNOWN1)) {
+ sr_dbg("Invalid state at acquisition stop: 0x%02x != 0x%02x.", sta_con_reg & ~0x20, FPGA_STATUS_CONTROL(UNKNOWN1));
return SR_ERR;
}
- if ((ret = read_fpga_register(sdi, 8, ®8)) != SR_OK)
- return ret;
- if ((ret = read_fpga_register(sdi, 9, ®9)) != SR_OK)
- return ret;
+ if (devc->fpga_variant == FPGA_VARIANT_ORIGINAL) {
+ uint8_t reg8, reg9;
+
+ if ((ret = read_fpga_register(sdi, 8, ®8)) != SR_OK)
+ return ret;
- if (devc->fpga_variant == FPGA_VARIANT_ORIGINAL && reg1 & 0x20) {
+ if ((ret = read_fpga_register(sdi, 9, ®9)) != SR_OK)
+ return ret;
+ }
+
+ if (devc->fpga_variant != FPGA_VARIANT_MCUPRO && sta_con_reg & FPGA_STATUS_CONTROL(OVERFLOW)) {
sr_warn("FIFO overflow, capture data may be truncated.");
return SR_ERR;
}
@@ -584,7 +731,7 @@ SR_PRIV int logic16_init_device(const struct sr_dev_inst *sdi)
/* mcupro Saleae16 has firmware pre-stored in FPGA.
So, we can query it right away. */
- if (read_fpga_register(sdi, 0, &version) == SR_OK &&
+ if (read_fpga_register(sdi, 0 /* No mapping */, &version) == SR_OK &&
(version == 0x40 || version == 0x41)) {
sr_info("mcupro Saleae16 detected.");
devc->fpga_variant = FPGA_VARIANT_MCUPRO;
@@ -602,16 +749,12 @@ SR_PRIV int logic16_init_device(const struct sr_dev_inst *sdi)
static void finish_acquisition(struct sr_dev_inst *sdi)
{
- struct sr_datafeed_packet packet;
struct dev_context *devc;
devc = sdi->priv;
- /* Terminate session. */
- packet.type = SR_DF_END;
- sr_session_send(devc->cb_data, &packet);
+ std_session_send_df_end(sdi);
- /* Remove fds from polling. */
usb_source_remove(sdi->session, devc->ctx);
devc->num_transfers = 0;
@@ -703,7 +846,7 @@ static size_t convert_sample_data(struct dev_context *devc,
return ret;
}
-SR_PRIV void logic16_receive_transfer(struct libusb_transfer *transfer)
+SR_PRIV void LIBUSB_CALL logic16_receive_transfer(struct libusb_transfer *transfer)
{
gboolean packet_has_error = FALSE;
struct sr_datafeed_packet packet;
@@ -770,47 +913,51 @@ SR_PRIV void logic16_receive_transfer(struct libusb_transfer *transfer)
new_samples = convert_sample_data(devc, devc->convbuffer,
devc->convbuffer_size, transfer->buffer, transfer->actual_length);
- if (new_samples > 0) {
- if (devc->trigger_fired) {
- /* Send the incoming transfer to the session bus. */
+ if (new_samples <= 0) {
+ resubmit_transfer(transfer);
+ return;
+ }
+
+ /* At least one new sample. */
+ if (devc->trigger_fired) {
+ /* Send the incoming transfer to the session bus. */
+ packet.type = SR_DF_LOGIC;
+ packet.payload = &logic;
+ if (devc->limit_samples &&
+ new_samples > devc->limit_samples - devc->sent_samples)
+ new_samples = devc->limit_samples - devc->sent_samples;
+ logic.length = new_samples * 2;
+ logic.unitsize = 2;
+ logic.data = devc->convbuffer;
+ sr_session_send(sdi, &packet);
+ devc->sent_samples += new_samples;
+ } else {
+ trigger_offset = soft_trigger_logic_check(devc->stl,
+ devc->convbuffer, new_samples * 2, &pre_trigger_samples);
+ if (trigger_offset > -1) {
+ devc->sent_samples += pre_trigger_samples;
packet.type = SR_DF_LOGIC;
packet.payload = &logic;
+ num_samples = new_samples - trigger_offset;
if (devc->limit_samples &&
- new_samples > devc->limit_samples - devc->sent_samples)
- new_samples = devc->limit_samples - devc->sent_samples;
- logic.length = new_samples * 2;
+ num_samples > devc->limit_samples - devc->sent_samples)
+ num_samples = devc->limit_samples - devc->sent_samples;
+ logic.length = num_samples * 2;
logic.unitsize = 2;
- logic.data = devc->convbuffer;
- sr_session_send(devc->cb_data, &packet);
- devc->sent_samples += new_samples;
- } else {
- trigger_offset = soft_trigger_logic_check(devc->stl,
- devc->convbuffer, new_samples * 2, &pre_trigger_samples);
- if (trigger_offset > -1) {
- devc->sent_samples += pre_trigger_samples;
- packet.type = SR_DF_LOGIC;
- packet.payload = &logic;
- num_samples = new_samples - trigger_offset;
- if (devc->limit_samples &&
- num_samples > devc->limit_samples - devc->sent_samples)
- num_samples = devc->limit_samples - devc->sent_samples;
- logic.length = num_samples * 2;
- logic.unitsize = 2;
- logic.data = devc->convbuffer + trigger_offset * 2;
- sr_session_send(devc->cb_data, &packet);
- devc->sent_samples += num_samples;
-
- devc->trigger_fired = TRUE;
- }
- }
+ logic.data = devc->convbuffer + trigger_offset * 2;
+ sr_session_send(sdi, &packet);
+ devc->sent_samples += num_samples;
- if (devc->limit_samples &&
- (uint64_t)devc->sent_samples >= devc->limit_samples) {
- devc->sent_samples = -2;
- free_transfer(transfer);
- return;
+ devc->trigger_fired = TRUE;
}
}
+ if (devc->limit_samples &&
+ (uint64_t)devc->sent_samples >= devc->limit_samples) {
+ devc->sent_samples = -2;
+ free_transfer(transfer);
+ return;
+ }
+
resubmit_transfer(transfer);
}