1 /***************************************************************************
2 * Copyright (C) 2012 by Jan Dakinevich *
3 * jan.dakinevich@gmail.com *
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. *
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. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
24 #include <helper/log.h>
25 #include <helper/binarybuffer.h>
26 #include <helper/command.h>
27 #include <jtag/interface.h>
28 #include "libusb_common.h"
35 struct sequence
*next
;
39 struct sequence
*head
;
40 struct sequence
*tail
;
43 static struct sequence
*queue_add_tail(struct queue
*queue
, int len
)
46 LOG_ERROR("BUG: sequences with zero length are not allowed");
50 struct sequence
*next
;
51 next
= (struct sequence
*)malloc(sizeof(*next
));
53 next
->tms
= calloc(1, DIV_ROUND_UP(len
, 8));
61 /* Queue is empty at the moment */
64 /* Queue already contains at least one sequence */
65 queue
->tail
->next
= next
;
76 LOG_ERROR("Not enough memory");
81 static void queue_drop_head(struct queue
*queue
)
83 struct sequence
*head
= queue
->head
->next
; /* New head */
84 free(queue
->head
->tms
);
89 static void queue_free(struct queue
*queue
)
93 queue_drop_head(queue
);
99 static struct queue
*queue_alloc(void)
101 struct queue
*queue
= (struct queue
*)malloc(sizeof(struct queue
));
105 LOG_ERROR("Not enough memory");
110 /* Size of usb communnication buffer */
111 #define OSBDM_USB_BUFSIZE 64
112 /* Timeout for USB transfer, ms */
113 #define OSBDM_USB_TIMEOUT 1000
114 /* Write end point */
115 #define OSBDM_USB_EP_WRITE 0x01
117 #define OSBDM_USB_EP_READ 0x82
119 /* Initialize OSBDM device */
120 #define OSBDM_CMD_INIT 0x11
121 /* Execute special, not-BDM command. But only this
122 * command is used for JTAG operation */
123 #define OSBDM_CMD_SPECIAL 0x27
124 /* Execute JTAG swap (tms/tdi -> tdo) */
125 #define OSBDM_CMD_SPECIAL_SWAP 0x05
127 #define OSBDM_CMD_SPECIAL_SRST 0x01
128 /* Maximum bit-length in one swap */
129 #define OSBDM_SWAP_MAX (((OSBDM_USB_BUFSIZE - 6) / 5) * 16)
131 /* Lists of valid VID/PID pairs
133 static const uint16_t osbdm_vid
[] = { 0x15a2, 0x15a2, 0x15a2, 0 };
134 static const uint16_t osbdm_pid
[] = { 0x0042, 0x0058, 0x005e, 0 };
137 struct jtag_libusb_device_handle
*devh
; /* USB handle */
138 uint8_t buffer
[OSBDM_USB_BUFSIZE
]; /* Data to send and receive */
139 int count
; /* Count data to send and to read */
144 static struct osbdm osbdm_context
;
146 static int osbdm_send_and_recv(struct osbdm
*osbdm
)
149 int count
= jtag_libusb_bulk_write(osbdm
->devh
, OSBDM_USB_EP_WRITE
,
150 (char *)osbdm
->buffer
, osbdm
->count
, OSBDM_USB_TIMEOUT
);
152 if (count
!= osbdm
->count
) {
153 LOG_ERROR("OSBDM communnication error: can't write");
157 /* Save command code for next checking */
158 uint8_t cmd_saved
= osbdm
->buffer
[0];
161 osbdm
->count
= jtag_libusb_bulk_read(osbdm
->devh
, OSBDM_USB_EP_READ
,
162 (char *)osbdm
->buffer
, OSBDM_USB_BUFSIZE
, OSBDM_USB_TIMEOUT
);
164 /* Now perform basic checks for data sent by BDM device
167 if (osbdm
->count
< 0) {
168 LOG_ERROR("OSBDM communnication error: can't read");
172 if (osbdm
->count
< 2) {
173 LOG_ERROR("OSBDM communnication error: answer too small");
177 if (osbdm
->count
!= osbdm
->buffer
[1]) {
178 LOG_ERROR("OSBDM communnication error: answer size mismatch");
182 if (cmd_saved
!= osbdm
->buffer
[0]) {
183 LOG_ERROR("OSBDM communnication error: answer command mismatch");
190 static int osbdm_srst(struct osbdm
*osbdm
, int srst
)
193 (void)memset(osbdm
->buffer
, 0, OSBDM_USB_BUFSIZE
);
197 osbdm
->buffer
[osbdm
->count
++] = OSBDM_CMD_SPECIAL
; /* Command */
198 osbdm
->buffer
[osbdm
->count
++] = OSBDM_CMD_SPECIAL_SRST
; /* Subcommand */
199 /* Length in bytes - not used */
200 osbdm
->buffer
[osbdm
->count
++] = 0;
201 osbdm
->buffer
[osbdm
->count
++] = 0;
203 osbdm
->buffer
[osbdm
->count
++] = (srst
? 0 : 0x08);
207 if (osbdm_send_and_recv(osbdm
) != ERROR_OK
)
213 static int osbdm_swap(struct osbdm
*osbdm
, void *tms
, void *tdi
,
214 void *tdo
, int length
)
216 if (length
> OSBDM_SWAP_MAX
) {
217 LOG_ERROR("BUG: bit sequence too long");
222 LOG_ERROR("BUG: bit sequence equal or less to 0");
226 int swap_count
= DIV_ROUND_UP(length
, 16);
230 (void)memset(osbdm
->buffer
, 0, OSBDM_USB_BUFSIZE
);
235 osbdm
->buffer
[osbdm
->count
++] = OSBDM_CMD_SPECIAL
; /* Command */
236 osbdm
->buffer
[osbdm
->count
++] = OSBDM_CMD_SPECIAL_SWAP
; /* Subcommand */
237 /* Length in bytes - not used */
238 osbdm
->buffer
[osbdm
->count
++] = 0;
239 osbdm
->buffer
[osbdm
->count
++] = 0;
241 osbdm
->buffer
[osbdm
->count
++] = 0;
242 osbdm
->buffer
[osbdm
->count
++] = (uint8_t)swap_count
;
244 for (int bit_idx
= 0; bit_idx
< length
; ) {
245 /* Bit count in swap */
246 int bit_count
= length
- bit_idx
;
250 osbdm
->buffer
[osbdm
->count
++] = (uint8_t)bit_count
;
252 /* Copying TMS and TDI data to output buffer */
253 uint32_t tms_data
= buf_get_u32(tms
, bit_idx
, bit_count
);
254 uint32_t tdi_data
= buf_get_u32(tdi
, bit_idx
, bit_count
);
255 osbdm
->buffer
[osbdm
->count
++] = (uint8_t)(tdi_data
>> 8);
256 osbdm
->buffer
[osbdm
->count
++] = (uint8_t)tdi_data
;
257 osbdm
->buffer
[osbdm
->count
++] = (uint8_t)(tms_data
>> 8);
258 osbdm
->buffer
[osbdm
->count
++] = (uint8_t)tms_data
;
260 /* Next bit offset */
261 bit_idx
+= bit_count
;
264 assert(osbdm
->count
<= OSBDM_USB_BUFSIZE
);
268 if (osbdm_send_and_recv(osbdm
) != ERROR_OK
)
273 if (((osbdm
->buffer
[2] << 8) | osbdm
->buffer
[3]) != 2 * swap_count
) {
274 LOG_ERROR("OSBDM communnication error: not proper answer to swap command");
280 uint8_t *buffer
= (uint8_t *)osbdm
->buffer
+ 4;
281 for (int bit_idx
= 0; bit_idx
< length
; ) {
282 int bit_count
= length
- bit_idx
;
287 uint32_t tdo_data
= 0;
288 tdo_data
|= (*buffer
++) << 8;
289 tdo_data
|= (*buffer
++);
290 tdo_data
>>= (16 - bit_count
);
292 /* Copy TDO to return */
293 buf_set_u32(tdo
, bit_idx
, bit_count
, tdo_data
);
295 bit_idx
+= bit_count
;
301 static int osbdm_flush(struct osbdm
*osbdm
, struct queue
* queue
)
303 uint8_t tms
[DIV_ROUND_UP(OSBDM_SWAP_MAX
, 8)];
304 uint8_t tdi
[DIV_ROUND_UP(OSBDM_SWAP_MAX
, 8)];
305 uint8_t tdo
[DIV_ROUND_UP(OSBDM_SWAP_MAX
, 8)];
307 int seq_back_len
= 0;
309 while (queue
->head
) {
310 (void)memset(tms
, 0, sizeof(tms
));
311 (void)memset(tdi
, 0, sizeof(tdi
));
312 (void)memset(tdo
, 0, sizeof(tdo
));
316 struct sequence
*seq
;
318 /* Copy from queue to tms/tdi streams
321 seq_len
= seq_back_len
;
324 while (seq
&& swap_len
!= OSBDM_SWAP_MAX
) {
325 /* Count bit for copy at this iteration.
326 * len should fit into remaining space
327 * in tms/tdo bitstreams
329 int len
= seq
->len
- seq_len
;
330 if (len
> OSBDM_SWAP_MAX
- swap_len
)
331 len
= OSBDM_SWAP_MAX
- swap_len
;
334 buf_set_buf(seq
->tms
, seq_len
, tms
, swap_len
, len
);
336 /* Set tdi data if they exists */
338 buf_set_buf(seq
->tdi
, seq_len
, tdi
, swap_len
, len
);
342 if (seq_len
== seq
->len
) {
343 seq
= seq
->next
; /* Move to next sequence */
348 if (osbdm_swap(osbdm
, tms
, tdi
, tdo
, swap_len
))
351 /* Copy from tdo stream to queue
354 for (int swap_back_len
= 0; swap_back_len
< swap_len
; ) {
355 int len
= queue
->head
->len
- seq_back_len
;
356 if (len
> swap_len
- swap_back_len
)
357 len
= swap_len
- swap_back_len
;
359 if (queue
->head
->tdo
)
360 buf_set_buf(tdo
, swap_back_len
, queue
->head
->tdo
, seq_back_len
, len
);
362 swap_back_len
+= len
;
364 if (seq_back_len
== queue
->head
->len
) {
365 queue_drop_head(queue
);
374 /* Basic operation for opening USB device */
375 static int osbdm_open(struct osbdm
*osbdm
)
377 (void)memset(osbdm
, 0, sizeof(*osbdm
));
378 if (jtag_libusb_open(osbdm_vid
, osbdm_pid
, &osbdm
->devh
) != ERROR_OK
)
381 if (jtag_libusb_claim_interface(osbdm
->devh
, 0) != ERROR_OK
)
387 static int osbdm_quit(void)
389 jtag_libusb_close(osbdm_context
.devh
);
393 static int osbdm_add_pathmove(
398 assert(num_states
<= 32);
400 struct sequence
*next
= queue_add_tail(queue
, num_states
);
402 LOG_ERROR("BUG: can't allocate bit sequence");
407 for (int i
= 0; i
< num_states
; i
++) {
408 if (tap_state_transition(tap_get_state(), 1) == path
[i
]) {
410 } else if (tap_state_transition(tap_get_state(), 0) == path
[i
]) {
411 tms
&= ~(1 << i
); /* This line not so needed */
413 LOG_ERROR("BUG: %s -> %s isn't a valid TAP state transition",
414 tap_state_name(tap_get_state()),
415 tap_state_name(path
[i
]));
419 tap_set_state(path
[i
]);
422 buf_set_u32(next
->tms
, 0, num_states
, tms
);
423 tap_set_end_state(tap_get_state());
428 static int osbdm_add_statemove(
430 tap_state_t new_state
,
436 tap_set_end_state(new_state
);
437 if (tap_get_end_state() == TAP_RESET
) {
438 /* Ignore current state */
441 } else if (tap_get_state() != tap_get_end_state()) {
442 tms
= tap_get_tms_path(tap_get_state(), new_state
);
443 len
= tap_get_tms_path_len(tap_get_state(), new_state
);
446 if (len
&& skip_first
) {
452 struct sequence
*next
= queue_add_tail(queue
, len
);
454 LOG_ERROR("BUG: can't allocate bit sequence");
457 buf_set_u32(next
->tms
, 0, len
, tms
);
460 tap_set_state(tap_get_end_state());
464 static int osbdm_add_stableclocks(
468 if (!tap_is_state_stable(tap_get_state())) {
469 LOG_ERROR("BUG: current state (%s) is not stable",
470 tap_state_name(tap_get_state()));
474 struct sequence
*next
= queue_add_tail(queue
, count
);
476 LOG_ERROR("BUG: can't allocate bit sequence");
480 if (tap_get_state() == TAP_RESET
)
481 (void)memset(next
->tms
, 0xff, DIV_ROUND_UP(count
, 8));
486 static int osbdm_add_tms(
491 struct sequence
*next
= queue_add_tail(queue
, num_bits
);
493 LOG_ERROR("BUG: can't allocate bit sequence");
496 buf_set_buf(tms
, 0, next
->tms
, 0, num_bits
);
501 static int osbdm_add_scan(
503 struct scan_field
*fields
,
505 tap_state_t end_state
,
508 /* Move to desired shift state */
510 if (tap_get_state() != TAP_IRSHIFT
) {
511 if (osbdm_add_statemove(queue
, TAP_IRSHIFT
, 0) != ERROR_OK
)
515 if (tap_get_state() != TAP_DRSHIFT
) {
516 if (osbdm_add_statemove(queue
, TAP_DRSHIFT
, 0) != ERROR_OK
)
522 tap_set_end_state(end_state
);
523 for (int idx
= 0; idx
< num_fields
; idx
++) {
524 struct sequence
*next
= queue_add_tail(queue
, fields
[idx
].num_bits
);
526 LOG_ERROR("Can't allocate bit sequence");
530 (void)memset(next
->tms
, 0, DIV_ROUND_UP(fields
[idx
].num_bits
, 8));
531 next
->tdi
= fields
[idx
].out_value
;
532 next
->tdo
= fields
[idx
].in_value
;
537 if (tap_get_state() != tap_get_end_state()) {
538 /* Exit from IRSHIFT/DRSHIFT */
539 buf_set_u32(queue
->tail
->tms
, queue
->tail
->len
- 1, 1, 1);
541 /* Move with skip_first flag */
542 if (osbdm_add_statemove(queue
, tap_get_end_state(), 1) != ERROR_OK
)
549 static int osbdm_add_runtest(
552 tap_state_t end_state
)
554 if (osbdm_add_statemove(queue
, TAP_IDLE
, 0) != ERROR_OK
)
557 if (osbdm_add_stableclocks(queue
, num_cycles
) != ERROR_OK
)
560 if (osbdm_add_statemove(queue
, end_state
, 0) != ERROR_OK
)
566 static int osbdm_execute_command(
569 struct jtag_command
*cmd
)
571 int retval
= ERROR_OK
;
575 if (cmd
->cmd
.reset
->trst
) {
576 LOG_ERROR("BUG: nTRST signal is not supported");
579 retval
= osbdm_flush(osbdm
, queue
);
580 if (retval
== ERROR_OK
)
581 retval
= osbdm_srst(osbdm
, cmd
->cmd
.reset
->srst
);
586 retval
= osbdm_add_pathmove(
588 cmd
->cmd
.pathmove
->path
,
589 cmd
->cmd
.pathmove
->num_states
);
593 retval
= osbdm_add_statemove(
595 cmd
->cmd
.statemove
->end_state
,
599 case JTAG_STABLECLOCKS
:
600 retval
= osbdm_add_stableclocks(
602 cmd
->cmd
.stableclocks
->num_cycles
);
606 retval
= osbdm_add_tms(
609 cmd
->cmd
.tms
->num_bits
);
613 retval
= osbdm_add_scan(
615 cmd
->cmd
.scan
->fields
,
616 cmd
->cmd
.scan
->num_fields
,
617 cmd
->cmd
.scan
->end_state
,
618 cmd
->cmd
.scan
->ir_scan
);
622 retval
= osbdm_flush(osbdm
, queue
);
623 if (retval
== ERROR_OK
)
624 jtag_sleep(cmd
->cmd
.sleep
->us
);
628 retval
= osbdm_add_runtest(
630 cmd
->cmd
.runtest
->num_cycles
,
631 cmd
->cmd
.runtest
->end_state
);
635 LOG_ERROR("BUG: unknown JTAG command type encountered");
643 static int osbdm_execute_queue(void)
645 int retval
= ERROR_OK
;
647 struct queue
*queue
= queue_alloc();
649 LOG_ERROR("BUG: can't allocate bit queue");
652 struct jtag_command
*cmd
= jtag_command_queue
;
654 while (retval
== ERROR_OK
&& cmd
) {
655 retval
= osbdm_execute_command(&osbdm_context
, queue
, cmd
);
659 if (retval
== ERROR_OK
)
660 retval
= osbdm_flush(&osbdm_context
, queue
);
665 if (retval
!= ERROR_OK
) {
666 LOG_ERROR("FATAL: can't execute jtag command");
673 static int osbdm_init(void)
676 if (osbdm_open(&osbdm_context
) != ERROR_OK
) {
677 LOG_ERROR("Can't open OSBDM device");
680 /* Device successfully opened */
681 LOG_INFO("OSBDM has opened");
684 /* Perform initialize command */
685 osbdm_context
.count
= 0;
686 osbdm_context
.buffer
[osbdm_context
.count
++] = OSBDM_CMD_INIT
;
687 if (osbdm_send_and_recv(&osbdm_context
) != ERROR_OK
)
693 struct jtag_interface osbdm_interface
= {
696 .transports
= jtag_only
,
697 .execute_queue
= osbdm_execute_queue
,
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)