Root/Software/xc3sprog/iobase.cpp

1/* JTAG low level functions and base class for cables
2
3Copyright (C) 2004 Andrew Rogers
4
5This program is free software; you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation; either version 2 of the License, or
8(at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
18
19
20
21#include "iobase.h"
22
23#include <stdio.h>
24
25using namespace std;
26
27IOBase::IOBase()
28{
29  current_state=UNKNOWN;
30}
31
32int IOBase::shiftTDITDO(const unsigned char *tdi, unsigned char *tdo, int length, bool last)
33{
34  if(length==0)return 0;
35  int i=0;
36  int j=0;
37  unsigned char tdo_byte=0;
38  unsigned char tdi_byte=tdi[j];
39  while(i<length-1){
40    tdo_byte=tdo_byte+(txrx(false, (tdi_byte&1)==1)<<(i%8));
41    tdi_byte=tdi_byte>>1;
42    i++;
43    if((i%8)==0){ // Next byte
44      tdo[j]=tdo_byte; // Save the TDO byte
45      tdo_byte=0;
46      j++;
47      tdi_byte=tdi[j]; // Get the next TDI byte
48    }
49  };
50  tdo_byte=tdo_byte+(txrx(last, (tdi_byte&1)==1)<<(i%8)); // TMS set if last=true
51  tdo[j]=tdo_byte;
52  nextTapState(last); // If TMS is set the the state of the tap changes
53}
54
55int IOBase::shiftTDI(const unsigned char *tdi, int length, bool last)
56{
57  if(length==0)return 0;
58  int i=0;
59  int j=0;
60  unsigned char tdi_byte=tdi[j];
61  while(i<length-1){
62    tx(false, (tdi_byte&1)==1);
63    tdi_byte=tdi_byte>>1;
64    i++;
65    if((i%8)==0){ // Next byte
66      j++;
67      tdi_byte=tdi[j]; //Get the next TDI byte
68    }
69  };
70  tx(last, (tdi_byte&1)==1); // TMS set if last=true
71  nextTapState(last); // If TMS is set the the state of the tap changes
72}
73
74// TDI gets a load of zeros, we just record TDO.
75int IOBase::shiftTDO(unsigned char *tdo, int length, bool last)
76{
77  if(length==0)return 0;
78  int i=0;
79  int j=0;
80  unsigned char tdo_byte=0;
81  while(i<length-1){
82    tdo_byte=tdo_byte+(txrx(false, false)<<(i%8));
83    i++;
84    if((i%8)==0){ // Next byte
85      tdo[j]=tdo_byte; // Save the TDO byte
86      tdo_byte=0;
87      j++;
88    }
89  };
90  tdo_byte=tdo_byte+(txrx(last, false)<<(i%8)); // TMS set if last=true
91  tdo[j]=tdo_byte;
92  nextTapState(last); // If TMS is set the the state of the tap changes
93}
94
95// TDI gets a load of zeros or ones, and we ignore TDO
96int IOBase::shift(bool tdi, int length, bool last)
97{
98  if(length==0)return 0;
99  int i=0;
100  while(i<length-1){
101    tx(false, tdi);
102    i++;
103  };
104  tx(last, tdi); // TMS set if last=true
105  nextTapState(last); // If TMS is set the the state of the tap changes
106}
107
108int IOBase::setTapState(tapState_t state)
109{
110  bool tms;
111  while(current_state!=state){
112    switch(current_state){
113
114    case TEST_LOGIC_RESET:
115      switch(state){
116      case TEST_LOGIC_RESET:
117    tms=true;
118    break;
119      default:
120    tms=false;
121    current_state=RUN_TEST_IDLE;
122      };
123      break;
124
125    case RUN_TEST_IDLE:
126      switch(state){
127      case RUN_TEST_IDLE:
128    tms=false;
129    break;
130      default:
131    tms=true;
132    current_state=SELECT_DR_SCAN;
133      };
134      break;
135
136    case SELECT_DR_SCAN:
137      switch(state){
138      case CAPTURE_DR:
139      case SHIFT_DR:
140      case EXIT1_DR:
141      case PAUSE_DR:
142      case EXIT2_DR:
143      case UPDATE_DR:
144    tms=false;
145    current_state=CAPTURE_DR;
146    break;
147      default:
148    tms=true;
149    current_state=SELECT_IR_SCAN;
150      };
151      break;
152
153    case CAPTURE_DR:
154      switch(state){
155      case SHIFT_DR:
156    tms=false;
157    current_state=SHIFT_DR;
158    break;
159      default:
160    tms=true;
161    current_state=EXIT1_DR;
162      };
163      break;
164
165    case SHIFT_DR:
166      switch(state){
167      case SHIFT_DR:
168    tms=false;
169    break;
170      default:
171    tms=true;
172    current_state=EXIT1_DR;
173      };
174      break;
175
176    case EXIT1_DR:
177      switch(state){
178      case PAUSE_DR:
179      case EXIT2_DR:
180      case SHIFT_DR:
181      case EXIT1_DR:
182    tms=false;
183    current_state=PAUSE_DR;
184    break;
185      default:
186    tms=true;
187    current_state=UPDATE_DR;
188      };
189      break;
190
191    case PAUSE_DR:
192      switch(state){
193      case PAUSE_DR:
194    tms=false;
195    break;
196      default:
197    tms=true;
198    current_state=EXIT2_DR;
199      };
200      break;
201
202    case EXIT2_DR:
203      switch(state){
204      case SHIFT_DR:
205      case EXIT1_DR:
206      case PAUSE_DR:
207    tms=false;
208    current_state=SHIFT_DR;
209    break;
210      default:
211    tms=true;
212    current_state=UPDATE_DR;
213      };
214      break;
215
216    case UPDATE_DR:
217      switch(state){
218      case RUN_TEST_IDLE:
219    tms=false;
220    current_state=RUN_TEST_IDLE;
221    break;
222      default:
223    tms=true;
224    current_state=SELECT_DR_SCAN;
225      };
226      break;
227
228    case SELECT_IR_SCAN:
229      switch(state){
230      case CAPTURE_IR:
231      case SHIFT_IR:
232      case EXIT1_IR:
233      case PAUSE_IR:
234      case EXIT2_IR:
235      case UPDATE_IR:
236    tms=false;
237    current_state=CAPTURE_IR;
238    break;
239      default:
240    tms=true;
241    current_state=TEST_LOGIC_RESET;
242      };
243      break;
244
245    case CAPTURE_IR:
246      switch(state){
247      case SHIFT_IR:
248    tms=false;
249    current_state=SHIFT_IR;
250    break;
251      default:
252    tms=true;
253    current_state=EXIT1_IR;
254      };
255      break;
256
257    case SHIFT_IR:
258      switch(state){
259      case SHIFT_IR:
260    tms=false;
261    break;
262      default:
263    tms=true;
264    current_state=EXIT1_IR;
265      };
266      break;
267
268    case EXIT1_IR:
269      switch(state){
270      case PAUSE_IR:
271      case EXIT2_IR:
272      case SHIFT_IR:
273      case EXIT1_IR:
274    tms=false;
275    current_state=PAUSE_IR;
276    break;
277      default:
278    tms=true;
279    current_state=UPDATE_IR;
280      };
281      break;
282
283    case PAUSE_IR:
284      switch(state){
285      case PAUSE_IR:
286    tms=false;
287    break;
288      default:
289    tms=true;
290    current_state=EXIT2_IR;
291      };
292      break;
293
294    case EXIT2_IR:
295      switch(state){
296      case SHIFT_IR:
297      case EXIT1_IR:
298      case PAUSE_IR:
299    tms=false;
300    current_state=SHIFT_IR;
301    break;
302      default:
303    tms=true;
304    current_state=UPDATE_IR;
305      };
306      break;
307
308    case UPDATE_IR:
309      switch(state){
310      case RUN_TEST_IDLE:
311    tms=false;
312    current_state=RUN_TEST_IDLE;
313    break;
314      default:
315    tms=true;
316    current_state=SELECT_DR_SCAN;
317      };
318      break;
319
320    default:
321      tapTestLogicReset();
322      tms=true;
323    };
324    tx(tms,false);
325  };
326}
327
328// After shift data into the DR or IR we goto the next state
329// This function should only be called from the end of a shift function
330int IOBase::nextTapState(bool tms)
331{
332  if(current_state==SHIFT_DR){
333    if(tms)current_state=EXIT1_DR; // If TMS was set then goto next state
334  }
335  else if(current_state==SHIFT_IR){
336    if(tms)current_state=EXIT1_IR; // If TMS was set then goto next state
337  }
338  else tapTestLogicReset(); // We were in an unexpected state
339}
340
341void IOBase::tapTestLogicReset()
342{
343  for(int i=0; i<5; i++)tx(true,false);
344  current_state=TEST_LOGIC_RESET;
345}
346
347void IOBase::cycleTCK(int n, bool tdi)
348{
349  bool tms=false;
350  if(current_state==TEST_LOGIC_RESET)tms=true;
351  for(int i=0; i<n; i++)tx(tms,tdi);
352}
353

Archive Download this file

Branches:
master



interactive