bitq: remove a static variable
[openocd.git] / src / jtag / drivers / bitq.c
1 /***************************************************************************
2 * Copyright (C) 2007 by Pavel Chromy *
3 * chromy@asix.cz *
4 * *
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. *
9 * *
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. *
14 * *
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 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <jtag/jtag.h>
25 #include "bitq.h"
26 #include <jtag/interface.h>
27
28
29 struct bitq_interface* bitq_interface; /* low level bit queue interface */
30
31 /* state of input queue */
32 struct bitq_state {
33 struct jtag_command *cmd; /* command currently processed */
34 int field_idx; /* index of field currently being processed */
35 int bit_pos; /* position of bit curently being processed */
36 int status; /* processing status */
37 };
38 static struct bitq_state bitq_in_state;
39
40 /*
41 * input queue processing does not use jtag_read_buffer() to avoid unnecessary overhead
42 * no parameters, makes use of stored state information
43 */
44 void bitq_in_proc(void)
45 {
46 /* static information preserved between calls to increase performance */
47 static int in_idx; /* index of byte being scanned */
48 static uint8_t in_mask; /* mask of next bit to be scanned */
49
50 struct scan_field* field;
51 int tdo;
52
53 /* loop through the queue */
54 while (bitq_in_state.cmd)
55 {
56 /* only JTAG_SCAN command may return data */
57 if (bitq_in_state.cmd->type == JTAG_SCAN)
58 {
59 /* loop through the fields */
60 while (bitq_in_state.field_idx < bitq_in_state.cmd->cmd.scan->num_fields)
61 {
62 field = &bitq_in_state.cmd->cmd.scan->fields[bitq_in_state.field_idx];
63 if (field->in_value)
64 {
65 if (bitq_in_state.bit_pos == 0)
66 {
67 /* initialize field scanning */
68 in_mask = 0x01;
69 in_idx = 0;
70 }
71
72 /* field scanning */
73 while (bitq_in_state.bit_pos < field->num_bits)
74 {
75 if ((tdo = bitq_interface->in()) < 0)
76 {
77 #ifdef _DEBUG_JTAG_IO_
78 LOG_DEBUG("bitq in EOF");
79 #endif
80 return;
81 }
82 if (in_mask == 0x01)
83 field->in_value[in_idx] = 0;
84 if (tdo)
85 field->in_value[in_idx] |= in_mask;
86 if (in_mask == 0x80)
87 {
88 in_mask = 0x01;
89 in_idx++;
90 }
91 else
92 in_mask <<= 1;
93 bitq_in_state.bit_pos++;
94 }
95 }
96
97 bitq_in_state.field_idx++; /* advance to next field */
98 bitq_in_state.bit_pos = 0; /* start next field from the first bit */
99 }
100 }
101 bitq_in_state.cmd = bitq_in_state.cmd->next; /* advance to next command */
102 bitq_in_state.field_idx = 0; /* preselect first field */
103 }
104 }
105
106
107 void bitq_io(int tms, int tdi, int tdo_req)
108 {
109 bitq_interface->out(tms, tdi, tdo_req);
110 /* check and process the input queue */
111 if (bitq_interface->in_rdy())
112 bitq_in_proc();
113 }
114
115
116 void bitq_end_state(tap_state_t state)
117 {
118 if (!tap_is_state_stable(state))
119 {
120 LOG_ERROR("BUG: %i is not a valid end state", state);
121 exit(-1);
122 }
123 tap_set_end_state(state);
124 }
125
126
127 void bitq_state_move(tap_state_t new_state)
128 {
129 int i = 0;
130 uint8_t tms_scan;
131
132 if (!tap_is_state_stable(tap_get_state()) || !tap_is_state_stable(new_state))
133 {
134 LOG_ERROR("TAP move from or to unstable state");
135 exit(-1);
136 }
137
138 tms_scan = tap_get_tms_path(tap_get_state(), new_state);
139 int tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
140
141 for (i = 0; i < tms_count; i++)
142 {
143 bitq_io(tms_scan & 1, 0, 0);
144 tms_scan >>= 1;
145 }
146
147 tap_set_state(new_state);
148 }
149
150
151 void bitq_path_move(struct pathmove_command* cmd)
152 {
153 int i;
154
155 for (i = 0; i <= cmd->num_states; i++)
156 {
157 if (tap_state_transition(tap_get_state(), false) == cmd->path[i])
158 bitq_io(0, 0, 0);
159 else if (tap_state_transition(tap_get_state(), true) == cmd->path[i])
160 bitq_io(1, 0, 0);
161 else
162 {
163 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(
164 tap_get_state()), tap_state_name(cmd->path[i]));
165 exit(-1);
166 }
167
168 tap_set_state(cmd->path[i]);
169 }
170
171 tap_set_end_state(tap_get_state());
172 }
173
174
175 void bitq_runtest(int num_cycles)
176 {
177 int i;
178
179 /* only do a state_move when we're not already in IDLE */
180 if (tap_get_state() != TAP_IDLE)
181 bitq_state_move(TAP_IDLE);
182
183 /* execute num_cycles */
184 for (i = 0; i < num_cycles; i++)
185 bitq_io(0, 0, 0);
186
187 /* finish in end_state */
188 if (tap_get_state() != tap_get_end_state())
189 bitq_state_move(tap_get_end_state());
190 }
191
192
193 void bitq_scan_field(struct scan_field* field, int do_pause)
194 {
195 int bit_cnt;
196 int tdo_req;
197
198 const uint8_t* out_ptr;
199 uint8_t out_mask;
200
201 if (field->in_value)
202 tdo_req = 1;
203 else
204 tdo_req = 0;
205
206 if (field->out_value == NULL)
207 {
208 /* just send zeros and request data from TDO */
209 for (bit_cnt = field->num_bits; bit_cnt > 1; bit_cnt--)
210 bitq_io(0, 0, tdo_req);
211
212 bitq_io(do_pause, 0, tdo_req);
213 }
214 else
215 {
216 /* send data, and optionally request TDO */
217 out_mask = 0x01;
218 out_ptr = field->out_value;
219 for (bit_cnt = field->num_bits; bit_cnt > 1; bit_cnt--)
220 {
221 bitq_io(0, ((*out_ptr) & out_mask) != 0, tdo_req);
222 if (out_mask == 0x80)
223 {
224 out_mask = 0x01;
225 out_ptr++;
226 }
227 else
228 out_mask <<= 1;
229 }
230
231 bitq_io(do_pause, ((*out_ptr) & out_mask) != 0, tdo_req);
232 }
233
234 if (do_pause)
235 {
236 bitq_io(0, 0, 0);
237 if (tap_get_state() == TAP_IRSHIFT)
238 tap_set_state(TAP_IRPAUSE);
239 else if (tap_get_state() == TAP_DRSHIFT)
240 tap_set_state(TAP_DRPAUSE);
241 }
242 }
243
244
245 void bitq_scan(struct scan_command* cmd)
246 {
247 int i;
248
249 if (cmd->ir_scan)
250 bitq_state_move(TAP_IRSHIFT);
251 else
252 bitq_state_move(TAP_DRSHIFT);
253
254 for (i = 0; i < cmd->num_fields - 1; i++)
255 bitq_scan_field(&cmd->fields[i], 0);
256
257 bitq_scan_field(&cmd->fields[i], 1);
258 }
259
260
261 int bitq_execute_queue(void)
262 {
263 struct jtag_command* cmd = jtag_command_queue; /* currently processed command */
264
265 bitq_in_state.cmd = jtag_command_queue;
266 bitq_in_state.field_idx = 0;
267 bitq_in_state.bit_pos = 0;
268 bitq_in_state.status = ERROR_OK;
269
270 while (cmd)
271 {
272 switch (cmd->type)
273 {
274 case JTAG_RESET:
275 #ifdef _DEBUG_JTAG_IO_
276 LOG_DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
277 #endif
278 if ((cmd->cmd.reset->trst == 1) || (cmd->cmd.reset->srst && (jtag_get_reset_config() & RESET_SRST_PULLS_TRST)))
279 {
280 tap_set_state(TAP_RESET);
281 }
282 bitq_interface->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
283 if (bitq_interface->in_rdy())
284 bitq_in_proc();
285 break;
286
287 case JTAG_RUNTEST:
288 #ifdef _DEBUG_JTAG_IO_
289 LOG_DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);
290 #endif
291 bitq_end_state(cmd->cmd.runtest->end_state);
292 bitq_runtest(cmd->cmd.runtest->num_cycles);
293 break;
294
295 case JTAG_TLR_RESET:
296 #ifdef _DEBUG_JTAG_IO_
297 LOG_DEBUG("statemove end in %i", cmd->cmd.statemove->end_state);
298 #endif
299 bitq_end_state(cmd->cmd.statemove->end_state);
300 bitq_state_move(tap_get_end_state()); /* uncoditional TAP move */
301 break;
302
303 case JTAG_PATHMOVE:
304 #ifdef _DEBUG_JTAG_IO_
305 LOG_DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states,
306 cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
307 #endif
308 bitq_path_move(cmd->cmd.pathmove);
309 break;
310
311 case JTAG_SCAN:
312 #ifdef _DEBUG_JTAG_IO_
313 LOG_DEBUG("scan end in %i", cmd->cmd.scan->end_state);
314 if (cmd->cmd.scan->ir_scan)
315 LOG_DEBUG("scan ir");
316 else
317 LOG_DEBUG("scan dr");
318 #endif
319 bitq_end_state(cmd->cmd.scan->end_state);
320 bitq_scan(cmd->cmd.scan);
321 if (tap_get_state() != tap_get_end_state())
322 bitq_state_move(tap_get_end_state());
323 break;
324
325 case JTAG_SLEEP:
326 #ifdef _DEBUG_JTAG_IO_
327 LOG_DEBUG("sleep %i", cmd->cmd.sleep->us);
328 #endif
329 bitq_interface->sleep(cmd->cmd.sleep->us);
330 if (bitq_interface->in_rdy())
331 bitq_in_proc();
332 break;
333
334 default:
335 LOG_ERROR("BUG: unknown JTAG command type encountered");
336 exit(-1);
337 }
338
339 cmd = cmd->next;
340 }
341
342 bitq_interface->flush();
343 bitq_in_proc();
344
345 if (bitq_in_state.cmd)
346 {
347 LOG_ERROR("missing data from bitq interface");
348 return ERROR_JTAG_QUEUE_FAILED;
349 }
350 if (bitq_interface->in() >= 0)
351 {
352 LOG_ERROR("extra data from bitq interface");
353 return ERROR_JTAG_QUEUE_FAILED;
354 }
355
356 return bitq_in_state.status;
357 }
358
359
360 void bitq_cleanup(void)
361 {
362 }

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)