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

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)