Remove FSF address from GPL notices
[fw/openocd] / 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  */
52 void jtag_scan_in(uint8_t out_offset, uint8_t in_offset)
53 {
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;
58
59         uint8_t outb_buffer;
60
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];
68
69         if (tms_count_start > 0)
70                 jtag_clock_tms(tms_count_start, tms_sequence_start);
71
72         outb_buffer = OUTB & ~(PIN_TDI | PIN_TCK | PIN_TMS);
73
74         /* Shift all bytes except the last byte */
75         for (i = 0; i < scan_size_bytes - 1; i++) {
76                 tdo_data = 0;
77
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);
82
83                         if (GET_TDO())
84                                 tdo_data |= 0x80;
85                 }
86
87                 /* Copy TDO data to IN2BUF */
88                 IN2BUF[i + in_offset] = tdo_data;
89         }
90
91         tdo_data = 0;
92
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;
98                         tms_count_end--;
99                         tms_sequence_end = tms_sequence_end >> 1;
100                 }
101
102                 OUTB = outb_buffer;     /* TCK changes here */
103                 tdo_data = tdo_data >> 1;
104                 OUTB = (outb_buffer | PIN_TCK);
105
106                 if (GET_TDO())
107                         tdo_data |= 0x80;
108         }
109         tdo_data = tdo_data >> (8 - bits_last_byte);
110
111         /* Copy TDO data to IN2BUF */
112         IN2BUF[i + in_offset] = tdo_data;
113
114         /* Move to correct end state */
115         if (tms_count_end > 0)
116                 jtag_clock_tms(tms_count_end, tms_sequence_end);
117 }
118
119 /**
120  * Perform JTAG SCAN-IN operation at variable TCK frequency.
121  *
122  * Dummy data is shifted into the JTAG chain via TDI, TDO data is sampled and
123  * stored in the EP2 IN buffer.
124  *
125  * Maximum achievable TCK frequency is 113 kHz for ULINK clocked at 24 MHz.
126  *
127  * @param out_offset offset in OUT2BUF where payload data starts
128  */
129 void jtag_slow_scan_in(uint8_t out_offset, uint8_t in_offset)
130 {
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;
135
136         uint8_t outb_buffer;
137
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];
145
146         if (tms_count_start > 0)
147                 jtag_slow_clock_tms(tms_count_start, tms_sequence_start);
148
149         outb_buffer = OUTB & ~(PIN_TDI | PIN_TCK | PIN_TMS);
150
151         /* Shift all bytes except the last byte */
152         for (i = 0; i < scan_size_bytes - 1; i++) {
153                 tdo_data = 0;
154
155                 for (j = 0; j < 8; j++) {
156                         OUTB = outb_buffer;     /* TCK changes here */
157                         for (k = 0; k < delay_scan_in; k++)
158                                 ;
159                         tdo_data = tdo_data >> 1;
160
161                         OUTB = (outb_buffer | PIN_TCK);
162                         for (k = 0; k < delay_scan_in; k++)
163                                 ;
164
165                         if (GET_TDO())
166                                 tdo_data |= 0x80;
167                 }
168
169                 /* Copy TDO data to IN2BUF */
170                 IN2BUF[i + in_offset] = tdo_data;
171         }
172
173         tdo_data = 0;
174
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;
180                         tms_count_end--;
181                         tms_sequence_end = tms_sequence_end >> 1;
182                 }
183
184                 OUTB = outb_buffer;     /* TCK changes here */
185                 for (k = 0; k < delay_scan_in; k++)
186                         ;
187                 tdo_data = tdo_data >> 1;
188
189                 OUTB = (outb_buffer | PIN_TCK);
190                 for (k = 0; k < delay_scan_in; k++)
191                         ;
192
193                 if (GET_TDO())
194                         tdo_data |= 0x80;
195         }
196         tdo_data = tdo_data >> (8 - bits_last_byte);
197
198         /* Copy TDO data to IN2BUF */
199         IN2BUF[i + in_offset] = tdo_data;
200
201         /* Move to correct end state */
202         if (tms_count_end > 0)
203                 jtag_slow_clock_tms(tms_count_end, tms_sequence_end);
204 }
205
206 /**
207  * Perform JTAG SCAN-OUT operation at maximum TCK frequency.
208  *
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.
212  *
213  * Maximum achievable TCK frequency is 142 kHz for ULINK clocked at 24 MHz.
214  *
215  * @param out_offset offset in OUT2BUF where payload data starts
216  */
217 void jtag_scan_out(uint8_t out_offset)
218 {
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;
223
224         uint8_t outb_buffer;
225
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];
233
234         if (tms_count_start > 0)
235                 jtag_clock_tms(tms_count_start, tms_sequence_start);
236
237         outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);
238
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];
242
243                 for (j = 0; j < 8; j++) {
244                         if (tdi_data & 0x01)
245                                 outb_buffer |= PIN_TDI;
246                         else
247                                 outb_buffer &= ~PIN_TDI;
248
249                         OUTB = outb_buffer;     /* TDI and TCK change here */
250                         tdi_data = tdi_data >> 1;
251                         OUTB = (outb_buffer | PIN_TCK);
252                 }
253         }
254
255         tdi_data = OUT2BUF[i + out_offset + 5];
256
257         /* Shift the last byte */
258         for (j = 0; j < bits_last_byte; j++) {
259                 if (tdi_data & 0x01)
260                         outb_buffer |= PIN_TDI;
261                 else
262                         outb_buffer &= ~PIN_TDI;
263
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;
267                         tms_count_end--;
268                         tms_sequence_end = tms_sequence_end >> 1;
269                 }
270
271                 OUTB = outb_buffer;     /* TDI and TCK change here */
272                 tdi_data = tdi_data >> 1;
273                 OUTB = (outb_buffer | PIN_TCK);
274         }
275
276         /* Move to correct end state */
277         if (tms_count_end > 0)
278                 jtag_clock_tms(tms_count_end, tms_sequence_end);
279 }
280
281 /**
282  * Perform JTAG SCAN-OUT operation at maximum TCK frequency.
283  *
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.
287  *
288  * Maximum achievable TCK frequency is 97 kHz for ULINK clocked at 24 MHz.
289  *
290  * @param out_offset offset in OUT2BUF where payload data starts
291  */
292 void jtag_slow_scan_out(uint8_t out_offset)
293 {
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;
298
299         uint8_t outb_buffer;
300
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];
308
309         if (tms_count_start > 0)
310                 jtag_slow_clock_tms(tms_count_start, tms_sequence_start);
311
312         outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);
313
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];
317
318                 for (j = 0; j < 8; j++) {
319                         if (tdi_data & 0x01)
320                                 outb_buffer |= PIN_TDI;
321                         else
322                                 outb_buffer &= ~PIN_TDI;
323
324                         OUTB = outb_buffer;     /* TDI and TCK change here */
325                         for (k = 0; k < delay_scan_out; k++)
326                                 ;
327                         tdi_data = tdi_data >> 1;
328
329                         OUTB = (outb_buffer | PIN_TCK);
330                         for (k = 0; k < delay_scan_out; k++)
331                                 ;
332                 }
333         }
334
335         tdi_data = OUT2BUF[i + out_offset + 5];
336
337         /* Shift the last byte */
338         for (j = 0; j < bits_last_byte; j++) {
339                 if (tdi_data & 0x01)
340                         outb_buffer |= PIN_TDI;
341                 else
342                         outb_buffer &= ~PIN_TDI;
343
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;
347                         tms_count_end--;
348                         tms_sequence_end = tms_sequence_end >> 1;
349                 }
350
351                 OUTB = outb_buffer;     /* TDI and TCK change here */
352                 for (k = 0; k < delay_scan_out; k++)
353                         ;
354                 tdi_data = tdi_data >> 1;
355
356                 OUTB = (outb_buffer | PIN_TCK);
357                 for (k = 0; k < delay_scan_out; k++)
358                         ;
359         }
360
361         /* Move to correct end state */
362         if (tms_count_end > 0)
363                 jtag_slow_clock_tms(tms_count_end, tms_sequence_end);
364 }
365
366 /**
367  * Perform bidirectional JTAG SCAN operation at maximum TCK frequency.
368  *
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.
372  *
373  * Maximum achievable TCK frequency is 100 kHz for ULINK clocked at 24 MHz.
374  *
375  * @param out_offset offset in OUT2BUF where payload data starts
376  */
377 void jtag_scan_io(uint8_t out_offset, uint8_t in_offset)
378 {
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;
383
384         uint8_t outb_buffer;
385
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];
393
394         if (tms_count_start > 0)
395                 jtag_clock_tms(tms_count_start, tms_sequence_start);
396
397         outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);
398
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];
402                 tdo_data = 0;
403
404                 for (j = 0; j < 8; j++) {
405                         if (tdi_data & 0x01)
406                                 outb_buffer |= PIN_TDI;
407                         else
408                                 outb_buffer &= ~PIN_TDI;
409
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;
414
415                         if (GET_TDO())
416                                 tdo_data |= 0x80;
417                 }
418
419                 /* Copy TDO data to IN2BUF */
420                 IN2BUF[i + in_offset] = tdo_data;
421         }
422
423         tdi_data = OUT2BUF[i + out_offset + 5];
424         tdo_data = 0;
425
426         /* Shift the last byte */
427         for (j = 0; j < bits_last_byte; j++) {
428                 if (tdi_data & 0x01)
429                         outb_buffer |= PIN_TDI;
430                 else
431                         outb_buffer &= ~PIN_TDI;
432
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;
436                         tms_count_end--;
437                         tms_sequence_end = tms_sequence_end >> 1;
438                 }
439
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;
444
445                 if (GET_TDO())
446                         tdo_data |= 0x80;
447         }
448         tdo_data = tdo_data >> (8 - bits_last_byte);
449
450         /* Copy TDO data to IN2BUF */
451         IN2BUF[i + in_offset] = tdo_data;
452
453         /* Move to correct end state */
454         if (tms_count_end > 0)
455                 jtag_clock_tms(tms_count_end, tms_sequence_end);
456 }
457
458 /**
459  * Perform bidirectional JTAG SCAN operation at maximum TCK frequency.
460  *
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.
464  *
465  * Maximum achievable TCK frequency is 78 kHz for ULINK clocked at 24 MHz.
466  *
467  * @param out_offset offset in OUT2BUF where payload data starts
468  */
469 void jtag_slow_scan_io(uint8_t out_offset, uint8_t in_offset)
470 {
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;
475
476         uint8_t outb_buffer;
477
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];
485
486         if (tms_count_start > 0)
487                 jtag_slow_clock_tms(tms_count_start, tms_sequence_start);
488
489         outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);
490
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];
494                 tdo_data = 0;
495
496                 for (j = 0; j < 8; j++) {
497                         if (tdi_data & 0x01)
498                                 outb_buffer |= PIN_TDI;
499                         else
500                                 outb_buffer &= ~PIN_TDI;
501
502                         OUTB = outb_buffer;     /* TDI and TCK change here */
503                         for (k = 0; k < delay_scan_io; k++)
504                                 ;
505                         tdi_data = tdi_data >> 1;
506
507                         OUTB = (outb_buffer | PIN_TCK);
508                         for (k = 0; k < delay_scan_io; k++)
509                                 ;
510                         tdo_data = tdo_data >> 1;
511
512                         if (GET_TDO())
513                                 tdo_data |= 0x80;
514                 }
515
516                 /* Copy TDO data to IN2BUF */
517                 IN2BUF[i + in_offset] = tdo_data;
518         }
519
520         tdi_data = OUT2BUF[i + out_offset + 5];
521         tdo_data = 0;
522
523         /* Shift the last byte */
524         for (j = 0; j < bits_last_byte; j++) {
525                 if (tdi_data & 0x01)
526                         outb_buffer |= PIN_TDI;
527                 else
528                         outb_buffer &= ~PIN_TDI;
529
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;
533                         tms_count_end--;
534                         tms_sequence_end = tms_sequence_end >> 1;
535                 }
536
537                 OUTB = outb_buffer;     /* TDI and TCK change here */
538                 for (k = 0; k < delay_scan_io; k++)
539                         ;
540                 tdi_data = tdi_data >> 1;
541
542                 OUTB = (outb_buffer | PIN_TCK);
543                 for (k = 0; k < delay_scan_io; k++)
544                         ;
545                 tdo_data = tdo_data >> 1;
546
547                 if (GET_TDO())
548                         tdo_data |= 0x80;
549         }
550         tdo_data = tdo_data >> (8 - bits_last_byte);
551
552         /* Copy TDO data to IN2BUF */
553         IN2BUF[i + in_offset] = tdo_data;
554
555         /* Move to correct end state */
556         if (tms_count_end > 0)
557                 jtag_slow_clock_tms(tms_count_end, tms_sequence_end);
558 }
559
560 /**
561  * Generate TCK clock cycles.
562  *
563  * Maximum achievable TCK frequency is 375 kHz for ULINK clocked at 24 MHz.
564  *
565  * @param count number of TCK clock cyclces to generate.
566  */
567 void jtag_clock_tck(uint16_t count)
568 {
569         uint16_t i;
570         uint8_t outb_buffer = OUTB & ~(PIN_TCK);
571
572         for (i = 0; i < count; i++) {
573                 OUTB = outb_buffer;
574                 OUTB = outb_buffer | PIN_TCK;
575         }
576 }
577
578 /**
579  * Generate TCK clock cycles at variable frequency.
580  *
581  * Maximum achieveable TCK frequency is 166.6 kHz for ULINK clocked at 24 MHz.
582  *
583  * @param count number of TCK clock cyclces to generate.
584  */
585 void jtag_slow_clock_tck(uint16_t count)
586 {
587         uint16_t i;
588         uint8_t j;
589         uint8_t outb_buffer = OUTB & ~(PIN_TCK);
590
591         for (i = 0; i < count; i++) {
592                 OUTB = outb_buffer;
593                 for (j = 0; j < delay_tck; j++)
594                         ;
595                 OUTB = outb_buffer | PIN_TCK;
596                 for (j = 0; j < delay_tck; j++)
597                         ;
598         }
599 }
600
601 /**
602  * Perform TAP FSM state transitions at maximum TCK frequency.
603  *
604  * Maximum achievable TCK frequency is 176 kHz for ULINK clocked at 24 MHz.
605  *
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.
609  */
610 void jtag_clock_tms(uint8_t count, uint8_t sequence)
611 {
612         uint8_t outb_buffer = OUTB & ~(PIN_TCK);
613         uint8_t i;
614
615         for (i = 0; i < count; i++) {
616                 /* Set TMS pin according to sequence parameter */
617                 if (sequence & 0x1)
618                         outb_buffer |= PIN_TMS;
619                 else
620                         outb_buffer &= ~PIN_TMS;
621
622                 OUTB = outb_buffer;
623                 sequence = sequence >> 1;
624                 OUTB = outb_buffer | PIN_TCK;
625         }
626 }
627
628 /**
629  * Perform TAP-FSM state transitions at less than maximum TCK frequency.
630  *
631  * Maximum achievable TCK frequency is 117 kHz for ULINK clocked at 24 MHz.
632  *
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.
636  */
637 void jtag_slow_clock_tms(uint8_t count, uint8_t sequence)
638 {
639         uint8_t outb_buffer = OUTB & ~(PIN_TCK);
640         uint8_t i, j;
641
642         for (i = 0; i < count; i++) {
643                 /* Set TMS pin according to sequence parameter */
644                 if (sequence & 0x1)
645                         outb_buffer |= PIN_TMS;
646                 else
647                         outb_buffer &= ~PIN_TMS;
648
649                 OUTB = outb_buffer;
650                 for (j = 0; j < delay_tms; j++)
651                         ;
652                 sequence = sequence >> 1;
653                 OUTB = outb_buffer | PIN_TCK;
654                 for (j = 0; j < delay_tms; j++)
655                         ;
656         }
657 }
658
659 /**
660  * Get current JTAG signal states.
661  *
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.
665  */
666 uint16_t jtag_get_signals(void)
667 {
668         uint8_t input_signal_state, output_signal_state;
669
670         input_signal_state = 0;
671         output_signal_state = 0;
672
673         /* Get states of input pins */
674         if (GET_TDO())
675                 input_signal_state |= SIGNAL_TDO;
676         if (GET_BRKOUT())
677                 input_signal_state |= SIGNAL_BRKOUT;
678         if (GET_TRAP())
679                 input_signal_state |= SIGNAL_TRAP;
680         if (GET_RTCK()) {
681                 /* Using RTCK this way would be extremely slow,
682                  * implemented only for the sake of completeness */
683                 input_signal_state |= SIGNAL_RTCK;
684         }
685
686         /* Get states of output pins */
687         output_signal_state = PINSB & MASK_PORTB_DIRECTION_OUT;
688
689         return ((uint16_t)input_signal_state << 8) | ((uint16_t)output_signal_state);
690 }
691
692 /**
693  * Set state of JTAG output signals.
694  *
695  * @param low signals which should be de-asserted.
696  * @param high signals which should be asserted.
697  */
698 void jtag_set_signals(uint8_t low, uint8_t high)
699 {
700         OUTB &= ~(low & MASK_PORTB_DIRECTION_OUT);
701         OUTB |= (high & MASK_PORTB_DIRECTION_OUT);
702 }
703
704 /**
705  * Configure TCK delay parameters.
706  *
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.
712  */
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)
715 {
716         delay_scan_in = scan_in;
717         delay_scan_out = scan_out;
718         delay_scan_io = scan_io;
719         delay_tck = tck;
720         delay_tms = tms;
721 }