- prepare OpenOCD for branching, created ./trunk/
[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
21 #include "bitbang.h"
22
23 /* project specific includes */
24 #include "log.h"
25 #include "types.h"
26 #include "jtag.h"
27 #include "configuration.h"
28
29 /* system includes */
30 #include <string.h>
31 #include <stdlib.h>
32 #include <unistd.h>
33
34 #include <sys/time.h>
35 #include <time.h>
36
37 bitbang_interface_t *bitbang_interface;
38
39 int bitbang_execute_queue(void);
40
41 void bitbang_end_state(enum tap_state state)
42 {
43 if (tap_move_map[state] != -1)
44 end_state = state;
45 else
46 {
47 ERROR("BUG: %i is not a valid end state", state);
48 exit(-1);
49 }
50 }
51
52 void bitbang_state_move(void) {
53
54 int i=0, tms=0;
55 u8 tms_scan = TAP_MOVE(cur_state, end_state);
56
57 for (i = 0; i < 7; i++)
58 {
59 tms = (tms_scan >> i) & 1;
60 bitbang_interface->write(0, tms, 0);
61 bitbang_interface->write(1, tms, 0);
62 }
63 bitbang_interface->write(0, tms, 0);
64
65 cur_state = end_state;
66 }
67
68 void bitbang_runtest(int num_cycles)
69 {
70 int i;
71
72 enum tap_state saved_end_state = end_state;
73
74 /* only do a state_move when we're not already in RTI */
75 if (cur_state != TAP_RTI)
76 {
77 bitbang_end_state(TAP_RTI);
78 bitbang_state_move();
79 }
80
81 /* execute num_cycles */
82 bitbang_interface->write(0, 0, 0);
83 for (i = 0; i < num_cycles; i++)
84 {
85 bitbang_interface->write(1, 0, 0);
86 bitbang_interface->write(0, 0, 0);
87 }
88
89 /* finish in end_state */
90 bitbang_end_state(saved_end_state);
91 if (cur_state != end_state)
92 bitbang_state_move();
93 }
94
95 void bitbang_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size)
96 {
97 enum tap_state saved_end_state = end_state;
98 int bit_cnt;
99
100 if (ir_scan)
101 bitbang_end_state(TAP_SI);
102 else
103 bitbang_end_state(TAP_SD);
104
105 bitbang_state_move();
106 bitbang_end_state(saved_end_state);
107
108 for (bit_cnt = 0; bit_cnt < scan_size; bit_cnt++)
109 {
110 if ((buffer[bit_cnt/8] >> (bit_cnt % 8)) & 0x1) {
111 bitbang_interface->write(0, (bit_cnt==scan_size-1) ? 1 : 0, 1);
112 bitbang_interface->write(1, (bit_cnt==scan_size-1) ? 1 : 0, 1);
113 } else {
114 bitbang_interface->write(0, (bit_cnt==scan_size-1) ? 1 : 0, 0);
115 bitbang_interface->write(1, (bit_cnt==scan_size-1) ? 1 : 0, 0);
116 }
117
118 if (type != SCAN_OUT)
119 {
120 if (bitbang_interface->read())
121 buffer[(bit_cnt)/8] |= 1 << ((bit_cnt) % 8);
122 else
123 buffer[(bit_cnt)/8] &= ~(1 << ((bit_cnt) % 8));
124 }
125 }
126
127 /* Exit1 -> Pause */
128 bitbang_interface->write(0, 0, 0);
129 bitbang_interface->write(1, 0, 0);
130
131 if (ir_scan)
132 cur_state = TAP_PI;
133 else
134 cur_state = TAP_PD;
135
136 if (cur_state != end_state)
137 bitbang_state_move();
138 }
139
140 int bitbang_execute_queue(void)
141 {
142 jtag_command_t *cmd = jtag_command_queue; /* currently processed command */
143 int scan_size;
144 enum scan_type type;
145 u8 *buffer;
146
147 if (!bitbang_interface)
148 {
149 ERROR("BUG: Bitbang interface called, but not yet initialized");
150 exit(-1);
151 }
152
153 while (cmd)
154 {
155 switch (cmd->type)
156 {
157 case JTAG_END_STATE:
158 #ifdef _DEBUG_JTAG_IO_
159 DEBUG("end_state: %i", cmd->cmd.end_state->end_state);
160 #endif
161 if (cmd->cmd.end_state->end_state != -1)
162 bitbang_end_state(cmd->cmd.end_state->end_state);
163 break;
164 case JTAG_RESET:
165 #ifdef _DEBUG_JTAG_IO_
166 DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
167 #endif
168 if (cmd->cmd.reset->trst == 1)
169 {
170 cur_state = TAP_TLR;
171 }
172 bitbang_interface->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
173 break;
174 case JTAG_RUNTEST:
175 #ifdef _DEBUG_JTAG_IO_
176 DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);
177 #endif
178 if (cmd->cmd.runtest->end_state != -1)
179 bitbang_end_state(cmd->cmd.runtest->end_state);
180 bitbang_runtest(cmd->cmd.runtest->num_cycles);
181 break;
182 case JTAG_STATEMOVE:
183 #ifdef _DEBUG_JTAG_IO_
184 DEBUG("statemove end in %i", cmd->cmd.statemove->end_state);
185 #endif
186 if (cmd->cmd.statemove->end_state != -1)
187 bitbang_end_state(cmd->cmd.statemove->end_state);
188 bitbang_state_move();
189 break;
190 case JTAG_SCAN:
191 #ifdef _DEBUG_JTAG_IO_
192 DEBUG("scan end in %i", cmd->cmd.scan->end_state);
193 #endif
194 if (cmd->cmd.scan->end_state != -1)
195 bitbang_end_state(cmd->cmd.scan->end_state);
196 scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
197 type = jtag_scan_type(cmd->cmd.scan);
198 bitbang_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
199 if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
200 return ERROR_JTAG_QUEUE_FAILED;
201 if (buffer)
202 free(buffer);
203 break;
204 case JTAG_SLEEP:
205 #ifdef _DEBUG_JTAG_IO_
206 DEBUG("sleep", cmd->cmd.sleep->us);
207 #endif
208 jtag_sleep(cmd->cmd.sleep->us);
209 break;
210 default:
211 ERROR("BUG: unknown JTAG command type encountered");
212 exit(-1);
213 }
214 cmd = cmd->next;
215 }
216
217 return ERROR_OK;
218 }
219

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)