flash/nor: Rename flash_address() to cfi_flash_address()
[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 <libusb_common.h>
27 #include <target/image.h>
28
29 #include "ublast_access.h"
30
31 #define USBBLASTER_CTRL_READ_REV 0x94
32 #define USBBLASTER_CTRL_LOAD_FIRM 0xA0
33 #define USBBLASTER_EPOUT 4
34 #define USBBLASTER_EPIN 8
35
36 #define EZUSB_CPUCS 0xe600
37 #define CPU_RESET 1
38
39 /** Maximum size of a single firmware section. Entire EZ-USB code space = 16kB */
40 #define SECTION_BUFFERSIZE 16384
41
42 static int ublast2_libusb_read(struct ublast_lowlevel *low, uint8_t *buf,
43 unsigned size, uint32_t *bytes_read)
44 {
45 *bytes_read = jtag_libusb_bulk_read(low->libusb_dev,
46 USBBLASTER_EPIN | \
47 LIBUSB_ENDPOINT_IN,
48 (char *)buf,
49 size,
50 100);
51 return ERROR_OK;
52 }
53
54 static int ublast2_libusb_write(struct ublast_lowlevel *low, uint8_t *buf,
55 int size, uint32_t *bytes_written)
56 {
57 *bytes_written = jtag_libusb_bulk_write(low->libusb_dev,
58 USBBLASTER_EPOUT | \
59 LIBUSB_ENDPOINT_OUT,
60 (char *)buf,
61 size,
62 100);
63 return ERROR_OK;
64 }
65
66 static int ublast2_write_firmware_section(struct jtag_libusb_device_handle *libusb_dev,
67 struct image *firmware_image, int section_index)
68 {
69 uint16_t chunk_size;
70 uint8_t data[SECTION_BUFFERSIZE];
71 uint8_t *data_ptr = data;
72 size_t size_read;
73
74 uint16_t size = (uint16_t)firmware_image->sections[section_index].size;
75 uint16_t addr = (uint16_t)firmware_image->sections[section_index].base_address;
76
77 LOG_DEBUG("section %02i at addr 0x%04x (size 0x%04x)", section_index, addr,
78 size);
79
80 /* Copy section contents to local buffer */
81 int ret = image_read_section(firmware_image, section_index, 0, size, data,
82 &size_read);
83
84 if ((ret != ERROR_OK) || (size_read != size)) {
85 /* Propagating the return code would return '0' (misleadingly indicating
86 * successful execution of the function) if only the size check fails. */
87 return ERROR_FAIL;
88 }
89
90 uint16_t bytes_remaining = size;
91
92 /* Send section data in chunks of up to 64 bytes to ULINK */
93 while (bytes_remaining > 0) {
94 if (bytes_remaining > 64)
95 chunk_size = 64;
96 else
97 chunk_size = bytes_remaining;
98
99 jtag_libusb_control_transfer(libusb_dev,
100 LIBUSB_REQUEST_TYPE_VENDOR | \
101 LIBUSB_ENDPOINT_OUT,
102 USBBLASTER_CTRL_LOAD_FIRM,
103 addr,
104 0,
105 (char *)data_ptr,
106 chunk_size,
107 100);
108
109 bytes_remaining -= chunk_size;
110 addr += chunk_size;
111 data_ptr += chunk_size;
112 }
113
114 return ERROR_OK;
115 }
116
117 static int load_usb_blaster_firmware(struct jtag_libusb_device_handle *libusb_dev,
118 struct ublast_lowlevel *low)
119 {
120 struct image ublast2_firmware_image;
121
122 if (!low->firmware_path) {
123 LOG_ERROR("No firmware path specified");
124 return ERROR_FAIL;
125 }
126
127 ublast2_firmware_image.base_address = 0;
128 ublast2_firmware_image.base_address_set = 0;
129
130 int ret = image_open(&ublast2_firmware_image, low->firmware_path, "ihex");
131 if (ret != ERROR_OK) {
132 LOG_ERROR("Could not load firmware image");
133 return ret;
134 }
135
136 /** A host loader program must write 0x01 to the CPUCS register
137 * to put the CPU into RESET, load all or part of the EZUSB
138 * RAM with firmware, then reload the CPUCS register
139 * with ‘0’ to take the CPU out of RESET. The CPUCS register
140 * (at 0xE600) is the only EZ-USB register that can be written
141 * using the Firmware Download command.
142 */
143
144 char value = CPU_RESET;
145 jtag_libusb_control_transfer(libusb_dev,
146 LIBUSB_REQUEST_TYPE_VENDOR | \
147 LIBUSB_ENDPOINT_OUT,
148 USBBLASTER_CTRL_LOAD_FIRM,
149 EZUSB_CPUCS,
150 0,
151 &value,
152 1,
153 100);
154
155 /* Download all sections in the image to ULINK */
156 for (int i = 0; i < ublast2_firmware_image.num_sections; i++) {
157 ret = ublast2_write_firmware_section(libusb_dev,
158 &ublast2_firmware_image, i);
159 if (ret != ERROR_OK) {
160 LOG_ERROR("Error while downloading the firmware");
161 return ret;
162 }
163 }
164
165 value = !CPU_RESET;
166 jtag_libusb_control_transfer(libusb_dev,
167 LIBUSB_REQUEST_TYPE_VENDOR | \
168 LIBUSB_ENDPOINT_OUT,
169 USBBLASTER_CTRL_LOAD_FIRM,
170 EZUSB_CPUCS,
171 0,
172 &value,
173 1,
174 100);
175
176 image_close(&ublast2_firmware_image);
177
178 return ERROR_OK;
179 }
180
181 static int ublast2_libusb_init(struct ublast_lowlevel *low)
182 {
183 const uint16_t vids[] = { low->ublast_vid_uninit, 0 };
184 const uint16_t pids[] = { low->ublast_pid_uninit, 0 };
185 struct jtag_libusb_device_handle *temp;
186 bool renumeration = false;
187 int ret;
188
189 if (jtag_libusb_open(vids, pids, NULL, &temp) == ERROR_OK) {
190 LOG_INFO("Altera USB-Blaster II (uninitialized) found");
191 LOG_INFO("Loading firmware...");
192 ret = load_usb_blaster_firmware(temp, low);
193 jtag_libusb_close(temp);
194 if (ret != ERROR_OK)
195 return ret;
196 renumeration = true;
197 }
198
199 const uint16_t vids_renum[] = { low->ublast_vid, 0 };
200 const uint16_t pids_renum[] = { low->ublast_pid, 0 };
201
202 if (renumeration == false) {
203 if (jtag_libusb_open(vids_renum, pids_renum, NULL, &low->libusb_dev) != ERROR_OK) {
204 LOG_ERROR("Altera USB-Blaster II not found");
205 return ERROR_FAIL;
206 }
207 } else {
208 int retry = 10;
209 while (jtag_libusb_open(vids_renum, pids_renum, NULL, &low->libusb_dev) != ERROR_OK && retry--) {
210 usleep(1000000);
211 LOG_INFO("Waiting for renumerate...");
212 }
213
214 if (!retry) {
215 LOG_ERROR("Altera USB-Blaster II not found");
216 return ERROR_FAIL;
217 }
218 }
219
220 char buffer[5];
221 jtag_libusb_control_transfer(low->libusb_dev,
222 LIBUSB_REQUEST_TYPE_VENDOR | \
223 LIBUSB_ENDPOINT_IN,
224 USBBLASTER_CTRL_READ_REV,
225 0,
226 0,
227 buffer,
228 5,
229 100);
230
231 LOG_INFO("Altera USB-Blaster II found (Firm. rev. = %s)", buffer);
232
233 return ERROR_OK;
234 }
235
236 static int ublast2_libusb_quit(struct ublast_lowlevel *low)
237 {
238 jtag_libusb_close(low->libusb_dev);
239 return ERROR_OK;
240 };
241
242 static struct ublast_lowlevel low = {
243 .open = ublast2_libusb_init,
244 .close = ublast2_libusb_quit,
245 .read = ublast2_libusb_read,
246 .write = ublast2_libusb_write,
247 .flags = COPY_TDO_BUFFER,
248 };
249
250 struct ublast_lowlevel *ublast2_register_libusb(void)
251 {
252 return &low;
253 }

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)