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

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)