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/interface.h>
26 #include <jtag/hla/hla_layout.h>
27 #include <jtag/hla/hla_transport.h>
28 #include <jtag/hla/hla_interface.h>
29 #include <target/target.h>
31 #include <target/cortex_m.h>
35 #define NULINK_READ_TIMEOUT 1000
37 #define NULINK_HID_MAX_SIZE (64)
38 #define NULINK2_HID_MAX_SIZE (1024)
39 #define V6M_MAX_COMMAND_LENGTH (NULINK_HID_MAX_SIZE - 2)
40 #define V7M_MAX_COMMAND_LENGTH (NULINK_HID_MAX_SIZE - 3)
42 #define NULINK2_USB_PID1 (0x5200)
43 #define NULINK2_USB_PID2 (0x5201)
45 struct nulink_usb_handle_s
{
46 hid_device
*dev_handle
;
47 uint16_t max_packet_size
;
51 uint8_t cmdbuf
[NULINK2_HID_MAX_SIZE
+ 1];
52 uint8_t tempbuf
[NULINK2_HID_MAX_SIZE
];
53 uint8_t databuf
[NULINK2_HID_MAX_SIZE
];
54 uint32_t max_mem_packet
;
55 uint16_t hardware_config
; /* bit 0: 1:Nu-Link-Pro, 0:Nu-Link */
57 int (*xfer
)(void *handle
, uint8_t *buf
, int size
);
58 void (*init_buffer
)(void *handle
, uint32_t size
);
62 #define CMD_READ_REG 0xB5UL
63 #define CMD_READ_RAM 0xB1UL
64 #define CMD_WRITE_REG 0xB8UL
65 #define CMD_WRITE_RAM 0xB9UL
66 #define CMD_CHECK_ID 0xA3UL
67 #define CMD_MCU_RESET 0xE2UL
68 #define CMD_CHECK_MCU_STOP 0xD8UL
69 #define CMD_MCU_STEP_RUN 0xD1UL
70 #define CMD_MCU_STOP_RUN 0xD2UL
71 #define CMD_MCU_FREE_RUN 0xD3UL
72 #define CMD_SET_CONFIG 0xA2UL
74 #define ARM_SRAM_BASE 0x20000000UL
76 #define HARDWARE_CONFIG_NULINKPRO 1
77 #define HARDWARE_CONFIG_NULINK2 2
82 RESET_SYSRESETREQ
= 2,
84 RESET_FAST_RESCUE
= 4, /* Rescue and erase the chip, need very fast speed */
88 CONNECT_NORMAL
= 0, /* Support all reset method */
89 CONNECT_PRE_RESET
= 1, /* Support all reset method */
90 CONNECT_UNDER_RESET
= 2, /* Support all reset method */
91 CONNECT_NONE
= 3, /* Support RESET_HW, (RESET_AUTO = RESET_HW) */
92 CONNECT_DISCONNECT
= 4, /* Support RESET_NONE, (RESET_AUTO = RESET_NONE) */
93 CONNECT_ICP_MODE
= 5 /* Support NUC505 ICP mode*/
96 static int nulink_usb_xfer_rw(void *handle
, uint8_t *buf
)
98 struct nulink_usb_handle_s
*h
= handle
;
102 int ret
= hid_write(h
->dev_handle
, h
->cmdbuf
, h
->max_packet_size
+ 1);
104 LOG_ERROR("hid_write");
108 ret
= hid_read_timeout(h
->dev_handle
, buf
, h
->max_packet_size
, NULINK_READ_TIMEOUT
);
110 LOG_ERROR("hid_read_timeout");
116 static int nulink1_usb_xfer(void *handle
, uint8_t *buf
, int size
)
118 struct nulink_usb_handle_s
*h
= handle
;
122 int err
= nulink_usb_xfer_rw(h
, h
->tempbuf
);
124 memcpy(buf
, h
->tempbuf
+ 2, V6M_MAX_COMMAND_LENGTH
);
129 static int nulink2_usb_xfer(void *handle
, uint8_t *buf
, int size
)
131 struct nulink_usb_handle_s
*h
= handle
;
135 int err
= nulink_usb_xfer_rw(h
, h
->tempbuf
);
137 memcpy(buf
, h
->tempbuf
+ 3, V7M_MAX_COMMAND_LENGTH
);
142 static void nulink1_usb_init_buffer(void *handle
, uint32_t size
)
144 struct nulink_usb_handle_s
*h
= handle
;
148 memset(h
->cmdbuf
, 0, h
->max_packet_size
+ 1);
149 memset(h
->tempbuf
, 0, h
->max_packet_size
);
150 memset(h
->databuf
, 0, h
->max_packet_size
);
152 h
->cmdbuf
[0] = 0; /* report number */
153 h
->cmdbuf
[1] = ++h
->usbcmdidx
& 0x7F;
158 static void nulink2_usb_init_buffer(void *handle
, uint32_t size
)
160 struct nulink_usb_handle_s
*h
= handle
;
164 memset(h
->cmdbuf
, 0, h
->max_packet_size
+ 1);
165 memset(h
->tempbuf
, 0, h
->max_packet_size
);
166 memset(h
->databuf
, 0, h
->max_packet_size
);
168 h
->cmdbuf
[0] = 0; /* report number */
169 h
->cmdbuf
[1] = ++h
->usbcmdidx
& 0x7F;
170 h_u16_to_le(h
->cmdbuf
+ 2, size
);
174 static inline int nulink_usb_xfer(void *handle
, uint8_t *buf
, int size
)
176 struct nulink_usb_handle_s
*h
= handle
;
180 return h
->xfer(handle
, buf
, size
);
183 static inline void nulink_usb_init_buffer(void *handle
, uint32_t size
)
185 struct nulink_usb_handle_s
*h
= handle
;
189 h
->init_buffer(handle
, size
);
192 static int nulink_usb_version(void *handle
)
194 struct nulink_usb_handle_s
*h
= handle
;
196 LOG_DEBUG("nulink_usb_version");
200 nulink_usb_init_buffer(handle
, V6M_MAX_COMMAND_LENGTH
);
202 memset(h
->cmdbuf
+ h
->cmdidx
, 0xFF, V6M_MAX_COMMAND_LENGTH
);
203 h
->cmdbuf
[h
->cmdidx
+ 4] = 0xA1; /* host_rev_num: 6561 */;
204 h
->cmdbuf
[h
->cmdidx
+ 5] = 0x19;
206 int res
= nulink_usb_xfer(handle
, h
->databuf
, h
->cmdsize
);
210 LOG_INFO("Nu-Link firmware_version %" PRIu32
", product_id (0x%08" PRIx32
")",
211 le_to_h_u32(h
->databuf
),
212 le_to_h_u32(h
->databuf
+ 4 * 1));
214 const bool is_nulinkpro
= !!(le_to_h_u32(h
->databuf
+ 4 * 2) & 1);
216 LOG_INFO("Adapter is Nu-Link-Pro, target_voltage_mv(%" PRIu16
"), usb_voltage_mv(%" PRIu16
")",
217 le_to_h_u16(h
->databuf
+ 4 * 3 + 0),
218 le_to_h_u16(h
->databuf
+ 4 * 3 + 2));
220 h
->hardware_config
|= HARDWARE_CONFIG_NULINKPRO
;
222 LOG_INFO("Adapter is Nu-Link");
228 static int nulink_usb_idcode(void *handle
, uint32_t *idcode
)
230 struct nulink_usb_handle_s
*h
= handle
;
232 LOG_DEBUG("nulink_usb_idcode");
236 nulink_usb_init_buffer(handle
, 4 * 1);
238 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_CHECK_ID
);
241 int res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * 2);
245 *idcode
= le_to_h_u32(h
->databuf
+ 4 * 1);
247 LOG_INFO("IDCODE: 0x%08" PRIX32
, *idcode
);
252 static int nulink_usb_write_debug_reg(void *handle
, uint32_t addr
, uint32_t val
)
254 struct nulink_usb_handle_s
*h
= handle
;
256 LOG_DEBUG("nulink_usb_write_debug_reg 0x%08" PRIX32
" 0x%08" PRIX32
, addr
, val
);
258 nulink_usb_init_buffer(handle
, 8 + 12 * 1);
260 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_RAM
);
262 /* Count of registers */
263 h
->cmdbuf
[h
->cmdidx
] = 1;
265 /* Array of bool value (u8ReadOld) */
266 h
->cmdbuf
[h
->cmdidx
] = 0x00;
268 /* Array of bool value (u8Verify) */
269 h
->cmdbuf
[h
->cmdidx
] = 0x00;
272 h
->cmdbuf
[h
->cmdidx
] = 0;
275 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, addr
);
278 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, val
);
281 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0x00000000UL
);
284 return nulink_usb_xfer(handle
, h
->databuf
, 4 * 2);
287 static enum target_state
nulink_usb_state(void *handle
)
289 struct nulink_usb_handle_s
*h
= handle
;
293 nulink_usb_init_buffer(handle
, 4 * 1);
295 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_CHECK_MCU_STOP
);
298 int res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * 4);
300 return TARGET_UNKNOWN
;
302 if (!le_to_h_u32(h
->databuf
+ 4 * 2))
303 return TARGET_HALTED
;
305 return TARGET_RUNNING
;
308 static int nulink_usb_assert_srst(void *handle
, int srst
)
310 struct nulink_usb_handle_s
*h
= handle
;
312 LOG_DEBUG("nulink_usb_assert_srst");
316 nulink_usb_init_buffer(handle
, 4 * 4);
318 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_MCU_RESET
);
321 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, RESET_SYSRESETREQ
);
323 /* set connect type */
324 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CONNECT_NORMAL
);
327 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
330 return nulink_usb_xfer(handle
, h
->databuf
, 4 * 4);
333 static int nulink_usb_reset(void *handle
)
335 struct nulink_usb_handle_s
*h
= handle
;
337 LOG_DEBUG("nulink_usb_reset");
341 nulink_usb_init_buffer(handle
, 4 * 4);
343 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_MCU_RESET
);
346 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, RESET_HW
);
348 /* set connect type */
349 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CONNECT_NORMAL
);
352 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
355 return nulink_usb_xfer(handle
, h
->databuf
, 4 * 4);
358 static int nulink_usb_run(void *handle
)
360 struct nulink_usb_handle_s
*h
= handle
;
362 LOG_DEBUG("nulink_usb_run");
366 nulink_usb_init_buffer(handle
, 4 * 1);
368 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_MCU_FREE_RUN
);
371 return nulink_usb_xfer(handle
, h
->databuf
, 4 * 4);
374 static int nulink_usb_halt(void *handle
)
376 struct nulink_usb_handle_s
*h
= handle
;
378 LOG_DEBUG("nulink_usb_halt");
382 nulink_usb_init_buffer(handle
, 4 * 1);
384 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_MCU_STOP_RUN
);
387 int res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * 4);
389 LOG_DEBUG("Nu-Link stop_pc 0x%08" PRIx32
, le_to_h_u32(h
->databuf
+ 4));
394 static int nulink_usb_step(void *handle
)
396 struct nulink_usb_handle_s
*h
= handle
;
398 LOG_DEBUG("nulink_usb_step");
402 nulink_usb_init_buffer(handle
, 4 * 1);
404 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_MCU_STEP_RUN
);
407 int res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * 4);
409 LOG_DEBUG("Nu-Link pc 0x%08" PRIx32
, le_to_h_u32(h
->databuf
+ 4));
414 static int nulink_usb_read_reg(void *handle
, unsigned int regsel
, uint32_t *val
)
416 struct nulink_usb_handle_s
*h
= handle
;
420 nulink_usb_init_buffer(handle
, 8 + 12 * 1);
422 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_REG
);
424 /* Count of registers */
425 h
->cmdbuf
[h
->cmdidx
] = 1;
427 /* Array of bool value (u8ReadOld) */
428 h
->cmdbuf
[h
->cmdidx
] = 0xFF;
430 /* Array of bool value (u8Verify) */
431 h
->cmdbuf
[h
->cmdidx
] = 0x00;
434 h
->cmdbuf
[h
->cmdidx
] = 0;
437 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, regsel
);
440 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
443 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFFFFFFFFUL
);
446 int res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * 2);
448 *val
= le_to_h_u32(h
->databuf
+ 4 * 1);
453 static int nulink_usb_write_reg(void *handle
, unsigned int regsel
, uint32_t val
)
455 struct nulink_usb_handle_s
*h
= handle
;
459 nulink_usb_init_buffer(handle
, 8 + 12 * 1);
461 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_REG
);
463 /* Count of registers */
464 h
->cmdbuf
[h
->cmdidx
] = 1;
466 /* Array of bool value (u8ReadOld) */
467 h
->cmdbuf
[h
->cmdidx
] = 0x00;
469 /* Array of bool value (u8Verify) */
470 h
->cmdbuf
[h
->cmdidx
] = 0x00;
473 h
->cmdbuf
[h
->cmdidx
] = 0;
476 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, regsel
);
479 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, val
);
482 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0x00000000UL
);
485 return nulink_usb_xfer(handle
, h
->databuf
, 4 * 2);
488 static int nulink_usb_read_mem8(void *handle
, uint32_t addr
, uint16_t len
,
493 uint32_t bytes_remaining
= 12;
494 struct nulink_usb_handle_s
*h
= handle
;
496 LOG_DEBUG("nulink_usb_read_mem8: addr 0x%08" PRIx32
", len %" PRId16
, addr
, len
);
500 /* check whether data is word aligned */
502 uint32_t aligned_addr
= addr
/ 4;
503 aligned_addr
= aligned_addr
* 4;
504 offset
= addr
- aligned_addr
;
505 LOG_DEBUG("nulink_usb_read_mem8: unaligned address addr 0x%08" PRIx32
506 "/aligned addr 0x%08" PRIx32
" offset %" PRIu32
,
507 addr
, aligned_addr
, offset
);
515 if (len
< bytes_remaining
)
516 bytes_remaining
= len
;
523 nulink_usb_init_buffer(handle
, 8 + 12 * count
);
525 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_RAM
);
527 /* Count of registers */
528 h
->cmdbuf
[h
->cmdidx
] = count
;
530 /* Array of bool value (u8ReadOld) */
531 h
->cmdbuf
[h
->cmdidx
] = 0xFF;
533 /* Array of bool value (u8Verify) */
534 h
->cmdbuf
[h
->cmdidx
] = 0x00;
537 h
->cmdbuf
[h
->cmdidx
] = 0;
540 for (unsigned int i
= 0; i
< count
; i
++) {
542 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, addr
);
545 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
548 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFFFFFFFFUL
);
550 /* proceed to the next one */
554 res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * count
* 2);
558 /* fill in the output buffer */
559 for (unsigned int i
= 0; i
< count
; i
++) {
561 memcpy(buffer
, h
->databuf
+ 4 + offset
, len
);
563 memcpy(buffer
+ 2 * i
, h
->databuf
+ 4 * (2 * i
+ 1), len
- 2);
566 if (len
>= bytes_remaining
)
567 len
-= bytes_remaining
;
573 static int nulink_usb_write_mem8(void *handle
, uint32_t addr
, uint16_t len
,
574 const uint8_t *buffer
)
578 uint32_t bytes_remaining
= 12;
579 struct nulink_usb_handle_s
*h
= handle
;
581 LOG_DEBUG("nulink_usb_write_mem8: addr 0x%08" PRIx32
", len %" PRIu16
, addr
, len
);
585 /* check whether data is word aligned */
587 uint32_t aligned_addr
= addr
/ 4;
588 aligned_addr
= aligned_addr
* 4;
589 offset
= addr
- aligned_addr
;
590 LOG_DEBUG("nulink_usb_write_mem8: address not aligned. addr(0x%08" PRIx32
591 ")/aligned_addr(0x%08" PRIx32
")/offset(%" PRIu32
")",
592 addr
, aligned_addr
, offset
);
600 if (len
< bytes_remaining
)
601 bytes_remaining
= len
;
608 nulink_usb_init_buffer(handle
, 8 + 12 * count
);
610 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_RAM
);
612 /* Count of registers */
613 h
->cmdbuf
[h
->cmdidx
] = count
;
615 /* Array of bool value (u8ReadOld) */
616 h
->cmdbuf
[h
->cmdidx
] = 0x00;
618 /* Array of bool value (u8Verify) */
619 h
->cmdbuf
[h
->cmdidx
] = 0x00;
622 h
->cmdbuf
[h
->cmdidx
] = 0;
625 for (unsigned int i
= 0; i
< count
; i
++) {
627 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, addr
);
630 uint32_t u32buffer
= buf_get_u32(buffer
, 0, len
* 8);
631 u32buffer
= (u32buffer
<< offset
* 8);
632 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, u32buffer
);
638 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFFFFFF00UL
);
639 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFFFFFF00", i
);
641 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFFFF0000UL
);
642 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFFFF0000", i
);
646 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFF00FFFFUL
);
647 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFF00FFFF", i
);
650 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0x0000FFFFUL
);
651 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0x0000FFFF", i
);
656 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFFFF0000UL
);
657 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFFFF0000", i
);
659 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0x00000000UL
);
660 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0x00000000", i
);
665 /* proceed to the next one */
670 res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * count
* 2);
674 if (len
>= bytes_remaining
)
675 len
-= bytes_remaining
;
681 static int nulink_usb_read_mem32(void *handle
, uint32_t addr
, uint16_t len
,
685 uint32_t bytes_remaining
= 12;
686 struct nulink_usb_handle_s
*h
= handle
;
690 /* data must be a multiple of 4 and word aligned */
691 if (len
% 4 || addr
% 4) {
692 LOG_ERROR("Invalid data alignment");
693 return ERROR_TARGET_UNALIGNED_ACCESS
;
697 if (len
< bytes_remaining
)
698 bytes_remaining
= len
;
700 unsigned int count
= bytes_remaining
/ 4;
702 nulink_usb_init_buffer(handle
, 8 + 12 * count
);
704 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_RAM
);
706 /* Count of registers */
707 h
->cmdbuf
[h
->cmdidx
] = count
;
709 /* Array of bool value (u8ReadOld) */
710 h
->cmdbuf
[h
->cmdidx
] = 0xFF;
712 /* Array of bool value (u8Verify) */
713 h
->cmdbuf
[h
->cmdidx
] = 0x00;
716 h
->cmdbuf
[h
->cmdidx
] = 0;
719 for (unsigned int i
= 0; i
< count
; i
++) {
721 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, addr
);
724 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
727 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0xFFFFFFFFUL
);
729 /* proceed to the next one */
733 res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * count
* 2);
735 /* fill in the output buffer */
736 for (unsigned int i
= 0; i
< count
; i
++) {
737 memcpy(buffer
, h
->databuf
+ 4 * (2 * i
+ 1), 4);
741 if (len
>= bytes_remaining
)
742 len
-= bytes_remaining
;
750 static int nulink_usb_write_mem32(void *handle
, uint32_t addr
, uint16_t len
,
751 const uint8_t *buffer
)
754 uint32_t bytes_remaining
= 12;
755 struct nulink_usb_handle_s
*h
= handle
;
759 /* data must be a multiple of 4 and word aligned */
760 if (len
% 4 || addr
% 4) {
761 LOG_ERROR("Invalid data alignment");
762 return ERROR_TARGET_UNALIGNED_ACCESS
;
766 if (len
< bytes_remaining
)
767 bytes_remaining
= len
;
769 unsigned int count
= bytes_remaining
/ 4;
771 nulink_usb_init_buffer(handle
, 8 + 12 * count
);
773 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_WRITE_RAM
);
775 /* Count of registers */
776 h
->cmdbuf
[h
->cmdidx
] = count
;
778 /* Array of bool value (u8ReadOld) */
779 h
->cmdbuf
[h
->cmdidx
] = 0x00;
781 /* Array of bool value (u8Verify) */
782 h
->cmdbuf
[h
->cmdidx
] = 0x00;
785 h
->cmdbuf
[h
->cmdidx
] = 0;
788 for (unsigned int i
= 0; i
< count
; i
++) {
790 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, addr
);
793 uint32_t u32buffer
= buf_get_u32(buffer
, 0, 32);
794 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, u32buffer
);
797 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0x00000000);
800 /* proceed to the next one */
805 res
= nulink_usb_xfer(handle
, h
->databuf
, 4 * count
* 2);
807 if (len
>= bytes_remaining
)
808 len
-= bytes_remaining
;
816 static uint32_t nulink_max_block_size(uint32_t tar_autoincr_block
, uint32_t address
)
818 uint32_t max_tar_block
= (tar_autoincr_block
- ((tar_autoincr_block
- 1) & address
));
820 if (max_tar_block
== 0)
823 return max_tar_block
;
826 static int nulink_usb_read_mem(void *handle
, uint32_t addr
, uint32_t size
,
827 uint32_t count
, uint8_t *buffer
)
829 int retval
= ERROR_OK
;
830 struct nulink_usb_handle_s
*h
= handle
;
832 /* calculate byte count */
836 uint32_t bytes_remaining
= nulink_max_block_size(h
->max_mem_packet
, addr
);
838 if (count
< bytes_remaining
)
839 bytes_remaining
= count
;
841 if (bytes_remaining
>= 4)
844 /* the nulink only supports 8/32bit memory read/writes
845 * honour 32bit, all others will be handled as 8bit access */
847 /* When in jtag mode the nulink uses the auto-increment functionality.
848 * However it expects us to pass the data correctly, this includes
849 * alignment and any page boundaries. We already do this as part of the
850 * adi_v5 implementation, but the nulink is a hla adapter and so this
851 * needs implementing manually.
852 * currently this only affects jtag mode, they do single
853 * access in SWD mode - but this may change and so we do it for both modes */
855 /* we first need to check for any unaligned bytes */
857 uint32_t head_bytes
= 4 - (addr
% 4);
858 retval
= nulink_usb_read_mem8(handle
, addr
, head_bytes
, buffer
);
859 if (retval
!= ERROR_OK
)
861 buffer
+= head_bytes
;
864 bytes_remaining
-= head_bytes
;
867 if (bytes_remaining
% 4)
868 retval
= nulink_usb_read_mem(handle
, addr
, 1, bytes_remaining
, buffer
);
870 retval
= nulink_usb_read_mem32(handle
, addr
, bytes_remaining
, buffer
);
872 retval
= nulink_usb_read_mem8(handle
, addr
, bytes_remaining
, buffer
);
875 if (retval
!= ERROR_OK
)
878 buffer
+= bytes_remaining
;
879 addr
+= bytes_remaining
;
880 count
-= bytes_remaining
;
886 static int nulink_usb_write_mem(void *handle
, uint32_t addr
, uint32_t size
,
887 uint32_t count
, const uint8_t *buffer
)
889 int retval
= ERROR_OK
;
890 struct nulink_usb_handle_s
*h
= handle
;
892 if (addr
< ARM_SRAM_BASE
) {
893 LOG_DEBUG("nulink_usb_write_mem: address below ARM_SRAM_BASE, not supported.\n");
897 /* calculate byte count */
901 uint32_t bytes_remaining
= nulink_max_block_size(h
->max_mem_packet
, addr
);
903 if (count
< bytes_remaining
)
904 bytes_remaining
= count
;
906 if (bytes_remaining
>= 4)
909 /* the nulink only supports 8/32bit memory read/writes
910 * honour 32bit, all others will be handled as 8bit access */
912 /* When in jtag mode the nulink uses the auto-increment functionality.
913 * However it expects us to pass the data correctly, this includes
914 * alignment and any page boundaries. We already do this as part of the
915 * adi_v5 implementation, but the nulink is a hla adapter and so this
916 * needs implementing manually.
917 * currently this only affects jtag mode, do single
918 * access in SWD mode - but this may change and so we do it for both modes */
920 /* we first need to check for any unaligned bytes */
922 uint32_t head_bytes
= 4 - (addr
% 4);
923 retval
= nulink_usb_write_mem8(handle
, addr
, head_bytes
, buffer
);
924 if (retval
!= ERROR_OK
)
926 buffer
+= head_bytes
;
929 bytes_remaining
-= head_bytes
;
932 if (bytes_remaining
% 4)
933 retval
= nulink_usb_write_mem(handle
, addr
, 1, bytes_remaining
, buffer
);
935 retval
= nulink_usb_write_mem32(handle
, addr
, bytes_remaining
, buffer
);
938 retval
= nulink_usb_write_mem8(handle
, addr
, bytes_remaining
, buffer
);
941 if (retval
!= ERROR_OK
)
944 buffer
+= bytes_remaining
;
945 addr
+= bytes_remaining
;
946 count
-= bytes_remaining
;
952 static int nulink_usb_override_target(const char *targetname
)
954 LOG_DEBUG("nulink_usb_override_target");
956 return !strcmp(targetname
, "cortex_m");
959 static int nulink_speed(void *handle
, int khz
, bool query
)
961 struct nulink_usb_handle_s
*h
= handle
;
962 unsigned long max_ice_clock
= khz
;
964 LOG_DEBUG("nulink_speed: query %s", query
? "yes" : "no");
966 if (max_ice_clock
> 12000)
967 max_ice_clock
= 12000;
968 else if ((max_ice_clock
== 3 * 512) || (max_ice_clock
== 1500))
969 max_ice_clock
= 1500;
970 else if (max_ice_clock
>= 1000)
971 max_ice_clock
= max_ice_clock
/ 1000 * 1000;
973 max_ice_clock
= max_ice_clock
/ 100 * 100;
975 LOG_DEBUG("Nu-Link nulink_speed: %lu", max_ice_clock
);
978 nulink_usb_init_buffer(handle
, 4 * 6);
980 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, CMD_SET_CONFIG
);
982 /* set max SWD clock */
983 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, max_ice_clock
);
985 /* chip type: NUC_CHIP_TYPE_GENERAL_V6M */
986 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
989 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 5000);
991 /* If supply voltage to target or not */
992 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 0);
994 /* USB_FUNC_E: USB_FUNC_HID_BULK */
995 h_u32_to_le(h
->cmdbuf
+ h
->cmdidx
, 2);
998 nulink_usb_xfer(handle
, h
->databuf
, 4 * 3);
1000 LOG_DEBUG("nulink_speed: h->hardware_config(%" PRId16
")", h
->hardware_config
);
1001 if (h
->hardware_config
& HARDWARE_CONFIG_NULINKPRO
)
1002 LOG_INFO("Nu-Link target_voltage_mv[0](%04" PRIx16
"), target_voltage_mv[1](%04" PRIx16
1003 "), target_voltage_mv[2](%04" PRIx16
"), if_target_power_supplied(%d)",
1004 le_to_h_u16(h
->databuf
+ 4 * 1 + 0),
1005 le_to_h_u16(h
->databuf
+ 4 * 1 + 2),
1006 le_to_h_u16(h
->databuf
+ 4 * 2 + 0),
1007 le_to_h_u16(h
->databuf
+ 4 * 2 + 2) & 1);
1010 return max_ice_clock
;
1013 static int nulink_usb_close(void *handle
)
1015 struct nulink_usb_handle_s
*h
= handle
;
1017 LOG_DEBUG("nulink_usb_close");
1019 if (h
&& h
->dev_handle
)
1020 hid_close(h
->dev_handle
);
1029 static int nulink_usb_open(struct hl_interface_param_s
*param
, void **fd
)
1031 struct hid_device_info
*devs
, *cur_dev
;
1032 uint16_t target_vid
= 0;
1033 uint16_t target_pid
= 0;
1034 wchar_t *target_serial
= NULL
;
1036 LOG_DEBUG("nulink_usb_open");
1038 if (param
->transport
!= HL_TRANSPORT_SWD
)
1039 return TARGET_UNKNOWN
;
1041 if (!param
->vid
[0] && !param
->pid
[0]) {
1042 LOG_ERROR("Missing vid/pid");
1046 if (hid_init() != 0) {
1047 LOG_ERROR("unable to open HIDAPI");
1051 struct nulink_usb_handle_s
*h
= calloc(1, sizeof(*h
));
1053 LOG_ERROR("Out of memory");
1057 if (param
->serial
) {
1058 size_t len
= mbstowcs(NULL
, param
->serial
, 0);
1060 target_serial
= calloc(len
+ 1, sizeof(wchar_t));
1061 if (!target_serial
) {
1062 LOG_ERROR("Out of memory");
1066 if (mbstowcs(target_serial
, param
->serial
, len
+ 1) == (size_t)(-1)) {
1067 LOG_WARNING("unable to convert serial");
1068 free(target_serial
);
1069 target_serial
= NULL
;
1073 devs
= hid_enumerate(0, 0);
1078 for (unsigned int i
= 0; param
->vid
[i
] || param
->pid
[i
]; i
++) {
1079 if (param
->vid
[i
] == cur_dev
->vendor_id
&& param
->pid
[i
] == cur_dev
->product_id
) {
1088 if (cur_dev
->serial_number
&& wcscmp(target_serial
, cur_dev
->serial_number
) == 0)
1092 cur_dev
= cur_dev
->next
;
1095 target_vid
= cur_dev
->vendor_id
;
1096 target_pid
= cur_dev
->product_id
;
1099 hid_free_enumeration(devs
);
1101 if (target_vid
== 0 && target_pid
== 0) {
1102 LOG_ERROR("unable to find Nu-Link");
1106 hid_device
*dev
= hid_open(target_vid
, target_pid
, target_serial
);
1108 LOG_ERROR("unable to open Nu-Link device 0x%" PRIx16
":0x%" PRIx16
, target_vid
, target_pid
);
1112 h
->dev_handle
= dev
;
1115 switch (target_pid
) {
1116 case NULINK2_USB_PID1
:
1117 case NULINK2_USB_PID2
:
1118 h
->hardware_config
= HARDWARE_CONFIG_NULINK2
;
1119 h
->max_packet_size
= NULINK2_HID_MAX_SIZE
;
1120 h
->init_buffer
= nulink2_usb_init_buffer
;
1121 h
->xfer
= nulink2_usb_xfer
;
1124 h
->hardware_config
= 0;
1125 h
->max_packet_size
= NULINK_HID_MAX_SIZE
;
1126 h
->init_buffer
= nulink1_usb_init_buffer
;
1127 h
->xfer
= nulink1_usb_xfer
;
1131 /* get the device version */
1133 int err
= nulink_usb_version(h
);
1134 if (err
!= ERROR_OK
) {
1135 LOG_DEBUG("nulink_usb_version failed with cmdSize(4 * 5)");
1137 err
= nulink_usb_version(h
);
1138 if (err
!= ERROR_OK
)
1139 LOG_DEBUG("nulink_usb_version failed with cmdSize(4 * 6)");
1142 /* SWD clock rate : 1MHz */
1143 nulink_speed(h
, 1000, false);
1145 /* get cpuid, so we can determine the max page size
1146 * start with a safe default */
1147 h
->max_mem_packet
= (1 << 10);
1149 LOG_DEBUG("nulink_usb_open: we manually perform nulink_usb_reset");
1150 nulink_usb_reset(h
);
1154 free(target_serial
);
1158 nulink_usb_close(h
);
1159 free(target_serial
);
1164 struct hl_layout_api_s nulink_usb_layout_api
= {
1165 .open
= nulink_usb_open
,
1166 .close
= nulink_usb_close
,
1167 .idcode
= nulink_usb_idcode
,
1168 .state
= nulink_usb_state
,
1169 .reset
= nulink_usb_reset
,
1170 .assert_srst
= nulink_usb_assert_srst
,
1171 .run
= nulink_usb_run
,
1172 .halt
= nulink_usb_halt
,
1173 .step
= nulink_usb_step
,
1174 .read_reg
= nulink_usb_read_reg
,
1175 .write_reg
= nulink_usb_write_reg
,
1176 .read_mem
= nulink_usb_read_mem
,
1177 .write_mem
= nulink_usb_write_mem
,
1178 .write_debug_reg
= nulink_usb_write_debug_reg
,
1179 .override_target
= nulink_usb_override_target
,
1180 .speed
= nulink_speed
,
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)