merging...
[goodfet] / firmware / apps / jtag / jtag.c
1 /*! \file jtag.c
2   \author Travis Goodspeed <travis at radiantmachines.com>
3   \brief Low-level JTAG
4 */
5
6
7 #include "platform.h"
8 #include "command.h"
9 #include "jtag.h"
10
11 #define JTAG_APP
12
13 //! Handles a monitor command.
14 void jtag_handle_fn(uint8_t const app,
15                     uint8_t const verb,
16                     uint32_t const len);
17
18 //! JTAG device ID.
19 unsigned char jtagid=0;
20
21 // define the jtag app's app_t
22 app_t const jtag_app = {
23
24         /* app number */
25         JTAG,
26
27         /* handle fn */
28         jtag_handle_fn,
29
30         /* name */
31         "JTAG",
32
33         /* desc */
34         "\tThe JTAG app handles basic JTAG operations such as\n"
35         "\tresetting the TAP, resetting the target, detecting\n"
36         "\tthe instruction register width, shifting bits into\n"
37         "\tboth the instruction and data registers.\n"
38 };
39
40
41 //! Remembers what the current JTAG state is
42 enum eTAPState jtag_state = UNKNOWN;
43
44 //! Returns true if we're in any of the data register states
45 int in_dr()
46 {
47         return (int)(jtag_state & (SELECT_DR_SCAN | CAPTURE_DR |
48                                                            SHIFT_DR | EXIT1_DR | PAUSE_DR |
49                                                            EXIT2_DR | UPDATE_DR));
50 }
51
52 //! Returns true if we're in any of the instruction register states
53 int in_ir()
54 {
55         return (int)(jtag_state & (SELECT_IR_SCAN | CAPTURE_IR |
56                                                            SHIFT_IR | EXIT1_IR | PAUSE_IR |
57                                                            EXIT2_IR | UPDATE_IR));
58 }
59
60 //! Returns true if we're in run-test-idle state
61 int in_run_test_idle()
62 {
63         return (int)(jtag_state & RUN_TEST_IDLE);
64 }
65
66 //! Check the state
67 int in_state(enum eTAPState state)
68 {
69         return (int)(jtag_state & state);
70 }
71
72
73 //! Reset the target device
74 void jtag_reset_target()
75 {
76         SETRST;
77         PLEDOUT^=PLEDPIN; 
78         CLRRST;
79         PLEDOUT^=PLEDPIN; 
80 }
81
82 //! Clock the JTAG clock line
83 void jtag_tcktock() 
84 {
85         CLRTCK; 
86         PLEDOUT^=PLEDPIN; 
87         SETTCK; 
88         PLEDOUT^=PLEDPIN;
89 }
90
91 //! Goes through test-logic-reset and ends in run-test-idle
92 void jtag_reset_tap()
93 {
94         CLRMOSI;
95         SETTMS;
96         jtag_tcktock();
97         jtag_tcktock();
98         jtag_tcktock();
99         jtag_tcktock();
100         jtag_tcktock();  // now in Reset state
101         CLRTMS;
102         jtag_tcktock();  // now in Run-Test/Idle state
103         jtag_state = RUN_TEST_IDLE;
104 }
105
106 //! Set up the pins for JTAG mode.
107 void jtag_setup()
108 {
109         P5DIR|=MOSI+SCK+TMS;
110         P5DIR&=~MISO;
111         P4DIR|=TST;
112         P2DIR|=RST;
113         msdelay(100);
114         jtag_state = UNKNOWN;
115 }
116
117 //! Stop JTAG, release pins
118 void jtag_stop()
119 {
120         P5OUT=0;
121         P4OUT=0;
122 }
123
124 //! Get into Shift-IR or Shift-DR state
125 void jtag_shift_register()
126 {
127         // assumes we're in any state that can transition to Shift-IR or Shift-DR
128         if (!in_state(CAPTURE_DR | CAPTURE_IR | SHIFT_DR | 
129                                   SHIFT_IR | EXIT2_DR | EXIT2_IR ))
130         {
131                 debugstr("Invalid JTAG state");
132                 return;
133         }
134
135         CLRMOSI;
136         CLRTMS;
137         jtag_tcktock();
138
139         if (in_dr())
140                 jtag_state = SHIFT_DR;
141         else
142                 jtag_state = SHIFT_IR;
143 }
144
145 //! Get into Capture-IR state
146 void jtag_capture_ir()
147 {
148         // assumes you're in Run-Test/Idle, Update-DR or Update-IR
149         if (!in_state(RUN_TEST_IDLE | UPDATE_DR | UPDATE_IR))
150         {
151                 debugstr("Invalid JTAG state");
152                 return;
153         }
154
155         CLRMOSI;
156         SETTMS;
157         jtag_tcktock(); // Select-DR-Scan
158         jtag_tcktock(); // Select-IR-Scan
159         CLRTMS;
160         jtag_tcktock(); // Capture-IR
161
162         jtag_state = CAPTURE_IR;
163 }
164
165 //! Get into Capture-DR state
166 void jtag_capture_dr()
167 {
168         // assumes you're in Run-Test/Idle, Update-DR or Update-IR
169         if (!in_state(RUN_TEST_IDLE | UPDATE_DR | UPDATE_IR))
170         {
171                 debugstr("Invalid JTAG state");
172                 return;
173         }
174
175         CLRMOSI;
176         SETTMS;
177         jtag_tcktock(); // Select-DR-Scan
178         CLRTMS;
179         jtag_tcktock(); // Capture-IR
180
181         jtag_state = CAPTURE_DR;
182 }
183
184 //! Gets back to run-test-idle without going through the test-logic-reset
185 void jtag_run_test_idle()
186 {
187         CLRMOSI;
188
189         if (in_state(SELECT_DR_SCAN | SELECT_IR_SCAN))
190         {
191                 CLRTMS;
192                 jtag_tcktock();
193                 jtag_state <<= 1; //CAPTURE_DR or CAPTURE_IR
194         }
195
196         if (in_state(CAPTURE_DR | CAPTURE_IR))
197         {
198                 SETTMS;
199                 jtag_tcktock();
200                 jtag_state <<= 2; //EXIT1_DR or EXIT1_IR
201         }
202
203         if (in_state(SHIFT_DR | SHIFT_IR))
204         {
205                 SETTMS;
206                 jtag_tcktock();
207                 jtag_state <<= 1; //EXIT1_DR or EXIT1_IR
208         }
209
210         if (in_state(EXIT1_DR | EXIT1_IR))
211         {
212                 SETTMS;
213                 jtag_tcktock();
214                 jtag_state <<=3; //UPDATE_DR or UPDATE_IR
215         }
216
217         if (in_state(PAUSE_DR | PAUSE_IR))
218         {
219                 SETTMS;
220                 jtag_tcktock();
221                 jtag_state <<= 1; // EXIT2_DR or EXIT2_IR
222         }
223
224         if (in_state(EXIT2_DR | EXIT2_IR))
225         {
226                 SETTMS;
227                 jtag_tcktock();
228                 jtag_state <<= 1; // UPDATE_DR or UPDATE_IR
229         }
230
231         if (in_state(UPDATE_DR | UPDATE_IR | TEST_LOGIC_RESET))
232         {
233                 CLRTMS;
234                 jtag_tcktock();
235                 jtag_state = RUN_TEST_IDLE;
236         }
237 }
238
239 int savedtclk;
240 //      NOTE: important: THIS MODULE REVOLVES AROUND RETURNING TO RUNTEST/IDLE, OR 
241 //      THE FUNCTIONAL EQUIVALENT
242 //! Shift N bits over TDI/TDO.  May choose LSB or MSB, and select whether to 
243 //      terminate (TMS-high on last bit) and whether to return to RUNTEST/IDLE
244 //              flags should be 0 for most uses.  
245 //              for the extreme case, flags should be  (NOEND|NORETDLE|LSB)
246 //              other edge cases can involve a combination of those three flags
247 //
248 //              the max bit-size that can be be shifted is 32-bits.  
249 //              for longer shifts, use the NOEND flag (which infers NORETIDLE so the 
250 //              additional flag is unnecessary)
251 //
252 //              NORETIDLE is used for special cases where (as with arm) the debug 
253 //              subsystem does not want to return to the RUN-TEST/IDLE state between 
254 //              setting IR and DR
255 uint32_t jtag_trans_n(uint32_t word, 
256                                           uint8_t bitcount, 
257                                           enum eTransFlags flags) 
258 {
259         uint8_t bit;
260         uint32_t high = (1L << (bitcount - 1));
261         uint32_t mask = high - 1;
262
263         if (!in_state(SHIFT_IR | SHIFT_DR))
264         {
265                 debugstr("jtag_trans_n from invalid TAP state");
266                 return 0;
267         }
268
269         SAVETCLK;
270
271         if (flags & LSB) 
272         {
273                 for (bit = bitcount; bit > 0; bit--) 
274                 {
275                         /* write MOSI on trailing edge of previous clock */
276                         if (word & 1)
277                         {
278                                 SETMOSI;
279                         }
280                         else
281                         {
282                                 CLRMOSI;
283                         }
284                         word >>= 1;
285
286                         if ((bit == 1) && !(flags & NOEND))
287                                 SETTMS; //TMS high on last bit to exit.
288
289                         jtag_tcktock();
290
291                         if ((bit == 1) && !(flags & NOEND))
292                                 jtag_state <<= 1; // Exit1-DR or Exit1-IR
293
294                         /* read MISO on trailing edge */
295                         if (READMISO)
296                         {
297                                 word += (high);
298                         }
299                 }
300         } 
301         else 
302         {
303                 for (bit = bitcount; bit > 0; bit--) 
304                 {
305                         /* write MOSI on trailing edge of previous clock */
306                         if (word & high)
307                         {
308                                 SETMOSI;
309                         }
310                         else
311                         {
312                                 CLRMOSI;
313                         }
314                         word = (word & mask) << 1;
315
316                         if ((bit==1) && !(flags & NOEND))
317                                 SETTMS; //TMS high on last bit to exit.
318
319                         jtag_tcktock();
320
321                         if ((bit == 1) && !(flags & NOEND))
322                                 jtag_state <<= 1; // Exit1-DR or Exit1-IR
323
324                         /* read MISO on trailing edge */
325                         word |= (READMISO);
326                 }
327         }
328
329         RESTORETCLK;
330
331         if (!(flags & NOEND))
332         {
333                 // exit state
334                 jtag_tcktock();
335
336                 jtag_state <<= 3; // Update-DR or Update-IR
337
338                 // update state
339                 if (!(flags & NORETIDLE))
340                 {
341                         CLRTMS;
342                         jtag_tcktock();
343
344                         jtag_state = RUN_TEST_IDLE;
345                 }
346         }
347
348         return word;
349 }
350
351 //! Detects the width of the IR register
352 uint16_t jtag_detect_ir_width()
353 {
354         int i;
355         uint16_t width = 0;
356
357         if (!in_run_test_idle())
358         {
359                 debugstr("Not in run-test-idle state");
360                 return 0;
361         }
362
363         // get to shift-ir state
364         jtag_capture_ir();
365         jtag_shift_register();
366
367         // first we shift in 1024 zeros
368         CLRMOSI;
369         for(i = 0; i < 1024; i++)
370         {
371                 jtag_tcktock();
372         }
373
374         // now we'll clock in ones until we see one
375         SETMOSI;
376         for(i = 0; i < 1024; i++)
377         {
378                 jtag_tcktock();
379                 if(READMISO)
380                         break;
381                 width++;
382         }
383
384         // now get back to run-test-idle
385         jtag_run_test_idle();
386
387         return width;
388 }
389
390 //! Detects how many TAPs are in the JTAG chain
391 uint16_t jtag_detect_chain_length()
392 {
393         int i;
394         int bit;
395         uint16_t length = 0;
396
397         if (!in_run_test_idle())
398         {
399                 debugstr("detect chain length must start from run-test-idle");
400                 return 0;
401         }
402
403         // The standard JTAG instruction for "bypass" mode is to set all 1's in the
404         // instruction register.  When in "bypass" mode, the DR acts like a 1-bit
405         // shift regiser.  So we can use that to detect how many TAPs are in the 
406         // chain.
407         
408         // first get into shift IR mode
409         jtag_capture_ir();
410         jtag_shift_register();
411
412         // then we flood the IR chain with all 1's to put all device's DRs
413         // into bypass mode
414         CLRTMS;
415         SETMOSI;
416         for (i = 0; i < 1024; i++)
417         {
418                 if (i == 1023)
419                         SETTMS; // exit on last bit
420                 jtag_tcktock();
421         }
422         jtag_state = EXIT1_IR;
423
424         // go to Update-IR
425         CLRMOSI;
426         jtag_tcktock();
427         jtag_state = UPDATE_IR;
428
429         // go to Shift-DR state
430         jtag_capture_dr();
431         jtag_shift_register();
432
433         // flush the DR's with zeros
434         CLRTMS;
435         CLRMOSI;
436         for (i = 0; i < 1024; i++)
437         {
438                 jtag_tcktock();
439         }
440
441         // send 1's into the DRs until we see one come out the other side
442         SETMOSI;
443         for (i = 0; i < 1024; i++)
444         {
445                 jtag_tcktock();
446                 bit = READMISO;
447                 if (bit)
448                         break;
449                 length++;
450         }
451
452         // now get back to run-test-idle
453         jtag_run_test_idle();
454
455         return length;
456 }
457
458 //! Gets device ID for specified chip in the chain
459 uint32_t jtag_get_device_id(int chip)
460 {
461         int i;
462         uint16_t chain_length;
463         uint32_t id = 0;
464
465         // reset everything
466         jtag_reset_tap();
467
468         // figure out how many devices are in the chain
469         chain_length = jtag_detect_chain_length();
470
471         if (chip >= chain_length)
472         {
473                 debugstr("invalid part index");
474                 return 0;
475         }
476
477         // reset everything again because going through test-logic-reset forces
478         // all IR's to have their manufacturer specific instruction for IDCODE
479         // and loads the DR's with the chip's ID code.
480         jtag_reset_tap();
481
482         // get into shift DR state
483         jtag_capture_dr();
484         jtag_shift_register();
485
486         // read out the 32-bit ID codes for each device
487         CLRTMS;
488         CLRMOSI;
489         for (i = 0; i < (chip + 1); i++)
490         {
491                 id = jtag_trans_n(0xFFFFFFFF, 32, LSB | NOEND | NORETIDLE);
492         }
493
494         jtag_run_test_idle();
495
496         return id;
497 }
498
499 //! Shift 8 bits in/out of selected register
500 uint8_t jtag_trans_8(uint8_t in)
501 {
502         uint32_t out = jtag_trans_n((uint32_t)in, 8, MSB);
503         return (uint8_t)(0x000000FF & out);
504 }
505
506 //! Shift 16 bits in/out of selected register
507 uint16_t jtag_trans_16(uint16_t in)
508 {
509         uint32_t out = jtag_trans_n((uint32_t)in, 16, MSB);
510         return (uint16_t)(0x0000FFFF & out);
511 }
512
513 //! Shift 8 bits of the IR.
514 uint8_t jtag_ir_shift_8(uint8_t in)
515 {
516         if (!in_run_test_idle())
517         {
518                 debugstr("Not in run-test-idle state");
519                 return 0;
520         }
521
522         // get intot the right state
523         jtag_capture_ir();
524         jtag_shift_register();
525
526         // shift IR bits
527         return jtag_trans_8(in);
528 }
529
530 //! Shift 16 bits of the DR.
531 uint16_t jtag_dr_shift_16(uint16_t in)
532 {
533
534         if (!in_run_test_idle())
535         {
536                 debugstr("Not in run-test-idle state");
537                 return 0;
538         }
539
540         // get intot the right state
541         jtag_capture_dr();
542         jtag_shift_register();
543
544         // shift DR, then idle
545         return jtag_trans_16(in);
546 }
547
548 //! Handles a monitor command.
549 void jtag_handle_fn(uint8_t const app,
550                                         uint8_t const verb,
551                                         uint32_t const len)
552 {
553         switch(verb)
554         {
555         // START handled by specific JTAG
556         case STOP:
557                 jtag_stop();
558                 txdata(app,verb,0);
559                 break;
560
561         case SETUP:
562                 jtag_setup();
563                 txdata(app,verb,0);
564                 break;
565
566         case JTAG_IR_SHIFT:
567                 cmddata[0] = jtag_ir_shift_8(cmddata[0]);
568                 txdata(app,verb,1);
569                 break;
570
571         case JTAG_DR_SHIFT:
572                 cmddataword[0] = htons(jtag_dr_shift_16(ntohs(cmddataword[0])));
573                 txdata(app,verb,2);
574                 break;
575
576         case JTAG_RESET_TAP:
577                 jtag_reset_tap();
578                 txdata(app,verb,0);
579                 break;
580
581         case JTAG_RESET_TARGET:
582                 jtag_reset_tap();
583                 jtag_reset_target();
584                 txdata(app,verb,0);
585                 break;
586
587         case JTAG_DETECT_IR_WIDTH:
588                 jtag_reset_tap();
589                 cmddataword[0] = htons(jtag_detect_ir_width());
590                 txdata(app,verb,2);
591                 break;
592
593         case JTAG_DETECT_CHAIN_LENGTH:
594                 jtag_reset_tap();
595                 cmddataword[0] = htons(jtag_detect_chain_length());
596                 txdata(app,verb,2);
597                 break;
598
599         case JTAG_GET_DEVICE_ID:
600                 jtag_reset_tap();
601                 cmddatalong[0] = htonl(jtag_get_device_id(ntohs(cmddataword[0])));
602                 txdata(app,verb,4);
603                 break;
604
605         default:
606                 txdata(app,NOK,0);
607         }
608 }
609
610