libusb 0.5.1 → 0.6.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 (155) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +8 -2
  3. data/Gemfile +2 -0
  4. data/History.md +12 -0
  5. data/README.md +25 -14
  6. data/Rakefile +64 -109
  7. data/appveyor.yml +23 -0
  8. data/ext/extconf.rb +10 -12
  9. data/ext/libusb_recipe.rb +29 -0
  10. data/lib/libusb/call.rb +14 -11
  11. data/lib/libusb/compat.rb +9 -9
  12. data/lib/libusb/context.rb +16 -1
  13. data/lib/libusb/dependencies.rb +7 -0
  14. data/lib/libusb/dev_handle.rb +13 -3
  15. data/lib/libusb/eventmachine.rb +4 -4
  16. data/lib/libusb/transfer.rb +71 -10
  17. data/lib/libusb/version_gem.rb +1 -1
  18. data/libusb.gemspec +7 -5
  19. data/ports/archives/libusb-1.0.21.tar.bz2 +0 -0
  20. data/test/test_libusb_bulk_stream_transfer.rb +1 -1
  21. data/test/test_libusb_descriptors.rb +4 -4
  22. data/test/test_libusb_event_machine.rb +7 -7
  23. data/test/test_libusb_hotplug.rb +15 -3
  24. data/test/test_libusb_iso_transfer.rb +1 -1
  25. data/test/test_libusb_mass_storage.rb +19 -19
  26. data/test/test_libusb_mass_storage2.rb +1 -1
  27. data/test/test_libusb_structs.rb +13 -0
  28. data/test/test_libusb_threads.rb +2 -2
  29. data/wireshark-usb-sniffer.png +0 -0
  30. metadata +32 -156
  31. checksums.yaml.gz.sig +0 -0
  32. data.tar.gz.sig +0 -0
  33. data/ext/libusb-1.0.20/AUTHORS +0 -89
  34. data/ext/libusb-1.0.20/COPYING +0 -504
  35. data/ext/libusb-1.0.20/ChangeLog +0 -227
  36. data/ext/libusb-1.0.20/INSTALL +0 -234
  37. data/ext/libusb-1.0.20/Makefile.am +0 -28
  38. data/ext/libusb-1.0.20/Makefile.in +0 -897
  39. data/ext/libusb-1.0.20/NEWS +0 -2
  40. data/ext/libusb-1.0.20/PORTING +0 -94
  41. data/ext/libusb-1.0.20/README +0 -29
  42. data/ext/libusb-1.0.20/TODO +0 -2
  43. data/ext/libusb-1.0.20/Xcode/common.xcconfig +0 -49
  44. data/ext/libusb-1.0.20/Xcode/config.h +0 -28
  45. data/ext/libusb-1.0.20/Xcode/debug.xcconfig +0 -29
  46. data/ext/libusb-1.0.20/Xcode/libusb.xcconfig +0 -21
  47. data/ext/libusb-1.0.20/Xcode/libusb.xcodeproj/project.pbxproj +0 -865
  48. data/ext/libusb-1.0.20/Xcode/libusb_debug.xcconfig +0 -21
  49. data/ext/libusb-1.0.20/Xcode/libusb_release.xcconfig +0 -21
  50. data/ext/libusb-1.0.20/Xcode/release.xcconfig +0 -30
  51. data/ext/libusb-1.0.20/aclocal.m4 +0 -1193
  52. data/ext/libusb-1.0.20/android/README +0 -114
  53. data/ext/libusb-1.0.20/android/config.h +0 -81
  54. data/ext/libusb-1.0.20/android/jni/Android.mk +0 -23
  55. data/ext/libusb-1.0.20/android/jni/Application.mk +0 -24
  56. data/ext/libusb-1.0.20/android/jni/examples.mk +0 -134
  57. data/ext/libusb-1.0.20/android/jni/libusb.mk +0 -54
  58. data/ext/libusb-1.0.20/android/jni/tests.mk +0 -56
  59. data/ext/libusb-1.0.20/compile +0 -347
  60. data/ext/libusb-1.0.20/config.guess +0 -1421
  61. data/ext/libusb-1.0.20/config.h.in +0 -155
  62. data/ext/libusb-1.0.20/config.sub +0 -1807
  63. data/ext/libusb-1.0.20/configure +0 -15466
  64. data/ext/libusb-1.0.20/configure.ac +0 -326
  65. data/ext/libusb-1.0.20/depcomp +0 -791
  66. data/ext/libusb-1.0.20/doc/Makefile.am +0 -9
  67. data/ext/libusb-1.0.20/doc/Makefile.in +0 -456
  68. data/ext/libusb-1.0.20/doc/doxygen.cfg.in +0 -2334
  69. data/ext/libusb-1.0.20/examples/Makefile.am +0 -19
  70. data/ext/libusb-1.0.20/examples/Makefile.in +0 -713
  71. data/ext/libusb-1.0.20/examples/dpfp.c +0 -506
  72. data/ext/libusb-1.0.20/examples/dpfp_threaded.c +0 -549
  73. data/ext/libusb-1.0.20/examples/ezusb.c +0 -831
  74. data/ext/libusb-1.0.20/examples/ezusb.h +0 -120
  75. data/ext/libusb-1.0.20/examples/fxload.c +0 -308
  76. data/ext/libusb-1.0.20/examples/getopt/getopt.c +0 -1060
  77. data/ext/libusb-1.0.20/examples/getopt/getopt.h +0 -180
  78. data/ext/libusb-1.0.20/examples/getopt/getopt1.c +0 -188
  79. data/ext/libusb-1.0.20/examples/hotplugtest.c +0 -122
  80. data/ext/libusb-1.0.20/examples/listdevs.c +0 -71
  81. data/ext/libusb-1.0.20/examples/sam3u_benchmark.c +0 -193
  82. data/ext/libusb-1.0.20/examples/xusb.c +0 -1130
  83. data/ext/libusb-1.0.20/install-sh +0 -501
  84. data/ext/libusb-1.0.20/libusb-1.0.pc.in +0 -11
  85. data/ext/libusb-1.0.20/libusb/Makefile.am +0 -90
  86. data/ext/libusb-1.0.20/libusb/Makefile.in +0 -1053
  87. data/ext/libusb-1.0.20/libusb/core.c +0 -2452
  88. data/ext/libusb-1.0.20/libusb/descriptor.c +0 -1201
  89. data/ext/libusb-1.0.20/libusb/hotplug.c +0 -344
  90. data/ext/libusb-1.0.20/libusb/hotplug.h +0 -90
  91. data/ext/libusb-1.0.20/libusb/io.c +0 -2760
  92. data/ext/libusb-1.0.20/libusb/libusb-1.0.def +0 -168
  93. data/ext/libusb-1.0.20/libusb/libusb-1.0.rc +0 -61
  94. data/ext/libusb-1.0.20/libusb/libusb.h +0 -1999
  95. data/ext/libusb-1.0.20/libusb/libusbi.h +0 -1102
  96. data/ext/libusb-1.0.20/libusb/os/darwin_usb.c +0 -1969
  97. data/ext/libusb-1.0.20/libusb/os/darwin_usb.h +0 -158
  98. data/ext/libusb-1.0.20/libusb/os/haiku/Makefile.am +0 -5
  99. data/ext/libusb-1.0.20/libusb/os/haiku/Makefile.in +0 -810
  100. data/ext/libusb-1.0.20/libusb/os/haiku/aclocal.m4 +0 -1193
  101. data/ext/libusb-1.0.20/libusb/os/haiku/compile +0 -347
  102. data/ext/libusb-1.0.20/libusb/os/haiku/config.guess +0 -1421
  103. data/ext/libusb-1.0.20/libusb/os/haiku/config.sub +0 -1807
  104. data/ext/libusb-1.0.20/libusb/os/haiku/configure +0 -17579
  105. data/ext/libusb-1.0.20/libusb/os/haiku/configure.ac +0 -8
  106. data/ext/libusb-1.0.20/libusb/os/haiku/depcomp +0 -791
  107. data/ext/libusb-1.0.20/libusb/os/haiku/haiku_pollfs.cpp +0 -378
  108. data/ext/libusb-1.0.20/libusb/os/haiku/haiku_usb.h +0 -112
  109. data/ext/libusb-1.0.20/libusb/os/haiku/haiku_usb_backend.cpp +0 -550
  110. data/ext/libusb-1.0.20/libusb/os/haiku/haiku_usb_raw.cpp +0 -255
  111. data/ext/libusb-1.0.20/libusb/os/haiku/haiku_usb_raw.h +0 -180
  112. data/ext/libusb-1.0.20/libusb/os/haiku/install-sh +0 -501
  113. data/ext/libusb-1.0.20/libusb/os/haiku/ltmain.sh +0 -9655
  114. data/ext/libusb-1.0.20/libusb/os/haiku/m4/libtool.m4 +0 -7992
  115. data/ext/libusb-1.0.20/libusb/os/haiku/m4/ltoptions.m4 +0 -384
  116. data/ext/libusb-1.0.20/libusb/os/haiku/m4/ltsugar.m4 +0 -123
  117. data/ext/libusb-1.0.20/libusb/os/haiku/m4/ltversion.m4 +0 -23
  118. data/ext/libusb-1.0.20/libusb/os/haiku/m4/lt~obsolete.m4 +0 -98
  119. data/ext/libusb-1.0.20/libusb/os/haiku/missing +0 -215
  120. data/ext/libusb-1.0.20/libusb/os/linux_netlink.c +0 -369
  121. data/ext/libusb-1.0.20/libusb/os/linux_udev.c +0 -306
  122. data/ext/libusb-1.0.20/libusb/os/linux_usbfs.c +0 -2692
  123. data/ext/libusb-1.0.20/libusb/os/linux_usbfs.h +0 -192
  124. data/ext/libusb-1.0.20/libusb/os/netbsd_usb.c +0 -674
  125. data/ext/libusb-1.0.20/libusb/os/openbsd_usb.c +0 -768
  126. data/ext/libusb-1.0.20/libusb/os/poll_posix.c +0 -53
  127. data/ext/libusb-1.0.20/libusb/os/poll_posix.h +0 -11
  128. data/ext/libusb-1.0.20/libusb/os/poll_windows.c +0 -728
  129. data/ext/libusb-1.0.20/libusb/os/poll_windows.h +0 -131
  130. data/ext/libusb-1.0.20/libusb/os/threads_posix.c +0 -82
  131. data/ext/libusb-1.0.20/libusb/os/threads_posix.h +0 -50
  132. data/ext/libusb-1.0.20/libusb/os/threads_windows.c +0 -214
  133. data/ext/libusb-1.0.20/libusb/os/threads_windows.h +0 -87
  134. data/ext/libusb-1.0.20/libusb/os/wince_usb.c +0 -869
  135. data/ext/libusb-1.0.20/libusb/os/wince_usb.h +0 -131
  136. data/ext/libusb-1.0.20/libusb/os/windows_common.h +0 -108
  137. data/ext/libusb-1.0.20/libusb/os/windows_usb.c +0 -4643
  138. data/ext/libusb-1.0.20/libusb/os/windows_usb.h +0 -973
  139. data/ext/libusb-1.0.20/libusb/strerror.c +0 -202
  140. data/ext/libusb-1.0.20/libusb/sync.c +0 -308
  141. data/ext/libusb-1.0.20/libusb/version.h +0 -18
  142. data/ext/libusb-1.0.20/libusb/version_nano.h +0 -1
  143. data/ext/libusb-1.0.20/ltmain.sh +0 -9655
  144. data/ext/libusb-1.0.20/m4/libtool.m4 +0 -7992
  145. data/ext/libusb-1.0.20/m4/ltoptions.m4 +0 -384
  146. data/ext/libusb-1.0.20/m4/ltsugar.m4 +0 -123
  147. data/ext/libusb-1.0.20/m4/ltversion.m4 +0 -23
  148. data/ext/libusb-1.0.20/m4/lt~obsolete.m4 +0 -98
  149. data/ext/libusb-1.0.20/missing +0 -215
  150. data/ext/libusb-1.0.20/tests/Makefile.am +0 -6
  151. data/ext/libusb-1.0.20/tests/Makefile.in +0 -596
  152. data/ext/libusb-1.0.20/tests/libusb_testlib.h +0 -107
  153. data/ext/libusb-1.0.20/tests/stress.c +0 -160
  154. data/ext/libusb-1.0.20/tests/testlib.c +0 -277
  155. metadata.gz.sig +0 -0
@@ -1,831 +0,0 @@
1
- /*
2
- * Copyright © 2001 Stephen Williams (steve@icarus.com)
3
- * Copyright © 2001-2002 David Brownell (dbrownell@users.sourceforge.net)
4
- * Copyright © 2008 Roger Williams (rawqux@users.sourceforge.net)
5
- * Copyright © 2012 Pete Batard (pete@akeo.ie)
6
- * Copyright © 2013 Federico Manzan (f.manzan@gmail.com)
7
- *
8
- * This source code is free software; you can redistribute it
9
- * and/or modify it in source code form under the terms of the GNU
10
- * General Public License as published by the Free Software
11
- * Foundation; either version 2 of the License, or (at your option)
12
- * any later version.
13
- *
14
- * This program is distributed in the hope that it will be useful,
15
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
- * GNU General Public License for more details.
18
- *
19
- * You should have received a copy of the GNU General Public License
20
- * along with this program; if not, write to the Free Software
21
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
22
- */
23
- #include <stdio.h>
24
- #include <errno.h>
25
- #include <stdlib.h>
26
- #include <string.h>
27
- #include <stdint.h>
28
-
29
- #include "libusb.h"
30
- #include "ezusb.h"
31
-
32
- extern void logerror(const char *format, ...)
33
- __attribute__ ((format(printf, 1, 2)));
34
-
35
- /*
36
- * This file contains functions for uploading firmware into Cypress
37
- * EZ-USB microcontrollers. These chips use control endpoint 0 and vendor
38
- * specific commands to support writing into the on-chip SRAM. They also
39
- * support writing into the CPUCS register, which is how we reset the
40
- * processor after loading firmware (including the reset vector).
41
- *
42
- * These Cypress devices are 8-bit 8051 based microcontrollers with
43
- * special support for USB I/O. They come in several packages, and
44
- * some can be set up with external memory when device costs allow.
45
- * Note that the design was originally by AnchorChips, so you may find
46
- * references to that vendor (which was later merged into Cypress).
47
- * The Cypress FX parts are largely compatible with the Anchorhip ones.
48
- */
49
-
50
- int verbose = 1;
51
-
52
- /*
53
- * return true if [addr,addr+len] includes external RAM
54
- * for Anchorchips EZ-USB or Cypress EZ-USB FX
55
- */
56
- static bool fx_is_external(uint32_t addr, size_t len)
57
- {
58
- /* with 8KB RAM, 0x0000-0x1b3f can be written
59
- * we can't tell if it's a 4KB device here
60
- */
61
- if (addr <= 0x1b3f)
62
- return ((addr + len) > 0x1b40);
63
-
64
- /* there may be more RAM; unclear if we can write it.
65
- * some bulk buffers may be unused, 0x1b3f-0x1f3f
66
- * firmware can set ISODISAB for 2KB at 0x2000-0x27ff
67
- */
68
- return true;
69
- }
70
-
71
- /*
72
- * return true if [addr,addr+len] includes external RAM
73
- * for Cypress EZ-USB FX2
74
- */
75
- static bool fx2_is_external(uint32_t addr, size_t len)
76
- {
77
- /* 1st 8KB for data/code, 0x0000-0x1fff */
78
- if (addr <= 0x1fff)
79
- return ((addr + len) > 0x2000);
80
-
81
- /* and 512 for data, 0xe000-0xe1ff */
82
- else if (addr >= 0xe000 && addr <= 0xe1ff)
83
- return ((addr + len) > 0xe200);
84
-
85
- /* otherwise, it's certainly external */
86
- else
87
- return true;
88
- }
89
-
90
- /*
91
- * return true if [addr,addr+len] includes external RAM
92
- * for Cypress EZ-USB FX2LP
93
- */
94
- static bool fx2lp_is_external(uint32_t addr, size_t len)
95
- {
96
- /* 1st 16KB for data/code, 0x0000-0x3fff */
97
- if (addr <= 0x3fff)
98
- return ((addr + len) > 0x4000);
99
-
100
- /* and 512 for data, 0xe000-0xe1ff */
101
- else if (addr >= 0xe000 && addr <= 0xe1ff)
102
- return ((addr + len) > 0xe200);
103
-
104
- /* otherwise, it's certainly external */
105
- else
106
- return true;
107
- }
108
-
109
-
110
- /*****************************************************************************/
111
-
112
- /*
113
- * These are the requests (bRequest) that the bootstrap loader is expected
114
- * to recognize. The codes are reserved by Cypress, and these values match
115
- * what EZ-USB hardware, or "Vend_Ax" firmware (2nd stage loader) uses.
116
- * Cypress' "a3load" is nice because it supports both FX and FX2, although
117
- * it doesn't have the EEPROM support (subset of "Vend_Ax").
118
- */
119
- #define RW_INTERNAL 0xA0 /* hardware implements this one */
120
- #define RW_MEMORY 0xA3
121
-
122
- /*
123
- * Issues the specified vendor-specific write request.
124
- */
125
- static int ezusb_write(libusb_device_handle *device, const char *label,
126
- uint8_t opcode, uint32_t addr, const unsigned char *data, size_t len)
127
- {
128
- int status;
129
-
130
- if (verbose > 1)
131
- logerror("%s, addr 0x%08x len %4u (0x%04x)\n", label, addr, (unsigned)len, (unsigned)len);
132
- status = libusb_control_transfer(device,
133
- LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
134
- opcode, addr & 0xFFFF, addr >> 16,
135
- (unsigned char*)data, (uint16_t)len, 1000);
136
- if (status != len) {
137
- if (status < 0)
138
- logerror("%s: %s\n", label, libusb_error_name(status));
139
- else
140
- logerror("%s ==> %d\n", label, status);
141
- }
142
- return (status < 0) ? -EIO : 0;
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
-
168
- /*
169
- * Modifies the CPUCS register to stop or reset the CPU.
170
- * Returns false on error.
171
- */
172
- static bool ezusb_cpucs(libusb_device_handle *device, uint32_t addr, bool doRun)
173
- {
174
- int status;
175
- uint8_t data = doRun ? 0x00 : 0x01;
176
-
177
- if (verbose)
178
- logerror("%s\n", data ? "stop CPU" : "reset CPU");
179
- status = libusb_control_transfer(device,
180
- LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
181
- RW_INTERNAL, addr & 0xFFFF, addr >> 16,
182
- &data, 1, 1000);
183
- if ((status != 1) &&
184
- /* We may get an I/O error from libusb as the device disappears */
185
- ((!doRun) || (status != LIBUSB_ERROR_IO)))
186
- {
187
- const char *mesg = "can't modify CPUCS";
188
- if (status < 0)
189
- logerror("%s: %s\n", mesg, libusb_error_name(status));
190
- else
191
- logerror("%s\n", mesg);
192
- return false;
193
- } else
194
- return true;
195
- }
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 libusb 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
-
224
- /*****************************************************************************/
225
-
226
- /*
227
- * Parse an Intel HEX image file and invoke the poke() function on the
228
- * various segments to implement policies such as writing to RAM (with
229
- * a one or two stage loader setup, depending on the firmware) or to
230
- * EEPROM (two stages required).
231
- *
232
- * image - the hex image file
233
- * context - for use by poke()
234
- * is_external - if non-null, used to check which segments go into
235
- * external memory (writable only by software loader)
236
- * poke - called with each memory segment; errors indicated
237
- * by returning negative values.
238
- *
239
- * Caller is responsible for halting CPU as needed, such as when
240
- * overwriting a second stage loader.
241
- */
242
- static int parse_ihex(FILE *image, void *context,
243
- bool (*is_external)(uint32_t addr, size_t len),
244
- int (*poke) (void *context, uint32_t addr, bool external,
245
- const unsigned char *data, size_t len))
246
- {
247
- unsigned char data[1023];
248
- uint32_t data_addr = 0;
249
- size_t data_len = 0;
250
- int rc;
251
- int first_line = 1;
252
- bool external = false;
253
-
254
- /* Read the input file as an IHEX file, and report the memory segments
255
- * as we go. Each line holds a max of 16 bytes, but uploading is
256
- * faster (and EEPROM space smaller) if we merge those lines into larger
257
- * chunks. Most hex files keep memory segments together, which makes
258
- * such merging all but free. (But it may still be worth sorting the
259
- * hex files to make up for undesirable behavior from tools.)
260
- *
261
- * Note that EEPROM segments max out at 1023 bytes; the upload protocol
262
- * allows segments of up to 64 KBytes (more than a loader could handle).
263
- */
264
- for (;;) {
265
- char buf[512], *cp;
266
- char tmp, type;
267
- size_t len;
268
- unsigned idx, off;
269
-
270
- cp = fgets(buf, sizeof(buf), image);
271
- if (cp == NULL) {
272
- logerror("EOF without EOF record!\n");
273
- break;
274
- }
275
-
276
- /* EXTENSION: "# comment-till-end-of-line", for copyrights etc */
277
- if (buf[0] == '#')
278
- continue;
279
-
280
- if (buf[0] != ':') {
281
- logerror("not an ihex record: %s", buf);
282
- return -2;
283
- }
284
-
285
- /* ignore any newline */
286
- cp = strchr(buf, '\n');
287
- if (cp)
288
- *cp = 0;
289
-
290
- if (verbose >= 3)
291
- logerror("** LINE: %s\n", buf);
292
-
293
- /* Read the length field (up to 16 bytes) */
294
- tmp = buf[3];
295
- buf[3] = 0;
296
- len = strtoul(buf+1, NULL, 16);
297
- buf[3] = tmp;
298
-
299
- /* Read the target offset (address up to 64KB) */
300
- tmp = buf[7];
301
- buf[7] = 0;
302
- off = (int)strtoul(buf+3, NULL, 16);
303
- buf[7] = tmp;
304
-
305
- /* Initialize data_addr */
306
- if (first_line) {
307
- data_addr = off;
308
- first_line = 0;
309
- }
310
-
311
- /* Read the record type */
312
- tmp = buf[9];
313
- buf[9] = 0;
314
- type = (char)strtoul(buf+7, NULL, 16);
315
- buf[9] = tmp;
316
-
317
- /* If this is an EOF record, then make it so. */
318
- if (type == 1) {
319
- if (verbose >= 2)
320
- logerror("EOF on hexfile\n");
321
- break;
322
- }
323
-
324
- if (type != 0) {
325
- logerror("unsupported record type: %u\n", type);
326
- return -3;
327
- }
328
-
329
- if ((len * 2) + 11 > strlen(buf)) {
330
- logerror("record too short?\n");
331
- return -4;
332
- }
333
-
334
- /* FIXME check for _physically_ contiguous not just virtually
335
- * e.g. on FX2 0x1f00-0x2100 includes both on-chip and external
336
- * memory so it's not really contiguous */
337
-
338
- /* flush the saved data if it's not contiguous,
339
- * or when we've buffered as much as we can.
340
- */
341
- if (data_len != 0
342
- && (off != (data_addr + data_len)
343
- /* || !merge */
344
- || (data_len + len) > sizeof(data))) {
345
- if (is_external)
346
- external = is_external(data_addr, data_len);
347
- rc = poke(context, data_addr, external, data, data_len);
348
- if (rc < 0)
349
- return -1;
350
- data_addr = off;
351
- data_len = 0;
352
- }
353
-
354
- /* append to saved data, flush later */
355
- for (idx = 0, cp = buf+9 ; idx < len ; idx += 1, cp += 2) {
356
- tmp = cp[2];
357
- cp[2] = 0;
358
- data[data_len + idx] = (uint8_t)strtoul(cp, NULL, 16);
359
- cp[2] = tmp;
360
- }
361
- data_len += len;
362
- }
363
-
364
-
365
- /* flush any data remaining */
366
- if (data_len != 0) {
367
- if (is_external)
368
- external = is_external(data_addr, data_len);
369
- rc = poke(context, data_addr, external, data, data_len);
370
- if (rc < 0)
371
- return -1;
372
- }
373
- return 0;
374
- }
375
-
376
- /*
377
- * Parse a binary image file and write it as is to the target.
378
- * Applies to Cypress BIX images for RAM or Cypress IIC images
379
- * for EEPROM.
380
- *
381
- * image - the BIX image file
382
- * context - for use by poke()
383
- * is_external - if non-null, used to check which segments go into
384
- * external memory (writable only by software loader)
385
- * poke - called with each memory segment; errors indicated
386
- * by returning negative values.
387
- *
388
- * Caller is responsible for halting CPU as needed, such as when
389
- * overwriting a second stage loader.
390
- */
391
- static int parse_bin(FILE *image, void *context,
392
- bool (*is_external)(uint32_t addr, size_t len), int (*poke)(void *context,
393
- uint32_t addr, bool external, const unsigned char *data, size_t len))
394
- {
395
- unsigned char data[4096];
396
- uint32_t data_addr = 0;
397
- size_t data_len = 0;
398
- int rc;
399
- bool external = false;
400
-
401
- for (;;) {
402
- data_len = fread(data, 1, 4096, image);
403
- if (data_len == 0)
404
- break;
405
- if (is_external)
406
- external = is_external(data_addr, data_len);
407
- rc = poke(context, data_addr, external, data, data_len);
408
- if (rc < 0)
409
- return -1;
410
- data_addr += (uint32_t)data_len;
411
- }
412
- return feof(image)?0:-1;
413
- }
414
-
415
- /*
416
- * Parse a Cypress IIC image file and invoke the poke() function on the
417
- * various segments for writing to RAM
418
- *
419
- * image - the IIC image file
420
- * context - for use by poke()
421
- * is_external - if non-null, used to check which segments go into
422
- * external memory (writable only by software loader)
423
- * poke - called with each memory segment; errors indicated
424
- * by returning negative values.
425
- *
426
- * Caller is responsible for halting CPU as needed, such as when
427
- * overwriting a second stage loader.
428
- */
429
- static int parse_iic(FILE *image, void *context,
430
- bool (*is_external)(uint32_t addr, size_t len),
431
- int (*poke)(void *context, uint32_t addr, bool external, const unsigned char *data, size_t len))
432
- {
433
- unsigned char data[4096];
434
- uint32_t data_addr = 0;
435
- size_t data_len = 0, read_len;
436
- uint8_t block_header[4];
437
- int rc;
438
- bool external = false;
439
- long file_size, initial_pos;
440
-
441
- initial_pos = ftell(image);
442
- if (initial_pos < 0)
443
- return -1;
444
-
445
- if (fseek(image, 0L, SEEK_END) != 0)
446
- return -1;
447
- file_size = ftell(image);
448
- if (fseek(image, initial_pos, SEEK_SET) != 0)
449
- return -1;
450
- for (;;) {
451
- /* Ignore the trailing reset IIC data (5 bytes) */
452
- if (ftell(image) >= (file_size - 5))
453
- break;
454
- if (fread(&block_header, 1, sizeof(block_header), image) != 4) {
455
- logerror("unable to read IIC block header\n");
456
- return -1;
457
- }
458
- data_len = (block_header[0] << 8) + block_header[1];
459
- data_addr = (block_header[2] << 8) + block_header[3];
460
- if (data_len > sizeof(data)) {
461
- /* If this is ever reported as an error, switch to using malloc/realloc */
462
- logerror("IIC data block too small - please report this error to libusb.info\n");
463
- return -1;
464
- }
465
- read_len = fread(data, 1, data_len, image);
466
- if (read_len != data_len) {
467
- logerror("read error\n");
468
- return -1;
469
- }
470
- if (is_external)
471
- external = is_external(data_addr, data_len);
472
- rc = poke(context, data_addr, external, data, data_len);
473
- if (rc < 0)
474
- return -1;
475
- }
476
- return 0;
477
- }
478
-
479
- /* the parse call will be selected according to the image type */
480
- static int (*parse[IMG_TYPE_MAX])(FILE *image, void *context, bool (*is_external)(uint32_t addr, size_t len),
481
- int (*poke)(void *context, uint32_t addr, bool external, const unsigned char *data, size_t len))
482
- = { parse_ihex, parse_iic, parse_bin };
483
-
484
- /*****************************************************************************/
485
-
486
- /*
487
- * For writing to RAM using a first (hardware) or second (software)
488
- * stage loader and 0xA0 or 0xA3 vendor requests
489
- */
490
- typedef enum {
491
- _undef = 0,
492
- internal_only, /* hardware first-stage loader */
493
- skip_internal, /* first phase, second-stage loader */
494
- skip_external /* second phase, second-stage loader */
495
- } ram_mode;
496
-
497
- struct ram_poke_context {
498
- libusb_device_handle *device;
499
- ram_mode mode;
500
- size_t total, count;
501
- };
502
-
503
- #define RETRY_LIMIT 5
504
-
505
- static int ram_poke(void *context, uint32_t addr, bool external,
506
- const unsigned char *data, size_t len)
507
- {
508
- struct ram_poke_context *ctx = (struct ram_poke_context*)context;
509
- int rc;
510
- unsigned retry = 0;
511
-
512
- switch (ctx->mode) {
513
- case internal_only: /* CPU should be stopped */
514
- if (external) {
515
- logerror("can't write %u bytes external memory at 0x%08x\n",
516
- (unsigned)len, addr);
517
- return -EINVAL;
518
- }
519
- break;
520
- case skip_internal: /* CPU must be running */
521
- if (!external) {
522
- if (verbose >= 2) {
523
- logerror("SKIP on-chip RAM, %u bytes at 0x%08x\n",
524
- (unsigned)len, addr);
525
- }
526
- return 0;
527
- }
528
- break;
529
- case skip_external: /* CPU should be stopped */
530
- if (external) {
531
- if (verbose >= 2) {
532
- logerror("SKIP external RAM, %u bytes at 0x%08x\n",
533
- (unsigned)len, addr);
534
- }
535
- return 0;
536
- }
537
- break;
538
- case _undef:
539
- default:
540
- logerror("bug\n");
541
- return -EDOM;
542
- }
543
-
544
- ctx->total += len;
545
- ctx->count++;
546
-
547
- /* Retry this till we get a real error. Control messages are not
548
- * NAKed (just dropped) so time out means is a real problem.
549
- */
550
- while ((rc = ezusb_write(ctx->device,
551
- external ? "write external" : "write on-chip",
552
- external ? RW_MEMORY : RW_INTERNAL,
553
- addr, data, len)) < 0
554
- && retry < RETRY_LIMIT) {
555
- if (rc != LIBUSB_ERROR_TIMEOUT)
556
- break;
557
- retry += 1;
558
- }
559
- return rc;
560
- }
561
-
562
- /*
563
- * Load a Cypress Image file into target RAM.
564
- * See http://www.cypress.com/?docID=41351 (AN76405 PDF) for more info.
565
- */
566
- static int fx3_load_ram(libusb_device_handle *device, const char *path)
567
- {
568
- uint32_t dCheckSum, dExpectedCheckSum, dAddress, i, dLen, dLength;
569
- uint32_t* dImageBuf;
570
- unsigned char *bBuf, hBuf[4], blBuf[4], rBuf[4096];
571
- FILE *image;
572
- int ret = 0;
573
-
574
- image = fopen(path, "rb");
575
- if (image == NULL) {
576
- logerror("unable to open '%s' for input\n", path);
577
- return -2;
578
- } else if (verbose)
579
- logerror("open firmware image %s for RAM upload\n", path);
580
-
581
- // Read header
582
- if (fread(hBuf, sizeof(char), sizeof(hBuf), image) != sizeof(hBuf)) {
583
- logerror("could not read image header");
584
- ret = -3;
585
- goto exit;
586
- }
587
-
588
- // check "CY" signature byte and format
589
- if ((hBuf[0] != 'C') || (hBuf[1] != 'Y')) {
590
- logerror("image doesn't have a CYpress signature\n");
591
- ret = -3;
592
- goto exit;
593
- }
594
-
595
- // Check bImageType
596
- switch(hBuf[3]) {
597
- case 0xB0:
598
- if (verbose)
599
- logerror("normal FW binary %s image with checksum\n", (hBuf[2]&0x01)?"data":"executable");
600
- break;
601
- case 0xB1:
602
- logerror("security binary image is not currently supported\n");
603
- ret = -3;
604
- goto exit;
605
- case 0xB2:
606
- logerror("VID:PID image is not currently supported\n");
607
- ret = -3;
608
- goto exit;
609
- default:
610
- logerror("invalid image type 0x%02X\n", hBuf[3]);
611
- ret = -3;
612
- goto exit;
613
- }
614
-
615
- // Read the bootloader version
616
- if (verbose) {
617
- if ((ezusb_read(device, "read bootloader version", RW_INTERNAL, 0xFFFF0020, blBuf, 4) < 0)) {
618
- logerror("Could not read bootloader version\n");
619
- ret = -8;
620
- goto exit;
621
- }
622
- logerror("FX3 bootloader version: 0x%02X%02X%02X%02X\n", blBuf[3], blBuf[2], blBuf[1], blBuf[0]);
623
- }
624
-
625
- dCheckSum = 0;
626
- if (verbose)
627
- logerror("writing image...\n");
628
- while (1) {
629
- if ((fread(&dLength, sizeof(uint32_t), 1, image) != 1) || // read dLength
630
- (fread(&dAddress, sizeof(uint32_t), 1, image) != 1)) { // read dAddress
631
- logerror("could not read image");
632
- ret = -3;
633
- goto exit;
634
- }
635
- if (dLength == 0)
636
- break; // done
637
-
638
- // coverity[tainted_data]
639
- dImageBuf = (uint32_t*)calloc(dLength, sizeof(uint32_t));
640
- if (dImageBuf == NULL) {
641
- logerror("could not allocate buffer for image chunk\n");
642
- ret = -4;
643
- goto exit;
644
- }
645
-
646
- // read sections
647
- if (fread(dImageBuf, sizeof(uint32_t), dLength, image) != dLength) {
648
- logerror("could not read image");
649
- free(dImageBuf);
650
- ret = -3;
651
- goto exit;
652
- }
653
- for (i = 0; i < dLength; i++)
654
- dCheckSum += dImageBuf[i];
655
- dLength <<= 2; // convert to Byte length
656
- bBuf = (unsigned char*) dImageBuf;
657
-
658
- while (dLength > 0) {
659
- dLen = 4096; // 4K max
660
- if (dLen > dLength)
661
- dLen = dLength;
662
- if ((ezusb_write(device, "write firmware", RW_INTERNAL, dAddress, bBuf, dLen) < 0) ||
663
- (ezusb_read(device, "read firmware", RW_INTERNAL, dAddress, rBuf, dLen) < 0)) {
664
- logerror("R/W error\n");
665
- free(dImageBuf);
666
- ret = -5;
667
- goto exit;
668
- }
669
- // Verify data: rBuf with bBuf
670
- for (i = 0; i < dLen; i++) {
671
- if (rBuf[i] != bBuf[i]) {
672
- logerror("verify error");
673
- free(dImageBuf);
674
- ret = -6;
675
- goto exit;
676
- }
677
- }
678
-
679
- dLength -= dLen;
680
- bBuf += dLen;
681
- dAddress += dLen;
682
- }
683
- free(dImageBuf);
684
- }
685
-
686
- // read pre-computed checksum data
687
- if ((fread(&dExpectedCheckSum, sizeof(uint32_t), 1, image) != 1) ||
688
- (dCheckSum != dExpectedCheckSum)) {
689
- logerror("checksum error\n");
690
- ret = -7;
691
- goto exit;
692
- }
693
-
694
- // transfer execution to Program Entry
695
- if (!ezusb_fx3_jump(device, dAddress)) {
696
- ret = -6;
697
- }
698
-
699
- exit:
700
- fclose(image);
701
- return ret;
702
- }
703
-
704
- /*
705
- * Load a firmware file into target RAM. device is the open libusb
706
- * device, and the path is the name of the source file. Open the file,
707
- * parse the bytes, and write them in one or two phases.
708
- *
709
- * If stage == 0, this uses the first stage loader, built into EZ-USB
710
- * hardware but limited to writing on-chip memory or CPUCS. Everything
711
- * is written during one stage, unless there's an error such as the image
712
- * holding data that needs to be written to external memory.
713
- *
714
- * Otherwise, things are written in two stages. First the external
715
- * memory is written, expecting a second stage loader to have already
716
- * been loaded. Then file is re-parsed and on-chip memory is written.
717
- */
718
- int ezusb_load_ram(libusb_device_handle *device, const char *path, int fx_type, int img_type, int stage)
719
- {
720
- FILE *image;
721
- uint32_t cpucs_addr;
722
- bool (*is_external)(uint32_t off, size_t len);
723
- struct ram_poke_context ctx;
724
- int status;
725
- uint8_t iic_header[8] = { 0 };
726
- int ret = 0;
727
-
728
- if (fx_type == FX_TYPE_FX3)
729
- return fx3_load_ram(device, path);
730
-
731
- image = fopen(path, "rb");
732
- if (image == NULL) {
733
- logerror("%s: unable to open for input.\n", path);
734
- return -2;
735
- } else if (verbose > 1)
736
- logerror("open firmware image %s for RAM upload\n", path);
737
-
738
- if (img_type == IMG_TYPE_IIC) {
739
- if ( (fread(iic_header, 1, sizeof(iic_header), image) != sizeof(iic_header))
740
- || (((fx_type == FX_TYPE_FX2LP) || (fx_type == FX_TYPE_FX2)) && (iic_header[0] != 0xC2))
741
- || ((fx_type == FX_TYPE_AN21) && (iic_header[0] != 0xB2))
742
- || ((fx_type == FX_TYPE_FX1) && (iic_header[0] != 0xB6)) ) {
743
- logerror("IIC image does not contain executable code - cannot load to RAM.\n");
744
- ret = -1;
745
- goto exit;
746
- }
747
- }
748
-
749
- /* EZ-USB original/FX and FX2 devices differ, apart from the 8051 core */
750
- switch(fx_type) {
751
- case FX_TYPE_FX2LP:
752
- cpucs_addr = 0xe600;
753
- is_external = fx2lp_is_external;
754
- break;
755
- case FX_TYPE_FX2:
756
- cpucs_addr = 0xe600;
757
- is_external = fx2_is_external;
758
- break;
759
- default:
760
- cpucs_addr = 0x7f92;
761
- is_external = fx_is_external;
762
- break;
763
- }
764
-
765
- /* use only first stage loader? */
766
- if (stage == 0) {
767
- ctx.mode = internal_only;
768
-
769
- /* if required, halt the CPU while we overwrite its code/data */
770
- if (cpucs_addr && !ezusb_cpucs(device, cpucs_addr, false))
771
- {
772
- ret = -1;
773
- goto exit;
774
- }
775
-
776
- /* 2nd stage, first part? loader was already uploaded */
777
- } else {
778
- ctx.mode = skip_internal;
779
-
780
- /* let CPU run; overwrite the 2nd stage loader later */
781
- if (verbose)
782
- logerror("2nd stage: write external memory\n");
783
- }
784
-
785
- /* scan the image, first (maybe only) time */
786
- ctx.device = device;
787
- ctx.total = ctx.count = 0;
788
- status = parse[img_type](image, &ctx, is_external, ram_poke);
789
- if (status < 0) {
790
- logerror("unable to upload %s\n", path);
791
- ret = status;
792
- goto exit;
793
- }
794
-
795
- /* second part of 2nd stage: rescan */
796
- // TODO: what should we do for non HEX images there?
797
- if (stage) {
798
- ctx.mode = skip_external;
799
-
800
- /* if needed, halt the CPU while we overwrite the 1st stage loader */
801
- if (cpucs_addr && !ezusb_cpucs(device, cpucs_addr, false))
802
- {
803
- ret = -1;
804
- goto exit;
805
- }
806
-
807
- /* at least write the interrupt vectors (at 0x0000) for reset! */
808
- rewind(image);
809
- if (verbose)
810
- logerror("2nd stage: write on-chip memory\n");
811
- status = parse_ihex(image, &ctx, is_external, ram_poke);
812
- if (status < 0) {
813
- logerror("unable to completely upload %s\n", path);
814
- ret = status;
815
- goto exit;
816
- }
817
- }
818
-
819
- if (verbose && (ctx.count != 0)) {
820
- logerror("... WROTE: %d bytes, %d segments, avg %d\n",
821
- (int)ctx.total, (int)ctx.count, (int)(ctx.total/ctx.count));
822
- }
823
-
824
- /* if required, reset the CPU so it runs what we just uploaded */
825
- if (cpucs_addr && !ezusb_cpucs(device, cpucs_addr, true))
826
- ret = -1;
827
-
828
- exit:
829
- fclose(image);
830
- return ret;
831
- }