X-Git-Url: http://git.rot13.org/?p=x300-pci;a=blobdiff_plain;f=openocd-jtag-boundary-scan.pl;h=76c16ed8329257982d739921c8b504b117fd848b;hp=2a3d9ebce5c40a56ea48e9104ca4fa5902bcda6a;hb=HEAD;hpb=a1d2bf03abed7d4e058c6686be393a67dc21a9fa diff --git a/openocd-jtag-boundary-scan.pl b/openocd-jtag-boundary-scan.pl index 2a3d9eb..76c16ed 100755 --- a/openocd-jtag-boundary-scan.pl +++ b/openocd-jtag-boundary-scan.pl @@ -9,11 +9,11 @@ use Storable; my $openocd_remote = shift @ARGV || 'picam:4444'; my $bsdl_file = $ENV{BSDL} || - 'EP4CE6E22.bsd'; -# '_3128at100.bsd'; -# '3064at44.bsd'; # XXX + 'x300-dongle/3064at44.bsd'; # XXX +#$bsdl_file = 'EP4CE6E22.bsd'; +#$bsdl_file = '_3128at100.bsd'; my $project_file = 'Altera/epm3064_dac/3064at44.qsf'; -$project_file = 'tb276/f32c.qsf'; +#$project_file = 'tb276/f32c.qsf'; my $BOUNDARY_LENGTH = -1; my $entity; @@ -27,6 +27,8 @@ my $parse_in = 0; my $parse_regex = join('|', qw( PIN_MAP_STRING INSTRUCTION_OPCODE + INSTRUCTION_LENGTH + IDCODE_REGISTER )); $|=1; # flush stdout @@ -42,6 +44,7 @@ while(<$bsdl>) { $parse->{$1} .= $_; } elsif ( $parse_in ) { next if m/^\s*--/; + s/\s+--.+$//; # remove comments and EOL $parse->{$parse_in} .= $_; $parse_in = 0 if m/;/; } elsif ( m/"(\d+)\s+\(BC_\d+,\s+(\S+),\s+(\S+)/ ) { @@ -66,6 +69,10 @@ foreach my $chunk ( keys %$parse ) { $parse->{$chunk} =~ s/^.+?"//s; # strip upto first quote $parse->{$chunk} =~ s/"\s*;.*?$//s; # strip everything after closing $parse->{$chunk} =~ s/\s+/ /gs; + $parse->{$chunk} =~ s/^\s+//; + $parse->{$chunk} =~ s/\s+$//; + $parse->{$chunk} =~ s/attribute\s+$chunk\s+of\s+$entity\s+:\s+entity\s+is\s+(\d+)\s*;/$1/; + } warn "# parse = ",dump($parse); @@ -131,7 +138,7 @@ foreach my $pin_file ( glob "pins/$entity*.tsv" ) { if ( $set =~ m/set_location_assignment/i && $op =~ m/-to/i && $pin =~ s/^PIN_//ig ) { $pin_desc->{$pin} = $desc; # overwrite pin description } else { - warn "# ignored $_\n"; + #warn "## ignored $_\n"; } } close($fh); @@ -159,6 +166,7 @@ sub bits { my $last_bits = ''; sub print_io { my $bits = shift; + return unless length($bits) == $BOUNDARY_LENGTH; my $o_bits = $bits; $bits = reverse $bits; # make substr work as expected my $last_bits_r = reverse $last_bits; @@ -215,6 +223,7 @@ sub hex2bin { sub bin2hex { my $b = shift; + $b =~ s/\s+//g; my $blen = length($b); my $hlen = $blen / 4; return unpack("H$hlen", pack("B$blen", $b)); @@ -226,35 +235,56 @@ print $sock "jtag names\n"; # will fill-in $tap variable from openocd my $BSR; +my $scan_chain; + while(1) { while (<$sock>) { warn "<< ",dump($_); chomp; s/[\r\x00]+//g; - if ( /^\s*([A-F0-9]+)/ ) { + if ( ! $tap && m/^(\w+\.tap)$/ ) { + $tap = $1; + warn "# using TAP $tap\n"; + + print $sock "scan_chain\n"; + $scan_chain = 0; + + } elsif ( ! $scan_chain && m/\d+\s+$tap\s+Y\s+0x([0-9a-f]+)\s+0x[0-9a-f]+\s+(\d+)/ ) { + + my ($IdCode,$IrLen) = ( $1, $2 ); + + my $bsdl_id_code = bin2hex( $parse->{IDCODE_REGISTER} ); + die "IdCode != IDCODE_REGISTER $IdCode != $bsdl_id_code" if lc($IdCode) ne lc($bsdl_id_code); + + die "IrLen != INSTRUCTION_LENGTH $IrLen != $parse->{INSTRUCTION_LENGTH}" if $IrLen != $parse->{INSTRUCTION_LENGTH}; + + warn "# OK IdCode $IdCode IrLen $IrLen\n"; + $scan_chain = 1; + + # first sample + print $sock "irscan $tap $opcode->{SAMPLE}\n"; # SAMPLE/PRELOAD + print $sock "drscan $tap $BOUNDARY_LENGTH 0\n"; + + } elsif ( /^\s*([A-F0-9]+)$/ ) { my $hex = $1; my $bin = hex2bin($hex); + $bin = substr($bin,0, $BOUNDARY_LENGTH) if length($bin) > $BOUNDARY_LENGTH; diff_bits($BSR, $bin); $BSR = $bin; print_io $bin if $bin ne $last_bits; gpio::pins() if $have_gpio; last; - } elsif ( m/^(\w+\.tap)$/ && !$tap ) { - $tap = $1; - warn "# using TAP $tap"; - - # first sample - print $sock "irscan $tap $opcode->{SAMPLE}\n"; # SAMPLE/PRELOAD - print $sock "drscan $tap $BOUNDARY_LENGTH 0\n"; - + } elsif ( m/>\s+\S+/ ) { + # ignore command echo } else { - warn "# in ",dump($_); + warn "# ignored ",dump($_); } } sub diff_bits { my ($old, $new) = @_; + return unless $old && $new; $old = reverse $old; # extra bits must be on the end $new = reverse $new; $old =~ s/(...)/$1 /g;