1 /* JTAG routines
2
3 Copyright (C) 2004 Andrew Rogers
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, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
18
19 #include "config.h"
20
21 #include "jtag.h"
22 #include <unistd.h>
23 #include <stdio.h>
24
25 #ifdef WINDOWS
26 #include <windows.h>
27 #define usleep(x) Sleep((x+999)/1000)
28 #endif
29
Jtag(IOBase * iob)30 Jtag::Jtag(IOBase *iob)
31 {
32 io=iob;
33 postDRState=IOBase::RUN_TEST_IDLE;
34 postIRState=IOBase::RUN_TEST_IDLE;
35 deviceIndex=-1;
36 shiftDRincomplete=false;
37 }
38
getChain()39 int Jtag::getChain()
40 {
41 io->tapTestLogicReset();
42 io->setTapState(IOBase::SHIFT_DR);
43 byte idx[4];
44 byte zero[4];
45 numDevices=0;
46 for(int i=0; i<4; i++)zero[i]=0;
47 do{
48 io->shiftTDITDO(zero,idx,32,false);
49 unsigned long id=byteArrayToLong(idx);
50 if(id!=0 && id !=0xffffffff){
51 numDevices++;
52 chainParam_t dev;
53 dev.idcode=id;
54 devices.insert(devices.begin(),dev);
55 }
56 else{
57 if (id == 0xffffffff && numDevices >0)
58 {
59 fprintf(stderr,"You probably have a broken Atmel device in your chain!\n");
60 fprintf(stderr,"No succeeding device can be identified\n");
61 }
62 break;
63 }
64 }while(numDevices<MAXNUMDEVICES);
65 io->setTapState(IOBase::TEST_LOGIC_RESET);
66 return numDevices;
67 }
68
selectDevice(int dev)69 int Jtag::selectDevice(int dev)
70 {
71 if(dev>=numDevices)deviceIndex=-1;
72 else deviceIndex=dev;
73 return deviceIndex;
74 }
75
Usleep(unsigned int usec)76 void Jtag::Usleep(unsigned int usec)
77 {
78 io->flush_tms();
79 io->flush();
80 usleep(usec);
81 }
82
setDeviceIRLength(int dev,int len)83 int Jtag::setDeviceIRLength(int dev, int len)
84 {
85 if(dev>=numDevices||dev<0)return -1;
86 devices[dev].irlen=len;
87 return dev;
88 }
89
shiftDR(const byte * tdi,byte * tdo,int length,int align,bool exit)90 void Jtag::shiftDR(const byte *tdi, byte *tdo, int length, int align, bool exit)
91 {
92 if(deviceIndex<0)return;
93 int post=deviceIndex;
94 if(!shiftDRincomplete){
95 int pre=numDevices-deviceIndex-1;
96 if(align){
97 pre=-post;
98 while(pre<=0)pre+=align;
99 }
100 /* We can combine the pre bits to reach the target device with
101 the TMS bits to reach the SHIFT-DR state, as the pre bit can be '0'*/
102 io->setTapState(IOBase::SHIFT_DR,pre);
103 }
104 if(tdi!=0&&tdo!=0)io->shiftTDITDO(tdi,tdo,length,post==0&&exit);
105 else if(tdi!=0&&tdo==0)io->shiftTDI(tdi,length,post==0&&exit);
106 else if(tdi==0&&tdo!=0)io->shiftTDO(tdo,length,post==0&&exit);
107 else io->shift(false,length,post==0&&exit);
108 if(exit){
109 io->shift(false,post);
110 io->setTapState(postDRState);
111 shiftDRincomplete=false;
112 }
113 else shiftDRincomplete=true;
114 }
115
shiftIR(const byte * tdi,byte * tdo)116 void Jtag::shiftIR(const byte *tdi, byte *tdo)
117 {
118 int dev;
119
120 if(deviceIndex<0)return;
121 io->setTapState(IOBase::SHIFT_IR);
122 int pre=0;
123 for(dev=deviceIndex+1; dev<numDevices; dev++)pre+=devices[dev].irlen; // Calculate number of pre BYPASS bits.
124 int post=0;
125 for(dev=0; dev<deviceIndex; dev++)post+=devices[dev].irlen; // Calculate number of post BYPASS bits.
126 io->shift(true,pre,false);
127 if(tdo!=0)io->shiftTDITDO(tdi,tdo,devices[deviceIndex].irlen,post==0);
128 else if(tdo==0)io->shiftTDI(tdi,devices[deviceIndex].irlen,post==0);
129 io->shift(true,post);
130 io->setTapState(postIRState);
131 }
132