From: Daniel Elstner Date: Sat, 26 Sep 2015 20:41:05 +0000 (+0200) Subject: drivers: Load firmware via new resource API X-Git-Tag: libsigrok-0.4.0~238 X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=8e2d6c9db788785466d61fdac4d8fdc1535bc20c;p=libsigrok.git drivers: Load firmware via new resource API --- diff --git a/src/ezusb.c b/src/ezusb.c index 517e5f72..c2d270c4 100644 --- a/src/ezusb.c +++ b/src/ezusb.c @@ -33,6 +33,8 @@ #define LOG_PREFIX "ezusb" +#define FW_CHUNKSIZE (4 * 1024) + SR_PRIV int ezusb_reset(struct libusb_device_handle *hdl, int set_clear) { int ret; @@ -50,46 +52,51 @@ SR_PRIV int ezusb_reset(struct libusb_device_handle *hdl, int set_clear) 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; @@ -125,7 +132,7 @@ SR_PRIV int ezusb_upload_firmware(libusb_device *dev, int configuration, 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) diff --git a/src/hardware/asix-sigma/asix-sigma.c b/src/hardware/asix-sigma/asix-sigma.c index db40d533..9db557b3 100644 --- a/src/hardware/asix-sigma/asix-sigma.c +++ b/src/hardware/asix-sigma/asix-sigma.c @@ -90,17 +90,17 @@ static const int32_t trigger_matches[] = { 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) @@ -508,31 +508,20 @@ err: * 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; @@ -571,11 +560,12 @@ static int sigma_fw_2_bitbang(const char *filename, *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; @@ -614,7 +604,7 @@ static int upload_firmware(int firmware_idx, struct dev_context *devc) 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); @@ -677,10 +667,12 @@ static int dev_open(struct sr_dev_inst *sdi) 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++) { @@ -691,13 +683,13 @@ static int set_samplerate(const struct sr_dev_inst *sdi, uint64_t samplerate) 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; } diff --git a/src/hardware/fx2lafw/api.c b/src/hardware/fx2lafw/api.c index b9123513..fc6081b4 100644 --- a/src/hardware/fx2lafw/api.c +++ b/src/hardware/fx2lafw/api.c @@ -29,48 +29,48 @@ static const struct fx2lafw_profile supported_fx2[] = { * 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"}, /* @@ -80,7 +80,7 @@ static const struct fx2lafw_profile supported_fx2[] = { * Robomotic BugLogic 3 */ { 0x0925, 0x3881, "Saleae", "Logic", NULL, - FIRMWARE_DIR "/fx2lafw-saleae-logic.fw", + "fx2lafw-saleae-logic.fw", 0, NULL, NULL}, /* @@ -89,14 +89,14 @@ static const struct fx2lafw_profile supported_fx2[] = { * 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 } @@ -330,8 +330,8 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options) 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 diff --git a/src/hardware/fx2lafw/dslogic.c b/src/hardware/fx2lafw/dslogic.c index 7363faac..ec8d5342 100644 --- a/src/hardware/fx2lafw/dslogic.c +++ b/src/hardware/fx2lafw/dslogic.c @@ -19,10 +19,6 @@ */ #include -#include -#include -#include -#include #include #include #include @@ -35,24 +31,28 @@ #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)); @@ -60,22 +60,22 @@ int dslogic_fpga_firmware_upload(const struct sr_dev_inst *sdi, 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, @@ -86,8 +86,8 @@ int dslogic_fpga_firmware_upload(const struct sr_dev_inst *sdi, 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."); @@ -95,15 +95,16 @@ int dslogic_fpga_firmware_upload(const struct sr_dev_inst *sdi, 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; @@ -128,7 +129,7 @@ int dslogic_start_acquisition(const struct sr_dev_inst *sdi) 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; @@ -149,7 +150,7 @@ int dslogic_stop_acquisition(const struct sr_dev_inst *sdi) 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; diff --git a/src/hardware/fx2lafw/dslogic.h b/src/hardware/fx2lafw/dslogic.h index 83d5f4e4..54067693 100644 --- a/src/hardware/fx2lafw/dslogic.h +++ b/src/hardware/fx2lafw/dslogic.h @@ -123,10 +123,10 @@ struct dslogic_fpga_config { 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 diff --git a/src/hardware/fx2lafw/protocol.h b/src/hardware/fx2lafw/protocol.h index 35a52fba..373770d2 100644 --- a/src/hardware/fx2lafw/protocol.h +++ b/src/hardware/fx2lafw/protocol.h @@ -51,9 +51,9 @@ #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 diff --git a/src/hardware/hantek-dso/api.c b/src/hardware/hantek-dso/api.c index b05e644a..e55f4e09 100644 --- a/src/hardware/hantek-dso/api.c +++ b/src/hardware/hantek-dso/api.c @@ -88,23 +88,23 @@ static const struct dso_profile dev_profiles[] = { { 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 }, }; @@ -323,8 +323,8 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options) 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 diff --git a/src/hardware/saleae-logic16/api.c b/src/hardware/saleae-logic16/api.c index 9d523144..43477d5b 100644 --- a/src/hardware/saleae-logic16/api.c +++ b/src/hardware/saleae-logic16/api.c @@ -34,7 +34,7 @@ #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 @@ -218,8 +218,8 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options) 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 diff --git a/src/hardware/saleae-logic16/protocol.c b/src/hardware/saleae-logic16/protocol.c index af0eed6a..5566b859 100644 --- a/src/hardware/saleae-logic16/protocol.c +++ b/src/hardware/saleae-logic16/protocol.c @@ -31,8 +31,8 @@ #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) @@ -465,13 +465,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; @@ -479,51 +483,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, 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. */ diff --git a/src/hardware/sysclk-lwla/lwla.c b/src/hardware/sysclk-lwla/lwla.c index ab9fece8..1934d617 100644 --- a/src/hardware/sysclk-lwla/lwla.c +++ b/src/hardware/sysclk-lwla/lwla.c @@ -18,8 +18,6 @@ */ #include -#include -#include #include #include #include "libsigrok-internal.h" @@ -29,59 +27,47 @@ #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; @@ -90,27 +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; - 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); diff --git a/src/hardware/sysclk-lwla/lwla.h b/src/hardware/sysclk-lwla/lwla.h index d4abea3f..5484d2eb 100644 --- a/src/hardware/sysclk-lwla/lwla.h +++ b/src/hardware/sysclk-lwla/lwla.h @@ -101,8 +101,9 @@ struct regval_pair { 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); diff --git a/src/hardware/sysclk-lwla/protocol.c b/src/hardware/sysclk-lwla/protocol.c index 1c9bca88..5891af4f 100644 --- a/src/hardware/sysclk-lwla/protocol.c +++ b/src/hardware/sysclk-lwla/protocol.c @@ -748,10 +748,12 @@ SR_PRIV int lwla_init_device(const struct sr_dev_inst *sdi) 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; @@ -764,7 +766,8 @@ SR_PRIV int lwla_set_clock_config(const struct sr_dev_inst *sdi) 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; diff --git a/src/libsigrok-internal.h b/src/libsigrok-internal.h index f3b932b7..39167164 100644 --- a/src/libsigrok-internal.h +++ b/src/libsigrok-internal.h @@ -859,10 +859,10 @@ SR_PRIV int serial_timeout(struct sr_serial_dev_inst *port, int num_bytes); #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 --------------------------------------------------------*/