1 /***************************************************************************
2 * Copyright (C) 2011 by Martin Schmoelzer *
3 * <martin.schmoelzer@student.tuwien.ac.at> *
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. *
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. *
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 ***************************************************************************/
27 /** Delay value for SCAN_IN operations with less than maximum TCK frequency */
28 uint8_t delay_scan_in;
30 /** Delay value for SCAN_OUT operations with less than maximum TCK frequency */
31 uint8_t delay_scan_out;
33 /** Delay value for SCAN_IO operations with less than maximum TCK frequency */
34 uint8_t delay_scan_io;
36 /** Delay value for CLOCK_TCK operations with less than maximum frequency */
39 /** Delay value for CLOCK_TMS operations with less than maximum frequency */
43 * Perform JTAG SCAN-IN operation at maximum TCK frequency.
45 * Dummy data is shifted into the JTAG chain via TDI, TDO data is sampled and
46 * stored in the EP2 IN buffer.
48 * Maximum achievable TCK frequency is 182 kHz for ULINK clocked at 24 MHz.
50 * @param out_offset offset in OUT2BUF where payload data starts
52 void jtag_scan_in(uint8_t out_offset, uint8_t in_offset)
54 uint8_t scan_size_bytes, bits_last_byte;
55 uint8_t tms_count_start, tms_count_end;
56 uint8_t tms_sequence_start, tms_sequence_end;
57 uint8_t tdo_data, i, j;
61 /* Get parameters from OUT2BUF */
62 scan_size_bytes = OUT2BUF[out_offset];
63 bits_last_byte = OUT2BUF[out_offset + 1];
64 tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
65 tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
66 tms_sequence_start = OUT2BUF[out_offset + 3];
67 tms_sequence_end = OUT2BUF[out_offset + 4];
69 if (tms_count_start > 0)
70 jtag_clock_tms(tms_count_start, tms_sequence_start);
72 outb_buffer = OUTB & ~(PIN_TDI | PIN_TCK | PIN_TMS);
74 /* Shift all bytes except the last byte */
75 for (i = 0; i < scan_size_bytes - 1; i++) {
78 for (j = 0; j < 8; j++) {
79 OUTB = outb_buffer; /* TCK changes here */
80 tdo_data = tdo_data >> 1;
81 OUTB = (outb_buffer | PIN_TCK);
87 /* Copy TDO data to IN2BUF */
88 IN2BUF[i + in_offset] = tdo_data;
93 /* Shift the last byte */
94 for (j = 0; j < bits_last_byte; j++) {
95 /* Assert TMS signal if requested and this is the last bit */
96 if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
97 outb_buffer |= PIN_TMS;
99 tms_sequence_end = tms_sequence_end >> 1;
102 OUTB = outb_buffer; /* TCK changes here */
103 tdo_data = tdo_data >> 1;
104 OUTB = (outb_buffer | PIN_TCK);
109 tdo_data = tdo_data >> (8 - bits_last_byte);
111 /* Copy TDO data to IN2BUF */
112 IN2BUF[i + in_offset] = tdo_data;
114 /* Move to correct end state */
115 if (tms_count_end > 0)
116 jtag_clock_tms(tms_count_end, tms_sequence_end);
120 * Perform JTAG SCAN-IN operation at variable TCK frequency.
122 * Dummy data is shifted into the JTAG chain via TDI, TDO data is sampled and
123 * stored in the EP2 IN buffer.
125 * Maximum achievable TCK frequency is 113 kHz for ULINK clocked at 24 MHz.
127 * @param out_offset offset in OUT2BUF where payload data starts
129 void jtag_slow_scan_in(uint8_t out_offset, uint8_t in_offset)
131 uint8_t scan_size_bytes, bits_last_byte;
132 uint8_t tms_count_start, tms_count_end;
133 uint8_t tms_sequence_start, tms_sequence_end;
134 uint8_t tdo_data, i, j, k;
138 /* Get parameters from OUT2BUF */
139 scan_size_bytes = OUT2BUF[out_offset];
140 bits_last_byte = OUT2BUF[out_offset + 1];
141 tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
142 tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
143 tms_sequence_start = OUT2BUF[out_offset + 3];
144 tms_sequence_end = OUT2BUF[out_offset + 4];
146 if (tms_count_start > 0)
147 jtag_slow_clock_tms(tms_count_start, tms_sequence_start);
149 outb_buffer = OUTB & ~(PIN_TDI | PIN_TCK | PIN_TMS);
151 /* Shift all bytes except the last byte */
152 for (i = 0; i < scan_size_bytes - 1; i++) {
155 for (j = 0; j < 8; j++) {
156 OUTB = outb_buffer; /* TCK changes here */
157 for (k = 0; k < delay_scan_in; k++)
159 tdo_data = tdo_data >> 1;
161 OUTB = (outb_buffer | PIN_TCK);
162 for (k = 0; k < delay_scan_in; k++)
169 /* Copy TDO data to IN2BUF */
170 IN2BUF[i + in_offset] = tdo_data;
175 /* Shift the last byte */
176 for (j = 0; j < bits_last_byte; j++) {
177 /* Assert TMS signal if requested and this is the last bit */
178 if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
179 outb_buffer |= PIN_TMS;
181 tms_sequence_end = tms_sequence_end >> 1;
184 OUTB = outb_buffer; /* TCK changes here */
185 for (k = 0; k < delay_scan_in; k++)
187 tdo_data = tdo_data >> 1;
189 OUTB = (outb_buffer | PIN_TCK);
190 for (k = 0; k < delay_scan_in; k++)
196 tdo_data = tdo_data >> (8 - bits_last_byte);
198 /* Copy TDO data to IN2BUF */
199 IN2BUF[i + in_offset] = tdo_data;
201 /* Move to correct end state */
202 if (tms_count_end > 0)
203 jtag_slow_clock_tms(tms_count_end, tms_sequence_end);
207 * Perform JTAG SCAN-OUT operation at maximum TCK frequency.
209 * Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO
210 * data is not sampled.
211 * The TAP-FSM state is alyways left in the PAUSE-DR/PAUSE-IR state.
213 * Maximum achievable TCK frequency is 142 kHz for ULINK clocked at 24 MHz.
215 * @param out_offset offset in OUT2BUF where payload data starts
217 void jtag_scan_out(uint8_t out_offset)
219 uint8_t scan_size_bytes, bits_last_byte;
220 uint8_t tms_count_start, tms_count_end;
221 uint8_t tms_sequence_start, tms_sequence_end;
222 uint8_t tdi_data, i, j;
226 /* Get parameters from OUT2BUF */
227 scan_size_bytes = OUT2BUF[out_offset];
228 bits_last_byte = OUT2BUF[out_offset + 1];
229 tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
230 tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
231 tms_sequence_start = OUT2BUF[out_offset + 3];
232 tms_sequence_end = OUT2BUF[out_offset + 4];
234 if (tms_count_start > 0)
235 jtag_clock_tms(tms_count_start, tms_sequence_start);
237 outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);
239 /* Shift all bytes except the last byte */
240 for (i = 0; i < scan_size_bytes - 1; i++) {
241 tdi_data = OUT2BUF[i + out_offset + 5];
243 for (j = 0; j < 8; j++) {
245 outb_buffer |= PIN_TDI;
247 outb_buffer &= ~PIN_TDI;
249 OUTB = outb_buffer; /* TDI and TCK change here */
250 tdi_data = tdi_data >> 1;
251 OUTB = (outb_buffer | PIN_TCK);
255 tdi_data = OUT2BUF[i + out_offset + 5];
257 /* Shift the last byte */
258 for (j = 0; j < bits_last_byte; j++) {
260 outb_buffer |= PIN_TDI;
262 outb_buffer &= ~PIN_TDI;
264 /* Assert TMS signal if requested and this is the last bit */
265 if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
266 outb_buffer |= PIN_TMS;
268 tms_sequence_end = tms_sequence_end >> 1;
271 OUTB = outb_buffer; /* TDI and TCK change here */
272 tdi_data = tdi_data >> 1;
273 OUTB = (outb_buffer | PIN_TCK);
276 /* Move to correct end state */
277 if (tms_count_end > 0)
278 jtag_clock_tms(tms_count_end, tms_sequence_end);
282 * Perform JTAG SCAN-OUT operation at maximum TCK frequency.
284 * Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO
285 * data is not sampled.
286 * The TAP-FSM state is alyways left in the PAUSE-DR/PAUSE-IR state.
288 * Maximum achievable TCK frequency is 97 kHz for ULINK clocked at 24 MHz.
290 * @param out_offset offset in OUT2BUF where payload data starts
292 void jtag_slow_scan_out(uint8_t out_offset)
294 uint8_t scan_size_bytes, bits_last_byte;
295 uint8_t tms_count_start, tms_count_end;
296 uint8_t tms_sequence_start, tms_sequence_end;
297 uint8_t tdi_data, i, j, k;
301 /* Get parameters from OUT2BUF */
302 scan_size_bytes = OUT2BUF[out_offset];
303 bits_last_byte = OUT2BUF[out_offset + 1];
304 tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
305 tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
306 tms_sequence_start = OUT2BUF[out_offset + 3];
307 tms_sequence_end = OUT2BUF[out_offset + 4];
309 if (tms_count_start > 0)
310 jtag_slow_clock_tms(tms_count_start, tms_sequence_start);
312 outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);
314 /* Shift all bytes except the last byte */
315 for (i = 0; i < scan_size_bytes - 1; i++) {
316 tdi_data = OUT2BUF[i + out_offset + 5];
318 for (j = 0; j < 8; j++) {
320 outb_buffer |= PIN_TDI;
322 outb_buffer &= ~PIN_TDI;
324 OUTB = outb_buffer; /* TDI and TCK change here */
325 for (k = 0; k < delay_scan_out; k++)
327 tdi_data = tdi_data >> 1;
329 OUTB = (outb_buffer | PIN_TCK);
330 for (k = 0; k < delay_scan_out; k++)
335 tdi_data = OUT2BUF[i + out_offset + 5];
337 /* Shift the last byte */
338 for (j = 0; j < bits_last_byte; j++) {
340 outb_buffer |= PIN_TDI;
342 outb_buffer &= ~PIN_TDI;
344 /* Assert TMS signal if requested and this is the last bit */
345 if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
346 outb_buffer |= PIN_TMS;
348 tms_sequence_end = tms_sequence_end >> 1;
351 OUTB = outb_buffer; /* TDI and TCK change here */
352 for (k = 0; k < delay_scan_out; k++)
354 tdi_data = tdi_data >> 1;
356 OUTB = (outb_buffer | PIN_TCK);
357 for (k = 0; k < delay_scan_out; k++)
361 /* Move to correct end state */
362 if (tms_count_end > 0)
363 jtag_slow_clock_tms(tms_count_end, tms_sequence_end);
367 * Perform bidirectional JTAG SCAN operation at maximum TCK frequency.
369 * Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO
370 * data is sampled and stored in the EP2 IN buffer.
371 * The TAP-FSM state is alyways left in the PAUSE-DR/PAUSE-IR state.
373 * Maximum achievable TCK frequency is 100 kHz for ULINK clocked at 24 MHz.
375 * @param out_offset offset in OUT2BUF where payload data starts
377 void jtag_scan_io(uint8_t out_offset, uint8_t in_offset)
379 uint8_t scan_size_bytes, bits_last_byte;
380 uint8_t tms_count_start, tms_count_end;
381 uint8_t tms_sequence_start, tms_sequence_end;
382 uint8_t tdi_data, tdo_data, i, j;
386 /* Get parameters from OUT2BUF */
387 scan_size_bytes = OUT2BUF[out_offset];
388 bits_last_byte = OUT2BUF[out_offset + 1];
389 tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
390 tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
391 tms_sequence_start = OUT2BUF[out_offset + 3];
392 tms_sequence_end = OUT2BUF[out_offset + 4];
394 if (tms_count_start > 0)
395 jtag_clock_tms(tms_count_start, tms_sequence_start);
397 outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);
399 /* Shift all bytes except the last byte */
400 for (i = 0; i < scan_size_bytes - 1; i++) {
401 tdi_data = OUT2BUF[i + out_offset + 5];
404 for (j = 0; j < 8; j++) {
406 outb_buffer |= PIN_TDI;
408 outb_buffer &= ~PIN_TDI;
410 OUTB = outb_buffer; /* TDI and TCK change here */
411 tdi_data = tdi_data >> 1;
412 OUTB = (outb_buffer | PIN_TCK);
413 tdo_data = tdo_data >> 1;
419 /* Copy TDO data to IN2BUF */
420 IN2BUF[i + in_offset] = tdo_data;
423 tdi_data = OUT2BUF[i + out_offset + 5];
426 /* Shift the last byte */
427 for (j = 0; j < bits_last_byte; j++) {
429 outb_buffer |= PIN_TDI;
431 outb_buffer &= ~PIN_TDI;
433 /* Assert TMS signal if requested and this is the last bit */
434 if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
435 outb_buffer |= PIN_TMS;
437 tms_sequence_end = tms_sequence_end >> 1;
440 OUTB = outb_buffer; /* TDI and TCK change here */
441 tdi_data = tdi_data >> 1;
442 OUTB = (outb_buffer | PIN_TCK);
443 tdo_data = tdo_data >> 1;
448 tdo_data = tdo_data >> (8 - bits_last_byte);
450 /* Copy TDO data to IN2BUF */
451 IN2BUF[i + in_offset] = tdo_data;
453 /* Move to correct end state */
454 if (tms_count_end > 0)
455 jtag_clock_tms(tms_count_end, tms_sequence_end);
459 * Perform bidirectional JTAG SCAN operation at maximum TCK frequency.
461 * Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO
462 * data is sampled and stored in the EP2 IN buffer.
463 * The TAP-FSM state is alyways left in the PAUSE-DR/PAUSE-IR state.
465 * Maximum achievable TCK frequency is 78 kHz for ULINK clocked at 24 MHz.
467 * @param out_offset offset in OUT2BUF where payload data starts
469 void jtag_slow_scan_io(uint8_t out_offset, uint8_t in_offset)
471 uint8_t scan_size_bytes, bits_last_byte;
472 uint8_t tms_count_start, tms_count_end;
473 uint8_t tms_sequence_start, tms_sequence_end;
474 uint8_t tdi_data, tdo_data, i, j, k;
478 /* Get parameters from OUT2BUF */
479 scan_size_bytes = OUT2BUF[out_offset];
480 bits_last_byte = OUT2BUF[out_offset + 1];
481 tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
482 tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
483 tms_sequence_start = OUT2BUF[out_offset + 3];
484 tms_sequence_end = OUT2BUF[out_offset + 4];
486 if (tms_count_start > 0)
487 jtag_slow_clock_tms(tms_count_start, tms_sequence_start);
489 outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);
491 /* Shift all bytes except the last byte */
492 for (i = 0; i < scan_size_bytes - 1; i++) {
493 tdi_data = OUT2BUF[i + out_offset + 5];
496 for (j = 0; j < 8; j++) {
498 outb_buffer |= PIN_TDI;
500 outb_buffer &= ~PIN_TDI;
502 OUTB = outb_buffer; /* TDI and TCK change here */
503 for (k = 0; k < delay_scan_io; k++)
505 tdi_data = tdi_data >> 1;
507 OUTB = (outb_buffer | PIN_TCK);
508 for (k = 0; k < delay_scan_io; k++)
510 tdo_data = tdo_data >> 1;
516 /* Copy TDO data to IN2BUF */
517 IN2BUF[i + in_offset] = tdo_data;
520 tdi_data = OUT2BUF[i + out_offset + 5];
523 /* Shift the last byte */
524 for (j = 0; j < bits_last_byte; j++) {
526 outb_buffer |= PIN_TDI;
528 outb_buffer &= ~PIN_TDI;
530 /* Assert TMS signal if requested and this is the last bit */
531 if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
532 outb_buffer |= PIN_TMS;
534 tms_sequence_end = tms_sequence_end >> 1;
537 OUTB = outb_buffer; /* TDI and TCK change here */
538 for (k = 0; k < delay_scan_io; k++)
540 tdi_data = tdi_data >> 1;
542 OUTB = (outb_buffer | PIN_TCK);
543 for (k = 0; k < delay_scan_io; k++)
545 tdo_data = tdo_data >> 1;
550 tdo_data = tdo_data >> (8 - bits_last_byte);
552 /* Copy TDO data to IN2BUF */
553 IN2BUF[i + in_offset] = tdo_data;
555 /* Move to correct end state */
556 if (tms_count_end > 0)
557 jtag_slow_clock_tms(tms_count_end, tms_sequence_end);
561 * Generate TCK clock cycles.
563 * Maximum achievable TCK frequency is 375 kHz for ULINK clocked at 24 MHz.
565 * @param count number of TCK clock cyclces to generate.
567 void jtag_clock_tck(uint16_t count)
570 uint8_t outb_buffer = OUTB & ~(PIN_TCK);
572 for (i = 0; i < count; i++) {
574 OUTB = outb_buffer | PIN_TCK;
579 * Generate TCK clock cycles at variable frequency.
581 * Maximum achieveable TCK frequency is 166.6 kHz for ULINK clocked at 24 MHz.
583 * @param count number of TCK clock cyclces to generate.
585 void jtag_slow_clock_tck(uint16_t count)
589 uint8_t outb_buffer = OUTB & ~(PIN_TCK);
591 for (i = 0; i < count; i++) {
593 for (j = 0; j < delay_tck; j++)
595 OUTB = outb_buffer | PIN_TCK;
596 for (j = 0; j < delay_tck; j++)
602 * Perform TAP FSM state transitions at maximum TCK frequency.
604 * Maximum achievable TCK frequency is 176 kHz for ULINK clocked at 24 MHz.
606 * @param count the number of state transitions to perform.
607 * @param sequence the TMS pin levels for each state transition, starting with
608 * the least-significant bit.
610 void jtag_clock_tms(uint8_t count, uint8_t sequence)
612 uint8_t outb_buffer = OUTB & ~(PIN_TCK);
615 for (i = 0; i < count; i++) {
616 /* Set TMS pin according to sequence parameter */
618 outb_buffer |= PIN_TMS;
620 outb_buffer &= ~PIN_TMS;
623 sequence = sequence >> 1;
624 OUTB = outb_buffer | PIN_TCK;
629 * Perform TAP-FSM state transitions at less than maximum TCK frequency.
631 * Maximum achievable TCK frequency is 117 kHz for ULINK clocked at 24 MHz.
633 * @param count the number of state transitions to perform.
634 * @param sequence the TMS pin levels for each state transition, starting with
635 * the least-significant bit.
637 void jtag_slow_clock_tms(uint8_t count, uint8_t sequence)
639 uint8_t outb_buffer = OUTB & ~(PIN_TCK);
642 for (i = 0; i < count; i++) {
643 /* Set TMS pin according to sequence parameter */
645 outb_buffer |= PIN_TMS;
647 outb_buffer &= ~PIN_TMS;
650 for (j = 0; j < delay_tms; j++)
652 sequence = sequence >> 1;
653 OUTB = outb_buffer | PIN_TCK;
654 for (j = 0; j < delay_tms; j++)
660 * Get current JTAG signal states.
662 * @return a 16-bit integer where the most-significant byte contains the state
663 * of the JTAG input signals and the least-significant byte contains the state
664 * of the JTAG output signals.
666 uint16_t jtag_get_signals(void)
668 uint8_t input_signal_state, output_signal_state;
670 input_signal_state = 0;
671 output_signal_state = 0;
673 /* Get states of input pins */
675 input_signal_state |= SIGNAL_TDO;
677 input_signal_state |= SIGNAL_BRKOUT;
679 input_signal_state |= SIGNAL_TRAP;
681 /* Using RTCK this way would be extremely slow,
682 * implemented only for the sake of completeness */
683 input_signal_state |= SIGNAL_RTCK;
686 /* Get states of output pins */
687 output_signal_state = PINSB & MASK_PORTB_DIRECTION_OUT;
689 return ((uint16_t)input_signal_state << 8) | ((uint16_t)output_signal_state);
693 * Set state of JTAG output signals.
695 * @param low signals which should be de-asserted.
696 * @param high signals which should be asserted.
698 void jtag_set_signals(uint8_t low, uint8_t high)
700 OUTB &= ~(low & MASK_PORTB_DIRECTION_OUT);
701 OUTB |= (high & MASK_PORTB_DIRECTION_OUT);
705 * Configure TCK delay parameters.
707 * @param scan_in number of delay cycles in scan_in operations.
708 * @param scan_out number of delay cycles in scan_out operations.
709 * @param scan_io number of delay cycles in scan_io operations.
710 * @param tck number of delay cycles in clock_tck operations.
711 * @param tms number of delay cycles in clock_tms operations.
713 void jtag_configure_tck_delay(uint8_t scan_in, uint8_t scan_out,
714 uint8_t scan_io, uint8_t tck, uint8_t tms)
716 delay_scan_in = scan_in;
717 delay_scan_out = scan_out;
718 delay_scan_io = scan_io;