3eea9de5860796d13413eedc4e2335d46a43250d
[openocd.git] / src / jtag / drivers / nulink_usb.c
1 /***************************************************************************
2 * Copyright (C) 2016-2017 by Nuvoton *
3 * Zale Yu <cyyu@nuvoton.com> *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 /* project specific includes */
24 #include <helper/binarybuffer.h>
25 #include <jtag/interface.h>
26 #include <jtag/hla/hla_layout.h>
27 #include <jtag/hla/hla_transport.h>
28 #include <jtag/hla/hla_interface.h>
29 #include <target/target.h>
30
31 #include <target/cortex_m.h>
32
33 #include <hidapi.h>
34
35 #define NULINK_READ_TIMEOUT 1000
36
37 #define NULINK_HID_MAX_SIZE (64)
38 #define NULINK2_HID_MAX_SIZE (1024)
39 #define V6M_MAX_COMMAND_LENGTH (NULINK_HID_MAX_SIZE - 2)
40 #define V7M_MAX_COMMAND_LENGTH (NULINK_HID_MAX_SIZE - 3)
41
42 #define NULINK2_USB_PID1 (0x5200)
43 #define NULINK2_USB_PID2 (0x5201)
44
45 struct nulink_usb_handle_s {
46 hid_device *dev_handle;
47 uint16_t max_packet_size;
48 uint8_t usbcmdidx;
49 uint8_t cmdidx;
50 uint8_t cmdsize;
51 uint8_t cmdbuf[NULINK2_HID_MAX_SIZE + 1];
52 uint8_t tempbuf[NULINK2_HID_MAX_SIZE];
53 uint8_t databuf[NULINK2_HID_MAX_SIZE];
54 uint32_t max_mem_packet;
55 uint16_t hardware_config; /* bit 0: 1:Nu-Link-Pro, 0:Nu-Link */
56
57 int (*xfer)(void *handle, uint8_t *buf, int size);
58 void (*init_buffer)(void *handle, uint32_t size);
59 };
60
61 /* ICE Command */
62 #define CMD_READ_REG 0xB5UL
63 #define CMD_READ_RAM 0xB1UL
64 #define CMD_WRITE_REG 0xB8UL
65 #define CMD_WRITE_RAM 0xB9UL
66 #define CMD_CHECK_ID 0xA3UL
67 #define CMD_MCU_RESET 0xE2UL
68 #define CMD_CHECK_MCU_STOP 0xD8UL
69 #define CMD_MCU_STEP_RUN 0xD1UL
70 #define CMD_MCU_STOP_RUN 0xD2UL
71 #define CMD_MCU_FREE_RUN 0xD3UL
72 #define CMD_SET_CONFIG 0xA2UL
73
74 #define ARM_SRAM_BASE 0x20000000UL
75
76 #define HARDWARE_CONFIG_NULINKPRO 1
77 #define HARDWARE_CONFIG_NULINK2 2
78
79 enum nulink_reset {
80 RESET_AUTO = 0,
81 RESET_HW = 1,
82 RESET_SYSRESETREQ = 2,
83 RESET_VECTRESET = 3,
84 RESET_FAST_RESCUE = 4, /* Rescue and erase the chip, need very fast speed */
85 };
86
87 enum nulink_connect {
88 CONNECT_NORMAL = 0, /* Support all reset method */
89 CONNECT_PRE_RESET = 1, /* Support all reset method */
90 CONNECT_UNDER_RESET = 2, /* Support all reset method */
91 CONNECT_NONE = 3, /* Support RESET_HW, (RESET_AUTO = RESET_HW) */
92 CONNECT_DISCONNECT = 4, /* Support RESET_NONE, (RESET_AUTO = RESET_NONE) */
93 CONNECT_ICP_MODE = 5 /* Support NUC505 ICP mode*/
94 };
95
96 static int nulink_usb_xfer_rw(void *handle, uint8_t *buf)
97 {
98 struct nulink_usb_handle_s *h = handle;
99
100 assert(handle);
101
102 int ret = hid_write(h->dev_handle, h->cmdbuf, h->max_packet_size + 1);
103 if (ret < 0) {
104 LOG_ERROR("hid_write");
105 return ERROR_FAIL;
106 }
107
108 ret = hid_read_timeout(h->dev_handle, buf, h->max_packet_size, NULINK_READ_TIMEOUT);
109 if (ret < 0) {
110 LOG_ERROR("hid_read_timeout");
111 return ERROR_FAIL;
112 }
113 return ERROR_OK;
114 }
115
116 static int nulink1_usb_xfer(void *handle, uint8_t *buf, int size)
117 {
118 struct nulink_usb_handle_s *h = handle;
119
120 assert(handle);
121
122 int err = nulink_usb_xfer_rw(h, h->tempbuf);
123
124 memcpy(buf, h->tempbuf + 2, V6M_MAX_COMMAND_LENGTH);
125
126 return err;
127 }
128
129 static int nulink2_usb_xfer(void *handle, uint8_t *buf, int size)
130 {
131 struct nulink_usb_handle_s *h = handle;
132
133 assert(handle);
134
135 int err = nulink_usb_xfer_rw(h, h->tempbuf);
136
137 memcpy(buf, h->tempbuf + 3, V7M_MAX_COMMAND_LENGTH);
138
139 return err;
140 }
141
142 static void nulink1_usb_init_buffer(void *handle, uint32_t size)
143 {
144 struct nulink_usb_handle_s *h = handle;
145
146 h->cmdidx = 0;
147
148 memset(h->cmdbuf, 0, h->max_packet_size + 1);
149 memset(h->tempbuf, 0, h->max_packet_size);
150 memset(h->databuf, 0, h->max_packet_size);
151
152 h->cmdbuf[0] = 0; /* report number */
153 h->cmdbuf[1] = ++h->usbcmdidx & 0x7F;
154 h->cmdbuf[2] = size;
155 h->cmdidx += 3;
156 }
157
158 static void nulink2_usb_init_buffer(void *handle, uint32_t size)
159 {
160 struct nulink_usb_handle_s *h = handle;
161
162 h->cmdidx = 0;
163
164 memset(h->cmdbuf, 0, h->max_packet_size + 1);
165 memset(h->tempbuf, 0, h->max_packet_size);
166 memset(h->databuf, 0, h->max_packet_size);
167
168 h->cmdbuf[0] = 0; /* report number */
169 h->cmdbuf[1] = ++h->usbcmdidx & 0x7F;
170 h_u16_to_le(h->cmdbuf + 2, size);
171 h->cmdidx += 4;
172 }
173
174 static inline int nulink_usb_xfer(void *handle, uint8_t *buf, int size)
175 {
176 struct nulink_usb_handle_s *h = handle;
177
178 assert(handle);
179
180 return h->xfer(handle, buf, size);
181 }
182
183 static inline void nulink_usb_init_buffer(void *handle, uint32_t size)
184 {
185 struct nulink_usb_handle_s *h = handle;
186
187 assert(handle);
188
189 h->init_buffer(handle, size);
190 }
191
192 static int nulink_usb_version(void *handle)
193 {
194 struct nulink_usb_handle_s *h = handle;
195
196 LOG_DEBUG("nulink_usb_version");
197
198 assert(handle);
199
200 nulink_usb_init_buffer(handle, V6M_MAX_COMMAND_LENGTH);
201
202 memset(h->cmdbuf + h->cmdidx, 0xFF, V6M_MAX_COMMAND_LENGTH);
203 h->cmdbuf[h->cmdidx + 4] = 0xA1; /* host_rev_num: 6561 */;
204 h->cmdbuf[h->cmdidx + 5] = 0x19;
205
206 int res = nulink_usb_xfer(handle, h->databuf, h->cmdsize);
207 if (res != ERROR_OK)
208 return res;
209
210 LOG_INFO("Nu-Link firmware_version %" PRIu32 ", product_id (0x%08" PRIx32 ")",
211 le_to_h_u32(h->databuf),
212 le_to_h_u32(h->databuf + 4 * 1));
213
214 const bool is_nulinkpro = !!(le_to_h_u32(h->databuf + 4 * 2) & 1);
215 if (is_nulinkpro) {
216 LOG_INFO("Adapter is Nu-Link-Pro, target_voltage_mv(%" PRIu16 "), usb_voltage_mv(%" PRIu16 ")",
217 le_to_h_u16(h->databuf + 4 * 3 + 0),
218 le_to_h_u16(h->databuf + 4 * 3 + 2));
219
220 h->hardware_config |= HARDWARE_CONFIG_NULINKPRO;
221 } else {
222 LOG_INFO("Adapter is Nu-Link");
223 }
224
225 return ERROR_OK;
226 }
227
228 static int nulink_usb_idcode(void *handle, uint32_t *idcode)
229 {
230 struct nulink_usb_handle_s *h = handle;
231
232 LOG_DEBUG("nulink_usb_idcode");
233
234 assert(handle);
235
236 nulink_usb_init_buffer(handle, 4 * 1);
237 /* set command ID */
238 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_CHECK_ID);
239 h->cmdidx += 4;
240
241 int res = nulink_usb_xfer(handle, h->databuf, 4 * 2);
242 if (res != ERROR_OK)
243 return res;
244
245 *idcode = le_to_h_u32(h->databuf + 4 * 1);
246
247 LOG_INFO("IDCODE: 0x%08" PRIX32, *idcode);
248
249 return ERROR_OK;
250 }
251
252 static int nulink_usb_write_debug_reg(void *handle, uint32_t addr, uint32_t val)
253 {
254 struct nulink_usb_handle_s *h = handle;
255
256 LOG_DEBUG("nulink_usb_write_debug_reg 0x%08" PRIX32 " 0x%08" PRIX32, addr, val);
257
258 nulink_usb_init_buffer(handle, 8 + 12 * 1);
259 /* set command ID */
260 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_RAM);
261 h->cmdidx += 4;
262 /* Count of registers */
263 h->cmdbuf[h->cmdidx] = 1;
264 h->cmdidx += 1;
265 /* Array of bool value (u8ReadOld) */
266 h->cmdbuf[h->cmdidx] = 0x00;
267 h->cmdidx += 1;
268 /* Array of bool value (u8Verify) */
269 h->cmdbuf[h->cmdidx] = 0x00;
270 h->cmdidx += 1;
271 /* ignore */
272 h->cmdbuf[h->cmdidx] = 0;
273 h->cmdidx += 1;
274 /* u32Addr */
275 h_u32_to_le(h->cmdbuf + h->cmdidx, addr);
276 h->cmdidx += 4;
277 /* u32Data */
278 h_u32_to_le(h->cmdbuf + h->cmdidx, val);
279 h->cmdidx += 4;
280 /* u32Mask */
281 h_u32_to_le(h->cmdbuf + h->cmdidx, 0x00000000UL);
282 h->cmdidx += 4;
283
284 return nulink_usb_xfer(handle, h->databuf, 4 * 2);
285 }
286
287 static enum target_state nulink_usb_state(void *handle)
288 {
289 struct nulink_usb_handle_s *h = handle;
290
291 assert(handle);
292
293 nulink_usb_init_buffer(handle, 4 * 1);
294 /* set command ID */
295 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_CHECK_MCU_STOP);
296 h->cmdidx += 4;
297
298 int res = nulink_usb_xfer(handle, h->databuf, 4 * 4);
299 if (res != ERROR_OK)
300 return TARGET_UNKNOWN;
301
302 if (!le_to_h_u32(h->databuf + 4 * 2))
303 return TARGET_HALTED;
304 else
305 return TARGET_RUNNING;
306 }
307
308 static int nulink_usb_assert_srst(void *handle, int srst)
309 {
310 struct nulink_usb_handle_s *h = handle;
311
312 LOG_DEBUG("nulink_usb_assert_srst");
313
314 assert(handle);
315
316 nulink_usb_init_buffer(handle, 4 * 4);
317 /* set command ID */
318 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_MCU_RESET);
319 h->cmdidx += 4;
320 /* set reset type */
321 h_u32_to_le(h->cmdbuf + h->cmdidx, RESET_SYSRESETREQ);
322 h->cmdidx += 4;
323 /* set connect type */
324 h_u32_to_le(h->cmdbuf + h->cmdidx, CONNECT_NORMAL);
325 h->cmdidx += 4;
326 /* set extMode */
327 h_u32_to_le(h->cmdbuf + h->cmdidx, 0);
328 h->cmdidx += 4;
329
330 return nulink_usb_xfer(handle, h->databuf, 4 * 4);
331 }
332
333 static int nulink_usb_reset(void *handle)
334 {
335 struct nulink_usb_handle_s *h = handle;
336
337 LOG_DEBUG("nulink_usb_reset");
338
339 assert(handle);
340
341 nulink_usb_init_buffer(handle, 4 * 4);
342 /* set command ID */
343 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_MCU_RESET);
344 h->cmdidx += 4;
345 /* set reset type */
346 h_u32_to_le(h->cmdbuf + h->cmdidx, RESET_HW);
347 h->cmdidx += 4;
348 /* set connect type */
349 h_u32_to_le(h->cmdbuf + h->cmdidx, CONNECT_NORMAL);
350 h->cmdidx += 4;
351 /* set extMode */
352 h_u32_to_le(h->cmdbuf + h->cmdidx, 0);
353 h->cmdidx += 4;
354
355 return nulink_usb_xfer(handle, h->databuf, 4 * 4);
356 }
357
358 static int nulink_usb_run(void *handle)
359 {
360 struct nulink_usb_handle_s *h = handle;
361
362 LOG_DEBUG("nulink_usb_run");
363
364 assert(handle);
365
366 nulink_usb_init_buffer(handle, 4 * 1);
367 /* set command ID */
368 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_MCU_FREE_RUN);
369 h->cmdidx += 4;
370
371 return nulink_usb_xfer(handle, h->databuf, 4 * 4);
372 }
373
374 static int nulink_usb_halt(void *handle)
375 {
376 struct nulink_usb_handle_s *h = handle;
377
378 LOG_DEBUG("nulink_usb_halt");
379
380 assert(handle);
381
382 nulink_usb_init_buffer(handle, 4 * 1);
383 /* set command ID */
384 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_MCU_STOP_RUN);
385 h->cmdidx += 4;
386
387 int res = nulink_usb_xfer(handle, h->databuf, 4 * 4);
388
389 LOG_DEBUG("Nu-Link stop_pc 0x%08" PRIx32, le_to_h_u32(h->databuf + 4));
390
391 return res;
392 }
393
394 static int nulink_usb_step(void *handle)
395 {
396 struct nulink_usb_handle_s *h = handle;
397
398 LOG_DEBUG("nulink_usb_step");
399
400 assert(handle);
401
402 nulink_usb_init_buffer(handle, 4 * 1);
403 /* set command ID */
404 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_MCU_STEP_RUN);
405 h->cmdidx += 4;
406
407 int res = nulink_usb_xfer(handle, h->databuf, 4 * 4);
408
409 LOG_DEBUG("Nu-Link pc 0x%08" PRIx32, le_to_h_u32(h->databuf + 4));
410
411 return res;
412 }
413
414 static int nulink_usb_read_reg(void *handle, unsigned int regsel, uint32_t *val)
415 {
416 struct nulink_usb_handle_s *h = handle;
417
418 assert(handle);
419
420 nulink_usb_init_buffer(handle, 8 + 12 * 1);
421 /* set command ID */
422 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_REG);
423 h->cmdidx += 4;
424 /* Count of registers */
425 h->cmdbuf[h->cmdidx] = 1;
426 h->cmdidx += 1;
427 /* Array of bool value (u8ReadOld) */
428 h->cmdbuf[h->cmdidx] = 0xFF;
429 h->cmdidx += 1;
430 /* Array of bool value (u8Verify) */
431 h->cmdbuf[h->cmdidx] = 0x00;
432 h->cmdidx += 1;
433 /* ignore */
434 h->cmdbuf[h->cmdidx] = 0;
435 h->cmdidx += 1;
436 /* u32Addr */
437 h_u32_to_le(h->cmdbuf + h->cmdidx, regsel);
438 h->cmdidx += 4;
439 /* u32Data */
440 h_u32_to_le(h->cmdbuf + h->cmdidx, 0);
441 h->cmdidx += 4;
442 /* u32Mask */
443 h_u32_to_le(h->cmdbuf + h->cmdidx, 0xFFFFFFFFUL);
444 h->cmdidx += 4;
445
446 int res = nulink_usb_xfer(handle, h->databuf, 4 * 2);
447
448 *val = le_to_h_u32(h->databuf + 4 * 1);
449
450 return res;
451 }
452
453 static int nulink_usb_write_reg(void *handle, unsigned int regsel, uint32_t val)
454 {
455 struct nulink_usb_handle_s *h = handle;
456
457 assert(handle);
458
459 nulink_usb_init_buffer(handle, 8 + 12 * 1);
460 /* set command ID */
461 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_REG);
462 h->cmdidx += 4;
463 /* Count of registers */
464 h->cmdbuf[h->cmdidx] = 1;
465 h->cmdidx += 1;
466 /* Array of bool value (u8ReadOld) */
467 h->cmdbuf[h->cmdidx] = 0x00;
468 h->cmdidx += 1;
469 /* Array of bool value (u8Verify) */
470 h->cmdbuf[h->cmdidx] = 0x00;
471 h->cmdidx += 1;
472 /* ignore */
473 h->cmdbuf[h->cmdidx] = 0;
474 h->cmdidx += 1;
475 /* u32Addr */
476 h_u32_to_le(h->cmdbuf + h->cmdidx, regsel);
477 h->cmdidx += 4;
478 /* u32Data */
479 h_u32_to_le(h->cmdbuf + h->cmdidx, val);
480 h->cmdidx += 4;
481 /* u32Mask */
482 h_u32_to_le(h->cmdbuf + h->cmdidx, 0x00000000UL);
483 h->cmdidx += 4;
484
485 return nulink_usb_xfer(handle, h->databuf, 4 * 2);
486 }
487
488 static int nulink_usb_read_mem8(void *handle, uint32_t addr, uint16_t len,
489 uint8_t *buffer)
490 {
491 int res = ERROR_OK;
492 uint32_t offset = 0;
493 uint32_t bytes_remaining = 12;
494 struct nulink_usb_handle_s *h = handle;
495
496 LOG_DEBUG("nulink_usb_read_mem8: addr 0x%08" PRIx32 ", len %" PRId16, addr, len);
497
498 assert(handle);
499
500 /* check whether data is word aligned */
501 if (addr % 4) {
502 uint32_t aligned_addr = addr / 4;
503 aligned_addr = aligned_addr * 4;
504 offset = addr - aligned_addr;
505 LOG_DEBUG("nulink_usb_read_mem8: unaligned address addr 0x%08" PRIx32
506 "/aligned addr 0x%08" PRIx32 " offset %" PRIu32,
507 addr, aligned_addr, offset);
508
509 addr = aligned_addr;
510 }
511
512 while (len) {
513 unsigned int count;
514
515 if (len < bytes_remaining)
516 bytes_remaining = len;
517
518 if (len < 4)
519 count = 1;
520 else
521 count = 2;
522
523 nulink_usb_init_buffer(handle, 8 + 12 * count);
524 /* set command ID */
525 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_RAM);
526 h->cmdidx += 4;
527 /* Count of registers */
528 h->cmdbuf[h->cmdidx] = count;
529 h->cmdidx += 1;
530 /* Array of bool value (u8ReadOld) */
531 h->cmdbuf[h->cmdidx] = 0xFF;
532 h->cmdidx += 1;
533 /* Array of bool value (u8Verify) */
534 h->cmdbuf[h->cmdidx] = 0x00;
535 h->cmdidx += 1;
536 /* ignore */
537 h->cmdbuf[h->cmdidx] = 0;
538 h->cmdidx += 1;
539
540 for (unsigned int i = 0; i < count; i++) {
541 /* u32Addr */
542 h_u32_to_le(h->cmdbuf + h->cmdidx, addr);
543 h->cmdidx += 4;
544 /* u32Data */
545 h_u32_to_le(h->cmdbuf + h->cmdidx, 0);
546 h->cmdidx += 4;
547 /* u32Mask */
548 h_u32_to_le(h->cmdbuf + h->cmdidx, 0xFFFFFFFFUL);
549 h->cmdidx += 4;
550 /* proceed to the next one */
551 addr += 4;
552 }
553
554 res = nulink_usb_xfer(handle, h->databuf, 4 * count * 2);
555 if (res != ERROR_OK)
556 break;
557
558 /* fill in the output buffer */
559 for (unsigned int i = 0; i < count; i++) {
560 if (i == 0)
561 memcpy(buffer, h->databuf + 4 + offset, len);
562 else
563 memcpy(buffer + 2 * i, h->databuf + 4 * (2 * i + 1), len - 2);
564 }
565
566 if (len >= bytes_remaining)
567 len -= bytes_remaining;
568 }
569
570 return res;
571 }
572
573 static int nulink_usb_write_mem8(void *handle, uint32_t addr, uint16_t len,
574 const uint8_t *buffer)
575 {
576 int res = ERROR_OK;
577 uint32_t offset = 0;
578 uint32_t bytes_remaining = 12;
579 struct nulink_usb_handle_s *h = handle;
580
581 LOG_DEBUG("nulink_usb_write_mem8: addr 0x%08" PRIx32 ", len %" PRIu16, addr, len);
582
583 assert(handle);
584
585 /* check whether data is word aligned */
586 if (addr % 4) {
587 uint32_t aligned_addr = addr / 4;
588 aligned_addr = aligned_addr * 4;
589 offset = addr - aligned_addr;
590 LOG_DEBUG("nulink_usb_write_mem8: address not aligned. addr(0x%08" PRIx32
591 ")/aligned_addr(0x%08" PRIx32 ")/offset(%" PRIu32 ")",
592 addr, aligned_addr, offset);
593
594 addr = aligned_addr;
595 }
596
597 while (len) {
598 unsigned int count;
599
600 if (len < bytes_remaining)
601 bytes_remaining = len;
602
603 if (len < 4)
604 count = 1;
605 else
606 count = 2;
607
608 nulink_usb_init_buffer(handle, 8 + 12 * count);
609 /* set command ID */
610 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_RAM);
611 h->cmdidx += 4;
612 /* Count of registers */
613 h->cmdbuf[h->cmdidx] = count;
614 h->cmdidx += 1;
615 /* Array of bool value (u8ReadOld) */
616 h->cmdbuf[h->cmdidx] = 0x00;
617 h->cmdidx += 1;
618 /* Array of bool value (u8Verify) */
619 h->cmdbuf[h->cmdidx] = 0x00;
620 h->cmdidx += 1;
621 /* ignore */
622 h->cmdbuf[h->cmdidx] = 0;
623 h->cmdidx += 1;
624
625 for (unsigned int i = 0; i < count; i++) {
626 /* u32Addr */
627 h_u32_to_le(h->cmdbuf + h->cmdidx, addr);
628 h->cmdidx += 4;
629 /* u32Data */
630 uint32_t u32buffer = buf_get_u32(buffer, 0, len * 8);
631 u32buffer = (u32buffer << offset * 8);
632 h_u32_to_le(h->cmdbuf + h->cmdidx, u32buffer);
633 h->cmdidx += 4;
634 /* u32Mask */
635 if (i == 0) {
636 if (offset == 0) {
637 if (len == 1) {
638 h_u32_to_le(h->cmdbuf + h->cmdidx, 0xFFFFFF00UL);
639 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFFFFFF00", i);
640 } else {
641 h_u32_to_le(h->cmdbuf + h->cmdidx, 0xFFFF0000UL);
642 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFFFF0000", i);
643 }
644 } else {
645 if (len == 1) {
646 h_u32_to_le(h->cmdbuf + h->cmdidx, 0xFF00FFFFUL);
647 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFF00FFFF", i);
648
649 } else {
650 h_u32_to_le(h->cmdbuf + h->cmdidx, 0x0000FFFFUL);
651 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0x0000FFFF", i);
652 }
653 }
654 } else {
655 if (len == 4) {
656 h_u32_to_le(h->cmdbuf + h->cmdidx, 0xFFFF0000UL);
657 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFFFF0000", i);
658 } else {
659 h_u32_to_le(h->cmdbuf + h->cmdidx, 0x00000000UL);
660 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0x00000000", i);
661 }
662 }
663 h->cmdidx += 4;
664
665 /* proceed to the next one */
666 addr += 4;
667 buffer += 4;
668 }
669
670 res = nulink_usb_xfer(handle, h->databuf, 4 * count * 2);
671 if (res != ERROR_OK)
672 break;
673
674 if (len >= bytes_remaining)
675 len -= bytes_remaining;
676 }
677
678 return res;
679 }
680
681 static int nulink_usb_read_mem32(void *handle, uint32_t addr, uint16_t len,
682 uint8_t *buffer)
683 {
684 int res = ERROR_OK;
685 uint32_t bytes_remaining = 12;
686 struct nulink_usb_handle_s *h = handle;
687
688 assert(handle);
689
690 /* data must be a multiple of 4 and word aligned */
691 if (len % 4 || addr % 4) {
692 LOG_ERROR("Invalid data alignment");
693 return ERROR_TARGET_UNALIGNED_ACCESS;
694 }
695
696 while (len) {
697 if (len < bytes_remaining)
698 bytes_remaining = len;
699
700 unsigned int count = bytes_remaining / 4;
701
702 nulink_usb_init_buffer(handle, 8 + 12 * count);
703 /* set command ID */
704 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_RAM);
705 h->cmdidx += 4;
706 /* Count of registers */
707 h->cmdbuf[h->cmdidx] = count;
708 h->cmdidx += 1;
709 /* Array of bool value (u8ReadOld) */
710 h->cmdbuf[h->cmdidx] = 0xFF;
711 h->cmdidx += 1;
712 /* Array of bool value (u8Verify) */
713 h->cmdbuf[h->cmdidx] = 0x00;
714 h->cmdidx += 1;
715 /* ignore */
716 h->cmdbuf[h->cmdidx] = 0;
717 h->cmdidx += 1;
718
719 for (unsigned int i = 0; i < count; i++) {
720 /* u32Addr */
721 h_u32_to_le(h->cmdbuf + h->cmdidx, addr);
722 h->cmdidx += 4;
723 /* u32Data */
724 h_u32_to_le(h->cmdbuf + h->cmdidx, 0);
725 h->cmdidx += 4;
726 /* u32Mask */
727 h_u32_to_le(h->cmdbuf + h->cmdidx, 0xFFFFFFFFUL);
728 h->cmdidx += 4;
729 /* proceed to the next one */
730 addr += 4;
731 }
732
733 res = nulink_usb_xfer(handle, h->databuf, 4 * count * 2);
734
735 /* fill in the output buffer */
736 for (unsigned int i = 0; i < count; i++) {
737 memcpy(buffer, h->databuf + 4 * (2 * i + 1), 4);
738 buffer += 4;
739 }
740
741 if (len >= bytes_remaining)
742 len -= bytes_remaining;
743 else
744 len = 0;
745 }
746
747 return res;
748 }
749
750 static int nulink_usb_write_mem32(void *handle, uint32_t addr, uint16_t len,
751 const uint8_t *buffer)
752 {
753 int res = ERROR_OK;
754 uint32_t bytes_remaining = 12;
755 struct nulink_usb_handle_s *h = handle;
756
757 assert(handle);
758
759 /* data must be a multiple of 4 and word aligned */
760 if (len % 4 || addr % 4) {
761 LOG_ERROR("Invalid data alignment");
762 return ERROR_TARGET_UNALIGNED_ACCESS;
763 }
764
765 while (len) {
766 if (len < bytes_remaining)
767 bytes_remaining = len;
768
769 unsigned int count = bytes_remaining / 4;
770
771 nulink_usb_init_buffer(handle, 8 + 12 * count);
772 /* set command ID */
773 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_RAM);
774 h->cmdidx += 4;
775 /* Count of registers */
776 h->cmdbuf[h->cmdidx] = count;
777 h->cmdidx += 1;
778 /* Array of bool value (u8ReadOld) */
779 h->cmdbuf[h->cmdidx] = 0x00;
780 h->cmdidx += 1;
781 /* Array of bool value (u8Verify) */
782 h->cmdbuf[h->cmdidx] = 0x00;
783 h->cmdidx += 1;
784 /* ignore */
785 h->cmdbuf[h->cmdidx] = 0;
786 h->cmdidx += 1;
787
788 for (unsigned int i = 0; i < count; i++) {
789 /* u32Addr */
790 h_u32_to_le(h->cmdbuf + h->cmdidx, addr);
791 h->cmdidx += 4;
792 /* u32Data */
793 uint32_t u32buffer = buf_get_u32(buffer, 0, 32);
794 h_u32_to_le(h->cmdbuf + h->cmdidx, u32buffer);
795 h->cmdidx += 4;
796 /* u32Mask */
797 h_u32_to_le(h->cmdbuf + h->cmdidx, 0x00000000);
798 h->cmdidx += 4;
799
800 /* proceed to the next one */
801 addr += 4;
802 buffer += 4;
803 }
804
805 res = nulink_usb_xfer(handle, h->databuf, 4 * count * 2);
806
807 if (len >= bytes_remaining)
808 len -= bytes_remaining;
809 else
810 len = 0;
811 }
812
813 return res;
814 }
815
816 static uint32_t nulink_max_block_size(uint32_t tar_autoincr_block, uint32_t address)
817 {
818 uint32_t max_tar_block = (tar_autoincr_block - ((tar_autoincr_block - 1) & address));
819
820 if (max_tar_block == 0)
821 max_tar_block = 4;
822
823 return max_tar_block;
824 }
825
826 static int nulink_usb_read_mem(void *handle, uint32_t addr, uint32_t size,
827 uint32_t count, uint8_t *buffer)
828 {
829 int retval = ERROR_OK;
830 struct nulink_usb_handle_s *h = handle;
831
832 /* calculate byte count */
833 count *= size;
834
835 while (count) {
836 uint32_t bytes_remaining = nulink_max_block_size(h->max_mem_packet, addr);
837
838 if (count < bytes_remaining)
839 bytes_remaining = count;
840
841 if (bytes_remaining >= 4)
842 size = 4;
843
844 /* the nulink only supports 8/32bit memory read/writes
845 * honour 32bit, all others will be handled as 8bit access */
846 if (size == 4) {
847 /* When in jtag mode the nulink uses the auto-increment functionality.
848 * However it expects us to pass the data correctly, this includes
849 * alignment and any page boundaries. We already do this as part of the
850 * adi_v5 implementation, but the nulink is a hla adapter and so this
851 * needs implementing manually.
852 * currently this only affects jtag mode, they do single
853 * access in SWD mode - but this may change and so we do it for both modes */
854
855 /* we first need to check for any unaligned bytes */
856 if (addr % 4) {
857 uint32_t head_bytes = 4 - (addr % 4);
858 retval = nulink_usb_read_mem8(handle, addr, head_bytes, buffer);
859 if (retval != ERROR_OK)
860 return retval;
861 buffer += head_bytes;
862 addr += head_bytes;
863 count -= head_bytes;
864 bytes_remaining -= head_bytes;
865 }
866
867 if (bytes_remaining % 4)
868 retval = nulink_usb_read_mem(handle, addr, 1, bytes_remaining, buffer);
869 else
870 retval = nulink_usb_read_mem32(handle, addr, bytes_remaining, buffer);
871 } else {
872 retval = nulink_usb_read_mem8(handle, addr, bytes_remaining, buffer);
873 }
874
875 if (retval != ERROR_OK)
876 return retval;
877
878 buffer += bytes_remaining;
879 addr += bytes_remaining;
880 count -= bytes_remaining;
881 }
882
883 return retval;
884 }
885
886 static int nulink_usb_write_mem(void *handle, uint32_t addr, uint32_t size,
887 uint32_t count, const uint8_t *buffer)
888 {
889 int retval = ERROR_OK;
890 struct nulink_usb_handle_s *h = handle;
891
892 if (addr < ARM_SRAM_BASE) {
893 LOG_DEBUG("nulink_usb_write_mem: address below ARM_SRAM_BASE, not supported.\n");
894 return retval;
895 }
896
897 /* calculate byte count */
898 count *= size;
899
900 while (count) {
901 uint32_t bytes_remaining = nulink_max_block_size(h->max_mem_packet, addr);
902
903 if (count < bytes_remaining)
904 bytes_remaining = count;
905
906 if (bytes_remaining >= 4)
907 size = 4;
908
909 /* the nulink only supports 8/32bit memory read/writes
910 * honour 32bit, all others will be handled as 8bit access */
911 if (size == 4) {
912 /* When in jtag mode the nulink uses the auto-increment functionality.
913 * However it expects us to pass the data correctly, this includes
914 * alignment and any page boundaries. We already do this as part of the
915 * adi_v5 implementation, but the nulink is a hla adapter and so this
916 * needs implementing manually.
917 * currently this only affects jtag mode, do single
918 * access in SWD mode - but this may change and so we do it for both modes */
919
920 /* we first need to check for any unaligned bytes */
921 if (addr % 4) {
922 uint32_t head_bytes = 4 - (addr % 4);
923 retval = nulink_usb_write_mem8(handle, addr, head_bytes, buffer);
924 if (retval != ERROR_OK)
925 return retval;
926 buffer += head_bytes;
927 addr += head_bytes;
928 count -= head_bytes;
929 bytes_remaining -= head_bytes;
930 }
931
932 if (bytes_remaining % 4)
933 retval = nulink_usb_write_mem(handle, addr, 1, bytes_remaining, buffer);
934 else
935 retval = nulink_usb_write_mem32(handle, addr, bytes_remaining, buffer);
936
937 } else {
938 retval = nulink_usb_write_mem8(handle, addr, bytes_remaining, buffer);
939 }
940
941 if (retval != ERROR_OK)
942 return retval;
943
944 buffer += bytes_remaining;
945 addr += bytes_remaining;
946 count -= bytes_remaining;
947 }
948
949 return retval;
950 }
951
952 static int nulink_usb_override_target(const char *targetname)
953 {
954 LOG_DEBUG("nulink_usb_override_target");
955
956 return !strcmp(targetname, "cortex_m");
957 }
958
959 static int nulink_speed(void *handle, int khz, bool query)
960 {
961 struct nulink_usb_handle_s *h = handle;
962 unsigned long max_ice_clock = khz;
963
964 LOG_DEBUG("nulink_speed: query %s", query ? "yes" : "no");
965
966 if (max_ice_clock > 12000)
967 max_ice_clock = 12000;
968 else if ((max_ice_clock == 3 * 512) || (max_ice_clock == 1500))
969 max_ice_clock = 1500;
970 else if (max_ice_clock >= 1000)
971 max_ice_clock = max_ice_clock / 1000 * 1000;
972 else
973 max_ice_clock = max_ice_clock / 100 * 100;
974
975 LOG_DEBUG("Nu-Link nulink_speed: %lu", max_ice_clock);
976
977 if (!query) {
978 nulink_usb_init_buffer(handle, 4 * 6);
979 /* set command ID */
980 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_SET_CONFIG);
981 h->cmdidx += 4;
982 /* set max SWD clock */
983 h_u32_to_le(h->cmdbuf + h->cmdidx, max_ice_clock);
984 h->cmdidx += 4;
985 /* chip type: NUC_CHIP_TYPE_GENERAL_V6M */
986 h_u32_to_le(h->cmdbuf + h->cmdidx, 0);
987 h->cmdidx += 4;
988 /* IO voltage */
989 h_u32_to_le(h->cmdbuf + h->cmdidx, 5000);
990 h->cmdidx += 4;
991 /* If supply voltage to target or not */
992 h_u32_to_le(h->cmdbuf + h->cmdidx, 0);
993 h->cmdidx += 4;
994 /* USB_FUNC_E: USB_FUNC_HID_BULK */
995 h_u32_to_le(h->cmdbuf + h->cmdidx, 2);
996 h->cmdidx += 4;
997
998 nulink_usb_xfer(handle, h->databuf, 4 * 3);
999
1000 LOG_DEBUG("nulink_speed: h->hardware_config(%" PRId16 ")", h->hardware_config);
1001 if (h->hardware_config & HARDWARE_CONFIG_NULINKPRO)
1002 LOG_INFO("Nu-Link target_voltage_mv[0](%04" PRIx16 "), target_voltage_mv[1](%04" PRIx16
1003 "), target_voltage_mv[2](%04" PRIx16 "), if_target_power_supplied(%d)",
1004 le_to_h_u16(h->databuf + 4 * 1 + 0),
1005 le_to_h_u16(h->databuf + 4 * 1 + 2),
1006 le_to_h_u16(h->databuf + 4 * 2 + 0),
1007 le_to_h_u16(h->databuf + 4 * 2 + 2) & 1);
1008 }
1009
1010 return max_ice_clock;
1011 }
1012
1013 static int nulink_usb_close(void *handle)
1014 {
1015 struct nulink_usb_handle_s *h = handle;
1016
1017 LOG_DEBUG("nulink_usb_close");
1018
1019 if (h && h->dev_handle)
1020 hid_close(h->dev_handle);
1021
1022 free(h);
1023
1024 hid_exit();
1025
1026 return ERROR_OK;
1027 }
1028
1029 static int nulink_usb_open(struct hl_interface_param_s *param, void **fd)
1030 {
1031 struct hid_device_info *devs, *cur_dev;
1032 uint16_t target_vid = 0;
1033 uint16_t target_pid = 0;
1034 wchar_t *target_serial = NULL;
1035
1036 LOG_DEBUG("nulink_usb_open");
1037
1038 if (param->transport != HL_TRANSPORT_SWD)
1039 return TARGET_UNKNOWN;
1040
1041 if (!param->vid[0] && !param->pid[0]) {
1042 LOG_ERROR("Missing vid/pid");
1043 return ERROR_FAIL;
1044 }
1045
1046 if (hid_init() != 0) {
1047 LOG_ERROR("unable to open HIDAPI");
1048 return ERROR_FAIL;
1049 }
1050
1051 struct nulink_usb_handle_s *h = calloc(1, sizeof(*h));
1052 if (!h) {
1053 LOG_ERROR("Out of memory");
1054 goto error_open;
1055 }
1056
1057 if (param->serial) {
1058 size_t len = mbstowcs(NULL, param->serial, 0);
1059
1060 target_serial = calloc(len + 1, sizeof(wchar_t));
1061 if (!target_serial) {
1062 LOG_ERROR("Out of memory");
1063 goto error_open;
1064 }
1065
1066 if (mbstowcs(target_serial, param->serial, len + 1) == (size_t)(-1)) {
1067 LOG_WARNING("unable to convert serial");
1068 free(target_serial);
1069 target_serial = NULL;
1070 }
1071 }
1072
1073 devs = hid_enumerate(0, 0);
1074 cur_dev = devs;
1075 while (cur_dev) {
1076 bool found = false;
1077
1078 for (unsigned int i = 0; param->vid[i] || param->pid[i]; i++) {
1079 if (param->vid[i] == cur_dev->vendor_id && param->pid[i] == cur_dev->product_id) {
1080 found = true;
1081 break;
1082 }
1083 }
1084
1085 if (found) {
1086 if (!target_serial)
1087 break;
1088 if (cur_dev->serial_number && wcscmp(target_serial, cur_dev->serial_number) == 0)
1089 break;
1090 }
1091
1092 cur_dev = cur_dev->next;
1093 }
1094 if (cur_dev) {
1095 target_vid = cur_dev->vendor_id;
1096 target_pid = cur_dev->product_id;
1097 }
1098
1099 hid_free_enumeration(devs);
1100
1101 if (target_vid == 0 && target_pid == 0) {
1102 LOG_ERROR("unable to find Nu-Link");
1103 goto error_open;
1104 }
1105
1106 hid_device *dev = hid_open(target_vid, target_pid, target_serial);
1107 if (!dev) {
1108 LOG_ERROR("unable to open Nu-Link device 0x%" PRIx16 ":0x%" PRIx16, target_vid, target_pid);
1109 goto error_open;
1110 }
1111
1112 h->dev_handle = dev;
1113 h->usbcmdidx = 0;
1114
1115 switch (target_pid) {
1116 case NULINK2_USB_PID1:
1117 case NULINK2_USB_PID2:
1118 h->hardware_config = HARDWARE_CONFIG_NULINK2;
1119 h->max_packet_size = NULINK2_HID_MAX_SIZE;
1120 h->init_buffer = nulink2_usb_init_buffer;
1121 h->xfer = nulink2_usb_xfer;
1122 break;
1123 default:
1124 h->hardware_config = 0;
1125 h->max_packet_size = NULINK_HID_MAX_SIZE;
1126 h->init_buffer = nulink1_usb_init_buffer;
1127 h->xfer = nulink1_usb_xfer;
1128 break;
1129 }
1130
1131 /* get the device version */
1132 h->cmdsize = 4 * 5;
1133 int err = nulink_usb_version(h);
1134 if (err != ERROR_OK) {
1135 LOG_DEBUG("nulink_usb_version failed with cmdSize(4 * 5)");
1136 h->cmdsize = 4 * 6;
1137 err = nulink_usb_version(h);
1138 if (err != ERROR_OK)
1139 LOG_DEBUG("nulink_usb_version failed with cmdSize(4 * 6)");
1140 }
1141
1142 /* SWD clock rate : 1MHz */
1143 nulink_speed(h, 1000, false);
1144
1145 /* get cpuid, so we can determine the max page size
1146 * start with a safe default */
1147 h->max_mem_packet = (1 << 10);
1148
1149 LOG_DEBUG("nulink_usb_open: we manually perform nulink_usb_reset");
1150 nulink_usb_reset(h);
1151
1152 *fd = h;
1153
1154 free(target_serial);
1155 return ERROR_OK;
1156
1157 error_open:
1158 nulink_usb_close(h);
1159 free(target_serial);
1160
1161 return ERROR_FAIL;
1162 }
1163
1164 struct hl_layout_api_s nulink_usb_layout_api = {
1165 .open = nulink_usb_open,
1166 .close = nulink_usb_close,
1167 .idcode = nulink_usb_idcode,
1168 .state = nulink_usb_state,
1169 .reset = nulink_usb_reset,
1170 .assert_srst = nulink_usb_assert_srst,
1171 .run = nulink_usb_run,
1172 .halt = nulink_usb_halt,
1173 .step = nulink_usb_step,
1174 .read_reg = nulink_usb_read_reg,
1175 .write_reg = nulink_usb_write_reg,
1176 .read_mem = nulink_usb_read_mem,
1177 .write_mem = nulink_usb_write_mem,
1178 .write_debug_reg = nulink_usb_write_debug_reg,
1179 .override_target = nulink_usb_override_target,
1180 .speed = nulink_speed,
1181 };

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)