]> sigrok.org Git - libsigrok.git/blobdiff - src/hardware/saleae-logic16/protocol.c
output/csv: use intermediate time_t var, silence compiler warning
[libsigrok.git] / src / hardware / saleae-logic16 / protocol.c
index 532320d9216a10f132652e0d8b5c36a9d4c7bfba..ce8db37f169c6a5b03dc495c6da3081775aeb3af 100644 (file)
@@ -19,6 +19,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <config.h>
 #include <stdint.h>
 #include <string.h>
 #include <glib.h>
 #include "libsigrok-internal.h"
 #include "protocol.h"
 
-#define FPGA_FIRMWARE_18       FIRMWARE_DIR"/saleae-logic16-fpga-18.bitstream"
-#define FPGA_FIRMWARE_33       FIRMWARE_DIR"/saleae-logic16-fpga-33.bitstream"
+#define FPGA_FIRMWARE_18       "saleae-logic16-fpga-18.bitstream"
+#define FPGA_FIRMWARE_33       "saleae-logic16-fpga-33.bitstream"
 
 #define MAX_SAMPLE_RATE                SR_MHZ(100)
-#define MAX_4CH_SAMPLE_RATE    SR_MHZ(50)
-#define MAX_7CH_SAMPLE_RATE    SR_MHZ(40)
-#define MAX_8CH_SAMPLE_RATE    SR_MHZ(32)
-#define MAX_10CH_SAMPLE_RATE   SR_MHZ(25)
-#define MAX_13CH_SAMPLE_RATE   SR_MHZ(16)
+#define MAX_SAMPLE_RATE_X_CH   SR_MHZ(300)
 
 #define BASE_CLOCK_0_FREQ      SR_MHZ(100)
 #define BASE_CLOCK_1_FREQ      SR_MHZ(160)
@@ -214,7 +211,7 @@ static int do_ep1_command(const struct sr_dev_inst *sdi,
        }
        if (xfer != cmd_len) {
                sr_dbg("Failed to send EP1 command 0x%02x: incorrect length "
-                      "%d != %d.", xfer, cmd_len);
+                      "%d != %d.", command[0], xfer, cmd_len);
                return SR_ERR;
        }
 
@@ -230,7 +227,7 @@ static int do_ep1_command(const struct sr_dev_inst *sdi,
        }
        if (xfer != reply_len) {
                sr_dbg("Failed to receive reply to EP1 command 0x%02x: "
-                      "incorrect length %d != %d.", xfer, reply_len);
+                      "incorrect length %d != %d.", command[0], xfer, reply_len);
                return SR_ERR;
        }
 
@@ -431,8 +428,7 @@ static int prime_fpga(const struct sr_dev_inst *sdi)
                return ret;
 
        if (version != 0x10 && version != 0x13 && version != 0x40 && version != 0x41) {
-               sr_err("Unsupported FPGA version: 0x%02x.", version);
-               return SR_ERR;
+               sr_warn("Unsupported FPGA version: 0x%02x.", version);
        }
 
        return SR_OK;
@@ -464,13 +460,17 @@ static int configure_led(const struct sr_dev_inst *sdi)
 static int upload_fpga_bitstream(const struct sr_dev_inst *sdi,
                                 enum voltage_range vrange)
 {
+       uint64_t sum;
+       struct sr_resource bitstream;
        struct dev_context *devc;
-       int offset, chunksize, ret;
-       const char *filename;
-       uint8_t len, buf[256 * 62], command[64];
-       FILE *fw;
+       struct drv_context *drvc;
+       const char *name;
+       ssize_t chunksize;
+       int ret;
+       uint8_t command[64];
 
        devc = sdi->priv;
+       drvc = sdi->driver->context;
 
        if (devc->cur_voltage_range == vrange)
                return SR_OK;
@@ -478,51 +478,51 @@ static int upload_fpga_bitstream(const struct sr_dev_inst *sdi,
        if (devc->fpga_variant != FPGA_VARIANT_MCUPRO) {
                switch (vrange) {
                case VOLTAGE_RANGE_18_33_V:
-                       filename = FPGA_FIRMWARE_18;
+                       name = FPGA_FIRMWARE_18;
                        break;
                case VOLTAGE_RANGE_5_V:
-                       filename = FPGA_FIRMWARE_33;
+                       name = 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"))) {
-                       sr_err("Unable to open bitstream file %s for reading: %s.",
-                              filename, strerror(errno));
-                       return SR_ERR;
-               }
+               sr_info("Uploading FPGA bitstream '%s'.", name);
+               ret = sr_resource_open(drvc->sr_ctx, &bitstream,
+                               SR_RESOURCE_FIRMWARE, name);
+               if (ret != SR_OK)
+                       return ret;
 
-               buf[0] = COMMAND_FPGA_UPLOAD_INIT;
-               if ((ret = do_ep1_command(sdi, buf, 1, NULL, 0)) != SR_OK) {
-                       fclose(fw);
+               command[0] = COMMAND_FPGA_UPLOAD_INIT;
+               if ((ret = do_ep1_command(sdi, command, 1, NULL, 0)) != SR_OK) {
+                       sr_resource_close(drvc->sr_ctx, &bitstream);
                        return ret;
                }
 
+               sum = 0;
                while (1) {
-                       chunksize = fread(buf, 1, sizeof(buf), fw);
+                       chunksize = sr_resource_read(drvc->sr_ctx, &bitstream,
+                                       &command[2], sizeof(command) - 2);
+                       if (chunksize < 0) {
+                               sr_resource_close(drvc->sr_ctx, &bitstream);
+                               return SR_ERR;
+                       }
                        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;
-                               }
+                       command[0] = COMMAND_FPGA_UPLOAD_SEND_DATA;
+                       command[1] = chunksize;
+
+                       ret = do_ep1_command(sdi, command, chunksize + 2,
+                                       NULL, 0);
+                       if (ret != SR_OK) {
+                               sr_resource_close(drvc->sr_ctx, &bitstream);
+                               return ret;
                        }
-
-                       sr_info("Uploaded %d bytes.", chunksize);
+                       sum += chunksize;
                }
-               fclose(fw);
-               sr_info("FPGA bitstream upload done.");
+               sr_resource_close(drvc->sr_ctx, &bitstream);
+               sr_info("FPGA bitstream upload (%" PRIu64 " bytes) done.", sum);
        }
 
        /* This needs to be called before accessing any FPGA registers. */
@@ -591,11 +591,7 @@ SR_PRIV int logic16_setup_acquisition(const struct sr_dev_inst *sdi,
                if (channels & (1U << i))
                        nchan++;
 
-       if ((nchan >= 13 && samplerate > MAX_13CH_SAMPLE_RATE) ||
-           (nchan >= 10 && samplerate > MAX_10CH_SAMPLE_RATE) ||
-           (nchan >= 8  && samplerate > MAX_8CH_SAMPLE_RATE) ||
-           (nchan >= 7  && samplerate > MAX_7CH_SAMPLE_RATE) ||
-           (nchan >= 4  && samplerate > MAX_4CH_SAMPLE_RATE)) {
+       if (nchan * samplerate > MAX_SAMPLE_RATE_X_CH) {
                sr_err("Unable to sample at %" PRIu64 "Hz "
                       "with this many channels.", samplerate);
                return SR_ERR;
@@ -752,16 +748,12 @@ SR_PRIV int logic16_init_device(const struct sr_dev_inst *sdi)
 
 static void finish_acquisition(struct sr_dev_inst *sdi)
 {
-       struct sr_datafeed_packet packet;
        struct dev_context *devc;
 
        devc = sdi->priv;
 
-       /* Terminate session. */
-       packet.type = SR_DF_END;
-       sr_session_send(devc->cb_data, &packet);
+       std_session_send_df_end(sdi);
 
-       /* Remove fds from polling. */
        usb_source_remove(sdi->session, devc->ctx);
 
        devc->num_transfers = 0;
@@ -920,47 +912,51 @@ SR_PRIV void LIBUSB_CALL logic16_receive_transfer(struct libusb_transfer *transf
        new_samples = convert_sample_data(devc, devc->convbuffer,
                        devc->convbuffer_size, transfer->buffer, transfer->actual_length);
 
-       if (new_samples > 0) {
-               if (devc->trigger_fired) {
-                       /* Send the incoming transfer to the session bus. */
+       if (new_samples <= 0) {
+               resubmit_transfer(transfer);
+               return;
+       }
+
+       /* At least one new sample. */
+       if (devc->trigger_fired) {
+               /* Send the incoming transfer to the session bus. */
+               packet.type = SR_DF_LOGIC;
+               packet.payload = &logic;
+               if (devc->limit_samples &&
+                               new_samples > devc->limit_samples - devc->sent_samples)
+                       new_samples = devc->limit_samples - devc->sent_samples;
+               logic.length = new_samples * 2;
+               logic.unitsize = 2;
+               logic.data = devc->convbuffer;
+               sr_session_send(sdi, &packet);
+               devc->sent_samples += new_samples;
+       } else {
+               trigger_offset = soft_trigger_logic_check(devc->stl,
+                               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;
                        if (devc->limit_samples &&
-                                       new_samples > devc->limit_samples - devc->sent_samples)
-                               new_samples = devc->limit_samples - devc->sent_samples;
-                       logic.length = new_samples * 2;
+                                       num_samples > devc->limit_samples - devc->sent_samples)
+                               num_samples = devc->limit_samples - devc->sent_samples;
+                       logic.length = num_samples * 2;
                        logic.unitsize = 2;
-                       logic.data = devc->convbuffer;
-                       sr_session_send(devc->cb_data, &packet);
-                       devc->sent_samples += new_samples;
-               } else {
-                       trigger_offset = soft_trigger_logic_check(devc->stl,
-                                       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;
-                               if (devc->limit_samples &&
-                                               num_samples > devc->limit_samples - devc->sent_samples)
-                                       num_samples = devc->limit_samples - devc->sent_samples;
-                               logic.length = num_samples * 2;
-                               logic.unitsize = 2;
-                               logic.data = devc->convbuffer + trigger_offset * 2;
-                               sr_session_send(devc->cb_data, &packet);
-                               devc->sent_samples += num_samples;
-
-                               devc->trigger_fired = TRUE;
-                       }
-               }
+                       logic.data = devc->convbuffer + trigger_offset * 2;
+                       sr_session_send(sdi, &packet);
+                       devc->sent_samples += num_samples;
 
-               if (devc->limit_samples &&
-                               (uint64_t)devc->sent_samples >= devc->limit_samples) {
-                       devc->sent_samples = -2;
-                       free_transfer(transfer);
-                       return;
+                       devc->trigger_fired = TRUE;
                }
        }
 
+       if (devc->limit_samples &&
+                       (uint64_t)devc->sent_samples >= devc->limit_samples) {
+               devc->sent_samples = -2;
+               free_transfer(transfer);
+               return;
+       }
+
        resubmit_transfer(transfer);
 }