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