]> sigrok.org Git - libsigrok.git/commitdiff
kingst-la2016: adjust sample memory interpretation for LA5032
authorGerhard Sittig <redacted>
Sun, 16 Oct 2022 10:50:55 +0000 (12:50 +0200)
committerGerhard Sittig <redacted>
Sun, 23 Oct 2022 05:05:49 +0000 (07:05 +0200)
The 32-channel model in the Kingst LA series uses a different sample
memory layout than 16-channel models. The previously encoded assumption
of 3x (u32 + u8) to hold 32 channels within the same 15 bytes as other
models was incorrect. User feedback in bug #1805 suggests that the
transfer size and the sequence number size differs as well. Thus the
packet count per transfer differs, too. LA5032 holds 6 packets within
a transfer that spans 32 bytes.

Reported-By: Roman Shishkin <redacted>
src/hardware/kingst-la2016/api.c
src/hardware/kingst-la2016/protocol.c
src/hardware/kingst-la2016/protocol.h

index 742f3e3ae6a0a3155e2516e32903894db4770c84..5f536933fe6d8b49d9120a7c19454f8fb724595d 100644 (file)
@@ -1035,7 +1035,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
        struct drv_context *drvc;
        struct sr_context *ctx;
        struct dev_context *devc;
-       size_t unitsize;
+       size_t unitsize, xfersize, repsize, seqsize;
        double voltage;
        int ret;
 
@@ -1045,21 +1045,35 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi)
        devc = sdi->priv;
 
        if (!devc->feed_queue) {
-               if (devc->model->channel_count == 32)
+               /*
+                * TODO
+                * Move this into protocol.c which concentrates the
+                * wire format. The api.c source should not bother.
+                */
+               if (devc->model->channel_count == 32) {
                        unitsize = sizeof(uint32_t);
-               else if (devc->model->channel_count == 16)
+                       repsize = sizeof(uint8_t);
+                       seqsize = 2 * sizeof(uint8_t);
+                       xfersize = 32;
+               } else if (devc->model->channel_count == 16) {
                        unitsize = sizeof(uint16_t);
-               else
+                       repsize = sizeof(uint8_t);
+                       seqsize = 1 * sizeof(uint8_t);
+                       xfersize = 16;
+               } else {
                        return SR_ERR_ARG;
+               }
                devc->feed_queue = feed_queue_logic_alloc(sdi,
                        LA2016_CONVBUFFER_SIZE, unitsize);
                if (!devc->feed_queue) {
                        sr_err("Cannot allocate buffer for session feed.");
                        return SR_ERR_MALLOC;
                }
-               devc->packets_per_chunk = TRANSFER_PACKET_LENGTH;
-               devc->packets_per_chunk--;
-               devc->packets_per_chunk /= unitsize + sizeof(uint8_t);
+               devc->transfer_size = xfersize;
+               devc->sequence_size = seqsize;
+               devc->packets_per_chunk = xfersize;
+               devc->packets_per_chunk -= seqsize;
+               devc->packets_per_chunk /= unitsize + repsize;
        }
 
        sr_sw_limits_acquisition_start(&devc->sw_limits);
index e8b15c4f90069285745ff449fb67f215624c5ba8..d5ae567e5216f111d118e7f06d43a6238a74c26a 100644 (file)
@@ -1283,7 +1283,7 @@ static int la2016_start_download(const struct sr_dev_inst *sdi)
        devc->n_transfer_packets_to_read = devc->info.n_rep_packets;
        devc->n_transfer_packets_to_read /= devc->packets_per_chunk;
        devc->n_bytes_to_read = devc->n_transfer_packets_to_read;
-       devc->n_bytes_to_read *= TRANSFER_PACKET_LENGTH;
+       devc->n_bytes_to_read *= devc->transfer_size;
        devc->read_pos = devc->info.write_pos - devc->n_bytes_to_read;
        devc->n_reps_until_trigger = devc->info.n_rep_packets_before_trigger;
 
@@ -1341,15 +1341,12 @@ static int la2016_start_download(const struct sr_dev_inst *sdi)
  * - 2x u8 sequence number (inverted, and normal)
  *
  * This implementation silently ignores the (weak) sequence number.
- *
- * TODO Adjust the code paths for the 32-channel models. The version
- * below currently only works correctly for 16-channel models.
  */
 static void send_chunk(struct sr_dev_inst *sdi,
        const uint8_t *data_buffer, size_t data_length)
 {
        struct dev_context *devc;
-       size_t num_xfers, num_pkts;
+       size_t num_xfers, num_pkts, num_seqs;
        const uint8_t *rp;
        uint32_t sample_value;
        size_t repetitions;
@@ -1379,12 +1376,11 @@ static void send_chunk(struct sr_dev_inst *sdi,
        /* Process the received chunk of capture data. */
        sample_value = 0;
        rp = data_buffer;
-       num_xfers = data_length / TRANSFER_PACKET_LENGTH;
+       num_xfers = data_length / devc->transfer_size;
        while (num_xfers--) {
                num_pkts = devc->packets_per_chunk;
                while (num_pkts--) {
 
-                       /* TODO Verify 32channel layout. */
                        if (devc->model->channel_count == 32)
                                sample_value = read_u32le_inc(&rp);
                        else if (devc->model->channel_count == 16)
@@ -1409,7 +1405,10 @@ static void send_chunk(struct sr_dev_inst *sdi,
                                }
                        }
                }
-               (void)read_u8_inc(&rp); /* Skip sequence number. */
+               /* Skip the sequence number bytes. */
+               num_seqs = devc->sequence_size;
+               while (num_seqs--)
+                       (void)read_u8_inc(&rp);
        }
 
        /*
index 995ae64bfd80f063626e01f0399f9c7c04ad7d62..371a3ccd8e710255a866ef1907f0b1caad029155 100644 (file)
@@ -81,8 +81,6 @@
 #define LA2016_THR_VOLTAGE_MIN 0.40
 #define LA2016_THR_VOLTAGE_MAX 4.00
 
-/* Properties related to the layout of capture data downloads. */
-#define TRANSFER_PACKET_LENGTH 16
 #define LA2016_NUM_SAMPLES_MAX (UINT64_C(10 * 1000 * 1000 * 1000))
 
 /* Maximum device capabilities. May differ between models. */
@@ -143,6 +141,8 @@ struct dev_context {
        gboolean frame_begin_sent;
        gboolean completion_seen;
        gboolean download_finished;
+       size_t transfer_size;
+       size_t sequence_size;
        uint32_t packets_per_chunk;
        struct capture_info {
                uint32_t n_rep_packets;