summaryrefslogtreecommitdiff
path: root/xpp/utils/fpga_load.c
diff options
context:
space:
mode:
Diffstat (limited to 'xpp/utils/fpga_load.c')
-rw-r--r--xpp/utils/fpga_load.c217
1 files changed, 115 insertions, 102 deletions
diff --git a/xpp/utils/fpga_load.c b/xpp/utils/fpga_load.c
index 2c03704..1cbd749 100644
--- a/xpp/utils/fpga_load.c
+++ b/xpp/utils/fpga_load.c
@@ -12,8 +12,8 @@ static const char rcsid[] = "$Id$";
#define ERR(fmt, arg...) do { \
if(verbose >= LOG_ERR) \
- fprintf(stderr, "%s: ERROR: " fmt, \
- progname, ## arg); \
+ fprintf(stderr, "%s: ERROR (%d): " fmt, \
+ progname, __LINE__, ## arg); \
} while(0);
#define INFO(fmt, arg...) do { \
if(verbose >= LOG_INFO) \
@@ -35,14 +35,15 @@ static char *progname;
#define SERIAL_SIZE 8
enum fpga_load_packet_types {
- STATUS_REPLY = 0x01,
- DATA_PACKET = 0x01,
+ PT_STATUS_REPLY = 0x01,
+ PT_DATA_PACKET = 0x01,
#ifdef XORCOM_INTERNAL
- EEPROM_SET = 0x04,
+ PT_EEPROM_SET = 0x04,
#endif
- EEPROM_GET = 0x08,
- RENUMERATE = 0x10,
- BAD_COMMAND = 0xAA
+ PT_EEPROM_GET = 0x08,
+ PT_RENUMERATE = 0x10,
+ PT_RESET = 0x20,
+ PT_BAD_COMMAND = 0xAA
};
struct myeeprom {
@@ -173,8 +174,8 @@ int get_usb_string(char *buf, unsigned int len, uint16_t item, usb_dev_handle *h
}
/* My device parameters */
-#define MY_INTERFACE 0
#define MY_CONFIG 1
+#define MY_INTERFACE 0
#define MY_ENDPOINTS 4
#define MY_EP_OUT 0x04
@@ -186,10 +187,10 @@ int get_usb_string(char *buf, unsigned int len, uint16_t item, usb_dev_handle *h
#define TIMEOUT 5000
static const int my_endpoints[MY_ENDPOINTS] = {
- 0x02,
- 0x04,
- 0x86,
- 0x88
+ FPGA_EP_OUT,
+ MY_EP_OUT,
+ FPGA_EP_IN,
+ MY_EP_IN
};
void my_usb_device_cleanup(struct my_usb_device *mydev)
@@ -226,12 +227,47 @@ static void show_device_info(const struct my_usb_device *mydev)
data[4], data[5], data[6], data[7]);
}
-void dump_packet(const char *buf, int len)
+void dump_packet(const char *msg, const char *buf, int len)
{
int i;
for(i = 0; i < len; i++)
- INFO("dump: %2d> 0x%02X\n", i, (uint8_t)buf[i]);
+ INFO("%s: %2d> 0x%02X\n", msg, i, (uint8_t)buf[i]);
+}
+
+int send_usb(const char *msg, struct my_usb_device *mydev, int endpoint, struct fpga_packet_header *phead, int len, int timeout)
+{
+ char *p = (char *)phead;
+ int ret;
+
+ if(verbose >= LOG_DEBUG)
+ dump_packet(msg, p, len);
+ ret = usb_bulk_write(mydev->handle, endpoint, p, len, timeout);
+ if(ret < 0) {
+ ERR("bulk_write failed: %s\n", usb_strerror());
+ dump_packet("send_usb[ERR]", p, len);
+ return ret;
+ } else if(ret != len) {
+ ERR("bulk_write short write: %s\n", usb_strerror());
+ dump_packet("send_usb[ERR]", p, len);
+ return -EFAULT;
+ }
+ return ret;
+}
+
+int recv_usb(const char *msg, struct my_usb_device *mydev, int endpoint, char *buf, size_t len, int timeout)
+{
+ int ret;
+
+ if(verbose >= LOG_DEBUG)
+ dump_packet(msg, buf, len);
+ ret = usb_bulk_read(mydev->handle, endpoint, buf, len, timeout);
+ if(ret < 0) {
+ ERR("bulk_read failed: %s\n", usb_strerror());
+ dump_packet("recv_usb[ERR]", buf, len);
+ return ret;
+ }
+ return ret;
}
#ifdef XORCOM_INTERNAL
@@ -244,39 +280,23 @@ int eeprom_set(struct my_usb_device *mydev, const struct myeeprom *eeprom)
DBG("%s Start...\n", __FUNCTION__);
assert(mydev != NULL);
- phead->header.op = EEPROM_SET;
+ phead->header.op = PT_EEPROM_SET;
memcpy(&phead->d.eeprom_set.data, eeprom, EEPROM_SIZE);
len = sizeof(phead->d.eeprom_set) + sizeof(phead->header.op);
- if(verbose >= LOG_DEBUG) {
- DBG("%s write %d bytes\n", __FUNCTION__, len);
- dump_packet((char *)phead, len);
- }
- ret = usb_bulk_write(mydev->handle, MY_EP_OUT, (char *)phead, len, TIMEOUT);
- if(ret < 0) {
- ERR("bulk_write failed: %s\n", usb_strerror());
+ ret = send_usb("eeprom_set[W]", mydev, MY_EP_OUT, phead, len, TIMEOUT);
+ if(ret < 0)
return ret;
- } else if(ret != len) {
- ERR("bulk_write short write: %s\n", usb_strerror());
- return -EFAULT;
- }
- ret = usb_bulk_read(mydev->handle, MY_EP_IN, buf, sizeof(buf), TIMEOUT);
- if(ret < 0) {
- ERR("bulk_read failed: %s\n", usb_strerror());
+ ret = recv_usb("eeprom_set[R]", mydev, MY_EP_IN, buf, sizeof(buf), TIMEOUT);
+ if(ret <= 0)
return ret;
- } else if(ret == 0)
- return 0;
phead = (struct fpga_packet_header *)buf;
- if(phead->header.op == BAD_COMMAND) {
- ERR("Firmware rejected EEPROM_SET command\n");
+ if(phead->header.op == PT_BAD_COMMAND) {
+ ERR("Firmware rejected PT_EEPROM_SET command\n");
return -EINVAL;
- } else if(phead->header.op != EEPROM_SET) {
+ } else if(phead->header.op != PT_EEPROM_SET) {
ERR("Got unexpected reply op=%d\n", phead->header.op);
return -EINVAL;
}
- if(verbose >= LOG_DEBUG) {
- DBG("%s read %d bytes\n", __FUNCTION__, ret);
- dump_packet(buf, ret);
- }
return 0;
}
#endif
@@ -292,38 +312,22 @@ int eeprom_get(struct my_usb_device *mydev)
assert(mydev != NULL);
eeprom = &mydev->eeprom;
DBG("%s Start...\n", __FUNCTION__);
- phead->header.op = EEPROM_GET;
+ phead->header.op = PT_EEPROM_GET;
len = sizeof(phead->header.op); /* warning: sending small packet */
- if(verbose >= LOG_DEBUG) {
- DBG("%s write %d bytes\n", __FUNCTION__, len);
- dump_packet(buf, len);
- }
- ret = usb_bulk_write(mydev->handle, MY_EP_OUT, (char *)phead, len, TIMEOUT);
- if(ret < 0) {
- ERR("bulk_write failed: %s\n", usb_strerror());
+ ret = send_usb("eeprom_get[W]", mydev, MY_EP_OUT, phead, len, TIMEOUT);
+ if(ret < 0)
return ret;
- } else if(ret != len) {
- ERR("bulk_write short write: %s\n", usb_strerror());
- return -EFAULT;
- }
- ret = usb_bulk_read(mydev->handle, MY_EP_IN, buf, sizeof(buf), TIMEOUT);
- if(ret < 0) {
- ERR("bulk_read failed: %s\n", usb_strerror());
+ ret = recv_usb("eeprom_get[R]", mydev, MY_EP_IN, buf, sizeof(buf), TIMEOUT);
+ if(ret <= 0)
return ret;
- } else if(ret == 0)
- return 0;
phead = (struct fpga_packet_header *)buf;
- if(phead->header.op == BAD_COMMAND) {
- ERR("BAD_COMMAND\n");
+ if(phead->header.op == PT_BAD_COMMAND) {
+ ERR("PT_BAD_COMMAND\n");
return -EINVAL;
- } else if(phead->header.op != EEPROM_GET) {
+ } else if(phead->header.op != PT_EEPROM_GET) {
ERR("Got unexpected reply op=%d\n", phead->header.op);
return -EINVAL;
}
- if(verbose >= LOG_DEBUG) {
- DBG("%s read %d bytes\n", __FUNCTION__, ret);
- dump_packet(buf, ret);
- }
memcpy(eeprom, &phead->d.eeprom_get.data, EEPROM_SIZE);
return 0;
}
@@ -345,32 +349,23 @@ int send_hexline(struct my_usb_device *mydev, struct hexline *hexline, int seq)
ERR("Bad record %d type = %d\n", seq, hexline->d.content.header.tt);
return -EINVAL;
}
- phead->header.op = DATA_PACKET;
+ phead->header.op = PT_DATA_PACKET;
phead->d.data_packet.seq = seq;
phead->d.data_packet.reserved = 0x00;
memcpy(phead->d.data_packet.data, data, len);
len += sizeof(hexline->d.content.header);
DBG("%04d+\r", seq);
- ret = usb_bulk_write(mydev->handle, MY_EP_OUT, (char *)phead, len, TIMEOUT);
- if(ret < 0) {
- ERR("bulk_write failed: %s\n", usb_strerror());
+ ret = send_usb("hexline[W]", mydev, MY_EP_OUT, phead, len, TIMEOUT);
+ if(ret < 0)
return ret;
- } else if(ret != len) {
- ERR("bulk_write short write: %s\n", usb_strerror());
- return -EFAULT;
- }
- if (verbose >= LOG_DEBUG)
- dump_packet((char*)phead, len);
- ret = usb_bulk_read(mydev->handle, MY_EP_IN, buf, sizeof(buf), TIMEOUT);
- if(ret < 0) {
- ERR("bulk_read failed: %s\n", usb_strerror());
+ ret = recv_usb("hexline[R]", mydev, MY_EP_IN, buf, sizeof(buf), TIMEOUT);
+ if(ret <= 0)
return ret;
- } else if(ret == 0)
- return 0;
DBG("%04d-\r", seq);
phead = (struct fpga_packet_header *)buf;
- if(phead->header.op != STATUS_REPLY) {
+ if(phead->header.op != PT_STATUS_REPLY) {
ERR("Got unexpected reply op=%d\n", phead->header.op);
+ dump_packet("hexline[ERR]", buf, ret);
return -EINVAL;
}
status = (enum fpga_load_status)phead->d.status_reply.status;
@@ -381,11 +376,11 @@ int send_hexline(struct my_usb_device *mydev, struct hexline *hexline, int seq)
case FW_FAIL_RESET:
case FW_FAIL_TRANS:
ERR("status reply %s (%d)\n", load_status2str(status), status);
- dump_packet(buf, ret);
+ dump_packet("hexline[ERR]", buf, ret);
return -EPROTO;
default:
ERR("Unknown status reply %d\n", status);
- dump_packet(buf, ret);
+ dump_packet("hexline[ERR]", buf, ret);
return -EPROTO;
}
return 0;
@@ -459,10 +454,6 @@ int my_usb_device_init(const char devpath[], struct my_usb_device *mydev)
ERR("Failed to open usb device '%s/%s': %s\n", mydev->dev->bus->dirname, mydev->dev->filename, usb_strerror());
return 0;
}
- if(usb_reset(mydev->handle) != 0) {
- ERR("Reseting device: usb: %s\n", usb_strerror());
- return 0;
- }
if(usb_set_configuration(mydev->handle, MY_CONFIG) != 0) {
ERR("usb: %s\n", usb_strerror());
return 0;
@@ -471,9 +462,13 @@ int my_usb_device_init(const char devpath[], struct my_usb_device *mydev)
ERR("usb: %s\n", usb_strerror());
return 0;
}
+ if(usb_reset(mydev->handle) != 0) {
+ ERR("Reseting device: usb: %s\n", usb_strerror());
+ return 0;
+ }
dev_desc = &mydev->dev->descriptor;
config_desc = mydev->dev->config;
- interface = config_desc->interface;
+ interface = &config_desc->interface[MY_INTERFACE];
iface_desc = interface->altsetting;
INFO("Vendor:Product=%04X:%04X Class=%d (endpoints=%d)\n",
dev_desc->idVendor,
@@ -520,23 +515,18 @@ int my_usb_device_init(const char devpath[], struct my_usb_device *mydev)
return 1;
}
-int renumerate_device(struct my_usb_device *mydev)
+int renumerate_device(struct my_usb_device *mydev, enum fpga_load_packet_types pt)
{
char buf[PACKET_SIZE];
struct fpga_packet_header *phead = (struct fpga_packet_header *)buf;
int ret;
assert(mydev != NULL);
- DBG("Renumerating\n");
- phead->header.op = RENUMERATE;
- ret = usb_bulk_write(mydev->handle, MY_EP_OUT, (char *)phead, 1, TIMEOUT);
- if(ret < 0) {
- ERR("bulk_write failed: %s\n", usb_strerror());
+ DBG("Renumerating with 0x%X\n", pt);
+ phead->header.op = pt;
+ ret = send_usb("renumerate[W]", mydev, MY_EP_OUT, phead, 1, TIMEOUT);
+ if(ret < 0)
return ret;
- } else if(ret != 1) {
- ERR("bulk_write short write: %s\n", usb_strerror());
- return -EFAULT;
- }
return 0;
}
@@ -597,8 +587,10 @@ void usage()
{
fprintf(stderr, "Usage: %s -D {/proc/bus/usb|/dev/bus/usb}/<bus>/<dev> [options...]\n", progname);
fprintf(stderr, "\tOptions:\n");
- fprintf(stderr, "\t\t[-b <binfile>] # output to <binfile>\n");
+ fprintf(stderr, "\t\t[-r] # Reset the device\n");
+ fprintf(stderr, "\t\t[-b <binfile>] # Output to <binfile>\n");
fprintf(stderr, "\t\t[-I <hexfile>] # Input from <hexfile>\n");
+ fprintf(stderr, "\t\t[-i] # Show hexfile information\n");
fprintf(stderr, "\t\t[-g] # Get eeprom from device\n");
#ifdef XORCOM_INTERNAL
fprintf(stderr, "\t\t[-C srC byte] # Set Address sourCe (default: C0)\n");
@@ -627,6 +619,8 @@ int main(int argc, char *argv[])
const char *binfile = NULL;
const char *hexfile = NULL;
struct hexdata *hexdata = NULL;
+ int opt_reset = 0;
+ int opt_info = 0;
int opt_read_eeprom = 0;
#ifdef XORCOM_INTERNAL
int opt_write_eeprom = 0;
@@ -637,9 +631,9 @@ int main(int argc, char *argv[])
char *release = NULL;
char *serial = NULL;
uint8_t serial_buf[SERIAL_SIZE];
- const char options[] = "b:C:D:ghI:vV:P:R:S:";
+ const char options[] = "rib:C:D:ghI:vV:P:R:S:";
#else
- const char options[] = "b:D:ghI:v";
+ const char options[] = "rib:D:ghI:v";
#endif
int ret = 0;
@@ -657,6 +651,12 @@ int main(int argc, char *argv[])
case 'D':
devpath = optarg;
break;
+ case 'r':
+ opt_reset = 1;
+ break;
+ case 'i':
+ opt_info = 1;
+ break;
case 'b':
binfile = optarg;
break;
@@ -725,10 +725,15 @@ int main(int argc, char *argv[])
ERR("Bailing out\n");
exit(1);
}
- if(binfile) {
+ if(opt_info) {
+ printf("%s: Version=%s Checksum=%d\n",
+ hexfile, hexdata->version_info,
+ calc_checksum(hexdata));
+ }
+ if(binfile)
dump_binary(hexdata, binfile);
+ if(!devpath)
return 0;
- }
}
if(!devpath) {
ERR("Missing device path\n");
@@ -761,7 +766,7 @@ int main(int argc, char *argv[])
ret = -ENODEV;
goto dev_err;
}
- ret = renumerate_device(&mydev);
+ ret = renumerate_device(&mydev, PT_RENUMERATE);
if(ret < 0) {
ERR("Renumeration failed: errno=%d\n", ret);
goto dev_err;
@@ -798,6 +803,14 @@ int main(int argc, char *argv[])
show_device_info(&mydev);
}
#endif
+ if(opt_reset) {
+ DBG("Reseting to default\n");
+ ret = renumerate_device(&mydev, PT_RESET);
+ if(ret < 0) {
+ ERR("Renumeration to default failed: errno=%d\n", ret);
+ goto dev_err;
+ }
+ }
DBG("Exiting\n");
dev_err:
my_usb_device_cleanup(&mydev);