#define LOG_PREFIX "ezusb"
+#define FW_CHUNKSIZE (4 * 1024)
+
SR_PRIV int ezusb_reset(struct libusb_device_handle *hdl, int set_clear)
{
int ret;
return ret;
}
-SR_PRIV int ezusb_install_firmware(libusb_device_handle *hdl,
- const char *filename)
+SR_PRIV int ezusb_install_firmware(struct sr_context *ctx,
+ libusb_device_handle *hdl,
+ const char *name)
{
- FILE *fw;
- int offset, chunksize, ret, result;
- unsigned char buf[4096];
-
- sr_info("Uploading firmware at %s", filename);
- if (!(fw = g_fopen(filename, "rb"))) {
- sr_err("Unable to open firmware file %s for reading: %s",
- filename, g_strerror(errno));
+ unsigned char *firmware;
+ size_t length, offset, chunksize;
+ int ret, result;
+
+ /* Max size is 64 kiB since the value field of the setup packet,
+ * which holds the firmware offset, is only 16 bit wide.
+ */
+ firmware = sr_resource_load(ctx, SR_RESOURCE_FIRMWARE,
+ name, &length, 1 << 16);
+ if (!firmware)
return SR_ERR;
- }
+
+ sr_info("Uploading firmware '%s'.", name);
result = SR_OK;
offset = 0;
- while (1) {
- chunksize = fread(buf, 1, 4096, fw);
- if (chunksize == 0)
- break;
+ while (offset < length) {
+ chunksize = MIN(length - offset, FW_CHUNKSIZE);
+
ret = libusb_control_transfer(hdl, LIBUSB_REQUEST_TYPE_VENDOR |
LIBUSB_ENDPOINT_OUT, 0xa0, offset,
- 0x0000, buf, chunksize, 100);
+ 0x0000, firmware + offset,
+ chunksize, 100);
if (ret < 0) {
sr_err("Unable to send firmware to device: %s.",
libusb_error_name(ret));
- result = SR_ERR;
- break;
+ g_free(firmware);
+ return SR_ERR;
}
- sr_info("Uploaded %d bytes", chunksize);
+ sr_info("Uploaded %zu bytes.", chunksize);
offset += chunksize;
}
- fclose(fw);
- sr_info("Firmware upload done");
+ g_free(firmware);
+
+ sr_info("Firmware upload done.");
return result;
}
-SR_PRIV int ezusb_upload_firmware(libusb_device *dev, int configuration,
- const char *filename)
+SR_PRIV int ezusb_upload_firmware(struct sr_context *ctx, libusb_device *dev,
+ int configuration, const char *name)
{
struct libusb_device_handle *hdl;
int ret;
if ((ezusb_reset(hdl, 1)) < 0)
return SR_ERR;
- if (ezusb_install_firmware(hdl, filename) < 0)
+ if (ezusb_install_firmware(ctx, hdl, name) < 0)
return SR_ERR;
if ((ezusb_reset(hdl, 0)) < 0)
SR_TRIGGER_FALLING,
};
-static const char *sigma_firmware_files[] = {
+static const char sigma_firmware_files[][24] = {
/* 50 MHz, supports 8 bit fractions */
- FIRMWARE_DIR "/asix-sigma-50.fw",
+ "asix-sigma-50.fw",
/* 100 MHz */
- FIRMWARE_DIR "/asix-sigma-100.fw",
+ "asix-sigma-100.fw",
/* 200 MHz */
- FIRMWARE_DIR "/asix-sigma-200.fw",
+ "asix-sigma-200.fw",
/* Synchronous clock from pin */
- FIRMWARE_DIR "/asix-sigma-50sync.fw",
+ "asix-sigma-50sync.fw",
/* Frequency counter */
- FIRMWARE_DIR "/asix-sigma-phasor.fw",
+ "asix-sigma-phasor.fw",
};
static int sigma_read(void *buf, size_t size, struct dev_context *devc)
* pulses used to program the FPGA. Note that the *bb_cmd must be free()'d
* by the caller of this function.
*/
-static int sigma_fw_2_bitbang(const char *filename,
+static int sigma_fw_2_bitbang(struct sr_context *ctx, const char *name,
uint8_t **bb_cmd, gsize *bb_cmd_size)
{
- GMappedFile *file;
- GError *error;
- gsize i, file_size, bb_size;
- gchar *firmware;
+ size_t i, file_size, bb_size;
+ char *firmware;
uint8_t *bb_stream, *bbs;
uint32_t imm;
int bit, v;
int ret = SR_OK;
- /*
- * Map the file and make the mapped buffer writable.
- * NOTE: Using writable=TRUE does _NOT_ mean that file that is mapped
- * will be modified. It will not be modified until someone uses
- * g_file_set_contents() on it.
- */
- error = NULL;
- file = g_mapped_file_new(filename, TRUE, &error);
- g_assert_no_error(error);
-
- file_size = g_mapped_file_get_length(file);
- firmware = g_mapped_file_get_contents(file);
- g_assert(firmware);
+ firmware = sr_resource_load(ctx, SR_RESOURCE_FIRMWARE,
+ name, &file_size, 256 * 1024);
+ if (!firmware)
+ return SR_ERR;
/* Weird magic transformation below, I have no idea what it does. */
imm = 0x3f6df2ab;
*bb_cmd_size = bb_size;
exit:
- g_mapped_file_unref(file);
+ g_free(firmware);
return ret;
}
-static int upload_firmware(int firmware_idx, struct dev_context *devc)
+static int upload_firmware(struct sr_context *ctx,
+ int firmware_idx, struct dev_context *devc)
{
int ret;
unsigned char *buf;
return ret;
/* Prepare firmware. */
- ret = sigma_fw_2_bitbang(firmware, &buf, &buf_size);
+ ret = sigma_fw_2_bitbang(ctx, firmware, &buf, &buf_size);
if (ret != SR_OK) {
sr_err("An error occurred while reading the firmware: %s",
firmware);
static int set_samplerate(const struct sr_dev_inst *sdi, uint64_t samplerate)
{
struct dev_context *devc;
+ struct drv_context *drvc;
unsigned int i;
int ret;
devc = sdi->priv;
+ drvc = sdi->driver->context;
ret = SR_OK;
for (i = 0; i < ARRAY_SIZE(samplerates); i++) {
return SR_ERR_SAMPLERATE;
if (samplerate <= SR_MHZ(50)) {
- ret = upload_firmware(0, devc);
+ ret = upload_firmware(drvc->sr_ctx, 0, devc);
devc->num_channels = 16;
} else if (samplerate == SR_MHZ(100)) {
- ret = upload_firmware(1, devc);
+ ret = upload_firmware(drvc->sr_ctx, 1, devc);
devc->num_channels = 8;
} else if (samplerate == SR_MHZ(200)) {
- ret = upload_firmware(2, devc);
+ ret = upload_firmware(drvc->sr_ctx, 2, devc);
devc->num_channels = 4;
}
* ARMFLY AX-Pro
*/
{ 0x08a9, 0x0014, "CWAV", "USBee AX", NULL,
- FIRMWARE_DIR "/fx2lafw-cwav-usbeeax.fw",
+ "fx2lafw-cwav-usbeeax.fw",
0, NULL, NULL},
/*
* CWAV USBee DX
* XZL-Studio DX
*/
{ 0x08a9, 0x0015, "CWAV", "USBee DX", NULL,
- FIRMWARE_DIR "/fx2lafw-cwav-usbeedx.fw",
+ "fx2lafw-cwav-usbeedx.fw",
DEV_CAPS_16BIT, NULL, NULL },
/*
* CWAV USBee SX
*/
{ 0x08a9, 0x0009, "CWAV", "USBee SX", NULL,
- FIRMWARE_DIR "/fx2lafw-cwav-usbeesx.fw",
+ "fx2lafw-cwav-usbeesx.fw",
0, NULL, NULL},
/* DreamSourceLab DSLogic (before FW upload) */
{ 0x2a0e, 0x0001, "DreamSourceLab", "DSLogic", NULL,
- FIRMWARE_DIR "/dreamsourcelab-dslogic-fx2.fw",
+ "dreamsourcelab-dslogic-fx2.fw",
DEV_CAPS_16BIT, NULL, NULL},
/* DreamSourceLab DSLogic (after FW upload) */
{ 0x2a0e, 0x0001, "DreamSourceLab", "DSLogic", NULL,
- FIRMWARE_DIR "/dreamsourcelab-dslogic-fx2.fw",
+ "dreamsourcelab-dslogic-fx2.fw",
DEV_CAPS_16BIT, "DreamSourceLab", "DSLogic"},
/* DreamSourceLab DSCope (before FW upload) */
{ 0x2a0e, 0x0002, "DreamSourceLab", "DSCope", NULL,
- FIRMWARE_DIR "/dreamsourcelab-dscope-fx2.fw",
+ "dreamsourcelab-dscope-fx2.fw",
DEV_CAPS_16BIT, NULL, NULL},
/* DreamSourceLab DSCope (after FW upload) */
{ 0x2a0e, 0x0002, "DreamSourceLab", "DSCope", NULL,
- FIRMWARE_DIR "/dreamsourcelab-dscope-fx2.fw",
+ "dreamsourcelab-dscope-fx2.fw",
DEV_CAPS_16BIT, "DreamSourceLab", "DSCope"},
/* DreamSourceLab DSLogic Pro (before FW upload) */
{ 0x2a0e, 0x0003, "DreamSourceLab", "DSLogic Pro", NULL,
- FIRMWARE_DIR "/dreamsourcelab-dslogic-pro-fx2.fw",
+ "dreamsourcelab-dslogic-pro-fx2.fw",
DEV_CAPS_16BIT, NULL, NULL},
/* DreamSourceLab DSLogic Pro (after FW upload) */
{ 0x2a0e, 0x0003, "DreamSourceLab", "DSLogic Pro", NULL,
- FIRMWARE_DIR "/dreamsourcelab-dslogic-pro-fx2.fw",
+ "dreamsourcelab-dslogic-pro-fx2.fw",
DEV_CAPS_16BIT, "DreamSourceLab", "DSLogic"},
/*
* Robomotic BugLogic 3
*/
{ 0x0925, 0x3881, "Saleae", "Logic", NULL,
- FIRMWARE_DIR "/fx2lafw-saleae-logic.fw",
+ "fx2lafw-saleae-logic.fw",
0, NULL, NULL},
/*
* Braintechnology USB Interface V2.x
*/
{ 0x04B4, 0x8613, "Cypress", "FX2", NULL,
- FIRMWARE_DIR "/fx2lafw-cypress-fx2.fw",
+ "fx2lafw-cypress-fx2.fw",
DEV_CAPS_16BIT, NULL, NULL },
/*
* Braintechnology USB-LPS
*/
{ 0x16d0, 0x0498, "Braintechnology", "USB-LPS", NULL,
- FIRMWARE_DIR "/fx2lafw-braintechnology-usb-lps.fw",
+ "fx2lafw-braintechnology-usb-lps.fw",
DEV_CAPS_16BIT, NULL, NULL },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }
sdi->conn = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]),
libusb_get_device_address(devlist[i]), NULL);
} else {
- if (ezusb_upload_firmware(devlist[i], USB_CONFIGURATION,
- prof->firmware) == SR_OK)
+ if (ezusb_upload_firmware(drvc->sr_ctx, devlist[i],
+ USB_CONFIGURATION, prof->firmware) == SR_OK)
/* Store when this device's FW was updated. */
devc->fw_updated = g_get_monotonic_time();
else
*/
#include <config.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
#include <math.h>
#include <glib.h>
#include <glib/gstdio.h>
#define USB_TIMEOUT (3 * 1000)
-int dslogic_fpga_firmware_upload(const struct sr_dev_inst *sdi,
- const char *filename)
+SR_PRIV int dslogic_fpga_firmware_upload(const struct sr_dev_inst *sdi,
+ const char *name)
{
- FILE *fw;
- struct stat st;
+ uint64_t sum;
+ struct sr_resource bitstream;
+ struct drv_context *drvc;
struct sr_usb_dev_inst *usb;
- int chunksize, result, ret;
unsigned char *buf;
- int sum, transferred;
+ ssize_t chunksize;
+ int transferred;
+ int result, ret;
uint8_t cmd[3];
- sr_dbg("Uploading FPGA firmware at %s.", filename);
-
+ drvc = sdi->driver->context;
usb = sdi->conn;
- if (stat(filename, &st) < 0) {
- sr_err("Unable to upload FPGA firmware: %s", g_strerror(errno));
- return SR_ERR;
- }
+
+ sr_dbg("Uploading FPGA firmware '%s'.", name);
+
+ result = sr_resource_open(drvc->sr_ctx, &bitstream,
+ SR_RESOURCE_FIRMWARE, name);
+ if (result != SR_OK)
+ return result;
/* Tell the device firmware is coming. */
memset(cmd, 0, sizeof(cmd));
LIBUSB_ENDPOINT_OUT, DS_CMD_FPGA_FW, 0x0000, 0x0000,
(unsigned char *)&cmd, sizeof(cmd), USB_TIMEOUT)) < 0) {
sr_err("Failed to upload FPGA firmware: %s.", libusb_error_name(ret));
- return SR_ERR;
- }
- buf = g_malloc(FW_BUFSIZE);
-
- if (!(fw = g_fopen(filename, "rb"))) {
- sr_err("Unable to open %s for reading: %s.", filename, g_strerror(errno));
+ sr_resource_close(drvc->sr_ctx, &bitstream);
return SR_ERR;
}
/* Give the FX2 time to get ready for FPGA firmware upload. */
g_usleep(FPGA_UPLOAD_DELAY);
+ buf = g_malloc(FW_BUFSIZE);
sum = 0;
result = SR_OK;
while (1) {
- if ((chunksize = fread(buf, 1, FW_BUFSIZE, fw)) == 0)
+ chunksize = sr_resource_read(drvc->sr_ctx, &bitstream,
+ buf, FW_BUFSIZE);
+ if (chunksize < 0)
+ result = SR_ERR;
+ if (chunksize <= 0)
break;
if ((ret = libusb_bulk_transfer(usb->devhdl, 2 | LIBUSB_ENDPOINT_OUT,
break;
}
sum += transferred;
- sr_spew("Uploaded %d/%" PRIu64 " bytes.",
- sum, (uint64_t)st.st_size);
+ sr_spew("Uploaded %" PRIu64 "/%" PRIu64 " bytes.",
+ sum, bitstream.size);
if (transferred != chunksize) {
sr_err("Short transfer while uploading FPGA firmware.");
break;
}
}
- fclose(fw);
g_free(buf);
+ sr_resource_close(drvc->sr_ctx, &bitstream);
+
if (result == SR_OK)
sr_dbg("FPGA firmware upload done.");
return result;
}
-int dslogic_start_acquisition(const struct sr_dev_inst *sdi)
+SR_PRIV int dslogic_start_acquisition(const struct sr_dev_inst *sdi)
{
struct dev_context *devc;
struct sr_usb_dev_inst *usb;
return SR_OK;
}
-int dslogic_stop_acquisition(const struct sr_dev_inst *sdi)
+SR_PRIV int dslogic_stop_acquisition(const struct sr_dev_inst *sdi)
{
struct sr_usb_dev_inst *usb;
struct dslogic_mode mode;
return SR_OK;
}
-int dslogic_fpga_configure(const struct sr_dev_inst *sdi)
+SR_PRIV int dslogic_fpga_configure(const struct sr_dev_inst *sdi)
{
struct dev_context *devc;
struct sr_usb_dev_inst *usb;
uint32_t end_sync;
};
-int dslogic_fpga_firmware_upload(const struct sr_dev_inst *sdi,
- const char *filename);
-int dslogic_start_acquisition(const struct sr_dev_inst *sdi);
-int dslogic_stop_acquisition(const struct sr_dev_inst *sdi);
-int dslogic_fpga_configure(const struct sr_dev_inst *sdi);
+SR_PRIV int dslogic_fpga_firmware_upload(const struct sr_dev_inst *sdi,
+ const char *name);
+SR_PRIV int dslogic_start_acquisition(const struct sr_dev_inst *sdi);
+SR_PRIV int dslogic_stop_acquisition(const struct sr_dev_inst *sdi);
+SR_PRIV int dslogic_fpga_configure(const struct sr_dev_inst *sdi);
#endif
#define DEV_CAPS_16BIT (1 << DEV_CAPS_16BIT_POS)
-#define DSLOGIC_FPGA_FIRMWARE FIRMWARE_DIR "/dreamsourcelab-dslogic-fpga.fw"
-#define DSCOPE_FPGA_FIRMWARE FIRMWARE_DIR "/dreamsourcelab-dscope-fpga.fw"
-#define DSLOGIC_PRO_FPGA_FIRMWARE FIRMWARE_DIR "/dreamsourcelab-dslogic-pro-fpga.fw"
+#define DSLOGIC_FPGA_FIRMWARE "dreamsourcelab-dslogic-fpga.fw"
+#define DSCOPE_FPGA_FIRMWARE "dreamsourcelab-dscope-fpga.fw"
+#define DSLOGIC_PRO_FPGA_FIRMWARE "dreamsourcelab-dslogic-pro-fpga.fw"
/* Protocol commands */
#define CMD_GET_FW_VERSION 0xb0
{ 0x04b4, 0x2090, 0x04b5, 0x2090,
"Hantek", "DSO-2090",
buffersizes_32k,
- FIRMWARE_DIR "/hantek-dso-2090.fw" },
+ "hantek-dso-2090.fw" },
{ 0x04b4, 0x2150, 0x04b5, 0x2150,
"Hantek", "DSO-2150",
buffersizes_32k,
- FIRMWARE_DIR "/hantek-dso-2150.fw" },
+ "hantek-dso-2150.fw" },
{ 0x04b4, 0x2250, 0x04b5, 0x2250,
"Hantek", "DSO-2250",
buffersizes_512k,
- FIRMWARE_DIR "/hantek-dso-2250.fw" },
+ "hantek-dso-2250.fw" },
{ 0x04b4, 0x5200, 0x04b5, 0x5200,
"Hantek", "DSO-5200",
buffersizes_14k,
- FIRMWARE_DIR "/hantek-dso-5200.fw" },
+ "hantek-dso-5200.fw" },
{ 0x04b4, 0x520a, 0x04b5, 0x520a,
"Hantek", "DSO-5200A",
buffersizes_512k,
- FIRMWARE_DIR "/hantek-dso-5200A.fw" },
+ "hantek-dso-5200A.fw" },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
};
sdi->connection_id = g_strdup(connection_id);
devices = g_slist_append(devices, sdi);
devc = sdi->priv;
- if (ezusb_upload_firmware(devlist[i], USB_CONFIGURATION,
- prof->firmware) == SR_OK)
+ if (ezusb_upload_firmware(drvc->sr_ctx, devlist[i],
+ USB_CONFIGURATION, prof->firmware) == SR_OK)
/* Remember when the firmware on this device was updated */
devc->fw_updated = g_get_monotonic_time();
else
#define USB_INTERFACE 0
#define USB_CONFIGURATION 1
-#define FX2_FIRMWARE FIRMWARE_DIR "/saleae-logic16-fx2.fw"
+#define FX2_FIRMWARE "saleae-logic16-fx2.fw"
#define MAX_RENUM_DELAY_MS 3000
#define NUM_SIMUL_TRANSFERS 32
libusb_get_bus_number(devlist[i]),
libusb_get_device_address(devlist[i]), NULL);
} else {
- if (ezusb_upload_firmware(devlist[i], USB_CONFIGURATION,
- FX2_FIRMWARE) == SR_OK)
+ if (ezusb_upload_firmware(drvc->sr_ctx, devlist[i],
+ USB_CONFIGURATION, FX2_FIRMWARE) == SR_OK)
/* Store when this device's FW was updated. */
devc->fw_updated = g_get_monotonic_time();
else
#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)
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;
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, g_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. */
*/
#include <config.h>
-#include <errno.h>
-#include <sys/stat.h>
#include <glib/gstdio.h>
#include <libsigrok/libsigrok.h>
#include "libsigrok-internal.h"
#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)
{
- struct stat 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 (stat(filename, &statbuf) < 0) {
- sr_err("Failed to access bitstream file: %s.",
- g_strerror(errno));
+ if (sr_resource_open(ctx, &rbf, SR_RESOURCE_FIRMWARE, name) != SR_OK)
return NULL;
- }
- if (!S_ISREG(statbuf.st_mode)) {
- sr_err("Bitstream is not a regular file.");
- 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;
/* 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;
- 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,
stream, length, &xfer_len, USB_TIMEOUT_MS);
unsigned int val;
};
-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);
SR_PRIV int lwla_send_command(const struct sr_usb_dev_inst *usb,
const uint16_t *command, int cmd_len);
SR_PRIV int lwla_set_clock_config(const struct sr_dev_inst *sdi)
{
struct dev_context *devc;
+ struct drv_context *drvc;
int ret;
enum clock_config choice;
devc = sdi->priv;
+ drvc = sdi->driver->context;
if (sdi->status == SR_ST_INACTIVE)
choice = CONF_CLOCK_NONE;
if (choice != devc->cur_clock_config) {
devc->cur_clock_config = CONF_CLOCK_NONE;
- ret = lwla_send_bitstream(sdi->conn, bitstream_map[choice]);
+ ret = lwla_send_bitstream(drvc->sr_ctx, sdi->conn,
+ bitstream_map[choice]);
if (ret == SR_OK)
devc->cur_clock_config = choice;
return ret;
#ifdef HAVE_LIBUSB_1_0
SR_PRIV int ezusb_reset(struct libusb_device_handle *hdl, int set_clear);
-SR_PRIV int ezusb_install_firmware(libusb_device_handle *hdl,
- const char *filename);
-SR_PRIV int ezusb_upload_firmware(libusb_device *dev, int configuration,
- const char *filename);
+SR_PRIV int ezusb_install_firmware(struct sr_context *ctx, libusb_device_handle *hdl,
+ const char *name);
+SR_PRIV int ezusb_upload_firmware(struct sr_context *ctx, libusb_device *dev,
+ int configuration, const char *name);
#endif
/*--- hardware/usb.c --------------------------------------------------------*/