drivers: call adapter_get_required_serial() in jtag_libusb_open()
[openocd.git] / src / jtag / drivers / usb_blaster / ublast2_access_libusb.c
1 /*
2 * Driver for USB-JTAG, Altera USB-Blaster II and compatibles
3 *
4 * Copyright (C) 2013 Franck Jullien franck.jullien@gmail.com
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24 #include <jtag/interface.h>
25 #include <jtag/commands.h>
26 #include "helper/system.h"
27 #include <libusb_helper.h>
28 #include <target/image.h>
29
30 #include "ublast_access.h"
31
32 #define USBBLASTER_CTRL_READ_REV 0x94
33 #define USBBLASTER_CTRL_LOAD_FIRM 0xA0
34 #define USBBLASTER_EPOUT 4
35 #define USBBLASTER_EPIN 8
36
37 #define EZUSB_CPUCS 0xe600
38 #define CPU_RESET 1
39
40 /** Maximum size of a single firmware section. Entire EZ-USB code space = 16kB */
41 #define SECTION_BUFFERSIZE 16384
42
43 static int ublast2_libusb_read(struct ublast_lowlevel *low, uint8_t *buf,
44 unsigned size, uint32_t *bytes_read)
45 {
46 int ret, tmp = 0;
47
48 ret = jtag_libusb_bulk_read(low->libusb_dev,
49 USBBLASTER_EPIN |
50 LIBUSB_ENDPOINT_IN,
51 (char *)buf,
52 size,
53 100, &tmp);
54 *bytes_read = tmp;
55
56 return ret;
57 }
58
59 static int ublast2_libusb_write(struct ublast_lowlevel *low, uint8_t *buf,
60 int size, uint32_t *bytes_written)
61 {
62 int ret, tmp = 0;
63
64 ret = jtag_libusb_bulk_write(low->libusb_dev,
65 USBBLASTER_EPOUT |
66 LIBUSB_ENDPOINT_OUT,
67 (char *)buf,
68 size,
69 100, &tmp);
70 *bytes_written = tmp;
71
72 return ret;
73
74 }
75
76 static int ublast2_write_firmware_section(struct libusb_device_handle *libusb_dev,
77 struct image *firmware_image, int section_index)
78 {
79 uint16_t chunk_size;
80 uint8_t data[SECTION_BUFFERSIZE];
81 uint8_t *data_ptr = data;
82 size_t size_read;
83
84 uint16_t size = (uint16_t)firmware_image->sections[section_index].size;
85 uint16_t addr = (uint16_t)firmware_image->sections[section_index].base_address;
86
87 LOG_DEBUG("section %02i at addr 0x%04x (size 0x%04x)", section_index, addr,
88 size);
89
90 /* Copy section contents to local buffer */
91 int ret = image_read_section(firmware_image, section_index, 0, size, data,
92 &size_read);
93
94 if ((ret != ERROR_OK) || (size_read != size)) {
95 /* Propagating the return code would return '0' (misleadingly indicating
96 * successful execution of the function) if only the size check fails. */
97 return ERROR_FAIL;
98 }
99
100 uint16_t bytes_remaining = size;
101
102 /* Send section data in chunks of up to 64 bytes to ULINK */
103 while (bytes_remaining > 0) {
104 if (bytes_remaining > 64)
105 chunk_size = 64;
106 else
107 chunk_size = bytes_remaining;
108
109 jtag_libusb_control_transfer(libusb_dev,
110 LIBUSB_REQUEST_TYPE_VENDOR |
111 LIBUSB_ENDPOINT_OUT,
112 USBBLASTER_CTRL_LOAD_FIRM,
113 addr,
114 0,
115 (char *)data_ptr,
116 chunk_size,
117 100);
118
119 bytes_remaining -= chunk_size;
120 addr += chunk_size;
121 data_ptr += chunk_size;
122 }
123
124 return ERROR_OK;
125 }
126
127 static int load_usb_blaster_firmware(struct libusb_device_handle *libusb_dev,
128 struct ublast_lowlevel *low)
129 {
130 struct image ublast2_firmware_image;
131
132 if (!low->firmware_path) {
133 LOG_ERROR("No firmware path specified");
134 return ERROR_FAIL;
135 }
136
137 if (libusb_claim_interface(libusb_dev, 0)) {
138 LOG_ERROR("unable to claim interface");
139 return ERROR_JTAG_INIT_FAILED;
140 }
141
142 ublast2_firmware_image.base_address = 0;
143 ublast2_firmware_image.base_address_set = false;
144
145 int ret = image_open(&ublast2_firmware_image, low->firmware_path, "ihex");
146 if (ret != ERROR_OK) {
147 LOG_ERROR("Could not load firmware image");
148 goto error_release_usb;
149 }
150
151 /** A host loader program must write 0x01 to the CPUCS register
152 * to put the CPU into RESET, load all or part of the EZUSB
153 * RAM with firmware, then reload the CPUCS register
154 * with ‘0’ to take the CPU out of RESET. The CPUCS register
155 * (at 0xE600) is the only EZ-USB register that can be written
156 * using the Firmware Download command.
157 */
158
159 char value = CPU_RESET;
160 jtag_libusb_control_transfer(libusb_dev,
161 LIBUSB_REQUEST_TYPE_VENDOR |
162 LIBUSB_ENDPOINT_OUT,
163 USBBLASTER_CTRL_LOAD_FIRM,
164 EZUSB_CPUCS,
165 0,
166 &value,
167 1,
168 100);
169
170 /* Download all sections in the image to ULINK */
171 for (unsigned int i = 0; i < ublast2_firmware_image.num_sections; i++) {
172 ret = ublast2_write_firmware_section(libusb_dev,
173 &ublast2_firmware_image, i);
174 if (ret != ERROR_OK) {
175 LOG_ERROR("Error while downloading the firmware");
176 goto error_close_firmware;
177 }
178 }
179
180 value = !CPU_RESET;
181 jtag_libusb_control_transfer(libusb_dev,
182 LIBUSB_REQUEST_TYPE_VENDOR |
183 LIBUSB_ENDPOINT_OUT,
184 USBBLASTER_CTRL_LOAD_FIRM,
185 EZUSB_CPUCS,
186 0,
187 &value,
188 1,
189 100);
190
191 error_close_firmware:
192 image_close(&ublast2_firmware_image);
193
194 error_release_usb:
195 /*
196 * Release claimed interface. Most probably it is already disconnected
197 * and re-enumerated as new devices after firmware upload, so we do
198 * not need to care about errors.
199 */
200 libusb_release_interface(libusb_dev, 0);
201
202 return ret;
203 }
204
205 static int ublast2_libusb_init(struct ublast_lowlevel *low)
206 {
207 const uint16_t vids[] = { low->ublast_vid_uninit, 0 };
208 const uint16_t pids[] = { low->ublast_pid_uninit, 0 };
209 struct libusb_device_handle *temp;
210 bool renumeration = false;
211 int ret;
212
213 if (jtag_libusb_open(vids, pids, &temp, NULL) == ERROR_OK) {
214 LOG_INFO("Altera USB-Blaster II (uninitialized) found");
215 LOG_INFO("Loading firmware...");
216 ret = load_usb_blaster_firmware(temp, low);
217 jtag_libusb_close(temp);
218 if (ret != ERROR_OK)
219 return ret;
220 renumeration = true;
221 }
222
223 const uint16_t vids_renum[] = { low->ublast_vid, 0 };
224 const uint16_t pids_renum[] = { low->ublast_pid, 0 };
225
226 if (renumeration == false) {
227 if (jtag_libusb_open(vids_renum, pids_renum, &low->libusb_dev, NULL) != ERROR_OK) {
228 LOG_ERROR("Altera USB-Blaster II not found");
229 return ERROR_FAIL;
230 }
231 } else {
232 int retry = 10;
233 while (jtag_libusb_open(vids_renum, pids_renum, &low->libusb_dev, NULL) != ERROR_OK && retry--) {
234 usleep(1000000);
235 LOG_INFO("Waiting for reenumerate...");
236 }
237
238 if (!retry) {
239 LOG_ERROR("Altera USB-Blaster II not found");
240 return ERROR_FAIL;
241 }
242 }
243
244 if (libusb_claim_interface(low->libusb_dev, 0)) {
245 LOG_ERROR("unable to claim interface");
246 jtag_libusb_close(low->libusb_dev);
247 return ERROR_JTAG_INIT_FAILED;
248 }
249
250 char buffer[5];
251 jtag_libusb_control_transfer(low->libusb_dev,
252 LIBUSB_REQUEST_TYPE_VENDOR |
253 LIBUSB_ENDPOINT_IN,
254 USBBLASTER_CTRL_READ_REV,
255 0,
256 0,
257 buffer,
258 5,
259 100);
260
261 LOG_INFO("Altera USB-Blaster II found (Firm. rev. = %s)", buffer);
262
263 return ERROR_OK;
264 }
265
266 static int ublast2_libusb_quit(struct ublast_lowlevel *low)
267 {
268 if (libusb_release_interface(low->libusb_dev, 0))
269 LOG_ERROR("usb release interface failed");
270
271 jtag_libusb_close(low->libusb_dev);
272 return ERROR_OK;
273 };
274
275 static struct ublast_lowlevel low = {
276 .open = ublast2_libusb_init,
277 .close = ublast2_libusb_quit,
278 .read = ublast2_libusb_read,
279 .write = ublast2_libusb_write,
280 .flags = COPY_TDO_BUFFER,
281 };
282
283 struct ublast_lowlevel *ublast2_register_libusb(void)
284 {
285 return &low;
286 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)