#!/usr/bin/perl -w

# Builds hex "SPI" files from logic analyser listings
#
# Author: Emil
# Last modified: 11 August 2004

use Compress::Zlib;

$progname = $0;
$progname =~ s+^.*/++;
$usage  = "\nUsage: $progname text_file(s)\n";

#push @ARGV, "bel-normal-start2.txt";
die $usage if( $#ARGV < 0 );

while( @ARGV )
{
  my $tmp = shift;
  SW:
  {
    die "Error ($tmp)\n\n$usage" if( $tmp =~ /^-/ );
    push( @tfl, $tmp );
  }
}

foreach $txtfile( @tfl )
{
  printf( "Reading file $txtfile ...\n" );
  if( $txtfile =~ /\.gz$/ )
  {
    $tgz = 1;
    $gz = gzopen( $txtfile, "rb" ) or die "Cannot open $txtfile: $gzerrno\n";
  }
  else
  {
    $tgz = 0;
    open( IFILE, "$txtfile" ) || die "open $txtfile - $!\n";
  }
  $txtfile = $1 if( $txtfile =~ /(.*)\.txt(\.gz)?/ );

	$clk = 0, $lnnr = 0;
	$oc = 0;
	$dac = 0;
	$mem = $memcmd = 0;
	$ocs = $cs = 3;
	$mo = $mi = 0;
	$led = "";
	$nr = 0;
  if( $tgz )
  {
    while( $gz->gzreadline( $ln ) > 0 )
    {
      &process_line();
			$nr++;
    }
    die "Error reading from $txtfile: $gzerrno\n" if $gzerrno != Z_STREAM_END;
    $gz->gzclose();
  }
  else
  {
    while( $ln = <IFILE> )
    {
      &process_line();
			$nr++;
    }
    close( IFILE ) || die "close $txtfile $!\n";
  }
  $lnnr++;
  printf( "%d transactions\n", $lnnr );

  $binfile = $txtfile . ".spi";
  open( WRFILE, "> $binfile" ) || die "open file - $!\n";
  for( $i = 0; $i < $lnnr; $i++ )
  { print( WRFILE "$desc[$i]\n" ); delete $desc[$i]; }
  close( WRFILE );
}
exit;

sub process_line
{
  # Timestamp    CSF SPSCK MOSI MISO RSTF RSTP CSAD
  if( $ln =~ /^.*s\s+(\d)(\d)(\d)(\d)(\d)(\d)(\d)/ )
  {
		$clk = 0, $lnnr = 0, return if( $5 == 0 || $6 == 0 );
		$cs = $1 * 2 + $7;
		$dac = $mem = $clk = $mo = $mi = 0, if( $ocs > $cs );
		if( $oc == 0 && $2 == 1 )
		{
			if( $memcmd == 0x52 && $mem == 8 )
			{
				$memcmd = 0;
			}
			else
			{
		  	$mo <<= 1;
		  	$mo |= $3;
		  	$mi <<= 1;
		  	$mi |= $4;
		  	$clk++;
		  }
		}
		if( $oc == 1 && $2 == 0 && $clk == 8 )
		{
			if( $cs == 1 )
			{
				$memcmd = $mo if( $mem == 0 );
				$mem++;
			}
			else
			{
				$mem = 0;
			}
			$desc[$lnnr++] = sprintf( "MEM %02x %02x", $mo , $mi ) if( $cs == 1 );
			if( $cs == 2 )
			{
				$dac ^= 1;
				if( $dac & 1 )
				{
				   $dacreg = $mo;
				}
				else
				{ 
			     $desc[$lnnr++] = sprintf( "DAC %2d %02x", $dacreg + 1, $mo );
				}
		  }
			$led .= sprintf( "%02x ", $mo ) if( $cs == 3 );
			$desc[$lnnr++] = sprintf( "LED $led" ), $led = "" if( $led ne "" && $cs != 3 );
			$clk = $mo = $mi = 0;
		}
		$oc = $2;
		$ocs = $cs;
  }
  return;
}
# end
