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