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"
37 bitq_interface_t
*bitq_interface
; /* low level bit queue interface */
39 bitq_state_t bitq_in_state
; /* state of input queue */
41 u8
*bitq_in_buffer
; /* buffer dynamically reallocated as needed */
42 unsigned long bitq_in_bufsize
=32; /* min. buffer size */
45 * input queue processing does not use jtag_read_buffer() to avoid unnecessary overhead
46 * also the buffer for incomming data is reallocated only if necessary
47 * no parameters, makes use of stored state information
49 void bitq_in_proc(void)
51 /* static information preserved between calls to increase performance */
52 static u8
*in_buff
; /* pointer to buffer for scanned data */
53 static int in_idx
; /* index of byte being scanned */
54 static u8 in_mask
; /* mask of next bit to be scanned */
59 /* loop through the queue */
60 while (bitq_in_state
.cmd
) {
61 /* only JTAG_SCAN command may return data */
62 if (bitq_in_state
.cmd
->type
==JTAG_SCAN
) {
63 /* loop through the fields */
64 while (bitq_in_state
.field_idx
<bitq_in_state
.cmd
->cmd
.scan
->num_fields
) {
66 field
=&bitq_in_state
.cmd
->cmd
.scan
->fields
[bitq_in_state
.field_idx
];
67 if ( field
->in_value
|| field
->in_handler
) {
69 if (bitq_in_state
.bit_pos
==0) {
70 /* initialize field scanning */
73 if (field
->in_value
) in_buff
=field
->in_value
;
75 /* buffer reallocation needed? */
76 if (field
->num_bits
>bitq_in_bufsize
*8) {
77 /* buffer previously allocated? */
78 if (bitq_in_buffer
!=NULL
) {
83 /* double the buffer size until it fits */
84 while (field
->num_bits
>bitq_in_bufsize
*8) bitq_in_bufsize
*=2;
86 /* if necessary, allocate buffer and check for malloc error */
87 if (bitq_in_buffer
==NULL
&& (bitq_in_buffer
=malloc(bitq_in_bufsize
))==NULL
) {
88 LOG_ERROR("malloc error");
91 in_buff
=(void *)bitq_in_buffer
;
96 while (bitq_in_state
.bit_pos
<field
->num_bits
) {
97 if ((tdo
=bitq_interface
->in())<0) {
98 #ifdef _DEBUG_JTAG_IO_
99 LOG_DEBUG("bitq in EOF");
103 if (in_mask
==0x01) in_buff
[in_idx
]=0;
104 if (tdo
) in_buff
[in_idx
]|=in_mask
;
110 bitq_in_state
.bit_pos
++;
114 if (field
->in_handler
&& bitq_in_state
.status
==ERROR_OK
) {
115 bitq_in_state
.status
=(*field
->in_handler
)(in_buff
, field
->in_handler_priv
, field
);
120 bitq_in_state
.field_idx
++; /* advance to next field */
121 bitq_in_state
.bit_pos
=0; /* start next field from the first bit */
125 bitq_in_state
.cmd
=bitq_in_state
.cmd
->next
; /* advance to next command */
126 bitq_in_state
.field_idx
=0; /* preselect first field */
130 void bitq_io(int tms
, int tdi
, int tdo_req
)
132 bitq_interface
->out(tms
, tdi
, tdo_req
);
133 /* check and process the input queue */
134 if (bitq_interface
->in_rdy()) bitq_in_proc();
137 void bitq_end_state(enum tap_state state
)
139 if (state
==-1) return;
140 if (tap_move_map
[state
]==-1) {
141 LOG_ERROR("BUG: %i is not a valid end state", state
);
147 void bitq_state_move(enum tap_state new_state
)
152 if (tap_move_map
[cur_state
]==-1 || tap_move_map
[new_state
]==-1) {
153 LOG_ERROR("TAP move from or to unstable state");
157 tms_scan
=TAP_MOVE(cur_state
, new_state
);
159 for (i
=0; i
<7; i
++) {
160 bitq_io(tms_scan
&1, 0, 0);
164 cur_state
= new_state
;
167 void bitq_path_move(pathmove_command_t
*cmd
)
171 for (i
=0; i
<=cmd
->num_states
; i
++) {
172 if (tap_transitions
[cur_state
].low
== cmd
->path
[i
]) bitq_io(0, 0, 0);
173 else if (tap_transitions
[cur_state
].high
== cmd
->path
[i
]) bitq_io(1, 0, 0);
175 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", jtag_state_name(cur_state
), jtag_state_name(cmd
->path
[i
)]);
179 cur_state
= cmd
->path
[i
];
182 end_state
= cur_state
;
185 void bitq_runtest(int num_cycles
)
189 /* only do a state_move when we're not already in IDLE */
190 if (cur_state
!= TAP_IDLE
) bitq_state_move(TAP_IDLE
);
192 /* execute num_cycles */
193 for (i
= 0; i
< num_cycles
; i
++)
196 /* finish in end_state */
197 if (cur_state
!= end_state
) bitq_state_move(end_state
);
200 void bitq_scan_field(scan_field_t
*field
, int pause
)
208 if ( field
->in_value
|| field
->in_handler
) tdo_req
=1;
211 if (field
->out_value
==NULL
) {
212 /* just send zeros and request data from TDO */
213 for (bit_cnt
=field
->num_bits
; bit_cnt
>1; bit_cnt
--)
214 bitq_io(0, 0, tdo_req
);
215 bitq_io(pause
, 0, tdo_req
);
218 /* send data, and optionally request TDO */
220 out_ptr
=field
->out_value
;
221 for (bit_cnt
=field
->num_bits
; bit_cnt
>1; bit_cnt
--) {
222 bitq_io(0, ((*out_ptr
)&out_mask
)!=0, tdo_req
);
223 if (out_mask
==0x80) {
229 bitq_io(pause
, ((*out_ptr
)&out_mask
)!=0, tdo_req
);
234 if (cur_state
==TAP_IRSHIFT
) cur_state
=TAP_IRPAUSE
;
235 else if (cur_state
==TAP_DRSHIFT
) cur_state
=TAP_DRPAUSE
;
239 void bitq_scan(scan_command_t
*cmd
)
243 if (cmd
->ir_scan
) bitq_state_move(TAP_IRSHIFT
);
244 else bitq_state_move(TAP_DRSHIFT
);
246 for (i
=0; i
< cmd
->num_fields
-1; i
++)
247 bitq_scan_field(&cmd
->fields
[i
], 0);
248 bitq_scan_field(&cmd
->fields
[i
], 1);
251 int bitq_execute_queue(void)
253 jtag_command_t
*cmd
= jtag_command_queue
; /* currently processed command */
255 bitq_in_state
.cmd
= jtag_command_queue
;
256 bitq_in_state
.field_idx
= 0;
257 bitq_in_state
.bit_pos
= 0;
258 bitq_in_state
.status
= ERROR_OK
;
265 #ifdef _DEBUG_JTAG_IO_
266 LOG_DEBUG("end_state: %i", cmd
->cmd
.end_state
->end_state
);
268 bitq_end_state(cmd
->cmd
.end_state
->end_state
);
272 #ifdef _DEBUG_JTAG_IO_
273 LOG_DEBUG("reset trst: %i srst %i", cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
275 if ((cmd
->cmd
.reset
->trst
== 1) || (cmd
->cmd
.reset
->srst
&& (jtag_reset_config
& RESET_SRST_PULLS_TRST
)))
277 cur_state
= TAP_RESET
;
279 bitq_interface
->reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
280 if (bitq_interface
->in_rdy()) bitq_in_proc();
284 #ifdef _DEBUG_JTAG_IO_
285 LOG_DEBUG("runtest %i cycles, end in %i", cmd
->cmd
.runtest
->num_cycles
, cmd
->cmd
.runtest
->end_state
);
287 bitq_end_state(cmd
->cmd
.runtest
->end_state
);
288 bitq_runtest(cmd
->cmd
.runtest
->num_cycles
);
292 #ifdef _DEBUG_JTAG_IO_
293 LOG_DEBUG("statemove end in %i", cmd
->cmd
.statemove
->end_state
);
295 bitq_end_state(cmd
->cmd
.statemove
->end_state
);
296 bitq_state_move(end_state
); /* uncoditional TAP move */
300 #ifdef _DEBUG_JTAG_IO_
301 LOG_DEBUG("pathmove: %i states, end in %i", cmd
->cmd
.pathmove
->num_states
, cmd
->cmd
.pathmove
->path
[cmd
->cmd
.pathmove
->num_states
- 1]);
303 bitq_path_move(cmd
->cmd
.pathmove
);
307 #ifdef _DEBUG_JTAG_IO_
308 LOG_DEBUG("scan end in %i", cmd
->cmd
.scan
->end_state
);
309 if (cmd
->cmd
.scan
->ir_scan
) LOG_DEBUG("scan ir");
310 else LOG_DEBUG("scan dr");
312 bitq_end_state(cmd
->cmd
.scan
->end_state
);
313 bitq_scan(cmd
->cmd
.scan
);
314 if (cur_state
!= end_state
) bitq_state_move(end_state
);
318 #ifdef _DEBUG_JTAG_IO_
319 LOG_DEBUG("sleep %i", cmd
->cmd
.sleep
->us
);
321 bitq_interface
->sleep(cmd
->cmd
.sleep
->us
);
322 if (bitq_interface
->in_rdy()) bitq_in_proc();
326 LOG_ERROR("BUG: unknown JTAG command type encountered");
333 bitq_interface
->flush();
336 if (bitq_in_state
.cmd
) {
337 LOG_ERROR("missing data from bitq interface");
338 return ERROR_JTAG_QUEUE_FAILED
;
340 if (bitq_interface
->in()>=0) {
341 LOG_ERROR("extra data from bitq interface");
342 return ERROR_JTAG_QUEUE_FAILED
;
345 return bitq_in_state
.status
;
348 void bitq_cleanup(void)
350 if (bitq_in_buffer
!=NULL
)
352 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)