]> sigrok.org Git - libsigrok.git/blobdiff - src/hardware/kingst-la2016/protocol.c
kingst-la2016: more checks on configured rate/depth/channels
[libsigrok.git] / src / hardware / kingst-la2016 / protocol.c
index fb7703f73e88e94aad6fb1ad0988dbfcc0ac33d6..f21a2ba0613b75bd7130b7ad2c054a92bb8031b4 100644 (file)
 #define FPGA_FW_LA1016 "kingst-la1016-fpga.bitstream"
 #define FPGA_FW_LA1016A        "kingst-la1016a1-fpga.bitstream"
 
-/* Maximum device capabilities. May differ between models. */
-#define MAX_SAMPLE_RATE_LA2016 SR_MHZ(200)
-#define MAX_SAMPLE_RATE_LA1016 SR_MHZ(100)
-#define MAX_SAMPLE_DEPTH       10e9
-#define MAX_PWM_FREQ           SR_MHZ(20)
-#define PWM_CLOCK              SR_MHZ(200)     /* 200MHz for both LA2016 and LA1016 */
-
 /*
  * Default device configuration. Must be applicable to any of the
  * supported devices (no model specific default values yet). Specific
 #define LA2016_DFLT_SAMPLEDEPTH        (5 * 1000 * 1000)
 #define LA2016_DFLT_CAPT_RATIO 5 /* Capture ratio, in percent. */
 
-/* TODO
- * What is the origin and motivation of that 128Mi literal? What is its
- * unit? How does it relate to a device's hardware capabilities? How to
- * map the 1GiB of RAM of an LA2016 (at 16 channels) to the 128Mi value?
- * It cannot be sample count. Is it memory size in bytes perhaps?
- */
-#define LA2016_PRE_MEM_LIMIT_BASE      (128 * 1024 * 1024)
-
 /* USB vendor class control requests, executed by the Cypress FX2 MCU. */
 #define CMD_FPGA_ENABLE        0x10
 #define CMD_FPGA_SPI   0x20    /* R/W access to FPGA registers via SPI. */
@@ -114,10 +99,11 @@ static int ctrl_in(const struct sr_dev_inst *sdi,
 
        usb = sdi->conn;
 
-       if ((ret = libusb_control_transfer(usb->devhdl,
-                    LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN,
-                    bRequest, wValue, wIndex, (unsigned char *)data, wLength,
-                    DEFAULT_TIMEOUT_MS)) != wLength) {
+       ret = libusb_control_transfer(usb->devhdl,
+               LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN,
+               bRequest, wValue, wIndex, data, wLength,
+               DEFAULT_TIMEOUT_MS);
+       if (ret != wLength) {
                sr_dbg("USB ctrl in: %d bytes, req %d val %#x idx %d: %s.",
                        wLength, bRequest, wValue, wIndex,
                        libusb_error_name(ret));
@@ -138,10 +124,11 @@ static int ctrl_out(const struct sr_dev_inst *sdi,
 
        usb = sdi->conn;
 
-       if ((ret = libusb_control_transfer(usb->devhdl,
-                    LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT,
-                    bRequest, wValue, wIndex, (unsigned char*)data, wLength,
-                    DEFAULT_TIMEOUT_MS)) != wLength) {
+       ret = libusb_control_transfer(usb->devhdl,
+               LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT,
+               bRequest, wValue, wIndex, data, wLength,
+               DEFAULT_TIMEOUT_MS);
+       if (ret != wLength) {
                sr_dbg("USB ctrl out: %d bytes, req %d val %#x idx %d: %s.",
                        wLength, bRequest, wValue, wIndex,
                        libusb_error_name(ret));
@@ -244,7 +231,8 @@ static int upload_fpga_bitstream(const struct sr_dev_inst *sdi,
 
        sr_info("Uploading FPGA bitstream '%s'.", bitstream_fname);
 
-       ret = sr_resource_open(drvc->sr_ctx, &bitstream, SR_RESOURCE_FIRMWARE, bitstream_fname);
+       ret = sr_resource_open(drvc->sr_ctx, &bitstream,
+               SR_RESOURCE_FIRMWARE, bitstream_fname);
        if (ret != SR_OK) {
                sr_err("Cannot find FPGA bitstream %s.", bitstream_fname);
                return ret;
@@ -253,7 +241,8 @@ static int upload_fpga_bitstream(const struct sr_dev_inst *sdi,
        bitstream_size = (uint32_t)bitstream.size;
        wrptr = buffer;
        write_u32le_inc(&wrptr, bitstream_size);
-       if ((ret = ctrl_out(sdi, CMD_FPGA_INIT, 0x00, 0, buffer, wrptr - buffer)) != SR_OK) {
+       ret = ctrl_out(sdi, CMD_FPGA_INIT, 0x00, 0, buffer, wrptr - buffer);
+       if (ret != SR_OK) {
                sr_err("Cannot initiate FPGA bitstream upload.");
                sr_resource_close(drvc->sr_ctx, &bitstream);
                return ret;
@@ -266,7 +255,8 @@ static int upload_fpga_bitstream(const struct sr_dev_inst *sdi,
        pos = 0;
        while (1) {
                if (pos < bitstream.size) {
-                       len = (int)sr_resource_read(drvc->sr_ctx, &bitstream, &block, sizeof(block));
+                       len = (int)sr_resource_read(drvc->sr_ctx, &bitstream,
+                               block, sizeof(block));
                        if (len < 0) {
                                sr_err("Cannot read FPGA bitstream.");
                                sr_resource_close(drvc->sr_ctx, &bitstream);
@@ -299,7 +289,7 @@ static int upload_fpga_bitstream(const struct sr_dev_inst *sdi,
                pos += len;
        }
        sr_resource_close(drvc->sr_ctx, &bitstream);
-       if (ret != 0)
+       if (ret != SR_OK)
                return ret;
        sr_info("FPGA bitstream upload (%" PRIu64 " bytes) done.",
                bitstream.size);
@@ -310,20 +300,22 @@ static int upload_fpga_bitstream(const struct sr_dev_inst *sdi,
 static int enable_fpga_bitstream(const struct sr_dev_inst *sdi)
 {
        int ret;
-       uint8_t cmd_resp;
+       uint8_t resp;
 
-       if ((ret = ctrl_in(sdi, CMD_FPGA_INIT, 0x00, 0, &cmd_resp, sizeof(cmd_resp))) != SR_OK) {
+       ret = ctrl_in(sdi, CMD_FPGA_INIT, 0x00, 0, &resp, sizeof(resp));
+       if (ret != SR_OK) {
                sr_err("Cannot read response after FPGA bitstream upload.");
                return ret;
        }
-       if (cmd_resp != 0) {
+       if (resp != 0) {
                sr_err("Unexpected FPGA bitstream upload response, got 0x%02x, want 0.",
-                       cmd_resp);
+                       resp);
                return SR_ERR;
        }
        g_usleep(30 * 1000);
 
-       if ((ret = ctrl_out(sdi, CMD_FPGA_ENABLE, 0x01, 0, NULL, 0)) != SR_OK) {
+       ret = ctrl_out(sdi, CMD_FPGA_ENABLE, 0x01, 0, NULL, 0);
+       if (ret != SR_OK) {
                sr_err("Cannot enable FPGA after bitstream upload.");
                return ret;
        }
@@ -336,13 +328,12 @@ static int set_threshold_voltage(const struct sr_dev_inst *sdi, float voltage)
 {
        struct dev_context *devc;
        int ret;
-
-       devc = sdi->priv;
-
        uint16_t duty_R79, duty_R56;
        uint8_t buf[2 * sizeof(uint16_t)];
        uint8_t *wrptr;
 
+       devc = sdi->priv;
+
        /* Clamp threshold setting to valid range for LA2016. */
        if (voltage > 4.0) {
                voltage = 4.0;
@@ -508,6 +499,25 @@ static int set_defaults(const struct sr_dev_inst *sdi)
        return SR_OK;
 }
 
+static uint16_t get_channels_mask(const struct sr_dev_inst *sdi)
+{
+       uint16_t channels;
+       GSList *l;
+       struct sr_channel *ch;
+
+       channels = 0;
+       for (l = sdi->channels; l; l = l->next) {
+               ch = l->data;
+               if (ch->type != SR_CHANNEL_LOGIC)
+                       continue;
+               if (!ch->enabled)
+                       continue;
+               channels |= 1UL << ch->index;
+       }
+
+       return channels;
+}
+
 static int set_trigger_config(const struct sr_dev_inst *sdi)
 {
        struct dev_context *devc;
@@ -527,7 +537,7 @@ static int set_trigger_config(const struct sr_dev_inst *sdi)
 
        memset(&cfg, 0, sizeof(cfg));
 
-       cfg.channels = devc->cur_channels;
+       cfg.channels = get_channels_mask(sdi);
 
        if (trigger && trigger->stages) {
                stages = trigger->stages;
@@ -617,7 +627,12 @@ static int set_sample_config(const struct sr_dev_inst *sdi)
        if (devc->cur_samplerate > devc->max_samplerate) {
                sr_err("Too high a sample rate: %" PRIu64 ".",
                        devc->cur_samplerate);
-               return SR_ERR;
+               return SR_ERR_ARG;
+       }
+       if (devc->cur_samplerate < MIN_SAMPLE_RATE_LA2016) {
+               sr_err("Too low a sample rate: %" PRIu64 ".",
+                       devc->cur_samplerate);
+               return SR_ERR_ARG;
        }
 
        clock_divisor = devc->max_samplerate / (double)devc->cur_samplerate;
@@ -626,11 +641,16 @@ static int set_sample_config(const struct sr_dev_inst *sdi)
        divider_u16 = (uint16_t)(clock_divisor + 0.5);
        devc->cur_samplerate = devc->max_samplerate / divider_u16;
 
-       if (devc->limit_samples > MAX_SAMPLE_DEPTH) {
+       if (devc->limit_samples > LA2016_NUM_SAMPLES_MAX) {
                sr_err("Too high a sample depth: %" PRIu64 ".",
                        devc->limit_samples);
                return SR_ERR;
        }
+       if (devc->limit_samples < LA2016_NUM_SAMPLES_MIN) {
+               sr_err("Too low a sample depth: %" PRIu64 ".",
+                       devc->limit_samples);
+               return SR_ERR;
+       }
 
        /*
         * The acquisition configuration communicates "pre-trigger"
@@ -729,7 +749,8 @@ static uint16_t run_state(const struct sr_dev_inst *sdi)
        const uint8_t *rdptr;
        const char *label;
 
-       if ((ret = ctrl_in(sdi, CMD_FPGA_SPI, REG_RUN, 0, buff, sizeof(state))) != SR_OK) {
+       ret = ctrl_in(sdi, CMD_FPGA_SPI, REG_RUN, 0, buff, sizeof(state));
+       if (ret != SR_OK) {
                sr_err("Cannot read run state.");
                return ret;
        }
@@ -776,7 +797,8 @@ static int set_run_mode(const struct sr_dev_inst *sdi, uint8_t mode)
 {
        int ret;
 
-       if ((ret = ctrl_out(sdi, CMD_FPGA_SPI, REG_RUN, 0, &mode, sizeof(mode))) != SR_OK) {
+       ret = ctrl_out(sdi, CMD_FPGA_SPI, REG_RUN, 0, &mode, sizeof(mode));
+       if (ret != SR_OK) {
                sr_err("Cannot configure run mode %d.", mode);
                return ret;
        }
@@ -793,7 +815,8 @@ static int get_capture_info(const struct sr_dev_inst *sdi)
 
        devc = sdi->priv;
 
-       if ((ret = ctrl_in(sdi, CMD_FPGA_SPI, REG_SAMPLING, 0, buf, sizeof(buf))) != SR_OK) {
+       ret = ctrl_in(sdi, CMD_FPGA_SPI, REG_SAMPLING, 0, buf, sizeof(buf));
+       if (ret != SR_OK) {
                sr_err("Cannot read capture info.");
                return ret;
        }
@@ -822,7 +845,7 @@ SR_PRIV int la2016_upload_firmware(struct sr_context *sr_ctx,
        libusb_device *dev, uint16_t product_id)
 {
        char fw_file[1024];
-       snprintf(fw_file, sizeof(fw_file) - 1, UC_FIRMWARE, product_id);
+       snprintf(fw_file, sizeof(fw_file), UC_FIRMWARE, product_id);
        return ezusb_upload_firmware(sr_ctx, dev, USB_CONFIGURATION, fw_file);
 }
 
@@ -839,7 +862,8 @@ SR_PRIV int la2016_setup_acquisition(const struct sr_dev_inst *sdi)
                return ret;
 
        cmd = 0;
-       if ((ret = ctrl_out(sdi, CMD_FPGA_SPI, REG_CAPT_MODE, 0, &cmd, sizeof(cmd))) != SR_OK) {
+       ret = ctrl_out(sdi, CMD_FPGA_SPI, REG_CAPT_MODE, 0, &cmd, sizeof(cmd));
+       if (ret != SR_OK) {
                sr_err("Cannot send command to stop sampling.");
                return ret;
        }
@@ -907,7 +931,8 @@ static int la2016_start_download(const struct sr_dev_inst *sdi,
        devc = sdi->priv;
        usb = sdi->conn;
 
-       if ((ret = get_capture_info(sdi)) != SR_OK)
+       ret = get_capture_info(sdi);
+       if (ret != SR_OK)
                return ret;
 
        devc->n_transfer_packets_to_read = devc->info.n_rep_packets / NUM_PACKETS_IN_CHUNK;
@@ -918,7 +943,8 @@ static int la2016_start_download(const struct sr_dev_inst *sdi,
        sr_dbg("Want to read %u xfer-packets starting from pos %" PRIu32 ".",
                devc->n_transfer_packets_to_read, devc->read_pos);
 
-       if ((ret = ctrl_out(sdi, CMD_BULK_RESET, 0x00, 0, NULL, 0)) != SR_OK) {
+       ret = ctrl_out(sdi, CMD_BULK_RESET, 0x00, 0, NULL, 0);
+       if (ret != SR_OK) {
                sr_err("Cannot reset USB bulk state.");
                return ret;
        }
@@ -927,11 +953,13 @@ static int la2016_start_download(const struct sr_dev_inst *sdi,
        wrptr = wrbuf;
        write_u32le_inc(&wrptr, devc->read_pos);
        write_u32le_inc(&wrptr, devc->n_bytes_to_read);
-       if ((ret = ctrl_out(sdi, CMD_FPGA_SPI, REG_BULK, 0, wrbuf, wrptr - wrbuf)) != SR_OK) {
+       ret = ctrl_out(sdi, CMD_FPGA_SPI, REG_BULK, 0, wrbuf, wrptr - wrbuf);
+       if (ret != SR_OK) {
                sr_err("Cannot send USB bulk config.");
                return ret;
        }
-       if ((ret = ctrl_out(sdi, CMD_BULK_START, 0x00, 0, NULL, 0)) != SR_OK) {
+       ret = ctrl_out(sdi, CMD_BULK_START, 0x00, 0, NULL, 0);
+       if (ret != SR_OK) {
                sr_err("Cannot unblock USB bulk transfers.");
                return ret;
        }
@@ -956,10 +984,10 @@ static int la2016_start_download(const struct sr_dev_inst *sdi,
        devc->transfer = libusb_alloc_transfer(0);
        libusb_fill_bulk_transfer(devc->transfer,
                usb->devhdl, USB_EP_CAPTURE_DATA | LIBUSB_ENDPOINT_IN,
-               buffer, to_read,
-               cb, (void *)sdi, DEFAULT_TIMEOUT_MS);
+               buffer, to_read, cb, (void *)sdi, DEFAULT_TIMEOUT_MS);
 
-       if ((ret = libusb_submit_transfer(devc->transfer)) != 0) {
+       ret = libusb_submit_transfer(devc->transfer);
+       if (ret != 0) {
                sr_err("Cannot submit USB transfer: %s.", libusb_error_name(ret));
                libusb_free_transfer(devc->transfer);
                devc->transfer = NULL;
@@ -1103,7 +1131,8 @@ static void LIBUSB_CALL receive_transfer(struct libusb_transfer *transfer)
                        transfer->buffer, to_read,
                        receive_transfer, (void *)sdi, DEFAULT_TIMEOUT_MS);
 
-               if ((ret = libusb_submit_transfer(transfer)) == 0)
+               ret = libusb_submit_transfer(transfer);
+               if (ret == 0)
                        return;
                sr_err("Cannot submit another USB transfer: %s.",
                        libusb_error_name(ret));