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
,
108 bytes_remaining
-= chunk_size
;
110 data_ptr
+= chunk_size
;
116 static int load_usb_blaster_firmware(struct libusb_device_handle
*libusb_dev
,
117 struct ublast_lowlevel
*low
)
119 struct image ublast2_firmware_image
;
121 if (!low
->firmware_path
) {
122 LOG_ERROR("No firmware path specified");
126 if (libusb_claim_interface(libusb_dev
, 0)) {
127 LOG_ERROR("unable to claim interface");
128 return ERROR_JTAG_INIT_FAILED
;
131 ublast2_firmware_image
.base_address
= 0;
132 ublast2_firmware_image
.base_address_set
= false;
134 int ret
= image_open(&ublast2_firmware_image
, low
->firmware_path
, "ihex");
135 if (ret
!= ERROR_OK
) {
136 LOG_ERROR("Could not load firmware image");
137 goto error_release_usb
;
140 /** A host loader program must write 0x01 to the CPUCS register
141 * to put the CPU into RESET, load all or part of the EZUSB
142 * RAM with firmware, then reload the CPUCS register
143 * with ‘0’ to take the CPU out of RESET. The CPUCS register
144 * (at 0xE600) is the only EZ-USB register that can be written
145 * using the Firmware Download command.
148 char value
= CPU_RESET
;
149 jtag_libusb_control_transfer(libusb_dev
,
150 LIBUSB_REQUEST_TYPE_VENDOR
|
152 USBBLASTER_CTRL_LOAD_FIRM
,
159 /* Download all sections in the image to ULINK */
160 for (unsigned int i
= 0; i
< ublast2_firmware_image
.num_sections
; i
++) {
161 ret
= ublast2_write_firmware_section(libusb_dev
,
162 &ublast2_firmware_image
, i
);
163 if (ret
!= ERROR_OK
) {
164 LOG_ERROR("Error while downloading the firmware");
165 goto error_close_firmware
;
170 jtag_libusb_control_transfer(libusb_dev
,
171 LIBUSB_REQUEST_TYPE_VENDOR
|
173 USBBLASTER_CTRL_LOAD_FIRM
,
180 error_close_firmware
:
181 image_close(&ublast2_firmware_image
);
185 * Release claimed interface. Most probably it is already disconnected
186 * and re-enumerated as new devices after firmware upload, so we do
187 * not need to care about errors.
189 libusb_release_interface(libusb_dev
, 0);
194 static int ublast2_libusb_init(struct ublast_lowlevel
*low
)
196 const uint16_t vids
[] = { low
->ublast_vid_uninit
, 0 };
197 const uint16_t pids
[] = { low
->ublast_pid_uninit
, 0 };
198 struct libusb_device_handle
*temp
;
199 bool renumeration
= false;
202 if (jtag_libusb_open(vids
, pids
, &temp
, NULL
) == ERROR_OK
) {
203 LOG_INFO("Altera USB-Blaster II (uninitialized) found");
204 LOG_INFO("Loading firmware...");
205 ret
= load_usb_blaster_firmware(temp
, low
);
206 jtag_libusb_close(temp
);
212 const uint16_t vids_renum
[] = { low
->ublast_vid
, 0 };
213 const uint16_t pids_renum
[] = { low
->ublast_pid
, 0 };
215 if (renumeration
== false) {
216 if (jtag_libusb_open(vids_renum
, pids_renum
, &low
->libusb_dev
, NULL
) != ERROR_OK
) {
217 LOG_ERROR("Altera USB-Blaster II not found");
222 while (jtag_libusb_open(vids_renum
, pids_renum
, &low
->libusb_dev
, NULL
) != ERROR_OK
&& retry
--) {
224 LOG_INFO("Waiting for reenumerate...");
228 LOG_ERROR("Altera USB-Blaster II not found");
233 if (libusb_claim_interface(low
->libusb_dev
, 0)) {
234 LOG_ERROR("unable to claim interface");
235 jtag_libusb_close(low
->libusb_dev
);
236 return ERROR_JTAG_INIT_FAILED
;
240 jtag_libusb_control_transfer(low
->libusb_dev
,
241 LIBUSB_REQUEST_TYPE_VENDOR
|
243 USBBLASTER_CTRL_READ_REV
,
250 LOG_INFO("Altera USB-Blaster II found (Firm. rev. = %s)", buffer
);
255 static int ublast2_libusb_quit(struct ublast_lowlevel
*low
)
257 if (libusb_release_interface(low
->libusb_dev
, 0))
258 LOG_ERROR("usb release interface failed");
260 jtag_libusb_close(low
->libusb_dev
);
264 static struct ublast_lowlevel low
= {
265 .open
= ublast2_libusb_init
,
266 .close
= ublast2_libusb_quit
,
267 .read
= ublast2_libusb_read
,
268 .write
= ublast2_libusb_write
,
269 .flags
= COPY_TDO_BUFFER
,
272 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)