Add support for mcupro Logic16, a Saleae Logic16 clone.

From sigrok's point of view, this analyzer has two differences:

  * It does not require uploading the firmware.
  * It returns garbage in some registers used for sanity checks.
    Saleae's software ignores that garbage; sigrok only does if it
    specifically detects the mcupro clone.
This commit is contained in:
Peter Zotov 2014-08-22 22:27:56 +04:00 committed by Bert Vermeulen
parent f88c73732c
commit 6f479a0a72
2 changed files with 75 additions and 50 deletions

View File

@ -292,8 +292,8 @@ static int prime_fpga(const struct sr_dev_inst *sdi)
if ((ret = read_fpga_register(sdi, 0, &version)) != SR_OK)
return ret;
if (version != 0x10) {
sr_err("Invalid FPGA bitstream version: 0x%02x != 0x10.", version);
if (version != 0x10 && version != 0x40 && version != 0x41) {
sr_err("Unsupported FPGA version: 0x%02x.", version);
return SR_ERR;
}
@ -337,6 +337,7 @@ static int upload_fpga_bitstream(const struct sr_dev_inst *sdi,
if (devc->cur_voltage_range == vrange)
return SR_OK;
if (devc->fpga_variant == FPGA_VARIANT_ORIGINAL) {
switch (vrange) {
case VOLTAGE_RANGE_18_33_V:
filename = FPGA_FIRMWARE_18;
@ -384,6 +385,7 @@ static int upload_fpga_bitstream(const struct sr_dev_inst *sdi,
}
fclose(fw);
sr_info("FPGA bitstream upload done.");
}
if ((ret = prime_fpga(sdi)) != SR_OK)
return ret;
@ -467,7 +469,7 @@ SR_PRIV int logic16_setup_acquisition(const struct sr_dev_inst *sdi,
/* Ignore FIFO overflow on previous capture */
reg1 &= ~0x20;
if (reg1 != 0x08) {
if (devc->fpga_variant == FPGA_VARIANT_ORIGINAL && reg1 != 0x08) {
sr_dbg("Invalid state at acquisition setup: 0x%02x != 0x08.", reg1);
return SR_ERR;
}
@ -496,7 +498,7 @@ SR_PRIV int logic16_setup_acquisition(const struct sr_dev_inst *sdi,
if ((ret = read_fpga_register(sdi, 1, &reg1)) != SR_OK)
return ret;
if (reg1 != 0x48) {
if (devc->fpga_variant == FPGA_VARIANT_ORIGINAL && reg1 != 0x48) {
sr_dbg("Invalid state at acquisition setup: 0x%02x != 0x48.", reg1);
return SR_ERR;
}
@ -504,7 +506,7 @@ SR_PRIV int logic16_setup_acquisition(const struct sr_dev_inst *sdi,
if ((ret = read_fpga_register(sdi, 10, &reg10)) != SR_OK)
return ret;
if (reg10 != clock_select) {
if (devc->fpga_variant == FPGA_VARIANT_ORIGINAL && reg10 != clock_select) {
sr_dbg("Invalid state at acquisition setup: 0x%02x != 0x%02x.",
reg10, clock_select);
return SR_ERR;
@ -533,6 +535,9 @@ SR_PRIV int logic16_abort_acquisition(const struct sr_dev_inst *sdi)
};
int ret;
uint8_t reg1, reg8, reg9;
struct dev_context *devc;
devc = sdi->priv;
if ((ret = do_ep1_command(sdi, command, 1, NULL, 0)) != SR_OK)
return ret;
@ -543,7 +548,7 @@ SR_PRIV int logic16_abort_acquisition(const struct sr_dev_inst *sdi)
if ((ret = read_fpga_register(sdi, 1, &reg1)) != SR_OK)
return ret;
if ((reg1 & ~0x20) != 0x08) {
if (devc->fpga_variant == FPGA_VARIANT_ORIGINAL && (reg1 & ~0x20) != 0x08) {
sr_dbg("Invalid state at acquisition stop: 0x%02x != 0x08.", reg1 & ~0x20);
return SR_ERR;
}
@ -554,7 +559,7 @@ SR_PRIV int logic16_abort_acquisition(const struct sr_dev_inst *sdi)
if ((ret = read_fpga_register(sdi, 9, &reg9)) != SR_OK)
return ret;
if (reg1 & 0x20) {
if (devc->fpga_variant == FPGA_VARIANT_ORIGINAL && reg1 & 0x20) {
sr_warn("FIFO overflow, capture data may be truncated.");
return SR_ERR;
}
@ -564,6 +569,7 @@ SR_PRIV int logic16_abort_acquisition(const struct sr_dev_inst *sdi)
SR_PRIV int logic16_init_device(const struct sr_dev_inst *sdi)
{
uint8_t version;
struct dev_context *devc;
int ret;
@ -577,6 +583,17 @@ SR_PRIV int logic16_init_device(const struct sr_dev_inst *sdi)
if ((ret = read_eeprom(sdi, 8, 8, devc->eeprom_data)) != SR_OK)
return ret;
/* mcupro Saleae16 has firmware pre-stored in FPGA.
So, we can query it right away. */
if (read_fpga_register(sdi, 0, &version) == SR_OK &&
(version == 0x40 || version == 0x41)) {
sr_info("mcupro Saleae16 detected.");
devc->fpga_variant = FPGA_VARIANT_MCUPRO;
} else {
sr_info("Original Saleae Logic16 detected.");
devc->fpga_variant = FPGA_VARIANT_ORIGINAL;
}
ret = upload_fpga_bitstream(sdi, devc->selected_voltage_range);
if (ret != SR_OK)
return ret;

View File

@ -35,8 +35,16 @@ enum voltage_range {
VOLTAGE_RANGE_5_V, /* 5V logic */
};
enum fpga_variant {
FPGA_VARIANT_ORIGINAL,
FPGA_VARIANT_MCUPRO /* mcupro clone v4.6 with Actel FPGA */
};
/** Private, per-device-instance driver context. */
struct dev_context {
/** Distinguishing between original Logic16 and clones */
enum fpga_variant fpga_variant;
/*
* Since we can't keep track of a Logic16 device after upgrading
* the firmware (it renumerates into a different device address