1 /***************************************************************************
2 * Copyright (C) 2011 by Mathias Kuester *
3 * Mathias Kuester <kesmtp@freenet.de> *
5 * This code is based on https://github.com/texane/stlink *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 ***************************************************************************/
27 /* project specific includes */
28 #include <helper/binarybuffer.h>
29 #include <jtag/interface.h>
30 #include <jtag/stlink/stlink_layout.h>
31 #include <jtag/stlink/stlink_interface.h>
32 #include <target/target.h>
34 #include "libusb_common.h"
36 #define ENDPOINT_IN 0x80
37 #define ENDPOINT_OUT 0x00
39 #define STLINK_RX_EP (1|ENDPOINT_IN)
40 #define STLINK_TX_EP (2|ENDPOINT_OUT)
41 #define STLINK_CMD_SIZE (16)
42 #define STLINK_TX_SIZE (4*128)
43 #define STLINK_RX_SIZE (4*128)
46 struct stlink_usb_handle_s
{
48 struct jtag_libusb_device_handle
*fd
;
50 struct libusb_transfer
*trans
;
52 uint8_t txbuf
[STLINK_TX_SIZE
];
54 uint8_t rxbuf
[STLINK_RX_SIZE
];
57 #define STLINK_OK 0x80
58 #define STLINK_FALSE 0x81
59 #define STLINK_CORE_RUNNING 0x80
60 #define STLINK_CORE_HALTED 0x81
61 #define STLINK_CORE_STAT_UNKNOWN -1
63 #define STLINK_GET_VERSION 0xf1
64 #define STLINK_GET_CURRENT_MODE 0xf5
66 #define STLINK_DEBUG_COMMAND 0xF2
67 #define STLINK_DFU_COMMAND 0xF3
68 #define STLINK_DFU_EXIT 0x07
70 #define STLINK_DEV_DFU_MODE 0x00
71 #define STLINK_DEV_MASS_MODE 0x01
72 #define STLINK_DEV_DEBUG_MODE 0x02
73 #define STLINK_DEV_UNKNOWN_MODE -1
75 #define STLINK_DEBUG_ENTER 0x20
76 #define STLINK_DEBUG_EXIT 0x21
77 #define STLINK_DEBUG_READCOREID 0x22
79 #define STLINK_DEBUG_GETSTATUS 0x01
80 #define STLINK_DEBUG_FORCEDEBUG 0x02
81 #define STLINK_DEBUG_RESETSYS 0x03
82 #define STLINK_DEBUG_READALLREGS 0x04
83 #define STLINK_DEBUG_READREG 0x05
84 #define STLINK_DEBUG_WRITEREG 0x06
85 #define STLINK_DEBUG_READMEM_32BIT 0x07
86 #define STLINK_DEBUG_WRITEMEM_32BIT 0x08
87 #define STLINK_DEBUG_RUNCORE 0x09
88 #define STLINK_DEBUG_STEPCORE 0x0a
89 #define STLINK_DEBUG_SETFP 0x0b
90 #define STLINK_DEBUG_WRITEMEM_8BIT 0x0d
91 #define STLINK_DEBUG_CLEARFP 0x0e
92 #define STLINK_DEBUG_WRITEDEBUGREG 0x0f
93 #define STLINK_DEBUG_ENTER_SWD 0xa3
94 #define STLINK_DEBUG_ENTER_JTAG 0x00
96 #define STLINK_SWD_ENTER 0x30
97 #define STLINK_SWD_READCOREID 0x32
100 int stlink_usb_recv(void *handle
, uint8_t *txbuf
, int txsize
, uint8_t *rxbuf
,
103 struct stlink_usb_handle_s
*h
;
105 assert(handle
!= NULL
);
107 h
= (struct stlink_usb_handle_s
*)handle
;
109 if (jtag_libusb_bulk_write(h
->fd
, STLINK_TX_EP
, (char *)txbuf
, txsize
,
113 if (rxsize
&& rxbuf
) {
114 if (jtag_libusb_bulk_read(h
->fd
, STLINK_RX_EP
, (char *)rxbuf
,
115 rxsize
, 1000) != rxsize
) {
123 void stlink_usb_init_buffer(void *handle
)
125 struct stlink_usb_handle_s
*h
;
127 assert(handle
!= NULL
);
129 h
= (struct stlink_usb_handle_s
*)handle
;
131 memset(h
->txbuf
, 0, STLINK_CMD_SIZE
);
135 int stlink_usb_version(void *handle
)
139 struct stlink_usb_handle_s
*h
;
141 assert(handle
!= NULL
);
143 h
= (struct stlink_usb_handle_s
*)handle
;
145 stlink_usb_init_buffer(handle
);
147 h
->txbuf
[0] = STLINK_GET_VERSION
;
149 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, h
->rxbuf
, 6);
154 v
= (h
->rxbuf
[0] << 8) | h
->rxbuf
[1];
156 LOG_DEBUG("STLINK v%d", (v
>> 12) & 0x0f);
157 LOG_DEBUG("JTAG v%d", (v
>> 6) & 0x3f);
158 LOG_DEBUG("SWIM v%d", v
& 0x3f);
159 LOG_DEBUG("VID %04X", buf_get_u32(h
->rxbuf
, 16, 16));
160 LOG_DEBUG("PID %04X", buf_get_u32(h
->rxbuf
, 32, 16));
166 int stlink_usb_current_mode(void *handle
, uint8_t *mode
)
169 struct stlink_usb_handle_s
*h
;
171 assert(handle
!= NULL
);
173 h
= (struct stlink_usb_handle_s
*)handle
;
175 stlink_usb_init_buffer(handle
);
177 h
->txbuf
[0] = STLINK_GET_CURRENT_MODE
;
179 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, h
->rxbuf
, 2);
190 int stlink_usb_dfu_mode_leave(void *handle
)
193 struct stlink_usb_handle_s
*h
;
195 assert(handle
!= NULL
);
197 h
= (struct stlink_usb_handle_s
*)handle
;
199 stlink_usb_init_buffer(handle
);
201 h
->txbuf
[0] = STLINK_DFU_COMMAND
;
202 h
->txbuf
[1] = STLINK_DFU_EXIT
;
204 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, 0, 0);
213 int stlink_usb_swd_mode_enter(void *handle
)
216 struct stlink_usb_handle_s
*h
;
218 assert(handle
!= NULL
);
220 h
= (struct stlink_usb_handle_s
*)handle
;
222 stlink_usb_init_buffer(handle
);
224 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
225 h
->txbuf
[1] = STLINK_DEBUG_ENTER
;
226 h
->txbuf
[2] = STLINK_DEBUG_ENTER_SWD
;
228 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, 0, 0);
236 int stlink_usb_debug_mode_leave(void *handle
)
239 struct stlink_usb_handle_s
*h
;
241 assert(handle
!= NULL
);
243 h
= (struct stlink_usb_handle_s
*)handle
;
245 stlink_usb_init_buffer(handle
);
247 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
248 h
->txbuf
[1] = STLINK_DEBUG_EXIT
;
250 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, 0, 0);
258 int stlink_usb_init_mode(void *handle
)
263 assert(handle
!= NULL
);
265 res
= stlink_usb_current_mode(handle
, &mode
);
270 LOG_DEBUG("MODE: %02X", mode
);
272 if (mode
== STLINK_DEV_DFU_MODE
) {
273 res
= stlink_usb_dfu_mode_leave(handle
);
279 res
= stlink_usb_current_mode(handle
, &mode
);
284 LOG_DEBUG("MODE: %02X", mode
);
286 if (mode
!= STLINK_DEV_DEBUG_MODE
) {
287 res
= stlink_usb_swd_mode_enter(handle
);
293 res
= stlink_usb_current_mode(handle
, &mode
);
298 LOG_DEBUG("MODE: %02X", mode
);
304 int stlink_usb_idcode(void *handle
, uint32_t *idcode
)
307 struct stlink_usb_handle_s
*h
;
309 assert(handle
!= NULL
);
311 h
= (struct stlink_usb_handle_s
*)handle
;
313 stlink_usb_init_buffer(handle
);
315 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
316 h
->txbuf
[1] = STLINK_DEBUG_READCOREID
;
318 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, h
->rxbuf
, 4);
323 *idcode
= le_to_h_u32(h
->rxbuf
);
325 LOG_DEBUG("IDCODE: %08X", *idcode
);
331 enum target_state
stlink_usb_state(void *handle
)
334 struct stlink_usb_handle_s
*h
;
336 assert(handle
!= NULL
);
338 h
= (struct stlink_usb_handle_s
*)handle
;
340 stlink_usb_init_buffer(handle
);
342 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
343 h
->txbuf
[1] = STLINK_DEBUG_GETSTATUS
;
345 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, h
->rxbuf
, 2);
348 return TARGET_UNKNOWN
;
350 if (h
->rxbuf
[0] == STLINK_CORE_RUNNING
)
351 return TARGET_RUNNING
;
352 if (h
->rxbuf
[0] == STLINK_CORE_HALTED
)
353 return TARGET_HALTED
;
355 return TARGET_UNKNOWN
;
359 int stlink_usb_reset(void *handle
)
362 struct stlink_usb_handle_s
*h
;
364 assert(handle
!= NULL
);
366 h
= (struct stlink_usb_handle_s
*)handle
;
368 stlink_usb_init_buffer(handle
);
370 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
371 h
->txbuf
[1] = STLINK_DEBUG_RESETSYS
;
373 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, h
->rxbuf
, 2);
378 LOG_DEBUG("RESET: %08X", h
->rxbuf
[0]);
384 int stlink_usb_run(void *handle
)
387 struct stlink_usb_handle_s
*h
;
389 assert(handle
!= NULL
);
391 h
= (struct stlink_usb_handle_s
*)handle
;
393 stlink_usb_init_buffer(handle
);
395 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
396 h
->txbuf
[1] = STLINK_DEBUG_RUNCORE
;
398 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, h
->rxbuf
, 2);
407 int stlink_usb_halt(void *handle
)
410 struct stlink_usb_handle_s
*h
;
412 assert(handle
!= NULL
);
414 h
= (struct stlink_usb_handle_s
*)handle
;
416 stlink_usb_init_buffer(handle
);
418 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
419 h
->txbuf
[1] = STLINK_DEBUG_FORCEDEBUG
;
421 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, h
->rxbuf
, 2);
430 int stlink_usb_step(void *handle
)
433 struct stlink_usb_handle_s
*h
;
435 assert(handle
!= NULL
);
437 h
= (struct stlink_usb_handle_s
*)handle
;
439 stlink_usb_init_buffer(handle
);
441 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
442 h
->txbuf
[1] = STLINK_DEBUG_STEPCORE
;
444 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, h
->rxbuf
, 2);
453 int stlink_usb_read_regs(void *handle
)
456 struct stlink_usb_handle_s
*h
;
458 assert(handle
!= NULL
);
460 h
= (struct stlink_usb_handle_s
*)handle
;
462 stlink_usb_init_buffer(handle
);
464 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
465 h
->txbuf
[1] = STLINK_DEBUG_READALLREGS
;
467 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, h
->rxbuf
, 84);
476 int stlink_usb_read_reg(void *handle
, int num
, uint32_t *val
)
479 struct stlink_usb_handle_s
*h
;
481 assert(handle
!= NULL
);
483 h
= (struct stlink_usb_handle_s
*)handle
;
485 stlink_usb_init_buffer(handle
);
487 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
488 h
->txbuf
[1] = STLINK_DEBUG_READREG
;
491 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, h
->rxbuf
, 4);
496 *val
= le_to_h_u32(h
->rxbuf
);
502 int stlink_usb_write_reg(void *handle
, int num
, uint32_t val
)
505 struct stlink_usb_handle_s
*h
;
507 assert(handle
!= NULL
);
509 h
= (struct stlink_usb_handle_s
*)handle
;
511 stlink_usb_init_buffer(handle
);
513 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
514 h
->txbuf
[1] = STLINK_DEBUG_WRITEREG
;
516 h_u32_to_le(h
->txbuf
+ 3, val
);
518 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, h
->rxbuf
, 2);
527 int stlink_usb_read_mem32(void *handle
, uint32_t addr
, uint16_t len
,
531 struct stlink_usb_handle_s
*h
;
533 assert(handle
!= NULL
);
535 h
= (struct stlink_usb_handle_s
*)handle
;
537 stlink_usb_init_buffer(handle
);
541 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
542 h
->txbuf
[1] = STLINK_DEBUG_READMEM_32BIT
;
543 h_u32_to_le(h
->txbuf
+ 2, addr
);
544 h_u16_to_le(h
->txbuf
+ 2 + 4, len
);
546 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, h
->rxbuf
, len
);
551 memcpy(buffer
, h
->rxbuf
, len
);
557 int stlink_usb_write_mem32(void *handle
, uint32_t addr
, uint16_t len
,
561 struct stlink_usb_handle_s
*h
;
563 assert(handle
!= NULL
);
565 h
= (struct stlink_usb_handle_s
*)handle
;
567 stlink_usb_init_buffer(handle
);
571 h
->txbuf
[0] = STLINK_DEBUG_COMMAND
;
572 h
->txbuf
[1] = STLINK_DEBUG_WRITEMEM_32BIT
;
573 h_u32_to_le(h
->txbuf
+ 2, addr
);
574 h_u16_to_le(h
->txbuf
+ 2 + 4, len
);
576 res
= stlink_usb_recv(handle
, h
->txbuf
, STLINK_CMD_SIZE
, 0, 0);
581 res
= stlink_usb_recv(handle
, (uint8_t *) buffer
, len
, 0, 0);
586 memcpy(buffer
, h
->rxbuf
, len
);
592 int stlink_usb_open(struct stlink_interface_param_s
*param
, void **fd
)
594 struct stlink_usb_handle_s
*h
;
596 LOG_DEBUG("stlink_usb_open");
598 h
= malloc(sizeof(struct stlink_usb_handle_s
));
601 LOG_DEBUG("stlink_open_usb: malloc failed");
605 const uint16_t vids
[] = { param
->vid
, 0 };
606 const uint16_t pids
[] = { param
->pid
, 0 };
608 LOG_DEBUG("stlink_open_usb: vid: %04x pid: %04x", param
->vid
,
611 if (jtag_libusb_open(vids
, pids
, &h
->fd
) != ERROR_OK
) {
612 LOG_DEBUG("stlink_open_usb: open failed");
616 jtag_libusb_set_configuration(h
->fd
, 0);
618 if (jtag_libusb_claim_interface(h
->fd
, 0) != ERROR_OK
) {
619 LOG_DEBUG("stlink_open_usb: claim failed");
623 stlink_usb_init_mode(h
);
625 stlink_usb_version(h
);
633 struct stlink_layout_api_s stlink_layout_api
= {
635 .open
= stlink_usb_open
,
637 .idcode
= stlink_usb_idcode
,
639 .state
= stlink_usb_state
,
641 .reset
= stlink_usb_reset
,
643 .run
= stlink_usb_run
,
645 .halt
= stlink_usb_halt
,
647 .step
= stlink_usb_step
,
649 .read_regs
= stlink_usb_read_regs
,
651 .read_reg
= stlink_usb_read_reg
,
653 .write_reg
= stlink_usb_write_reg
,
655 .read_mem32
= stlink_usb_read_mem32
,
657 .write_mem32
= stlink_usb_write_mem32
,
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)