1 /***************************************************************************
2 * Copyright (C) 2016-2017 by Nuvoton *
3 * Zale Yu <cyyu@nuvoton.com> *
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. *
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. *
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 ***************************************************************************/
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>
32 #include <target/cortex_m.h>
36 #define NULINK_READ_TIMEOUT 1000
38 #define NULINK_HID_MAX_SIZE (64)
39 #define NULINK2_HID_MAX_SIZE (1024)
40 #define V6M_MAX_COMMAND_LENGTH (NULINK_HID_MAX_SIZE - 2)
41 #define V7M_MAX_COMMAND_LENGTH (NULINK_HID_MAX_SIZE - 3)
43 #define NULINK2_USB_PID1 (0x5200)
44 #define NULINK2_USB_PID2 (0x5201)
46 struct nulink_usb_handle_s
{
47 hid_device
*dev_handle
;
48 uint16_t max_packet_size
;
52 uint8_t cmdbuf
[NULINK2_HID_MAX_SIZE
+ 1];
53 uint8_t tempbuf
[NULINK2_HID_MAX_SIZE
];
54 uint8_t databuf
[NULINK2_HID_MAX_SIZE
];
55 uint32_t max_mem_packet
;
56 uint16_t hardware_config
; /* bit 0: 1:Nu-Link-Pro, 0:Nu-Link */
58 int (*xfer
)(void *handle
, uint8_t *buf
, int size
);
59 void (*init_buffer
)(void *handle
, uint32_t size
);
63 #define CMD_READ_REG 0xB5UL
64 #define CMD_READ_RAM 0xB1UL
65 #define CMD_WRITE_REG 0xB8UL
66 #define CMD_WRITE_RAM 0xB9UL
67 #define CMD_CHECK_ID 0xA3UL
68 #define CMD_MCU_RESET 0xE2UL
69 #define CMD_CHECK_MCU_STOP 0xD8UL
70 #define CMD_MCU_STEP_RUN 0xD1UL
71 #define CMD_MCU_STOP_RUN 0xD2UL
72 #define CMD_MCU_FREE_RUN 0xD3UL
73 #define CMD_SET_CONFIG 0xA2UL
75 #define ARM_SRAM_BASE 0x20000000UL
77 #define HARDWARE_CONFIG_NULINKPRO 1
78 #define HARDWARE_CONFIG_NULINK2 2
83 RESET_SYSRESETREQ
= 2,
85 RESET_FAST_RESCUE
= 4, /* Rescue and erase the chip, need very fast speed */
89 CONNECT_NORMAL
= 0, /* Support all reset method */
90 CONNECT_PRE_RESET
= 1, /* Support all reset method */
91 CONNECT_UNDER_RESET
= 2, /* Support all reset method */
92 CONNECT_NONE
= 3, /* Support RESET_HW, (RESET_AUTO = RESET_HW) */
93 CONNECT_DISCONNECT
= 4, /* Support RESET_NONE, (RESET_AUTO = RESET_NONE) */
94 CONNECT_ICP_MODE
= 5 /* Support NUC505 ICP mode*/
97 static int nulink_usb_xfer_rw(void *handle
, uint8_t *buf
)
99 struct nulink_usb_handle_s
*h
= handle
;
103 int ret
= hid_write(h
->dev_handle
, h
->cmdbuf
, h
->max_packet_size
+ 1);
105 LOG_ERROR("hid_write");
109 ret
= hid_read_timeout(h
->dev_handle
, buf
, h
->max_packet_size
, NULINK_READ_TIMEOUT
);
111 LOG_ERROR("hid_read_timeout");
117 static int nulink1_usb_xfer(void *handle
, uint8_t *buf
, int size
)
119 struct nulink_usb_handle_s
*h
= handle
;
123 int err
= nulink_usb_xfer_rw(h
, h
->tempbuf
);
125 memcpy(buf
, h
->tempbuf
+ 2, V6M_MAX_COMMAND_LENGTH
);
130 static int nulink2_usb_xfer(void *handle
, uint8_t *buf
, int size
)
132 struct nulink_usb_handle_s
*h
= handle
;
136 int err
= nulink_usb_xfer_rw(h
, h
->tempbuf
);
138 memcpy(buf
, h
->tempbuf
+ 3, V7M_MAX_COMMAND_LENGTH
);
143 static void nulink1_usb_init_buffer(void *handle
, uint32_t size
)
145 struct nulink_usb_handle_s
*h
= handle
;
149 memset(h
->cmdbuf
, 0, h
->max_packet_size
+ 1);
150 memset(h
->tempbuf
, 0, h
->max_packet_size
);
151 memset(h
->databuf
, 0, h
->max_packet_size
);
153 h
->cmdbuf
[0] = 0; /* report number */
154 h
->cmdbuf
[1] = ++h
->usbcmdidx
& 0x7F;
159 static void nulink2_usb_init_buffer(void *handle
, uint32_t size
)
161 struct nulink_usb_handle_s
*h
= handle
;
165 memset(h
->cmdbuf
, 0, h
->max_packet_size
+ 1);
166 memset(h
->tempbuf
, 0, h
->max_packet_size
);
167 memset(h
->databuf
, 0, h
->max_packet_size
);
169 h
->cmdbuf
[0] = 0; /* report number */
170 h
->cmdbuf
[1] = ++h
->usbcmdidx
& 0x7F;
171 h_u16_to_le(h
->cmdbuf
+ 2, size
);
175 static inline int nulink_usb_xfer(void *handle
, uint8_t *buf
, int size
)
177 struct nulink_usb_handle_s
*h
= handle
;
181 return h
->xfer(handle
, buf
, size
);
184 static inline void nulink_usb_init_buffer(void *handle
, uint32_t size
)
186 struct nulink_usb_handle_s
*h
= handle
;
190 h
->init_buffer(handle
, size
);
193 static int nulink_usb_version(void *handle
)
195 struct nulink_usb_handle_s
*h
= handle
;
197 LOG_DEBUG("nulink_usb_version");
201 nulink_usb_init_buffer(handle
, V6M_MAX_COMMAND_LENGTH
);
203 memset(h
->cmdbuf
+ h
->cmdidx
, 0xFF, V6M_MAX_COMMAND_LENGTH
);
204 h
->cmdbuf
[h
->cmdidx
+ 4] = 0xA1; /* host_rev_num: 6561 */;
205 h
->cmdbuf
[h
->cmdidx
+ 5] = 0x19;
207 int res
= nulink_usb_xfer(handle
, h
->databuf
, h
->cmdsize
);
211 LOG_INFO("Nu-Link firmware_version %" PRIu32
", product_id (0x%08" PRIx32
")",
212 le_to_h_u32(h
->databuf
),
213 le_to_h_u32(h
->databuf
+ 4 * 1));
215 const bool is_nulinkpro
= !!(le_to_h_u32(h
->databuf
+ 4 * 2) & 1);
217 LOG_INFO("Adapter is Nu-Link-Pro, target_voltage_mv(%" PRIu16
"), usb_voltage_mv(%" PRIu16
")",
218 le_to_h_u16(h
->databuf
+ 4 * 3 + 0),
219 le_to_h_u16(h
->databuf
+ 4 * 3 + 2));
221 h
->hardware_config
|= HARDWARE_CONFIG_NULINKPRO
;
223 LOG_INFO("Adapter is Nu-Link");
229 static int nulink_usb_idcode(void *handle
, uint32_t *idcode
)
231 struct nulink_usb_handle_s
*h
= handle
;
233 LOG_DEBUG("nulink_usb_idcode");
237 nulink_usb_init_buffer(handle
, 4 * 1);
239 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_CHECK_ID
);
242 int res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * 2);
246 *idcode
= le_to_h_u32(h
->databuf
+ 4 * 1);
248 LOG_INFO("IDCODE: 0x%08" PRIX32
, *idcode
);
253 static int nulink_usb_write_debug_reg(void *handle
, uint32_t addr
, uint32_t val
)
255 struct nulink_usb_handle_s
*h
= handle
;
257 LOG_DEBUG("nulink_usb_write_debug_reg 0x%08" PRIX32
" 0x%08" PRIX32
, addr
, val
);
259 nulink_usb_init_buffer(handle
, 8 + 12 * 1);
261 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_RAM
);
263 /* Count of registers */
264 h
->cmdbuf
[h
->cmdidx
] = 1;
266 /* Array of bool value (u8ReadOld) */
267 h
->cmdbuf
[h
->cmdidx
] = 0x00;
269 /* Array of bool value (u8Verify) */
270 h
->cmdbuf
[h
->cmdidx
] = 0x00;
273 h
->cmdbuf
[h
->cmdidx
] = 0;
276 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, addr
);
279 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, val
);
282 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0x00000000UL
);
285 return nulink_usb_xfer(handle
, h
->databuf
, 4 * 2);
288 static enum target_state
nulink_usb_state(void *handle
)
290 struct nulink_usb_handle_s
*h
= handle
;
294 nulink_usb_init_buffer(handle
, 4 * 1);
296 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_CHECK_MCU_STOP
);
299 int res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * 4);
301 return TARGET_UNKNOWN
;
303 if (!le_to_h_u32(h
->databuf
+ 4 * 2))
304 return TARGET_HALTED
;
306 return TARGET_RUNNING
;
309 static int nulink_usb_assert_srst(void *handle
, int srst
)
311 struct nulink_usb_handle_s
*h
= handle
;
313 LOG_DEBUG("nulink_usb_assert_srst");
317 nulink_usb_init_buffer(handle
, 4 * 4);
319 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_MCU_RESET
);
322 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, RESET_SYSRESETREQ
);
324 /* set connect type */
325 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CONNECT_NORMAL
);
328 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
331 return nulink_usb_xfer(handle
, h
->databuf
, 4 * 4);
334 static int nulink_usb_reset(void *handle
)
336 struct nulink_usb_handle_s
*h
= handle
;
338 LOG_DEBUG("nulink_usb_reset");
342 nulink_usb_init_buffer(handle
, 4 * 4);
344 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_MCU_RESET
);
347 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, RESET_HW
);
349 /* set connect type */
350 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CONNECT_NORMAL
);
353 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
356 return nulink_usb_xfer(handle
, h
->databuf
, 4 * 4);
359 static int nulink_usb_run(void *handle
)
361 struct nulink_usb_handle_s
*h
= handle
;
363 LOG_DEBUG("nulink_usb_run");
367 nulink_usb_init_buffer(handle
, 4 * 1);
369 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_MCU_FREE_RUN
);
372 return nulink_usb_xfer(handle
, h
->databuf
, 4 * 4);
375 static int nulink_usb_halt(void *handle
)
377 struct nulink_usb_handle_s
*h
= handle
;
379 LOG_DEBUG("nulink_usb_halt");
383 nulink_usb_init_buffer(handle
, 4 * 1);
385 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_MCU_STOP_RUN
);
388 int res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * 4);
390 LOG_DEBUG("Nu-Link stop_pc 0x%08" PRIx32
, le_to_h_u32(h
->databuf
+ 4));
395 static int nulink_usb_step(void *handle
)
397 struct nulink_usb_handle_s
*h
= handle
;
399 LOG_DEBUG("nulink_usb_step");
403 nulink_usb_init_buffer(handle
, 4 * 1);
405 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_MCU_STEP_RUN
);
408 int res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * 4);
410 LOG_DEBUG("Nu-Link pc 0x%08" PRIx32
, le_to_h_u32(h
->databuf
+ 4));
415 static int nulink_usb_read_reg(void *handle
, unsigned int regsel
, uint32_t *val
)
417 struct nulink_usb_handle_s
*h
= handle
;
421 nulink_usb_init_buffer(handle
, 8 + 12 * 1);
423 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_REG
);
425 /* Count of registers */
426 h
->cmdbuf
[h
->cmdidx
] = 1;
428 /* Array of bool value (u8ReadOld) */
429 h
->cmdbuf
[h
->cmdidx
] = 0xFF;
431 /* Array of bool value (u8Verify) */
432 h
->cmdbuf
[h
->cmdidx
] = 0x00;
435 h
->cmdbuf
[h
->cmdidx
] = 0;
438 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, regsel
);
441 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
444 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFFFFFFFFUL
);
447 int res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * 2);
449 *val
= le_to_h_u32(h
->databuf
+ 4 * 1);
454 static int nulink_usb_write_reg(void *handle
, unsigned int regsel
, uint32_t val
)
456 struct nulink_usb_handle_s
*h
= handle
;
460 nulink_usb_init_buffer(handle
, 8 + 12 * 1);
462 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_REG
);
464 /* Count of registers */
465 h
->cmdbuf
[h
->cmdidx
] = 1;
467 /* Array of bool value (u8ReadOld) */
468 h
->cmdbuf
[h
->cmdidx
] = 0x00;
470 /* Array of bool value (u8Verify) */
471 h
->cmdbuf
[h
->cmdidx
] = 0x00;
474 h
->cmdbuf
[h
->cmdidx
] = 0;
477 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, regsel
);
480 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, val
);
483 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0x00000000UL
);
486 return nulink_usb_xfer(handle
, h
->databuf
, 4 * 2);
489 static int nulink_usb_read_mem8(void *handle
, uint32_t addr
, uint16_t len
,
494 uint32_t bytes_remaining
= 12;
495 struct nulink_usb_handle_s
*h
= handle
;
497 LOG_DEBUG("nulink_usb_read_mem8: addr 0x%08" PRIx32
", len %" PRId16
, addr
, len
);
501 /* check whether data is word aligned */
503 uint32_t aligned_addr
= addr
/ 4;
504 aligned_addr
= aligned_addr
* 4;
505 offset
= addr
- aligned_addr
;
506 LOG_DEBUG("nulink_usb_read_mem8: unaligned address addr 0x%08" PRIx32
507 "/aligned addr 0x%08" PRIx32
" offset %" PRIu32
,
508 addr
, aligned_addr
, offset
);
516 if (len
< bytes_remaining
)
517 bytes_remaining
= len
;
524 nulink_usb_init_buffer(handle
, 8 + 12 * count
);
526 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_RAM
);
528 /* Count of registers */
529 h
->cmdbuf
[h
->cmdidx
] = count
;
531 /* Array of bool value (u8ReadOld) */
532 h
->cmdbuf
[h
->cmdidx
] = 0xFF;
534 /* Array of bool value (u8Verify) */
535 h
->cmdbuf
[h
->cmdidx
] = 0x00;
538 h
->cmdbuf
[h
->cmdidx
] = 0;
541 for (unsigned int i
= 0; i
< count
; i
++) {
543 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, addr
);
546 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
549 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFFFFFFFFUL
);
551 /* proceed to the next one */
555 res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * count
* 2);
559 /* fill in the output buffer */
560 for (unsigned int i
= 0; i
< count
; i
++) {
562 memcpy(buffer
, h
->databuf
+ 4 + offset
, len
);
564 memcpy(buffer
+ 2 * i
, h
->databuf
+ 4 * (2 * i
+ 1), len
- 2);
567 if (len
>= bytes_remaining
)
568 len
-= bytes_remaining
;
574 static int nulink_usb_write_mem8(void *handle
, uint32_t addr
, uint16_t len
,
575 const uint8_t *buffer
)
579 uint32_t bytes_remaining
= 12;
580 struct nulink_usb_handle_s
*h
= handle
;
582 LOG_DEBUG("nulink_usb_write_mem8: addr 0x%08" PRIx32
", len %" PRIu16
, addr
, len
);
586 /* check whether data is word aligned */
588 uint32_t aligned_addr
= addr
/ 4;
589 aligned_addr
= aligned_addr
* 4;
590 offset
= addr
- aligned_addr
;
591 LOG_DEBUG("nulink_usb_write_mem8: address not aligned. addr(0x%08" PRIx32
592 ")/aligned_addr(0x%08" PRIx32
")/offset(%" PRIu32
")",
593 addr
, aligned_addr
, offset
);
601 if (len
< bytes_remaining
)
602 bytes_remaining
= len
;
609 nulink_usb_init_buffer(handle
, 8 + 12 * count
);
611 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_RAM
);
613 /* Count of registers */
614 h
->cmdbuf
[h
->cmdidx
] = count
;
616 /* Array of bool value (u8ReadOld) */
617 h
->cmdbuf
[h
->cmdidx
] = 0x00;
619 /* Array of bool value (u8Verify) */
620 h
->cmdbuf
[h
->cmdidx
] = 0x00;
623 h
->cmdbuf
[h
->cmdidx
] = 0;
626 for (unsigned int i
= 0; i
< count
; i
++) {
628 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, addr
);
631 uint32_t u32buffer
= buf_get_u32(buffer
, 0, len
* 8);
632 u32buffer
= (u32buffer
<< offset
* 8);
633 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, u32buffer
);
639 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFFFFFF00UL
);
640 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFFFFFF00", i
);
642 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFFFF0000UL
);
643 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFFFF0000", i
);
647 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFF00FFFFUL
);
648 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFF00FFFF", i
);
651 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0x0000FFFFUL
);
652 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0x0000FFFF", i
);
657 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFFFF0000UL
);
658 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFFFF0000", i
);
660 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0x00000000UL
);
661 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0x00000000", i
);
666 /* proceed to the next one */
671 res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * count
* 2);
675 if (len
>= bytes_remaining
)
676 len
-= bytes_remaining
;
682 static int nulink_usb_read_mem32(void *handle
, uint32_t addr
, uint16_t len
,
686 uint32_t bytes_remaining
= 12;
687 struct nulink_usb_handle_s
*h
= handle
;
691 /* data must be a multiple of 4 and word aligned */
692 if (len
% 4 || addr
% 4) {
693 LOG_ERROR("Invalid data alignment");
694 return ERROR_TARGET_UNALIGNED_ACCESS
;
698 if (len
< bytes_remaining
)
699 bytes_remaining
= len
;
701 unsigned int count
= bytes_remaining
/ 4;
703 nulink_usb_init_buffer(handle
, 8 + 12 * count
);
705 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_RAM
);
707 /* Count of registers */
708 h
->cmdbuf
[h
->cmdidx
] = count
;
710 /* Array of bool value (u8ReadOld) */
711 h
->cmdbuf
[h
->cmdidx
] = 0xFF;
713 /* Array of bool value (u8Verify) */
714 h
->cmdbuf
[h
->cmdidx
] = 0x00;
717 h
->cmdbuf
[h
->cmdidx
] = 0;
720 for (unsigned int i
= 0; i
< count
; i
++) {
722 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, addr
);
725 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
728 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFFFFFFFFUL
);
730 /* proceed to the next one */
734 res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * count
* 2);
736 /* fill in the output buffer */
737 for (unsigned int i
= 0; i
< count
; i
++) {
738 memcpy(buffer
, h
->databuf
+ 4 * (2 * i
+ 1), 4);
742 if (len
>= bytes_remaining
)
743 len
-= bytes_remaining
;
751 static int nulink_usb_write_mem32(void *handle
, uint32_t addr
, uint16_t len
,
752 const uint8_t *buffer
)
755 uint32_t bytes_remaining
= 12;
756 struct nulink_usb_handle_s
*h
= handle
;
760 /* data must be a multiple of 4 and word aligned */
761 if (len
% 4 || addr
% 4) {
762 LOG_ERROR("Invalid data alignment");
763 return ERROR_TARGET_UNALIGNED_ACCESS
;
767 if (len
< bytes_remaining
)
768 bytes_remaining
= len
;
770 unsigned int count
= bytes_remaining
/ 4;
772 nulink_usb_init_buffer(handle
, 8 + 12 * count
);
774 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_RAM
);
776 /* Count of registers */
777 h
->cmdbuf
[h
->cmdidx
] = count
;
779 /* Array of bool value (u8ReadOld) */
780 h
->cmdbuf
[h
->cmdidx
] = 0x00;
782 /* Array of bool value (u8Verify) */
783 h
->cmdbuf
[h
->cmdidx
] = 0x00;
786 h
->cmdbuf
[h
->cmdidx
] = 0;
789 for (unsigned int i
= 0; i
< count
; i
++) {
791 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, addr
);
794 uint32_t u32buffer
= buf_get_u32(buffer
, 0, 32);
795 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, u32buffer
);
798 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0x00000000);
801 /* proceed to the next one */
806 res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * count
* 2);
808 if (len
>= bytes_remaining
)
809 len
-= bytes_remaining
;
817 static uint32_t nulink_max_block_size(uint32_t tar_autoincr_block
, uint32_t address
)
819 uint32_t max_tar_block
= (tar_autoincr_block
- ((tar_autoincr_block
- 1) & address
));
821 if (max_tar_block
== 0)
824 return max_tar_block
;
827 static int nulink_usb_read_mem(void *handle
, uint32_t addr
, uint32_t size
,
828 uint32_t count
, uint8_t *buffer
)
830 int retval
= ERROR_OK
;
831 struct nulink_usb_handle_s
*h
= handle
;
833 /* calculate byte count */
837 uint32_t bytes_remaining
= nulink_max_block_size(h
->max_mem_packet
, addr
);
839 if (count
< bytes_remaining
)
840 bytes_remaining
= count
;
842 if (bytes_remaining
>= 4)
845 /* the nulink only supports 8/32bit memory read/writes
846 * honour 32bit, all others will be handled as 8bit access */
848 /* When in jtag mode the nulink uses the auto-increment functionality.
849 * However it expects us to pass the data correctly, this includes
850 * alignment and any page boundaries. We already do this as part of the
851 * adi_v5 implementation, but the nulink is a hla adapter and so this
852 * needs implementing manually.
853 * currently this only affects jtag mode, they do single
854 * access in SWD mode - but this may change and so we do it for both modes */
856 /* we first need to check for any unaligned bytes */
858 uint32_t head_bytes
= 4 - (addr
% 4);
859 retval
= nulink_usb_read_mem8(handle
, addr
, head_bytes
, buffer
);
860 if (retval
!= ERROR_OK
)
862 buffer
+= head_bytes
;
865 bytes_remaining
-= head_bytes
;
868 if (bytes_remaining
% 4)
869 retval
= nulink_usb_read_mem(handle
, addr
, 1, bytes_remaining
, buffer
);
871 retval
= nulink_usb_read_mem32(handle
, addr
, bytes_remaining
, buffer
);
873 retval
= nulink_usb_read_mem8(handle
, addr
, bytes_remaining
, buffer
);
876 if (retval
!= ERROR_OK
)
879 buffer
+= bytes_remaining
;
880 addr
+= bytes_remaining
;
881 count
-= bytes_remaining
;
887 static int nulink_usb_write_mem(void *handle
, uint32_t addr
, uint32_t size
,
888 uint32_t count
, const uint8_t *buffer
)
890 int retval
= ERROR_OK
;
891 struct nulink_usb_handle_s
*h
= handle
;
893 if (addr
< ARM_SRAM_BASE
) {
894 LOG_DEBUG("nulink_usb_write_mem: address below ARM_SRAM_BASE, not supported.\n");
898 /* calculate byte count */
902 uint32_t bytes_remaining
= nulink_max_block_size(h
->max_mem_packet
, addr
);
904 if (count
< bytes_remaining
)
905 bytes_remaining
= count
;
907 if (bytes_remaining
>= 4)
910 /* the nulink only supports 8/32bit memory read/writes
911 * honour 32bit, all others will be handled as 8bit access */
913 /* When in jtag mode the nulink uses the auto-increment functionality.
914 * However it expects us to pass the data correctly, this includes
915 * alignment and any page boundaries. We already do this as part of the
916 * adi_v5 implementation, but the nulink is a hla adapter and so this
917 * needs implementing manually.
918 * currently this only affects jtag mode, do single
919 * access in SWD mode - but this may change and so we do it for both modes */
921 /* we first need to check for any unaligned bytes */
923 uint32_t head_bytes
= 4 - (addr
% 4);
924 retval
= nulink_usb_write_mem8(handle
, addr
, head_bytes
, buffer
);
925 if (retval
!= ERROR_OK
)
927 buffer
+= head_bytes
;
930 bytes_remaining
-= head_bytes
;
933 if (bytes_remaining
% 4)
934 retval
= nulink_usb_write_mem(handle
, addr
, 1, bytes_remaining
, buffer
);
936 retval
= nulink_usb_write_mem32(handle
, addr
, bytes_remaining
, buffer
);
939 retval
= nulink_usb_write_mem8(handle
, addr
, bytes_remaining
, buffer
);
942 if (retval
!= ERROR_OK
)
945 buffer
+= bytes_remaining
;
946 addr
+= bytes_remaining
;
947 count
-= bytes_remaining
;
953 static int nulink_usb_override_target(const char *targetname
)
955 LOG_DEBUG("nulink_usb_override_target");
957 return !strcmp(targetname
, "cortex_m");
960 static int nulink_speed(void *handle
, int khz
, bool query
)
962 struct nulink_usb_handle_s
*h
= handle
;
963 unsigned long max_ice_clock
= khz
;
965 LOG_DEBUG("nulink_speed: query %s", query
? "yes" : "no");
967 if (max_ice_clock
> 12000)
968 max_ice_clock
= 12000;
969 else if ((max_ice_clock
== 3 * 512) || (max_ice_clock
== 1500))
970 max_ice_clock
= 1500;
971 else if (max_ice_clock
>= 1000)
972 max_ice_clock
= max_ice_clock
/ 1000 * 1000;
974 max_ice_clock
= max_ice_clock
/ 100 * 100;
976 LOG_DEBUG("Nu-Link nulink_speed: %lu", max_ice_clock
);
979 nulink_usb_init_buffer(handle
, 4 * 6);
981 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_SET_CONFIG
);
983 /* set max SWD clock */
984 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, max_ice_clock
);
986 /* chip type: NUC_CHIP_TYPE_GENERAL_V6M */
987 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
990 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 5000);
992 /* If supply voltage to target or not */
993 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
995 /* USB_FUNC_E: USB_FUNC_HID_BULK */
996 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 2);
999 nulink_usb_xfer(handle
, h
->databuf
, 4 * 3);
1001 LOG_DEBUG("nulink_speed: h->hardware_config(%" PRId16
")", h
->hardware_config
);
1002 if (h
->hardware_config
& HARDWARE_CONFIG_NULINKPRO
)
1003 LOG_INFO("Nu-Link target_voltage_mv[0](%04" PRIx16
"), target_voltage_mv[1](%04" PRIx16
1004 "), target_voltage_mv[2](%04" PRIx16
"), if_target_power_supplied(%d)",
1005 le_to_h_u16(h
->databuf
+ 4 * 1 + 0),
1006 le_to_h_u16(h
->databuf
+ 4 * 1 + 2),
1007 le_to_h_u16(h
->databuf
+ 4 * 2 + 0),
1008 le_to_h_u16(h
->databuf
+ 4 * 2 + 2) & 1);
1011 return max_ice_clock
;
1014 static int nulink_usb_close(void *handle
)
1016 struct nulink_usb_handle_s
*h
= handle
;
1018 LOG_DEBUG("nulink_usb_close");
1020 if (h
&& h
->dev_handle
)
1021 hid_close(h
->dev_handle
);
1030 static int nulink_usb_open(struct hl_interface_param_s
*param
, void **fd
)
1032 struct hid_device_info
*devs
, *cur_dev
;
1033 uint16_t target_vid
= 0;
1034 uint16_t target_pid
= 0;
1035 wchar_t *target_serial
= NULL
;
1037 LOG_DEBUG("nulink_usb_open");
1039 if (param
->transport
!= HL_TRANSPORT_SWD
)
1040 return TARGET_UNKNOWN
;
1042 if (!param
->vid
[0] && !param
->pid
[0]) {
1043 LOG_ERROR("Missing vid/pid");
1047 if (hid_init() != 0) {
1048 LOG_ERROR("unable to open HIDAPI");
1052 struct nulink_usb_handle_s
*h
= calloc(1, sizeof(*h
));
1054 LOG_ERROR("Out of memory");
1058 const char *serial
= adapter_get_required_serial();
1060 size_t len
= mbstowcs(NULL
, serial
, 0);
1062 target_serial
= calloc(len
+ 1, sizeof(wchar_t));
1063 if (!target_serial
) {
1064 LOG_ERROR("Out of memory");
1068 if (mbstowcs(target_serial
, serial
, len
+ 1) == (size_t)(-1)) {
1069 LOG_WARNING("unable to convert serial");
1070 free(target_serial
);
1071 target_serial
= NULL
;
1075 devs
= hid_enumerate(0, 0);
1080 for (unsigned int i
= 0; param
->vid
[i
] || param
->pid
[i
]; i
++) {
1081 if (param
->vid
[i
] == cur_dev
->vendor_id
&& param
->pid
[i
] == cur_dev
->product_id
) {
1090 if (cur_dev
->serial_number
&& wcscmp(target_serial
, cur_dev
->serial_number
) == 0)
1094 cur_dev
= cur_dev
->next
;
1097 target_vid
= cur_dev
->vendor_id
;
1098 target_pid
= cur_dev
->product_id
;
1101 hid_free_enumeration(devs
);
1103 if (target_vid
== 0 && target_pid
== 0) {
1104 LOG_ERROR("unable to find Nu-Link");
1108 hid_device
*dev
= hid_open(target_vid
, target_pid
, target_serial
);
1110 LOG_ERROR("unable to open Nu-Link device 0x%" PRIx16
":0x%" PRIx16
, target_vid
, target_pid
);
1114 h
->dev_handle
= dev
;
1117 switch (target_pid
) {
1118 case NULINK2_USB_PID1
:
1119 case NULINK2_USB_PID2
:
1120 h
->hardware_config
= HARDWARE_CONFIG_NULINK2
;
1121 h
->max_packet_size
= NULINK2_HID_MAX_SIZE
;
1122 h
->init_buffer
= nulink2_usb_init_buffer
;
1123 h
->xfer
= nulink2_usb_xfer
;
1126 h
->hardware_config
= 0;
1127 h
->max_packet_size
= NULINK_HID_MAX_SIZE
;
1128 h
->init_buffer
= nulink1_usb_init_buffer
;
1129 h
->xfer
= nulink1_usb_xfer
;
1133 /* get the device version */
1135 int err
= nulink_usb_version(h
);
1136 if (err
!= ERROR_OK
) {
1137 LOG_DEBUG("nulink_usb_version failed with cmdSize(4 * 5)");
1139 err
= nulink_usb_version(h
);
1140 if (err
!= ERROR_OK
)
1141 LOG_DEBUG("nulink_usb_version failed with cmdSize(4 * 6)");
1144 /* SWD clock rate : 1MHz */
1145 nulink_speed(h
, 1000, false);
1147 /* get cpuid, so we can determine the max page size
1148 * start with a safe default */
1149 h
->max_mem_packet
= (1 << 10);
1151 LOG_DEBUG("nulink_usb_open: we manually perform nulink_usb_reset");
1152 nulink_usb_reset(h
);
1156 free(target_serial
);
1160 nulink_usb_close(h
);
1161 free(target_serial
);
1166 struct hl_layout_api_s nulink_usb_layout_api
= {
1167 .open
= nulink_usb_open
,
1168 .close
= nulink_usb_close
,
1169 .idcode
= nulink_usb_idcode
,
1170 .state
= nulink_usb_state
,
1171 .reset
= nulink_usb_reset
,
1172 .assert_srst
= nulink_usb_assert_srst
,
1173 .run
= nulink_usb_run
,
1174 .halt
= nulink_usb_halt
,
1175 .step
= nulink_usb_step
,
1176 .read_reg
= nulink_usb_read_reg
,
1177 .write_reg
= nulink_usb_write_reg
,
1178 .read_mem
= nulink_usb_read_mem
,
1179 .write_mem
= nulink_usb_write_mem
,
1180 .write_debug_reg
= nulink_usb_write_debug_reg
,
1181 .override_target
= nulink_usb_override_target
,
1182 .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)