Empty files for STM32F407 support.
[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         led_toggle();
78         CLRRST;
79         led_toggle();
80 }
81
82 //! Clock the JTAG clock line
83 void jtag_tcktock() 
84 {
85         CLRTCK; 
86         led_toggle();
87         SETTCK; 
88         led_toggle();
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         //This is needed for 20-bit MSP430 chips.
330         //Might break another 20-bit chip, if one exists.
331         if(bitcount==20){
332           word = ((word << 16) | (word >> 4)) & 0x000FFFFF;
333         }
334         
335         RESTORETCLK;
336
337         if (!(flags & NOEND))
338         {
339                 // exit state
340                 jtag_tcktock();
341
342                 jtag_state <<= 3; // Update-DR or Update-IR
343
344                 // update state
345                 if (!(flags & NORETIDLE))
346                 {
347                         CLRTMS;
348                         jtag_tcktock();
349
350                         jtag_state = RUN_TEST_IDLE;
351                 }
352         }
353
354         return word;
355 }
356
357 //! Detects the width of the IR register
358 uint16_t jtag_detect_ir_width()
359 {
360         int i;
361         uint16_t width = 0;
362
363         if (!in_run_test_idle())
364         {
365                 debugstr("Not in run-test-idle state");
366                 return 0;
367         }
368
369         // get to shift-ir state
370         jtag_capture_ir();
371         jtag_shift_register();
372
373         // first we shift in 1024 zeros
374         CLRMOSI;
375         for(i = 0; i < 1024; i++)
376         {
377                 jtag_tcktock();
378         }
379
380         // now we'll clock in ones until we see one
381         SETMOSI;
382         for(i = 0; i < 1024; i++)
383         {
384                 jtag_tcktock();
385                 if(READMISO)
386                         break;
387                 width++;
388         }
389
390         // now get back to run-test-idle
391         jtag_run_test_idle();
392
393         return width;
394 }
395
396 //! Detects how many TAPs are in the JTAG chain
397 uint16_t jtag_detect_chain_length()
398 {
399         int i;
400         int bit;
401         uint16_t length = 0;
402
403         if (!in_run_test_idle())
404         {
405                 debugstr("detect chain length must start from run-test-idle");
406                 return 0;
407         }
408
409         // The standard JTAG instruction for "bypass" mode is to set all 1's in the
410         // instruction register.  When in "bypass" mode, the DR acts like a 1-bit
411         // shift regiser.  So we can use that to detect how many TAPs are in the 
412         // chain.
413         
414         // first get into shift IR mode
415         jtag_capture_ir();
416         jtag_shift_register();
417
418         // then we flood the IR chain with all 1's to put all device's DRs
419         // into bypass mode
420         CLRTMS;
421         SETMOSI;
422         for (i = 0; i < 1024; i++)
423         {
424                 if (i == 1023)
425                         SETTMS; // exit on last bit
426                 jtag_tcktock();
427         }
428         jtag_state = EXIT1_IR;
429
430         // go to Update-IR
431         CLRMOSI;
432         jtag_tcktock();
433         jtag_state = UPDATE_IR;
434
435         // go to Shift-DR state
436         jtag_capture_dr();
437         jtag_shift_register();
438
439         // flush the DR's with zeros
440         CLRTMS;
441         CLRMOSI;
442         for (i = 0; i < 1024; i++)
443         {
444                 jtag_tcktock();
445         }
446
447         // send 1's into the DRs until we see one come out the other side
448         SETMOSI;
449         for (i = 0; i < 1024; i++)
450         {
451                 jtag_tcktock();
452                 bit = READMISO;
453                 if (bit)
454                         break;
455                 length++;
456         }
457
458         // now get back to run-test-idle
459         jtag_run_test_idle();
460
461         return length;
462 }
463
464 //! Gets device ID for specified chip in the chain
465 uint32_t jtag_get_device_id(int chip)
466 {
467         int i;
468         uint16_t chain_length;
469         uint32_t id = 0;
470
471         // reset everything
472         jtag_reset_tap();
473
474         // figure out how many devices are in the chain
475         chain_length = jtag_detect_chain_length();
476
477         if (chip >= chain_length)
478         {
479                 debugstr("invalid part index");
480                 return 0;
481         }
482
483         // reset everything again because going through test-logic-reset forces
484         // all IR's to have their manufacturer specific instruction for IDCODE
485         // and loads the DR's with the chip's ID code.
486         jtag_reset_tap();
487
488         // get into shift DR state
489         jtag_capture_dr();
490         jtag_shift_register();
491
492         // read out the 32-bit ID codes for each device
493         CLRTMS;
494         CLRMOSI;
495         for (i = 0; i < (chip + 1); i++)
496         {
497                 id = jtag_trans_n(0xFFFFFFFF, 32, LSB | NOEND | NORETIDLE);
498         }
499
500         jtag_run_test_idle();
501
502         return id;
503 }
504
505 //! Shift 8 bits in/out of selected register
506 uint8_t jtag_trans_8(uint8_t in)
507 {
508         uint32_t out = jtag_trans_n((uint32_t)in, 8, MSB);
509         return (uint8_t)(0x000000FF & out);
510 }
511
512 //! Shift 16 bits in/out of selected register
513 uint16_t jtag_trans_16(uint16_t in)
514 {
515         uint32_t out = jtag_trans_n((uint32_t)in, 16, MSB);
516         return (uint16_t)(0x0000FFFF & out);
517 }
518
519 //! Shift 8 bits of the IR.
520 uint8_t jtag_ir_shift_8(uint8_t in)
521 {
522   /* Huseby's code, which breaks MSP430 support.
523      The code is broken because either the invalid jtag state error
524      causes the client to give up, or because it adds an extra clock edge.
525      
526         if (!in_run_test_idle())
527         {
528                 debugstr("Not in run-test-idle state");
529                 return 0;
530         }
531
532         // get intot the right state
533         jtag_capture_ir();
534         jtag_shift_register();
535   */
536   
537   
538   
539   // idle
540   SETTMS;
541   jtag_tcktock();
542   // select DR
543   jtag_tcktock();
544   // select IR
545   CLRTMS;
546   jtag_tcktock();
547   // capture IR
548   jtag_tcktock();
549   //jtag_state = CAPTURE_IR;
550   jtag_state = SHIFT_IR;
551   // shift IR bits
552   return jtag_trans_8(in);
553 }
554
555 //! Shift 16 bits of the DR.
556 uint16_t jtag_dr_shift_16(uint16_t in)
557 {
558
559         if (!in_run_test_idle())
560         {
561                 debugstr("Not in run-test-idle state");
562                 return 0;
563         }
564
565         // get intot the right state
566         jtag_capture_dr();
567         jtag_shift_register();
568
569         // shift DR, then idle
570         return jtag_trans_16(in);
571 }
572
573 //! Handles a monitor command.
574 void jtag_handle_fn(uint8_t const app,
575                                         uint8_t const verb,
576                                         uint32_t const len)
577 {
578         switch(verb)
579         {
580         // START handled by specific JTAG
581         case STOP:
582                 jtag_stop();
583                 txdata(app,verb,0);
584                 break;
585
586         case SETUP:
587                 jtag_setup();
588                 txdata(app,verb,0);
589                 break;
590
591         case JTAG_IR_SHIFT:
592                 cmddata[0] = jtag_ir_shift_8(cmddata[0]);
593                 txdata(app,verb,1);
594                 break;
595
596         case JTAG_DR_SHIFT:
597                 cmddataword[0] = htons(jtag_dr_shift_16(ntohs(cmddataword[0])));
598                 txdata(app,verb,2);
599                 break;
600
601         case JTAG_RESET_TAP:
602                 jtag_reset_tap();
603                 txdata(app,verb,0);
604                 break;
605
606         case JTAG_RESET_TARGET:
607                 jtag_reset_tap();
608                 jtag_reset_target();
609                 txdata(app,verb,0);
610                 break;
611
612         case JTAG_DETECT_IR_WIDTH:
613                 jtag_reset_tap();
614                 cmddataword[0] = htons(jtag_detect_ir_width());
615                 txdata(app,verb,2);
616                 break;
617
618         case JTAG_DETECT_CHAIN_LENGTH:
619                 jtag_reset_tap();
620                 cmddataword[0] = htons(jtag_detect_chain_length());
621                 txdata(app,verb,2);
622                 break;
623
624         case JTAG_GET_DEVICE_ID:
625                 jtag_reset_tap();
626                 cmddatalong[0] = htonl(jtag_get_device_id(ntohs(cmddataword[0])));
627                 txdata(app,verb,4);
628                 break;
629
630         default:
631                 txdata(app,NOK,0);
632         }
633 }
634
635