1 /***************************************************************************
2 * Copyright (C) 2007 by Pavel Chromy *
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 ***************************************************************************/
26 /* project specific includes */
30 #include "configuration.h"
41 bitq_interface_t
*bitq_interface
; /* low level bit queue interface */
43 bitq_state_t bitq_in_state
; /* state of input queue */
45 u8
*bitq_in_buffer
; /* buffer dynamically reallocated as needed */
46 unsigned long bitq_in_bufsize
=32; /* min. buffer size */
50 * input queue processing does not use jtag_read_buffer() to avoid unnecessary overhead
51 * also the buffer for incomming data is reallocated only if necessary
52 * no parameters, makes use of stored state information
54 void bitq_in_proc(void)
56 /* static information preserved between calls to increase performance */
57 static u8
*in_buff
; /* pointer to buffer for scanned data */
58 static int in_idx
; /* index of byte being scanned */
59 static u8 in_mask
; /* mask of next bit to be scanned */
64 /* loop through the queue */
65 while (bitq_in_state
.cmd
) {
66 /* only JTAG_SCAN command may return data */
67 if (bitq_in_state
.cmd
->type
==JTAG_SCAN
) {
68 /* loop through the fields */
69 while (bitq_in_state
.field_idx
<bitq_in_state
.cmd
->cmd
.scan
->num_fields
) {
71 field
=&bitq_in_state
.cmd
->cmd
.scan
->fields
[bitq_in_state
.field_idx
];
72 if ( field
->in_value
|| field
->in_handler
) {
74 if (bitq_in_state
.bit_pos
==0) {
75 /* initialize field scanning */
78 if (field
->in_value
) in_buff
=field
->in_value
;
80 /* buffer reallocation needed? */
81 if (field
->num_bits
>bitq_in_bufsize
*8) {
82 /* buffer previously allocated? */
83 if (bitq_in_buffer
!=NULL
) {
88 /* double the buffer size until it fits */
89 while (field
->num_bits
>bitq_in_bufsize
*8) bitq_in_bufsize
*=2;
91 /* if necessary, allocate buffer and check for malloc error */
92 if (bitq_in_buffer
==NULL
&& (bitq_in_buffer
=malloc(bitq_in_bufsize
))==NULL
) {
93 ERROR("malloc error");
96 in_buff
=(void *)bitq_in_buffer
;
101 while (bitq_in_state
.bit_pos
<field
->num_bits
) {
102 if ((tdo
=bitq_interface
->in())<0) {
103 #ifdef _DEBUG_JTAG_IO_
104 DEBUG("bitq in EOF");
108 if (in_mask
==0x01) in_buff
[in_idx
]=0;
109 if (tdo
) in_buff
[in_idx
]|=in_mask
;
115 bitq_in_state
.bit_pos
++;
119 if (field
->in_handler
&& bitq_in_state
.status
==ERROR_OK
) {
120 bitq_in_state
.status
=(*field
->in_handler
)(in_buff
, field
->in_handler_priv
, field
);
125 bitq_in_state
.field_idx
++; /* advance to next field */
126 bitq_in_state
.bit_pos
=0; /* start next field from the first bit */
130 bitq_in_state
.cmd
=bitq_in_state
.cmd
->next
; /* advance to next command */
131 bitq_in_state
.field_idx
=0; /* preselect first field */
137 void bitq_io(int tms
, int tdi
, int tdo_req
)
139 bitq_interface
->out(tms
, tdi
, tdo_req
);
140 /* check and process the input queue */
141 if (bitq_interface
->in_rdy()) bitq_in_proc();
145 void bitq_end_state(enum tap_state state
)
147 if (state
==-1) return;
148 if (tap_move_map
[state
]==-1) {
149 ERROR("BUG: %i is not a valid end state", state
);
156 void bitq_state_move(enum tap_state new_state
)
161 if (tap_move_map
[cur_state
]==-1 || tap_move_map
[new_state
]==-1) {
162 ERROR("TAP move from or to unstable state");
166 tms_scan
=TAP_MOVE(cur_state
, new_state
);
168 for (i
=0; i
<7; i
++) {
169 bitq_io(tms_scan
&1, 0, 0);
173 cur_state
= new_state
;
177 void bitq_path_move(pathmove_command_t
*cmd
)
181 for (i
=0; i
<=cmd
->num_states
; i
++) {
182 if (tap_transitions
[cur_state
].low
== cmd
->path
[i
]) bitq_io(0, 0, 0);
183 else if (tap_transitions
[cur_state
].high
== cmd
->path
[i
]) bitq_io(1, 0, 0);
185 ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings
[cur_state
], tap_state_strings
[cmd
->path
[i
]]);
189 cur_state
= cmd
->path
[i
];
192 end_state
= cur_state
;
196 void bitq_runtest(int num_cycles
)
200 /* only do a state_move when we're not already in RTI */
201 if (cur_state
!= TAP_RTI
) bitq_state_move(TAP_RTI
);
203 /* execute num_cycles */
204 for (i
= 0; i
< num_cycles
; i
++)
207 /* finish in end_state */
208 if (cur_state
!= end_state
) bitq_state_move(end_state
);
212 void bitq_scan_field(scan_field_t
*field
, int pause
)
220 if ( field
->in_value
|| field
->in_handler
) tdo_req
=1;
223 if (field
->out_value
==NULL
) {
224 /* just send zeros and request data from TDO */
225 for (bit_cnt
=field
->num_bits
; bit_cnt
>1; bit_cnt
--)
226 bitq_io(0, 0, tdo_req
);
227 bitq_io(pause
, 0, tdo_req
);
230 /* send data, and optionally request TDO */
232 out_ptr
=field
->out_value
;
233 for (bit_cnt
=field
->num_bits
; bit_cnt
>1; bit_cnt
--) {
234 bitq_io(0, ((*out_ptr
)&out_mask
)!=0, tdo_req
);
235 if (out_mask
==0x80) {
241 bitq_io(pause
, ((*out_ptr
)&out_mask
)!=0, tdo_req
);
246 if (cur_state
==TAP_SI
) cur_state
=TAP_PI
;
247 else if (cur_state
==TAP_SD
) cur_state
=TAP_PD
;
252 void bitq_scan(scan_command_t
*cmd
)
256 if (cmd
->ir_scan
) bitq_state_move(TAP_SI
);
257 else bitq_state_move(TAP_SD
);
259 for (i
=0; i
< cmd
->num_fields
-1; i
++)
260 bitq_scan_field(&cmd
->fields
[i
], 0);
261 bitq_scan_field(&cmd
->fields
[i
], 1);
265 int bitq_execute_queue(void)
267 jtag_command_t
*cmd
= jtag_command_queue
; /* currently processed command */
269 bitq_in_state
.cmd
= jtag_command_queue
;
270 bitq_in_state
.field_idx
= 0;
271 bitq_in_state
.bit_pos
= 0;
272 bitq_in_state
.status
= ERROR_OK
;
279 #ifdef _DEBUG_JTAG_IO_
280 DEBUG("end_state: %i", cmd
->cmd
.end_state
->end_state
);
282 bitq_end_state(cmd
->cmd
.end_state
->end_state
);
286 #ifdef _DEBUG_JTAG_IO_
287 DEBUG("reset trst: %i srst %i", cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
289 bitq_interface
->reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
290 if (bitq_interface
->in_rdy()) bitq_in_proc();
294 #ifdef _DEBUG_JTAG_IO_
295 DEBUG("runtest %i cycles, end in %i", cmd
->cmd
.runtest
->num_cycles
, cmd
->cmd
.runtest
->end_state
);
297 bitq_end_state(cmd
->cmd
.runtest
->end_state
);
298 bitq_runtest(cmd
->cmd
.runtest
->num_cycles
);
302 #ifdef _DEBUG_JTAG_IO_
303 DEBUG("statemove end in %i", cmd
->cmd
.statemove
->end_state
);
305 bitq_end_state(cmd
->cmd
.statemove
->end_state
);
306 bitq_state_move(end_state
); /* uncoditional TAP move */
310 #ifdef _DEBUG_JTAG_IO_
311 DEBUG("pathmove: %i states, end in %i", cmd
->cmd
.pathmove
->num_states
, cmd
->cmd
.pathmove
->path
[cmd
->cmd
.pathmove
->num_states
- 1]);
313 bitq_path_move(cmd
->cmd
.pathmove
);
317 #ifdef _DEBUG_JTAG_IO_
318 DEBUG("scan end in %i", cmd
->cmd
.scan
->end_state
);
319 if (cmd
->cmd
.scan
->ir_scan
) DEBUG("scan ir");
320 else DEBUG("scan dr");
322 bitq_end_state(cmd
->cmd
.scan
->end_state
);
323 bitq_scan(cmd
->cmd
.scan
);
324 if (cur_state
!= end_state
) bitq_state_move(end_state
);
328 #ifdef _DEBUG_JTAG_IO_
329 DEBUG("sleep %i", cmd
->cmd
.sleep
->us
);
331 bitq_interface
->sleep(cmd
->cmd
.sleep
->us
);
332 if (bitq_interface
->in_rdy()) bitq_in_proc();
336 ERROR("BUG: unknown JTAG command type encountered");
343 bitq_interface
->flush();
346 if (bitq_in_state
.cmd
) {
347 ERROR("missing data from bitq interface");
348 return ERROR_JTAG_QUEUE_FAILED
;
350 if (bitq_interface
->in()>=0) {
351 ERROR("extra data from bitq interface");
352 return ERROR_JTAG_QUEUE_FAILED
;
355 return bitq_in_state
.status
;
359 void bitq_cleanup(void)
361 if (bitq_in_buffer
!=NULL
)
363 free(bitq_in_buffer
);
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)