drivers: Load firmware via new resource API
This commit is contained in:
parent
7d89fd60e5
commit
8e2d6c9db7
53
src/ezusb.c
53
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];
|
||||
unsigned char *firmware;
|
||||
size_t length, offset, chunksize;
|
||||
int ret, result;
|
||||
|
||||
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));
|
||||
/* 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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -19,10 +19,6 @@
|
|||
*/
|
||||
|
||||
#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>
|
||||
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
command[0] = COMMAND_FPGA_UPLOAD_SEND_DATA;
|
||||
command[1] = chunksize;
|
||||
|
||||
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;
|
||||
}
|
||||
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. */
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <libsigrok/libsigrok.h>
|
||||
#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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 --------------------------------------------------------*/
|
||||
|
|
Loading…
Reference in New Issue