0bb5ec4443541ee65c80e5bc196ba3340a898778
[fw/openocd] / src / jtag / drivers / nulink_usb.c
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
37 struct nulink_usb_handle_s {
38         hid_device *dev_handle;
39         uint16_t max_packet_size;
40         uint8_t usbcmdidx;
41         uint8_t cmdidx;
42         uint8_t cmdsize;
43         uint8_t cmdbuf[NULINK2_HID_MAX_SIZE + 1];
44         uint8_t tempbuf[NULINK2_HID_MAX_SIZE];
45         uint8_t databuf[NULINK2_HID_MAX_SIZE];
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
71 enum nulink_reset {
72         RESET_AUTO = 0,
73         RESET_HW = 1,
74         RESET_SYSRESETREQ = 2,
75         RESET_VECTRESET = 3,
76         RESET_FAST_RESCUE = 4, /* Rescue and erase the chip, need very fast speed */
77 };
78
79 enum nulink_connect {
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
192         nulink_usb_init_buffer(handle, V6M_MAX_COMMAND_LENGTH);
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
212                 h->hardware_config |= HARDWARE_CONFIG_NULINKPRO;
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 */
230         h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_CHECK_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 */
252         h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_RAM);
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 */
287         h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_CHECK_MCU_STOP);
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 */
310         h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_MCU_RESET);
311         h->cmdidx += 4;
312         /* set reset type */
313         h_u32_to_le(h->cmdbuf + h->cmdidx, RESET_SYSRESETREQ);
314         h->cmdidx += 4;
315         /* set connect type */
316         h_u32_to_le(h->cmdbuf + h->cmdidx, CONNECT_NORMAL);
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 */
335         h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_MCU_RESET);
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 */
341         h_u32_to_le(h->cmdbuf + h->cmdidx, CONNECT_NORMAL);
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 */
360         h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_MCU_FREE_RUN);
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 */
376         h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_MCU_STOP_RUN);
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 */
396         h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_MCU_STEP_RUN);
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 */
414         h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_REG);
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 */
453         h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_REG);
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 */
517                 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_RAM);
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 */
602                 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_RAM);
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");
685                 return ERROR_TARGET_UNALIGNED_ACCESS;
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 */
696                 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_RAM);
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");
754                 return ERROR_TARGET_UNALIGNED_ACCESS;
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 */
765                 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_RAM);
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 */
972                 h_u32_to_le(h->cmdbuf + h->cmdidx, CMD_SET_CONFIG);
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);
993                 if (h->hardware_config & HARDWARE_CONFIG_NULINKPRO)
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:
1111                 h->hardware_config = HARDWARE_CONFIG_NULINK2;
1112                 h->max_packet_size = NULINK2_HID_MAX_SIZE;
1113                 h->init_buffer = nulink2_usb_init_buffer;
1114                 h->xfer = nulink2_usb_xfer;
1115                 break;
1116         default:
1117                 h->hardware_config = 0;
1118                 h->max_packet_size = NULINK_HID_MAX_SIZE;
1119                 h->init_buffer = nulink1_usb_init_buffer;
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
1157 struct hl_layout_api_s nulink_usb_layout_api = {
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 };