Dick Hollenbeck <dick@softplc.com> adds jtag_add_clocks() and implements those in...
[openocd.git] / src / jtag / dummy.c
1 /***************************************************************************
2 * Copyright (C) 2008 by Øyvind Harboe *
3 * oyvind.harboe@zylin.com *
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 "replacements.h"
25
26 #include "jtag.h"
27 #include "bitbang.h"
28
29
30 /* my private tap controller state, which tracks state for calling code */
31 static tap_state_t dummy_state = TAP_RESET;
32
33 static int dummy_clock; /* edge detector */
34
35 static int clock_count; /* count clocks in any stable state, only stable states */
36
37
38 static tap_state_t tap_state_transition(tap_state_t cur_state, int tms);
39
40 static u32 dummy_data;
41
42
43 int dummy_speed(int speed);
44 int dummy_register_commands(struct command_context_s *cmd_ctx);
45 int dummy_init(void);
46 int dummy_quit(void);
47 static int dummy_khz(int khz, int *jtag_speed);
48 static int dummy_speed_div(int speed, int *khz);
49
50
51 /* The dummy driver is used to easily check the code path
52 * where the target is unresponsive.
53 */
54 jtag_interface_t dummy_interface =
55 {
56 .name = "dummy",
57
58 .execute_queue = bitbang_execute_queue,
59
60 .speed = dummy_speed,
61 .register_commands = dummy_register_commands,
62 .khz = dummy_khz,
63 .speed_div = dummy_speed_div,
64
65 .init = dummy_init,
66 .quit = dummy_quit,
67 };
68
69 int dummy_read(void);
70 void dummy_write(int tck, int tms, int tdi);
71 void dummy_reset(int trst, int srst);
72 void dummy_led(int on);
73
74 bitbang_interface_t dummy_bitbang =
75 {
76 .read = dummy_read,
77 .write = dummy_write,
78 .reset = dummy_reset,
79 .blink = dummy_led
80 };
81
82 int dummy_read(void)
83 {
84 int data = 1 & dummy_data;
85 dummy_data = (dummy_data >> 1) | (1<<31);
86 return data;
87 }
88
89
90 void dummy_write(int tck, int tms, int tdi)
91 {
92 /* TAP standard: "state transitions occur on rising edge of clock" */
93 if( tck != dummy_clock )
94 {
95 if( tck )
96 {
97 int old_state = dummy_state;
98 dummy_state = tap_state_transition( old_state, tms );
99
100 if( old_state != dummy_state )
101 {
102 if( clock_count )
103 {
104 LOG_DEBUG("dummy_tap: %d stable clocks", clock_count);
105 clock_count = 0;
106 }
107
108 LOG_DEBUG("dummy_tap: %s", jtag_state_name(dummy_state) );
109
110 #if defined(DEBUG)
111 if(dummy_state == TAP_DRCAPTURE)
112 dummy_data = 0x01255043;
113 #endif
114 }
115 else
116 {
117 /* this is a stable state clock edge, no change of state here,
118 * simply increment clock_count for subsequent logging
119 */
120 ++clock_count;
121 }
122 }
123 dummy_clock = tck;
124 }
125 }
126
127 void dummy_reset(int trst, int srst)
128 {
129 dummy_clock = 0;
130
131 if (trst || (srst && (jtag_reset_config & RESET_SRST_PULLS_TRST)))
132 dummy_state = TAP_RESET;
133
134 LOG_DEBUG("reset to: %s", jtag_state_name(dummy_state) );
135 }
136
137 static int dummy_khz(int khz, int *jtag_speed)
138 {
139 if (khz==0)
140 {
141 *jtag_speed=0;
142 }
143 else
144 {
145 *jtag_speed=64000/khz;
146 }
147 return ERROR_OK;
148 }
149
150 static int dummy_speed_div(int speed, int *khz)
151 {
152 if (speed==0)
153 {
154 *khz = 0;
155 }
156 else
157 {
158 *khz=64000/speed;
159 }
160
161 return ERROR_OK;
162 }
163
164 int dummy_speed(int speed)
165 {
166 return ERROR_OK;
167 }
168
169 int dummy_register_commands(struct command_context_s *cmd_ctx)
170 {
171 return ERROR_OK;
172 }
173
174 int dummy_init(void)
175 {
176 bitbang_interface = &dummy_bitbang;
177
178 return ERROR_OK;
179 }
180
181 int dummy_quit(void)
182 {
183 return ERROR_OK;
184 }
185
186 void dummy_led(int on)
187 {
188 }
189
190
191 /**
192 * Function tap_state_transition
193 * takes a current TAP state and returns the next state according to the tms value.
194 *
195 * Even though there is code to duplicate this elsewhere, we do it here a little
196 * differently just to get a second opinion, i.e. a verification, on state tracking
197 * in that other logic. Plus array lookups without index checking are no favorite thing.
198 * This is educational for developers new to TAP controllers.
199 */
200 static tap_state_t tap_state_transition(tap_state_t cur_state, int tms)
201 {
202 tap_state_t new_state;
203
204 if (tms)
205 {
206 switch (cur_state)
207 {
208 case TAP_RESET:
209 new_state = cur_state;
210 break;
211 case TAP_IDLE:
212 case TAP_DRUPDATE:
213 case TAP_IRUPDATE:
214 new_state = TAP_DRSELECT;
215 break;
216 case TAP_DRSELECT:
217 new_state = TAP_IRSELECT;
218 break;
219 case TAP_DRCAPTURE:
220 case TAP_DRSHIFT:
221 new_state = TAP_DREXIT1;
222 break;
223 case TAP_DREXIT1:
224 case TAP_DREXIT2:
225 new_state = TAP_DRUPDATE;
226 break;
227 case TAP_DRPAUSE:
228 new_state = TAP_DREXIT2;
229 break;
230 case TAP_IRSELECT:
231 new_state = TAP_RESET;
232 break;
233 case TAP_IRCAPTURE:
234 case TAP_IRSHIFT:
235 new_state = TAP_IREXIT1;
236 break;
237 case TAP_IREXIT1:
238 case TAP_IREXIT2:
239 new_state = TAP_IRUPDATE;
240 break;
241 case TAP_IRPAUSE:
242 new_state = TAP_IREXIT2;
243 break;
244 default:
245 LOG_ERROR( "fatal: invalid argument cur_state=%d", cur_state );
246 exit(1);
247 break;
248 }
249 }
250 else
251 {
252 switch (cur_state)
253 {
254 case TAP_RESET:
255 case TAP_IDLE:
256 case TAP_DRUPDATE:
257 case TAP_IRUPDATE:
258 new_state = TAP_IDLE;
259 break;
260 case TAP_DRSELECT:
261 new_state = TAP_DRCAPTURE;
262 break;
263 case TAP_DRCAPTURE:
264 case TAP_DRSHIFT:
265 case TAP_DREXIT2:
266 new_state = TAP_DRSHIFT;
267 break;
268 case TAP_DREXIT1:
269 case TAP_DRPAUSE:
270 new_state = TAP_DRPAUSE;
271 break;
272 case TAP_IRSELECT:
273 new_state = TAP_IRCAPTURE;
274 break;
275 case TAP_IRCAPTURE:
276 case TAP_IRSHIFT:
277 case TAP_IREXIT2:
278 new_state = TAP_IRSHIFT;
279 break;
280 case TAP_IREXIT1:
281 case TAP_IRPAUSE:
282 new_state = TAP_IRPAUSE;
283 break;
284 default:
285 LOG_ERROR( "fatal: invalid argument cur_state=%d", cur_state );
286 exit(1);
287 break;
288 }
289 }
290
291 return new_state;
292 }

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)