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