]> sigrok.org Git - libsigrok.git/blobdiff - src/hardware/sysclk-lwla/lwla.c
uni-t-ut181a: silence compiler warning, use of uninitialized variable
[libsigrok.git] / src / hardware / sysclk-lwla / lwla.c
index d2f2a2579e5e41861ef053339736a8e2d672090c..dd36f87fc33c9b6f96a6b88b338b97304a5ca113 100644 (file)
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <errno.h>
+#include <config.h>
 #include <glib/gstdio.h>
 #include <libsigrok/libsigrok.h>
-#include "libsigrok-internal.h"
-#include "protocol.h"
+#include <libsigrok-internal.h>
 #include "lwla.h"
+#include "protocol.h"
 
-#define BITSTREAM_MAX_SIZE    (256 * 1024) /* bitstream size limit for safety */
-#define BITSTREAM_HEADER_SIZE 4            /* transfer header size in bytes */
+#define BITSTREAM_MAX_SIZE    (256 * 1024) /* Bitstream size limit for safety */
+#define BITSTREAM_HEADER_SIZE 4            /* Transfer header size in bytes */
 
-/* Load a bitstream file into memory.  Returns a newly allocated array
+/* Load a bitstream file into memory. Returns a newly allocated array
  * consisting of a 32-bit length field followed by the bitstream data.
  */
-static unsigned char *load_bitstream_file(const char *filename, int *length_p)
+static unsigned char *load_bitstream(struct sr_context *ctx,
+                                    const char *name, int *length_p)
 {
-       GStatBuf statbuf;
-       FILE *file;
+       struct sr_resource rbf;
        unsigned char *stream;
-       size_t length, count;
+       ssize_t length, count;
 
-       /* Retrieve and validate the file size. */
-       if (g_stat(filename, &statbuf) < 0) {
-               sr_err("Failed to access bitstream file: %s.",
-                      g_strerror(errno));
-               return NULL;
-       }
-       if (!S_ISREG(statbuf.st_mode)) {
-               sr_err("Bitstream is not a regular file.");
+       if (sr_resource_open(ctx, &rbf, SR_RESOURCE_FIRMWARE, name) != SR_OK)
                return NULL;
-       }
-       if (statbuf.st_size <= 0 || statbuf.st_size > BITSTREAM_MAX_SIZE) {
+
+       if (rbf.size == 0 || rbf.size > BITSTREAM_MAX_SIZE) {
                sr_err("Refusing to load bitstream of unreasonable size "
-                      "(%" PRIu64 " bytes).", (uint64_t)statbuf.st_size);
+                      "(%" PRIu64 " bytes).", rbf.size);
+               sr_resource_close(ctx, &rbf);
                return NULL;
        }
 
        /* The message length includes the 4-byte header. */
-       length = BITSTREAM_HEADER_SIZE + statbuf.st_size;
+       length = BITSTREAM_HEADER_SIZE + rbf.size;
        stream = g_try_malloc(length);
        if (!stream) {
                sr_err("Failed to allocate bitstream buffer.");
-               return NULL;
-       }
-
-       file = g_fopen(filename, "rb");
-       if (!file) {
-               sr_err("Failed to open bitstream file: %s.", g_strerror(errno));
-               g_free(stream);
+               sr_resource_close(ctx, &rbf);
                return NULL;
        }
 
        /* Write the message length header. */
        *(uint32_t *)stream = GUINT32_TO_BE(length);
 
-       count = fread(stream + BITSTREAM_HEADER_SIZE,
-                     length - BITSTREAM_HEADER_SIZE, 1, file);
-       if (count != 1) {
-               sr_err("Failed to read bitstream file: %s.", g_strerror(errno));
-               fclose(file);
+       count = sr_resource_read(ctx, &rbf, stream + BITSTREAM_HEADER_SIZE,
+                                length - BITSTREAM_HEADER_SIZE);
+       sr_resource_close(ctx, &rbf);
+
+       if (count != length - BITSTREAM_HEADER_SIZE) {
+               sr_err("Failed to read bitstream '%s'.", name);
                g_free(stream);
                return NULL;
        }
-       fclose(file);
 
        *length_p = length;
        return stream;
@@ -88,29 +76,24 @@ static unsigned char *load_bitstream_file(const char *filename, int *length_p)
 /* Load a Raw Binary File (.rbf) from the firmware directory and transfer
  * it to the device.
  */
-SR_PRIV int lwla_send_bitstream(const struct sr_usb_dev_inst *usb,
-                               const char *basename)
+SR_PRIV int lwla_send_bitstream(struct sr_context *ctx,
+                               const struct sr_usb_dev_inst *usb,
+                               const char *name)
 {
-       char *filename;
        unsigned char *stream;
-       int ret;
-       int length;
-       int xfer_len;
+       int ret, length, xfer_len;
 
-       if (!usb || !basename)
+       if (!ctx || !usb || !name)
                return SR_ERR_BUG;
 
-       filename = g_build_filename(FIRMWARE_DIR, basename, NULL);
-       sr_info("Downloading FPGA bitstream at '%s'.", filename);
-
-       stream = load_bitstream_file(filename, &length);
-       g_free(filename);
-
+       stream = load_bitstream(ctx, name, &length);
        if (!stream)
                return SR_ERR;
 
+       sr_info("Downloading FPGA bitstream '%s'.", name);
+
        /* Transfer the entire bitstream in one URB. */
-       ret = libusb_bulk_transfer(usb->devhdl, EP_BITSTREAM,
+       ret = libusb_bulk_transfer(usb->devhdl, EP_CONFIG,
                                   stream, length, &xfer_len, USB_TIMEOUT_MS);
        g_free(stream);
 
@@ -135,8 +118,7 @@ SR_PRIV int lwla_send_bitstream(const struct sr_usb_dev_inst *usb,
 SR_PRIV int lwla_send_command(const struct sr_usb_dev_inst *usb,
                              const uint16_t *command, int cmd_len)
 {
-       int ret;
-       int xfer_len;
+       int ret, xfer_len;
 
        if (!usb || !command || cmd_len <= 0)
                return SR_ERR_BUG;
@@ -155,55 +137,54 @@ SR_PRIV int lwla_send_command(const struct sr_usb_dev_inst *usb,
                       LWLA_TO_UINT16(command[0]), xfer_len, cmd_len * 2);
                return SR_ERR;
        }
+
        return SR_OK;
 }
 
 SR_PRIV int lwla_receive_reply(const struct sr_usb_dev_inst *usb,
-                              uint32_t *reply, int reply_len, int expect_len)
+                              void *reply, int buf_size, int *xfer_len)
 {
        int ret;
-       int xfer_len;
 
-       if (!usb || !reply || reply_len <= 0)
+       if (!usb || !reply || buf_size <= 0)
                return SR_ERR_BUG;
 
-       xfer_len = 0;
-       ret = libusb_bulk_transfer(usb->devhdl, EP_REPLY,
-                                  (unsigned char *)reply, reply_len * 4,
-                                  &xfer_len, USB_TIMEOUT_MS);
+       ret = libusb_bulk_transfer(usb->devhdl, EP_REPLY, reply, buf_size,
+                                  xfer_len, USB_TIMEOUT_MS);
        if (ret != 0) {
                sr_dbg("Failed to receive reply: %s.", libusb_error_name(ret));
                return SR_ERR;
        }
-       if (xfer_len != expect_len * 4) {
-               sr_dbg("Failed to receive reply: incorrect length %d != %d.",
-                      xfer_len, expect_len * 4);
-               return SR_ERR;
-       }
+
        return SR_OK;
 }
 
 SR_PRIV int lwla_read_reg(const struct sr_usb_dev_inst *usb,
                          uint16_t reg, uint32_t *value)
 {
-       int ret;
+       int xfer_len, ret;
        uint16_t command[2];
-       uint32_t reply[128]; /* full EP buffer to avoid overflows */
+       uint32_t reply[128]; /* Full EP buffer to avoid overflows. */
 
        command[0] = LWLA_WORD(CMD_READ_REG);
        command[1] = LWLA_WORD(reg);
 
-       ret = lwla_send_command(usb, command, ARRAY_SIZE(command));
-
+       ret = lwla_send_command(usb, ARRAY_AND_SIZE(command));
        if (ret != SR_OK)
                return ret;
 
-       ret = lwla_receive_reply(usb, reply, ARRAY_SIZE(reply), 1);
+       ret = lwla_receive_reply(usb, reply, sizeof(reply), &xfer_len);
+       if (ret != SR_OK)
+               return ret;
 
-       if (ret == SR_OK)
-               *value = LWLA_TO_UINT32(reply[0]);
+       if (xfer_len != 4) {
+               sr_dbg("Invalid register read response of length %d.",
+                      xfer_len);
+               return SR_ERR;
+       }
+       *value = LWLA_TO_UINT32(reply[0]);
 
-       return ret;
+       return SR_OK;
 }
 
 SR_PRIV int lwla_write_reg(const struct sr_usb_dev_inst *usb,
@@ -216,18 +197,17 @@ SR_PRIV int lwla_write_reg(const struct sr_usb_dev_inst *usb,
        command[2] = LWLA_WORD_0(value);
        command[3] = LWLA_WORD_1(value);
 
-       return lwla_send_command(usb, command, ARRAY_SIZE(command));
+       return lwla_send_command(usb, ARRAY_AND_SIZE(command));
 }
 
 SR_PRIV int lwla_write_regs(const struct sr_usb_dev_inst *usb,
-                           const struct regval_pair *regvals, int count)
+                           const struct regval *regvals, int count)
 {
-       int i;
-       int ret;
+       int i, ret;
 
        ret = SR_OK;
 
-       for (i = 0; i < count; ++i) {
+       for (i = 0; i < count; i++) {
                ret = lwla_write_reg(usb, regvals[i].reg, regvals[i].val);
 
                if (ret != SR_OK)