1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Driver for USB-JTAG, Altera USB-Blaster II and compatibles
6 * Copyright (C) 2013 Franck Jullien franck.jullien@gmail.com
13 #include <jtag/interface.h>
14 #include <jtag/commands.h>
15 #include "helper/system.h"
16 #include <libusb_helper.h>
17 #include <target/image.h>
19 #include "ublast_access.h"
21 #define USBBLASTER_CTRL_READ_REV 0x94
22 #define USBBLASTER_CTRL_LOAD_FIRM 0xA0
23 #define USBBLASTER_EPOUT 4
24 #define USBBLASTER_EPIN 8
26 #define EZUSB_CPUCS 0xe600
29 /** Maximum size of a single firmware section. Entire EZ-USB code space = 16kB */
30 #define SECTION_BUFFERSIZE 16384
32 static int ublast2_libusb_read(struct ublast_lowlevel
*low
, uint8_t *buf
,
33 unsigned size
, uint32_t *bytes_read
)
37 ret
= jtag_libusb_bulk_read(low
->libusb_dev
,
48 static int ublast2_libusb_write(struct ublast_lowlevel
*low
, uint8_t *buf
,
49 int size
, uint32_t *bytes_written
)
53 ret
= jtag_libusb_bulk_write(low
->libusb_dev
,
65 static int ublast2_write_firmware_section(struct libusb_device_handle
*libusb_dev
,
66 struct image
*firmware_image
, int section_index
)
69 uint8_t data
[SECTION_BUFFERSIZE
];
70 uint8_t *data_ptr
= data
;
73 uint16_t size
= (uint16_t)firmware_image
->sections
[section_index
].size
;
74 uint16_t addr
= (uint16_t)firmware_image
->sections
[section_index
].base_address
;
76 LOG_DEBUG("section %02i at addr 0x%04x (size 0x%04x)", section_index
, addr
,
79 /* Copy section contents to local buffer */
80 int ret
= image_read_section(firmware_image
, section_index
, 0, size
, data
,
83 if ((ret
!= ERROR_OK
) || (size_read
!= size
)) {
84 /* Propagating the return code would return '0' (misleadingly indicating
85 * successful execution of the function) if only the size check fails. */
89 uint16_t bytes_remaining
= size
;
91 /* Send section data in chunks of up to 64 bytes to ULINK */
92 while (bytes_remaining
> 0) {
93 if (bytes_remaining
> 64)
96 chunk_size
= bytes_remaining
;
98 jtag_libusb_control_transfer(libusb_dev
,
99 LIBUSB_REQUEST_TYPE_VENDOR
|
101 USBBLASTER_CTRL_LOAD_FIRM
,
109 bytes_remaining
-= chunk_size
;
111 data_ptr
+= chunk_size
;
117 static int load_usb_blaster_firmware(struct libusb_device_handle
*libusb_dev
,
118 struct ublast_lowlevel
*low
)
120 struct image ublast2_firmware_image
;
122 if (!low
->firmware_path
) {
123 LOG_ERROR("No firmware path specified");
127 if (libusb_claim_interface(libusb_dev
, 0)) {
128 LOG_ERROR("unable to claim interface");
129 return ERROR_JTAG_INIT_FAILED
;
132 ublast2_firmware_image
.base_address
= 0;
133 ublast2_firmware_image
.base_address_set
= false;
135 int ret
= image_open(&ublast2_firmware_image
, low
->firmware_path
, "ihex");
136 if (ret
!= ERROR_OK
) {
137 LOG_ERROR("Could not load firmware image");
138 goto error_release_usb
;
141 /** A host loader program must write 0x01 to the CPUCS register
142 * to put the CPU into RESET, load all or part of the EZUSB
143 * RAM with firmware, then reload the CPUCS register
144 * with ‘0’ to take the CPU out of RESET. The CPUCS register
145 * (at 0xE600) is the only EZ-USB register that can be written
146 * using the Firmware Download command.
149 char value
= CPU_RESET
;
150 jtag_libusb_control_transfer(libusb_dev
,
151 LIBUSB_REQUEST_TYPE_VENDOR
|
153 USBBLASTER_CTRL_LOAD_FIRM
,
161 /* Download all sections in the image to ULINK */
162 for (unsigned int i
= 0; i
< ublast2_firmware_image
.num_sections
; i
++) {
163 ret
= ublast2_write_firmware_section(libusb_dev
,
164 &ublast2_firmware_image
, i
);
165 if (ret
!= ERROR_OK
) {
166 LOG_ERROR("Error while downloading the firmware");
167 goto error_close_firmware
;
172 jtag_libusb_control_transfer(libusb_dev
,
173 LIBUSB_REQUEST_TYPE_VENDOR
|
175 USBBLASTER_CTRL_LOAD_FIRM
,
183 error_close_firmware
:
184 image_close(&ublast2_firmware_image
);
188 * Release claimed interface. Most probably it is already disconnected
189 * and re-enumerated as new devices after firmware upload, so we do
190 * not need to care about errors.
192 libusb_release_interface(libusb_dev
, 0);
197 static int ublast2_libusb_init(struct ublast_lowlevel
*low
)
199 const uint16_t vids
[] = { low
->ublast_vid_uninit
, 0 };
200 const uint16_t pids
[] = { low
->ublast_pid_uninit
, 0 };
201 struct libusb_device_handle
*temp
;
202 bool renumeration
= false;
205 if (jtag_libusb_open(vids
, pids
, NULL
, &temp
, NULL
) == ERROR_OK
) {
206 LOG_INFO("Altera USB-Blaster II (uninitialized) found");
207 LOG_INFO("Loading firmware...");
208 ret
= load_usb_blaster_firmware(temp
, low
);
209 jtag_libusb_close(temp
);
215 const uint16_t vids_renum
[] = { low
->ublast_vid
, 0 };
216 const uint16_t pids_renum
[] = { low
->ublast_pid
, 0 };
218 if (renumeration
== false) {
219 if (jtag_libusb_open(vids_renum
, pids_renum
, NULL
, &low
->libusb_dev
, NULL
) != ERROR_OK
) {
220 LOG_ERROR("Altera USB-Blaster II not found");
225 while (jtag_libusb_open(vids_renum
, pids_renum
, NULL
, &low
->libusb_dev
, NULL
) != ERROR_OK
&& retry
--) {
227 LOG_INFO("Waiting for reenumerate...");
231 LOG_ERROR("Altera USB-Blaster II not found");
236 if (libusb_claim_interface(low
->libusb_dev
, 0)) {
237 LOG_ERROR("unable to claim interface");
238 jtag_libusb_close(low
->libusb_dev
);
239 return ERROR_JTAG_INIT_FAILED
;
243 jtag_libusb_control_transfer(low
->libusb_dev
,
244 LIBUSB_REQUEST_TYPE_VENDOR
|
246 USBBLASTER_CTRL_READ_REV
,
254 LOG_INFO("Altera USB-Blaster II found (Firm. rev. = %s)", buffer
);
259 static int ublast2_libusb_quit(struct ublast_lowlevel
*low
)
261 if (libusb_release_interface(low
->libusb_dev
, 0))
262 LOG_ERROR("usb release interface failed");
264 jtag_libusb_close(low
->libusb_dev
);
268 static struct ublast_lowlevel low
= {
269 .open
= ublast2_libusb_init
,
270 .close
= ublast2_libusb_quit
,
271 .read
= ublast2_libusb_read
,
272 .write
= ublast2_libusb_write
,
273 .flags
= COPY_TDO_BUFFER
,
276 struct ublast_lowlevel
*ublast2_register_libusb(void)
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)