1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 /***************************************************************************
4 * Copyright (C) 2016-2017 by Nuvoton *
5 * Zale Yu <cyyu@nuvoton.com> *
6 ***************************************************************************/
12 /* project specific includes */
13 #include <helper/binarybuffer.h>
14 #include <jtag/adapter.h>
15 #include <jtag/interface.h>
16 #include <jtag/hla/hla_layout.h>
17 #include <jtag/hla/hla_transport.h>
18 #include <jtag/hla/hla_interface.h>
19 #include <target/target.h>
21 #include <target/cortex_m.h>
25 #include "libusb_helper.h"
27 #define NULINK_READ_TIMEOUT LIBUSB_TIMEOUT_MS
29 #define NULINK_HID_MAX_SIZE (64)
30 #define NULINK2_HID_MAX_SIZE (1024)
31 #define V6M_MAX_COMMAND_LENGTH (NULINK_HID_MAX_SIZE - 2)
32 #define V7M_MAX_COMMAND_LENGTH (NULINK_HID_MAX_SIZE - 3)
34 #define NULINK2_USB_PID1 (0x5200)
35 #define NULINK2_USB_PID2 (0x5201)
37 struct nulink_usb_handle_s
{
38 hid_device
*dev_handle
;
39 uint16_t max_packet_size
;
43 uint8_t cmdbuf
[NULINK2_HID_MAX_SIZE
+ 1];
44 uint8_t tempbuf
[NULINK2_HID_MAX_SIZE
];
45 uint8_t databuf
[NULINK2_HID_MAX_SIZE
];
46 uint32_t max_mem_packet
;
47 uint16_t hardware_config
; /* bit 0: 1:Nu-Link-Pro, 0:Nu-Link */
49 int (*xfer
)(void *handle
, uint8_t *buf
, int size
);
50 void (*init_buffer
)(void *handle
, uint32_t size
);
54 #define CMD_READ_REG 0xB5UL
55 #define CMD_READ_RAM 0xB1UL
56 #define CMD_WRITE_REG 0xB8UL
57 #define CMD_WRITE_RAM 0xB9UL
58 #define CMD_CHECK_ID 0xA3UL
59 #define CMD_MCU_RESET 0xE2UL
60 #define CMD_CHECK_MCU_STOP 0xD8UL
61 #define CMD_MCU_STEP_RUN 0xD1UL
62 #define CMD_MCU_STOP_RUN 0xD2UL
63 #define CMD_MCU_FREE_RUN 0xD3UL
64 #define CMD_SET_CONFIG 0xA2UL
66 #define ARM_SRAM_BASE 0x20000000UL
68 #define HARDWARE_CONFIG_NULINKPRO 1
69 #define HARDWARE_CONFIG_NULINK2 2
74 RESET_SYSRESETREQ
= 2,
76 RESET_FAST_RESCUE
= 4, /* Rescue and erase the chip, need very fast speed */
80 CONNECT_NORMAL
= 0, /* Support all reset method */
81 CONNECT_PRE_RESET
= 1, /* Support all reset method */
82 CONNECT_UNDER_RESET
= 2, /* Support all reset method */
83 CONNECT_NONE
= 3, /* Support RESET_HW, (RESET_AUTO = RESET_HW) */
84 CONNECT_DISCONNECT
= 4, /* Support RESET_NONE, (RESET_AUTO = RESET_NONE) */
85 CONNECT_ICP_MODE
= 5 /* Support NUC505 ICP mode*/
88 static int nulink_usb_xfer_rw(void *handle
, uint8_t *buf
)
90 struct nulink_usb_handle_s
*h
= handle
;
94 int ret
= hid_write(h
->dev_handle
, h
->cmdbuf
, h
->max_packet_size
+ 1);
96 LOG_ERROR("hid_write");
100 ret
= hid_read_timeout(h
->dev_handle
, buf
, h
->max_packet_size
, NULINK_READ_TIMEOUT
);
102 LOG_ERROR("hid_read_timeout");
108 static int nulink1_usb_xfer(void *handle
, uint8_t *buf
, int size
)
110 struct nulink_usb_handle_s
*h
= handle
;
114 int err
= nulink_usb_xfer_rw(h
, h
->tempbuf
);
116 memcpy(buf
, h
->tempbuf
+ 2, V6M_MAX_COMMAND_LENGTH
);
121 static int nulink2_usb_xfer(void *handle
, uint8_t *buf
, int size
)
123 struct nulink_usb_handle_s
*h
= handle
;
127 int err
= nulink_usb_xfer_rw(h
, h
->tempbuf
);
129 memcpy(buf
, h
->tempbuf
+ 3, V7M_MAX_COMMAND_LENGTH
);
134 static void nulink1_usb_init_buffer(void *handle
, uint32_t size
)
136 struct nulink_usb_handle_s
*h
= handle
;
140 memset(h
->cmdbuf
, 0, h
->max_packet_size
+ 1);
141 memset(h
->tempbuf
, 0, h
->max_packet_size
);
142 memset(h
->databuf
, 0, h
->max_packet_size
);
144 h
->cmdbuf
[0] = 0; /* report number */
145 h
->cmdbuf
[1] = ++h
->usbcmdidx
& 0x7F;
150 static void nulink2_usb_init_buffer(void *handle
, uint32_t size
)
152 struct nulink_usb_handle_s
*h
= handle
;
156 memset(h
->cmdbuf
, 0, h
->max_packet_size
+ 1);
157 memset(h
->tempbuf
, 0, h
->max_packet_size
);
158 memset(h
->databuf
, 0, h
->max_packet_size
);
160 h
->cmdbuf
[0] = 0; /* report number */
161 h
->cmdbuf
[1] = ++h
->usbcmdidx
& 0x7F;
162 h_u16_to_le(h
->cmdbuf
+ 2, size
);
166 static inline int nulink_usb_xfer(void *handle
, uint8_t *buf
, int size
)
168 struct nulink_usb_handle_s
*h
= handle
;
172 return h
->xfer(handle
, buf
, size
);
175 static inline void nulink_usb_init_buffer(void *handle
, uint32_t size
)
177 struct nulink_usb_handle_s
*h
= handle
;
181 h
->init_buffer(handle
, size
);
184 static int nulink_usb_version(void *handle
)
186 struct nulink_usb_handle_s
*h
= handle
;
188 LOG_DEBUG("nulink_usb_version");
192 nulink_usb_init_buffer(handle
, V6M_MAX_COMMAND_LENGTH
);
194 memset(h
->cmdbuf
+ h
->cmdidx
, 0xFF, V6M_MAX_COMMAND_LENGTH
);
195 h
->cmdbuf
[h
->cmdidx
+ 4] = 0xA1; /* host_rev_num: 6561 */;
196 h
->cmdbuf
[h
->cmdidx
+ 5] = 0x19;
198 int res
= nulink_usb_xfer(handle
, h
->databuf
, h
->cmdsize
);
202 LOG_INFO("Nu-Link firmware_version %" PRIu32
", product_id (0x%08" PRIx32
")",
203 le_to_h_u32(h
->databuf
),
204 le_to_h_u32(h
->databuf
+ 4 * 1));
206 const bool is_nulinkpro
= !!(le_to_h_u32(h
->databuf
+ 4 * 2) & 1);
208 LOG_INFO("Adapter is Nu-Link-Pro, target_voltage_mv(%" PRIu16
"), usb_voltage_mv(%" PRIu16
")",
209 le_to_h_u16(h
->databuf
+ 4 * 3 + 0),
210 le_to_h_u16(h
->databuf
+ 4 * 3 + 2));
212 h
->hardware_config
|= HARDWARE_CONFIG_NULINKPRO
;
214 LOG_INFO("Adapter is Nu-Link");
220 static int nulink_usb_idcode(void *handle
, uint32_t *idcode
)
222 struct nulink_usb_handle_s
*h
= handle
;
224 LOG_DEBUG("nulink_usb_idcode");
228 nulink_usb_init_buffer(handle
, 4 * 1);
230 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_CHECK_ID
);
233 int res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * 2);
237 *idcode
= le_to_h_u32(h
->databuf
+ 4 * 1);
239 LOG_INFO("IDCODE: 0x%08" PRIX32
, *idcode
);
244 static int nulink_usb_write_debug_reg(void *handle
, uint32_t addr
, uint32_t val
)
246 struct nulink_usb_handle_s
*h
= handle
;
248 LOG_DEBUG("nulink_usb_write_debug_reg 0x%08" PRIX32
" 0x%08" PRIX32
, addr
, val
);
250 nulink_usb_init_buffer(handle
, 8 + 12 * 1);
252 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_RAM
);
254 /* Count of registers */
255 h
->cmdbuf
[h
->cmdidx
] = 1;
257 /* Array of bool value (u8ReadOld) */
258 h
->cmdbuf
[h
->cmdidx
] = 0x00;
260 /* Array of bool value (u8Verify) */
261 h
->cmdbuf
[h
->cmdidx
] = 0x00;
264 h
->cmdbuf
[h
->cmdidx
] = 0;
267 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, addr
);
270 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, val
);
273 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0x00000000UL
);
276 return nulink_usb_xfer(handle
, h
->databuf
, 4 * 2);
279 static enum target_state
nulink_usb_state(void *handle
)
281 struct nulink_usb_handle_s
*h
= handle
;
285 nulink_usb_init_buffer(handle
, 4 * 1);
287 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_CHECK_MCU_STOP
);
290 int res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * 4);
292 return TARGET_UNKNOWN
;
294 if (!le_to_h_u32(h
->databuf
+ 4 * 2))
295 return TARGET_HALTED
;
297 return TARGET_RUNNING
;
300 static int nulink_usb_assert_srst(void *handle
, int srst
)
302 struct nulink_usb_handle_s
*h
= handle
;
304 LOG_DEBUG("nulink_usb_assert_srst");
308 nulink_usb_init_buffer(handle
, 4 * 4);
310 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_MCU_RESET
);
313 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, RESET_SYSRESETREQ
);
315 /* set connect type */
316 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CONNECT_NORMAL
);
319 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
322 return nulink_usb_xfer(handle
, h
->databuf
, 4 * 4);
325 static int nulink_usb_reset(void *handle
)
327 struct nulink_usb_handle_s
*h
= handle
;
329 LOG_DEBUG("nulink_usb_reset");
333 nulink_usb_init_buffer(handle
, 4 * 4);
335 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_MCU_RESET
);
338 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, RESET_HW
);
340 /* set connect type */
341 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CONNECT_NORMAL
);
344 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
347 return nulink_usb_xfer(handle
, h
->databuf
, 4 * 4);
350 static int nulink_usb_run(void *handle
)
352 struct nulink_usb_handle_s
*h
= handle
;
354 LOG_DEBUG("nulink_usb_run");
358 nulink_usb_init_buffer(handle
, 4 * 1);
360 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_MCU_FREE_RUN
);
363 return nulink_usb_xfer(handle
, h
->databuf
, 4 * 4);
366 static int nulink_usb_halt(void *handle
)
368 struct nulink_usb_handle_s
*h
= handle
;
370 LOG_DEBUG("nulink_usb_halt");
374 nulink_usb_init_buffer(handle
, 4 * 1);
376 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_MCU_STOP_RUN
);
379 int res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * 4);
381 LOG_DEBUG("Nu-Link stop_pc 0x%08" PRIx32
, le_to_h_u32(h
->databuf
+ 4));
386 static int nulink_usb_step(void *handle
)
388 struct nulink_usb_handle_s
*h
= handle
;
390 LOG_DEBUG("nulink_usb_step");
394 nulink_usb_init_buffer(handle
, 4 * 1);
396 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_MCU_STEP_RUN
);
399 int res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * 4);
401 LOG_DEBUG("Nu-Link pc 0x%08" PRIx32
, le_to_h_u32(h
->databuf
+ 4));
406 static int nulink_usb_read_reg(void *handle
, unsigned int regsel
, uint32_t *val
)
408 struct nulink_usb_handle_s
*h
= handle
;
412 nulink_usb_init_buffer(handle
, 8 + 12 * 1);
414 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_REG
);
416 /* Count of registers */
417 h
->cmdbuf
[h
->cmdidx
] = 1;
419 /* Array of bool value (u8ReadOld) */
420 h
->cmdbuf
[h
->cmdidx
] = 0xFF;
422 /* Array of bool value (u8Verify) */
423 h
->cmdbuf
[h
->cmdidx
] = 0x00;
426 h
->cmdbuf
[h
->cmdidx
] = 0;
429 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, regsel
);
432 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
435 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFFFFFFFFUL
);
438 int res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * 2);
440 *val
= le_to_h_u32(h
->databuf
+ 4 * 1);
445 static int nulink_usb_write_reg(void *handle
, unsigned int regsel
, uint32_t val
)
447 struct nulink_usb_handle_s
*h
= handle
;
451 nulink_usb_init_buffer(handle
, 8 + 12 * 1);
453 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_REG
);
455 /* Count of registers */
456 h
->cmdbuf
[h
->cmdidx
] = 1;
458 /* Array of bool value (u8ReadOld) */
459 h
->cmdbuf
[h
->cmdidx
] = 0x00;
461 /* Array of bool value (u8Verify) */
462 h
->cmdbuf
[h
->cmdidx
] = 0x00;
465 h
->cmdbuf
[h
->cmdidx
] = 0;
468 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, regsel
);
471 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, val
);
474 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0x00000000UL
);
477 return nulink_usb_xfer(handle
, h
->databuf
, 4 * 2);
480 static int nulink_usb_read_mem8(void *handle
, uint32_t addr
, uint16_t len
,
485 uint32_t bytes_remaining
= 12;
486 struct nulink_usb_handle_s
*h
= handle
;
488 LOG_DEBUG("nulink_usb_read_mem8: addr 0x%08" PRIx32
", len %" PRId16
, addr
, len
);
492 /* check whether data is word aligned */
494 uint32_t aligned_addr
= addr
/ 4;
495 aligned_addr
= aligned_addr
* 4;
496 offset
= addr
- aligned_addr
;
497 LOG_DEBUG("nulink_usb_read_mem8: unaligned address addr 0x%08" PRIx32
498 "/aligned addr 0x%08" PRIx32
" offset %" PRIu32
,
499 addr
, aligned_addr
, offset
);
507 if (len
< bytes_remaining
)
508 bytes_remaining
= len
;
515 nulink_usb_init_buffer(handle
, 8 + 12 * count
);
517 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_RAM
);
519 /* Count of registers */
520 h
->cmdbuf
[h
->cmdidx
] = count
;
522 /* Array of bool value (u8ReadOld) */
523 h
->cmdbuf
[h
->cmdidx
] = 0xFF;
525 /* Array of bool value (u8Verify) */
526 h
->cmdbuf
[h
->cmdidx
] = 0x00;
529 h
->cmdbuf
[h
->cmdidx
] = 0;
532 for (unsigned int i
= 0; i
< count
; i
++) {
534 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, addr
);
537 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
540 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFFFFFFFFUL
);
542 /* proceed to the next one */
546 res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * count
* 2);
550 /* fill in the output buffer */
551 for (unsigned int i
= 0; i
< count
; i
++) {
553 memcpy(buffer
, h
->databuf
+ 4 + offset
, len
);
555 memcpy(buffer
+ 2 * i
, h
->databuf
+ 4 * (2 * i
+ 1), len
- 2);
558 if (len
>= bytes_remaining
)
559 len
-= bytes_remaining
;
565 static int nulink_usb_write_mem8(void *handle
, uint32_t addr
, uint16_t len
,
566 const uint8_t *buffer
)
570 uint32_t bytes_remaining
= 12;
571 struct nulink_usb_handle_s
*h
= handle
;
573 LOG_DEBUG("nulink_usb_write_mem8: addr 0x%08" PRIx32
", len %" PRIu16
, addr
, len
);
577 /* check whether data is word aligned */
579 uint32_t aligned_addr
= addr
/ 4;
580 aligned_addr
= aligned_addr
* 4;
581 offset
= addr
- aligned_addr
;
582 LOG_DEBUG("nulink_usb_write_mem8: address not aligned. addr(0x%08" PRIx32
583 ")/aligned_addr(0x%08" PRIx32
")/offset(%" PRIu32
")",
584 addr
, aligned_addr
, offset
);
592 if (len
< bytes_remaining
)
593 bytes_remaining
= len
;
600 nulink_usb_init_buffer(handle
, 8 + 12 * count
);
602 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_RAM
);
604 /* Count of registers */
605 h
->cmdbuf
[h
->cmdidx
] = count
;
607 /* Array of bool value (u8ReadOld) */
608 h
->cmdbuf
[h
->cmdidx
] = 0x00;
610 /* Array of bool value (u8Verify) */
611 h
->cmdbuf
[h
->cmdidx
] = 0x00;
614 h
->cmdbuf
[h
->cmdidx
] = 0;
617 for (unsigned int i
= 0; i
< count
; i
++) {
619 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, addr
);
622 uint32_t u32buffer
= buf_get_u32(buffer
, 0, len
* 8);
623 u32buffer
= (u32buffer
<< offset
* 8);
624 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, u32buffer
);
630 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFFFFFF00UL
);
631 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFFFFFF00", i
);
633 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFFFF0000UL
);
634 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFFFF0000", i
);
638 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFF00FFFFUL
);
639 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFF00FFFF", i
);
642 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0x0000FFFFUL
);
643 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0x0000FFFF", i
);
648 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFFFF0000UL
);
649 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFFFF0000", i
);
651 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0x00000000UL
);
652 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0x00000000", i
);
657 /* proceed to the next one */
662 res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * count
* 2);
666 if (len
>= bytes_remaining
)
667 len
-= bytes_remaining
;
673 static int nulink_usb_read_mem32(void *handle
, uint32_t addr
, uint16_t len
,
677 uint32_t bytes_remaining
= 12;
678 struct nulink_usb_handle_s
*h
= handle
;
682 /* data must be a multiple of 4 and word aligned */
683 if (len
% 4 || addr
% 4) {
684 LOG_ERROR("Invalid data alignment");
685 return ERROR_TARGET_UNALIGNED_ACCESS
;
689 if (len
< bytes_remaining
)
690 bytes_remaining
= len
;
692 unsigned int count
= bytes_remaining
/ 4;
694 nulink_usb_init_buffer(handle
, 8 + 12 * count
);
696 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_RAM
);
698 /* Count of registers */
699 h
->cmdbuf
[h
->cmdidx
] = count
;
701 /* Array of bool value (u8ReadOld) */
702 h
->cmdbuf
[h
->cmdidx
] = 0xFF;
704 /* Array of bool value (u8Verify) */
705 h
->cmdbuf
[h
->cmdidx
] = 0x00;
708 h
->cmdbuf
[h
->cmdidx
] = 0;
711 for (unsigned int i
= 0; i
< count
; i
++) {
713 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, addr
);
716 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
719 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFFFFFFFFUL
);
721 /* proceed to the next one */
725 res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * count
* 2);
727 /* fill in the output buffer */
728 for (unsigned int i
= 0; i
< count
; i
++) {
729 memcpy(buffer
, h
->databuf
+ 4 * (2 * i
+ 1), 4);
733 if (len
>= bytes_remaining
)
734 len
-= bytes_remaining
;
742 static int nulink_usb_write_mem32(void *handle
, uint32_t addr
, uint16_t len
,
743 const uint8_t *buffer
)
746 uint32_t bytes_remaining
= 12;
747 struct nulink_usb_handle_s
*h
= handle
;
751 /* data must be a multiple of 4 and word aligned */
752 if (len
% 4 || addr
% 4) {
753 LOG_ERROR("Invalid data alignment");
754 return ERROR_TARGET_UNALIGNED_ACCESS
;
758 if (len
< bytes_remaining
)
759 bytes_remaining
= len
;
761 unsigned int count
= bytes_remaining
/ 4;
763 nulink_usb_init_buffer(handle
, 8 + 12 * count
);
765 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_RAM
);
767 /* Count of registers */
768 h
->cmdbuf
[h
->cmdidx
] = count
;
770 /* Array of bool value (u8ReadOld) */
771 h
->cmdbuf
[h
->cmdidx
] = 0x00;
773 /* Array of bool value (u8Verify) */
774 h
->cmdbuf
[h
->cmdidx
] = 0x00;
777 h
->cmdbuf
[h
->cmdidx
] = 0;
780 for (unsigned int i
= 0; i
< count
; i
++) {
782 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, addr
);
785 uint32_t u32buffer
= buf_get_u32(buffer
, 0, 32);
786 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, u32buffer
);
789 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0x00000000);
792 /* proceed to the next one */
797 res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * count
* 2);
799 if (len
>= bytes_remaining
)
800 len
-= bytes_remaining
;
808 static uint32_t nulink_max_block_size(uint32_t tar_autoincr_block
, uint32_t address
)
810 uint32_t max_tar_block
= (tar_autoincr_block
- ((tar_autoincr_block
- 1) & address
));
812 if (max_tar_block
== 0)
815 return max_tar_block
;
818 static int nulink_usb_read_mem(void *handle
, uint32_t addr
, uint32_t size
,
819 uint32_t count
, uint8_t *buffer
)
821 int retval
= ERROR_OK
;
822 struct nulink_usb_handle_s
*h
= handle
;
824 /* calculate byte count */
828 uint32_t bytes_remaining
= nulink_max_block_size(h
->max_mem_packet
, addr
);
830 if (count
< bytes_remaining
)
831 bytes_remaining
= count
;
833 if (bytes_remaining
>= 4)
836 /* the nulink only supports 8/32bit memory read/writes
837 * honour 32bit, all others will be handled as 8bit access */
839 /* When in jtag mode the nulink uses the auto-increment functionality.
840 * However it expects us to pass the data correctly, this includes
841 * alignment and any page boundaries. We already do this as part of the
842 * adi_v5 implementation, but the nulink is a hla adapter and so this
843 * needs implementing manually.
844 * currently this only affects jtag mode, they do single
845 * access in SWD mode - but this may change and so we do it for both modes */
847 /* we first need to check for any unaligned bytes */
849 uint32_t head_bytes
= 4 - (addr
% 4);
850 retval
= nulink_usb_read_mem8(handle
, addr
, head_bytes
, buffer
);
851 if (retval
!= ERROR_OK
)
853 buffer
+= head_bytes
;
856 bytes_remaining
-= head_bytes
;
859 if (bytes_remaining
% 4)
860 retval
= nulink_usb_read_mem(handle
, addr
, 1, bytes_remaining
, buffer
);
862 retval
= nulink_usb_read_mem32(handle
, addr
, bytes_remaining
, buffer
);
864 retval
= nulink_usb_read_mem8(handle
, addr
, bytes_remaining
, buffer
);
867 if (retval
!= ERROR_OK
)
870 buffer
+= bytes_remaining
;
871 addr
+= bytes_remaining
;
872 count
-= bytes_remaining
;
878 static int nulink_usb_write_mem(void *handle
, uint32_t addr
, uint32_t size
,
879 uint32_t count
, const uint8_t *buffer
)
881 int retval
= ERROR_OK
;
882 struct nulink_usb_handle_s
*h
= handle
;
884 if (addr
< ARM_SRAM_BASE
) {
885 LOG_DEBUG("nulink_usb_write_mem: address below ARM_SRAM_BASE, not supported.\n");
889 /* calculate byte count */
893 uint32_t bytes_remaining
= nulink_max_block_size(h
->max_mem_packet
, addr
);
895 if (count
< bytes_remaining
)
896 bytes_remaining
= count
;
898 if (bytes_remaining
>= 4)
901 /* the nulink only supports 8/32bit memory read/writes
902 * honour 32bit, all others will be handled as 8bit access */
904 /* When in jtag mode the nulink uses the auto-increment functionality.
905 * However it expects us to pass the data correctly, this includes
906 * alignment and any page boundaries. We already do this as part of the
907 * adi_v5 implementation, but the nulink is a hla adapter and so this
908 * needs implementing manually.
909 * currently this only affects jtag mode, do single
910 * access in SWD mode - but this may change and so we do it for both modes */
912 /* we first need to check for any unaligned bytes */
914 uint32_t head_bytes
= 4 - (addr
% 4);
915 retval
= nulink_usb_write_mem8(handle
, addr
, head_bytes
, buffer
);
916 if (retval
!= ERROR_OK
)
918 buffer
+= head_bytes
;
921 bytes_remaining
-= head_bytes
;
924 if (bytes_remaining
% 4)
925 retval
= nulink_usb_write_mem(handle
, addr
, 1, bytes_remaining
, buffer
);
927 retval
= nulink_usb_write_mem32(handle
, addr
, bytes_remaining
, buffer
);
930 retval
= nulink_usb_write_mem8(handle
, addr
, bytes_remaining
, buffer
);
933 if (retval
!= ERROR_OK
)
936 buffer
+= bytes_remaining
;
937 addr
+= bytes_remaining
;
938 count
-= bytes_remaining
;
944 static int nulink_usb_override_target(const char *targetname
)
946 LOG_DEBUG("nulink_usb_override_target");
948 return !strcmp(targetname
, "cortex_m");
951 static int nulink_speed(void *handle
, int khz
, bool query
)
953 struct nulink_usb_handle_s
*h
= handle
;
954 unsigned long max_ice_clock
= khz
;
956 LOG_DEBUG("nulink_speed: query %s", query
? "yes" : "no");
958 if (max_ice_clock
> 12000)
959 max_ice_clock
= 12000;
960 else if ((max_ice_clock
== 3 * 512) || (max_ice_clock
== 1500))
961 max_ice_clock
= 1500;
962 else if (max_ice_clock
>= 1000)
963 max_ice_clock
= max_ice_clock
/ 1000 * 1000;
965 max_ice_clock
= max_ice_clock
/ 100 * 100;
967 LOG_DEBUG("Nu-Link nulink_speed: %lu", max_ice_clock
);
970 nulink_usb_init_buffer(handle
, 4 * 6);
972 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_SET_CONFIG
);
974 /* set max SWD clock */
975 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, max_ice_clock
);
977 /* chip type: NUC_CHIP_TYPE_GENERAL_V6M */
978 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
981 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 5000);
983 /* If supply voltage to target or not */
984 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
986 /* USB_FUNC_E: USB_FUNC_HID_BULK */
987 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 2);
990 nulink_usb_xfer(handle
, h
->databuf
, 4 * 3);
992 LOG_DEBUG("nulink_speed: h->hardware_config(%" PRId16
")", h
->hardware_config
);
993 if (h
->hardware_config
& HARDWARE_CONFIG_NULINKPRO
)
994 LOG_INFO("Nu-Link target_voltage_mv[0](%04" PRIx16
"), target_voltage_mv[1](%04" PRIx16
995 "), target_voltage_mv[2](%04" PRIx16
"), if_target_power_supplied(%d)",
996 le_to_h_u16(h
->databuf
+ 4 * 1 + 0),
997 le_to_h_u16(h
->databuf
+ 4 * 1 + 2),
998 le_to_h_u16(h
->databuf
+ 4 * 2 + 0),
999 le_to_h_u16(h
->databuf
+ 4 * 2 + 2) & 1);
1002 return max_ice_clock
;
1005 static int nulink_usb_close(void *handle
)
1007 struct nulink_usb_handle_s
*h
= handle
;
1009 LOG_DEBUG("nulink_usb_close");
1011 if (h
&& h
->dev_handle
)
1012 hid_close(h
->dev_handle
);
1021 static int nulink_usb_open(struct hl_interface_param_s
*param
, void **fd
)
1023 struct hid_device_info
*devs
, *cur_dev
;
1024 uint16_t target_vid
= 0;
1025 uint16_t target_pid
= 0;
1026 wchar_t *target_serial
= NULL
;
1028 LOG_DEBUG("nulink_usb_open");
1030 if (param
->transport
!= HL_TRANSPORT_SWD
)
1031 return TARGET_UNKNOWN
;
1033 if (!param
->vid
[0] && !param
->pid
[0]) {
1034 LOG_ERROR("Missing vid/pid");
1038 if (hid_init() != 0) {
1039 LOG_ERROR("unable to open HIDAPI");
1043 struct nulink_usb_handle_s
*h
= calloc(1, sizeof(*h
));
1045 LOG_ERROR("Out of memory");
1049 const char *serial
= adapter_get_required_serial();
1051 size_t len
= mbstowcs(NULL
, serial
, 0);
1053 target_serial
= calloc(len
+ 1, sizeof(wchar_t));
1054 if (!target_serial
) {
1055 LOG_ERROR("Out of memory");
1059 if (mbstowcs(target_serial
, serial
, len
+ 1) == (size_t)(-1)) {
1060 LOG_WARNING("unable to convert serial");
1061 free(target_serial
);
1062 target_serial
= NULL
;
1066 devs
= hid_enumerate(0, 0);
1071 for (unsigned int i
= 0; param
->vid
[i
] || param
->pid
[i
]; i
++) {
1072 if (param
->vid
[i
] == cur_dev
->vendor_id
&& param
->pid
[i
] == cur_dev
->product_id
) {
1081 if (cur_dev
->serial_number
&& wcscmp(target_serial
, cur_dev
->serial_number
) == 0)
1085 cur_dev
= cur_dev
->next
;
1088 target_vid
= cur_dev
->vendor_id
;
1089 target_pid
= cur_dev
->product_id
;
1092 hid_free_enumeration(devs
);
1094 if (target_vid
== 0 && target_pid
== 0) {
1095 LOG_ERROR("unable to find Nu-Link");
1099 hid_device
*dev
= hid_open(target_vid
, target_pid
, target_serial
);
1101 LOG_ERROR("unable to open Nu-Link device 0x%" PRIx16
":0x%" PRIx16
, target_vid
, target_pid
);
1105 h
->dev_handle
= dev
;
1108 switch (target_pid
) {
1109 case NULINK2_USB_PID1
:
1110 case NULINK2_USB_PID2
:
1111 h
->hardware_config
= HARDWARE_CONFIG_NULINK2
;
1112 h
->max_packet_size
= NULINK2_HID_MAX_SIZE
;
1113 h
->init_buffer
= nulink2_usb_init_buffer
;
1114 h
->xfer
= nulink2_usb_xfer
;
1117 h
->hardware_config
= 0;
1118 h
->max_packet_size
= NULINK_HID_MAX_SIZE
;
1119 h
->init_buffer
= nulink1_usb_init_buffer
;
1120 h
->xfer
= nulink1_usb_xfer
;
1124 /* get the device version */
1126 int err
= nulink_usb_version(h
);
1127 if (err
!= ERROR_OK
) {
1128 LOG_DEBUG("nulink_usb_version failed with cmdSize(4 * 5)");
1130 err
= nulink_usb_version(h
);
1131 if (err
!= ERROR_OK
)
1132 LOG_DEBUG("nulink_usb_version failed with cmdSize(4 * 6)");
1135 /* SWD clock rate : 1MHz */
1136 nulink_speed(h
, 1000, false);
1138 /* get cpuid, so we can determine the max page size
1139 * start with a safe default */
1140 h
->max_mem_packet
= (1 << 10);
1142 LOG_DEBUG("nulink_usb_open: we manually perform nulink_usb_reset");
1143 nulink_usb_reset(h
);
1147 free(target_serial
);
1151 nulink_usb_close(h
);
1152 free(target_serial
);
1157 struct hl_layout_api_s nulink_usb_layout_api
= {
1158 .open
= nulink_usb_open
,
1159 .close
= nulink_usb_close
,
1160 .idcode
= nulink_usb_idcode
,
1161 .state
= nulink_usb_state
,
1162 .reset
= nulink_usb_reset
,
1163 .assert_srst
= nulink_usb_assert_srst
,
1164 .run
= nulink_usb_run
,
1165 .halt
= nulink_usb_halt
,
1166 .step
= nulink_usb_step
,
1167 .read_reg
= nulink_usb_read_reg
,
1168 .write_reg
= nulink_usb_write_reg
,
1169 .read_mem
= nulink_usb_read_mem
,
1170 .write_mem
= nulink_usb_write_mem
,
1171 .write_debug_reg
= nulink_usb_write_debug_reg
,
1172 .override_target
= nulink_usb_override_target
,
1173 .speed
= nulink_speed
,
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)