X-Git-Url: http://git.rot13.org/?p=x300-pci;a=blobdiff_plain;f=openocd-jtag-boundary-scan.pl;h=76c16ed8329257982d739921c8b504b117fd848b;hp=c44a386eaf7b65f49a5843c8402cf6d5d88a3ecd;hb=HEAD;hpb=ff8ab03f34e7dbf879e1c04a060613a5f45b663b diff --git a/openocd-jtag-boundary-scan.pl b/openocd-jtag-boundary-scan.pl index c44a386..76c16ed 100755 --- a/openocd-jtag-boundary-scan.pl +++ b/openocd-jtag-boundary-scan.pl @@ -9,12 +9,13 @@ use Storable; my $openocd_remote = shift @ARGV || 'picam:4444'; my $bsdl_file = $ENV{BSDL} || - 'EP4CE6E22.bsd'; -# '_3128at100.bsd'; -# '3064at44.bsd'; # XXX -my $tap = $ENV{TAP} || 'tb276.tap'; + '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'; -my $BOUNDARY_LENGTH = 288; +my $BOUNDARY_LENGTH = -1; my $entity; my $bit2pin; @@ -26,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>) { @@ -39,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+)/ ) { @@ -63,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); @@ -91,12 +101,11 @@ store \$pin2io, $entity . '.pin2io.storable'; my $opcode; my $o = $parse->{INSTRUCTION_OPCODE} || die "no INSTRUCTION_OPCODE in ",dump($parse); -warn "XXX [$o]"; foreach ( split(/\)\s*,\s*/, $o) ) { s/\s+\(/ /g; s/\s*\)\s*$//g; - warn "XXX [$_]\n"; + warn "### [$_]\n"; my ( $inst_opcode, $bin ) = split(/\s+/, $_); $opcode->{$inst_opcode} = sprintf "0x%02x", eval '0b' . $bin; } @@ -113,26 +122,27 @@ 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); } { - my $pin_file = 'Altera/epm3064_dac/3064at44.qsf'; - open(my $fh, '<', $pin_file); + open(my $fh, '<', $project_file); 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); - warn "# $pin_file ",dump($pin_desc); + warn "# $project_file ",dump($pin_desc); } =for remove @@ -156,10 +166,12 @@ 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; - print "pin off io___ ICO prv | " x 4, $openocd_remote,"\n"; + print "pin off io___ ICO | " x 4, $openocd_remote,"\n"; foreach my $i ( 0 .. ($#$pin2io/4)-1 ) { foreach my $j ( 0 .. 3 ) { #my $pin = ($i*4) + $j + 1; # rows @@ -169,7 +181,7 @@ sub print_io { if ( defined $o ) { my $l = $b = substr($bits, $o, 3); - $l = substr($last_bits,$o,3) if $last_bits; + $l = substr($last_bits_r,$o,3) if $last_bits; my $desc = $pin_desc->{$pin} || ''; my $bits = bits($b); @@ -182,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 ... %-5s %3s %-8s | ", $pin, $io, '', ''; + printf "%-3d ... %-18s | ", $pin, $io; } } print "\n"; @@ -208,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) { @@ -229,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+)/ ) { @@ -297,7 +341,7 @@ warn "XXX",length($old_bsr), " == ",length($b); $b = reverse $b; - diff_bits( $BSR, $b ), $/; + diff_bits( $BSR, $b ); # print $sock "irscan $tap $opcode->{SAMPLE}\n"; # SAMPLE/PRELOAD print $sock "drscan $tap $BOUNDARY_LENGTH 0x", bin2hex($b), "\n"; @@ -309,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"; }