libusb 0.3.4 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Gemfile +1 -0
  5. data/History.md +10 -0
  6. data/README.md +19 -6
  7. data/Rakefile +1 -1
  8. data/ext/extconf.rb +17 -1
  9. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/AUTHORS +18 -6
  10. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/COPYING +0 -0
  11. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/ChangeLog +58 -1
  12. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/INSTALL +0 -0
  13. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/Makefile.am +6 -1
  14. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/Makefile.in +248 -174
  15. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/NEWS +2 -2
  16. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/PORTING +0 -0
  17. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/README +2 -1
  18. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/TODO +0 -0
  19. data/ext/libusbx-1.0.17/Xcode/common.xcconfig +40 -0
  20. data/ext/libusbx-1.0.17/Xcode/config.h +28 -0
  21. data/ext/libusbx-1.0.17/Xcode/debug.xcconfig +29 -0
  22. data/ext/libusbx-1.0.17/Xcode/libusbx.xcconfig +21 -0
  23. data/ext/libusbx-1.0.17/Xcode/libusbx.xcodeproj/project.pbxproj +864 -0
  24. data/ext/libusbx-1.0.17/Xcode/libusbx_debug.xcconfig +21 -0
  25. data/ext/libusbx-1.0.17/Xcode/libusbx_release.xcconfig +21 -0
  26. data/ext/libusbx-1.0.17/Xcode/release.xcconfig +29 -0
  27. data/ext/libusbx-1.0.17/aclocal.m4 +1112 -0
  28. data/ext/libusbx-1.0.17/android/README +114 -0
  29. data/ext/libusbx-1.0.17/android/config.h +90 -0
  30. data/ext/libusbx-1.0.17/android/jni/Android.mk +23 -0
  31. data/ext/libusbx-1.0.17/android/jni/Application.mk +19 -0
  32. data/ext/libusbx-1.0.17/android/jni/examples.mk +134 -0
  33. data/ext/libusbx-1.0.17/android/jni/libusb.mk +54 -0
  34. data/ext/libusbx-1.0.17/android/jni/tests.mk +56 -0
  35. data/ext/libusbx-1.0.17/compile +347 -0
  36. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.guess +164 -130
  37. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.h.in +37 -1
  38. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.sub +174 -89
  39. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/configure +723 -302
  40. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/configure.ac +71 -20
  41. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/depcomp +345 -185
  42. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/Makefile.am +0 -0
  43. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/Makefile.in +95 -32
  44. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/doxygen.cfg.in +1 -1
  45. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/Makefile.am +5 -4
  46. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/Makefile.in +208 -104
  47. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/dpfp.c +1 -1
  48. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/dpfp_threaded.c +1 -1
  49. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/ezusb.c +188 -8
  50. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/ezusb.h +18 -5
  51. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/fxload.c +90 -64
  52. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt.c +0 -0
  53. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt.h +0 -0
  54. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt1.c +0 -0
  55. data/ext/libusbx-1.0.17/examples/hotplugtest.c +97 -0
  56. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/listdevs.c +12 -4
  57. data/ext/libusbx-1.0.17/examples/sam3u_benchmark.c +193 -0
  58. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/xusb.c +106 -49
  59. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/install-sh +21 -14
  60. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb-1.0.pc.in +1 -1
  61. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/Makefile.am +29 -10
  62. data/ext/libusbx-1.0.17/libusb/Makefile.in +914 -0
  63. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/core.c +378 -87
  64. data/ext/libusbx-1.0.17/libusb/descriptor.c +1199 -0
  65. data/ext/libusbx-1.0.17/libusb/hotplug.c +322 -0
  66. data/ext/libusbx-1.0.17/libusb/hotplug.h +82 -0
  67. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/io.c +182 -62
  68. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb-1.0.def +32 -0
  69. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb-1.0.rc +2 -0
  70. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb.h +481 -32
  71. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusbi.h +135 -38
  72. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/darwin_usb.c +591 -496
  73. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/darwin_usb.h +39 -46
  74. data/ext/libusbx-1.0.17/libusb/os/linux_netlink.c +345 -0
  75. data/ext/libusbx-1.0.17/libusb/os/linux_udev.c +306 -0
  76. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/linux_usbfs.c +653 -617
  77. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/linux_usbfs.h +32 -0
  78. data/ext/{libusbx-1.0.14/libusb/os/openbsd_usb.c → libusbx-1.0.17/libusb/os/netbsd_usb.c} +70 -63
  79. data/ext/libusbx-1.0.17/libusb/os/openbsd_usb.c +823 -0
  80. data/ext/libusbx-1.0.17/libusb/os/poll_posix.c +51 -0
  81. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_posix.h +2 -1
  82. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_windows.c +85 -106
  83. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_windows.h +14 -3
  84. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_posix.c +3 -1
  85. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_posix.h +0 -0
  86. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_windows.c +6 -5
  87. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_windows.h +0 -0
  88. data/ext/libusbx-1.0.17/libusb/os/wince_usb.c +1026 -0
  89. data/ext/libusbx-1.0.17/libusb/os/wince_usb.h +131 -0
  90. data/ext/libusbx-1.0.17/libusb/os/windows_common.h +108 -0
  91. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/windows_usb.c +92 -57
  92. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/windows_usb.h +2 -63
  93. data/ext/libusbx-1.0.17/libusb/strerror.c +184 -0
  94. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/sync.c +24 -38
  95. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/version.h +1 -1
  96. data/ext/libusbx-1.0.17/libusb/version_nano.h +1 -0
  97. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/ltmain.sh +60 -41
  98. data/ext/{libusbx-1.0.14/aclocal.m4 → libusbx-1.0.17/m4/libtool.m4} +229 -1723
  99. data/ext/libusbx-1.0.17/m4/ltoptions.m4 +384 -0
  100. data/ext/libusbx-1.0.17/m4/ltsugar.m4 +123 -0
  101. data/ext/libusbx-1.0.17/m4/ltversion.m4 +23 -0
  102. data/ext/libusbx-1.0.17/m4/lt~obsolete.m4 +98 -0
  103. data/ext/libusbx-1.0.17/missing +215 -0
  104. data/ext/libusbx-1.0.17/tests/Makefile.am +6 -0
  105. data/ext/libusbx-1.0.17/tests/Makefile.in +583 -0
  106. data/ext/libusbx-1.0.17/tests/libusbx_testlib.h +107 -0
  107. data/ext/libusbx-1.0.17/tests/stress.c +160 -0
  108. data/ext/libusbx-1.0.17/tests/testlib.c +276 -0
  109. data/lib/libusb.rb +4 -0
  110. data/lib/libusb/call.rb +43 -1
  111. data/lib/libusb/constants.rb +5 -0
  112. data/lib/libusb/context.rb +100 -0
  113. data/lib/libusb/dev_handle.rb +27 -0
  114. data/lib/libusb/device.rb +10 -4
  115. data/lib/libusb/version_gem.rb +1 -1
  116. data/test/test_libusb_capability.rb +2 -2
  117. data/test/test_libusb_compat.rb +2 -2
  118. data/test/test_libusb_compat_mass_storage.rb +2 -2
  119. data/test/test_libusb_descriptors.rb +4 -2
  120. data/test/test_libusb_event_machine.rb +2 -2
  121. data/test/test_libusb_gc.rb +2 -2
  122. data/test/test_libusb_hotplug.rb +115 -0
  123. data/test/test_libusb_iso_transfer.rb +3 -3
  124. data/test/test_libusb_mass_storage.rb +6 -16
  125. data/test/test_libusb_mass_storage2.rb +26 -3
  126. data/test/test_libusb_structs.rb +2 -2
  127. data/test/test_libusb_threads.rb +2 -2
  128. data/test/test_libusb_version.rb +2 -2
  129. metadata +127 -68
  130. metadata.gz.sig +0 -0
  131. data/ext/libusbx-1.0.14/THANKS +0 -7
  132. data/ext/libusbx-1.0.14/compile +0 -143
  133. data/ext/libusbx-1.0.14/libusb/Makefile.in +0 -721
  134. data/ext/libusbx-1.0.14/libusb/descriptor.c +0 -731
  135. data/ext/libusbx-1.0.14/libusb/version_nano.h +0 -1
  136. data/ext/libusbx-1.0.14/missing +0 -376
@@ -27,7 +27,7 @@
27
27
  #include <stdio.h>
28
28
  #include <stdlib.h>
29
29
 
30
- #include <libusb.h>
30
+ #include "libusb.h"
31
31
 
32
32
  #define EP_INTR (1 | LIBUSB_ENDPOINT_IN)
33
33
  #define EP_DATA (2 | LIBUSB_ENDPOINT_IN)
@@ -28,7 +28,7 @@
28
28
  #include <stdio.h>
29
29
  #include <stdlib.h>
30
30
 
31
- #include <libusb.h>
31
+ #include "libusb.h"
32
32
 
33
33
  #define EP_INTR (1 | LIBUSB_ENDPOINT_IN)
34
34
  #define EP_DATA (2 | LIBUSB_ENDPOINT_IN)
@@ -3,6 +3,7 @@
3
3
  * Copyright © 2001-2002 David Brownell (dbrownell@users.sourceforge.net)
4
4
  * Copyright © 2008 Roger Williams (rawqux@users.sourceforge.net)
5
5
  * Copyright © 2012 Pete Batard (pete@akeo.ie)
6
+ * Copyright © 2013 Federico Manzan (f.manzan@gmail.com)
6
7
  *
7
8
  * This source code is free software; you can redistribute it
8
9
  * and/or modify it in source code form under the terms of the GNU
@@ -25,7 +26,7 @@
25
26
  #include <string.h>
26
27
  #include <stdint.h>
27
28
 
28
- #include <libusb.h>
29
+ #include "libusb.h"
29
30
  #include "ezusb.h"
30
31
 
31
32
  extern void logerror(const char *format, ...)
@@ -46,7 +47,7 @@ extern void logerror(const char *format, ...)
46
47
  * The Cypress FX parts are largely compatible with the Anchorhip ones.
47
48
  */
48
49
 
49
- int verbose;
50
+ int verbose = 1;
50
51
 
51
52
  /*
52
53
  * return true if [addr,addr+len] includes external RAM
@@ -126,7 +127,7 @@ static int ezusb_write(libusb_device_handle *device, const char *label,
126
127
  {
127
128
  int status;
128
129
 
129
- if (verbose)
130
+ if (verbose > 1)
130
131
  logerror("%s, addr 0x%08x len %4u (0x%04x)\n", label, addr, (unsigned)len, (unsigned)len);
131
132
  status = libusb_control_transfer(device,
132
133
  LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
@@ -141,6 +142,29 @@ static int ezusb_write(libusb_device_handle *device, const char *label,
141
142
  return (status < 0) ? -EIO : 0;
142
143
  }
143
144
 
145
+ /*
146
+ * Issues the specified vendor-specific read request.
147
+ */
148
+ static int ezusb_read(libusb_device_handle *device, const char *label,
149
+ uint8_t opcode, uint32_t addr, const unsigned char *data, size_t len)
150
+ {
151
+ int status;
152
+
153
+ if (verbose > 1)
154
+ logerror("%s, addr 0x%08x len %4u (0x%04x)\n", label, addr, (unsigned)len, (unsigned)len);
155
+ status = libusb_control_transfer(device,
156
+ LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
157
+ opcode, addr & 0xFFFF, addr >> 16,
158
+ (unsigned char*)data, (uint16_t)len, 1000);
159
+ if (status != len) {
160
+ if (status < 0)
161
+ logerror("%s: %s\n", label, libusb_error_name(status));
162
+ else
163
+ logerror("%s ==> %d\n", label, status);
164
+ }
165
+ return (status < 0) ? -EIO : 0;
166
+ }
167
+
144
168
  /*
145
169
  * Modifies the CPUCS register to stop or reset the CPU.
146
170
  * Returns false on error.
@@ -170,6 +194,33 @@ static bool ezusb_cpucs(libusb_device_handle *device, uint32_t addr, bool doRun)
170
194
  return true;
171
195
  }
172
196
 
197
+ /*
198
+ * Send an FX3 jumpt to address command
199
+ * Returns false on error.
200
+ */
201
+ static bool ezusb_fx3_jump(libusb_device_handle *device, uint32_t addr)
202
+ {
203
+ int status;
204
+
205
+ if (verbose)
206
+ logerror("transfer execution to Program Entry at 0x%08x\n", addr);
207
+ status = libusb_control_transfer(device,
208
+ LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
209
+ RW_INTERNAL, addr & 0xFFFF, addr >> 16,
210
+ NULL, 0, 1000);
211
+ /* We may get an I/O error from libusbx as the device disappears */
212
+ if ((status != 0) && (status != LIBUSB_ERROR_IO))
213
+ {
214
+ const char *mesg = "failed to send jump command";
215
+ if (status < 0)
216
+ logerror("%s: %s\n", mesg, libusb_error_name(status));
217
+ else
218
+ logerror("%s\n", mesg);
219
+ return false;
220
+ } else
221
+ return true;
222
+ }
223
+
173
224
  /*****************************************************************************/
174
225
 
175
226
  /*
@@ -248,7 +299,7 @@ static int parse_ihex(FILE *image, void *context,
248
299
  /* Read the target offset (address up to 64KB) */
249
300
  tmp = buf[7];
250
301
  buf[7] = 0;
251
- off = strtoul(buf+3, NULL, 16);
302
+ off = (int)strtoul(buf+3, NULL, 16);
252
303
  buf[7] = tmp;
253
304
 
254
305
  /* Initialize data_addr */
@@ -420,9 +471,9 @@ static int parse_iic(FILE *image, void *context,
420
471
  }
421
472
 
422
473
  /* the parse call will be selected according to the image type */
423
- int (*parse[IMG_TYPE_MAX])(FILE *image, void *context, bool (*is_external)(uint32_t addr, size_t len),
424
- int (*poke)(void *context, uint32_t addr, bool external, const unsigned char *data, size_t len))
425
- = { parse_ihex, parse_iic, parse_bin };
474
+ static int (*parse[IMG_TYPE_MAX])(FILE *image, void *context, bool (*is_external)(uint32_t addr, size_t len),
475
+ int (*poke)(void *context, uint32_t addr, bool external, const unsigned char *data, size_t len))
476
+ = { parse_ihex, parse_iic, parse_bin };
426
477
 
427
478
  /*****************************************************************************/
428
479
 
@@ -502,6 +553,132 @@ static int ram_poke(void *context, uint32_t addr, bool external,
502
553
  return rc;
503
554
  }
504
555
 
556
+ /*
557
+ * Load a Cypress Image file into target RAM.
558
+ * See http://www.cypress.com/?docID=41351 (AN76405 PDF) for more info.
559
+ */
560
+ static int fx3_load_ram(libusb_device_handle *device, const char *path)
561
+ {
562
+ uint32_t dCheckSum, dExpectedCheckSum, dAddress, i, dLen, dLength;
563
+ uint32_t* dImageBuf;
564
+ unsigned char *bBuf, hBuf[4], blBuf[4], rBuf[4096];
565
+ FILE *image;
566
+
567
+ image = fopen(path, "rb");
568
+ if (image == NULL) {
569
+ logerror("unable to open '%s' for input\n", path);
570
+ return -2;
571
+ } else if (verbose)
572
+ logerror("open firmware image %s for RAM upload\n", path);
573
+
574
+ // Read header
575
+ if (fread(hBuf, sizeof(char), sizeof(hBuf), image) != sizeof(hBuf)) {
576
+ logerror("could not read image header");
577
+ return -3;
578
+ }
579
+
580
+ // check "CY" signature byte and format
581
+ if ((hBuf[0] != 'C') || (hBuf[1] != 'Y')) {
582
+ logerror("image doesn't have a CYpress signature\n");
583
+ return -3;
584
+ }
585
+
586
+ // Check bImageType
587
+ switch(hBuf[3]) {
588
+ case 0xB0:
589
+ if (verbose)
590
+ logerror("normal FW binary %s image with checksum\n", (hBuf[2]&0x01)?"data":"executable");
591
+ break;
592
+ case 0xB1:
593
+ logerror("security binary image is not currently supported\n");
594
+ return -3;
595
+ case 0xB2:
596
+ logerror("VID:PID image is not currently supported\n");
597
+ return -3;
598
+ default:
599
+ logerror("invalid image type 0x%02X\n", hBuf[3]);
600
+ return -3;
601
+ }
602
+
603
+ // Read the bootloader version
604
+ if (verbose) {
605
+ if ((ezusb_read(device, "read bootloader version", RW_INTERNAL, 0xFFFF0020, blBuf, 4) < 0)) {
606
+ logerror("Could not read bootloader version\n");
607
+ return -8;
608
+ }
609
+ logerror("FX3 bootloader version: 0x%02X%02X%02X%02X\n", blBuf[3], blBuf[2], blBuf[1], blBuf[0]);
610
+ }
611
+
612
+ dCheckSum = 0;
613
+ if (verbose)
614
+ logerror("writing image...\n");
615
+ while (1) {
616
+ if ((fread(&dLength, sizeof(uint32_t), 1, image) != 1) || // read dLength
617
+ (fread(&dAddress, sizeof(uint32_t), 1, image) != 1)) { // read dAddress
618
+ logerror("could not read image");
619
+ return -3;
620
+ }
621
+ if (dLength == 0)
622
+ break; // done
623
+
624
+ dImageBuf = calloc(dLength, sizeof(uint32_t));
625
+ if (dImageBuf == NULL) {
626
+ logerror("could not allocate buffer for image chunk\n");
627
+ return -4;
628
+ }
629
+
630
+ // read sections
631
+ if (fread(dImageBuf, sizeof(uint32_t), dLength, image) != dLength) {
632
+ logerror("could not read image");
633
+ free(dImageBuf);
634
+ return -3;
635
+ }
636
+ for (i = 0; i < dLength; i++)
637
+ dCheckSum += dImageBuf[i];
638
+ dLength <<= 2; // convert to Byte length
639
+ bBuf = (unsigned char*) dImageBuf;
640
+
641
+ while (dLength > 0) {
642
+ dLen = 4096; // 4K max
643
+ if (dLen > dLength)
644
+ dLen = dLength;
645
+ if ((ezusb_write(device, "write firmware", RW_INTERNAL, dAddress, bBuf, dLen) < 0) ||
646
+ (ezusb_read(device, "read firmware", RW_INTERNAL, dAddress, rBuf, dLen) < 0)) {
647
+ logerror("R/W error\n");
648
+ free(dImageBuf);
649
+ return -5;
650
+ }
651
+ // Verify data: rBuf with bBuf
652
+ for (i = 0; i < dLen; i++) {
653
+ if (rBuf[i] != bBuf[i]) {
654
+ logerror("verify error");
655
+ free(dImageBuf);
656
+ return -6;
657
+ }
658
+ }
659
+
660
+ dLength -= dLen;
661
+ bBuf += dLen;
662
+ dAddress += dLen;
663
+ }
664
+ free(dImageBuf);
665
+ }
666
+
667
+ // read pre-computed checksum data
668
+ if ((fread(&dExpectedCheckSum, sizeof(uint32_t), 1, image) != 1) ||
669
+ (dCheckSum != dExpectedCheckSum)) {
670
+ logerror("checksum error\n");
671
+ return -7;
672
+ }
673
+
674
+ // transfer execution to Program Entry
675
+ if (!ezusb_fx3_jump(device, dAddress)) {
676
+ return -6;
677
+ }
678
+
679
+ return 0;
680
+ }
681
+
505
682
  /*
506
683
  * Load a firmware file into target RAM. device is the open libusbx
507
684
  * device, and the path is the name of the source file. Open the file,
@@ -525,11 +702,14 @@ int ezusb_load_ram(libusb_device_handle *device, const char *path, int fx_type,
525
702
  int status;
526
703
  uint8_t iic_header[8] = { 0 };
527
704
 
705
+ if (fx_type == FX_TYPE_FX3)
706
+ return fx3_load_ram(device, path);
707
+
528
708
  image = fopen(path, "rb");
529
709
  if (image == NULL) {
530
710
  logerror("%s: unable to open for input.\n", path);
531
711
  return -2;
532
- } else if (verbose)
712
+ } else if (verbose > 1)
533
713
  logerror("open firmware image %s for RAM upload\n", path);
534
714
 
535
715
  if (img_type == IMG_TYPE_IIC) {
@@ -3,6 +3,7 @@
3
3
  /*
4
4
  * Copyright © 2001 Stephen Williams (steve@icarus.com)
5
5
  * Copyright © 2002 David Brownell (dbrownell@users.sourceforge.net)
6
+ * Copyright © 2013 Federico Manzan (f.manzan@gmail.com)
6
7
  *
7
8
  * This source code is free software; you can redistribute it
8
9
  * and/or modify it in source code form under the terms of the GNU
@@ -42,15 +43,21 @@
42
43
  #define FX_TYPE_FX1 1 /* Updated Cypress versions */
43
44
  #define FX_TYPE_FX2 2 /* USB 2.0 versions */
44
45
  #define FX_TYPE_FX2LP 3 /* Updated FX2 */
45
- #define FX_TYPE_MAX 4
46
- #define FX_TYPE_NAMES { "an21", "fx", "fx2", "fx2lp" }
46
+ #define FX_TYPE_FX3 4 /* USB 3.0 versions */
47
+ #define FX_TYPE_MAX 5
48
+ #define FX_TYPE_NAMES { "an21", "fx", "fx2", "fx2lp", "fx3" }
47
49
 
48
50
  #define IMG_TYPE_UNDEFINED -1
49
51
  #define IMG_TYPE_HEX 0 /* Intel HEX */
50
52
  #define IMG_TYPE_IIC 1 /* Cypress 8051 IIC */
51
53
  #define IMG_TYPE_BIX 2 /* Cypress 8051 BIX */
52
- #define IMG_TYPE_MAX 3
53
- #define IMG_TYPE_NAMES { "Intel HEX", "Cypress 8051 IIC", "Cypress 8051 BIX" }
54
+ #define IMG_TYPE_IMG 3 /* Cypress IMG format */
55
+ #define IMG_TYPE_MAX 4
56
+ #define IMG_TYPE_NAMES { "Intel HEX", "Cypress 8051 IIC", "Cypress 8051 BIX", "Cypress IMG format" }
57
+
58
+ #ifdef __cplusplus
59
+ extern "C" {
60
+ #endif
54
61
 
55
62
  /*
56
63
  * Automatically identified devices (VID, PID, type, designation).
@@ -75,6 +82,7 @@ typedef struct {
75
82
  { 0x0547, 0x2236, FX_TYPE_AN21, "Cypress EZ-USB (2236)" },\
76
83
  { 0x04b4, 0x6473, FX_TYPE_FX1, "Cypress EZ-USB FX1" },\
77
84
  { 0x04b4, 0x8613, FX_TYPE_FX2LP, "Cypress EZ-USB FX2LP (68013A/68014A/68015A/68016A)" }, \
85
+ { 0x04b4, 0x00f3, FX_TYPE_FX3, "Cypress FX3" },\
78
86
  }
79
87
 
80
88
  /*
@@ -102,6 +110,11 @@ extern int ezusb_load_ram(libusb_device_handle *device,
102
110
  extern int ezusb_load_eeprom(libusb_device_handle *device,
103
111
  const char *path, int fx_type, int img_type, int config);
104
112
 
105
- /* boolean flag, says whether to write extra messages to stderr */
113
+ /* Verbosity level (default 1). Can be increased or decreased with options v/q */
106
114
  extern int verbose;
115
+
116
+ #ifdef __cplusplus
117
+ }
118
+ #endif
119
+
107
120
  #endif
@@ -3,6 +3,7 @@
3
3
  * Copyright © 2001-2002 David Brownell (dbrownell@users.sourceforge.net)
4
4
  * Copyright © 2008 Roger Williams (rawqux@users.sourceforge.net)
5
5
  * Copyright © 2012 Pete Batard (pete@akeo.ie)
6
+ * Copyright © 2013 Federico Manzan (f.manzan@gmail.com)
6
7
  *
7
8
  * This source code is free software; you can redistribute it
8
9
  * and/or modify it in source code form under the terms of the GNU
@@ -20,16 +21,6 @@
20
21
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21
22
  */
22
23
 
23
- /*
24
- * This program supports uploading firmware into a target USB device.
25
- *
26
- * -I <path> -- Upload this firmware
27
- * -t <type> -- uController type: an21, fx, fx2, fx2lp
28
- *
29
- * -D <vid:pid> -- Use this device, instead of $DEVICE
30
- *
31
- * -V -- Print version ID for program
32
- */
33
24
  #include <stdlib.h>
34
25
  #include <stdio.h>
35
26
  #include <string.h>
@@ -38,7 +29,7 @@
38
29
  #include <sys/types.h>
39
30
  #include <getopt.h>
40
31
 
41
- #include <libusb.h>
32
+ #include "libusb.h"
42
33
  #include "ezusb.h"
43
34
 
44
35
  #if !defined(_WIN32) || defined(__CYGWIN__ )
@@ -49,7 +40,7 @@ static bool dosyslog = false;
49
40
  #endif
50
41
 
51
42
  #ifndef FXLOAD_VERSION
52
- #define FXLOAD_VERSION (__DATE__ " (development)")
43
+ #define FXLOAD_VERSION (__DATE__ " (libusbx)")
53
44
  #endif
54
45
 
55
46
  #ifndef ARRAYSIZE
@@ -73,30 +64,57 @@ void logerror(const char *format, ...)
73
64
  va_end(ap);
74
65
  }
75
66
 
67
+ static int print_usage(int error_code) {
68
+ fprintf(stderr, "\nUsage: fxload [-v] [-V] [-t type] [-d vid:pid] [-p bus,addr] -i firmware\n");
69
+ fprintf(stderr, " -i <path> -- Firmware to upload\n");
70
+ fprintf(stderr, " -t <type> -- Target type: an21, fx, fx2, fx2lp, fx3\n");
71
+ fprintf(stderr, " -d <vid:pid> -- Target device, as an USB VID:PID\n");
72
+ fprintf(stderr, " -p <bus,addr> -- Target device, as a libusbx bus number and device address path\n");
73
+ fprintf(stderr, " -v -- Increase verbosity\n");
74
+ fprintf(stderr, " -q -- Decrease verbosity (silent mode)\n");
75
+ fprintf(stderr, " -V -- Print program version\n");
76
+ return error_code;
77
+ }
78
+
76
79
  #define FIRMWARE 0
77
80
  #define LOADER 1
78
81
  int main(int argc, char*argv[])
79
82
  {
80
83
  fx_known_device known_device[] = FX_KNOWN_DEVICES;
81
84
  const char *path[] = { NULL, NULL };
82
- const char *device_id = getenv("DEVICE");
85
+ const char *device_id = NULL;
86
+ const char *device_path = getenv("DEVICE");
83
87
  const char *type = NULL;
84
88
  const char *fx_name[FX_TYPE_MAX] = FX_TYPE_NAMES;
85
89
  const char *ext, *img_name[] = IMG_TYPE_NAMES;
86
90
  int fx_type = FX_TYPE_UNDEFINED, img_type[ARRAYSIZE(path)];
87
91
  int i, j, opt, status;
88
92
  unsigned vid = 0, pid = 0;
93
+ unsigned busnum = 0, devaddr = 0, _busnum, _devaddr;
89
94
  libusb_device *dev, **devs;
90
95
  libusb_device_handle *device = NULL;
91
96
  struct libusb_device_descriptor desc;
92
97
 
93
- while ((opt = getopt(argc, argv, "vV?D:I:c:s:t:")) != EOF)
98
+ while ((opt = getopt(argc, argv, "qvV?hd:p:i:I:t:")) != EOF)
94
99
  switch (opt) {
95
100
 
96
- case 'D':
101
+ case 'd':
97
102
  device_id = optarg;
103
+ if (sscanf(device_id, "%x:%x" , &vid, &pid) != 2 ) {
104
+ fputs ("please specify VID & PID as \"vid:pid\" in hexadecimal format\n", stderr);
105
+ return -1;
106
+ }
107
+ break;
108
+
109
+ case 'p':
110
+ device_path = optarg;
111
+ if (sscanf(device_path, "%u,%u", &busnum, &devaddr) != 2 ) {
112
+ fputs ("please specify bus number & device number as \"bus,dev\" in decimal format\n", stderr);
113
+ return -1;
114
+ }
98
115
  break;
99
116
 
117
+ case 'i':
100
118
  case 'I':
101
119
  path[FIRMWARE] = optarg;
102
120
  break;
@@ -113,23 +131,24 @@ int main(int argc, char*argv[])
113
131
  verbose++;
114
132
  break;
115
133
 
134
+ case 'q':
135
+ verbose--;
136
+ break;
137
+
116
138
  case '?':
139
+ case 'h':
117
140
  default:
118
- goto usage;
141
+ return print_usage(-1);
119
142
 
120
143
  }
121
144
 
122
145
  if (path[FIRMWARE] == NULL) {
123
146
  logerror("no firmware specified!\n");
124
- usage:
125
- fprintf(stderr, "\nusage: %s [-vV] [-t type] [-D vid:pid] -I firmware\n", argv[0]);
126
- fprintf(stderr, " type: one of an21, fx, fx2, fx2lp\n");
127
- return -1;
147
+ return print_usage(-1);
128
148
  }
129
-
130
- if ((device_id != NULL) && (sscanf(device_id, "%x:%x" , &vid, &pid) != 2 )) {
131
- fputs ("please specify VID & PID as \"vid:pid\" in hexadecimal format\n", stderr);
132
- return -1;
149
+ if ((device_id != NULL) && (device_path != NULL)) {
150
+ logerror("only one of -d or -a can be specified\n");
151
+ return print_usage(-1);
133
152
  }
134
153
 
135
154
  /* determine the target type */
@@ -142,7 +161,7 @@ usage:
142
161
  }
143
162
  if (i >= FX_TYPE_MAX) {
144
163
  logerror("illegal microcontroller type: %s\n", type);
145
- goto usage;
164
+ return print_usage(-1);
146
165
  }
147
166
  }
148
167
 
@@ -155,48 +174,58 @@ usage:
155
174
  libusb_set_debug(NULL, verbose);
156
175
 
157
176
  /* try to pick up missing parameters from known devices */
158
- if ((type == NULL) || (device_id == NULL)) {
177
+ if ((type == NULL) || (device_id == NULL) || (device_path != NULL)) {
159
178
  if (libusb_get_device_list(NULL, &devs) < 0) {
160
179
  logerror("libusb_get_device_list() failed: %s\n", libusb_error_name(status));
161
180
  goto err;
162
181
  }
163
182
  for (i=0; (dev=devs[i]) != NULL; i++) {
164
- status = libusb_get_device_descriptor(dev, &desc);
165
- if (status >= 0) {
166
- if (verbose >= 2)
167
- logerror("trying to match against %04x:%04x\n", desc.idVendor, desc.idProduct);
168
- for (j=0; j<ARRAYSIZE(known_device); j++) {
169
- if ((desc.idVendor == known_device[j].vid)
170
- && (desc.idProduct == known_device[j].pid)) {
171
- if ((type == NULL) && (device_id == NULL)) {
172
- fx_type = known_device[j].type;
173
- vid = desc.idVendor;
174
- pid = desc.idProduct;
175
- break;
176
- } else if ((type == NULL) && (vid == desc.idVendor)
177
- && (pid == desc.idProduct)) {
178
- fx_type = known_device[j].type;
179
- break;
180
- } else if ((device_id == NULL)
181
- && (fx_type == known_device[j].type)) {
182
- vid = desc.idVendor;
183
- pid = desc.idProduct;
184
- break;
183
+ _busnum = libusb_get_bus_number(dev);
184
+ _devaddr = libusb_get_device_address(dev);
185
+ if ((type != NULL) && (device_path != NULL)) {
186
+ // if both a type and bus,addr were specified, we just need to find our match
187
+ if ((libusb_get_bus_number(dev) == busnum) && (libusb_get_device_address(dev) == devaddr))
188
+ break;
189
+ } else {
190
+ status = libusb_get_device_descriptor(dev, &desc);
191
+ if (status >= 0) {
192
+ if (verbose >= 3) {
193
+ logerror("examining %04x:%04x (%d,%d)\n",
194
+ desc.idVendor, desc.idProduct, _busnum, _devaddr);
195
+ }
196
+ for (j=0; j<ARRAYSIZE(known_device); j++) {
197
+ if ((desc.idVendor == known_device[j].vid)
198
+ && (desc.idProduct == known_device[j].pid)) {
199
+ if (// nothing was specified
200
+ ((type == NULL) && (device_id == NULL) && (device_path == NULL)) ||
201
+ // vid:pid was specified and we have a match
202
+ ((type == NULL) && (device_id != NULL) && (vid == desc.idVendor) && (pid == desc.idProduct)) ||
203
+ // bus,addr was specified and we have a match
204
+ ((type == NULL) && (device_path != NULL) && (busnum == _busnum) && (devaddr == _devaddr)) ||
205
+ // type was specified and we have a match
206
+ ((type != NULL) && (device_id == NULL) && (device_path == NULL) && (fx_type == known_device[j].type)) ) {
207
+ fx_type = known_device[j].type;
208
+ vid = desc.idVendor;
209
+ pid = desc.idProduct;
210
+ busnum = _busnum;
211
+ devaddr = _devaddr;
212
+ break;
213
+ }
185
214
  }
186
215
  }
187
- }
188
- if (j < ARRAYSIZE(known_device)) {
189
- if (verbose)
190
- logerror("found device '%s' [%04x:%04x]\n",
191
- known_device[j].designation, vid, pid);
192
- break;
216
+ if (j < ARRAYSIZE(known_device)) {
217
+ if (verbose)
218
+ logerror("found device '%s' [%04x:%04x] (%d,%d)\n",
219
+ known_device[j].designation, vid, pid, busnum, devaddr);
220
+ break;
221
+ }
193
222
  }
194
223
  }
195
224
  }
196
225
  if (dev == NULL) {
197
226
  libusb_free_device_list(devs, 1);
198
- logerror("could not find a known device - please specify type and/or vid:pid\n");
199
- goto usage;
227
+ logerror("could not find a known device - please specify type and/or vid:pid and/or bus,dev\n");
228
+ return print_usage(-1);
200
229
  }
201
230
  status = libusb_open(dev, &device);
202
231
  if (status < 0) {
@@ -204,22 +233,17 @@ usage:
204
233
  goto err;
205
234
  }
206
235
  libusb_free_device_list(devs, 1);
207
- } else {
236
+ } else if (device_id != NULL) {
208
237
  device = libusb_open_device_with_vid_pid(NULL, (uint16_t)vid, (uint16_t)pid);
209
238
  if (device == NULL) {
210
239
  logerror("libusb_open() failed\n");
211
240
  goto err;
212
241
  }
213
242
  }
243
+
214
244
  /* We need to claim the first interface */
245
+ libusb_set_auto_detach_kernel_driver(device, 1);
215
246
  status = libusb_claim_interface(device, 0);
216
- #if defined(__linux__)
217
- if (status != LIBUSB_SUCCESS) {
218
- /* Maybe we need to detach the driver */
219
- libusb_detach_kernel_driver(device, 0);
220
- status = libusb_claim_interface(device, 0);
221
- }
222
- #endif
223
247
  if (status != LIBUSB_SUCCESS) {
224
248
  logerror("libusb_claim_interface failed: %s\n", libusb_error_name(status));
225
249
  goto err;
@@ -237,6 +261,8 @@ usage:
237
261
  img_type[i] = IMG_TYPE_IIC;
238
262
  else if (_stricmp(ext, ".bix") == 0)
239
263
  img_type[i] = IMG_TYPE_BIX;
264
+ else if (_stricmp(ext, ".img") == 0)
265
+ img_type[i] = IMG_TYPE_IMG;
240
266
  else {
241
267
  logerror("%s is not a recognized image type\n", path[i]);
242
268
  goto err;
@@ -247,7 +273,7 @@ usage:
247
273
  }
248
274
 
249
275
  /* single stage, put into internal memory */
250
- if (verbose)
276
+ if (verbose > 1)
251
277
  logerror("single stage: load on-chip memory\n");
252
278
  status = ezusb_load_ram(device, path[FIRMWARE], fx_type, img_type[FIRMWARE], 0);
253
279