1 /* JTAG low level functions and base class for cables
2 
3 Copyright (C) 2004 Andrew Rogers
4 Additions (C) 2005-2011  Uwe Bonnes
5                          bon@elektron.ikp.physik.tu-darmstadt.de
6 
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11 
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 
21 Changes:
22 Sandro Amato [sdroamt@netscape.net] 26 Jun 2006 [applied 13 Jul 2006]:
23    Added a 'dotted' progress bar
24 Dmitry Teytelman [dimtey@gmail.com] 14 Jun 2006 [applied 13 Aug 2006]:
25     Code cleanup for clean -Wall compile.
26     Extensive changes to support FT2232 driver.
27     Moved progress bar to ioparport.cpp and ioftdi.cpp.
28 */
29 
30 
31 
32 #include "iobase.h"
33 
34 #include <unistd.h>
35 #include <stdio.h>
36 #include <string.h>
37 
38 using namespace std;
IOBase()39 IOBase::IOBase()
40 {
41     verbose = false;
42     memset( ones,0xff,CHUNK_SIZE);
43     memset(zeros,   0,CHUNK_SIZE);
44     memset(tms_buf,   0,CHUNK_SIZE);
45     tms_len = 0;
46 }
47 
Init(struct cable_t * cable,const char * devopt,unsigned int freq)48 int IOBase::Init(struct cable_t *cable, const char *devopt, unsigned int freq)
49 {
50     return 0;
51 }
52 
flush_tms(int force)53 void IOBase::flush_tms(int force)
54 {
55   if (tms_len)
56     tx_tms(tms_buf, tms_len, force);
57   memset(tms_buf,   0,CHUNK_SIZE);
58   tms_len = 0;
59 }
60 
set_tms(bool val)61 void IOBase::set_tms(bool val)
62 {
63   if( tms_len + 1 > CHUNK_SIZE*8)
64     flush_tms(false);
65   if(val)
66     tms_buf[tms_len/8] |= (1 <<(tms_len &0x7));
67   tms_len++;
68 }
69 
shiftTDITDO(const unsigned char * tdi,unsigned char * tdo,int length,bool last)70 void IOBase::shiftTDITDO(const unsigned char *tdi, unsigned char *tdo,
71 			 int length, bool last)
72 {
73   if(length==0) return;
74   flush_tms(false);
75   txrx_block(tdi, tdo, length,last);
76   return;
77 }
78 
shiftTDI(const unsigned char * tdi,int length,bool last)79 void IOBase::shiftTDI(const unsigned char *tdi, int length, bool last)
80 {
81   shiftTDITDO(tdi, NULL, length,last);
82 }
83 
84 // TDI gets a load of zeros, we just record TDO.
shiftTDO(unsigned char * tdo,int length,bool last)85 void IOBase::shiftTDO(unsigned char *tdo, int length, bool last)
86 {
87     shiftTDITDO(NULL, tdo, length,last);
88 }
89 
90 // TDI gets a load of zeros or ones, and we ignore TDO
shift(bool tdi,int length,bool last)91 void IOBase::shift(bool tdi, int length, bool last)
92 {
93     int len = length;
94     unsigned char *block = (tdi)?ones:zeros;
95     flush_tms(false);
96     while (len > CHUNK_SIZE*8)
97     {
98 	txrx_block(block, NULL, CHUNK_SIZE*8, false);
99 	len -= (CHUNK_SIZE*8);
100     }
101     shiftTDITDO(block, NULL, len, last);
102 }
103 
104 
105