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