X-Git-Url: https://sigrok.org/gitweb/?p=libsigrok.git;a=blobdiff_plain;f=src%2Fhardware%2Fsaleae-logic16%2Fprotocol.c;h=9e5806e0ae4c89c620121e158b345753d38022dd;hp=785833432749f2f71f772a841699197e5d56da41;hb=974fb0fffaffb0b2d1437ee280e4308a252741a0;hpb=155b680da482cea2381becb73c51cfb838bff31e diff --git a/src/hardware/saleae-logic16/protocol.c b/src/hardware/saleae-logic16/protocol.c index 78583343..9e5806e0 100644 --- a/src/hardware/saleae-logic16/protocol.c +++ b/src/hardware/saleae-logic16/protocol.c @@ -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,53 +337,55 @@ static int upload_fpga_bitstream(const struct sr_dev_inst *sdi, if (devc->cur_voltage_range == vrange) return SR_OK; - switch (vrange) { - case VOLTAGE_RANGE_18_33_V: - filename = FPGA_FIRMWARE_18; - break; - case VOLTAGE_RANGE_5_V: - filename = FPGA_FIRMWARE_33; - break; - default: - sr_err("Unsupported voltage range."); - return SR_ERR; - } + if (devc->fpga_variant == FPGA_VARIANT_ORIGINAL) { + switch (vrange) { + case VOLTAGE_RANGE_18_33_V: + filename = FPGA_FIRMWARE_18; + break; + case VOLTAGE_RANGE_5_V: + filename = 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 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; + } - buf[0] = COMMAND_FPGA_UPLOAD_INIT; - if ((ret = do_ep1_command(sdi, buf, 1, NULL, 0)) != SR_OK) { - fclose(fw); - return ret; - } + buf[0] = COMMAND_FPGA_UPLOAD_INIT; + if ((ret = do_ep1_command(sdi, buf, 1, NULL, 0)) != SR_OK) { + fclose(fw); + return ret; + } - while (1) { - chunksize = fread(buf, 1, sizeof(buf), fw); - if (chunksize == 0) - break; + while (1) { + chunksize = fread(buf, 1, sizeof(buf), fw); + 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; + 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; + } } - } - sr_info("Uploaded %d bytes.", chunksize); + sr_info("Uploaded %d bytes.", chunksize); + } + fclose(fw); + sr_info("FPGA bitstream upload done."); } - fclose(fw); - sr_info("FPGA bitstream upload done."); if ((ret = prime_fpga(sdi)) != SR_OK) return ret; @@ -464,9 +466,12 @@ 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 != 0x08) { - sr_dbg("Invalid state at acquisition setup: 0x%02x != 0x08.", reg1); - return SR_ERR; + /* Ignore FIFO overflow on previous capture */ + reg1 &= ~0x20; + + 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 ((ret = write_fpga_register(sdi, 1, 0x40)) != SR_OK) @@ -493,18 +498,17 @@ 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) { - sr_dbg("Invalid state at acquisition setup: 0x%02x != 0x48.", reg1); - return SR_ERR; + 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 ((ret = read_fpga_register(sdi, 10, ®10)) != SR_OK) return ret; - if (reg10 != clock_select) { - sr_dbg("Invalid state at acquisition setup: 0x%02x != 0x%02x.", - reg10, clock_select); - return SR_ERR; + if (devc->fpga_variant == FPGA_VARIANT_ORIGINAL && reg10 != clock_select) { + sr_dbg("Invalid state at acquisition setup register 10: 0x%02x != 0x%02x. " + "Proceeding anyway.", reg10, clock_select); } return SR_OK; @@ -530,6 +534,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; @@ -540,8 +547,8 @@ 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 != 0x08) { - sr_dbg("Invalid state at acquisition stop: 0x%02x != 0x08.", reg1); + 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; } @@ -551,11 +558,17 @@ 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 (devc->fpga_variant == FPGA_VARIANT_ORIGINAL && reg1 & 0x20) { + sr_warn("FIFO overflow, capture data may be truncated."); + return SR_ERR; + } + return SR_OK; } SR_PRIV int logic16_init_device(const struct sr_dev_inst *sdi) { + uint8_t version; struct dev_context *devc; int ret; @@ -569,6 +582,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; @@ -688,6 +712,7 @@ SR_PRIV void logic16_receive_transfer(struct libusb_transfer *transfer) struct dev_context *devc; size_t new_samples, num_samples; int trigger_offset; + int pre_trigger_samples; sdi = transfer->user_data; devc = sdi->priv; @@ -701,8 +726,8 @@ SR_PRIV void logic16_receive_transfer(struct libusb_transfer *transfer) return; } - sr_info("receive_transfer(): status %d received %d bytes.", - transfer->status, transfer->actual_length); + sr_info("receive_transfer(): status %s received %d bytes.", + libusb_error_name(transfer->status), transfer->actual_length); switch (transfer->status) { case LIBUSB_TRANSFER_NO_DEVICE: @@ -760,8 +785,9 @@ SR_PRIV void logic16_receive_transfer(struct libusb_transfer *transfer) devc->sent_samples += new_samples; } else { trigger_offset = soft_trigger_logic_check(devc->stl, - devc->convbuffer, new_samples * 2); + 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;