]> sigrok.org Git - libsigrok.git/blobdiff - src/hardware/kingst-la2016/protocol.c
kingst-la2016: balance frame begin and frame end emission
[libsigrok.git] / src / hardware / kingst-la2016 / protocol.c
index 6ab72df02ecc517992a758c798fe50a80b97d53b..de5e1ac747eeba6927a4afe08e41f60f79043bfc 100644 (file)
@@ -86,6 +86,10 @@ static const struct kingst_model models[] = {
 #define REG_PWM1       0x70    /* Write config for user PWM1. */
 #define REG_PWM2       0x78    /* Write config for user PWM2. */
 
+/* Bit patterns to write to REG_CAPT_MODE. */
+#define CAPTMODE_TO_RAM        0x00
+#define CAPTMODE_STREAM        0x01
+
 /* Bit patterns to write to REG_RUN, setup run mode. */
 #define RUNMODE_HALT   0x00
 #define RUNMODE_RUN    0x03
@@ -96,17 +100,6 @@ 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.
- *
- * 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
-
 static int ctrl_in(const struct sr_dev_inst *sdi,
        uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
        void *data, uint16_t wLength)
@@ -499,9 +492,9 @@ static int set_pwm_config(const struct sr_dev_inst *sdi, size_t idx)
        return SR_OK;
 }
 
-static uint16_t get_channels_mask(const struct sr_dev_inst *sdi)
+static uint32_t get_channels_mask(const struct sr_dev_inst *sdi)
 {
-       uint16_t channels;
+       uint32_t channels;
        GSList *l;
        struct sr_channel *ch;
 
@@ -523,8 +516,8 @@ static int set_trigger_config(const struct sr_dev_inst *sdi)
        struct dev_context *devc;
        struct sr_trigger *trigger;
        struct trigger_cfg {
-               uint32_t channels;
-               uint32_t enabled;
+               uint32_t channels;      /* Actually: Enabled channels? */
+               uint32_t enabled;       /* Actually: Triggering channels? */
                uint32_t level;
                uint32_t high_or_falling;
        } cfg;
@@ -532,7 +525,7 @@ static int set_trigger_config(const struct sr_dev_inst *sdi)
        GSList *channel;
        struct sr_trigger_stage *stage1;
        struct sr_trigger_match *match;
-       uint16_t ch_mask;
+       uint32_t ch_mask;
        int ret;
        uint8_t buf[REG_UNKNOWN_30 - REG_TRIGGER]; /* Width of REG_TRIGGER. */
        uint8_t *wrptr;
@@ -590,7 +583,7 @@ static int set_trigger_config(const struct sr_dev_inst *sdi)
                }
        }
        sr_dbg("Set trigger config: "
-               "channels 0x%04x, trigger-enabled 0x%04x, "
+               "enabled-channels 0x%04x, triggering-channels 0x%04x, "
                "level-triggered 0x%04x, high/falling 0x%04x.",
                cfg.channels, cfg.enabled, cfg.level, cfg.high_or_falling);
 
@@ -861,10 +854,10 @@ static int get_capture_info(const struct sr_dev_inst *sdi)
                devc->info.n_rep_packets_before_trigger,
                devc->info.write_pos, devc->info.write_pos);
 
-       if (devc->info.n_rep_packets % NUM_PACKETS_IN_CHUNK) {
-               sr_warn("Unexpected packets count %lu, not a multiple of %d.",
+       if (devc->info.n_rep_packets % devc->packets_per_chunk) {
+               sr_warn("Unexpected packets count %lu, not a multiple of %lu.",
                        (unsigned long)devc->info.n_rep_packets,
-                       NUM_PACKETS_IN_CHUNK);
+                       (unsigned long)devc->packets_per_chunk);
        }
 
        return SR_OK;
@@ -907,7 +900,7 @@ SR_PRIV int la2016_setup_acquisition(const struct sr_dev_inst *sdi,
        if (ret != SR_OK)
                return ret;
 
-       cmd = 0;
+       cmd = CAPTMODE_TO_RAM;
        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.");
@@ -981,8 +974,10 @@ static int la2016_start_download(const struct sr_dev_inst *sdi,
        if (ret != SR_OK)
                return ret;
 
-       devc->n_transfer_packets_to_read = devc->info.n_rep_packets / NUM_PACKETS_IN_CHUNK;
-       devc->n_bytes_to_read = devc->n_transfer_packets_to_read * TRANSFER_PACKET_LENGTH;
+       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->read_pos = devc->info.write_pos - devc->n_bytes_to_read;
        devc->n_reps_until_trigger = devc->info.n_rep_packets_before_trigger;
 
@@ -1056,7 +1051,7 @@ static void send_chunk(struct sr_dev_inst *sdi,
        struct dev_context *devc;
        size_t num_pkts;
        const uint8_t *rp;
-       uint16_t sample_value;
+       uint32_t sample_value;
        size_t repetitions;
        uint8_t sample_buff[sizeof(sample_value)];
 
@@ -1071,17 +1066,22 @@ static void send_chunk(struct sr_dev_inst *sdi,
                devc->trigger_marked = TRUE;
        }
 
+       sample_value = 0;
        rp = packets;
        while (num_xfers--) {
-               num_pkts = NUM_PACKETS_IN_CHUNK;
+               num_pkts = devc->packets_per_chunk;
                while (num_pkts--) {
 
-                       sample_value = read_u16le_inc(&rp);
+                       /* TODO Verify 32channel layout. */
+                       if (devc->model->channel_count == 32)
+                               sample_value = read_u32le_inc(&rp);
+                       else if (devc->model->channel_count == 16)
+                               sample_value = read_u16le_inc(&rp);
                        repetitions = read_u8_inc(&rp);
 
                        devc->total_samples += repetitions;
 
-                       write_u16le(sample_buff, sample_value);
+                       write_u32le(sample_buff, sample_value);
                        feed_queue_logic_submit(devc->feed_queue,
                                sample_buff, repetitions);
                        sr_sw_limits_update_samples_read(&devc->sw_limits,
@@ -1203,6 +1203,7 @@ SR_PRIV int la2016_receive_data(int fd, int revents, void *cb_data)
 
                /* Initiate the download of acquired sample data. */
                std_session_send_df_frame_begin(sdi);
+               devc->frame_begin_sent = TRUE;
                ret = la2016_start_download(sdi, receive_transfer);
                if (ret != SR_OK) {
                        sr_err("Cannot start acquisition data download.");
@@ -1228,7 +1229,10 @@ SR_PRIV int la2016_receive_data(int fd, int revents, void *cb_data)
                feed_queue_logic_flush(devc->feed_queue);
                feed_queue_logic_free(devc->feed_queue);
                devc->feed_queue = NULL;
-               std_session_send_df_frame_end(sdi);
+               if (devc->frame_begin_sent) {
+                       std_session_send_df_frame_end(sdi);
+                       devc->frame_begin_sent = FALSE;
+               }
                std_session_send_df_end(sdi);
 
                sr_dbg("Download finished, done post processing.");