OpenOCD
nulink_usb.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2016-2017 by Nuvoton *
5  * Zale Yu <cyyu@nuvoton.com> *
6  ***************************************************************************/
7 
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11 
12 /* project specific includes */
13 #include <helper/binarybuffer.h>
14 #include <jtag/adapter.h>
15 #include <jtag/interface.h>
16 #include <jtag/hla/hla_layout.h>
17 #include <jtag/hla/hla_transport.h>
18 #include <jtag/hla/hla_interface.h>
19 #include <target/target.h>
20 
21 #include <target/cortex_m.h>
22 
23 #include <hidapi.h>
24 
25 #include "libusb_helper.h"
26 
27 #define NULINK_READ_TIMEOUT LIBUSB_TIMEOUT_MS
28 
29 #define NULINK_HID_MAX_SIZE (64)
30 #define NULINK2_HID_MAX_SIZE (1024)
31 #define V6M_MAX_COMMAND_LENGTH (NULINK_HID_MAX_SIZE - 2)
32 #define V7M_MAX_COMMAND_LENGTH (NULINK_HID_MAX_SIZE - 3)
33 
34 #define NULINK2_USB_PID1 (0x5200)
35 #define NULINK2_USB_PID2 (0x5201)
36 
38  hid_device *dev_handle;
39  uint16_t max_packet_size;
40  uint8_t usbcmdidx;
41  uint8_t cmdidx;
42  uint8_t cmdsize;
46  uint32_t max_mem_packet;
47  uint16_t hardware_config; /* bit 0: 1:Nu-Link-Pro, 0:Nu-Link */
48 
49  int (*xfer)(void *handle, uint8_t *buf, int size);
50  void (*init_buffer)(void *handle, uint32_t size);
51 };
52 
53 /* ICE Command */
54 #define CMD_READ_REG 0xB5UL
55 #define CMD_READ_RAM 0xB1UL
56 #define CMD_WRITE_REG 0xB8UL
57 #define CMD_WRITE_RAM 0xB9UL
58 #define CMD_CHECK_ID 0xA3UL
59 #define CMD_MCU_RESET 0xE2UL
60 #define CMD_CHECK_MCU_STOP 0xD8UL
61 #define CMD_MCU_STEP_RUN 0xD1UL
62 #define CMD_MCU_STOP_RUN 0xD2UL
63 #define CMD_MCU_FREE_RUN 0xD3UL
64 #define CMD_SET_CONFIG 0xA2UL
65 
66 #define ARM_SRAM_BASE 0x20000000UL
67 
68 #define HARDWARE_CONFIG_NULINKPRO 1
69 #define HARDWARE_CONFIG_NULINK2 2
70 
73  RESET_HW = 1,
76  RESET_FAST_RESCUE = 4, /* Rescue and erase the chip, need very fast speed */
77 };
78 
80  CONNECT_NORMAL = 0, /* Support all reset method */
81  CONNECT_PRE_RESET = 1, /* Support all reset method */
82  CONNECT_UNDER_RESET = 2, /* Support all reset method */
83  CONNECT_NONE = 3, /* Support RESET_HW, (RESET_AUTO = RESET_HW) */
84  CONNECT_DISCONNECT = 4, /* Support RESET_NONE, (RESET_AUTO = RESET_NONE) */
85  CONNECT_ICP_MODE = 5 /* Support NUC505 ICP mode*/
86 };
87 
88 static int nulink_usb_xfer_rw(void *handle, uint8_t *buf)
89 {
90  struct nulink_usb_handle_s *h = handle;
91 
92  assert(handle);
93 
94  int ret = hid_write(h->dev_handle, h->cmdbuf, h->max_packet_size + 1);
95  if (ret < 0) {
96  LOG_ERROR("hid_write");
97  return ERROR_FAIL;
98  }
99 
100  ret = hid_read_timeout(h->dev_handle, buf, h->max_packet_size, NULINK_READ_TIMEOUT);
101  if (ret < 0) {
102  LOG_ERROR("hid_read_timeout");
103  return ERROR_FAIL;
104  }
105  return ERROR_OK;
106 }
107 
108 static int nulink1_usb_xfer(void *handle, uint8_t *buf, int size)
109 {
110  struct nulink_usb_handle_s *h = handle;
111 
112  assert(handle);
113 
114  int err = nulink_usb_xfer_rw(h, h->tempbuf);
115 
116  memcpy(buf, h->tempbuf + 2, V6M_MAX_COMMAND_LENGTH);
117 
118  return err;
119 }
120 
121 static int nulink2_usb_xfer(void *handle, uint8_t *buf, int size)
122 {
123  struct nulink_usb_handle_s *h = handle;
124 
125  assert(handle);
126 
127  int err = nulink_usb_xfer_rw(h, h->tempbuf);
128 
129  memcpy(buf, h->tempbuf + 3, V7M_MAX_COMMAND_LENGTH);
130 
131  return err;
132 }
133 
134 static void nulink1_usb_init_buffer(void *handle, uint32_t size)
135 {
136  struct nulink_usb_handle_s *h = handle;
137 
138  h->cmdidx = 0;
139 
140  memset(h->cmdbuf, 0, h->max_packet_size + 1);
141  memset(h->tempbuf, 0, h->max_packet_size);
142  memset(h->databuf, 0, h->max_packet_size);
143 
144  h->cmdbuf[0] = 0; /* report number */
145  h->cmdbuf[1] = ++h->usbcmdidx & 0x7F;
146  h->cmdbuf[2] = size;
147  h->cmdidx += 3;
148 }
149 
150 static void nulink2_usb_init_buffer(void *handle, uint32_t size)
151 {
152  struct nulink_usb_handle_s *h = handle;
153 
154  h->cmdidx = 0;
155 
156  memset(h->cmdbuf, 0, h->max_packet_size + 1);
157  memset(h->tempbuf, 0, h->max_packet_size);
158  memset(h->databuf, 0, h->max_packet_size);
159 
160  h->cmdbuf[0] = 0; /* report number */
161  h->cmdbuf[1] = ++h->usbcmdidx & 0x7F;
162  h_u16_to_le(h->cmdbuf + 2, size);
163  h->cmdidx += 4;
164 }
165 
166 static inline int nulink_usb_xfer(void *handle, uint8_t *buf, int size)
167 {
168  struct nulink_usb_handle_s *h = handle;
169 
170  assert(handle);
171 
172  return h->xfer(handle, buf, size);
173 }
174 
175 static inline void nulink_usb_init_buffer(void *handle, uint32_t size)
176 {
177  struct nulink_usb_handle_s *h = handle;
178 
179  assert(handle);
180 
181  h->init_buffer(handle, size);
182 }
183 
184 static int nulink_usb_version(void *handle)
185 {
186  struct nulink_usb_handle_s *h = handle;
187 
188  LOG_DEBUG("nulink_usb_version");
189 
190  assert(handle);
191 
193 
194  memset(h->cmdbuf + h->cmdidx, 0xFF, V6M_MAX_COMMAND_LENGTH);
195  h->cmdbuf[h->cmdidx + 4] = 0xA1; /* host_rev_num: 6561 */;
196  h->cmdbuf[h->cmdidx + 5] = 0x19;
197 
198  int res = nulink_usb_xfer(handle, h->databuf, h->cmdsize);
199  if (res != ERROR_OK)
200  return res;
201 
202  LOG_INFO("Nu-Link firmware_version %" PRIu32 ", product_id (0x%08" PRIx32 ")",
203  le_to_h_u32(h->databuf),
204  le_to_h_u32(h->databuf + 4 * 1));
205 
206  const bool is_nulinkpro = !!(le_to_h_u32(h->databuf + 4 * 2) & 1);
207  if (is_nulinkpro) {
208  LOG_INFO("Adapter is Nu-Link-Pro, target_voltage_mv(%" PRIu16 "), usb_voltage_mv(%" PRIu16 ")",
209  le_to_h_u16(h->databuf + 4 * 3 + 0),
210  le_to_h_u16(h->databuf + 4 * 3 + 2));
211 
213  } else {
214  LOG_INFO("Adapter is Nu-Link");
215  }
216 
217  return ERROR_OK;
218 }
219 
220 static int nulink_usb_idcode(void *handle, uint32_t *idcode)
221 {
222  struct nulink_usb_handle_s *h = handle;
223 
224  LOG_DEBUG("nulink_usb_idcode");
225 
226  assert(handle);
227 
228  nulink_usb_init_buffer(handle, 4 * 1);
229  /* set command ID */
231  h->cmdidx += 4;
232 
233  int res = nulink_usb_xfer(handle, h->databuf, 4 * 2);
234  if (res != ERROR_OK)
235  return res;
236 
237  *idcode = le_to_h_u32(h->databuf + 4 * 1);
238 
239  LOG_INFO("IDCODE: 0x%08" PRIX32, *idcode);
240 
241  return ERROR_OK;
242 }
243 
244 static int nulink_usb_write_debug_reg(void *handle, uint32_t addr, uint32_t val)
245 {
246  struct nulink_usb_handle_s *h = handle;
247 
248  LOG_DEBUG("nulink_usb_write_debug_reg 0x%08" PRIX32 " 0x%08" PRIX32, addr, val);
249 
250  nulink_usb_init_buffer(handle, 8 + 12 * 1);
251  /* set command ID */
253  h->cmdidx += 4;
254  /* Count of registers */
255  h->cmdbuf[h->cmdidx] = 1;
256  h->cmdidx += 1;
257  /* Array of bool value (u8ReadOld) */
258  h->cmdbuf[h->cmdidx] = 0x00;
259  h->cmdidx += 1;
260  /* Array of bool value (u8Verify) */
261  h->cmdbuf[h->cmdidx] = 0x00;
262  h->cmdidx += 1;
263  /* ignore */
264  h->cmdbuf[h->cmdidx] = 0;
265  h->cmdidx += 1;
266  /* u32Addr */
267  h_u32_to_le(h->cmdbuf + h->cmdidx, addr);
268  h->cmdidx += 4;
269  /* u32Data */
270  h_u32_to_le(h->cmdbuf + h->cmdidx, val);
271  h->cmdidx += 4;
272  /* u32Mask */
273  h_u32_to_le(h->cmdbuf + h->cmdidx, 0x00000000UL);
274  h->cmdidx += 4;
275 
276  return nulink_usb_xfer(handle, h->databuf, 4 * 2);
277 }
278 
279 static enum target_state nulink_usb_state(void *handle)
280 {
281  struct nulink_usb_handle_s *h = handle;
282 
283  assert(handle);
284 
285  nulink_usb_init_buffer(handle, 4 * 1);
286  /* set command ID */
288  h->cmdidx += 4;
289 
290  int res = nulink_usb_xfer(handle, h->databuf, 4 * 4);
291  if (res != ERROR_OK)
292  return TARGET_UNKNOWN;
293 
294  if (!le_to_h_u32(h->databuf + 4 * 2))
295  return TARGET_HALTED;
296  else
297  return TARGET_RUNNING;
298 }
299 
300 static int nulink_usb_assert_srst(void *handle, int srst)
301 {
302  struct nulink_usb_handle_s *h = handle;
303 
304  LOG_DEBUG("nulink_usb_assert_srst");
305 
306  assert(handle);
307 
308  nulink_usb_init_buffer(handle, 4 * 4);
309  /* set command ID */
311  h->cmdidx += 4;
312  /* set reset type */
314  h->cmdidx += 4;
315  /* set connect type */
317  h->cmdidx += 4;
318  /* set extMode */
319  h_u32_to_le(h->cmdbuf + h->cmdidx, 0);
320  h->cmdidx += 4;
321 
322  return nulink_usb_xfer(handle, h->databuf, 4 * 4);
323 }
324 
325 static int nulink_usb_reset(void *handle)
326 {
327  struct nulink_usb_handle_s *h = handle;
328 
329  LOG_DEBUG("nulink_usb_reset");
330 
331  assert(handle);
332 
333  nulink_usb_init_buffer(handle, 4 * 4);
334  /* set command ID */
336  h->cmdidx += 4;
337  /* set reset type */
338  h_u32_to_le(h->cmdbuf + h->cmdidx, RESET_HW);
339  h->cmdidx += 4;
340  /* set connect type */
342  h->cmdidx += 4;
343  /* set extMode */
344  h_u32_to_le(h->cmdbuf + h->cmdidx, 0);
345  h->cmdidx += 4;
346 
347  return nulink_usb_xfer(handle, h->databuf, 4 * 4);
348 }
349 
350 static int nulink_usb_run(void *handle)
351 {
352  struct nulink_usb_handle_s *h = handle;
353 
354  LOG_DEBUG("nulink_usb_run");
355 
356  assert(handle);
357 
358  nulink_usb_init_buffer(handle, 4 * 1);
359  /* set command ID */
361  h->cmdidx += 4;
362 
363  return nulink_usb_xfer(handle, h->databuf, 4 * 4);
364 }
365 
366 static int nulink_usb_halt(void *handle)
367 {
368  struct nulink_usb_handle_s *h = handle;
369 
370  LOG_DEBUG("nulink_usb_halt");
371 
372  assert(handle);
373 
374  nulink_usb_init_buffer(handle, 4 * 1);
375  /* set command ID */
377  h->cmdidx += 4;
378 
379  int res = nulink_usb_xfer(handle, h->databuf, 4 * 4);
380 
381  LOG_DEBUG("Nu-Link stop_pc 0x%08" PRIx32, le_to_h_u32(h->databuf + 4));
382 
383  return res;
384 }
385 
386 static int nulink_usb_step(void *handle)
387 {
388  struct nulink_usb_handle_s *h = handle;
389 
390  LOG_DEBUG("nulink_usb_step");
391 
392  assert(handle);
393 
394  nulink_usb_init_buffer(handle, 4 * 1);
395  /* set command ID */
397  h->cmdidx += 4;
398 
399  int res = nulink_usb_xfer(handle, h->databuf, 4 * 4);
400 
401  LOG_DEBUG("Nu-Link pc 0x%08" PRIx32, le_to_h_u32(h->databuf + 4));
402 
403  return res;
404 }
405 
406 static int nulink_usb_read_reg(void *handle, unsigned int regsel, uint32_t *val)
407 {
408  struct nulink_usb_handle_s *h = handle;
409 
410  assert(handle);
411 
412  nulink_usb_init_buffer(handle, 8 + 12 * 1);
413  /* set command ID */
415  h->cmdidx += 4;
416  /* Count of registers */
417  h->cmdbuf[h->cmdidx] = 1;
418  h->cmdidx += 1;
419  /* Array of bool value (u8ReadOld) */
420  h->cmdbuf[h->cmdidx] = 0xFF;
421  h->cmdidx += 1;
422  /* Array of bool value (u8Verify) */
423  h->cmdbuf[h->cmdidx] = 0x00;
424  h->cmdidx += 1;
425  /* ignore */
426  h->cmdbuf[h->cmdidx] = 0;
427  h->cmdidx += 1;
428  /* u32Addr */
429  h_u32_to_le(h->cmdbuf + h->cmdidx, regsel);
430  h->cmdidx += 4;
431  /* u32Data */
432  h_u32_to_le(h->cmdbuf + h->cmdidx, 0);
433  h->cmdidx += 4;
434  /* u32Mask */
435  h_u32_to_le(h->cmdbuf + h->cmdidx, 0xFFFFFFFFUL);
436  h->cmdidx += 4;
437 
438  int res = nulink_usb_xfer(handle, h->databuf, 4 * 2);
439 
440  *val = le_to_h_u32(h->databuf + 4 * 1);
441 
442  return res;
443 }
444 
445 static int nulink_usb_write_reg(void *handle, unsigned int regsel, uint32_t val)
446 {
447  struct nulink_usb_handle_s *h = handle;
448 
449  assert(handle);
450 
451  nulink_usb_init_buffer(handle, 8 + 12 * 1);
452  /* set command ID */
454  h->cmdidx += 4;
455  /* Count of registers */
456  h->cmdbuf[h->cmdidx] = 1;
457  h->cmdidx += 1;
458  /* Array of bool value (u8ReadOld) */
459  h->cmdbuf[h->cmdidx] = 0x00;
460  h->cmdidx += 1;
461  /* Array of bool value (u8Verify) */
462  h->cmdbuf[h->cmdidx] = 0x00;
463  h->cmdidx += 1;
464  /* ignore */
465  h->cmdbuf[h->cmdidx] = 0;
466  h->cmdidx += 1;
467  /* u32Addr */
468  h_u32_to_le(h->cmdbuf + h->cmdidx, regsel);
469  h->cmdidx += 4;
470  /* u32Data */
471  h_u32_to_le(h->cmdbuf + h->cmdidx, val);
472  h->cmdidx += 4;
473  /* u32Mask */
474  h_u32_to_le(h->cmdbuf + h->cmdidx, 0x00000000UL);
475  h->cmdidx += 4;
476 
477  return nulink_usb_xfer(handle, h->databuf, 4 * 2);
478 }
479 
480 static int nulink_usb_read_mem8(void *handle, uint32_t addr, uint16_t len,
481  uint8_t *buffer)
482 {
483  int res = ERROR_OK;
484  uint32_t offset = 0;
485  uint32_t bytes_remaining = 12;
486  struct nulink_usb_handle_s *h = handle;
487 
488  LOG_DEBUG("nulink_usb_read_mem8: addr 0x%08" PRIx32 ", len %" PRId16, addr, len);
489 
490  assert(handle);
491 
492  /* check whether data is word aligned */
493  if (addr % 4) {
494  uint32_t aligned_addr = addr / 4;
495  aligned_addr = aligned_addr * 4;
496  offset = addr - aligned_addr;
497  LOG_DEBUG("nulink_usb_read_mem8: unaligned address addr 0x%08" PRIx32
498  "/aligned addr 0x%08" PRIx32 " offset %" PRIu32,
499  addr, aligned_addr, offset);
500 
501  addr = aligned_addr;
502  }
503 
504  while (len) {
505  unsigned int count;
506 
507  if (len < bytes_remaining)
508  bytes_remaining = len;
509 
510  if (len < 4)
511  count = 1;
512  else
513  count = 2;
514 
515  nulink_usb_init_buffer(handle, 8 + 12 * count);
516  /* set command ID */
518  h->cmdidx += 4;
519  /* Count of registers */
520  h->cmdbuf[h->cmdidx] = count;
521  h->cmdidx += 1;
522  /* Array of bool value (u8ReadOld) */
523  h->cmdbuf[h->cmdidx] = 0xFF;
524  h->cmdidx += 1;
525  /* Array of bool value (u8Verify) */
526  h->cmdbuf[h->cmdidx] = 0x00;
527  h->cmdidx += 1;
528  /* ignore */
529  h->cmdbuf[h->cmdidx] = 0;
530  h->cmdidx += 1;
531 
532  for (unsigned int i = 0; i < count; i++) {
533  /* u32Addr */
534  h_u32_to_le(h->cmdbuf + h->cmdidx, addr);
535  h->cmdidx += 4;
536  /* u32Data */
537  h_u32_to_le(h->cmdbuf + h->cmdidx, 0);
538  h->cmdidx += 4;
539  /* u32Mask */
540  h_u32_to_le(h->cmdbuf + h->cmdidx, 0xFFFFFFFFUL);
541  h->cmdidx += 4;
542  /* proceed to the next one */
543  addr += 4;
544  }
545 
546  res = nulink_usb_xfer(handle, h->databuf, 4 * count * 2);
547  if (res != ERROR_OK)
548  break;
549 
550  /* fill in the output buffer */
551  for (unsigned int i = 0; i < count; i++) {
552  if (i == 0)
553  memcpy(buffer, h->databuf + 4 + offset, len);
554  else
555  memcpy(buffer + 2 * i, h->databuf + 4 * (2 * i + 1), len - 2);
556  }
557 
558  if (len >= bytes_remaining)
559  len -= bytes_remaining;
560  }
561 
562  return res;
563 }
564 
565 static int nulink_usb_write_mem8(void *handle, uint32_t addr, uint16_t len,
566  const uint8_t *buffer)
567 {
568  int res = ERROR_OK;
569  uint32_t offset = 0;
570  uint32_t bytes_remaining = 12;
571  struct nulink_usb_handle_s *h = handle;
572 
573  LOG_DEBUG("nulink_usb_write_mem8: addr 0x%08" PRIx32 ", len %" PRIu16, addr, len);
574 
575  assert(handle);
576 
577  /* check whether data is word aligned */
578  if (addr % 4) {
579  uint32_t aligned_addr = addr / 4;
580  aligned_addr = aligned_addr * 4;
581  offset = addr - aligned_addr;
582  LOG_DEBUG("nulink_usb_write_mem8: address not aligned. addr(0x%08" PRIx32
583  ")/aligned_addr(0x%08" PRIx32 ")/offset(%" PRIu32 ")",
584  addr, aligned_addr, offset);
585 
586  addr = aligned_addr;
587  }
588 
589  while (len) {
590  unsigned int count;
591 
592  if (len < bytes_remaining)
593  bytes_remaining = len;
594 
595  if (len < 4)
596  count = 1;
597  else
598  count = 2;
599 
600  nulink_usb_init_buffer(handle, 8 + 12 * count);
601  /* set command ID */
603  h->cmdidx += 4;
604  /* Count of registers */
605  h->cmdbuf[h->cmdidx] = count;
606  h->cmdidx += 1;
607  /* Array of bool value (u8ReadOld) */
608  h->cmdbuf[h->cmdidx] = 0x00;
609  h->cmdidx += 1;
610  /* Array of bool value (u8Verify) */
611  h->cmdbuf[h->cmdidx] = 0x00;
612  h->cmdidx += 1;
613  /* ignore */
614  h->cmdbuf[h->cmdidx] = 0;
615  h->cmdidx += 1;
616 
617  for (unsigned int i = 0; i < count; i++) {
618  /* u32Addr */
619  h_u32_to_le(h->cmdbuf + h->cmdidx, addr);
620  h->cmdidx += 4;
621  /* u32Data */
622  uint32_t u32buffer = buf_get_u32(buffer, 0, len * 8);
623  u32buffer = (u32buffer << offset * 8);
624  h_u32_to_le(h->cmdbuf + h->cmdidx, u32buffer);
625  h->cmdidx += 4;
626  /* u32Mask */
627  if (i == 0) {
628  if (offset == 0) {
629  if (len == 1) {
630  h_u32_to_le(h->cmdbuf + h->cmdidx, 0xFFFFFF00UL);
631  LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFFFFFF00", i);
632  } else {
633  h_u32_to_le(h->cmdbuf + h->cmdidx, 0xFFFF0000UL);
634  LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFFFF0000", i);
635  }
636  } else {
637  if (len == 1) {
638  h_u32_to_le(h->cmdbuf + h->cmdidx, 0xFF00FFFFUL);
639  LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFF00FFFF", i);
640 
641  } else {
642  h_u32_to_le(h->cmdbuf + h->cmdidx, 0x0000FFFFUL);
643  LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0x0000FFFF", i);
644  }
645  }
646  } else {
647  if (len == 4) {
648  h_u32_to_le(h->cmdbuf + h->cmdidx, 0xFFFF0000UL);
649  LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0xFFFF0000", i);
650  } else {
651  h_u32_to_le(h->cmdbuf + h->cmdidx, 0x00000000UL);
652  LOG_DEBUG("nulink_usb_write_mem8: count(%u), mask: 0x00000000", i);
653  }
654  }
655  h->cmdidx += 4;
656 
657  /* proceed to the next one */
658  addr += 4;
659  buffer += 4;
660  }
661 
662  res = nulink_usb_xfer(handle, h->databuf, 4 * count * 2);
663  if (res != ERROR_OK)
664  break;
665 
666  if (len >= bytes_remaining)
667  len -= bytes_remaining;
668  }
669 
670  return res;
671 }
672 
673 static int nulink_usb_read_mem32(void *handle, uint32_t addr, uint16_t len,
674  uint8_t *buffer)
675 {
676  int res = ERROR_OK;
677  uint32_t bytes_remaining = 12;
678  struct nulink_usb_handle_s *h = handle;
679 
680  assert(handle);
681 
682  /* data must be a multiple of 4 and word aligned */
683  if (len % 4 || addr % 4) {
684  LOG_ERROR("Invalid data alignment");
686  }
687 
688  while (len) {
689  if (len < bytes_remaining)
690  bytes_remaining = len;
691 
692  unsigned int count = bytes_remaining / 4;
693 
694  nulink_usb_init_buffer(handle, 8 + 12 * count);
695  /* set command ID */
697  h->cmdidx += 4;
698  /* Count of registers */
699  h->cmdbuf[h->cmdidx] = count;
700  h->cmdidx += 1;
701  /* Array of bool value (u8ReadOld) */
702  h->cmdbuf[h->cmdidx] = 0xFF;
703  h->cmdidx += 1;
704  /* Array of bool value (u8Verify) */
705  h->cmdbuf[h->cmdidx] = 0x00;
706  h->cmdidx += 1;
707  /* ignore */
708  h->cmdbuf[h->cmdidx] = 0;
709  h->cmdidx += 1;
710 
711  for (unsigned int i = 0; i < count; i++) {
712  /* u32Addr */
713  h_u32_to_le(h->cmdbuf + h->cmdidx, addr);
714  h->cmdidx += 4;
715  /* u32Data */
716  h_u32_to_le(h->cmdbuf + h->cmdidx, 0);
717  h->cmdidx += 4;
718  /* u32Mask */
719  h_u32_to_le(h->cmdbuf + h->cmdidx, 0xFFFFFFFFUL);
720  h->cmdidx += 4;
721  /* proceed to the next one */
722  addr += 4;
723  }
724 
725  res = nulink_usb_xfer(handle, h->databuf, 4 * count * 2);
726 
727  /* fill in the output buffer */
728  for (unsigned int i = 0; i < count; i++) {
729  memcpy(buffer, h->databuf + 4 * (2 * i + 1), 4);
730  buffer += 4;
731  }
732 
733  if (len >= bytes_remaining)
734  len -= bytes_remaining;
735  else
736  len = 0;
737  }
738 
739  return res;
740 }
741 
742 static int nulink_usb_write_mem32(void *handle, uint32_t addr, uint16_t len,
743  const uint8_t *buffer)
744 {
745  int res = ERROR_OK;
746  uint32_t bytes_remaining = 12;
747  struct nulink_usb_handle_s *h = handle;
748 
749  assert(handle);
750 
751  /* data must be a multiple of 4 and word aligned */
752  if (len % 4 || addr % 4) {
753  LOG_ERROR("Invalid data alignment");
755  }
756 
757  while (len) {
758  if (len < bytes_remaining)
759  bytes_remaining = len;
760 
761  unsigned int count = bytes_remaining / 4;
762 
763  nulink_usb_init_buffer(handle, 8 + 12 * count);
764  /* set command ID */
766  h->cmdidx += 4;
767  /* Count of registers */
768  h->cmdbuf[h->cmdidx] = count;
769  h->cmdidx += 1;
770  /* Array of bool value (u8ReadOld) */
771  h->cmdbuf[h->cmdidx] = 0x00;
772  h->cmdidx += 1;
773  /* Array of bool value (u8Verify) */
774  h->cmdbuf[h->cmdidx] = 0x00;
775  h->cmdidx += 1;
776  /* ignore */
777  h->cmdbuf[h->cmdidx] = 0;
778  h->cmdidx += 1;
779 
780  for (unsigned int i = 0; i < count; i++) {
781  /* u32Addr */
782  h_u32_to_le(h->cmdbuf + h->cmdidx, addr);
783  h->cmdidx += 4;
784  /* u32Data */
785  uint32_t u32buffer = buf_get_u32(buffer, 0, 32);
786  h_u32_to_le(h->cmdbuf + h->cmdidx, u32buffer);
787  h->cmdidx += 4;
788  /* u32Mask */
789  h_u32_to_le(h->cmdbuf + h->cmdidx, 0x00000000);
790  h->cmdidx += 4;
791 
792  /* proceed to the next one */
793  addr += 4;
794  buffer += 4;
795  }
796 
797  res = nulink_usb_xfer(handle, h->databuf, 4 * count * 2);
798 
799  if (len >= bytes_remaining)
800  len -= bytes_remaining;
801  else
802  len = 0;
803  }
804 
805  return res;
806 }
807 
808 static uint32_t nulink_max_block_size(uint32_t tar_autoincr_block, uint32_t address)
809 {
810  uint32_t max_tar_block = (tar_autoincr_block - ((tar_autoincr_block - 1) & address));
811 
812  if (max_tar_block == 0)
813  max_tar_block = 4;
814 
815  return max_tar_block;
816 }
817 
818 static int nulink_usb_read_mem(void *handle, uint32_t addr, uint32_t size,
819  uint32_t count, uint8_t *buffer)
820 {
821  int retval = ERROR_OK;
822  struct nulink_usb_handle_s *h = handle;
823 
824  /* calculate byte count */
825  count *= size;
826 
827  while (count) {
828  uint32_t bytes_remaining = nulink_max_block_size(h->max_mem_packet, addr);
829 
830  if (count < bytes_remaining)
831  bytes_remaining = count;
832 
833  if (bytes_remaining >= 4)
834  size = 4;
835 
836  /* the nulink only supports 8/32bit memory read/writes
837  * honour 32bit, all others will be handled as 8bit access */
838  if (size == 4) {
839  /* When in jtag mode the nulink uses the auto-increment functionality.
840  * However it expects us to pass the data correctly, this includes
841  * alignment and any page boundaries. We already do this as part of the
842  * adi_v5 implementation, but the nulink is a hla adapter and so this
843  * needs implementing manually.
844  * currently this only affects jtag mode, they do single
845  * access in SWD mode - but this may change and so we do it for both modes */
846 
847  /* we first need to check for any unaligned bytes */
848  if (addr % 4) {
849  uint32_t head_bytes = 4 - (addr % 4);
850  retval = nulink_usb_read_mem8(handle, addr, head_bytes, buffer);
851  if (retval != ERROR_OK)
852  return retval;
853  buffer += head_bytes;
854  addr += head_bytes;
855  count -= head_bytes;
856  bytes_remaining -= head_bytes;
857  }
858 
859  if (bytes_remaining % 4)
860  retval = nulink_usb_read_mem(handle, addr, 1, bytes_remaining, buffer);
861  else
862  retval = nulink_usb_read_mem32(handle, addr, bytes_remaining, buffer);
863  } else {
864  retval = nulink_usb_read_mem8(handle, addr, bytes_remaining, buffer);
865  }
866 
867  if (retval != ERROR_OK)
868  return retval;
869 
870  buffer += bytes_remaining;
871  addr += bytes_remaining;
872  count -= bytes_remaining;
873  }
874 
875  return retval;
876 }
877 
878 static int nulink_usb_write_mem(void *handle, uint32_t addr, uint32_t size,
879  uint32_t count, const uint8_t *buffer)
880 {
881  int retval = ERROR_OK;
882  struct nulink_usb_handle_s *h = handle;
883 
884  if (addr < ARM_SRAM_BASE) {
885  LOG_DEBUG("nulink_usb_write_mem: address below ARM_SRAM_BASE, not supported.\n");
886  return retval;
887  }
888 
889  /* calculate byte count */
890  count *= size;
891 
892  while (count) {
893  uint32_t bytes_remaining = nulink_max_block_size(h->max_mem_packet, addr);
894 
895  if (count < bytes_remaining)
896  bytes_remaining = count;
897 
898  if (bytes_remaining >= 4)
899  size = 4;
900 
901  /* the nulink only supports 8/32bit memory read/writes
902  * honour 32bit, all others will be handled as 8bit access */
903  if (size == 4) {
904  /* When in jtag mode the nulink uses the auto-increment functionality.
905  * However it expects us to pass the data correctly, this includes
906  * alignment and any page boundaries. We already do this as part of the
907  * adi_v5 implementation, but the nulink is a hla adapter and so this
908  * needs implementing manually.
909  * currently this only affects jtag mode, do single
910  * access in SWD mode - but this may change and so we do it for both modes */
911 
912  /* we first need to check for any unaligned bytes */
913  if (addr % 4) {
914  uint32_t head_bytes = 4 - (addr % 4);
915  retval = nulink_usb_write_mem8(handle, addr, head_bytes, buffer);
916  if (retval != ERROR_OK)
917  return retval;
918  buffer += head_bytes;
919  addr += head_bytes;
920  count -= head_bytes;
921  bytes_remaining -= head_bytes;
922  }
923 
924  if (bytes_remaining % 4)
925  retval = nulink_usb_write_mem(handle, addr, 1, bytes_remaining, buffer);
926  else
927  retval = nulink_usb_write_mem32(handle, addr, bytes_remaining, buffer);
928 
929  } else {
930  retval = nulink_usb_write_mem8(handle, addr, bytes_remaining, buffer);
931  }
932 
933  if (retval != ERROR_OK)
934  return retval;
935 
936  buffer += bytes_remaining;
937  addr += bytes_remaining;
938  count -= bytes_remaining;
939  }
940 
941  return retval;
942 }
943 
944 static int nulink_usb_override_target(const char *targetname)
945 {
946  LOG_DEBUG("nulink_usb_override_target");
947 
948  return !strcmp(targetname, "cortex_m");
949 }
950 
951 static int nulink_speed(void *handle, int khz, bool query)
952 {
953  struct nulink_usb_handle_s *h = handle;
954  unsigned long max_ice_clock = khz;
955 
956  LOG_DEBUG("nulink_speed: query %s", query ? "yes" : "no");
957 
958  if (max_ice_clock > 12000)
959  max_ice_clock = 12000;
960  else if ((max_ice_clock == 3 * 512) || (max_ice_clock == 1500))
961  max_ice_clock = 1500;
962  else if (max_ice_clock >= 1000)
963  max_ice_clock = max_ice_clock / 1000 * 1000;
964  else
965  max_ice_clock = max_ice_clock / 100 * 100;
966 
967  LOG_DEBUG("Nu-Link nulink_speed: %lu", max_ice_clock);
968 
969  if (!query) {
970  nulink_usb_init_buffer(handle, 4 * 6);
971  /* set command ID */
973  h->cmdidx += 4;
974  /* set max SWD clock */
975  h_u32_to_le(h->cmdbuf + h->cmdidx, max_ice_clock);
976  h->cmdidx += 4;
977  /* chip type: NUC_CHIP_TYPE_GENERAL_V6M */
978  h_u32_to_le(h->cmdbuf + h->cmdidx, 0);
979  h->cmdidx += 4;
980  /* IO voltage */
981  h_u32_to_le(h->cmdbuf + h->cmdidx, 5000);
982  h->cmdidx += 4;
983  /* If supply voltage to target or not */
984  h_u32_to_le(h->cmdbuf + h->cmdidx, 0);
985  h->cmdidx += 4;
986  /* USB_FUNC_E: USB_FUNC_HID_BULK */
987  h_u32_to_le(h->cmdbuf + h->cmdidx, 2);
988  h->cmdidx += 4;
989 
990  nulink_usb_xfer(handle, h->databuf, 4 * 3);
991 
992  LOG_DEBUG("nulink_speed: h->hardware_config(%" PRId16 ")", h->hardware_config);
994  LOG_INFO("Nu-Link target_voltage_mv[0](%04" PRIx16 "), target_voltage_mv[1](%04" PRIx16
995  "), target_voltage_mv[2](%04" PRIx16 "), if_target_power_supplied(%d)",
996  le_to_h_u16(h->databuf + 4 * 1 + 0),
997  le_to_h_u16(h->databuf + 4 * 1 + 2),
998  le_to_h_u16(h->databuf + 4 * 2 + 0),
999  le_to_h_u16(h->databuf + 4 * 2 + 2) & 1);
1000  }
1001 
1002  return max_ice_clock;
1003 }
1004 
1005 static int nulink_usb_close(void *handle)
1006 {
1007  struct nulink_usb_handle_s *h = handle;
1008 
1009  LOG_DEBUG("nulink_usb_close");
1010 
1011  if (h && h->dev_handle)
1012  hid_close(h->dev_handle);
1013 
1014  free(h);
1015 
1016  hid_exit();
1017 
1018  return ERROR_OK;
1019 }
1020 
1021 static int nulink_usb_open(struct hl_interface_param_s *param, void **fd)
1022 {
1023  struct hid_device_info *devs, *cur_dev;
1024  uint16_t target_vid = 0;
1025  uint16_t target_pid = 0;
1026  wchar_t *target_serial = NULL;
1027 
1028  LOG_DEBUG("nulink_usb_open");
1029 
1030  if (param->transport != HL_TRANSPORT_SWD)
1031  return TARGET_UNKNOWN;
1032 
1033  if (!param->vid[0] && !param->pid[0]) {
1034  LOG_ERROR("Missing vid/pid");
1035  return ERROR_FAIL;
1036  }
1037 
1038  if (hid_init() != 0) {
1039  LOG_ERROR("unable to open HIDAPI");
1040  return ERROR_FAIL;
1041  }
1042 
1043  struct nulink_usb_handle_s *h = calloc(1, sizeof(*h));
1044  if (!h) {
1045  LOG_ERROR("Out of memory");
1046  goto error_open;
1047  }
1048 
1049  const char *serial = adapter_get_required_serial();
1050  if (serial) {
1051  size_t len = mbstowcs(NULL, serial, 0);
1052 
1053  target_serial = calloc(len + 1, sizeof(wchar_t));
1054  if (!target_serial) {
1055  LOG_ERROR("Out of memory");
1056  goto error_open;
1057  }
1058 
1059  if (mbstowcs(target_serial, serial, len + 1) == (size_t)(-1)) {
1060  LOG_WARNING("unable to convert serial");
1061  free(target_serial);
1062  target_serial = NULL;
1063  }
1064  }
1065 
1066  devs = hid_enumerate(0, 0);
1067  cur_dev = devs;
1068  while (cur_dev) {
1069  bool found = false;
1070 
1071  for (unsigned int i = 0; param->vid[i] || param->pid[i]; i++) {
1072  if (param->vid[i] == cur_dev->vendor_id && param->pid[i] == cur_dev->product_id) {
1073  found = true;
1074  break;
1075  }
1076  }
1077 
1078  if (found) {
1079  if (!target_serial)
1080  break;
1081  if (cur_dev->serial_number && wcscmp(target_serial, cur_dev->serial_number) == 0)
1082  break;
1083  }
1084 
1085  cur_dev = cur_dev->next;
1086  }
1087  if (cur_dev) {
1088  target_vid = cur_dev->vendor_id;
1089  target_pid = cur_dev->product_id;
1090  }
1091 
1092  hid_free_enumeration(devs);
1093 
1094  if (target_vid == 0 && target_pid == 0) {
1095  LOG_ERROR("unable to find Nu-Link");
1096  goto error_open;
1097  }
1098 
1099  hid_device *dev = hid_open(target_vid, target_pid, target_serial);
1100  if (!dev) {
1101  LOG_ERROR("unable to open Nu-Link device 0x%" PRIx16 ":0x%" PRIx16, target_vid, target_pid);
1102  goto error_open;
1103  }
1104 
1105  h->dev_handle = dev;
1106  h->usbcmdidx = 0;
1107 
1108  switch (target_pid) {
1109  case NULINK2_USB_PID1:
1110  case NULINK2_USB_PID2:
1114  h->xfer = nulink2_usb_xfer;
1115  break;
1116  default:
1117  h->hardware_config = 0;
1120  h->xfer = nulink1_usb_xfer;
1121  break;
1122  }
1123 
1124  /* get the device version */
1125  h->cmdsize = 4 * 5;
1126  int err = nulink_usb_version(h);
1127  if (err != ERROR_OK) {
1128  LOG_DEBUG("nulink_usb_version failed with cmdSize(4 * 5)");
1129  h->cmdsize = 4 * 6;
1130  err = nulink_usb_version(h);
1131  if (err != ERROR_OK)
1132  LOG_DEBUG("nulink_usb_version failed with cmdSize(4 * 6)");
1133  }
1134 
1135  /* SWD clock rate : 1MHz */
1136  nulink_speed(h, 1000, false);
1137 
1138  /* get cpuid, so we can determine the max page size
1139  * start with a safe default */
1140  h->max_mem_packet = (1 << 10);
1141 
1142  LOG_DEBUG("nulink_usb_open: we manually perform nulink_usb_reset");
1143  nulink_usb_reset(h);
1144 
1145  *fd = h;
1146 
1147  free(target_serial);
1148  return ERROR_OK;
1149 
1150 error_open:
1151  nulink_usb_close(h);
1152  free(target_serial);
1153 
1154  return ERROR_FAIL;
1155 }
1156 
1158  .open = nulink_usb_open,
1159  .close = nulink_usb_close,
1160  .idcode = nulink_usb_idcode,
1161  .state = nulink_usb_state,
1162  .reset = nulink_usb_reset,
1163  .assert_srst = nulink_usb_assert_srst,
1164  .run = nulink_usb_run,
1165  .halt = nulink_usb_halt,
1166  .step = nulink_usb_step,
1167  .read_reg = nulink_usb_read_reg,
1168  .write_reg = nulink_usb_write_reg,
1169  .read_mem = nulink_usb_read_mem,
1170  .write_mem = nulink_usb_write_mem,
1171  .write_debug_reg = nulink_usb_write_debug_reg,
1172  .override_target = nulink_usb_override_target,
1173  .speed = nulink_speed,
1174 };
const char * adapter_get_required_serial(void)
Retrieves the serial number set with command 'adapter serial'.
Definition: adapter.c:299
char * serial
Definition: adapter.c:47
static struct aice_port_param_s param
Support functions to access arbitrary bits in a byte array.
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned first, unsigned num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 32-bit word.
Definition: binarybuffer.h:98
@ HL_TRANSPORT_SWD
Definition: hla_transport.h:16
static struct libusb_device ** devs
The usb device list.
Definition: libusb_helper.c:26
#define LOG_WARNING(expr ...)
Definition: log.h:120
#define ERROR_FAIL
Definition: log.h:161
#define LOG_ERROR(expr ...)
Definition: log.h:123
#define LOG_INFO(expr ...)
Definition: log.h:117
#define LOG_DEBUG(expr ...)
Definition: log.h:109
#define ERROR_OK
Definition: log.h:155
uint32_t addr
Definition: nuttx.c:65
size_t size
Size of the control block search area.
Definition: rtt/rtt.c:30
uint16_t vid
Definition: aice_port.h:99
int(* open)(struct hl_interface_param_s *param, void **handle)
Definition: hla_layout.h:29
#define ERROR_TARGET_UNALIGNED_ACCESS
Definition: target.h:794
target_state
Definition: target.h:52
@ TARGET_UNKNOWN
Definition: target.h:53
@ TARGET_HALTED
Definition: target.h:55
@ TARGET_RUNNING
Definition: target.h:54
static uint16_t le_to_h_u16(const uint8_t *buf)
Definition: types.h:122
static void h_u32_to_le(uint8_t *buf, uint32_t val)
Definition: types.h:178
static void h_u16_to_le(uint8_t *buf, uint16_t val)
Definition: types.h:208
static uint32_t le_to_h_u32(const uint8_t *buf)
Definition: types.h:112
#define NULL
Definition: usb.h:16
uint8_t offset[4]
Definition: vdebug.c:9
uint8_t count[4]
Definition: vdebug.c:22