openocd: fix doxygen parameters of functions
[openocd.git] / src / jtag / drivers / OpenULINK / src / jtag.c
1 /***************************************************************************
2 * Copyright (C) 2011 by Martin Schmoelzer *
3 * <martin.schmoelzer@student.tuwien.ac.at> *
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, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
18
19 #include "jtag.h"
20
21 #include "io.h"
22 #include "msgtypes.h"
23 #include "common.h"
24
25 #include <stdbool.h>
26
27 /** Delay value for SCAN_IN operations with less than maximum TCK frequency */
28 uint8_t delay_scan_in;
29
30 /** Delay value for SCAN_OUT operations with less than maximum TCK frequency */
31 uint8_t delay_scan_out;
32
33 /** Delay value for SCAN_IO operations with less than maximum TCK frequency */
34 uint8_t delay_scan_io;
35
36 /** Delay value for CLOCK_TCK operations with less than maximum frequency */
37 uint8_t delay_tck;
38
39 /** Delay value for CLOCK_TMS operations with less than maximum frequency */
40 uint8_t delay_tms;
41
42 /**
43 * Perform JTAG SCAN-IN operation at maximum TCK frequency.
44 *
45 * Dummy data is shifted into the JTAG chain via TDI, TDO data is sampled and
46 * stored in the EP2 IN buffer.
47 *
48 * Maximum achievable TCK frequency is 182 kHz for ULINK clocked at 24 MHz.
49 *
50 * @param out_offset offset in OUT2BUF where payload data starts
51 * @param in_offset
52 */
53 void jtag_scan_in(uint8_t out_offset, uint8_t in_offset)
54 {
55 uint8_t scan_size_bytes, bits_last_byte;
56 uint8_t tms_count_start, tms_count_end;
57 uint8_t tms_sequence_start, tms_sequence_end;
58 uint8_t tdo_data, i, j;
59
60 uint8_t outb_buffer;
61
62 /* Get parameters from OUT2BUF */
63 scan_size_bytes = OUT2BUF[out_offset];
64 bits_last_byte = OUT2BUF[out_offset + 1];
65 tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
66 tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
67 tms_sequence_start = OUT2BUF[out_offset + 3];
68 tms_sequence_end = OUT2BUF[out_offset + 4];
69
70 if (tms_count_start > 0)
71 jtag_clock_tms(tms_count_start, tms_sequence_start);
72
73 outb_buffer = OUTB & ~(PIN_TDI | PIN_TCK | PIN_TMS);
74
75 /* Shift all bytes except the last byte */
76 for (i = 0; i < scan_size_bytes - 1; i++) {
77 tdo_data = 0;
78
79 for (j = 0; j < 8; j++) {
80 OUTB = outb_buffer; /* TCK changes here */
81 tdo_data = tdo_data >> 1;
82 OUTB = (outb_buffer | PIN_TCK);
83
84 if (GET_TDO())
85 tdo_data |= 0x80;
86 }
87
88 /* Copy TDO data to IN2BUF */
89 IN2BUF[i + in_offset] = tdo_data;
90 }
91
92 tdo_data = 0;
93
94 /* Shift the last byte */
95 for (j = 0; j < bits_last_byte; j++) {
96 /* Assert TMS signal if requested and this is the last bit */
97 if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
98 outb_buffer |= PIN_TMS;
99 tms_count_end--;
100 tms_sequence_end = tms_sequence_end >> 1;
101 }
102
103 OUTB = outb_buffer; /* TCK changes here */
104 tdo_data = tdo_data >> 1;
105 OUTB = (outb_buffer | PIN_TCK);
106
107 if (GET_TDO())
108 tdo_data |= 0x80;
109 }
110 tdo_data = tdo_data >> (8 - bits_last_byte);
111
112 /* Copy TDO data to IN2BUF */
113 IN2BUF[i + in_offset] = tdo_data;
114
115 /* Move to correct end state */
116 if (tms_count_end > 0)
117 jtag_clock_tms(tms_count_end, tms_sequence_end);
118 }
119
120 /**
121 * Perform JTAG SCAN-IN operation at variable TCK frequency.
122 *
123 * Dummy data is shifted into the JTAG chain via TDI, TDO data is sampled and
124 * stored in the EP2 IN buffer.
125 *
126 * Maximum achievable TCK frequency is 113 kHz for ULINK clocked at 24 MHz.
127 *
128 * @param out_offset offset in OUT2BUF where payload data starts
129 * @param in_offset
130 */
131 void jtag_slow_scan_in(uint8_t out_offset, uint8_t in_offset)
132 {
133 uint8_t scan_size_bytes, bits_last_byte;
134 uint8_t tms_count_start, tms_count_end;
135 uint8_t tms_sequence_start, tms_sequence_end;
136 uint8_t tdo_data, i, j, k;
137
138 uint8_t outb_buffer;
139
140 /* Get parameters from OUT2BUF */
141 scan_size_bytes = OUT2BUF[out_offset];
142 bits_last_byte = OUT2BUF[out_offset + 1];
143 tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
144 tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
145 tms_sequence_start = OUT2BUF[out_offset + 3];
146 tms_sequence_end = OUT2BUF[out_offset + 4];
147
148 if (tms_count_start > 0)
149 jtag_slow_clock_tms(tms_count_start, tms_sequence_start);
150
151 outb_buffer = OUTB & ~(PIN_TDI | PIN_TCK | PIN_TMS);
152
153 /* Shift all bytes except the last byte */
154 for (i = 0; i < scan_size_bytes - 1; i++) {
155 tdo_data = 0;
156
157 for (j = 0; j < 8; j++) {
158 OUTB = outb_buffer; /* TCK changes here */
159 for (k = 0; k < delay_scan_in; k++)
160 ;
161 tdo_data = tdo_data >> 1;
162
163 OUTB = (outb_buffer | PIN_TCK);
164 for (k = 0; k < delay_scan_in; k++)
165 ;
166
167 if (GET_TDO())
168 tdo_data |= 0x80;
169 }
170
171 /* Copy TDO data to IN2BUF */
172 IN2BUF[i + in_offset] = tdo_data;
173 }
174
175 tdo_data = 0;
176
177 /* Shift the last byte */
178 for (j = 0; j < bits_last_byte; j++) {
179 /* Assert TMS signal if requested and this is the last bit */
180 if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
181 outb_buffer |= PIN_TMS;
182 tms_count_end--;
183 tms_sequence_end = tms_sequence_end >> 1;
184 }
185
186 OUTB = outb_buffer; /* TCK changes here */
187 for (k = 0; k < delay_scan_in; k++)
188 ;
189 tdo_data = tdo_data >> 1;
190
191 OUTB = (outb_buffer | PIN_TCK);
192 for (k = 0; k < delay_scan_in; k++)
193 ;
194
195 if (GET_TDO())
196 tdo_data |= 0x80;
197 }
198 tdo_data = tdo_data >> (8 - bits_last_byte);
199
200 /* Copy TDO data to IN2BUF */
201 IN2BUF[i + in_offset] = tdo_data;
202
203 /* Move to correct end state */
204 if (tms_count_end > 0)
205 jtag_slow_clock_tms(tms_count_end, tms_sequence_end);
206 }
207
208 /**
209 * Perform JTAG SCAN-OUT operation at maximum TCK frequency.
210 *
211 * Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO
212 * data is not sampled.
213 * The TAP-FSM state is always left in the PAUSE-DR/PAUSE-IR state.
214 *
215 * Maximum achievable TCK frequency is 142 kHz for ULINK clocked at 24 MHz.
216 *
217 * @param out_offset offset in OUT2BUF where payload data starts
218 */
219 void jtag_scan_out(uint8_t out_offset)
220 {
221 uint8_t scan_size_bytes, bits_last_byte;
222 uint8_t tms_count_start, tms_count_end;
223 uint8_t tms_sequence_start, tms_sequence_end;
224 uint8_t tdi_data, i, j;
225
226 uint8_t outb_buffer;
227
228 /* Get parameters from OUT2BUF */
229 scan_size_bytes = OUT2BUF[out_offset];
230 bits_last_byte = OUT2BUF[out_offset + 1];
231 tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
232 tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
233 tms_sequence_start = OUT2BUF[out_offset + 3];
234 tms_sequence_end = OUT2BUF[out_offset + 4];
235
236 if (tms_count_start > 0)
237 jtag_clock_tms(tms_count_start, tms_sequence_start);
238
239 outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);
240
241 /* Shift all bytes except the last byte */
242 for (i = 0; i < scan_size_bytes - 1; i++) {
243 tdi_data = OUT2BUF[i + out_offset + 5];
244
245 for (j = 0; j < 8; j++) {
246 if (tdi_data & 0x01)
247 outb_buffer |= PIN_TDI;
248 else
249 outb_buffer &= ~PIN_TDI;
250
251 OUTB = outb_buffer; /* TDI and TCK change here */
252 tdi_data = tdi_data >> 1;
253 OUTB = (outb_buffer | PIN_TCK);
254 }
255 }
256
257 tdi_data = OUT2BUF[i + out_offset + 5];
258
259 /* Shift the last byte */
260 for (j = 0; j < bits_last_byte; j++) {
261 if (tdi_data & 0x01)
262 outb_buffer |= PIN_TDI;
263 else
264 outb_buffer &= ~PIN_TDI;
265
266 /* Assert TMS signal if requested and this is the last bit */
267 if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
268 outb_buffer |= PIN_TMS;
269 tms_count_end--;
270 tms_sequence_end = tms_sequence_end >> 1;
271 }
272
273 OUTB = outb_buffer; /* TDI and TCK change here */
274 tdi_data = tdi_data >> 1;
275 OUTB = (outb_buffer | PIN_TCK);
276 }
277
278 /* Move to correct end state */
279 if (tms_count_end > 0)
280 jtag_clock_tms(tms_count_end, tms_sequence_end);
281 }
282
283 /**
284 * Perform JTAG SCAN-OUT operation at maximum TCK frequency.
285 *
286 * Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO
287 * data is not sampled.
288 * The TAP-FSM state is always left in the PAUSE-DR/PAUSE-IR state.
289 *
290 * Maximum achievable TCK frequency is 97 kHz for ULINK clocked at 24 MHz.
291 *
292 * @param out_offset offset in OUT2BUF where payload data starts
293 */
294 void jtag_slow_scan_out(uint8_t out_offset)
295 {
296 uint8_t scan_size_bytes, bits_last_byte;
297 uint8_t tms_count_start, tms_count_end;
298 uint8_t tms_sequence_start, tms_sequence_end;
299 uint8_t tdi_data, i, j, k;
300
301 uint8_t outb_buffer;
302
303 /* Get parameters from OUT2BUF */
304 scan_size_bytes = OUT2BUF[out_offset];
305 bits_last_byte = OUT2BUF[out_offset + 1];
306 tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
307 tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
308 tms_sequence_start = OUT2BUF[out_offset + 3];
309 tms_sequence_end = OUT2BUF[out_offset + 4];
310
311 if (tms_count_start > 0)
312 jtag_slow_clock_tms(tms_count_start, tms_sequence_start);
313
314 outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);
315
316 /* Shift all bytes except the last byte */
317 for (i = 0; i < scan_size_bytes - 1; i++) {
318 tdi_data = OUT2BUF[i + out_offset + 5];
319
320 for (j = 0; j < 8; j++) {
321 if (tdi_data & 0x01)
322 outb_buffer |= PIN_TDI;
323 else
324 outb_buffer &= ~PIN_TDI;
325
326 OUTB = outb_buffer; /* TDI and TCK change here */
327 for (k = 0; k < delay_scan_out; k++)
328 ;
329 tdi_data = tdi_data >> 1;
330
331 OUTB = (outb_buffer | PIN_TCK);
332 for (k = 0; k < delay_scan_out; k++)
333 ;
334 }
335 }
336
337 tdi_data = OUT2BUF[i + out_offset + 5];
338
339 /* Shift the last byte */
340 for (j = 0; j < bits_last_byte; j++) {
341 if (tdi_data & 0x01)
342 outb_buffer |= PIN_TDI;
343 else
344 outb_buffer &= ~PIN_TDI;
345
346 /* Assert TMS signal if requested and this is the last bit */
347 if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
348 outb_buffer |= PIN_TMS;
349 tms_count_end--;
350 tms_sequence_end = tms_sequence_end >> 1;
351 }
352
353 OUTB = outb_buffer; /* TDI and TCK change here */
354 for (k = 0; k < delay_scan_out; k++)
355 ;
356 tdi_data = tdi_data >> 1;
357
358 OUTB = (outb_buffer | PIN_TCK);
359 for (k = 0; k < delay_scan_out; k++)
360 ;
361 }
362
363 /* Move to correct end state */
364 if (tms_count_end > 0)
365 jtag_slow_clock_tms(tms_count_end, tms_sequence_end);
366 }
367
368 /**
369 * Perform bidirectional JTAG SCAN operation at maximum TCK frequency.
370 *
371 * Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO
372 * data is sampled and stored in the EP2 IN buffer.
373 * The TAP-FSM state is always left in the PAUSE-DR/PAUSE-IR state.
374 *
375 * Maximum achievable TCK frequency is 100 kHz for ULINK clocked at 24 MHz.
376 *
377 * @param out_offset offset in OUT2BUF where payload data starts
378 * @param in_offset
379 */
380 void jtag_scan_io(uint8_t out_offset, uint8_t in_offset)
381 {
382 uint8_t scan_size_bytes, bits_last_byte;
383 uint8_t tms_count_start, tms_count_end;
384 uint8_t tms_sequence_start, tms_sequence_end;
385 uint8_t tdi_data, tdo_data, i, j;
386
387 uint8_t outb_buffer;
388
389 /* Get parameters from OUT2BUF */
390 scan_size_bytes = OUT2BUF[out_offset];
391 bits_last_byte = OUT2BUF[out_offset + 1];
392 tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
393 tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
394 tms_sequence_start = OUT2BUF[out_offset + 3];
395 tms_sequence_end = OUT2BUF[out_offset + 4];
396
397 if (tms_count_start > 0)
398 jtag_clock_tms(tms_count_start, tms_sequence_start);
399
400 outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);
401
402 /* Shift all bytes except the last byte */
403 for (i = 0; i < scan_size_bytes - 1; i++) {
404 tdi_data = OUT2BUF[i + out_offset + 5];
405 tdo_data = 0;
406
407 for (j = 0; j < 8; j++) {
408 if (tdi_data & 0x01)
409 outb_buffer |= PIN_TDI;
410 else
411 outb_buffer &= ~PIN_TDI;
412
413 OUTB = outb_buffer; /* TDI and TCK change here */
414 tdi_data = tdi_data >> 1;
415 OUTB = (outb_buffer | PIN_TCK);
416 tdo_data = tdo_data >> 1;
417
418 if (GET_TDO())
419 tdo_data |= 0x80;
420 }
421
422 /* Copy TDO data to IN2BUF */
423 IN2BUF[i + in_offset] = tdo_data;
424 }
425
426 tdi_data = OUT2BUF[i + out_offset + 5];
427 tdo_data = 0;
428
429 /* Shift the last byte */
430 for (j = 0; j < bits_last_byte; j++) {
431 if (tdi_data & 0x01)
432 outb_buffer |= PIN_TDI;
433 else
434 outb_buffer &= ~PIN_TDI;
435
436 /* Assert TMS signal if requested and this is the last bit */
437 if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
438 outb_buffer |= PIN_TMS;
439 tms_count_end--;
440 tms_sequence_end = tms_sequence_end >> 1;
441 }
442
443 OUTB = outb_buffer; /* TDI and TCK change here */
444 tdi_data = tdi_data >> 1;
445 OUTB = (outb_buffer | PIN_TCK);
446 tdo_data = tdo_data >> 1;
447
448 if (GET_TDO())
449 tdo_data |= 0x80;
450 }
451 tdo_data = tdo_data >> (8 - bits_last_byte);
452
453 /* Copy TDO data to IN2BUF */
454 IN2BUF[i + in_offset] = tdo_data;
455
456 /* Move to correct end state */
457 if (tms_count_end > 0)
458 jtag_clock_tms(tms_count_end, tms_sequence_end);
459 }
460
461 /**
462 * Perform bidirectional JTAG SCAN operation at maximum TCK frequency.
463 *
464 * Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO
465 * data is sampled and stored in the EP2 IN buffer.
466 * The TAP-FSM state is always left in the PAUSE-DR/PAUSE-IR state.
467 *
468 * Maximum achievable TCK frequency is 78 kHz for ULINK clocked at 24 MHz.
469 *
470 * @param out_offset offset in OUT2BUF where payload data starts
471 * @param in_offset
472 */
473 void jtag_slow_scan_io(uint8_t out_offset, uint8_t in_offset)
474 {
475 uint8_t scan_size_bytes, bits_last_byte;
476 uint8_t tms_count_start, tms_count_end;
477 uint8_t tms_sequence_start, tms_sequence_end;
478 uint8_t tdi_data, tdo_data, i, j, k;
479
480 uint8_t outb_buffer;
481
482 /* Get parameters from OUT2BUF */
483 scan_size_bytes = OUT2BUF[out_offset];
484 bits_last_byte = OUT2BUF[out_offset + 1];
485 tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
486 tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
487 tms_sequence_start = OUT2BUF[out_offset + 3];
488 tms_sequence_end = OUT2BUF[out_offset + 4];
489
490 if (tms_count_start > 0)
491 jtag_slow_clock_tms(tms_count_start, tms_sequence_start);
492
493 outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);
494
495 /* Shift all bytes except the last byte */
496 for (i = 0; i < scan_size_bytes - 1; i++) {
497 tdi_data = OUT2BUF[i + out_offset + 5];
498 tdo_data = 0;
499
500 for (j = 0; j < 8; j++) {
501 if (tdi_data & 0x01)
502 outb_buffer |= PIN_TDI;
503 else
504 outb_buffer &= ~PIN_TDI;
505
506 OUTB = outb_buffer; /* TDI and TCK change here */
507 for (k = 0; k < delay_scan_io; k++)
508 ;
509 tdi_data = tdi_data >> 1;
510
511 OUTB = (outb_buffer | PIN_TCK);
512 for (k = 0; k < delay_scan_io; k++)
513 ;
514 tdo_data = tdo_data >> 1;
515
516 if (GET_TDO())
517 tdo_data |= 0x80;
518 }
519
520 /* Copy TDO data to IN2BUF */
521 IN2BUF[i + in_offset] = tdo_data;
522 }
523
524 tdi_data = OUT2BUF[i + out_offset + 5];
525 tdo_data = 0;
526
527 /* Shift the last byte */
528 for (j = 0; j < bits_last_byte; j++) {
529 if (tdi_data & 0x01)
530 outb_buffer |= PIN_TDI;
531 else
532 outb_buffer &= ~PIN_TDI;
533
534 /* Assert TMS signal if requested and this is the last bit */
535 if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
536 outb_buffer |= PIN_TMS;
537 tms_count_end--;
538 tms_sequence_end = tms_sequence_end >> 1;
539 }
540
541 OUTB = outb_buffer; /* TDI and TCK change here */
542 for (k = 0; k < delay_scan_io; k++)
543 ;
544 tdi_data = tdi_data >> 1;
545
546 OUTB = (outb_buffer | PIN_TCK);
547 for (k = 0; k < delay_scan_io; k++)
548 ;
549 tdo_data = tdo_data >> 1;
550
551 if (GET_TDO())
552 tdo_data |= 0x80;
553 }
554 tdo_data = tdo_data >> (8 - bits_last_byte);
555
556 /* Copy TDO data to IN2BUF */
557 IN2BUF[i + in_offset] = tdo_data;
558
559 /* Move to correct end state */
560 if (tms_count_end > 0)
561 jtag_slow_clock_tms(tms_count_end, tms_sequence_end);
562 }
563
564 /**
565 * Generate TCK clock cycles.
566 *
567 * Maximum achievable TCK frequency is 375 kHz for ULINK clocked at 24 MHz.
568 *
569 * @param count number of TCK clock cycles to generate.
570 */
571 void jtag_clock_tck(uint16_t count)
572 {
573 uint16_t i;
574 uint8_t outb_buffer = OUTB & ~(PIN_TCK);
575
576 for (i = 0; i < count; i++) {
577 OUTB = outb_buffer;
578 OUTB = outb_buffer | PIN_TCK;
579 }
580 }
581
582 /**
583 * Generate TCK clock cycles at variable frequency.
584 *
585 * Maximum achievable TCK frequency is 166.6 kHz for ULINK clocked at 24 MHz.
586 *
587 * @param count number of TCK clock cycles to generate.
588 */
589 void jtag_slow_clock_tck(uint16_t count)
590 {
591 uint16_t i;
592 uint8_t j;
593 uint8_t outb_buffer = OUTB & ~(PIN_TCK);
594
595 for (i = 0; i < count; i++) {
596 OUTB = outb_buffer;
597 for (j = 0; j < delay_tck; j++)
598 ;
599 OUTB = outb_buffer | PIN_TCK;
600 for (j = 0; j < delay_tck; j++)
601 ;
602 }
603 }
604
605 /**
606 * Perform TAP FSM state transitions at maximum TCK frequency.
607 *
608 * Maximum achievable TCK frequency is 176 kHz for ULINK clocked at 24 MHz.
609 *
610 * @param count the number of state transitions to perform.
611 * @param sequence the TMS pin levels for each state transition, starting with
612 * the least-significant bit.
613 */
614 void jtag_clock_tms(uint8_t count, uint8_t sequence)
615 {
616 uint8_t outb_buffer = OUTB & ~(PIN_TCK);
617 uint8_t i;
618
619 for (i = 0; i < count; i++) {
620 /* Set TMS pin according to sequence parameter */
621 if (sequence & 0x1)
622 outb_buffer |= PIN_TMS;
623 else
624 outb_buffer &= ~PIN_TMS;
625
626 OUTB = outb_buffer;
627 sequence = sequence >> 1;
628 OUTB = outb_buffer | PIN_TCK;
629 }
630 }
631
632 /**
633 * Perform TAP-FSM state transitions at less than maximum TCK frequency.
634 *
635 * Maximum achievable TCK frequency is 117 kHz for ULINK clocked at 24 MHz.
636 *
637 * @param count the number of state transitions to perform.
638 * @param sequence the TMS pin levels for each state transition, starting with
639 * the least-significant bit.
640 */
641 void jtag_slow_clock_tms(uint8_t count, uint8_t sequence)
642 {
643 uint8_t outb_buffer = OUTB & ~(PIN_TCK);
644 uint8_t i, j;
645
646 for (i = 0; i < count; i++) {
647 /* Set TMS pin according to sequence parameter */
648 if (sequence & 0x1)
649 outb_buffer |= PIN_TMS;
650 else
651 outb_buffer &= ~PIN_TMS;
652
653 OUTB = outb_buffer;
654 for (j = 0; j < delay_tms; j++)
655 ;
656 sequence = sequence >> 1;
657 OUTB = outb_buffer | PIN_TCK;
658 for (j = 0; j < delay_tms; j++)
659 ;
660 }
661 }
662
663 /**
664 * Get current JTAG signal states.
665 *
666 * @return a 16-bit integer where the most-significant byte contains the state
667 * of the JTAG input signals and the least-significant byte contains the state
668 * of the JTAG output signals.
669 */
670 uint16_t jtag_get_signals(void)
671 {
672 uint8_t input_signal_state, output_signal_state;
673
674 input_signal_state = 0;
675 output_signal_state = 0;
676
677 /* Get states of input pins */
678 if (GET_TDO())
679 input_signal_state |= SIGNAL_TDO;
680 if (GET_BRKOUT())
681 input_signal_state |= SIGNAL_BRKOUT;
682 if (GET_TRAP())
683 input_signal_state |= SIGNAL_TRAP;
684 if (GET_RTCK()) {
685 /* Using RTCK this way would be extremely slow,
686 * implemented only for the sake of completeness */
687 input_signal_state |= SIGNAL_RTCK;
688 }
689
690 /* Get states of output pins */
691 output_signal_state = PINSB & MASK_PORTB_DIRECTION_OUT;
692
693 return ((uint16_t)input_signal_state << 8) | ((uint16_t)output_signal_state);
694 }
695
696 /**
697 * Set state of JTAG output signals.
698 *
699 * @param low signals which should be de-asserted.
700 * @param high signals which should be asserted.
701 */
702 void jtag_set_signals(uint8_t low, uint8_t high)
703 {
704 OUTB &= ~(low & MASK_PORTB_DIRECTION_OUT);
705 OUTB |= (high & MASK_PORTB_DIRECTION_OUT);
706 }
707
708 /**
709 * Configure TCK delay parameters.
710 *
711 * @param scan_in number of delay cycles in scan_in operations.
712 * @param scan_out number of delay cycles in scan_out operations.
713 * @param scan_io number of delay cycles in scan_io operations.
714 * @param tck number of delay cycles in clock_tck operations.
715 * @param tms number of delay cycles in clock_tms operations.
716 */
717 void jtag_configure_tck_delay(uint8_t scan_in, uint8_t scan_out,
718 uint8_t scan_io, uint8_t tck, uint8_t tms)
719 {
720 delay_scan_in = scan_in;
721 delay_scan_out = scan_out;
722 delay_scan_io = scan_io;
723 delay_tck = tck;
724 delay_tms = tms;
725 }

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)