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