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