#!/usr/bin/perl -w

use strict;


system "clear";
print "\nOASE REPLACEMENT BOARD - EEPROM SETTINGS/VALUES\n===============================================\n";


# Read out file into buffer.

my @Lines = ("");
open(OUTDAT, "<out") || die "out could not be opened!\n";

while(<OUTDAT>)
{
   push(@Lines, $_);
}
close(OUTDAT);

#
# Loop through the lines, 
# search for the lines containing the desired EEPROM content.
#

my $line;
my @Values;
my $AllHigh = 1;


for(@Lines)
{

  # Expected line format is;  0x9 0xf0f0 0x9e 1  -- wrong data, expected 0x0\n

  if($_ =~ "0x9 0xf0f*")
  {
   
   	$line = $_; 
   	
	my @lineparts = split(/ /, $line);
	my $addr = hex(substr($lineparts[1], 4, 2)) - 0xf0;
	my $val = hex($lineparts[2]);
	
	if ($addr >= 0)
	{
	
		$Values[$addr] = $val;
		# print "Line: $line -> Addr=$addr, val=$val\n";
	
		if ($val != 255)
		{
			$AllHigh = 0;
		}
	}
	
   }
  }
  
# Now all data are available,
# thus evaluate all relevant data and display.

if ($AllHigh == 1)
{
	print "\n*************************************************************\n";
	print "* ALL VALUES ARE 0xFF, PROBABLY THE EEPROM IS UNPROGRAMMED! *\n";
	print "*************************************************************\n\n";
}

#
# Global Settings
#


print "SYS_CONFIG\n";

my $APC = (($Values[0] & 0b00001000) > 0);
print pack("A34", "Automatic Power Control Enable: ");
if ($APC > 0) 
{
  print "ON  -> Automatic Power Control Mode activated\n";
}
else
{
  print "OFF -> Constant Current Control Mode activated\n";
}

if (($Values[2] & 0b10000000) > 0)
{
	print "Laser Power Controller:           ON  -> SRC_DAC and MOD-DAC servo controlled\n";
}
else
{
	print "Laser Power Controller:           OFF -> SRC_DAC and MOD-DAC controlled externally\n";
}

print pack("A34", "Current Mode Logic Enable:");

if (($Values[0] & 0b10000000) > 0) 
{
  print "ON  -> CML compatible input";
}
else
{
  print "OFF -> Floating Differential Input Termination";
}
print "\n";

if (($Values[3] & 0b10) > 0)
{
	print "Rapid Restart:                    ON  -> Controller settings are retained\n";
}
else
{
	print "Rapid Restart:                    OFF -> Controller settings are cleared\n";
}


#
# Current related
#

my $Im_nom = $Values[8] | (($Values[9] & 0b11) << 8);
my $Im_rng = ($Values[9] & 0b1100) >> 2;
my $Is_rng = ($Values[5] & 0b1100) >> 2;
my $Imd_rng = ($Values[13] & 0b1100) >> 2;
my $Peaking = ($Values[15] & 0b11111);

print "\nCURRENTS\n";

if ($Is_rng == 0)
{
	print "Source Current Range        = 0   -> Source Current Limited to 9mA\n";
}
elsif  ($Is_rng == 1)
{
	print "Source Current Range        = 1   -> Source Current Limited to 18mA\n";
}
elsif  ($Is_rng == 2)
{
	print "Source Current Range        = 2   -> Source Current Limited to 27mA\n";
}
else
{
	print "Source Current Range        = 3   -> Source Current Limited to 36mA\n";
}

if ($Im_rng == 0)
{
	print "Modulation Current Range    = 0   -> Modulation Current Limited to 4.5mA\n";
}
elsif  ($Im_rng == 1)
{
	print "Modulation Current Range    = 1   -> Modulation Current Limited to 9mA\n";	
}
elsif  ($Im_rng == 2)
{
	print "Modulation Current Range    = 2   -> Modulation Current Limited to 13.5mA\n";	
}
else
{
	print "Modulation Current Range    = 3   -> Modulation Current Limited to 18mA\n";	
}

print "Modulation Current at T_nom = $Im_nom\n";

if ($Imd_rng == 0)
{
	print "Monitor Diode Current Range = 0   -> Monitor Diode Current between 4.25 and 34 ľA \n";
}
elsif  ($Imd_rng == 1)
{
	print "Monitor Diode Current Range = 1   -> Monitor Diode Current between 17 and 136 ľA\n";	
}
elsif  ($Imd_rng == 2)
{
	print "Monitor Diode Current Range = 2   -> Monitor Diode Current between 68 and 544 ľA\n";	
}
else
{
	print "Monitor Diode Current Range = 3   -> Monitor Diode Current between 272 and 2176 ľA\n";	
}

print "Peaking                     = $Peaking\n";

#
# Temperature related
#

print "\nTEMPERATURE COMPENSATION\n";
my $Tnom = ((($Values[13] & 3) <<  8) | $Values[12]) / 2 - 273;
my $Tnom_raw = ((($Values[13] & 3) <<  8) | $Values[12]);


if (($Values[0] & 0b100000) > 0)
{
	print "Using external temperature source.\n";
}
else
{
	print "Using internal temperature sensor.\n";
}

print "T_nom = $Tnom °C  ($Tnom_raw)\n";

print "Modulation Current:    TC1 = $Values[10], TC2 = $Values[11] -> ";
if (($Values[11] > 0) & (($Values[10] > 0)))
{
print "Im = Im_nom * (1 + $Values[11] * 2^-18 * (T - $Tnom°C)^2 + $Values[10] * 2^-13 * (T - $Tnom°C))\n";
}
elsif (($Values[11] == 0) & (($Values[10] > 0)))
{
print "Im = Im_nom * (1 + $Values[10] * 2^-13 * (T - $Tnom°C))\n";
}
elsif (($Values[11] > 0) & (($Values[10] == 0)))
{
print "Im = Im_nom * (1 + $Values[11] * 2^-18 * (T - $Tnom°C)^2)\n";
}
else
{
print "Im = Im_nom\n";
}

if ($APC > 0)
{
	# APC mode activated -> Monitor diode current is in at addresses 6 and 7.

	print "Monitor Diode Current: TC1 = $Values[6], TC2 = $Values[7] -> ";
	if (($Values[7] > 0) & (($Values[6] > 0)))

	{
		print "Imd = Imd_nom * (1 + $Values[7] * 2^-18 * (T - $Tnom°C)^2 + $Values[6] * 2^-13 * (T - $Tnom°C))\n";
	}
	elsif (($Values[7] == 0) & (($Values[6] > 0)))
	{
		print "Imd = Imd_nom * (1 + $Values[6] * 2^-13 * (T - $Tnom°C))\n";
	}
	elsif (($Values[7] > 0) & (($Values[6] == 0)))
	{
		print "Imd = Imd_nom * (1 + $Values[7] * 2^-18 * (T - $Tnom°C)^2)\n";
	}
	else
	{
		print "Imd = Imd_nom\n";
	}
}
else
{
	# Constant Current mode activated -> Constant Base Current is at adresses 6 and 7.

	print "Base Current: TC1 = $Values[6], TC2 = $Values[7] -> ";
	if (($Values[7] > 0) & (($Values[6] > 0)))

	{
		print "Ib = Ib_nom * (1 + $Values[7] * 2^-18 * (T - $Tnom°C)^2 + $Values[6] * 2^-13 * (T - $Tnom°C))\n";
	}
	elsif (($Values[7] == 0) & (($Values[6] > 0)))
	{
		print "Ib = Ib_nom * (1 + $Values[6] * 2^-13 * (T - $Tnom°C))\n";
	}
	elsif (($Values[7] > 0) & (($Values[6] == 0)))
	{
		print "Ib = Ib_nom * (1 + $Values[7] * 2^-18 * (T - $Tnom°C)^2)\n";
	}
	else
	{
		print "Ib = Ib_nom\n";
	}
}

#
#  APC Controller related.
#

my $APC_gain = (($Values[14] & 0b11111000) >> 3);
my $Im_gain = ($Values[14] & 0b111);
print "\nAPC CONTROLLER\n";

if ($APC > 0) 
{
  print "APC Controller          = ON\n";
}
else
{
  print "APC Controller          = OFF\n";
}

print "APC Gain                = $APC_gain\n";	
print "Modulation Current Gain = $Im_gain\n";	


#
#  FAULT register values.
#

print "\nFAULT RELATED\n";

if (($Values[2] & 0b100000) > 0)
{
	print "Fault Pin Polarity     = ON  -> Logic High signals an error\n";
}
else
{
	print "Fault Pin Polarity     = OFF -> Logic Low signals an error\n";
}

if (($Values[2] & 0b1000000) > 0)
{
	print "Fault Auto Shutdown    = ON  -> Transmitter disable on fault\n";
}
else
{
	print "Fault Auto Shutdown    = OFF -> Transmitter NOT disabled on fault\n";
}

if (($Values[3] & 0b100) > 0)
{
	print "Repeated Fault Inhibit = ON  -> Only one attempt to clear fault allowed\n";
}
else
{
	print "Repeated Fault Inhibit = OFF -> Repeated attempts to clear fault allowed\n";
}


if (($Values[2] & 0b100) > 0)
{
	print "Laser Overpower enable = ON  -> Laser overpower detection enabled\n";
}
else
{
	print "Laser Overpower enable = OFF -> Laser overpower detection disabled\n";
}

if (($Values[2] & 0b10) > 0)
{
	print "Laser Underpower en.   = ON  -> Laser underpower detection enabled\n";
}
else
{
	print "Laser Underpower en.   = OFF -> Laser under	power detection disabled\n";
}

if (($Values[2] & 0b1) > 0)
{
	print "Laser Overcurrent en.  = ON  -> Laser overcurrent detection enabled\n";
}
else
{
	print "Laser Overcurrent en.  = OFF -> Laser overcurrent detection disabled\n";
}

if (($Values[2] & 0b10000) > 0)
{
	print "Fault Pin Override     = ON  -> Fault Pin is inactive, to be externally controlled\n";
}
else
{
	print "Fault Pin Override     = OFF -> Fault Pin is driven active\n";
}

if (($Values[2] & 0b10000) > 0)
{
	if (($Values[2] & 0b1000) > 0)
	{
		print "Force Fault Pin Output = ON  -> Force the fault pin active\n";
	}	
	else
	{
		print "Force Fault Pin Output = OFF -> Force the fault pin inactive\n";
	}
}

my $Flt_drv_mode = $Values[3] & 0b11;
if ($Flt_drv_mode == 0)
{
	print "Fault Drive Mode       = 0   -> Open Drain, 3.3mA sink capability\n";
}
elsif ($Flt_drv_mode == 1)
{
	print "Fault Drive Mode       = 1   -> Open Drain, 280ľA internal pullup\n";
}
elsif ($Flt_drv_mode == 2)
{
	print "Fault Drive Mode       = 2   -> Open Drain, 425ľA internal pullup\n";
}
else
{
	print "Fault Drive Mode       = 3   -> Push-Pull, 3.3mA source and sink capability\n";
}


print "\nOTHER SETTINGS\n";

if (($Values[0] & 0b10) > 0)
{
	print "Soft Enable            = ON  -> Transmitter enable depends on EN Pin\n";
}
else
{
	print "Soft Enable            = OFF -> Transmitter disabled\n";
}

if (($Values[0] & 0b100) > 0)
{
	print "Enable Pin Polarity    = ON  -> Logic High enables Transmitter\n";
}
else
{
	print "Enable Pin Polarity    = OFF -> Logic Low enables Transmitter\n";
}


if (($Values[0] & 0b1) > 0)
{
	print "Operating Mode         = ON  -> Externally Controlled\n";
}
else
{
	print "Operating Mode         = OFF -> Standalone Operation (EEPROM based)\n";
}

if (($Values[0] & 0b10000) > 0)
{
	print "Powerdown Enable       = ON  -> Turn off amplifiers when transmitter disabled\n";
}
else
{
	print "Powerdown Enable       = OFF -> No Power reduction when transmitter is disabled\n";
}

if (($Values[0] & 0b1000000) > 0)
{
	print "Monitor Diode Polarity = ON  -> Anode connected to MD pin\n";
}
else
{
	print "Monitor Diode Polarity = OFF -> Cathode connected to MD pin\n";
}




# Print out raw data.

print "\n-- Raw data ----------------------\n";
print "\nADDR   VALUE\n";
my $counter;
for($counter=0 ; $counter < 16 ; $counter++)
{
	print sprintf ("0x%.2X   %.8bb  (0x%.2X, %.3Dd)\n",  $counter, $Values[$counter], $Values[$counter], $Values[$counter]);
}


print "\n";
