blackmagic-sys 0.1.0

Bindings to Blackmagic-debug host functions
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
/*
 * This file is part of the Black Magic Debug project.
 *
 * Copyright (C) 2023 1BitSquared <info@1bitsquared.com>
 * Written by Rachel Mant <git@dragonmux.network>
 * Modified by Rafael Silva <perigoso@riseup.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.	 If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef PLATFORMS_HOSTED_JLINK_PROTOCOL_H
#define PLATFORMS_HOSTED_JLINK_PROTOCOL_H

#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>

/*
 * This file contains the definitions for the J-Link USB Protocol as defined in the RM08001 Reference manual (Chapter §5)
 * 
 * Overview
 * The J-Link firmware uses several commands in a request reply topology to communicate with the host software
 * Communication is always initiated by the host, which sends an 8 bit command to the probe followed by optional parameters
 * USB bulk communication is used to transfer data between host and J-Link
 * All data units larger than a single byte are transferred little endian, meaning least significant bytes are transferred first
 * All USB operations use a 5 second timeout
 * 
 * The commands have been reordered and renamed in the context of Black Magic Debug in an effort to make them more intuitive, consistent and easier to use.
 * The mapping between the J-Link USB Protocol reference manual commands and the new Black Magic Debug commands is listed at the start of each command group below.
 */

/* 
 * System information commands
 *
 * ┌────────────────────────────────────────────────┬──────────────────────────────────┐
 * │              BMDA J-Link command               │  RM08001 J-Link USB Protocol RM  │
 * ├────────────────────────────────────────────────┼──────────────────────────────────┤
 * │ JLINK_CMD_INFO_GET_FIRMWARE_VERSION            │ §5.3.1 EMU_CMD_VERSION           │
 * │ JLINK_CMD_INFO_GET_HARDWARE_VERSION            │ §5.3.6 EMU_CMD_GET_HW_VERSION    │
 * │ JLINK_CMD_INFO_GET_PROBE_CAPABILITIES          │ §5.3.4 EMU_CMD_GET_CAPS          │
 * │ JLINK_CMD_INFO_GET_PROBE_EXTENDED_CAPABILITIES │ §5.3.5 EMU_CMD_GET_CAPS_EX       │
 * │ JLINK_CMD_INFO_GET_MAX_MEM_BLOCK               │ §5.3.3 EMU_CMD_GET_MAX_MEM_BLOCK │
 * └────────────────────────────────────────────────┴──────────────────────────────────┘
 */
#define JLINK_CMD_INFO_GET_FIRMWARE_VERSION            0x01U /* Get probe firmware version string */
#define JLINK_CMD_INFO_GET_HARDWARE_VERSION            0xf0U /* Get probe hardware version */
#define JLINK_CMD_INFO_GET_PROBE_CAPABILITIES          0xe8U /* Get probe capabilities */
#define JLINK_CMD_INFO_GET_PROBE_EXTENDED_CAPABILITIES 0xedU /* Get probe extended capabilities */
#define JLINK_CMD_INFO_GET_MAX_MEM_BLOCK               0xd4U /* Get the maximum memory blocksize */

/* 
 * Interface commands
 *
 * ┌────────────────────────────────────────┬────────────────────────────────┐
 * │          BMDA J-Link command           │ RM08001 J-Link USB Protocol RM │
 * ├────────────────────────────────────────┼────────────────────────────────┤
 * │ JLINK_CMD_INTERFACE_GET_BASE_FREQUENCY │ §5.3.2 EMU_CMD_GET_SPEEDS      │
 * │ JLINK_CMD_INTERFACE_SET_FREQUENCY_KHZ  │ §5.5.2 EMU_CMD_SET_SPEED       │
 * │ JLINK_CMD_INTERFACE_SET_SELECTED       │ §5.5.3 EMU_CMD_SELECT_IF       │
 * │ JLINK_CMD_INTERFACE_GET                │ §5.5.3 EMU_CMD_SELECT_IF       │
 * └────────────────────────────────────────┴────────────────────────────────┘
 */
#define JLINK_CMD_INTERFACE_GET_BASE_FREQUENCY 0xc0U /* Get base frequency and minimum divider of selected interface */
#define JLINK_CMD_INTERFACE_SET_FREQUENCY_KHZ  0x05U /* Sets the interface speed in kHz*/
#define JLINK_CMD_INTERFACE_SET_SELECTED       0xc7U /* Select the probe interface */
#define JLINK_CMD_INTERFACE_GET                0xc7U /* Get current selected interface or available interfaces */

/* 
 * Target power commands
 *
 * ┌───────────────────────────────┬────────────────────────────────┐
 * │      BMDA J-Link command      │ RM08001 J-Link USB Protocol RM │
 * ├───────────────────────────────┼────────────────────────────────┤
 * │ JLINK_CMD_POWER_SET_KICKSTART │ §5.5.4 EMU_CMD_SET_KS_POWER    │
 * │ JLINK_CMD_POWER_GET_STATE     │ §5.4.2 EMU_CMD_GET_HW_INFO     │
 * └───────────────────────────────┴────────────────────────────────┘
 */
#define JLINK_CMD_POWER_SET_KICKSTART 0x08U /* Set KickStart power state on pin 19 (J-Link 20 pin connector) */
#define JLINK_CMD_POWER_GET_STATE     0xc1U /* Get Kickstart power state and overcurrent timers */

/* 
 * Low level hardware commands
 *
 * ┌──────────────────────────────┬────────────────────────────────┐
 * │     BMDA J-Link command      │ RM08001 J-Link USB Protocol RM │
 * ├──────────────────────────────┼────────────────────────────────┤
 * │ JLINK_CMD_SIGNAL_GET_STATE   │ §5.4.1  EMU_CMD_GET_STATE      │
 * │ JLINK_CMD_SIGNAL_CLEAR_RESET │ §5.6.4  EMU_CMD_HW_RESET0      │
 * │ JLINK_CMD_SIGNAL_SET_RESET   │ §5.6.5  EMU_CMD_HW_RESET1      │
 * │ JLINK_CMD_SIGNAL_PULSE_RESET │ §5.6.1  EMU_CMD_RESET_TARGET   │
 * │ JLINK_CMD_SIGNAL_CLEAR_TRST  │ §5.5.15 EMU_CMD_HW_TRST0       │
 * │ JLINK_CMD_SIGNAL_SET_TRST    │ §5.5.16 EMU_CMD_HW_TRST1       │
 * │ JLINK_CMD_SIGNAL_PULSE_TRST  │ §5.5.1  EMU_CMD_RESET_TRST     │
 * │ JLINK_CMD_SIGNAL_CLEAR_TMS   │ §5.5.6  EMU_CMD_HW_TMS0        │
 * │ JLINK_CMD_SIGNAL_SET_TMS     │ §5.5.7  EMU_CMD_HW_TMS1        │
 * │ JLINK_CMD_SIGNAL_CLEAR_TDI   │ §5.5.8  EMU_CMD_HW_DATA0       │
 * │ JLINK_CMD_SIGNAL_SET_TDI     │ §5.5.9  EMU_CMD_HW_DATA1       │
 * └──────────────────────────────┴────────────────────────────────┘
 */
#define JLINK_CMD_SIGNAL_GET_STATE   0x07U /* Get target voltage and pin logic states */
#define JLINK_CMD_SIGNAL_CLEAR_RESET 0xdcU /* Assert target reset */
#define JLINK_CMD_SIGNAL_SET_RESET   0xddU /* Deassert target reset */
#define JLINK_CMD_SIGNAL_PULSE_RESET 0x03U /* Assert target reset for 2ms */
#define JLINK_CMD_SIGNAL_CLEAR_TRST  0xdeU /* Clear TRST */
#define JLINK_CMD_SIGNAL_SET_TRST    0xdfU /* Set TRST */
#define JLINK_CMD_SIGNAL_PULSE_TRST  0x02U /* Pulse TRST LOW for 2ms */
#define JLINK_CMD_SIGNAL_CLEAR_TMS   0xc9U /* Clear TMS pin */
#define JLINK_CMD_SIGNAL_SET_TMS     0xcaU /* Set TMS pin */
#define JLINK_CMD_SIGNAL_CLEAR_TDI   0xcbU /* Clear TDI pin */
#define JLINK_CMD_SIGNAL_SET_TDI     0xccU /* Set TDI pin */

/* 
 * Low level IO commands
 *
 * ┌────────────────────────────────────┬────────────────────────────────────┐
 * │        BMDA J-Link command         │   RM08001 J-Link USB Protocol RM   │
 * ├────────────────────────────────────┼────────────────────────────────────┤
 * │ JLINK_CMD_IO_PULSE_CLOCK           │ §5.5.5  EMU_CMD_HW_CLOCK           │
 * │ JLINK_CMD_IO_TRANSACTION           │ §5.5.12 EMU_CMD_HW_JTAG3           │
 * │ JLINK_CMD_IO_WRITE                 │ §5.5.13 EMU_CMD_HW_JTAG_WRITE      │
 * │ JLINK_CMD_IO_GET_WRITE_RESULT      │ §5.5.14 EMU_CMD_HW_JTAG_GET_RESULT │
 * │ JLINK_CMD_IO_WRITE_DCC             │ §5.5.17 EMU_CMD_WRITE_DCC          │
 * │ JLINK_CMD_IO_TRANSACTION_OBSOLETE1 │ §5.5.10 EMU_CMD_HW_JTAG            │
 * │ JLINK_CMD_IO_TRANSACTION_OBSOLETE2 │ §5.5.11 EMU_CMD_HW_JTAG2           │
 * └────────────────────────────────────┴────────────────────────────────────┘
 */
#define JLINK_CMD_IO_PULSE_CLOCK           0xc8U /* Generate one clock cycle and return TDI value on falling edge */
#define JLINK_CMD_IO_TRANSACTION           0xcfU /* Send data on TDI and TMS (SWDIO on SWD) and return TDO (SWDIO on SWD) */
#define JLINK_CMD_IO_WRITE                 0xd5U /* Same as IO_TRANSACTION w/o response data */
#define JLINK_CMD_IO_GET_WRITE_RESULT      0xd6U /* Status of sticky error by CMD_IO_WRITE */
#define JLINK_CMD_IO_WRITE_DCC             0xf1U /* Write to JTAG using DCC */
#define JLINK_CMD_IO_TRANSACTION_OBSOLETE1 0xcdU /* Obsolete: Send data on TDI and TMS and return TDO */
#define JLINK_CMD_IO_TRANSACTION_OBSOLETE2 0xceU /* Obsolete: Send data on TDI and TMS and return TDO  */

/* 
 * High level target commands
 *
 * ┌─────────────────────────────────────────────┬────────────────────────────────────────────┐
 * │             BMDA J-Link command             │       RM08001 J-Link USB Protocol RM       │
 * ├─────────────────────────────────────────────┼────────────────────────────────────────────┤
 * │ JLINK_CMD_TARGET_RELEASE_RESET_HALT_RETRY   │ §5.6.2 EMU_CMD_HW_RELEASE_RESET_STOP_EX    │
 * │ JLINK_CMD_TARGET_RELEASE_RESET_HALT_TIMEOUT │ §5.6.3 EMU_CMD_HW_RELEASE_RESET_STOP_TIMED │
 * │ JLINK_CMD_TARGET_GET_CPU_CAPABILITIES       │ §5.6.6 EMU_CMD_GET_CPU_CAPS                │
 * │ JLINK_CMD_TARGET_EXECUTE_CPU_CMD            │ §5.6.7 EMU_CMD_EXEC_CPU_CMD                │
 * │ JLINK_CMD_TARGET_WRITE_MEMORY               │    -   EMU_CMD_WRITE_MEM                   │
 * │ JLINK_CMD_TARGET_READ_MEMORY                │    -   EMU_CMD_READ_MEM                    │
 * │ JLINK_CMD_TARGET_WRITE_MEMORY_ARM79         │ §5.6.8 EMU_CMD_WRITE_MEM_ARM79             │
 * │ JLINK_CMD_TARGET_READ_MEMORY_ARM79          │ §5.6.9 EMU_CMD_READ_MEM_ARM79              │
 * │ JLINK_CMD_TARGET_MEASURE_RTCK_REACTION_TIME │ §5.4.4 EMU_CMD_MEASURE_RTCK_REACT          │
 * │ JLINK_CMD_TARGET_GET_CONNECTION_STATE       │ §5.4.3 EMU_CMD_GET_COUNTERS                │
 * └─────────────────────────────────────────────┴────────────────────────────────────────────┘
 */
#define JLINK_CMD_TARGET_RELEASE_RESET_HALT_RETRY   0xd0U /* Resets the CPU and halts ASAP (fails after n retries) */
#define JLINK_CMD_TARGET_RELEASE_RESET_HALT_TIMEOUT 0xd1U /* Resets the CPU and halts ASAP (fails after timeout) */
#define JLINK_CMD_TARGET_GET_CPU_CAPABILITIES       0xe9U /* Get the capabilities of the target CPU */
#define JLINK_CMD_TARGET_EXECUTE_CPU_CMD            0xeaU /* Executes target CPU functions */
#define JLINK_CMD_TARGET_WRITE_MEMORY               0xf4U /* Write to target memory */
#define JLINK_CMD_TARGET_READ_MEMORY                0xf5U /* Read from target memory */
#define JLINK_CMD_TARGET_WRITE_MEMORY_ARM79         0xf7U /* Write to target memory on ARM 7/9 targets */
#define JLINK_CMD_TARGET_READ_MEMORY_ARM79          0xf8U /* Read from target memory on ARM 7/9 targets */
#define JLINK_CMD_TARGET_MEASURE_RTCK_REACTION_TIME 0xf6U /* Measure RTCK reaction time of the target device */
#define JLINK_CMD_TARGET_GET_CONNECTION_STATE       0xc2U /* Get target connection timer counters */

/* 
 * Configuration commands
 *
 * ┌────────────────────────┬────────────────────────────────┐
 * │  BMDA J-Link command   │ RM08001 J-Link USB Protocol RM │
 * ├────────────────────────┼────────────────────────────────┤
 * │ JLINK_CMD_CONFIG_READ  │ §5.7.1 EMU_CMD_READ_CONFIG     │
 * │ JLINK_CMD_CONFIG_WRITE │ §5.7.2 EMU_CMD_WRITE_CONFIG    │
 * └────────────────────────┴────────────────────────────────┘
 */
#define JLINK_CMD_CONFIG_READ  0xf2U /* Read the probe configuration */
#define JLINK_CMD_CONFIG_WRITE 0xf3U /* Write the probe configuration */

/* 
 * The hardware version is returned as a 32 bit value with the following format:
 * TTMMmmrr
 * TT: Hardware type
 * MM: Major version
 * mm: Minor version
 * rr: Revision
 * 
 * Note for clarification of the reference manual:
 * This is a 32 bit decimal value! not hex! (ugh... let's not question how long it took to figure that one out)
*/
#define JLINK_HARDWARE_VERSION_TYPE(v)     ((v / 1000000U) % 100U) /* Get hardware type from hardware version value */
#define JLINK_HARDWARE_VERSION_MAJOR(v)    ((v / 10000U) % 100U)   /* Get major version from hardware version value */
#define JLINK_HARDWARE_VERSION_MINOR(v)    ((v / 100U) % 100U)     /* Get minor version from hardware version value */
#define JLINK_HARDWARE_VERSION_REVISION(v) (v % 100U)              /* Get revision from hardware version value */

/* J-Link hardware version - JLINK_CMD_INFO_GET_HARDWARE_VERSION */
#define JLINK_HARDWARE_VERSION_TYPE_JLINK    0U
#define JLINK_HARDWARE_VERSION_TYPE_JTRACE   1U
#define JLINK_HARDWARE_VERSION_TYPE_FLASHER  2U
#define JLINK_HARDWARE_VERSION_TYPE_JLINKPRO 3U
#define JLINK_HARDWARE_VERSION_TYPE_LPCLINK2 18U

/*
 * J-Link capabilities - JLINK_CMD_INFO_GET_PROBE_CAPABILITIES 
 *
 * ┌─────┬──────────────────────────────────────────┬────────────────────────────┐
 * │ Bit │          BMDA J-Link capability          │  §5.3.4 EMU_CMD_GET_CAPS   │
 * ├─────┼──────────────────────────────────────────┼────────────────────────────┤
 * │   1 │ JLINK_CAPABILITY_RESERVED                │ EMU_CAP_RESERVED           │
 * │   2 │ JLINK_CAPABILITY_HARDWARE_VERSION        │ EMU_CAP_GET_HW_VERSION     │
 * │   3 │ JLINK_CAPABILITY_WRITE_DCC               │ EMU_CAP_WRITE_DCC          │
 * │   4 │ JLINK_CAPABILITY_ADAPTIVE_CLOCKING       │ EMU_CAP_ADAPTIVE_CLOCKING  │
 * │   5 │ JLINK_CAPABILITY_READ_CONFIG             │ EMU_CAP_READ_CONFIG        │
 * │   6 │ JLINK_CAPABILITY_WRITE_CONFIG            │ EMU_CAP_WRITE_CONFIG       │
 * │   7 │ JLINK_CAPABILITY_TRACE                   │ EMU_CAP_TRACE              │
 * │   8 │ JLINK_CAPABILITY_WRITE_MEMORY            │ EMU_CAP_WRITE_MEM          │
 * │   9 │ JLINK_CAPABILITY_READ_MEMORY             │ EMU_CAP_READ_MEM           │
 * │  10 │ JLINK_CAPABILITY_INTERFACE_FREQUENCY     │ EMU_CAP_SPEED_INFO         │
 * │  11 │ JLINK_CAPABILITY_EXECUTE_CODE            │ EMU_CAP_EXEC_CODE          │
 * │  12 │ JLINK_CAPABILITY_MAX_MEM_BLOCK           │ EMU_CAP_GET_MAX_BLOCK_SIZE │
 * │  13 │ JLINK_CAPABILITY_POWER_STATE             │ EMU_CAP_GET_HW_INFO        │
 * │  14 │ JLINK_CAPABILITY_KICKSTART_POWER         │ EMU_CAP_SET_KS_POWER       │
 * │  15 │ JLINK_CAPABILITY_HALT_TIMEOUT            │ EMU_CAP_RESET_STOP_TIMED   │
 * │  15 │ JLINK_CAPABILITY_RESERVED2               │ -                          │
 * │  16 │ JLINK_CAPABILITY_MEASURE_RTCK_REACT      │ EMU_CAP_MEASURE_RTCK_REACT │
 * │  17 │ JLINK_CAPABILITY_INTERFACES              │ EMU_CAP_SELECT_IF          │
 * │  18 │ JLINK_CAPABILITY_MEMORY_ARM79            │ EMU_CAP_RW_MEM_ARM79       │
 * │  19 │ JLINK_CAPABILITY_CONNECTION_STATE        │ EMU_CAP_GET_COUNTERS       │
 * │  20 │ JLINK_CAPABILITY_READ_DCC                │ EMU_CAP_READ_DCC           │
 * │  21 │ JLINK_CAPABILITY_TARGET_CPU_CAPABILITIES │ EMU_CAP_GET_CPU_CAPS       │
 * │  22 │ JLINK_CAPABILITY_TARGET_EXECUTE_CPU_CMD  │ EMU_CAP_EXEC_CPU_CMD       │
 * │  23 │ JLINK_CAPABILITY_SWO                     │ EMU_CAP_SWO                │
 * │  24 │ JLINK_CAPABILITY_WRITE_DCC_EX            │ EMU_CAP_WRITE_DCC_EX       │
 * │  25 │ JLINK_CAPABILITY_UPDATE_FIRMWARE_EX      │ EMU_CAP_UPDATE_FIRMWARE_EX │
 * │  26 │ JLINK_CAPABILITY_FILE_IO                 │ EMU_CAP_FILE_IO            │
 * │  27 │ JLINK_CAPABILITY_REGISTER                │ EMU_CAP_REGISTER           │
 * │  28 │ JLINK_CAPABILITY_INDICATORS              │ EMU_CAP_INDICATORS         │
 * │  29 │ JLINK_CAPABILITY_TEST_NET_SPEED          │ EMU_CAP_TEST_NET_SPEED     │
 * │  30 │ JLINK_CAPABILITY_RAWTRACE                │ EMU_CAP_RAWTRACE           │
 * │  31 │ JLINK_CAPABILITY_EXTENDED_CAPABILITIES   │ EMU_CAP_EX_GET_CAPS_EX     │
 * │  32 │ JLINK_CAPABILITY_CMD_IO_WRITE            │ EMU_CAP_EX_HW_JTAG_WRITE   │
 * └─────┴──────────────────────────────────────────┴────────────────────────────┘
 * 
 * 'Undocumented' - The command/capability is not documented in the reference manual nor listed on this page
 */
#define JLINK_CAPABILITY_RESERVED                (1U << 0U)  /* Always 1 */
#define JLINK_CAPABILITY_HARDWARE_VERSION        (1U << 1U)  /* Supports JLINK_CMD_INFO_GET_HARDWARE_VERSION */
#define JLINK_CAPABILITY_WRITE_DCC               (1U << 2U)  /* Supports JLINK_CMD_IO_WRITE_DCC */
#define JLINK_CAPABILITY_ADAPTIVE_CLOCKING       (1U << 3U)  /* Supports adaptive clocking */
#define JLINK_CAPABILITY_READ_CONFIG             (1U << 4U)  /* Supports JLINK_CMD_CONFIG_READ */
#define JLINK_CAPABILITY_WRITE_CONFIG            (1U << 5U)  /* Supports JLINK_CMD_CONFIG_WRITE */
#define JLINK_CAPABILITY_TRACE                   (1U << 6U)  /* Supports trace commands */
#define JLINK_CAPABILITY_WRITE_MEMORY            (1U << 7U)  /* Supports JLINK_CMD_TARGET_WRITE_MEMORY */
#define JLINK_CAPABILITY_READ_MEMORY             (1U << 8U)  /* Supports JLINK_CMD_TARGET_READ_MEMORY */
#define JLINK_CAPABILITY_INTERFACE_FREQUENCY     (1U << 9U)  /* Supports JLINK_CMD_INTERFACE_GET_BASE_FREQUENCY */
#define JLINK_CAPABILITY_EXECUTE_CODE            (1U << 10U) /* Undocumented: Supports EMU_CMD_CODE_... commands */
#define JLINK_CAPABILITY_MAX_MEM_BLOCK           (1U << 11U) /* Supports JLINK_CMD_INFO_GET_MAX_MEM_BLOCK */
#define JLINK_CAPABILITY_POWER_STATE             (1U << 12U) /* Supports JLINK_CMD_POWER_GET_STATE */
#define JLINK_CAPABILITY_KICKSTART_POWER         (1U << 13U) /* Supports Kickstart power on pin 19 (J-Link 20 pin connector) */
#define JLINK_CAPABILITY_HALT_TIMEOUT            (1U << 14U) /* Supports JLINK_CMD_TARGET_RELEASE_RESET_HALT_TIMEOUT */
#define JLINK_CAPABILITY_RESERVED2               (1U << 0U)  /* 15 Unknown Reserved */
#define JLINK_CAPABILITY_MEASURE_RTCK_REACT      (1U << 16U) /* Supports JLINK_CMD_TARGET_MEASURE_RTCK_REACTION_TIME */
#define JLINK_CAPABILITY_INTERFACES              (1U << 17U) /* Supports JLINK_CMD_INTERFACE_GET/SET_SELECTED */
#define JLINK_CAPABILITY_MEMORY_ARM79            (1U << 18U) /* Supports JLINK_CMD_TARGET_READ/WRITE_MEMORY_ARM79 */
#define JLINK_CAPABILITY_CONNECTION_STATE        (1U << 19U) /* Supports JLINK_CMD_TARGET_GET_CONNECTION_STATE */
#define JLINK_CAPABILITY_READ_DCC                (1U << 20U) /* Undocumented: Supports READ_DCC */
#define JLINK_CAPABILITY_TARGET_CPU_CAPABILITIES (1U << 21U) /* Supports JLINK_CMD_TARGET_GET_CPU_CAPABILITIES */
#define JLINK_CAPABILITY_TARGET_EXECUTE_CPU_CMD  (1U << 22U) /* Supports JLINK_CMD_TARGET_EXECUTE_CPU_CMD */
#define JLINK_CAPABILITY_SWO                     (1U << 23U) /* Supports SWO */
#define JLINK_CAPABILITY_WRITE_DCC_EX            (1U << 24U) /* Undocumented: Supports WRITE_DCC_EX */
#define JLINK_CAPABILITY_UPDATE_FIRMWARE_EX      (1U << 25U) /* Undocumented: Supports UPDATE_FIRMWARE_EX */
#define JLINK_CAPABILITY_FILE_IO                 (1U << 26U) /* Undocumented: Supports FILE_IO */
#define JLINK_CAPABILITY_REGISTER                (1U << 27U) /* Undocumented: Supports REGISTER */
#define JLINK_CAPABILITY_INDICATORS              (1U << 28U) /* Undocumented: Supports INDICATORS */
#define JLINK_CAPABILITY_TEST_NET_SPEED          (1U << 29U) /* Undocumented: Supports TEST_NET_SPEED */
#define JLINK_CAPABILITY_RAWTRACE                (1U << 30U) /* Undocumented: Supports RAWTRACE */
#define JLINK_CAPABILITY_EXTENDED_CAPABILITIES   (1U << 31U) /* Supports extended capabilities */
#define JLINK_CAPABILITY_CMD_IO_WRITE            (1U << 32U) /* Supports JLINK_CMD_IO_WRITE */

/* Interface base frequency and min divider - JLINK_CMD_INTERFACE_GET_BASE_FREQUENCY */
#define JLINK_INTERFACE_BASE_FREQUENCY_OFFSET 0U /* 32 bit value */
#define JLINK_INTERFACE_MIN_DIV_OFFSET        4U /* 8 bit value */

/* Interface get - JLINK_CMD_INTERFACE_GET */
#define JLINK_INTERFACE_GET_AVAILABLE 0xffU /* returns 32 bit bitfield of available interfaces */
#define JLINK_INTERFACE_GET_CURRENT   0xfeU /* return currently selected interface number */

#define JLINK_INTERFACE_AVAILABLE(i) (1U << (i)) /* Convert interface number to bitfield bit */

/* Interfaces */
#define JLINK_INTERFACE_MAX  32U
#define JLINK_INTERFACE_JTAG 0U
#define JLINK_INTERFACE_SWD  1U
/* The following interfaces were obtained from libjaylink, with no official documentation to back them up */
#define JLINK_INTERFACE_BDM3          2U /* Background Debug Mode 3 (BDM3) */
#define JLINK_INTERFACE_FINE          3U /* Renesas’ single-wire debug interface (FINE) */
#define JLINK_INTERFACE_2W_JTAG_PIC32 4U /* 2-wire JTAG for PIC32 compliant devices */
#define JLINK_INTERFACE_SPI           5U /* Serial Peripheral Interface (SPI) */
#define JLINK_INTERFACE_C2            6U /* Silicon Labs 2-wire interface (C2) */
#define JLINK_INTERFACE_CJTAG         7U /* Compact JTAG (cJTAG) */

/* Kickstart power - JLINK_CMD_POWER_SET_KICKSTART */
#define JLINK_POWER_KICKSTART_ENABLE 0x01U /* Set Kickstart power on */

/* Power state - JLINK_CMD_POWER_GET_STATE */
#define JLINK_POWER_STATE_KICKSTART_ENABLED_MASK           (1U << 0U) /* Retrieves Kickstart power status */
#define JLINK_POWER_STATE_OVERCURRENT_MASK                 (1U << 1U) /* Information about why the target power was switched off */
#define JLINK_POWER_STATE_ITARGET_MASK                     (1U << 2U)  /* Target consumption(mA)  */
#define JLINK_POWER_STATE_ITARGET_PEAK_MASK                (1U << 3U)  /* Peak target consumption(mA) */
#define JLINK_POWER_STATE_ITARGET_PEAK_OPERATION_MASK      (1U << 4U)  /* Peak operation target consumption(mA) */
#define JLINK_POWER_STATE_ITARGET_MAX_TIME_2MS_3A_MASK     (1U << 10U) /* Time(ms) target consumption exceeded 3A */
#define JLINK_POWER_STATE_ITARGET_MAX_TIME_10MS_1A_MASK    (1U << 11U) /* Time(ms) target consumption exceeded 1A */
#define JLINK_POWER_STATE_ITARGET_MAX_TIME_40MS_400MA_MASK (1U << 12U) /* Time(ms) target consumption exceeded 400MA */
#define JLINK_POWER_STATE_VUSB_MASK                        (1U << 23U) /* USB voltage in mV */

#define JLINK_POWER_STATE_KICKSTART_ENABLED      0x1U /* Kickstart power is on */
#define JLINK_POWER_STATE_OVERCURRENT_NORMAL     0x0U /* Everything is normal */
#define JLINK_POWER_STATE_OVERCURRENT_2MS_3A     0x1U /* 2ms @ 3000mA */
#define JLINK_POWER_STATE_OVERCURRENT_10MS_1A    0x2U /* 10ms @ 1000mA */
#define JLINK_POWER_STATE_OVERCURRENT_40MS_400MA 0x3U /* 40ms @ 400mA */

/* Signal state - JLINK_CMD_SIGNAL_GET_STATE */
#define JLINK_SIGNAL_STATE_VOLTAGE_OFFSET 0U /* 16 bit value */
#define JLINK_SIGNAL_STATE_TCK_OFFSET     2U /* 1 bit value */
#define JLINK_SIGNAL_STATE_TDI_OFFSET     3U /* 1 bit value */
#define JLINK_SIGNAL_STATE_TDO_OFFSET     4U /* 1 bit value */
#define JLINK_SIGNAL_STATE_TMS_OFFSET     5U /* 1 bit value */
#define JLINK_SIGNAL_STATE_TRES_OFFSET    6U /* 1 bit value */
#define JLINK_SIGNAL_STATE_TRST_OFFSET    7U /* 1 bit value */

/* J-Link USB protocol constants */
#define JLINK_USB_TIMEOUT 5000U /* 5 seconds */

/* 
 * J-Link USB Product-Id assignment
 *
 * Old format
 * ┌───────────┬───────────────────┬──────────────┬──────────────────┐
 * │    Bit    │       15:8        │     7:4      │       3:0        │
 * ├───────────┼───────────────────┼──────────────┼──────────────────┤
 * │ Interface │ 0x01 - Old format │ 0 - Reserved │ Class interfaces │
 * └───────────┴───────────────────┴──────────────┴──────────────────┘
 * 
 * Class interfaces:
 * 1: J-Link (default)
 * 2: J-Link w/ USBAddr = 1 (obsolete)
 * 3: J-Link w/ USBAddr = 2 (obsolete)
 * 4: J-Link w/ USBAddr = 3 (obsolete)
 * 5: J-Link | CDC
 * 6: CDC
 * 7: J-Link | RNDIS
 * 8: J-Link | MSD
 * 
 * Known values:
 * 0x0101: J-Link | Flasher STM8 | Flasher ARM | Flasher 5 PRO
 * 0x0102: J-Link USBAddr = 1
 * 0x0103: J-Link USBAddr = 2
 * 0x0104: J-Link USBAddr = 3
 * 0x0105: J-Link | CDC
 * 0x0106: CDC
 * 0x0107: J-Link | RNDIS
 * 0x0108: J-Link | MSD
 * 
 * New format
 * ┌───────────┬───────────────────┬──────────────┬──────┬────────────┬────────────┬─────┬─────┬───────┬─────┐
 * │    Bit    │       15:8        │      7       │  6   │     5      │     4      │  3  │  2  │   1   │  0  │
 * ├───────────┼───────────────────┼──────────────┼──────┼────────────┼────────────┼─────┼─────┼───────┼─────┤
 * │ Interface │ 0x10 - New format │ 0 - Reserved │ CDC2 │ WINUSB_DRV │ SEGGER_DRV │ HID │ CDC │ RNDIS │ MSD │
 * └───────────┴───────────────────┴──────────────┴──────┴────────────┴────────────┴─────┴─────┴───────┴─────┘
 * 
 * 1: Denotes the interface is present
 * 0: Denotes the interface is not present
 * 
 * CDC/CDC2: Communication Device Class interfaces
 * 		Note:  It seems they added more CDC interfaces later on, and to handle them they added a new bit
 * 		but dislocated from the original bit, this makes up a 2 bit value for the number of CDC interfaces
 * 
 * SEGGER_DRV: BULK via SEGGER host driver interface
 * WINUSB_DRV: BULK via WinUSB driver interface (Needs enabling in J-Link config area)
 *		Note: SEGGER_DRV and WINUSB_DRV are mutually exclusive		
 *
 * Known values:
 * 0x1001: MSD
 * 0x1002: RNDIS
 * 0x1003: RNDIS | MSD
 * 0x1004: CDC
 * 0x1005: CDC | MSD
 * 0x1006: RNDIS | CDC
 * 0x1007: RNDIS | CDC | MSD
 * 0x1008: HID
 * 0x1009: MSD | HID
 * 0x100a: RNDIS | HID
 * 0x100b: RNDIS | MSD | HID
 * 0x100c: CDC | HID
 * 0x100d: CDC | MSD | HID
 * 0x100e: RNDIS | CDC | HID
 * 0x100f: RNDIS | CDC | MSD | HID
 * 0x1010: SEGGER_DRV
 * 0x1011: SEGGER_DRV | MSD
 * 0x1012: SEGGER_DRV | RNDIS
 * 0x1013: SEGGER_DRV | RNDIS | MSD
 * 0x1014: SEGGER_DRV | CDC
 * 0x1015: SEGGER_DRV | CDC | MSD
 * 0x1016: SEGGER_DRV | CDC | RNDIS
 * 0x1017: SEGGER_DRV | CDC | RNDIS | MSD
 * 0x1018: SEGGER_DRV | HID
 * 0x1019: SEGGER_DRV | HID | MSD
 * 0x101a: SEGGER_DRV | HID | RNDIS
 * 0x101b: SEGGER_DRV | HID | RNDIS | MSD
 * 0x101c: SEGGER_DRV | HID | CDC
 * 0x101d: SEGGER_DRV | HID | CDC | MSD
 * 0x101e: SEGGER_DRV | HID | CDC | RNDIS
 * 0x101f: SEGGER_DRV | HID | CDC | RNDIS | MSD
 * 0x1020: WINUSB_DRV
 * 0x1021: WINUSB_DRV | MSD
 * 0x1022: WINUSB_DRV | RNDIS
 * 0x1023: WINUSB_DRV | RNDIS | MSD
 * 0x1024: WINUSB_DRV | CDC
 * 0x1025: WINUSB_DRV | CDC | MSD
 * 0x1026: WINUSB_DRV | CDC | RNDIS
 * 0x1027: WINUSB_DRV | CDC | RNDIS | MSD
 * 0x1028: WINUSB_DRV | HID
 * 0x1029: WINUSB_DRV | HID | MSD
 * 0x102a: WINUSB_DRV | HID | RNDIS
 * 0x102b: WINUSB_DRV | HID | RNDIS | MSD
 * 0x102c: WINUSB_DRV | HID | CDC
 * 0x102d: WINUSB_DRV | HID | CDC | MSD
 * 0x102e: WINUSB_DRV | HID | CDC | RNDIS
 * 0x102f: WINUSB_DRV | HID | CDC | RNDIS | MSD
 * 0x103x: SEGGER_DRV | WINUSB_DRV is not valid
 * 0x1050: SEGGER_DRV | 2x CDC
 * 0x1051: SEGGER_DRV | 2x CDC | MSD
 * 0x1052: SEGGER_DRV | 2x CDC | RNDIS
 * 0x1053: SEGGER_DRV | 2x CDC | RNDIS | MSD
 * 0x1054: SEGGER_DRV | 3x CDC
 * 0x1055: SEGGER_DRV | 3x CDC | MSD
 * 0x1056: SEGGER_DRV | 3x CDC | RNDIS
 * 0x1057: SEGGER_DRV | 3x CDC | RNDIS | MSD
 * 0x1058: SEGGER_DRV | HID | 2x CDC
 * 0x1059: SEGGER_DRV | HID | 2x CDC | MSD
 * 0x105a: SEGGER_DRV | HID | 2x CDC | RNDIS
 * 0x105b: SEGGER_DRV | HID | 2x CDC | RNDIS  | MSD
 * 0x105c: SEGGER_DRV | HID | 3x CDC
 * 0x105d: SEGGER_DRV | HID | 3x CDC | MSD
 * 0x105e: SEGGER_DRV | HID | 3x CDC | RNDIS
 * 0x105f: SEGGER_DRV | HID | 3x CDC | RNDIS  | MSD
 * 0x1060: WINUSB_DRV | 2x CDC
 * 0x1061: WINUSB_DRV | 2x CDC | MSD
 * 0x1062: WINUSB_DRV | 2x CDC | RNDIS
 * 0x1063: WINUSB_DRV | 2x CDC | RNDIS  | MSD
 * 0x1064: WINUSB_DRV | 3x CDC
 * 0x1065: WINUSB_DRV | 3x CDC | MSD
 * 0x1066: WINUSB_DRV | 3x CDC | RNDIS
 * 0x1067: WINUSB_DRV | 3x CDC | RNDIS | MSD
 * 0x1068: WINUSB_DRV | HID | 2x CDC
 * 0x1069: WINUSB_DRV | HID | 2x CDC | MSD
 * 0x106a: WINUSB_DRV | HID | 2x CDC | RNDIS
 * 0x106b: WINUSB_DRV | HID | 2x CDC | RNDIS | MSD
 * 0x106c: WINUSB_DRV | HID | 3x CDC
 * 0x106d: WINUSB_DRV | HID | 3x CDC | MSD
 * 0x106e: WINUSB_DRV | HID | 3x CDC | RNDIS
 * 0x106f: WINUSB_DRV | HID | 3x CDC | RNDIS | MSD
 */
#define JLINK_USB_PID_FORMAT_OFFSET 8U
#define JLINK_USB_PID_FORMAT_MASK   (0xffU << JLINK_USB_PID_FORMAT_OFFSET)
#define JLINK_USB_PID_FORMAT_OLD    0x01U
#define JLINK_USB_PID_FORMAT_NEW    0x10U

#define JLINK_USB_PID_OLD_MASK        0x0fU
#define JLINK_USB_PID_OLD_JLINK       0x01U /* J-Link  */
#define JLINK_USB_PID_OLD_JLINK_ADDR1 0x02U /* J-Link USBAddr = 1 */
#define JLINK_USB_PID_OLD_JLINK_ADDR2 0x03U /* J-Link USBAddr = 2 */
#define JLINK_USB_PID_OLD_JLINK_ADDR3 0x04U /* J-Link USBAddr = 3 */
#define JLINK_USB_PID_OLD_JLINK_CDC   0x05U /* J-Link | CDC */
#define JLINK_USB_PID_OLD_CDC         0x06U /* CDC */
#define JLINK_USB_PID_OLD_JLINK_RNDIS 0x07U /* J-Link | RNDIS */
#define JLINK_USB_PID_OLD_JLINK_MSD   0x08U /* J-Link | MSD */

#define JLINK_USB_PID_MASK        0x7fU
#define JLINK_USB_PID_MSD         (1U << 0U) /* MSD */
#define JLINK_USB_PID_RNDIS       (1U << 1U) /* RNDIS */
#define JLINK_USB_PID_HID         (1U << 3U) /* HID */
#define JLINK_USB_PID_DRV_SEGGER  (1U << 4U) /* J-Link (BULK via SEGGER host driver) */
#define JLINK_USB_PID_DRV_WINUSB  (1U << 5U) /* J-Link (BULK via WinUSB driver. Needs enabling in J-Link config area) */
#define JLINK_USB_PID_CDC_OFFSET  2U
#define JLINK_USB_PID_CDC2_OFFSET 6U
#define JLINK_USB_PID_CDC         (1U << JLINK_USB_PID_CDC_OFFSET)  /* CDC */
#define JLINK_USB_PID_CDC2        (1U << JLINK_USB_PID_CDC2_OFFSET) /* CDC2 */

typedef enum jlink_swd_dir {
	JLINK_SWD_OUT,
	JLINK_SWD_IN,
} jlink_swd_dir_e;

typedef struct jlink_io_transact {
	/* This must always be set to JLINK_CMD_IO_TRANSACTION */
	uint8_t command;
	/* This value exists for alignment purposes and must be 0 */
	uint8_t reserved;
	/* clock_cycles defines how many bits need transferring */
	uint8_t clock_cycles[2];
} jlink_io_transact_s;

bool jlink_simple_query(uint8_t command, void *rx_buffer, size_t rx_len);
bool jlink_simple_request_8(uint8_t command, uint8_t operation, void *rx_buffer, size_t rx_len);
bool jlink_simple_request_16(uint8_t command, uint16_t operation, void *rx_buffer, size_t rx_len);
bool jlink_simple_request_32(uint8_t command, uint32_t operation, void *rx_buffer, size_t rx_len);
bool jlink_transfer(uint16_t clock_cycles, const uint8_t *tms, const uint8_t *tdi, uint8_t *tdo);
bool jlink_transfer_fixed_tms(uint16_t clock_cycles, bool final_tms, const uint8_t *tdi, uint8_t *tdo);
bool jlink_transfer_swd(uint16_t clock_cycles, jlink_swd_dir_e direction, const uint8_t *data_in, uint8_t *data_out);
bool jlink_select_interface(const uint8_t interface);

#endif /*PLATFORMS_HOSTED_JLINK_PROTOCOL_H*/