X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=openocd-jtag-boundary-scan.pl;h=93b183413d52558a82c5af2c4975f3f787cfb380;hb=a4d95211f6a271eb8192734e65d64d132adb5231;hp=bd7518b0103d5940505fd6bd32709e9d9ef1442e;hpb=aaf00534f4e1c3d8ebaa02e48ac8b94d5f919ec8;p=x300-pci diff --git a/openocd-jtag-boundary-scan.pl b/openocd-jtag-boundary-scan.pl index bd7518b..93b1834 100755 --- a/openocd-jtag-boundary-scan.pl +++ b/openocd-jtag-boundary-scan.pl @@ -12,7 +12,6 @@ my $bsdl_file = $ENV{BSDL} || 'EP4CE6E22.bsd'; # '_3128at100.bsd'; # '3064at44.bsd'; # XXX -my $tap = $ENV{TAP} || 'tb276.tap'; my $project_file = 'Altera/epm3064_dac/3064at44.qsf'; $project_file = 'tb276/f32c.qsf'; @@ -28,11 +27,15 @@ my $parse_in = 0; my $parse_regex = join('|', qw( PIN_MAP_STRING INSTRUCTION_OPCODE + INSTRUCTION_LENGTH + IDCODE_REGISTER )); $|=1; # flush stdout -require 'gpio.pl'; +my $have_gpio = `which gpio`; +warn "# ", ! $have_gpio ? "DOESN'T " : '', "have rpi gpio\n"; +require 'gpio.pl' if $have_gpio; open(my $bsdl, '<', $bsdl_file); while(<$bsdl>) { @@ -41,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+)/ ) { @@ -65,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); @@ -114,7 +122,7 @@ foreach my $pin_file ( glob "pins/$entity*.tsv" ) { chomp; my ($pin,$desc, $bcm) = split(/\t+/,$_,3); $pin_desc->{$pin} = $desc; - gpio::add_bcm_desc( $bcm => $desc ); + gpio::add_bcm_desc( $bcm => $desc ) if $have_gpio; } close($fh); warn "# $pin_file ",dump($pin_desc); @@ -125,11 +133,12 @@ foreach my $pin_file ( glob "pins/$entity*.tsv" ) { while(<$fh>) { chomp; s/[\r\n]+$//; + next if m/^\s*#/; my ($set,$pin, $op, $desc) = split(/\s+/,$_,4); 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); @@ -157,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; @@ -184,9 +194,12 @@ sub print_io { } } - printf "%-3d %-3d %-5s %3s %-8s | ", $pin, $o, $io, $bits, $desc; + $desc = ' ' . $desc if length($desc) < 10; + $desc = substr($desc,0,10); + + printf "%-3d %-3d %-5s %3s%-10s| ", $pin, $o, $io, $bits, $desc; } else { - printf "%-3d ... %-18s | ", $pin, $io, '', ''; + printf "%-3d ... %-18s | ", $pin, $io; } } print "\n"; @@ -210,20 +223,19 @@ 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)); } -#my $cmd; - +my $tap; +print $sock "jtag names\n"; # will fill-in $tap variable from openocd my $BSR; -# first sample -print $sock "irscan $tap $opcode->{SAMPLE}\n"; # SAMPLE/PRELOAD -print $sock "drscan $tap $BOUNDARY_LENGTH 0\n"; +my $scan_chain; while(1) { @@ -231,38 +243,68 @@ 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(); + gpio::pins() if $have_gpio; last; + } 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; $new =~ s/(...)/$1 /g; my @o = split(/ /, $old); my @n = split(/ /, $new); - foreach my $i ( 0 .. $#o ) { + my $bsr_max_bit = $BOUNDARY_LENGTH / 3 - 1; + foreach my $i ( 0 .. $bsr_max_bit ) { if ( $o[$i] eq $n[$i] ) { $o[$i]='.'; } else { - my $pin = $bit2pin->{ $BOUNDARY_LENGTH - ($i * 3) - 3 }->[0]; + my $pin = $bit2pin->{ $i * 3 }->[0]; $o[$i] = " $pin@" . ( $i * 3 ) . ":" . $o[$i] . '>' . $n[$i]; } } - my $diff = join('', @o); + my $diff = join('', @o[ 0 .. $bsr_max_bit ]); print "# diff_bits $diff\n"; } -print "[press enter]\n"; +print "> "; my $cmd = ; chomp $cmd; if ( $cmd =~ /(p|o)(\d+)=(\d+)/ ) { @@ -311,7 +353,7 @@ warn "XXX",length($old_bsr), " == ",length($b); print $sock "irscan $tap $opcode->{SAMPLE}\n"; # SAMPLE/PRELOAD print $sock "drscan $tap $BOUNDARY_LENGTH 0\n"; } else { - gpio::cmd( $cmd ); + gpio::cmd( $cmd ) if $have_gpio; print $sock "irscan $tap $opcode->{SAMPLE}\n"; # SAMPLE/PRELOAD print $sock "drscan $tap $BOUNDARY_LENGTH 0\n"; }