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 #include "libusb_helper.h"
38 #define NULINK_READ_TIMEOUT LIBUSB_TIMEOUT_MS
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)
45 #define NULINK2_USB_PID1 (0x5200)
46 #define NULINK2_USB_PID2 (0x5201)
48 struct nulink_usb_handle_s
{
49 hid_device
*dev_handle
;
50 uint16_t max_packet_size
;
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 */
60 int (*xfer
)(void *handle
, uint8_t *buf
, int size
);
61 void (*init_buffer
)(void *handle
, uint32_t size
);
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
77 #define ARM_SRAM_BASE 0x20000000UL
79 #define HARDWARE_CONFIG_NULINKPRO 1
80 #define HARDWARE_CONFIG_NULINK2 2
85 RESET_SYSRESETREQ
= 2,
87 RESET_FAST_RESCUE
= 4, /* Rescue and erase the chip, need very fast speed */
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*/
99 static int nulink_usb_xfer_rw(void *handle
, uint8_t *buf
)
101 struct nulink_usb_handle_s
*h
= handle
;
105 int ret
= hid_write(h
->dev_handle
, h
->cmdbuf
, h
->max_packet_size
+ 1);
107 LOG_ERROR("hid_write");
111 ret
= hid_read_timeout(h
->dev_handle
, buf
, h
->max_packet_size
, NULINK_READ_TIMEOUT
);
113 LOG_ERROR("hid_read_timeout");
119 static int nulink1_usb_xfer(void *handle
, uint8_t *buf
, int size
)
121 struct nulink_usb_handle_s
*h
= handle
;
125 int err
= nulink_usb_xfer_rw(h
, h
->tempbuf
);
127 memcpy(buf
, h
->tempbuf
+ 2, V6M_MAX_COMMAND_LENGTH
);
132 static int nulink2_usb_xfer(void *handle
, uint8_t *buf
, int size
)
134 struct nulink_usb_handle_s
*h
= handle
;
138 int err
= nulink_usb_xfer_rw(h
, h
->tempbuf
);
140 memcpy(buf
, h
->tempbuf
+ 3, V7M_MAX_COMMAND_LENGTH
);
145 static void nulink1_usb_init_buffer(void *handle
, uint32_t size
)
147 struct nulink_usb_handle_s
*h
= handle
;
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
);
155 h
->cmdbuf
[0] = 0; /* report number */
156 h
->cmdbuf
[1] = ++h
->usbcmdidx
& 0x7F;
161 static void nulink2_usb_init_buffer(void *handle
, uint32_t size
)
163 struct nulink_usb_handle_s
*h
= handle
;
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
);
171 h
->cmdbuf
[0] = 0; /* report number */
172 h
->cmdbuf
[1] = ++h
->usbcmdidx
& 0x7F;
173 h_u16_to_le(h
->cmdbuf
+ 2, size
);
177 static inline int nulink_usb_xfer(void *handle
, uint8_t *buf
, int size
)
179 struct nulink_usb_handle_s
*h
= handle
;
183 return h
->xfer(handle
, buf
, size
);
186 static inline void nulink_usb_init_buffer(void *handle
, uint32_t size
)
188 struct nulink_usb_handle_s
*h
= handle
;
192 h
->init_buffer(handle
, size
);
195 static int nulink_usb_version(void *handle
)
197 struct nulink_usb_handle_s
*h
= handle
;
199 LOG_DEBUG("nulink_usb_version");
203 nulink_usb_init_buffer(handle
, V6M_MAX_COMMAND_LENGTH
);
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;
209 int res
= nulink_usb_xfer(handle
, h
->databuf
, h
->cmdsize
);
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));
217 const bool is_nulinkpro
= !!(le_to_h_u32(h
->databuf
+ 4 * 2) & 1);
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));
223 h
->hardware_config
|= HARDWARE_CONFIG_NULINKPRO
;
225 LOG_INFO("Adapter is Nu-Link");
231 static int nulink_usb_idcode(void *handle
, uint32_t *idcode
)
233 struct nulink_usb_handle_s
*h
= handle
;
235 LOG_DEBUG("nulink_usb_idcode");
239 nulink_usb_init_buffer(handle
, 4 * 1);
241 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_CHECK_ID
);
244 int res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * 2);
248 *idcode
= le_to_h_u32(h
->databuf
+ 4 * 1);
250 LOG_INFO("IDCODE: 0x%08" PRIX32
, *idcode
);
255 static int nulink_usb_write_debug_reg(void *handle
, uint32_t addr
, uint32_t val
)
257 struct nulink_usb_handle_s
*h
= handle
;
259 LOG_DEBUG("nulink_usb_write_debug_reg 0x%08" PRIX32
" 0x%08" PRIX32
, addr
, val
);
261 nulink_usb_init_buffer(handle
, 8 + 12 * 1);
263 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_RAM
);
265 /* Count of registers */
266 h
->cmdbuf
[h
->cmdidx
] = 1;
268 /* Array of bool value (u8ReadOld) */
269 h
->cmdbuf
[h
->cmdidx
] = 0x00;
271 /* Array of bool value (u8Verify) */
272 h
->cmdbuf
[h
->cmdidx
] = 0x00;
275 h
->cmdbuf
[h
->cmdidx
] = 0;
278 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, addr
);
281 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, val
);
284 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0x00000000UL
);
287 return nulink_usb_xfer(handle
, h
->databuf
, 4 * 2);
290 static enum target_state
nulink_usb_state(void *handle
)
292 struct nulink_usb_handle_s
*h
= handle
;
296 nulink_usb_init_buffer(handle
, 4 * 1);
298 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_CHECK_MCU_STOP
);
301 int res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * 4);
303 return TARGET_UNKNOWN
;
305 if (!le_to_h_u32(h
->databuf
+ 4 * 2))
306 return TARGET_HALTED
;
308 return TARGET_RUNNING
;
311 static int nulink_usb_assert_srst(void *handle
, int srst
)
313 struct nulink_usb_handle_s
*h
= handle
;
315 LOG_DEBUG("nulink_usb_assert_srst");
319 nulink_usb_init_buffer(handle
, 4 * 4);
321 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_MCU_RESET
);
324 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, RESET_SYSRESETREQ
);
326 /* set connect type */
327 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CONNECT_NORMAL
);
330 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
333 return nulink_usb_xfer(handle
, h
->databuf
, 4 * 4);
336 static int nulink_usb_reset(void *handle
)
338 struct nulink_usb_handle_s
*h
= handle
;
340 LOG_DEBUG("nulink_usb_reset");
344 nulink_usb_init_buffer(handle
, 4 * 4);
346 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_MCU_RESET
);
349 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, RESET_HW
);
351 /* set connect type */
352 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CONNECT_NORMAL
);
355 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
358 return nulink_usb_xfer(handle
, h
->databuf
, 4 * 4);
361 static int nulink_usb_run(void *handle
)
363 struct nulink_usb_handle_s
*h
= handle
;
365 LOG_DEBUG("nulink_usb_run");
369 nulink_usb_init_buffer(handle
, 4 * 1);
371 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_MCU_FREE_RUN
);
374 return nulink_usb_xfer(handle
, h
->databuf
, 4 * 4);
377 static int nulink_usb_halt(void *handle
)
379 struct nulink_usb_handle_s
*h
= handle
;
381 LOG_DEBUG("nulink_usb_halt");
385 nulink_usb_init_buffer(handle
, 4 * 1);
387 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_MCU_STOP_RUN
);
390 int res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * 4);
392 LOG_DEBUG("Nu-Link stop_pc 0x%08" PRIx32
, le_to_h_u32(h
->databuf
+ 4));
397 static int nulink_usb_step(void *handle
)
399 struct nulink_usb_handle_s
*h
= handle
;
401 LOG_DEBUG("nulink_usb_step");
405 nulink_usb_init_buffer(handle
, 4 * 1);
407 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_MCU_STEP_RUN
);
410 int res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * 4);
412 LOG_DEBUG("Nu-Link pc 0x%08" PRIx32
, le_to_h_u32(h
->databuf
+ 4));
417 static int nulink_usb_read_reg(void *handle
, unsigned int regsel
, uint32_t *val
)
419 struct nulink_usb_handle_s
*h
= handle
;
423 nulink_usb_init_buffer(handle
, 8 + 12 * 1);
425 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_REG
);
427 /* Count of registers */
428 h
->cmdbuf
[h
->cmdidx
] = 1;
430 /* Array of bool value (u8ReadOld) */
431 h
->cmdbuf
[h
->cmdidx
] = 0xFF;
433 /* Array of bool value (u8Verify) */
434 h
->cmdbuf
[h
->cmdidx
] = 0x00;
437 h
->cmdbuf
[h
->cmdidx
] = 0;
440 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, regsel
);
443 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
446 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFFFFFFFFUL
);
449 int res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * 2);
451 *val
= le_to_h_u32(h
->databuf
+ 4 * 1);
456 static int nulink_usb_write_reg(void *handle
, unsigned int regsel
, uint32_t val
)
458 struct nulink_usb_handle_s
*h
= handle
;
462 nulink_usb_init_buffer(handle
, 8 + 12 * 1);
464 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_REG
);
466 /* Count of registers */
467 h
->cmdbuf
[h
->cmdidx
] = 1;
469 /* Array of bool value (u8ReadOld) */
470 h
->cmdbuf
[h
->cmdidx
] = 0x00;
472 /* Array of bool value (u8Verify) */
473 h
->cmdbuf
[h
->cmdidx
] = 0x00;
476 h
->cmdbuf
[h
->cmdidx
] = 0;
479 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, regsel
);
482 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, val
);
485 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0x00000000UL
);
488 return nulink_usb_xfer(handle
, h
->databuf
, 4 * 2);
491 static int nulink_usb_read_mem8(void *handle
, uint32_t addr
, uint16_t len
,
496 uint32_t bytes_remaining
= 12;
497 struct nulink_usb_handle_s
*h
= handle
;
499 LOG_DEBUG("nulink_usb_read_mem8: addr 0x%08" PRIx32
", len %" PRId16
, addr
, len
);
503 /* check whether data is word aligned */
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
);
518 if (len
< bytes_remaining
)
519 bytes_remaining
= len
;
526 nulink_usb_init_buffer(handle
, 8 + 12 * count
);
528 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_RAM
);
530 /* Count of registers */
531 h
->cmdbuf
[h
->cmdidx
] = count
;
533 /* Array of bool value (u8ReadOld) */
534 h
->cmdbuf
[h
->cmdidx
] = 0xFF;
536 /* Array of bool value (u8Verify) */
537 h
->cmdbuf
[h
->cmdidx
] = 0x00;
540 h
->cmdbuf
[h
->cmdidx
] = 0;
543 for (unsigned int i
= 0; i
< count
; i
++) {
545 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, addr
);
548 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
551 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFFFFFFFFUL
);
553 /* proceed to the next one */
557 res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * count
* 2);
561 /* fill in the output buffer */
562 for (unsigned int i
= 0; i
< count
; i
++) {
564 memcpy(buffer
, h
->databuf
+ 4 + offset
, len
);
566 memcpy(buffer
+ 2 * i
, h
->databuf
+ 4 * (2 * i
+ 1), len
- 2);
569 if (len
>= bytes_remaining
)
570 len
-= bytes_remaining
;
576 static int nulink_usb_write_mem8(void *handle
, uint32_t addr
, uint16_t len
,
577 const uint8_t *buffer
)
581 uint32_t bytes_remaining
= 12;
582 struct nulink_usb_handle_s
*h
= handle
;
584 LOG_DEBUG("nulink_usb_write_mem8: addr 0x%08" PRIx32
", len %" PRIu16
, addr
, len
);
588 /* check whether data is word aligned */
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
);
603 if (len
< bytes_remaining
)
604 bytes_remaining
= len
;
611 nulink_usb_init_buffer(handle
, 8 + 12 * count
);
613 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_RAM
);
615 /* Count of registers */
616 h
->cmdbuf
[h
->cmdidx
] = count
;
618 /* Array of bool value (u8ReadOld) */
619 h
->cmdbuf
[h
->cmdidx
] = 0x00;
621 /* Array of bool value (u8Verify) */
622 h
->cmdbuf
[h
->cmdidx
] = 0x00;
625 h
->cmdbuf
[h
->cmdidx
] = 0;
628 for (unsigned int i
= 0; i
< count
; i
++) {
630 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, addr
);
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
);
641 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFFFFFF00UL
);
642 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFFFFFF00", i
);
644 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFFFF0000UL
);
645 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFFFF0000", i
);
649 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFF00FFFFUL
);
650 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFF00FFFF", i
);
653 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0x0000FFFFUL
);
654 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0x0000FFFF", i
);
659 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFFFF0000UL
);
660 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFFFF0000", i
);
662 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0x00000000UL
);
663 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0x00000000", i
);
668 /* proceed to the next one */
673 res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * count
* 2);
677 if (len
>= bytes_remaining
)
678 len
-= bytes_remaining
;
684 static int nulink_usb_read_mem32(void *handle
, uint32_t addr
, uint16_t len
,
688 uint32_t bytes_remaining
= 12;
689 struct nulink_usb_handle_s
*h
= handle
;
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
;
700 if (len
< bytes_remaining
)
701 bytes_remaining
= len
;
703 unsigned int count
= bytes_remaining
/ 4;
705 nulink_usb_init_buffer(handle
, 8 + 12 * count
);
707 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_RAM
);
709 /* Count of registers */
710 h
->cmdbuf
[h
->cmdidx
] = count
;
712 /* Array of bool value (u8ReadOld) */
713 h
->cmdbuf
[h
->cmdidx
] = 0xFF;
715 /* Array of bool value (u8Verify) */
716 h
->cmdbuf
[h
->cmdidx
] = 0x00;
719 h
->cmdbuf
[h
->cmdidx
] = 0;
722 for (unsigned int i
= 0; i
< count
; i
++) {
724 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, addr
);
727 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
730 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFFFFFFFFUL
);
732 /* proceed to the next one */
736 res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * count
* 2);
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);
744 if (len
>= bytes_remaining
)
745 len
-= bytes_remaining
;
753 static int nulink_usb_write_mem32(void *handle
, uint32_t addr
, uint16_t len
,
754 const uint8_t *buffer
)
757 uint32_t bytes_remaining
= 12;
758 struct nulink_usb_handle_s
*h
= handle
;
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
;
769 if (len
< bytes_remaining
)
770 bytes_remaining
= len
;
772 unsigned int count
= bytes_remaining
/ 4;
774 nulink_usb_init_buffer(handle
, 8 + 12 * count
);
776 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_RAM
);
778 /* Count of registers */
779 h
->cmdbuf
[h
->cmdidx
] = count
;
781 /* Array of bool value (u8ReadOld) */
782 h
->cmdbuf
[h
->cmdidx
] = 0x00;
784 /* Array of bool value (u8Verify) */
785 h
->cmdbuf
[h
->cmdidx
] = 0x00;
788 h
->cmdbuf
[h
->cmdidx
] = 0;
791 for (unsigned int i
= 0; i
< count
; i
++) {
793 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, addr
);
796 uint32_t u32buffer
= buf_get_u32(buffer
, 0, 32);
797 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, u32buffer
);
800 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0x00000000);
803 /* proceed to the next one */
808 res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * count
* 2);
810 if (len
>= bytes_remaining
)
811 len
-= bytes_remaining
;
819 static uint32_t nulink_max_block_size(uint32_t tar_autoincr_block
, uint32_t address
)
821 uint32_t max_tar_block
= (tar_autoincr_block
- ((tar_autoincr_block
- 1) & address
));
823 if (max_tar_block
== 0)
826 return max_tar_block
;
829 static int nulink_usb_read_mem(void *handle
, uint32_t addr
, uint32_t size
,
830 uint32_t count
, uint8_t *buffer
)
832 int retval
= ERROR_OK
;
833 struct nulink_usb_handle_s
*h
= handle
;
835 /* calculate byte count */
839 uint32_t bytes_remaining
= nulink_max_block_size(h
->max_mem_packet
, addr
);
841 if (count
< bytes_remaining
)
842 bytes_remaining
= count
;
844 if (bytes_remaining
>= 4)
847 /* the nulink only supports 8/32bit memory read/writes
848 * honour 32bit, all others will be handled as 8bit access */
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 */
858 /* we first need to check for any unaligned bytes */
860 uint32_t head_bytes
= 4 - (addr
% 4);
861 retval
= nulink_usb_read_mem8(handle
, addr
, head_bytes
, buffer
);
862 if (retval
!= ERROR_OK
)
864 buffer
+= head_bytes
;
867 bytes_remaining
-= head_bytes
;
870 if (bytes_remaining
% 4)
871 retval
= nulink_usb_read_mem(handle
, addr
, 1, bytes_remaining
, buffer
);
873 retval
= nulink_usb_read_mem32(handle
, addr
, bytes_remaining
, buffer
);
875 retval
= nulink_usb_read_mem8(handle
, addr
, bytes_remaining
, buffer
);
878 if (retval
!= ERROR_OK
)
881 buffer
+= bytes_remaining
;
882 addr
+= bytes_remaining
;
883 count
-= bytes_remaining
;
889 static int nulink_usb_write_mem(void *handle
, uint32_t addr
, uint32_t size
,
890 uint32_t count
, const uint8_t *buffer
)
892 int retval
= ERROR_OK
;
893 struct nulink_usb_handle_s
*h
= handle
;
895 if (addr
< ARM_SRAM_BASE
) {
896 LOG_DEBUG("nulink_usb_write_mem: address below ARM_SRAM_BASE, not supported.\n");
900 /* calculate byte count */
904 uint32_t bytes_remaining
= nulink_max_block_size(h
->max_mem_packet
, addr
);
906 if (count
< bytes_remaining
)
907 bytes_remaining
= count
;
909 if (bytes_remaining
>= 4)
912 /* the nulink only supports 8/32bit memory read/writes
913 * honour 32bit, all others will be handled as 8bit access */
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 */
923 /* we first need to check for any unaligned bytes */
925 uint32_t head_bytes
= 4 - (addr
% 4);
926 retval
= nulink_usb_write_mem8(handle
, addr
, head_bytes
, buffer
);
927 if (retval
!= ERROR_OK
)
929 buffer
+= head_bytes
;
932 bytes_remaining
-= head_bytes
;
935 if (bytes_remaining
% 4)
936 retval
= nulink_usb_write_mem(handle
, addr
, 1, bytes_remaining
, buffer
);
938 retval
= nulink_usb_write_mem32(handle
, addr
, bytes_remaining
, buffer
);
941 retval
= nulink_usb_write_mem8(handle
, addr
, bytes_remaining
, buffer
);
944 if (retval
!= ERROR_OK
)
947 buffer
+= bytes_remaining
;
948 addr
+= bytes_remaining
;
949 count
-= bytes_remaining
;
955 static int nulink_usb_override_target(const char *targetname
)
957 LOG_DEBUG("nulink_usb_override_target");
959 return !strcmp(targetname
, "cortex_m");
962 static int nulink_speed(void *handle
, int khz
, bool query
)
964 struct nulink_usb_handle_s
*h
= handle
;
965 unsigned long max_ice_clock
= khz
;
967 LOG_DEBUG("nulink_speed: query %s", query
? "yes" : "no");
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;
976 max_ice_clock
= max_ice_clock
/ 100 * 100;
978 LOG_DEBUG("Nu-Link nulink_speed: %lu", max_ice_clock
);
981 nulink_usb_init_buffer(handle
, 4 * 6);
983 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_SET_CONFIG
);
985 /* set max SWD clock */
986 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, max_ice_clock
);
988 /* chip type: NUC_CHIP_TYPE_GENERAL_V6M */
989 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
992 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 5000);
994 /* If supply voltage to target or not */
995 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
997 /* USB_FUNC_E: USB_FUNC_HID_BULK */
998 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 2);
1001 nulink_usb_xfer(handle
, h
->databuf
, 4 * 3);
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);
1013 return max_ice_clock
;
1016 static int nulink_usb_close(void *handle
)
1018 struct nulink_usb_handle_s
*h
= handle
;
1020 LOG_DEBUG("nulink_usb_close");
1022 if (h
&& h
->dev_handle
)
1023 hid_close(h
->dev_handle
);
1032 static int nulink_usb_open(struct hl_interface_param_s
*param
, void **fd
)
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
;
1039 LOG_DEBUG("nulink_usb_open");
1041 if (param
->transport
!= HL_TRANSPORT_SWD
)
1042 return TARGET_UNKNOWN
;
1044 if (!param
->vid
[0] && !param
->pid
[0]) {
1045 LOG_ERROR("Missing vid/pid");
1049 if (hid_init() != 0) {
1050 LOG_ERROR("unable to open HIDAPI");
1054 struct nulink_usb_handle_s
*h
= calloc(1, sizeof(*h
));
1056 LOG_ERROR("Out of memory");
1060 const char *serial
= adapter_get_required_serial();
1062 size_t len
= mbstowcs(NULL
, serial
, 0);
1064 target_serial
= calloc(len
+ 1, sizeof(wchar_t));
1065 if (!target_serial
) {
1066 LOG_ERROR("Out of memory");
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
;
1077 devs
= hid_enumerate(0, 0);
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
) {
1092 if (cur_dev
->serial_number
&& wcscmp(target_serial
, cur_dev
->serial_number
) == 0)
1096 cur_dev
= cur_dev
->next
;
1099 target_vid
= cur_dev
->vendor_id
;
1100 target_pid
= cur_dev
->product_id
;
1103 hid_free_enumeration(devs
);
1105 if (target_vid
== 0 && target_pid
== 0) {
1106 LOG_ERROR("unable to find Nu-Link");
1110 hid_device
*dev
= hid_open(target_vid
, target_pid
, target_serial
);
1112 LOG_ERROR("unable to open Nu-Link device 0x%" PRIx16
":0x%" PRIx16
, target_vid
, target_pid
);
1116 h
->dev_handle
= dev
;
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
;
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
;
1135 /* get the device version */
1137 int err
= nulink_usb_version(h
);
1138 if (err
!= ERROR_OK
) {
1139 LOG_DEBUG("nulink_usb_version failed with cmdSize(4 * 5)");
1141 err
= nulink_usb_version(h
);
1142 if (err
!= ERROR_OK
)
1143 LOG_DEBUG("nulink_usb_version failed with cmdSize(4 * 6)");
1146 /* SWD clock rate : 1MHz */
1147 nulink_speed(h
, 1000, false);
1149 /* get cpuid, so we can determine the max page size
1150 * start with a safe default */
1151 h
->max_mem_packet
= (1 << 10);
1153 LOG_DEBUG("nulink_usb_open: we manually perform nulink_usb_reset");
1154 nulink_usb_reset(h
);
1158 free(target_serial
);
1162 nulink_usb_close(h
);
1163 free(target_serial
);
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
,
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)