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 V6M_MAX_COMMAND_LENGTH (NULINK_HID_MAX_SIZE - 2)
40 struct nulink_usb_handle_s {
41 hid_device *dev_handle;
42 uint16_t max_packet_size;
45 uint8_t cmdbuf[NULINK_HID_MAX_SIZE + 1];
46 uint8_t tempbuf[NULINK_HID_MAX_SIZE];
47 uint8_t databuf[NULINK_HID_MAX_SIZE];
48 uint32_t max_mem_packet;
49 uint16_t hardware_config; /* bit 0: 1:Nu-Link-Pro, 0:Nu-Link */
53 #define CMD_READ_REG 0xB5UL
54 #define CMD_READ_RAM 0xB1UL
55 #define CMD_WRITE_REG 0xB8UL
56 #define CMD_WRITE_RAM 0xB9UL
57 #define CMD_CHECK_ID 0xA3UL
58 #define CMD_MCU_RESET 0xE2UL
59 #define CMD_CHECK_MCU_STOP 0xD8UL
60 #define CMD_MCU_STEP_RUN 0xD1UL
61 #define CMD_MCU_STOP_RUN 0xD2UL
62 #define CMD_MCU_FREE_RUN 0xD3UL
63 #define CMD_SET_CONFIG 0xA2UL
65 #define ARM_SRAM_BASE 0x20000000UL
67 #define HARDWARE_CONFIG_NULINKPRO 1
72 RESET_SYSRESETREQ = 2,
74 RESET_FAST_RESCUE = 4, /* Rescue and erase the chip, need very fast speed */
78 CONNECT_NORMAL = 0, /* Support all reset method */
79 CONNECT_PRE_RESET = 1, /* Support all reset method */
80 CONNECT_UNDER_RESET = 2, /* Support all reset method */
81 CONNECT_NONE = 3, /* Support RESET_HW, (RESET_AUTO = RESET_HW) */
82 CONNECT_DISCONNECT = 4, /* Support RESET_NONE, (RESET_AUTO = RESET_NONE) */
83 CONNECT_ICP_MODE = 5 /* Support NUC505 ICP mode*/
86 static int nulink_usb_xfer_rw(void *handle, uint8_t *buf)
88 struct nulink_usb_handle_s *h = handle;
92 int ret = hid_write(h->dev_handle, h->cmdbuf, h->max_packet_size + 1);
94 LOG_ERROR("hid_write");
98 ret = hid_read_timeout(h->dev_handle, buf, h->max_packet_size, NULINK_READ_TIMEOUT);
100 LOG_ERROR("hid_read_timeout");
106 static int nulink_usb_xfer(void *handle, uint8_t *buf, int size)
108 struct nulink_usb_handle_s *h = handle;
112 int err = nulink_usb_xfer_rw(h, h->tempbuf);
114 memcpy(buf, h->tempbuf + 2, V6M_MAX_COMMAND_LENGTH);
119 static void nulink_usb_init_buffer(void *handle, uint32_t size)
121 struct nulink_usb_handle_s *h = handle;
125 memset(h->cmdbuf, 0, h->max_packet_size + 1);
126 memset(h->tempbuf, 0, h->max_packet_size);
127 memset(h->databuf, 0, h->max_packet_size);
129 h->cmdbuf[0] = 0; /* report number */
130 h->cmdbuf[1] = ++h->usbcmdidx & 0x7F;
135 static int nulink_usb_version(void *handle)
137 struct nulink_usb_handle_s *h = handle;
139 LOG_DEBUG("nulink_usb_version");
143 nulink_usb_init_buffer(handle, V6M_MAX_COMMAND_LENGTH);
145 memset(h->cmdbuf + h->cmdidx, 0xFF, V6M_MAX_COMMAND_LENGTH);
146 h->cmdbuf[h->cmdidx + 4] = 0xA1; /* host_rev_num: 6561 */;
147 h->cmdbuf[h->cmdidx + 5] = 0x19;
149 int res = nulink_usb_xfer(handle, h->databuf, 4 * 5);
153 LOG_INFO("Nu-Link firmware_version %" PRIu32 ", product_id (0x%08" PRIx32 ")",
154 le_to_h_u32(h->databuf),
155 le_to_h_u32(h->databuf + 4 * 1));
157 const bool is_nulinkpro = !!(le_to_h_u32(h->databuf + 4 * 2) & 1);
159 LOG_INFO("Adapter is Nu-Link-Pro, target_voltage_mv(%" PRIu16 "), usb_voltage_mv(%" PRIu16 ")",
160 le_to_h_u16(h->databuf + 4 * 3 + 0),
161 le_to_h_u16(h->databuf + 4 * 3 + 2));
163 h->hardware_config |= HARDWARE_CONFIG_NULINKPRO;
165 LOG_INFO("Adapter is Nu-Link");
171 static int nulink_usb_idcode(void *handle, uint32_t *idcode)
173 struct nulink_usb_handle_s *h = handle;
175 LOG_DEBUG("nulink_usb_idcode");
179 nulink_usb_init_buffer(handle, 4 * 1);
181 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_CHECK_ID);
184 int res = nulink_usb_xfer(handle, h->databuf, 4 * 2);
188 *idcode = le_to_h_u32(h->databuf + 4 * 1);
190 LOG_INFO("IDCODE: 0x%08" PRIX32, *idcode);
195 static int nulink_usb_write_debug_reg(void *handle, uint32_t addr, uint32_t val)
197 struct nulink_usb_handle_s *h = handle;
199 LOG_DEBUG("nulink_usb_write_debug_reg 0x%08" PRIX32 "0x%08" PRIX32, addr, val);
201 nulink_usb_init_buffer(handle, 8 + 12 * 1);
203 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_RAM);
205 /* Count of registers */
206 h->cmdbuf[h->cmdidx] = 1;
208 /* Array of bool value (u8ReadOld) */
209 h->cmdbuf[h->cmdidx] = 0x00;
211 /* Array of bool value (u8Verify) */
212 h->cmdbuf[h->cmdidx] = 0x00;
215 h->cmdbuf[h->cmdidx] = 0;
218 h_u32_to_le(h->cmdbuf + h->cmdidx, addr);
221 h_u32_to_le(h->cmdbuf + h->cmdidx, val);
224 h_u32_to_le(h->cmdbuf + h->cmdidx, 0x00000000UL);
227 return nulink_usb_xfer(handle, h->databuf, 4 * 2);
230 static enum target_state nulink_usb_state(void *handle)
232 struct nulink_usb_handle_s *h = handle;
236 nulink_usb_init_buffer(handle, 4 * 1);
238 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_CHECK_MCU_STOP);
241 int res = nulink_usb_xfer(handle, h->databuf, 4 * 4);
243 return TARGET_UNKNOWN;
245 if (!le_to_h_u32(h->databuf + 4 * 2))
246 return TARGET_HALTED;
248 return TARGET_RUNNING;
251 static int nulink_usb_assert_srst(void *handle, int srst)
253 struct nulink_usb_handle_s *h = handle;
255 LOG_DEBUG("nulink_usb_assert_srst");
259 nulink_usb_init_buffer(handle, 4 * 4);
261 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_MCU_RESET);
264 h_u32_to_le(h->cmdbuf + h->cmdidx, RESET_SYSRESETREQ);
266 /* set connect type */
267 h_u32_to_le(h->cmdbuf + h->cmdidx, CONNECT_NORMAL);
270 h_u32_to_le(h->cmdbuf + h->cmdidx, 0);
273 return nulink_usb_xfer(handle, h->databuf, 4 * 4);
276 static int nulink_usb_reset(void *handle)
278 struct nulink_usb_handle_s *h = handle;
280 LOG_DEBUG("nulink_usb_reset");
284 nulink_usb_init_buffer(handle, 4 * 4);
286 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_MCU_RESET);
289 h_u32_to_le(h->cmdbuf + h->cmdidx, RESET_HW);
291 /* set connect type */
292 h_u32_to_le(h->cmdbuf + h->cmdidx, CONNECT_NORMAL);
295 h_u32_to_le(h->cmdbuf + h->cmdidx, 0);
298 return nulink_usb_xfer(handle, h->databuf, 4 * 4);
301 static int nulink_usb_run(void *handle)
303 struct nulink_usb_handle_s *h = handle;
305 LOG_DEBUG("nulink_usb_run");
309 nulink_usb_init_buffer(handle, 4 * 1);
311 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_MCU_FREE_RUN);
314 return nulink_usb_xfer(handle, h->databuf, 4 * 4);
317 static int nulink_usb_halt(void *handle)
319 struct nulink_usb_handle_s *h = handle;
321 LOG_DEBUG("nulink_usb_halt");
325 nulink_usb_init_buffer(handle, 4 * 1);
327 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_MCU_STOP_RUN);
330 int res = nulink_usb_xfer(handle, h->databuf, 4 * 4);
332 LOG_DEBUG("Nu-Link stop_pc 0x%08" PRIx32, le_to_h_u32(h->databuf + 4));
337 static int nulink_usb_step(void *handle)
339 struct nulink_usb_handle_s *h = handle;
341 LOG_DEBUG("nulink_usb_step");
345 nulink_usb_init_buffer(handle, 4 * 1);
347 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_MCU_STEP_RUN);
350 int res = nulink_usb_xfer(handle, h->databuf, 4 * 4);
352 LOG_DEBUG("Nu-Link pc 0x%08" PRIx32, le_to_h_u32(h->databuf + 4));
357 static int nulink_usb_read_reg(void *handle, int num, uint32_t *val)
359 struct nulink_usb_handle_s *h = handle;
363 nulink_usb_init_buffer(handle, 8 + 12 * 1);
365 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_REG);
367 /* Count of registers */
368 h->cmdbuf[h->cmdidx] = 1;
370 /* Array of bool value (u8ReadOld) */
371 h->cmdbuf[h->cmdidx] = 0xFF;
373 /* Array of bool value (u8Verify) */
374 h->cmdbuf[h->cmdidx] = 0x00;
377 h->cmdbuf[h->cmdidx] = 0;
380 h_u32_to_le(h->cmdbuf + h->cmdidx, num);
383 h_u32_to_le(h->cmdbuf + h->cmdidx, 0);
386 h_u32_to_le(h->cmdbuf + h->cmdidx, 0xFFFFFFFFUL);
389 int res = nulink_usb_xfer(handle, h->databuf, 4 * 2);
391 *val = le_to_h_u32(h->databuf + 4 * 1);
396 static int nulink_usb_write_reg(void *handle, int num, uint32_t val)
398 struct nulink_usb_handle_s *h = handle;
402 nulink_usb_init_buffer(handle, 8 + 12 * 1);
404 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_REG);
406 /* Count of registers */
407 h->cmdbuf[h->cmdidx] = 1;
409 /* Array of bool value (u8ReadOld) */
410 h->cmdbuf[h->cmdidx] = 0x00;
412 /* Array of bool value (u8Verify) */
413 h->cmdbuf[h->cmdidx] = 0x00;
416 h->cmdbuf[h->cmdidx] = 0;
419 h_u32_to_le(h->cmdbuf + h->cmdidx, num);
422 h_u32_to_le(h->cmdbuf + h->cmdidx, val);
425 h_u32_to_le(h->cmdbuf + h->cmdidx, 0x00000000UL);
428 return nulink_usb_xfer(handle, h->databuf, 4 * 2);
431 static int nulink_usb_read_mem8(void *handle, uint32_t addr, uint16_t len,
436 uint32_t bytes_remaining = 12;
437 struct nulink_usb_handle_s *h = handle;
439 LOG_DEBUG("nulink_usb_read_mem8: addr 0x%08" PRIx32 ", len %" PRId16, addr, len);
443 /* check whether data is word aligned */
445 uint32_t aligned_addr = addr / 4;
446 aligned_addr = aligned_addr * 4;
447 offset = addr - aligned_addr;
448 LOG_DEBUG("nulink_usb_read_mem8: unaligned address addr 0x%08" PRIx32
449 "/aligned addr 0x%08" PRIx32 "offset %" PRIu32,
450 addr, aligned_addr, offset);
458 if (len < bytes_remaining)
459 bytes_remaining = len;
466 nulink_usb_init_buffer(handle, 8 + 12 * count);
468 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_RAM);
470 /* Count of registers */
471 h->cmdbuf[h->cmdidx] = count;
473 /* Array of bool value (u8ReadOld) */
474 h->cmdbuf[h->cmdidx] = 0xFF;
476 /* Array of bool value (u8Verify) */
477 h->cmdbuf[h->cmdidx] = 0x00;
480 h->cmdbuf[h->cmdidx] = 0;
483 for (unsigned int i = 0; i < count; i++) {
485 h_u32_to_le(h->cmdbuf + h->cmdidx, addr);
488 h_u32_to_le(h->cmdbuf + h->cmdidx, 0);
491 h_u32_to_le(h->cmdbuf + h->cmdidx, 0xFFFFFFFFUL);
493 /* proceed to the next one */
497 res = nulink_usb_xfer(handle, h->databuf, 4 * count * 2);
501 /* fill in the output buffer */
502 for (unsigned int i = 0; i < count; i++) {
504 memcpy(buffer, h->databuf + 4 + offset, len);
506 memcpy(buffer + 2 * i, h->databuf + 4 * (2 * i + 1), len - 2);
509 if (len >= bytes_remaining)
510 len -= bytes_remaining;
516 static int nulink_usb_write_mem8(void *handle, uint32_t addr, uint16_t len,
517 const uint8_t *buffer)
521 uint32_t bytes_remaining = 12;
522 struct nulink_usb_handle_s *h = handle;
524 LOG_DEBUG("nulink_usb_write_mem8: addr 0x%08" PRIx32 ", len %" PRIu16, addr, len);
528 /* check whether data is word aligned */
530 uint32_t aligned_addr = addr / 4;
531 aligned_addr = aligned_addr * 4;
532 offset = addr - aligned_addr;
533 LOG_DEBUG("nulink_usb_write_mem8: address not aligned. addr(0x%08" PRIx32
534 ")/aligned_addr(0x%08" PRIx32 ")/offset(%" PRIu32 ")",
535 addr, aligned_addr, offset);
543 if (len < bytes_remaining)
544 bytes_remaining = len;
551 nulink_usb_init_buffer(handle, 8 + 12 * count);
553 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_RAM);
555 /* Count of registers */
556 h->cmdbuf[h->cmdidx] = count;
558 /* Array of bool value (u8ReadOld) */
559 h->cmdbuf[h->cmdidx] = 0x00;
561 /* Array of bool value (u8Verify) */
562 h->cmdbuf[h->cmdidx] = 0x00;
565 h->cmdbuf[h->cmdidx] = 0;
568 for (unsigned int i = 0; i < count; i++) {
570 h_u32_to_le(h->cmdbuf + h->cmdidx, addr);
573 uint32_t u32buffer = buf_get_u32(buffer, 0, len * 8);
574 u32buffer = (u32buffer << offset * 8);
575 h_u32_to_le(h->cmdbuf + h->cmdidx, u32buffer);
581 h_u32_to_le(h->cmdbuf + h->cmdidx, 0xFFFFFF00UL);
582 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFFFFFF00", i);
584 h_u32_to_le(h->cmdbuf + h->cmdidx, 0xFFFF0000UL);
585 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFFFF0000", i);
589 h_u32_to_le(h->cmdbuf + h->cmdidx, 0xFF00FFFFUL);
590 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFF00FFFF", i);
593 h_u32_to_le(h->cmdbuf + h->cmdidx, 0x0000FFFFUL);
594 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0x0000FFFF", i);
599 h_u32_to_le(h->cmdbuf + h->cmdidx, 0xFFFF0000UL);
600 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFFFF0000", i);
602 h_u32_to_le(h->cmdbuf + h->cmdidx, 0x00000000UL);
603 LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0x00000000", i);
608 /* proceed to the next one */
613 res = nulink_usb_xfer(handle, h->databuf, 4 * count * 2);
617 if (len >= bytes_remaining)
618 len -= bytes_remaining;
624 static int nulink_usb_read_mem32(void *handle, uint32_t addr, uint16_t len,
628 uint32_t bytes_remaining = 12;
629 struct nulink_usb_handle_s *h = handle;
633 /* data must be a multiple of 4 and word aligned */
634 if (len % 4 || addr % 4) {
635 LOG_ERROR("Invalid data alignment");
636 return ERROR_TARGET_UNALIGNED_ACCESS;
640 if (len < bytes_remaining)
641 bytes_remaining = len;
643 unsigned int count = bytes_remaining / 4;
645 nulink_usb_init_buffer(handle, 8 + 12 * count);
647 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_RAM);
649 /* Count of registers */
650 h->cmdbuf[h->cmdidx] = count;
652 /* Array of bool value (u8ReadOld) */
653 h->cmdbuf[h->cmdidx] = 0xFF;
655 /* Array of bool value (u8Verify) */
656 h->cmdbuf[h->cmdidx] = 0x00;
659 h->cmdbuf[h->cmdidx] = 0;
662 for (unsigned int i = 0; i < count; i++) {
664 h_u32_to_le(h->cmdbuf + h->cmdidx, addr);
667 h_u32_to_le(h->cmdbuf + h->cmdidx, 0);
670 h_u32_to_le(h->cmdbuf + h->cmdidx, 0xFFFFFFFFUL);
672 /* proceed to the next one */
676 res = nulink_usb_xfer(handle, h->databuf, 4 * count * 2);
678 /* fill in the output buffer */
679 for (unsigned int i = 0; i < count; i++) {
680 memcpy(buffer, h->databuf + 4 * (2 * i + 1), 4);
684 if (len >= bytes_remaining)
685 len -= bytes_remaining;
693 static int nulink_usb_write_mem32(void *handle, uint32_t addr, uint16_t len,
694 const uint8_t *buffer)
697 uint32_t bytes_remaining = 12;
698 struct nulink_usb_handle_s *h = handle;
702 /* data must be a multiple of 4 and word aligned */
703 if (len % 4 || addr % 4) {
704 LOG_ERROR("Invalid data alignment");
705 return ERROR_TARGET_UNALIGNED_ACCESS;
709 if (len < bytes_remaining)
710 bytes_remaining = len;
712 unsigned int count = bytes_remaining / 4;
714 nulink_usb_init_buffer(handle, 8 + 12 * count);
716 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_RAM);
718 /* Count of registers */
719 h->cmdbuf[h->cmdidx] = count;
721 /* Array of bool value (u8ReadOld) */
722 h->cmdbuf[h->cmdidx] = 0x00;
724 /* Array of bool value (u8Verify) */
725 h->cmdbuf[h->cmdidx] = 0x00;
728 h->cmdbuf[h->cmdidx] = 0;
731 for (unsigned int i = 0; i < count; i++) {
733 h_u32_to_le(h->cmdbuf + h->cmdidx, addr);
736 uint32_t u32buffer = buf_get_u32(buffer, 0, 32);
737 h_u32_to_le(h->cmdbuf + h->cmdidx, u32buffer);
740 h_u32_to_le(h->cmdbuf + h->cmdidx, 0x00000000);
743 /* proceed to the next one */
748 res = nulink_usb_xfer(handle, h->databuf, 4 * count * 2);
750 if (len >= bytes_remaining)
751 len -= bytes_remaining;
759 static uint32_t nulink_max_block_size(uint32_t tar_autoincr_block, uint32_t address)
761 uint32_t max_tar_block = (tar_autoincr_block - ((tar_autoincr_block - 1) & address));
763 if (max_tar_block == 0)
766 return max_tar_block;
769 static int nulink_usb_read_mem(void *handle, uint32_t addr, uint32_t size,
770 uint32_t count, uint8_t *buffer)
772 int retval = ERROR_OK;
773 struct nulink_usb_handle_s *h = handle;
775 /* calculate byte count */
779 uint32_t bytes_remaining = nulink_max_block_size(h->max_mem_packet, addr);
781 if (count < bytes_remaining)
782 bytes_remaining = count;
784 if (bytes_remaining >= 4)
787 /* the nulink only supports 8/32bit memory read/writes
788 * honour 32bit, all others will be handled as 8bit access */
790 /* When in jtag mode the nulink uses the auto-increment functinality.
791 * However it expects us to pass the data correctly, this includes
792 * alignment and any page boundaries. We already do this as part of the
793 * adi_v5 implementation, but the nulink is a hla adapter and so this
794 * needs implementiong manually.
795 * currently this only affects jtag mode, they do single
796 * access in SWD mode - but this may change and so we do it for both modes */
798 /* we first need to check for any unaligned bytes */
800 uint32_t head_bytes = 4 - (addr % 4);
801 retval = nulink_usb_read_mem8(handle, addr, head_bytes, buffer);
802 if (retval != ERROR_OK)
804 buffer += head_bytes;
807 bytes_remaining -= head_bytes;
810 if (bytes_remaining % 4)
811 retval = nulink_usb_read_mem(handle, addr, 1, bytes_remaining, buffer);
813 retval = nulink_usb_read_mem32(handle, addr, bytes_remaining, buffer);
815 retval = nulink_usb_read_mem8(handle, addr, bytes_remaining, buffer);
818 if (retval != ERROR_OK)
821 buffer += bytes_remaining;
822 addr += bytes_remaining;
823 count -= bytes_remaining;
829 static int nulink_usb_write_mem(void *handle, uint32_t addr, uint32_t size,
830 uint32_t count, const uint8_t *buffer)
832 int retval = ERROR_OK;
833 struct nulink_usb_handle_s *h = handle;
835 if (addr < ARM_SRAM_BASE) {
836 LOG_DEBUG("nulink_usb_write_mem: address below ARM_SRAM_BASE, not supported.\n");
840 /* calculate byte count */
844 uint32_t bytes_remaining = nulink_max_block_size(h->max_mem_packet, addr);
846 if (count < bytes_remaining)
847 bytes_remaining = count;
849 if (bytes_remaining >= 4)
852 /* the nulink only supports 8/32bit memory read/writes
853 * honour 32bit, all others will be handled as 8bit access */
855 /* When in jtag mode the nulink uses the auto-increment functinality.
856 * However it expects us to pass the data correctly, this includes
857 * alignment and any page boundaries. We already do this as part of the
858 * adi_v5 implementation, but the nulink is a hla adapter and so this
859 * needs implementiong manually.
860 * currently this only affects jtag mode, do single
861 * access in SWD mode - but this may change and so we do it for both modes */
863 /* we first need to check for any unaligned bytes */
865 uint32_t head_bytes = 4 - (addr % 4);
866 retval = nulink_usb_write_mem8(handle, addr, head_bytes, buffer);
867 if (retval != ERROR_OK)
869 buffer += head_bytes;
872 bytes_remaining -= head_bytes;
875 if (bytes_remaining % 4)
876 retval = nulink_usb_write_mem(handle, addr, 1, bytes_remaining, buffer);
878 retval = nulink_usb_write_mem32(handle, addr, bytes_remaining, buffer);
881 retval = nulink_usb_write_mem8(handle, addr, bytes_remaining, buffer);
884 if (retval != ERROR_OK)
887 buffer += bytes_remaining;
888 addr += bytes_remaining;
889 count -= bytes_remaining;
895 static int nulink_usb_override_target(const char *targetname)
897 LOG_DEBUG("nulink_usb_override_target");
899 return !strcmp(targetname, "cortex_m");
902 static int nulink_speed(void *handle, int khz, bool query)
904 struct nulink_usb_handle_s *h = handle;
905 unsigned long max_ice_clock = khz;
907 LOG_DEBUG("nulink_speed: query %s", query ? "yes" : "no");
909 if (max_ice_clock > 12000)
910 max_ice_clock = 12000;
911 else if ((max_ice_clock == 3 * 512) || (max_ice_clock == 1500))
912 max_ice_clock = 1500;
913 else if (max_ice_clock >= 1000)
914 max_ice_clock = max_ice_clock / 1000 * 1000;
916 max_ice_clock = max_ice_clock / 100 * 100;
918 LOG_DEBUG("Nu-Link nulink_speed: %lu", max_ice_clock);
921 nulink_usb_init_buffer(handle, 4 * 6);
923 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_SET_CONFIG);
925 /* set max SWD clock */
926 h_u32_to_le(h->cmdbuf + h->cmdidx, max_ice_clock);
928 /* chip type: NUC_CHIP_TYPE_GENERAL_V6M */
929 h_u32_to_le(h->cmdbuf + h->cmdidx, 0);
932 h_u32_to_le(h->cmdbuf + h->cmdidx, 5000);
934 /* If supply voltage to target or not */
935 h_u32_to_le(h->cmdbuf + h->cmdidx, 0);
937 /* USB_FUNC_E: USB_FUNC_HID_BULK */
938 h_u32_to_le(h->cmdbuf + h->cmdidx, 2);
941 nulink_usb_xfer(handle, h->databuf, 4 * 3);
943 LOG_DEBUG("nulink_speed: h->hardware_config(%" PRId16 ")", h->hardware_config);
944 if (h->hardware_config & HARDWARE_CONFIG_NULINKPRO)
945 LOG_INFO("Nu-Link target_voltage_mv[0](%04" PRIx16 "), target_voltage_mv[1](%04" PRIx16
946 "), target_voltage_mv[2](%04" PRIx16 "), if_target_power_supplied(%d)",
947 le_to_h_u16(h->databuf + 4 * 1 + 0),
948 le_to_h_u16(h->databuf + 4 * 1 + 2),
949 le_to_h_u16(h->databuf + 4 * 2 + 0),
950 le_to_h_u16(h->databuf + 4 * 2 + 2) & 1);
953 return max_ice_clock;
956 static int nulink_usb_close(void *handle)
958 struct nulink_usb_handle_s *h = handle;
960 LOG_DEBUG("nulink_usb_close");
962 if (h && h->dev_handle)
963 hid_close(h->dev_handle);
972 static int nulink_usb_open(struct hl_interface_param_s *param, void **fd)
974 struct hid_device_info *devs, *cur_dev;
975 uint16_t target_vid = 0;
976 uint16_t target_pid = 0;
977 wchar_t *target_serial = NULL;
979 LOG_DEBUG("nulink_usb_open");
981 if (param->transport != HL_TRANSPORT_SWD)
982 return TARGET_UNKNOWN;
984 if (!param->vid[0] && !param->pid[0]) {
985 LOG_ERROR("Missing vid/pid");
989 if (hid_init() != 0) {
990 LOG_ERROR("unable to open HIDAPI");
994 struct nulink_usb_handle_s *h = calloc(1, sizeof(*h));
996 LOG_ERROR("Out of memory");
1000 if (param->serial) {
1001 size_t len = mbstowcs(NULL, param->serial, 0);
1003 target_serial = calloc(len + 1, sizeof(wchar_t));
1004 if (!target_serial) {
1005 LOG_ERROR("Out of memory");
1009 if (mbstowcs(target_serial, param->serial, len + 1) == (size_t)(-1)) {
1010 LOG_WARNING("unable to convert serial");
1011 free(target_serial);
1012 target_serial = NULL;
1016 devs = hid_enumerate(0, 0);
1021 for (unsigned int i = 0; param->vid[i] || param->pid[i]; i++) {
1022 if (param->vid[i] == cur_dev->vendor_id && param->pid[i] == cur_dev->product_id) {
1031 if (cur_dev->serial_number && wcscmp(target_serial, cur_dev->serial_number) == 0)
1035 cur_dev = cur_dev->next;
1038 target_vid = cur_dev->vendor_id;
1039 target_pid = cur_dev->product_id;
1042 hid_free_enumeration(devs);
1044 if (target_vid == 0 && target_pid == 0) {
1045 LOG_ERROR("unable to find Nu-Link");
1049 hid_device *dev = hid_open(target_vid, target_pid, target_serial);
1051 LOG_ERROR("unable to open Nu-Link device 0x%" PRIx16 ":0x%" PRIx16, target_vid, target_pid);
1055 h->dev_handle = dev;
1057 h->hardware_config = 0;
1058 h->max_packet_size = NULINK_HID_MAX_SIZE;
1060 /* get the device version */
1061 int err = nulink_usb_version(h);
1062 if (err != ERROR_OK)
1065 /* SWD clock rate : 1MHz */
1066 nulink_speed(h, 1000, false);
1068 /* get cpuid, so we can determine the max page size
1069 * start with a safe default */
1070 h->max_mem_packet = (1 << 10);
1072 LOG_DEBUG("nulink_usb_open: we manually perform nulink_usb_reset");
1073 nulink_usb_reset(h);
1077 free(target_serial);
1081 nulink_usb_close(h);
1082 free(target_serial);
1087 struct hl_layout_api_s nulink_usb_layout_api = {
1088 .open = nulink_usb_open,
1089 .close = nulink_usb_close,
1090 .idcode = nulink_usb_idcode,
1091 .state = nulink_usb_state,
1092 .reset = nulink_usb_reset,
1093 .assert_srst = nulink_usb_assert_srst,
1094 .run = nulink_usb_run,
1095 .halt = nulink_usb_halt,
1096 .step = nulink_usb_step,
1097 .read_reg = nulink_usb_read_reg,
1098 .write_reg = nulink_usb_write_reg,
1099 .read_mem = nulink_usb_read_mem,
1100 .write_mem = nulink_usb_write_mem,
1101 .write_debug_reg = nulink_usb_write_debug_reg,
1102 .override_target = nulink_usb_override_target,
1103 .speed = nulink_speed,