]> sigrok.org Git - libsigrok.git/blobdiff - src/hardware/kingst-la2016/protocol.c
kingst-la2016: rephrase USB bulk transfer size padding constraint
[libsigrok.git] / src / hardware / kingst-la2016 / protocol.c
index 976bc3e2dd612bfe818812daaccd2d702fd7b955..6ab72df02ecc517992a758c798fe50a80b97d53b 100644 (file)
@@ -80,7 +80,8 @@ static const struct kingst_model models[] = {
 #define REG_CAPT_MODE  0x03    /* Write 0x00 capture to SDRAM, 0x01 streaming. */
 #define REG_BULK       0x08    /* Write start addr, byte count to download samples. */
 #define REG_SAMPLING   0x10    /* Write capture config, read capture SDRAM location. */
-#define REG_TRIGGER    0x20    /* write level and edge trigger config. */
+#define REG_TRIGGER    0x20    /* Write level and edge trigger config. */
+#define REG_UNKNOWN_30 0x30
 #define REG_THRESHOLD  0x68    /* Write PWM config to setup input threshold DAC. */
 #define REG_PWM1       0x70    /* Write config for user PWM1. */
 #define REG_PWM2       0x78    /* Write config for user PWM2. */
@@ -95,7 +96,14 @@ static const struct kingst_model models[] = {
 #define RUNSTATE_TRGD_BIT      (1UL << 2)
 #define RUNSTATE_POST_BIT      (1UL << 3)
 
-/* Properties related to the layout of capture data downloads. */
+/*
+ * Properties related to the layout of capture data downloads.
+ *
+ * TODO Check the layout of 32 channel models' capture data. Could it be
+ * 3x (u32 + u8) instead of 5x (u16 + u8) perhaps? Same 16 bytes chunk
+ * but fewer packets per chunk and thus per transfer? Which questions
+ * the NUM_PACKETS_IN_CHUNK literal, maybe needs to be a runtime value?
+ */
 #define NUM_PACKETS_IN_CHUNK   5
 #define TRANSFER_PACKET_LENGTH 16
 
@@ -118,7 +126,7 @@ static int ctrl_in(const struct sr_dev_inst *sdi,
                        libusb_error_name(ret));
                sr_err("Cannot read %d bytes from USB: %s.",
                        wLength, libusb_error_name(ret));
-               return SR_ERR;
+               return SR_ERR_IO;
        }
 
        return SR_OK;
@@ -143,7 +151,7 @@ static int ctrl_out(const struct sr_dev_inst *sdi,
                        libusb_error_name(ret));
                sr_err("Cannot write %d bytes to USB: %s.",
                        wLength, libusb_error_name(ret));
-               return SR_ERR;
+               return SR_ERR_IO;
        }
 
        return SR_OK;
@@ -168,11 +176,11 @@ static int ctrl_out(const struct sr_dev_inst *sdi,
 static int check_fpga_bitstream(const struct sr_dev_inst *sdi)
 {
        uint8_t init_rsp;
+       uint8_t buff[REG_PWM_EN - REG_RUN]; /* Larger of REG_RUN, REG_PWM_EN. */
        int ret;
        uint16_t run_state;
        uint8_t pwm_en;
        size_t read_len;
-       uint8_t buff[sizeof(run_state)];
        const uint8_t *rdptr;
 
        sr_dbg("Checking operation of the FPGA bitstream.");
@@ -269,7 +277,7 @@ static int upload_fpga_bitstream(const struct sr_dev_inst *sdi,
                        if (len < 0) {
                                sr_err("Cannot read FPGA bitstream.");
                                sr_resource_close(drvc->sr_ctx, &bitstream);
-                               return SR_ERR;
+                               return SR_ERR_IO;
                        }
                } else {
                        /*  Zero-pad until 'zero_pad_to'. */
@@ -286,13 +294,13 @@ static int upload_fpga_bitstream(const struct sr_dev_inst *sdi,
                if (ret != 0) {
                        sr_dbg("Cannot write FPGA bitstream, block %#x len %d: %s.",
                                pos, (int)len, libusb_error_name(ret));
-                       ret = SR_ERR;
+                       ret = SR_ERR_IO;
                        break;
                }
                if (act_len != len) {
                        sr_dbg("Short write for FPGA bitstream, block %#x len %d: got %d.",
                                pos, (int)len, act_len);
-                       ret = SR_ERR;
+                       ret = SR_ERR_IO;
                        break;
                }
                pos += len;
@@ -319,7 +327,7 @@ static int enable_fpga_bitstream(const struct sr_dev_inst *sdi)
        if (resp != 0) {
                sr_err("Unexpected FPGA bitstream upload response, got 0x%02x, want 0.",
                        resp);
-               return SR_ERR;
+               return SR_ERR_DATA;
        }
        g_usleep(30 * 1000);
 
@@ -337,7 +345,7 @@ static int set_threshold_voltage(const struct sr_dev_inst *sdi, float voltage)
 {
        int ret;
        uint16_t duty_R79, duty_R56;
-       uint8_t buf[2 * sizeof(uint16_t)];
+       uint8_t buf[REG_PWM1 - REG_THRESHOLD]; /* Width of REG_THRESHOLD. */
        uint8_t *wrptr;
 
        /* Clamp threshold setting to valid range for LA2016. */
@@ -526,7 +534,7 @@ static int set_trigger_config(const struct sr_dev_inst *sdi)
        struct sr_trigger_match *match;
        uint16_t ch_mask;
        int ret;
-       uint8_t buf[4 * sizeof(uint32_t)];
+       uint8_t buf[REG_UNKNOWN_30 - REG_TRIGGER]; /* Width of REG_TRIGGER. */
        uint8_t *wrptr;
 
        devc = sdi->priv;
@@ -541,7 +549,7 @@ static int set_trigger_config(const struct sr_dev_inst *sdi)
                stage1 = stages->data;
                if (stages->next) {
                        sr_err("Only one trigger stage supported for now.");
-                       return SR_ERR;
+                       return SR_ERR_ARG;
                }
                channel = stage1->matches;
                while (channel) {
@@ -560,7 +568,7 @@ static int set_trigger_config(const struct sr_dev_inst *sdi)
                        case SR_TRIGGER_RISING:
                                if ((cfg.enabled & ~cfg.level)) {
                                        sr_err("Device only supports one edge trigger.");
-                                       return SR_ERR;
+                                       return SR_ERR_ARG;
                                }
                                cfg.level &= ~ch_mask;
                                cfg.high_or_falling &= ~ch_mask;
@@ -568,14 +576,14 @@ static int set_trigger_config(const struct sr_dev_inst *sdi)
                        case SR_TRIGGER_FALLING:
                                if ((cfg.enabled & ~cfg.level)) {
                                        sr_err("Device only supports one edge trigger.");
-                                       return SR_ERR;
+                                       return SR_ERR_ARG;
                                }
                                cfg.level &= ~ch_mask;
                                cfg.high_or_falling |= ch_mask;
                                break;
                        default:
                                sr_err("Unknown trigger condition.");
-                               return SR_ERR;
+                               return SR_ERR_ARG;
                        }
                        cfg.enabled |= ch_mask;
                        channel = channel->next;
@@ -766,7 +774,7 @@ static uint16_t run_state(const struct sr_dev_inst *sdi)
 
        int ret;
        uint16_t state;
-       uint8_t buff[sizeof(state)];
+       uint8_t buff[REG_PWM_EN - REG_RUN]; /* Width of REG_RUN. */
        const uint8_t *rdptr;
        const char *label;
 
@@ -831,7 +839,7 @@ static int get_capture_info(const struct sr_dev_inst *sdi)
 {
        struct dev_context *devc;
        int ret;
-       uint8_t buf[3 * sizeof(uint32_t)];
+       uint8_t buf[REG_TRIGGER - REG_SAMPLING]; /* Width of REG_SAMPLING. */
        const uint8_t *rdptr;
 
        devc = sdi->priv;
@@ -961,7 +969,7 @@ static int la2016_start_download(const struct sr_dev_inst *sdi,
        struct dev_context *devc;
        struct sr_usb_dev_inst *usb;
        int ret;
-       uint8_t wrbuf[2 * sizeof(uint32_t)];
+       uint8_t wrbuf[REG_SAMPLING - REG_BULK]; /* Width of REG_BULK. */
        uint8_t *wrptr;
        uint32_t to_read;
        uint8_t *buffer;
@@ -1010,8 +1018,9 @@ static int la2016_start_download(const struct sr_dev_inst *sdi,
        to_read = devc->n_bytes_to_read;
        if (to_read >= LA2016_USB_BUFSZ) /* Multiple transfers. */
                to_read = LA2016_USB_BUFSZ;
-       else /* One transfer. */
-               to_read = (to_read + (LA2016_EP6_PKTSZ-1)) & ~(LA2016_EP6_PKTSZ-1);
+       to_read += LA2016_EP6_PKTSZ - 1;
+       to_read /= LA2016_EP6_PKTSZ;
+       to_read *= LA2016_EP6_PKTSZ;
        buffer = g_try_malloc(to_read);
        if (!buffer) {
                sr_dbg("USB bulk transfer size %d bytes.", (int)to_read);
@@ -1030,7 +1039,7 @@ static int la2016_start_download(const struct sr_dev_inst *sdi,
                libusb_free_transfer(devc->transfer);
                devc->transfer = NULL;
                g_free(buffer);
-               return SR_ERR;
+               return SR_ERR_IO;
        }
 
        return SR_OK;
@@ -1136,8 +1145,9 @@ static void LIBUSB_CALL receive_transfer(struct libusb_transfer *transfer)
                 */
                if (to_read >= LA2016_USB_BUFSZ)
                        to_read = LA2016_USB_BUFSZ;
-               else
-                       to_read = (to_read + (LA2016_EP6_PKTSZ-1)) & ~(LA2016_EP6_PKTSZ-1);
+               to_read += LA2016_EP6_PKTSZ - 1;
+               to_read /= LA2016_EP6_PKTSZ;
+               to_read *= LA2016_EP6_PKTSZ;
                libusb_fill_bulk_transfer(transfer,
                        usb->devhdl, USB_EP_CAPTURE_DATA | LIBUSB_ENDPOINT_IN,
                        transfer->buffer, to_read,
@@ -1231,7 +1241,7 @@ SR_PRIV int la2016_identify_device(const struct sr_dev_inst *sdi,
        gboolean show_message)
 {
        struct dev_context *devc;
-       uint8_t buf[8];
+       uint8_t buf[8]; /* Larger size of manuf date and device type magic. */
        size_t rdoff, rdlen;
        const uint8_t *rdptr;
        uint8_t date_yy, date_mm;
@@ -1359,7 +1369,7 @@ SR_PRIV int la2016_identify_device(const struct sr_dev_inst *sdi,
        }
        if (!devc->model) {
                sr_err("Cannot identify as one of the supported models.");
-               return SR_ERR;
+               return SR_ERR_DATA;
        }
 
        return SR_OK;