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:
parent
f88c73732c
commit
6f479a0a72
|
@ -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, ®1)) != 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, ®10)) != 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, ®1)) != 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, ®9)) != 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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue