819d8e5800079b912783ba342c86d6ce90377b56
[openocd.git] / src / jtag / bitbang.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
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 "bitbang.h"
25
26 /* project specific includes */
27 #include "log.h"
28 #include "types.h"
29 #include "jtag.h"
30 #include "configuration.h"
31
32 /* system includes */
33 #include <string.h>
34 #include <stdlib.h>
35 #include <unistd.h>
36
37 #include <sys/time.h>
38 #include <time.h>
39
40 bitbang_interface_t *bitbang_interface;
41
42 int bitbang_execute_queue(void);
43
44 /* The bitbang driver leaves the TCK 0 when in idle */
45
46
47 void bitbang_end_state(enum tap_state state)
48 {
49 if (tap_move_map[state] != -1)
50 end_state = state;
51 else
52 {
53 ERROR("BUG: %i is not a valid end state", state);
54 exit(-1);
55 }
56 }
57
58 void bitbang_state_move(void) {
59
60 int i=0, tms=0;
61 u8 tms_scan = TAP_MOVE(cur_state, end_state);
62
63 for (i = 0; i < 7; i++)
64 {
65 tms = (tms_scan >> i) & 1;
66 bitbang_interface->write(0, tms, 0);
67 bitbang_interface->write(1, tms, 0);
68 }
69 bitbang_interface->write(0, tms, 0);
70
71 cur_state = end_state;
72 }
73
74 void bitbang_path_move(pathmove_command_t *cmd)
75 {
76 int num_states = cmd->num_states;
77 int state_count;
78 int tms;
79
80 state_count = 0;
81 while (num_states)
82 {
83 if (tap_transitions[cur_state].low == cmd->path[state_count])
84 {
85 tms = 0;
86 }
87 else if (tap_transitions[cur_state].high == cmd->path[state_count])
88 {
89 tms = 1;
90 }
91 else
92 {
93 ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[cmd->path[state_count]]);
94 exit(-1);
95 }
96
97 bitbang_interface->write(0, tms, 0);
98 bitbang_interface->write(1, tms, 0);
99
100 cur_state = cmd->path[state_count];
101 state_count++;
102 num_states--;
103 }
104
105 bitbang_interface->write(0, tms, 0);
106
107 end_state = cur_state;
108 }
109
110 void bitbang_runtest(int num_cycles)
111 {
112 int i;
113
114 enum tap_state saved_end_state = end_state;
115
116 /* only do a state_move when we're not already in RTI */
117 if (cur_state != TAP_RTI)
118 {
119 bitbang_end_state(TAP_RTI);
120 bitbang_state_move();
121 }
122
123 /* execute num_cycles */
124 bitbang_interface->write(0, 0, 0);
125 for (i = 0; i < num_cycles; i++)
126 {
127 bitbang_interface->write(1, 0, 0);
128 bitbang_interface->write(0, 0, 0);
129 }
130
131 /* finish in end_state */
132 bitbang_end_state(saved_end_state);
133 if (cur_state != end_state)
134 bitbang_state_move();
135 }
136
137 void bitbang_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size)
138 {
139 enum tap_state saved_end_state = end_state;
140 int bit_cnt;
141 int last_bit, last_bit_in;
142
143 if (!((!ir_scan && (cur_state == TAP_SD)) || (ir_scan && (cur_state == TAP_SI))))
144 {
145 if (ir_scan)
146 bitbang_end_state(TAP_SI);
147 else
148 bitbang_end_state(TAP_SD);
149
150 bitbang_state_move();
151 bitbang_end_state(saved_end_state);
152 }
153
154 for (bit_cnt = 0; bit_cnt < scan_size - 1; bit_cnt++)
155 {
156 /* if we're just reading the scan, but don't care about the output
157 * default to outputting 'low', this also makes valgrind traces more readable,
158 * as it removes the dependency on an uninitialised value
159 */
160 if ((type != SCAN_IN) && ((buffer[bit_cnt/8] >> (bit_cnt % 8)) & 0x1))
161 {
162 bitbang_interface->write(0, 0, 1);
163 bitbang_interface->write(1, 0, 1);
164 } else {
165 bitbang_interface->write(0, 0, 0);
166 bitbang_interface->write(1, 0, 0);
167 }
168
169 if (type != SCAN_OUT)
170 {
171 if (bitbang_interface->read())
172 buffer[(bit_cnt)/8] |= 1 << ((bit_cnt) % 8);
173 else
174 buffer[(bit_cnt)/8] &= ~(1 << ((bit_cnt) % 8));
175 }
176 }
177
178 if ((type != SCAN_IN) && ((buffer[bit_cnt/8] >> (bit_cnt % 8)) & 0x1))
179 last_bit = 1;
180 else
181 last_bit = 0;
182
183 if ((ir_scan && (end_state == TAP_SI)) ||
184 (!ir_scan && (end_state == TAP_SD)))
185 {
186 bitbang_interface->write(0, 0, last_bit);
187 bitbang_interface->write(1, 0, last_bit);
188
189 if (type != SCAN_OUT)
190 last_bit_in = bitbang_interface->read();
191
192 bitbang_interface->write(0, 0, last_bit);
193 }
194 else
195 {
196 /* Shift-[ID]R -> Exit1-[ID]R */
197 bitbang_interface->write(0, 1, last_bit);
198 bitbang_interface->write(1, 1, last_bit);
199
200 if (type != SCAN_OUT)
201 last_bit_in = bitbang_interface->read();
202
203 /* Exit1-[ID]R -> Pause-[ID]R */
204 bitbang_interface->write(0, 0, 0);
205 bitbang_interface->write(1, 0, 0);
206
207 if (cur_state == TAP_SI)
208 cur_state = TAP_PI;
209 else
210 cur_state = TAP_PD;
211
212 if (cur_state != end_state)
213 bitbang_state_move();
214 else
215 bitbang_interface->write(0, 0, 0);
216 }
217
218 if (type != SCAN_OUT)
219 {
220 if (last_bit_in)
221 buffer[(bit_cnt)/8] |= 1 << ((bit_cnt) % 8);
222 else
223 buffer[(bit_cnt)/8] &= ~(1 << ((bit_cnt) % 8));
224 }
225 }
226
227 int bitbang_execute_queue(void)
228 {
229 jtag_command_t *cmd = jtag_command_queue; /* currently processed command */
230 int scan_size;
231 enum scan_type type;
232 u8 *buffer;
233 int retval;
234
235 if (!bitbang_interface)
236 {
237 ERROR("BUG: Bitbang interface called, but not yet initialized");
238 exit(-1);
239 }
240
241 /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
242 * that wasn't handled by a caller-provided error handler
243 */
244 retval = ERROR_OK;
245
246 if(bitbang_interface->blink)
247 bitbang_interface->blink(1);
248
249 while (cmd)
250 {
251 switch (cmd->type)
252 {
253 case JTAG_END_STATE:
254 #ifdef _DEBUG_JTAG_IO_
255 DEBUG("end_state: %i", cmd->cmd.end_state->end_state);
256 #endif
257 if (cmd->cmd.end_state->end_state != -1)
258 bitbang_end_state(cmd->cmd.end_state->end_state);
259 break;
260 case JTAG_RESET:
261 #ifdef _DEBUG_JTAG_IO_
262 DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
263 #endif
264 if (cmd->cmd.reset->trst == 1)
265 {
266 cur_state = TAP_TLR;
267 }
268 bitbang_interface->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
269 break;
270 case JTAG_RUNTEST:
271 #ifdef _DEBUG_JTAG_IO_
272 DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);
273 #endif
274 if (cmd->cmd.runtest->end_state != -1)
275 bitbang_end_state(cmd->cmd.runtest->end_state);
276 bitbang_runtest(cmd->cmd.runtest->num_cycles);
277 break;
278 case JTAG_STATEMOVE:
279 #ifdef _DEBUG_JTAG_IO_
280 DEBUG("statemove end in %i", cmd->cmd.statemove->end_state);
281 #endif
282 if (cmd->cmd.statemove->end_state != -1)
283 bitbang_end_state(cmd->cmd.statemove->end_state);
284 bitbang_state_move();
285 break;
286 case JTAG_PATHMOVE:
287 #ifdef _DEBUG_JTAG_IO_
288 DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
289 #endif
290 bitbang_path_move(cmd->cmd.pathmove);
291 break;
292 case JTAG_SCAN:
293 #ifdef _DEBUG_JTAG_IO_
294 DEBUG("%s scan end in %i", (cmd->cmd.scan->ir_scan) ? "IR" : "DR", cmd->cmd.scan->end_state);
295 #endif
296 if (cmd->cmd.scan->end_state != -1)
297 bitbang_end_state(cmd->cmd.scan->end_state);
298 scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
299 type = jtag_scan_type(cmd->cmd.scan);
300 bitbang_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
301 if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
302 retval = ERROR_JTAG_QUEUE_FAILED;
303 if (buffer)
304 free(buffer);
305 break;
306 case JTAG_SLEEP:
307 #ifdef _DEBUG_JTAG_IO_
308 DEBUG("sleep %i", cmd->cmd.sleep->us);
309 #endif
310 jtag_sleep(cmd->cmd.sleep->us);
311 break;
312 default:
313 ERROR("BUG: unknown JTAG command type encountered");
314 exit(-1);
315 }
316 cmd = cmd->next;
317 }
318 if(bitbang_interface->blink)
319 bitbang_interface->blink(0);
320
321 return retval;
322 }
323

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)