Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,12 @@ src_libdrivers_la_SOURCES += \
src/hardware/conrad-digi-35-cpu/protocol.c \
src/hardware/conrad-digi-35-cpu/api.c
endif
if HW_CYPRESS_FX3
src_libdrivers_la_SOURCES += \
src/hardware/cypress-fx3/protocol.h \
src/hardware/cypress-fx3/protocol.c \
src/hardware/cypress-fx3/api.c
endif
if HW_DEMO
src_libdrivers_la_SOURCES += \
src/hardware/demo/protocol.h \
Expand Down
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ SR_DRIVER([Center 3xx], [center-3xx], [serial_comm])
SR_DRIVER([ChronoVu LA], [chronovu-la], [libusb libftdi])
SR_DRIVER([Colead SLM], [colead-slm], [serial_comm])
SR_DRIVER([Conrad DIGI 35 CPU], [conrad-digi-35-cpu], [serial_comm])
SR_DRIVER([cypress-fx3], [cypress-fx3])
SR_DRIVER([demo], [demo])
SR_DRIVER([DreamSourceLab DSLogic], [dreamsourcelab-dslogic], [libusb])
SR_DRIVER([Fluke 45], [fluke-45])
Expand Down
137 changes: 137 additions & 0 deletions src/ezusb.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@

#define FW_CHUNKSIZE (4 * 1024)

#define GET_LSW(v) ((unsigned short)((v) & 0xFFFF)) // Get Least Significant Word part of an integer.
#define GET_MSW(v) ((unsigned short)((v) >> 16)) // Get Most Significant Word part of an integer.

SR_PRIV int ezusb_reset(struct libusb_device_handle *hdl, int set_clear)
{
int ret;
Expand Down Expand Up @@ -142,3 +145,137 @@ SR_PRIV int ezusb_upload_firmware(struct sr_context *ctx, libusb_device *dev,

return SR_OK;
}

SR_PRIV int ezusb_fx3_ram_write (libusb_device_handle *hdl,
unsigned char *buf,
unsigned int ramAddress,
int len)
{
int r;
int index = 0;
int size;

while (len > 0) {
size = MIN(len ,FW_CHUNKSIZE);

r = libusb_control_transfer (hdl, 0x40, 0xA0, GET_LSW(ramAddress), GET_MSW(ramAddress),
&buf[index], size, 100);

if (r != size) {
sr_err ("Error: Vendor write to FX3 RAM failed\n");
return SR_ERR;
}
ramAddress += size;
index += size;
len -= size;
}

return SR_OK;
}




SR_PRIV int ezusb_install_firmware_fx3(struct sr_context *ctx,
libusb_device_handle *hdl,
const char *name)
{
unsigned char *firmware;
size_t length, offset, chunksize,filesize;
int ret, result;
unsigned int *data_p;
unsigned int i, checksum;
unsigned int address;
int r, index;

/* Max size of FX3 fw file is 256 KB = 1 << 18*/
firmware = sr_resource_load(ctx, SR_RESOURCE_FIRMWARE,
name, &filesize, 1 << 18);
if (!firmware)
return SR_ERR;

sr_info("Uploading FX3 firmware '%s'.", name);

result = SR_OK;
/* Run through each section of code, and use vendor commands to download them to RAM.*/
index = 4;
checksum = 0;
while (index < filesize) {
data_p = (unsigned int *)(firmware + index);
length = data_p[0];
address = data_p[1];
if (length != 0) {
for (i = 0; i < length; i++)
checksum += data_p[2 + i];
r = ezusb_fx3_ram_write (hdl, firmware + index + 8, address, length * 4);
if (r != 0) {
sr_err ("Error: Failed to download data to FX3 RAM\n");
free (firmware);
return SR_ERR;
}
} else {
if (checksum != data_p[2]) {
sr_err ("Error: Checksum error in firmware binary\n");
free (firmware);
return SR_ERR;
}
r = libusb_control_transfer (hdl, 0x40, 0xA0, GET_LSW(address), GET_MSW(address), NULL,
0, 100);
if (r != 0)
printf ("Info: Ignored error in control transfer: %d\n", r);
break;
}
index += (8 + length * 4);
}
g_free(firmware);

sr_info("Firmware upload done.");
return result;
}


SR_PRIV int ezusb_upload_firmware_fx3(struct sr_context *ctx, libusb_device *dev,
int configuration, const char *name)
{
struct libusb_device_handle *hdl;
int ret;

sr_info("uploading firmware to FX3 device on %d.%d",
libusb_get_bus_number(dev), libusb_get_device_address(dev));

if ((ret = libusb_open(dev, &hdl)) < 0) {
sr_err("failed to open FX3 device: %s.", libusb_error_name(ret));
return SR_ERR;
}

/*
* The libusb Darwin backend is broken: it can report a kernel driver being
* active, but detaching it always returns an error.
*/
#if !defined(__APPLE__)
if (libusb_kernel_driver_active(hdl, 0) == 1) {
if ((ret = libusb_detach_kernel_driver(hdl, 0)) < 0) {
sr_err("failed to detach kernel driver: %s",
libusb_error_name(ret));
return SR_ERR;
}
}
#endif

if ((ret = libusb_set_configuration(hdl, configuration)) < 0) {
sr_err("Unable to set configuration: %s",
libusb_error_name(ret));
return SR_ERR;
}

if (ezusb_install_firmware_fx3(ctx, hdl, name) < 0)
return SR_ERR;

libusb_close(hdl);

return SR_OK;
}




Loading