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 */
jtag_scan_in(uint8_t out_offset,uint8_t in_offset)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 */
jtag_slow_scan_in(uint8_t out_offset,uint8_t in_offset)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 */
jtag_scan_out(uint8_t out_offset)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 */
jtag_slow_scan_out(uint8_t out_offset)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 */
jtag_scan_io(uint8_t out_offset,uint8_t in_offset)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 */
jtag_slow_scan_io(uint8_t out_offset,uint8_t in_offset)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 */
jtag_clock_tck(uint16_t count)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 */
jtag_slow_clock_tck(uint16_t count)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 */
jtag_clock_tms(uint8_t count,uint8_t sequence)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 */
jtag_slow_clock_tms(uint8_t count,uint8_t sequence)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 */
jtag_get_signals(void)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 */
jtag_set_signals(uint8_t low,uint8_t high)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 */
jtag_configure_tck_delay(uint8_t scan_in,uint8_t scan_out,uint8_t scan_io,uint8_t tck,uint8_t tms)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 }
726