File Coverage

blib/lib/Device/Jtag/USB/FTCJTAG.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package Device::Jtag::USB::FTCJTAG;
2            
3             #use 5.008008;
4 1     1   45278 use strict;
  1         2  
  1         34  
5 1     1   4 use warnings;
  1         2  
  1         108  
6            
7             require Exporter;
8            
9             our @ISA = qw(Exporter);
10            
11             # Items to export into callers namespace by default. Note: do not export
12             # names by default without a very good reason. Use EXPORT_OK instead.
13             # Do not simply export all your public functions/methods/constants.
14            
15             # This allows declaration use Device::Jtag::USB::FTCJTAG ':all';
16             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
17             # will save memory.
18             our %EXPORT_TAGS = ( 'all' => [ qw(
19            
20             ) ] );
21            
22             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
23            
24             our @EXPORT = qw(
25            
26             );
27            
28             our $VERSION = '0.12';
29            
30            
31             # Preloaded methods go here.
32            
33 1     1   366 use Win32::API 0.46;
  0            
  0            
34             use Bit::Vector 6.4;
35            
36             ###################################################################################################
37             # Set debug verbosity level
38             ###################################################################################################
39             my $DEBUG = 1;
40            
41             ###################################################################################################
42             # Define FTC_STATUS return values
43             ###################################################################################################
44             my $ftc_status_type_aref;
45             $ftc_status_type_aref->[ 0] = 'FTC_SUCCESS';
46             $ftc_status_type_aref->[ 1] = 'FTC_INVALID_HANDLE';
47             $ftc_status_type_aref->[ 2] = 'FTC_DEVICE_NOT_FOUND';
48             $ftc_status_type_aref->[ 3] = 'FTC_DEVICE_NOT_OPENED';
49             $ftc_status_type_aref->[ 4] = 'FTC_IO_ERROR';
50             $ftc_status_type_aref->[ 5] = 'FTC_INSUFFICIENT_RESOURCES';
51             $ftc_status_type_aref->[20] = 'FTC_FAILED_TO_COMPLETE_COMMAND';
52             $ftc_status_type_aref->[21] = 'FTC_FAILED_TO_SYCHRONIZE_DEVICE_MPSSE';
53             $ftc_status_type_aref->[22] = 'FTC_INVALID_DEVICE_NAME_INDEX';
54             $ftc_status_type_aref->[23] = 'FTC_NULL_DEVICE_NAME_BUFFER_POINTER';
55             $ftc_status_type_aref->[24] = 'FTC_DEVICE_NAME_BUFFER_TOO_SMALL';
56             $ftc_status_type_aref->[25] = 'FTC_INVALID_DEVICE_NAME';
57             $ftc_status_type_aref->[26] = 'FTC_INVALID_LOCATION_ID';
58             $ftc_status_type_aref->[27] = 'FTC_DEVICE_IN_USE';
59             $ftc_status_type_aref->[28] = 'FTC_TOO_MANY_DEVICES';
60             $ftc_status_type_aref->[29] = 'FTC_INVALID_FREQUENCY_VALUE';
61             $ftc_status_type_aref->[30] = 'FTC_NULL_INPUT_OUTPUT_BUFFER_POINTER';
62             $ftc_status_type_aref->[31] = 'FTC_INVALID_NUMBER_BITS';
63             $ftc_status_type_aref->[32] = 'FTC_NULL_WRITE_DATA_BUFFER_POINTER';
64             $ftc_status_type_aref->[33] = 'FTC_INVALID_NUMBER_BYTES';
65             $ftc_status_type_aref->[34] = 'FTC_NUMBER_BYTES_TOO_SMALL';
66             $ftc_status_type_aref->[35] = 'FTC_INVALID_TAP_CONTROLLER_STATE';
67             $ftc_status_type_aref->[36] = 'FTC_NULL_READ_DATA_BUFFER_POINTER';
68             $ftc_status_type_aref->[37] = 'FTC_NULL_DLL_VERSION_BUFFER_POINTER';
69             $ftc_status_type_aref->[38] = 'FTC_DLL_VERSION_BUFFER_TOO_SMALL';
70             $ftc_status_type_aref->[39] = 'FTC_NULL_LANGUAGE_CODE_BUFFER_POINTER';
71             $ftc_status_type_aref->[40] = 'FTC_NULL_ERROR_MESSAGE_BUFFER_POINTER';
72             $ftc_status_type_aref->[41] = 'FTC_ERROR_MESSAGE_BUFFER_TOO_SMALL';
73             $ftc_status_type_aref->[42] = 'FTC_INVALID_LANGUAGE_CODE';
74             $ftc_status_type_aref->[43] = 'FTC_INVALID_STATUS_CODE';
75            
76             ###################################################################################################
77             # Define JTAG TAP controller states
78             ###################################################################################################
79             use constant TEST_LOGIC_STATE => 1;
80             use constant RUN_TEST_IDLE_STATE => 2;
81             use constant PAUSE_TEST_DATA_REGISTER_STATE => 3;
82             use constant PAUSE_INSTRUCTION_REGISTER_STATE => 4;
83             use constant SHIFT_TEST_DATA_REGISTER_STATE => 5;
84             use constant SHIFT_INSTRUCTION_REGISTER_STATE => 6;
85            
86             ###################################################################################################
87             # Define FTDI chip buffer size (64k bits)
88             ###################################################################################################
89             my $ftdi_buffer_size = 65535;
90            
91             ###################################################################################################
92             # Define Instruction Register vs Data Register constants
93             ###################################################################################################
94             use constant IRSHIFT => 1;
95             use constant DRSHIFT => 0;
96            
97             ###################################################################################################
98             # Construct the new object
99             ##################################################################################################
100             sub new {
101             my $self = {};
102            
103             debug('new', 1, "Debug level set to $DEBUG");
104            
105             # Import API functions and assign to function handles
106             debug('new', 1, "Importing APIs");
107             foreach my $href (
108             {perl_name => 'get_ndev', c_name => 'JTAG_GetNumDevices' , inputs => 'P' , outputs => 'N'},
109             {perl_name => 'open' , c_name => 'JTAG_Open' , inputs => 'P' , outputs => 'N'},
110             {perl_name => 'init' , c_name => 'JTAG_InitDevice' , inputs => 'NN' , outputs => 'N'},
111             {perl_name => 'write' , c_name => 'JTAG_Write' , inputs => 'NNNPNN', outputs => 'N'},
112             {perl_name => 'read' , c_name => 'JTAG_Read' , inputs => 'NNNPPN', outputs => 'N'},
113             {perl_name => 'gen_clks', c_name => 'JTAG_GenerateClockPulses', inputs => 'NN' , outputs => 'N'},
114             {perl_name => 'get_gpio', c_name => 'JTAG_GetGPIOs' , inputs => 'NNPNP' , outputs => 'N'},
115             {perl_name => 'set_gpio', c_name => 'JTAG_SetGPIOs' , inputs => 'NNPNP' , outputs => 'N'}) {
116            
117             $self->{fh}->{$href->{perl_name}} = Win32::API->new('FTCJTAG', $href->{c_name}, $href->{inputs}, $href->{outputs});
118             die(debug('new', 0, sprintf("Unable to import API %s: %s", $href->{c_name}, $!))) if(not defined $self->{fh}->{$href->{perl_name}});
119             }
120            
121            
122             # Open JTAG key
123             debug('new', 1, "Opening JTAGKey");
124             my $ftc_handle_lw = ' 'x4; # pre-allocate 4 bytes to long word
125             my $ftc_status = $self->{fh}->{open}->Call($ftc_handle_lw);
126             die(debug('new', 0, sprintf("Unable to open JTAGKey : %s", $ftc_status_type_aref->[$ftc_status]))) if ($ftc_status);
127            
128             # Assign JTAGKey device handle
129             $self->{key} = unpack('L', $ftc_handle_lw); # unpack long word
130            
131             # Initialize JTAGKey to 6MHz transfer rate
132             debug('new', 1, "Setting JTAGKey transfer rate");
133             $ftc_status = $self->{fh}->{init}->Call($self->{key},0);
134             die(debug('new', 0, sprintf("Unable to initialize JTAGkey : %s", $ftc_status_type_aref->[$ftc_status]))) if ($ftc_status);
135            
136             # Read JTAGKey GPIOs to see that VREF is powered
137             debug('new', 1, "Checking JTAGKey power");
138             my $gpio_lo_lw = ' 'x16; # pre-allocate 4x4 long words
139             my $gpio_hi_lw = ' 'x16; # pre-allocate 4x4 long words
140             $ftc_status = $self->{fh}->{get_gpio}->Call($self->{key}, 1, $gpio_lo_lw, 1, $gpio_hi_lw);
141             die(debug('new', 0, sprintf("Unable to read JTAGkey GPIOs : %s", $ftc_status_type_aref->[$ftc_status]))) if ($ftc_status);
142             my $gpio_lo_aref = [unpack('L4', $gpio_lo_lw)]; # unpack 4 long words into array ref
143             my $gpio_hi_aref = [unpack('L4', $gpio_hi_lw)]; # unpack 4 long words into array ref
144            
145             #foreach $b (0..3) {
146             # printf("GPIOL-%d = %d\n", $b, $gpio_lo_aref->[$b]);
147             #}
148            
149             # Check JTAGKey VREF (GPIO LO bit 1 low if powered)
150             die(debug('new', 0, "JTAGKey VREF not powered")) if ($gpio_lo_aref->[1] eq 1);
151            
152             # Set JTAGKey GPIO controlling output enable
153             debug('new', 1, "Setting JTAGKey output enable");
154             my $gpiol_data = (0,0,0,0,0,0,0,1); # this does not make sense, but happens to work
155             my $gpioh_data = (0,0,0,0,0,0,0,0);
156             $ftc_status = $self->{fh}->{set_gpio}->Call($self->{key}, 1, pack('L8',$gpiol_data), 0, pack('L8',$gpioh_data));
157             die(debug('new', 0, sprintf("[FTCJTAG.PM] Unable to set JTAGkey GPIOs : %s", $ftc_status_type_aref->[$ftc_status]))) if ($ftc_status);
158            
159             # Check JTAGKey output enable (GPIO LO bit 0 low)
160             #die("ERROR: JTAG_OE_N not driven low\n") if ($gpio_lo_aref->[0] eq 0);
161            
162             # Send JTAG devices to TEST LOGIC RESET state
163             init_chain($self);
164            
165             # Autodetect devices on scan chain
166             autodetect($self);
167            
168             bless($self);
169             return $self;
170             }
171            
172             ###########################################################################################################
173             # Initialized scan chain devices to TEST_LOGIC_STATE
174             ###########################################################################################################
175             sub init_chain {
176             my $self = shift;
177            
178             debug('init_chain', 1, "Initializing scan chain");
179            
180             # Perform the USB operation
181             my $data_lw = pack('L', 0);
182             my $ftc_status = $self->{fh}->{write}->Call($self->{key}, IRSHIFT, 2, $data_lw, $ftdi_buffer_size, TEST_LOGIC_STATE);
183            
184             }
185            
186             ###########################################################################################################
187             # Autodetect the IDCODEs of the devices on the chain and assign info
188             ###########################################################################################################
189             sub autodetect {
190             my $self = shift;
191            
192             # Allocate memory
193             my $rbuffer_lw = ' 'x$ftdi_buffer_size; # allocate memory for read string
194             my $nbytes_lw = ' 'x4; # allocate memory for number of bytes read
195            
196             my $idcode = '';
197             my $dev = 0;
198             my @idcodes = ();
199            
200             debug('autodetect', 1, "Autodetecting devices on scan chain");
201            
202             # Read IDCODEs, up to a max of 10 (this is arbitrary), until all zeroes are received
203             while ($idcode ne '0'x32 and $dev < 10) {
204             # Shift 32 bits through data registers, be sure to end in the PAUSE-DR state. If we return to the RUN-TEST-IDLE state
205             # then each device will reload its IDCODE data register.
206             my $ftc_status = $self->{fh}->{read}->Call($self->{key}, DRSHIFT, 32, $rbuffer_lw, $nbytes_lw, PAUSE_TEST_DATA_REGISTER_STATE);
207            
208             # Check return status
209             die(debug('autodetect', 0, sprintf("Unable to read via JTAGkey : %s", $ftc_status_type_aref->[$ftc_status]))) if ($ftc_status);
210            
211             # Unpack long words into binary string
212             $idcode = sprintf("%032b", unpack('L', $rbuffer_lw));
213            
214             # Add current IDCODE to array of IDCODEs
215             push(@idcodes, $idcode) if $idcode ne '0'x32;
216             debug('autodetect', 2, "Read IDCODE = $idcode");
217            
218             $dev++;
219             }
220            
221             # Assign device information and store in object. The last idcode pushed onto the array is the first one in the chain, which
222             # is defined here as device 0.
223             $dev = 0;
224             while (my $idcode = pop(@idcodes)) {
225             debug('autodetect', 2, sprintf("Looking up device information for IDCODE = %s", $idcode));
226             $self->{di}->[$dev] = idcode_lookup($idcode);
227             debug('autodetect', 1, sprintf("DEVICE %d : %s", $dev, $self->{di}->[$dev]->{name}));
228             $dev++;
229             }
230            
231             return;
232             }
233            
234             ###########################################################################################################
235             # Instruction register write to JTAG scan chain device
236             # Usage: write_dev_ir($self, $devid, $imntr, [$endstate]);
237             # Return: nothing
238             ###########################################################################################################
239             sub write_dev_ir {
240             my $self = shift; # jtagusb object
241             my $href = shift; # href containing parameters
242            
243             my $dev = $href->{dev}; # integer scan chain position of device to write, beginning with 0
244             my $imn = $href->{imn}; # string containing instruction mnemonic to write to selected device
245             my $end = $href->{end}; # optional state to leave device in
246            
247             # Find number of devices in scan chain
248             my $nscdevs = scalar(@{$self->{di}});
249            
250             # Construct full binary string to be shifted by padding the non-selected device data with the BYPASS command
251             my $data = '';
252             foreach my $d (0..$nscdevs-1) {
253             # All devices on the chain other than the selected device get the BYPASS instruction
254             my $imn_tmp = ($d eq $dev)? $imn : 'bypass';
255            
256             # Flag an error if the binary equivalent of the instruction isn't defined
257             if (not defined $self->{di}->[$d]->{ircmds}->{$imn_tmp}) {
258             die(debug('write_dev_ir', 0, "Instruction $imn_tmp not defined for scan chain device $d"));
259             }
260             # Get binary equivalent of instruction and add it to the binary string of write data
261             my $i0b = $self->{di}->[$d]->{ircmds}->{$imn_tmp};
262             $data .= $i0b;
263             debug('write_dev_ir', 2, sprintf("Writing %s (0b%s) to device %d", uc($imn_tmp), $i0b, $d));
264             }
265            
266             # Form Bit::Vector object containing binary string
267             my $vec = Bit::Vector->new_Bin(length($data), $data);
268            
269             # Call write_dev subroutine
270             write_dev($self,
271             {vec => $vec,
272             typ => IRSHIFT,
273             end => $end});
274            
275             return;
276            
277             }
278            
279             ###########################################################################################################
280             # Data register write to JTAG scan chain device
281             # Usage: write_dev_dr($self, $deviceid, $vec, [$end]);
282             # Return: nothing
283             ###########################################################################################################
284             sub write_dev_dr {
285             my $self = shift; # jtagusb object
286             my $href = shift; # href containing parameters
287            
288             my $dev = $href->{dev}; # integer scan chain position of device to write, beginning with 0
289             my $vec = $href->{vec}; # Bit::Vector object containing data to be written to device
290             my $end = $href->{end}; # optional state to leave device in
291            
292             # Pad the data with 0's on the left, depending upon the desired device's position in the scan chain
293             # All devices in the scan chain -- other than the one that we're interested in -- are assumed to
294             # be in the BYPASS state, representing a single flip flop in the chain. So, if there are any devices
295             # in the chain before the one we're writing to (this would be represented by the $dev of the device
296             # we're writing to being nonzero), then pad the end of the write string with a 0 for each device in
297             # the chain preceeding the one we're writing to.
298             my $pad_vec = Bit::Vector->new_Bin($dev, 0)->Concat($vec); # pad vector with additional 0's on the left
299            
300             # Write to device
301             write_dev($self,
302             {vec => $pad_vec,
303             typ => DRSHIFT,
304             end => $end});
305            
306             return;
307             }
308            
309             ###########################################################################################################
310             # Write to JTAG device
311             # Usage: write_dev($self, $deviceid, $vector, $type (IRSHIFT or DRSHIFT), [$endstate]);
312             # Return: nothing
313             ###########################################################################################################
314             sub write_dev {
315             my $self = shift; # jtagusb object
316             my $href = shift; # href containing parameters
317            
318             my $vec = $href->{vec}; # Bit::Vector object containing data to be written to device
319             my $typ = $href->{typ}; # shift type: IRSHIFT or DRSHIFT
320             my $end = $href->{end}; # optional state to leave device in
321            
322             # Trap unspecified endstate
323             if (not $end) {
324             $end = RUN_TEST_IDLE_STATE;
325             }
326            
327             # Convert Data::Vector object to binary string
328             my $data = $vec->to_Bin();
329            
330             # Determine number of bits to shift
331             my $nbits = length($data);
332            
333             debug('write_dev', 2, sprintf("Performing %s of 0b$data ($nbits bits)", $typ eq IRSHIFT? 'IRSHIFT' : 'DRSHIFT'));
334            
335             # Convert data to integer array @words, must be done 32 bits at a time
336             my $nlw = int((length($data)-1)/32) + 1;
337             my @words;
338            
339             debug('write_dev', 2, "Packing $nlw words");
340             for my $i (1..$nlw) {
341             my $datalen = length($data);
342             debug('write_dev', 2, sprintf("Data: %s (Length %s)", $data, $datalen));
343             my $offset = ($datalen > 32)? -32 : 0;
344             my $length = ($datalen > 32)? 32 : $datalen;
345             my $word = substr($data,$offset,$length); # get rightmost 32 bits
346             debug('write_dev', 2, sprintf("Long Word $i (%d,%d): %s", $offset,$length, $word));
347             substr($data,$offset,$length) = '';
348             push(@words, oct('0b'.$word));
349             }
350            
351             # pack integer data
352             my $data_lw = pack('L'x$nlw, @words);
353            
354             # Perform the USB operation
355             my $ftc_status = $self->{fh}->{write}->Call($self->{key}, $typ, $nbits, $data_lw, $ftdi_buffer_size, $end);
356            
357             # Check return status
358             die(debug('write_dev', 0, "Unable to write")) if ($ftc_status);
359            
360             return;
361             }
362            
363             ###########################################################################################################
364             # Read from data register of specified JTAG scan chain device
365             # Usage: read_dev($self, $devid, $nbits, [$endstate]);
366             # Return: Bit::Vector containing data read from selected device
367             ###########################################################################################################
368             sub read_dev_dr {
369             my $self = shift; # jtagusb object
370             my $href = shift; # href containing parameters
371            
372             my $dev = $href->{dev}; # integer scan chain position of device to read, beginning with 0
373             my $nbits = $href->{nbits}; # number of bits to read
374             my $end = $href->{end}; # optional state to leave device in
375            
376             my $rbuffer_lw = ' 'x$ftdi_buffer_size; # allocate memory for read string
377             my $nbytes_lw = ' 'x4; # allocate memory for number of bytes read
378            
379             # Trap unspecified endstate
380             if (not $end) {
381             $end = RUN_TEST_IDLE_STATE;
382             }
383            
384             # The first bit of data we want is sitting on TDO of the selected device. If there are any devices in
385             # the chain after the selected device, the data we want must get through those subsequent devices.
386             # If this is a DRSHIFT, we assume each non-selected device has been given the BYPASS command, thus each
387             # non-selected device will place the 1-bit BYPASS register on the chain. This means that if there are
388             # N devices in the chain after the selected device, and the number of bits of data being shifted is M,
389             # the total number of shifts must be 1*N+M. Finally, the first N bits of data received on TDO should be
390             # discarded.
391             my $nbits_extra = scalar(@{$self->{di}}) - ($dev+1); # Num devices on the scan chain after the selected device
392            
393             debug('read_dev', 2, sprintf("Reading %d bits from device %d", $nbits, $dev));
394             debug('read_dev', 2, sprintf("Reading %d extra bits from device %d", $nbits_extra, $dev));
395            
396             # Perform the USB operation
397             my $ftc_status = $self->{fh}->{read}->Call($self->{key}, DRSHIFT, $nbits + $nbits_extra, $rbuffer_lw, $nbytes_lw, $end);
398            
399             # Check return status
400             die(debug('read_dev', 0, sprintf("Unable to read via JTAGkey : %s", $ftc_status_type_aref->[$ftc_status]))) if ($ftc_status);
401            
402             # Calculate the number of long words to convert (each long word is 32 bytes)
403             my $nlw = int(($nbits+$nbits_extra-1)/32) + 1;
404            
405             debug('read_dev', 2, "Converting $nlw long words");
406            
407             # Unpack long words into binary string
408             my $rdata_bstr = '';
409             foreach my $d (unpack('L'x$nlw, $rbuffer_lw)) {
410             $rdata_bstr = sprintf("%032b",$d) . $rdata_bstr;
411             }
412             debug('read_dev', 2, sprintf("Binary read data: %s", $rdata_bstr));
413            
414             my $vector = Bit::Vector->new_Bin($nbits, substr($rdata_bstr, -1*($nbits+$nbits_extra), $nbits));
415             return($vector);
416            
417             }
418            
419             ###########################################################################################################
420             # IDCODE LOOKUP
421             # This information is lifted from Xilinx BSDL files
422             ###########################################################################################################
423             sub idcode_lookup {
424             my $idcode0b = shift;
425            
426             my $bsdl_info_href;
427            
428             $bsdl_info_href->{'....0001010000011100000010010011'} = {name => 'XC3S400_FT256',
429             ircmds => {extest => '000000', #
430             sample => '000001', #
431             user1 => '000010', # -- Not available until after configuration
432             user2 => '000011', # -- Not available until after configuration
433             cfg_out => '000100', # -- Not available during configuration with another mode.
434             cfg_in => '000101', # -- Not available during configuration with another mode.
435             intest => '000111', #
436             usercode => '001000', #
437             idcode => '001001', #
438             highz => '001010', #
439             jprogram => '001011', # -- Not available during configuration with another mode.
440             jstart => '001100', # -- Not available during configuration with another mode.
441             jshutdown => '001101', # -- Not available during configuration with another mode.
442             bypass => '111111' #
443             }};
444            
445             $bsdl_info_href->{'....0001010000101000000010010011'} = {name => 'XC3S1000_FT256',
446             ircmds => {extest => '000000', #
447             sample => '000001', #
448             user1 => '000010', # -- Not available until after configuration
449             user2 => '000011', # -- Not available until after configuration
450             cfg_out => '000100', # -- Not available during configuration with another mode.
451             cfg_in => '000101', # -- Not available during configuration with another mode.
452             intest => '000111', #
453             usercode => '001000', #
454             idcode => '001001', #
455             highz => '001010', #
456             jprogram => '001011', # -- Not available during configuration with another mode.
457             jstart => '001100', # -- Not available during configuration with another mode.
458             jshutdown => '001101', # -- Not available during configuration with another mode.
459             bypass => '111111' #
460             }};
461            
462             $bsdl_info_href->{'....0101000001000110000010010011'} = {name => 'XCF04S_VO20',
463             ircmds => {bypass => '11111111',
464             sample => '00000001',
465             preload => '00000001',
466             extest => '00000000',
467             idcode => '11111110',
468             usercode => '11111101',
469             highz => '11111100',
470             clamp => '11111010',
471             config => '11101110'}};
472            
473             $bsdl_info_href->{'....0001110000100010000010010011'} = {name => 'XC3S500E_FT256',
474             ircmds => {extest => '001111', #
475             sample => '000001', #
476             preload => '000001', # Not available until after configuration
477             user1 => '000010', # Not available until after configuration
478             user2 => '000011', # Not available during configuration with another mode.
479             cfg_out => '000100', # Not available during configuration with another mode.
480             cfg_in => '000101', #
481             intest => '000111', #
482             usercode => '001000', #
483             idcode => '001001', #
484             highz => '001010', # Not available during configuration with another mode.
485             jprogram => '001011', # Not available during configuration with another mode.
486             jstart => '001100', # Not available during configuration with another mode.
487             jshutdown => '001101', #
488             bypass => '111111', #
489             isc_enable => '010000', #
490             isc_program => '010001', #
491             isc_noop => '010100', #
492             isc_read => '010101',
493             isc_disable => '010110'}};
494            
495            
496             $bsdl_info_href->{'....0001110000101110000010010011'} = {name => 'XC3S1200E_FT256',
497             ircmds => {EXTEST => '001111', #
498             SAMPLE => '000001', #
499             PRELOAD => '000001', # Not available until after configuration
500             USER1 => '000010', # Not available until after configuration
501             USER2 => '000011', # Not available during configuration with another mode.
502             CFG_OUT => '000100', # Not available during configuration with another mode.
503             CFG_IN => '000101', #
504             INTEST => '000111', #
505             USERCODE => '001000', #
506             IDCODE => '001001', #
507             HIGHZ => '001010', # Not available during configuration with another mode.
508             JPROGRAM => '001011', # Not available during configuration with another mode.
509             JSTART => '001100', # Not available during configuration with another mode.
510             JSHUTDOWN => '001101', #
511             BYPASS => '111111', #
512             ISC_ENABLE => '010000', #
513             ISC_PROGRAM => '010001', #
514             ISC_NOOP => '010100', #
515             ISC_READ => '010101',
516             ISC_DISABLE => '010110'}};
517            
518             foreach my $key (keys %$bsdl_info_href) {
519             if ($idcode0b =~ m/$key/) {
520             return $bsdl_info_href->{$key};
521             }
522             }
523             die(debug('idcode_lookup', 0, "No IDCODE match for $idcode0b found"));
524             }
525            
526             ###########################################################################################################
527             # PRINT DEBUGGING INFORMATION
528             ###########################################################################################################
529             sub debug {
530             my $sub = shift;
531             my $print_level = shift;
532             my $message = shift;
533            
534             if ($DEBUG >= $print_level) {
535             printf("[%s][%-12.12s] %s\n", 'FTCJTAG', uc($sub), $message);
536             }
537             }
538             1;
539             __END__