#!/usr/bin/perl -w

use strict;
use Switch;

system "clear";

my ($Sekunden, $Minuten, $Stunden, $Monatstag, $Monat,
    $Jahr, $Wochentag, $Jahrestag, $Sommerzeit) = localtime(time);
$Monat+=1;
$Jahrestag+=1;
$Monat = $Monat < 10 ? $Monat = "0".$Monat : $Monat;
$Monatstag = $Monatstag < 10 ? $Monatstag = "0".$Monatstag : $Monatstag;
$Stunden = $Stunden < 10 ? $Stunden = "0".$Stunden : $Stunden;
$Minuten = $Minuten < 10 ? $Minuten = "0".$Minuten : $Minuten;
$Sekunden = $Sekunden < 10 ? $Sekunden = "0".$Sekunden : $Sekunden;
$Jahr+=1900;    

print "LTC5100 SETTINGS/VALUES";
print sprintf("   %02d.%02d.%04d  %02d:%02d:%02d\n", $Monatstag, $Monat, $Jahr, $Stunden, $Minuten, $Sekunden);
print "==============================================\n\n";
my $TimeTag = sprintf("%02d:%02d:%02d %5d", $Stunden, $Minuten, $Sekunden, $Stunden*3600 + $Minuten*60 + $Sekunden);

#
# Load out file generated with "make ltc_rd" into @Lines string array.
#

my @Lines = ("");
open(INDAT, "<out") || die "out could not be opened!\n";

while(<INDAT>)
{
   push(@Lines, $_);
}
close(INDAT);

#
# Open output file for writing.
#

open(OUTDAT, ">>ltc.log") || die "ltc.log could not be opened for writing.!\n";

#
#  Definition of constants.
#

my $DAT_write       = 0x0A;    # The write command value used in dat files.
my $LTC_I2C_Address = 0x0A;    # The seven higher bits of the I2C address byte.

#
# Initialise LTC data structure.
#

my @LTC_Data;
my @LTC_Data_Valid;

for (my $k = 0; $k < 32; $k++)
{
  $LTC_Data[$k] = -1;
  $LTC_Data_Valid[$k] = -1;
}

#
# Loop through the lines, 
# search for the lines containing the desired EEPROM content.
#

for(my $i = 1; $i < @Lines; $i++)
{

  if($Lines[$i] =~ "0xa 0xf0e0")
  {
  
  	my $line = $Lines[$i];

  	my @lineparts = split(/ /, $line);

	# Select writes (0xa) to 0xf0e0 only.
	if (hex($lineparts[0]) == $DAT_write)
	{
		# Restore the I2C device address, I2C command byte and read/write bit.
		my $I2C_Device = (hex($lineparts[2]) & 0b11111110) >> 1;
		my $I2C_Address = ((hex($lineparts[2]) >> 8) & 0b11111111);
		my $I2C_Read = hex($lineparts[2]) & 0b1;
		
		# Select reads from LTC registers only.
		if (($I2C_Read == 1) & ($I2C_Device == $LTC_I2C_Address))
		{
		
		   # A new sequence of interest starts.
		
		  #print sprintf("Device 0x%02X, address 0x%02X\n", $I2C_Device, $I2C_Address);	
		   
		   my $j = $i+1;
		   my $Value = -1;
		   
		   while( (not ($Lines[$j] =~ "0x9 0xf0f0")) & ($j < @Lines) )
		   {
		   	$j = $j+1;
		   }
		   
		   if (($Lines[$j] =~ "0x9 0xf0f0") & ($j < @Lines))
		   {
		   	# read out lower byte of LTC register value.
			my @parts = split(/ /, $Lines[$j]);
			my $Value = hex($parts[2]);
#			print "Address $I2C_Address, Value $Value\n";
			$LTC_Data[$I2C_Address] = $Value;
#			$LTC_Data_Valid[$I2C_Address] = 1;
			
			$j = $j+1;
		        while( (not ($Lines[$j] =~ "0x9 0xf0f1")) & ($j < @Lines) )
		        {
		            $j = $j+1;
		        }
			if (($Lines[$j] =~ "0x9 0xf0f1") & ($j < @Lines))
			{
			    my @parts = split(/ /, $Lines[$j]);
			    my $ValueHigh = hex($parts[2]);
			    $LTC_Data[$I2C_Address] = ($ValueHigh << 8) + $LTC_Data[$I2C_Address];
			    $LTC_Data_Valid[$I2C_Address] = 1;
			
			}
			else
			{
			    die "Unexpected syntax of out file (2)!\n";
			}
			
			
		   }
		   else
		   {
		   	die "Unexpected syntax of out file!\n";
		   }
		}
	}
   }
}

#
# By now there should be a memory mapping of the LTC registers in $LTC_Data.
#

my $SysCfg_OperationMode = ($LTC_Data[0x10] & 0b1) > 0;
my $SysCfg_SoftEnable = ($LTC_Data[0x10] & 0b10) > 1;

my $MonitorDiodeCurrentRange = ($LTC_Data[0x1D] & 0b110000000000) >> 10;

my $Fault_OverCurrent = ($LTC_Data[0x12] & 0b1) > 0;
my $Fault_UnderPower = ($LTC_Data[0x12] & 0b10) > 1;
my $Fault_OverPower = ($LTC_Data[0x12] & 0b100) > 2;
my $Fault_MemoryLoad = ($LTC_Data[0x12] & 0b1000) > 3;
my $Fault_UnderVoltage = ($LTC_Data[0x12] & 0b10000) > 4;
my $Fault_Faulted = ($LTC_Data[0x12] & 0b100000) > 5;
my $Fault_Faulted_Once = ($LTC_Data[0x12] & 0b1000000) > 6;
my $Fault_Faulted_Twice = ($LTC_Data[0x12] & 0b10000000) > 7;

my $Enable_Pin = ($LTC_Data[0x12] & 0b100000000) > 8;
my $Transmitter_Enable = ($LTC_Data[0x12] & 0b1000000000) > 9;
my $Transmit_Ready = ($LTC_Data[0x12] & 0b10000000000) > 10;

my $DieTemp = $LTC_Data[0x05] * 0.5 - 273;
my $TempNom = ($LTC_Data[0x1D] & 0b1111111111) * 0.5 - 273;
my $TempDev = $DieTemp - $TempNom;


if ($SysCfg_OperationMode > 0)
{
   print "Operation mode:               Microprocessor controlled operation\n"; 
}
else
{
   print "Operation mode:               EEPROM based standalone operation\n";
}
if ($SysCfg_SoftEnable > 0)
{
   print "Soft enable:                  enabled\n"; 
}
else
{
   print "Soft enable:                  DISABLED\n";
}

if ($Enable_Pin > 0)
{
   print "Enable pin is set to:         enabled";
}
else
{
   print "Enable pin is set to:         DISABLED";
}
print "\n";
if ($Transmitter_Enable > 0)
{
   print "Transmitter enable:           enabled";
}
else
{
   print "Transmitter enable:           DISABLED";
}
print "\n";
if ($Transmit_Ready > 0)
{
   print "Transmitter status:           ready";
}
else
{
   print "Transmitter status:           NOT ready";
}
print "\n\n";

print "Fault status:                 ";
if ($Fault_Faulted > 0)
{
   print "Fault flag set, ";
}
if ($Fault_Faulted_Once > 0)
{
   print "faulted once, ";
}
if ($Fault_Faulted_Twice > 0)
{
   print "faulted twice, ";
}

if ($Fault_OverCurrent > 0)
{
   print "Overcurrent";
}
if ($Fault_UnderPower > 0)
{
   print "Underpower";
}
if ($Fault_OverPower > 0)
{
   print "Overpower";
}	
if ($Fault_MemoryLoad > 0)
{
   print "Memory load";
}	
if ($Fault_UnderVoltage > 0)
{
   print "Power supply low";
}	


if (
      ($Fault_OverCurrent == 0)
    & ($Fault_OverPower == 0)
    & ($Fault_UnderPower == 0)
    & ($Fault_MemoryLoad == 0) 
    & ($Fault_UnderVoltage == 0) 
   )
{
   print "no errors";
}
print "\n\n";

if($LTC_Data_Valid[0x05])
{
   if ($TempDev > 0)
   {
      print "Die Temperature:              $DieTemp°C  -> +$TempDev°C\n";	
   }
   else
   {
      print "Die Temperature:              $DieTemp°C  -> $TempDev°C\n";
   }	
}

if($LTC_Data_Valid[0x1D])
{
   print "Nominal Temperature:          $TempNom°C\n";	
}

print "\nADC related\n";
my $ADC_Source = ($LTC_Data[0x18] & 0b111) >> 12;
print "ADC Source:                   $ADC_Source -> ";	

switch($ADC_Source)
{
   case 0b000 { print "Source Pin Current\n"; }
   case 0b001 { print "Avg. Modulation Current\n"; }
   case 0b010 { print "Laser Diode Voltage\n"; }
   case 0b011 { print "Monitor Diode Current\n"; }
   case 0b100 { print "Die Temperature\n"; }
   case 0b101 { print "Term. Resistor Voltage\n"; }
   case 0b110 { print "Reserved!\n"; }      
   case 0b111 { print "Reserved!\n"; }
}


print "\n";
print "Monitor Diode Current Range:  $MonitorDiodeCurrentRange\n";	

print "\nRAW DATA\n";
print "========\n";

for (my $m=0; $m < @LTC_Data; $m++)
{
   if ($LTC_Data_Valid[$m] == 1)
   {
      print sprintf("0x%02X: 0x%04X  (%06dd, %016b)\n", $m, $LTC_Data[$m], $LTC_Data[$m], $LTC_Data[$m]);
   }
}
  
print "\n";

#
# Write the log file.
#

print OUTDAT "$TimeTag  DIETEMP  $DieTemp °C\n";

close(OUTDAT);
