From: Maps Date: Thu, 12 Dec 2024 10:47:44 +0000 (+0100) Subject: qa script stuff X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=43dd621679580fa6017d82bb1212d9adfdb6a3f3;p=mimosis_chain.git qa script stuff --- diff --git a/scripts/qa/CONF_scurves.pl b/scripts/qa/CONF_scurves.pl index f7680c7..036e5f0 100644 --- a/scripts/qa/CONF_scurves.pl +++ b/scripts/qa/CONF_scurves.pl @@ -1,51 +1,15 @@ -#read files like my @config = do "CONF_allregisters.pl"; - - #DACs -# [0x0040, 7 ], #IBIAS 0 - 80 nA , 312 pA Pixel current -# [0x0041, 9 ], #ITHR 0 - 2.5 nA , 9.8 pA Pixel current -# [0x0042, 9 ], #IDB 0 - 40 nA , 157 pA Pixel current -# [0x0043, 171 ], #VRESET 0.37 - 1.79 V , 6 mV Pixel input amplifier reset voltage -# [0x0044, 70 ], #VPL 0.37 - 1.79 V , 6 mV Pixel voltage for charge injection (low value) -# [0x0045, 80 ], #VPH 0.37 - 1.79 V , 6 mV Pixel voltage for charge injection (high -# [0x0046, 0 ], #VPH_FINE 0 - 256 mV , 1 mV value) VPH+VPH_FINE -# [0x0047, 67 ], #VCASP 0 - 1.54 V , 6 mV Pixel voltage -# [0x0048, 0 ], #VCASNA 0 - 1.54 V , 6 mV Pixel threshold voltage for submatrix A -# [0x0049, 0 ], #VCASNB 0 - 1.54 V , 6 mV Pixel threshold voltage for submatrix B -# [0x004a, 0 ], #VCASNC 0 - 1.54 V , 6 mV Pixel threshold voltage for submatrix C -# [0x004b, 0 ], #VCASND 0 - 1.54 V , 6 mV Pixel threshold voltage for submatrix D -# [0x004c, 150 ], #VCASN2 0 - 1.54 V , 6 mV Pixel voltage -# [0x004d, 55 ], #VCLIP 0 - 1.54 V , 6 mV Pixel clipping amplifier voltage -# [0x004e, 26 ], #IBUFBIAS 0 - 10 μA , 312 pA Internal buffer bias (not in pixel) - - - [0x0040, 64 ], #IBIAS 0 - 80 nA , 312 pA Pixel current - [0x0041, 52 ], #ITHR 0 - 2.5 nA , 9.8 pA Pixel current - [0x0042, 28 ], #IDB 0 - 40 nA , 157 pA Pixel current - [0x0043, 171 ], #VRESET 0.37 - 1.79 V , 6 mV Pixel input amplifier reset voltage - [0x0044, 70 ], #VPL 0.37 - 1.79 V , 6 mV Pixel voltage for charge injection (low value) - [0x0045, 90 ], #VPH 0.37 - 1.79 V , 6 mV Pixel voltage for charge injection (high - [0x0046, 0 ], #VPH_FINE 0 - 256 mV , 1 mV value) VPH+VPH_FINE - [0x0047, 67 ], #VCASP 0 - 1.54 V , 6 mV Pixel voltage - [0x0048, 0 ], #VCASNA 0 - 1.54 V , 6 mV Pixel threshold voltage for submatrix A - [0x0049, 0 ], #VCASNB 0 - 1.54 V , 6 mV Pixel threshold voltage for submatrix B - [0x004a, 0 ], #VCASNC 0 - 1.54 V , 6 mV Pixel threshold voltage for submatrix C - [0x004b, 0 ], #VCASND 0 - 1.54 V , 6 mV Pixel threshold voltage for submatrix D - [0x004c, 175 ], #VCASN2 0 - 1.54 V , 6 mV Pixel voltage - [0x004d, 50 ], #VCLIP 0 - 1.54 V , 6 mV Pixel clipping amplifier voltage - [0x004e, 125 ], #IBUFBIAS 0 - 10 μA , 312 pA Internal buffer bias (not in pixel) - -#[0x0040, 31], #IBIAS 0 - 80 nA , 312 pA Pixel current -#[0x0041, 44], #ITHR 0 - 2.5 nA , 9.8 pA Pixel current -#[0x0042, 29], #IDB 0 - 40 nA , 157 pA Pixel current -#[0x0043, 171], #VRESET 0.37 - 1.79 V , 6 mV Pixel input amplifier reset voltage -#[0x0044, 70], #VPL 0.37 - 1.79 V , 6 mV Pixel voltage for charge injection (low value) -#[0x0045, 90], #VPH 0.37 - 1.79 V , 6 mV Pixel voltage for charge injection (high -#[0x0046, 0], #VPH_FINE 0 - 256 mV , 1 mV value) VPH+VPH_FINE -#[0x0047, 67], #VCASP 0 - 1.54 V , 6 mV Pixel voltage -#[0x0048, 90], #VCASNA 0 - 1.54 V , 6 mV Pixel threshold voltage for submatrix A -#[0x0049, 0], #VCASNB 0 - 1.54 V , 6 mV Pixel threshold voltage for submatrix B -#[0x004a, 0], #VCASNC 0 - 1.54 V , 6 mV Pixel threshold voltage for submatrix C -#[0x004b, 0], #VCASND 0 - 1.54 V , 6 mV Pixel threshold voltage for submatrix D -#[0x004c, 175], #VCASN2 0 - 1.54 V , 6 mV Pixel voltage -#[0x004d, 57], #VCLIP 0 - 1.54 V , 6 mV Pixel clipping amplifier voltage -#[0x004e, 125], #IBUFBIAS 0 - 10 μA , 312 pA Internal buffer bias (not in pixel) +[0x0040, 64], #IBIAS 0 - 80 nA , 312 pA Pixel current +[0x0041, 52], #ITHR 0 - 2.5 nA , 9.8 pA Pixel current +[0x0042, 28], #IDB 0 - 40 nA , 157 pA Pixel current +[0x0043, 171], #VRESET 0.37 - 1.79 V , 6 mV Pixel input amplifier reset voltage +[0x0044, 70], #VPL 0.37 - 1.79 V , 6 mV Pixel voltage for charge injection (low value) +[0x0045, 90], #VPH 0.37 - 1.79 V , 6 mV Pixel voltage for charge injection (high +[0x0046, 255], #VPH_FINE 0 - 256 mV , 1 mV value) VPH+VPH_FINE +[0x0047, 67], #VCASP 0 - 1.54 V , 6 mV Pixel voltage +[0x0048, 126], #VCASNA 0 - 1.54 V , 6 mV Pixel threshold voltage for submatrix A +[0x0049, 0], #VCASNB 0 - 1.54 V , 6 mV Pixel threshold voltage for submatrix B +[0x004a, 0], #VCASNC 0 - 1.54 V , 6 mV Pixel threshold voltage for submatrix C +[0x004b, 0], #VCASND 0 - 1.54 V , 6 mV Pixel threshold voltage for submatrix D +[0x004c, 180], #VCASN2 0 - 1.54 V , 6 mV Pixel voltage +[0x004d, 88], #VCLIP 0 - 1.54 V , 6 mV Pixel clipping amplifier voltage +[0x004e, 125], #IBUFBIAS 0 - 10 μA , 312 pA Internal buffer bias (not in pixel) diff --git a/scripts/qa/QAScript.pl b/scripts/qa/QAScript.pl deleted file mode 100755 index bc827d9..0000000 --- a/scripts/qa/QAScript.pl +++ /dev/null @@ -1,1297 +0,0 @@ -#!/usr/bin/perl - -## MIMOSIS-1 QA Script ... version 0.5 -## -## Authors: Benedict Arnoldi-Meadows and Benedikt Gutsche - -use strict; -use warnings; -use HADES::TrbNet; -use lib "/d/jspc37/mimosis/scripts/"; -use Mimosis; -use Time::HiRes qw( usleep ); -use POSIX; -use Data::Dump qw( dump ); -use List::Util qw( min max ); -use threads; -use IO::Handle; -use IO::Socket; -use File::Temp qw( tempfile ); -use File::Copy qw( cp ); -use Cwd qw(); - -my $arrRef = [ - 0x77, - 0x88, -]; - -my %regTest = ( - 0x20 => [ - 0xaa, - 0x55, - ], - 0x21 => [ - 0xcc, - 0x33, - ], - 0x22 => $arrRef, -); - -foreach my $k (keys %regTest) { - print "$k-------"; - foreach my $l (@{$regTest{$k}}) { - print "-------$l\n"; - } -} - -sub ask_continue -{ - print "Repeat test? [y/N]: "; - my $answer = ; - chomp $answer; - - return 0 if $answer eq "" || $answer eq "n" || $answer eq "N"; - return 1; -} - - -my $ZeroElectronVPHSetting = 95; -my $fpgalink = 0xa000; -my $singleaccessmode = 0; -my $slow = 100; -my $slow2 = 100000; -my $adcSlow = 100000; - -my %fineVCASNParams = (); - -my $peer = "192.168.0.61"; -my $port = "5025"; -my $bbCh = 2; - - - -trb_init_ports() or die trb_strerror(); - - - - -print "\n"; -print "############################################################################\n"; -print "### INIT ###\n"; -print "############################################################################\n"; -print "\n"; - -my $sensorname; - -# Perform loop until a good name is found, -# i.e. it has never been assigned or is not empty -while ( 1 ) { - - print "Enter the sensor name: "; - $sensorname = ; - chomp $sensorname; - - # Check for bad names - if (-d $sensorname or $sensorname eq "") { - - print "Sensor name already chosen or illegal. Choose new one...\n"; - - } else { - - mkdir($sensorname); - last; - } -} - - -# Hash where everything gets stored before written to file -my %file; - -# Trap sig int -$SIG{INT} = sub { - - open(RESULTS_FH, '>', $sensorname . "/results.db") or die $!; - print RESULTS_FH "$_\t$file{$_}\n" foreach (keys %file); - close RESULTS_FH; - die "\nAbort.\n" -}; - - -$file{"SensorName"} = $sensorname; - - - - -my $irraddeg; - -while ( 1 ) { - - print "TID dose [kRad]: "; - $irraddeg = ; - chomp $irraddeg; - - # Check if numeric and within good current range - if ($irraddeg =~ /^\d{1,4}$/ ) { - last; - } elsif ($irraddeg eq "") { - $irraddeg = 1000; - last; - } else { - print "Invalid value (letters).\n"; - } -} - - - - - -my $backbias; - -do { - my $socket = IO::Socket::INET->new(PeerAddr => $peer, PeerPort => $port, Proto => "tcp", Type => SOCK_STREAM) - or die "ERROR: Cannot connect: $@"; - - usleep 1e5; print $socket "INST OUT$bbCh\n"; - usleep 1e5; print $socket "MEAS:VOLT?\n"; - $backbias = <$socket>; - chomp $backbias; - $backbias = 1000 * $backbias; - print "Back bias: $backbias mV\n"; - -} while ask_continue(); - - - - - - - -# print "\n"; -# print "#############################################################################\n"; -# print "### CHIPID TEST ###\n"; -# print "#############################################################################\n"; -# print "\n"; - -# my @chipids = ( 0x0, 0x1 ); - -# my $gpioReg = 0xd580; -# my $testreg = 0x0020; # Pixel control register for testing -# my $testval = 0x1; -# my $shouldKill = 0; - -# do { -# foreach my $id (@chipids) { - -# # Reset all -# my $bitmaskClear = 0x1 << 30; - -# trb_register_clearbit( -# $fpgalink, -# $gpioReg, -# $bitmaskClear -# ); usleep($slow2); - -# # Set desired bits -# my $bitmaskSet = $id << 30; - -# trb_register_setbit( -# $fpgalink, -# $gpioReg, -# $bitmaskSet -# ); usleep($slow2); - -# Mimosis::set_chipid($id); - -# my $tmp = Mimosis::mimosis_register_read( -# $fpgalink, -# $testreg, -# $singleaccessmode -# ); usleep($slow2); - -# Mimosis::mimosis_register_write( -# $fpgalink, -# $testreg, -# $testval, -# $singleaccessmode -# ); usleep(100000); - -# my $testTmp = Mimosis::mimosis_register_read( -# $fpgalink, -# $testreg, -# $singleaccessmode -# ); usleep($slow2); - -# if ( ( $testTmp&0xff ) != $testval ) { - -# print "Chip-ID $id not working.\n"; -# $file{"CHIP-ID_$id"} = "F"; -# $shouldKill += 1; - -# } else { - -# $file{"CHIP-ID_$id"} = "S"; -# } -# } -# } while ask_continue(); - -# # die "Found broken chip ids. Exiting.\n" if $shouldKill; - -# # Reset chipid to 0x1 -# Mimosis::set_chipid(0x1); usleep($slow2); - -# trb_register_setbit( -# $fpgalink, -# $gpioReg, -# 0x1 << 30 -# ); usleep($slow2); - - - - - -# print "\n"; -# print "############################################################################\n"; -# print "### REGISTER TEST ###\n"; -# print "############################################################################\n"; -# print "\n"; - -# my %reglist = ( -# 0x0020 => 0x1, -# 0x0021 => 0x1, -# 0x0022 => 0x1, -# ); - - -# do { -# while( my ($reg, $val) = each(%reglist) ) { - -# # Save original value into register -# my $tmp = Mimosis::mimosis_register_read( -# $fpgalink, -# $reg, -# $singleaccessmode -# ); usleep($slow2); # - - -# # Write test value -# Mimosis::mimosis_register_write( -# $fpgalink, -# $reg, -# $val, -# $singleaccessmode -# ); usleep($slow2); # write value into register - -# # Get test value -# my $testVal = Mimosis::mimosis_register_read( -# $fpgalink, -# $reg, -# $singleaccessmode -# ); usleep($slow2); # - - - -# # Compare -# print("$testVal != $val\n") unless $testVal == $val; - -# # Write original value back into register -# Mimosis::mimosis_register_write( -# $fpgalink, -# $reg, -# $tmp, -# $singleaccessmode -# ); usleep($slow2); -# } -# } while ask_continue(); - - - - - -# print "\n"; -# print "############################################################################\n"; -# print "### LINK TEST ###\n"; -# print "############################################################################\n"; -# print "\n"; - -# do { -# my $currentWd = Cwd::cwd(); -# chdir("/d/jspc37/mimosis/scripts"); -# system("/d/jspc37/mimosis/scripts/start.sh"); -# chdir($currentWd); - -# my $cntBadLinks = 0; - -# for my $i (0 .. 7) { - -# my $reg = trb_register_read( $fpgalink, 0xa000 + $i ); -# $reg = ( $reg->{$fpgalink} & 0x7f00 ) >> 8; - -# $cntBadLinks += 1 if $reg >= 70; - -# $file{"Link_$i"} = $reg >= 70 ? "$reg\tBAD" : "$reg\tGOOD"; -# } - -# # die "Bad links. Exiting.\n" if $cntBadLinks > 0; -# print "Bad links.\n" if $cntBadLinks > 0; - -# } while ask_continue(); - - - - - -# print "\n"; -# print "#############################################################################\n"; -# print "### BB TEST ###\n"; -# print "#############################################################################\n"; -# print "\n"; - -# open(BB_FH, '>', $sensorname . "/bb.csv") or die $!; - -# do { -# my $socket = IO::Socket::INET->new(PeerAddr => $peer, PeerPort => $port, Proto => "tcp", Type => SOCK_STREAM) -# or die "ERROR: Cannot connect: $@"; - -# # Save current BB seting for later -# usleep 1e0; print $socket "INST OUT$bbCh\n"; -# usleep 1e5; print $socket "MEAS:VOLT?\n"; -# my $tmp = <$socket>; -# chomp $tmp; - -# for (my $i = 0; $i <= 5.0; $i += 0.5) { - -# usleep 1e5; print $socket "VOLT $i\n"; -# usleep 1e5; print $socket "MEAS:VOLT?\n"; my $volt = <$socket>; -# usleep 1e5; print $socket "MEAS:CURR?\n"; my $curr = <$socket>; - -# chomp $volt; -# chomp $curr; - -# print BB_FH "$volt\t$curr\n"; -# } - -# # Reset BB to what it was before -# usleep 1e5; print $socket "VOLT $tmp\n"; - -# } while ask_continue(); - -# close BB_FH; - - - - -# print "\n"; -# print "###########################################################################\n"; -# print "### POWERING TEST DIGITAL ###\n"; -# print "###########################################################################\n"; -# print "\n"; - -# #Find out current drawn by sensor on digital and perform data checks. -# my $lowleveldig = 100; # Minimum digital current for passing as ok -# my $highleveldig = 200; # Maximum digital current for passing as ok - - -# do { -# my $adc_addr = 0x48; -# my $adc_wreg = 0x1; -# my $adc_cmd = 0xc380; #CHANGE ME -# my $adc_rreg = 0x0; -# my $adcConv = ( 2 * 4096 ) / (2**16 * 10); - -# Mimosis::adc_i2c_command( -# $fpgalink, -# $adc_addr, -# $adc_wreg, -# $adc_cmd, -# 0, 0, 1 -# ); usleep($adcSlow); - -# my $digitalcur = Mimosis::adc_i2c_command( -# $fpgalink, -# $adc_addr, -# $adc_rreg, -# 0x0, -# 1, 0, 1 ); usleep($adcSlow); -# $digitalcur *= $adcConv; - -# # Check if numeric and within good current range -# if ( $digitalcur <= $highleveldig && -# $digitalcur >= $lowleveldig ) -# { -# $file{"Digitalcurrent"} = $digitalcur; -# print "Digital current: $digitalcur mA.\n"; - -# } else { - -# print "Digital current not in range: $digitalcur.\n"; -# $file{"Digitalcurrent"} = "F"; -# } - -# } while ask_continue(); - - - - - -# print "\n"; -# print "############################################################################\n"; -# print "### POWERING TEST ANALOG ###\n"; -# print "############################################################################\n"; -# print "\n"; - -# #Find out current drawn by sensor on analog and perform data checks. -# my $lowlevelana = 10; # Minimum analog current for passing as ok -# my $highlevelana = 80; # Maximum analog current for passing as ok - - -# do { -# my $adc_addr = 0x48; -# my $adc_wreg = 0x1; -# my $adc_cmd = 0xf380; #CHANGE ME -# my $adc_rreg = 0x0; -# my $adcConv = ( 2 * 4096 ) / (2**16 * 100); - -# Mimosis::adc_i2c_command( -# $fpgalink, -# $adc_addr, -# $adc_wreg, -# $adc_cmd, -# 0, 0, 1 -# ); usleep($adcSlow); - -# my $analogcur = Mimosis::adc_i2c_command( -# $fpgalink, -# $adc_addr, -# $adc_rreg, -# 0x0, -# 1, 0, 1 ); usleep($adcSlow); - -# $analogcur *= $adcConv; - -# # Check if numeric and within good current range -# if( $analogcur <= $highlevelana && -# $analogcur >= $lowlevelana ) -# { -# $file{"Analogcurrent"} = $analogcur; -# print "Analog current: $analogcur mA.\n"; - -# } else { - -# print "Analog current not in range: $analogcur.\n"; -# $file{"Analogcurrent"} = "F"; -# } - -# } while ask_continue(); - - -# # print "$_\t$file{$_}\n" foreach (keys %file); - - - - -# print "\n"; -# print "############################################################################\n"; -# print "### FAST DACSCAN TEST ###\n"; -# print "############################################################################\n"; -# print "\n"; - -# do { -# Mimosis::mimosis_dacscan_initial_test( -# fpga => $fpgalink, -# slow => 10000, -# a => 1, -# printall => 1, -# plotname => $sensorname, -# ikf => $fpgalink&1, -# ); - -# print "Please enter rapid DAC scan result classification.\n"; -# print "S = satisfactory if in grey areas\n"; -# print "F = unsatisfactory and exiting.\n"; - -# while ( 1 ) { - -# print "Rapid DAC scan classification: "; -# my $rapiddacclass = ; -# chomp $rapiddacclass; - -# if ( $rapiddacclass eq "S" || -# $rapiddacclass eq "s" ) { - -# $file{"RapidDACTest"} = "S"; -# last; - -# } elsif ( $rapiddacclass eq "F" || -# $rapiddacclass eq "f" ) { - -# $file{"RapidDACTest"} = "F"; -# exit 0; - -# } else { -# print "Invalid classification. Try again.\n"; -# } -# } - -# } while ask_continue(); - - - - - -print "\n"; -print "############################################################################\n"; -print "### DACSCAN TEST ###\n"; -print "############################################################################\n"; -print "\n"; - -my $VPHFSlope; -my $VPHOffsetElectron; - -do { - chdir($sensorname); - - my %dacVals = Mimosis::mimosis_dacscan_sf( - fpga => $fpgalink, - slow => 10000, - printall => 1, - ikf => $fpgalink&1, - ); - - chdir(".."); - - my %names = ( - 'IBIAS' => 0x0040, - 'ITHR' => 0x0041, - 'IDB' => 0x0042, - 'VRESET' => 0x0043, - 'VPL' => 0x0044, - 'VPH' => 0x0045, - 'VPH_FINE' => 0x0046, - 'VCASP' => 0x0047, - 'VCASNA' => 0x0048, - 'VCASNB' => 0x0049, - 'VCASNC' => 0x004a, - 'VCASND' => 0x004b, - 'VCASN2' => 0x004c, - 'VCLIP' => 0x004d, - 'IBUFBIAS' => 0x004e, - ); - - - my @VPHList = @{$dacVals{$names{"VPH"}}}; - my @VPLList = @{$dacVals{$names{"VPL"}}}; - my @VPHFINEList = @{$dacVals{$names{"VPH_FINE"}}}; - my @VRESETList = @{$dacVals{$names{"VRESET"}}}; - my @VCASNAList = @{$dacVals{$names{"VCASNA"}}}; - my @VCASNBList = @{$dacVals{$names{"VCASNB"}}}; - my @VCASNCList = @{$dacVals{$names{"VCASNC"}}}; - my @VCASNDList = @{$dacVals{$names{"VCASND"}}}; - my @VCASN2List = @{$dacVals{$names{"VCASN2"}}}; - my @VCLIPList = @{$dacVals{$names{"VCLIP"}}}; - my @VCASPList = @{$dacVals{$names{"VCASP"}}}; - my @IBIASList = @{$dacVals{$names{"IBIAS"}}}; - my @ITHRList = @{$dacVals{$names{"ITHR"}}}; - my @IDBList = @{$dacVals{$names{"IDB"}}}; - - - my($T,$N) = tempfile("plot-XXXX", "UNLINK", 1); - - foreach my $dac (keys %names) { - - foreach my $v (@{$dacVals{$names{$dac}}}) { - say $T $v; - } - - print $T "\n\n"; - } - - close $T; - - - open my $P, "|-", "gnuplot" or die; - - my $dacPng = "$sensorname/alldacs.png"; - - printflush $P qq[ -set terminal pngcairo size 1000,1000; -set output "$dacPng"; -set key Left left top box; -set xlabel "set."; -set ylabel "[mV]"; -plot "$N" with l; - -set terminal qt; -set xlabel "set."; -set ylabel "[mV]"; -plot "$N" with l; -]; - ; - close $P; - - - for my $i (0 .. scalar( @VPHFINEList ) - 1) { - $VPHFINEList[$i] = $VPHFINEList[$i] - $VPHList[0]; - } - - - my $sensorQuality = 4; - - my $VPHOffset = $VPHList[0]; - my $VPLOffset = $VPLList[0]; - my $VRESETOffset = $VRESETList[0]; - my $VPHFOffset = $VPHFINEList[0]; - my $VPH210 = $VPHList[211]; - my $VPL210 = $VPLList[211]; - my $VRESET210 = $VRESETList[211]; - my $VPHF210 = $VPHFINEList[211] - $VPHFOffset; - - - if ( (300 <= $VPHOffset) && - (375 >= $VPHOffset) && - (300 <= $VPLOffset) && - (375 >= $VPLOffset) && - (300 <= $VRESETOffset) && - (375 >= $VRESETOffset) && - ($VPH210 >= 1410) && - ($VPL210 >= 1410) && - ($VRESET210 >= 1410) && - ($VPHFOffset <= 20) && - ($VPHF210 >= 190) ) { - - $sensorQuality = 3; - - if ( max(@VCASNAList) > 1100 && - max(@VCASNBList) > 1100 && - max(@VCASNCList) > 1100 && - max(@VCASNDList) > 1100 && - max(@VCASN2List) > 1100 && - max(@VCLIPList) > 550 && - max(@VCASPList) > 550 && - max(@IBIASList) >= 260 && - max(@ITHRList) >= 260 && - max(@IDBList) >= 260 ) { - - $sensorQuality = 2; - - my $arrRef = [ 3,3,3,3 - ]; - - sub calcAbsDNLAbsINL { - - my @dac = @{$_[0]}; - - my $gain = ($dac[199] - $dac[24]) / 175.0; - - my @dnl = ( 0 ); - my @inl = ( 0 ); - - for my $i (21 .. 201) { - - my $currentDNL = ( ($dac[$i] - $dac[$i-1]) / $gain ) - 1; - push(@dnl, $currentDNL); - push(@inl, $inl[$i-21]+$currentDNL); - } - - @dnl = reverse @dnl; - @inl = reverse @inl; - return ( \@inl, \@dnl ); - } - - - my ( $ibiasinlRef, $ibiasdnlRef ) = calcAbsDNLAbsINL(\@IBIASList); - my @IBIASINL = @{$ibiasinlRef}; - my @IBIASDNL = @{$ibiasdnlRef}; - - my ( $ithrinlRef, $ithrdnlRef ) = calcAbsDNLAbsINL(\@ITHRList); - my @ITHRINL = @{$ithrinlRef}; - my @ITHRDNL = @{$ithrdnlRef}; - - my ( $idbinlRef, $idbdnlRef ) = calcAbsDNLAbsINL(\@IDBList); - my @IDBINL = @{$idbinlRef}; - my @IDBDNL = @{$idbdnlRef}; - - my ( $vphinlRef, $vphdnlRef ) = calcAbsDNLAbsINL(\@VPHList); - my @VPHINL = @{$vphinlRef}; - my @VPHDNL = @{$vphdnlRef}; - - my ( $vplinlRef, $vpldnlRef ) = calcAbsDNLAbsINL(\@VPLList); - my @VPLINL = @{$vplinlRef}; - my @VPLDNL = @{$vpldnlRef}; - - my ( $vresetinlRef, $vresetdnlRef ) = calcAbsDNLAbsINL(\@VRESETList); - my @VRESETINL = @{$vresetinlRef}; - my @VRESETDNL = @{$vresetdnlRef}; - - my ( $vphfineinlRef, $vphfinednlRef ) = calcAbsDNLAbsINL(\@VPHFINEList); - my @VPHFINEINL = @{$vphfineinlRef}; - my @VPHFINEDNL = @{$vphfinednlRef}; - - my ( $vcasnainlRef, $vcasnadnlRef ) = calcAbsDNLAbsINL(\@VCASNAList); - my @VCASNAINL = @{$vcasnainlRef}; - my @VCASNADNL = @{$vcasnadnlRef}; - - my ( $vcasnbinlRef, $vcasnbdnlRef ) = calcAbsDNLAbsINL(\@VCASNBList); - my @VCASNBINL = @{$vcasnbinlRef}; - my @VCASNBDNL = @{$vcasnbdnlRef}; - - my ( $vcasncinlRef, $vcasncdnlRef ) = calcAbsDNLAbsINL(\@VCASNCList); - my @VCASNCINL = @{$vcasncinlRef}; - my @VCASNCDNL = @{$vcasncdnlRef}; - - my ( $vcasndinlRef, $vcasnddnlRef ) = calcAbsDNLAbsINL(\@VCASNDList); - my @VCASNDINL = @{$vcasndinlRef}; - my @VCASNDDNL = @{$vcasnddnlRef}; - - my ( $vcasn2inlRef, $vcasn2dnlRef ) = calcAbsDNLAbsINL(\@VCASN2List); - my @VCASN2INL = @{$vcasn2inlRef}; - my @VCASN2DNL = @{$vcasn2dnlRef}; - - my ( $vcaspinlRef, $vcaspdnlRef ) = calcAbsDNLAbsINL(\@VCASPList); - my @VCASPINL = @{$vcaspinlRef}; - my @VCASPDNL = @{$vcaspdnlRef}; - - my ( $vclipinlRef, $vclipdnlRef ) = calcAbsDNLAbsINL(\@VCLIPList); - my @VCLIPINL = @{$vclipinlRef}; - my @VCLIPDNL = @{$vclipdnlRef}; - - my $goodDNL = 0; - - if ( $IBIASDNL[2] < 1 - && $ITHRDNL[2] < 1 - && $IDBDNL[2] < 1 - && $VCASNADNL[2] < 1 - && $VCASNBDNL[2] < 1 - && $VCASNCDNL[2] < 1 - && $VCASNDDNL[2] < 1 - && $VCASN2DNL[2] < 1 - && $VCASPDNL[2] < 1 - && $VCLIPDNL[2] < 1 - && $VPHDNL[2] < 1 - && $VPLDNL[2] < 1 - && $VRESETDNL[2] < 1 - && $VPHFINEDNL[2] < 1 - ) { - $goodDNL = 1; - } - - my $goodINL = 0; - - if ( $IBIASINL[2] < 5 - && $ITHRINL[2] < 5 - && $IDBINL[2] < 5 - && $VCASNAINL[2] < 5 - && $VCASNBINL[2] < 5 - && $VCASNCINL[2] < 5 - && $VCASNDINL[2] < 5 - && $VCASN2INL[2] < 5 - && $VCASPINL[2] < 5 - && $VCLIPINL[2] < 5 - && $VPHINL[2] < 1 - && $VPLINL[2] < 1 - && $VRESETINL[2] < 1 - && $VPHFINEINL[2] < 1 - ) { - $goodINL = 1; - } - - if ($goodDNL && $goodINL) { - $sensorQuality = 1; - } - } - } - - $VPHFSlope = ($VPHFINEList[255] - $VPHFINEList[0]) / 255.0; - # $VPHFSlope = 1.; - $VPHOffsetElectron = 150; - $ZeroElectronVPHSetting = 95; - - for my $i (0 .. scalar(@VPHList)) { - - if ( ($VPHList[$i] gt ($VPLList[70] - 6)) # or ($VPHList[$i] lt ($VPLList[70] + 6)) - ) { - - $ZeroElectronVPHSetting = $i; - $VPHOffsetElectron = $VPHList[$i] - $VPLList[70]; - last; - } - } - - print("ZeroSetting\t$ZeroElectronVPHSetting\t$VPHOffsetElectron"); - - print("Sensor Quality for DACs: $sensorQuality\n"); - - $file{"DACQuality"} = $sensorQuality; - $file{"VPHFSlope"} = $VPHFSlope; - $file{"VPHSetting0Electrons"} = "$ZeroElectronVPHSetting\t$VPHOffsetElectron"; - -} while ask_continue(); - - - - - -sub fit_thr { - my ($fname, $dirName, $vphOffsetElectron, $vphfSlope) = @_; - - system("/usr/bin/python3 /d/jspc37/mimosis/scripts/pulse/fit-raw.py $fname $dirName $vphOffsetElectron $vphfSlope"); -} - -# my $VPHFSlope = 1.0; -# my $VPHOffsetElectron = 0; - - - - - - -my %matrixParams = ( - A => { - VCASN => 0x48, - }, - # B => { - # VCASN => 0x49, - # }, - # C => { - # VCASN => 0x4a, - # }, - # D => { - # VCASN => 0x4b, - # }, - ); - - -print "\n"; -print "############################################################################\n"; -print "### SCURVE TEST ###\n"; -print "############################################################################\n"; -print "\n"; - -my $lowerlimitA = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 95 : -(( $backbias == 1000 && $irraddeg >= 1000 ) ? 60 : (( $backbias == 1000 && $irraddeg == 0 ) ? 70 : (( $backbias == 3000 && $irraddeg == 0 ) ? 110 : 50 ))); - -my $upperlimitA = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 120 : -(( $backbias == 1000 && $irraddeg >= 1000 ) ? 100 : (( $backbias == 1000 && $irraddeg == 0 ) ? 115 : (( $backbias == 3000 && $irraddeg == 0 ) ? 165 : 200 ))); - - -my $lowerlimitB = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 100 : -(( $backbias == 1000 && $irraddeg >= 1000 ) ? 75 : (( $backbias == 1000 && $irraddeg == 0 ) ? 95 : (( $backbias == 3000 && $irraddeg == 0 ) ? 130 : 50 ))); - -my $upperlimitB = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 150 : -(( $backbias == 1000 && $irraddeg >= 1000 ) ? 125 : (( $backbias == 1000 && $irraddeg == 0 ) ? 140 : (( $backbias == 3000 && $irraddeg == 0 ) ? 185 : 200 ))); - - -my $lowerlimitC = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 100 : -(( $backbias == 1000 && $irraddeg >= 1000 ) ? 75 : (( $backbias == 1000 && $irraddeg == 0 ) ? 95 : (( $backbias == 3000 && $irraddeg == 0 ) ? 130 : 50 ))); - -my $upperlimitC = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 150 : -(( $backbias == 1000 && $irraddeg >= 1000 ) ? 125 : (( $backbias == 1000 && $irraddeg == 0 ) ? 140 : (( $backbias == 3000 && $irraddeg == 0 ) ? 185 : 200 ))); - - -my $lowerlimitD = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 95 : -(( $backbias == 1000 && $irraddeg >= 1000 ) ? 60 : (( $backbias == 1000 && $irraddeg == 0 ) ? 75 : (( $backbias == 3000 && $irraddeg == 0 ) ? 115 : 50 ))); - -my $upperlimitD = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 120 : -(( $backbias == 1000 && $irraddeg >= 1000 ) ? 100 : (( $backbias == 1000 && $irraddeg == 0 ) ? 140 : (( $backbias == 3000 && $irraddeg == 0 ) ? 180 : 200 ))); - - -do { - - - # my $lowerlimitD = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 100 : - # ( ( $backbias == 1000 && $irraddeg >= 1000 ) ? 88 : 60); - - # my $upperlimitD = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 180 : - # ( ( $backbias == 1000 && $irraddeg >= 1000 ) ? 88 : 180); - - - # my $lowerlimitA = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 100 : - # ( ( $backbias == 1000 && $irraddeg >= 1000 ) ? 60 : 60); - - # my $upperlimitA = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 180 : - # ( ( $backbias == 1000 && $irraddeg >= 1000 ) ? 85 : 180); - - # my $lowerlimitB = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 100 : - # ( ( $backbias == 1000 && $irraddeg >= 1000 ) ? 88 : 80); - - # my $upperlimitB = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 180 : - # ( ( $backbias == 1000 && $irraddeg >= 1000 ) ? 88 : 180); - - # my $lowerlimitC = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 100 : - # ( ( $backbias == 1000 && $irraddeg >= 1000 ) ? 88 : 80); - - # my $upperlimitC = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 180 : - # ( ( $backbias == 1000 && $irraddeg >= 1000 ) ? 88 : 180); - - - # my $SixtyElectronVPHSetting = 70; - #print("VPHSetting: $SixtyElectronVPHSetting \n"); - #Mimosis::mimosis_register_write( $fpgalink, 0x45, $SixtyElectronVPHSetting, $singleaccessmode ); - - my $settingsScurves = "./CONF_scurves.pl"; - - cp($settingsScurves, "$sensorname/$settingsScurves"); - - Mimosis::mimosis_load_file( - fpga => $fpgalink, - slow => $slow, - a => $singleaccessmode, - file => $settingsScurves - ); - - Mimosis::mimosis_register_write( $fpgalink, 0x45, $ZeroElectronVPHSetting, $singleaccessmode ); - Mimosis::mimosis_register_write( $fpgalink, 0x4D, int( 45 + $backbias/1000.0 * 12.0 + 0.5 ), $singleaccessmode ); - - - chdir($sensorname); - - foreach my $matrix ( sort keys %matrixParams ) { - - Mimosis::mimosis_register_write( $fpgalink, 0x45, $ZeroElectronVPHSetting, $singleaccessmode ); - Mimosis::mimosis_register_write( $fpgalink, 0x4D, int( 45 + $backbias/1000.0 * 12.0 + 0.5 ), $singleaccessmode ); - - Mimosis::mimosis_pulse_region( - fpga => $fpgalink, - slow => $slow, - a => $singleaccessmode, - region => $matrix, - ySta => 250, - yEnd => 253, -# yTra => $yTraSc, -# xSta => $xStaSc, -# xEnd => $xEndSc, -# analogAlimA => $analogAlimASc, -# analogAlimB => $analogAlimBSc, -# analogDlimA => $analogDlimASc, -# analogDlimB => $analogDlimBSc, -# mod => $modpulse, - ); - - - if ($matrix eq "A" ) {print("Find proper VCASN setting in Go4! Suggested range: $lowerlimitA -- $upperlimitA: ");} - if ($matrix eq "B" ) {print("Find proper VCASN setting in Go4! Suggested range: $lowerlimitB -- $upperlimitB: ");} - if ($matrix eq "C" ) {print("Find proper VCASN setting in Go4! Suggested range: $lowerlimitC -- $upperlimitC: ");} - if ($matrix eq "D" ) {print("Find proper VCASN setting in Go4! Suggested range: $lowerlimitD -- $upperlimitD: ");} - - my $foundF = 0; - - while ( 1 ) { - - print "Enter the appropriate VCASN$matrix value or \'F\' if bad:" ; - - my $vcasnTmp = ; - chomp $vcasnTmp; - - if ( $vcasnTmp eq "F" or - $vcasnTmp eq "f" ) { - - $file{"CoarseSCurves,MATRIX-$matrix"} = "F"; - - $foundF = 1; - last; - - } else { - - $file{"CoarseSCurves,MATRIX-$matrix"} = $vcasnTmp; - $matrixParams{$matrix}{"VCASNCOARSE"} = $vcasnTmp; - last; - } - } - if ( $foundF ) { exit 0; } - - } - - foreach my $matrix ( sort keys %matrixParams ) { - - Mimosis::mimosis_register_write( $fpgalink, 0x45, $ZeroElectronVPHSetting, $singleaccessmode ); - Mimosis::mimosis_register_write( $fpgalink, 0x4D, int( 45 + $backbias/1000.0 * 12.0 + 0.5 ), $singleaccessmode ); - - my $matrixDir = "MATRIX-" . $matrix; - mkdir($matrixDir); - chdir($matrixDir); - - Mimosis::mimosis_scan_region_loop( - fpga => $fpgalink, - slow => $slow, - # a => $singleaccessmode, - a => 0, - region => $matrix, - vcasnSta => $matrixParams{$matrix}{"VCASNCOARSE"} - 5, - vcasnEnd => $matrixParams{$matrix}{"VCASNCOARSE"} + 5, - # vcasnSta => 100, - vcasnStep => 1, - ySta => 250, - yEnd => 253, - # yTra => $yTraSc, - # xSta => $xStaSc, - # xEnd => $xEndSc, - # setSta => $setStaSc, - # setEnd => $setEndSc, - # setTra => $setStepSc, - # setCnt => $setCntSc, - # analogAlimA => $analogAlimASc, - # analogAlimB => $analogAlimBSc, - # analogDlimA => $analogDlimASc, - # analogDlimB => $analogDlimBSc, - # mod => $modpulseSc, - ); - - opendir my $dir, "lastdir" or die "Cannot open directory: $!"; - - my @files = readdir $dir; - - foreach my $f ( @files ) { # FIXME Still a problem here - - print("$f\n"); - - if ( $f =~ /VCASN/ ) { - my $dirName = Cwd::cwd() . "/lastdir/$f"; - $matrixParams{$matrix}{"THREAD"} = threads->create(\&fit_thr, "$f.csv", $dirName, $VPHOffsetElectron, $VPHFSlope); - } - } - - closedir $dir; - - chdir(".."); - } - - chdir(".."); - - - print "Wait for fits to finish.\n"; - - foreach my $matrix ( sort keys %matrixParams ) { - - $matrixParams{$matrix}{"THREAD"}->join(); - } - - - print("Approximate a VCASN for each submatrix where the GMDT is closest to 150 e!\n"); - - my $foundF = 0; - - foreach my $matrix ( sort keys %matrixParams ) { - - while ( 1 ) { - - print "Enter the appropriate VCASN$matrix value or \'F\' if bad: " ; - - my $vcasnTmp = ; - chomp $vcasnTmp; - - if ( $vcasnTmp eq "F" or - $vcasnTmp eq "f" ) { - - $file{"RapidSCurves,MATRIX-$matrix"} = "F"; - - $foundF = 1; - last; - - } else { - - $file{"SCurvesFull,MATRIX-$matrix"} = $vcasnTmp; - $matrixParams{$matrix}{"VCASNFINAL"} = $vcasnTmp; - last; - } - } - } - if ( $foundF ) { exit 0; } - -} while ask_continue(); - - - - - - - - - - - - -do { - print "\n"; - print "############################################################################\n"; - print "### SCURVE TEST, FINAL ###\n"; - print "############################################################################\n"; - print "\n"; - - -# my $lowerlimitA = $matrixParams{"A"}{"PREV-VCASN"} - 2; -# my $upperlimitA = + 2; - -# my $lowerlimitB = $prevFoundB - 2; -# my $upperlimitB = $prevFoundB + 2; - -# my $lowerlimitC = $prevFoundC - 2; -# my $upperlimitC = $prevFoundC + 2; -# -# my $lowerlimitD = $prevFoundD - 2; -# my $upperlimitD = $prevFoundD + 2; - - - # my $SixtyElectronVPHSetting = 70; - #Mimosis::mimosis_register_write( $fpgalink, 0x45, $SixtyElectronVPHSetting, $singleaccessmode ); - - my $settingsScurves = "./CONF_scurves.pl"; - - cp($settingsScurves, "$sensorname/$settingsScurves"); - - Mimosis::mimosis_load_file( - fpga => $fpgalink, - slow => $slow, - a => $singleaccessmode, - file => $settingsScurves - ); - - #Mimosis::mimosis_register_write( $fpgalink, 0x4D, int( 45 + $backbias/1000.0 * 12.0 + 0.5 ), $singleaccessmode ); - - - - chdir($sensorname); - - foreach my $matrix ( sort keys %matrixParams ) { - - my $matrixDir = "MATRIXFINAL-" . $matrix; - mkdir($matrixDir); - chdir($matrixDir); - - Mimosis::mimosis_register_write( $fpgalink, 0x45, $ZeroElectronVPHSetting, $singleaccessmode ); - Mimosis::mimosis_register_write( $fpgalink, 0x4D, int( 45 + $backbias/1000.0 * 12.0 + 0.5 ), $singleaccessmode ); - my $vcasnSetting + $matrixParams{$matrix}{"VCASNFINAL"}; - - print("VCASNFINAL SETTING: $vcasnSetting"); - - Mimosis::mimosis_scan_region_loop( - fpga => $fpgalink, - slow => $slow, - # a => $singleaccessmode, - a => 0, - region => $matrix, - vcasnSta => $matrixParams{$matrix}{"VCASNFINAL"}, - vcasnEnd => $matrixParams{$matrix}{"VCASNFINAL"}, - # vcasnSta => 100, - vcasnStep => 1, - ySta => 0, - yEnd => 503, - # yTra => $yTraSc, - # xSta => $xStaSc, - # xEnd => $xEndSc, - # setSta => $setStaSc, - # setEnd => $setEndSc, - # setTra => $setStepSc, - # setCnt => $setCntSc, - # analogAlimA => $analogAlimASc, - # analogAlimB => $analogAlimBSc, - # analogDlimA => $analogDlimASc, - # analogDlimB => $analogDlimBSc, - # mod => $modpulseSc, - ); - - opendir my $dir, "lastdir" or die "Cannot open directory: $!"; - - my @files = readdir $dir; - - foreach my $f ( @files ) { # FIXME Still a problem here - - print("$f\n"); - - if ( $f =~ /VCASN/ ) { - my $dirName = Cwd::cwd() . "/lastdir/$f"; - $matrixParams{$matrix}{"THREAD"} = threads->create(\&fit_thr, "$f.csv", $dirName, $VPHOffsetElectron, $VPHFSlope); - } - } - - closedir $dir; - - chdir(".."); - -# opendir my $dir, "lastdir" or die "Cannot open directory: $!"; -# -# my @files = readdir $dir; -# -# foreach my $f ( @files ) { -# -# if ( $f =~ /VCASN/ ) { -# chdir("lastdir/$f"); -# -# $matrixParams{$matrix}{"THREAD"} = threads->create(\&fit_thr, $f, $VPHOffsetElectron, $VPHFSlope); -# -# chdir("../.."); -# } -# } -# -# closedir $dir; -# -# chdir(".."); - } - - print "Wait for fits to finish.\n"; - - foreach my $matrix ( sort keys %matrixParams ) { - - $matrixParams{$matrix}{"THREAD"}->join(); - } - - chdir(".."); - - - print "Wait for fits to finish.\n"; - - foreach my $matrix ( sort keys %matrixParams ) { - - $matrixParams{$matrix}{"THREAD"}->join(); - } - - - print("Give VCASN for each submatrix where the GMDT is closest to 150 e!\n"); - - my $foundF = 0; - - foreach my $matrix ( sort keys %matrixParams ) { - - while ( 1 ) { - - print "Enter the appropriate VCASN$matrix value or \'F\' if bad:" ; - - my $vcasnTmp = ; - chomp $vcasnTmp; - - if ( $vcasnTmp eq "F" or - $vcasnTmp eq "f" ) { - - $file{"FineSCurves,MATRIX-$matrix"} = "F"; - - $foundF = 1; - last; - - } else { - - $file{"FineSCurves,MATRIX-$matrix"} = $vcasnTmp; - $matrixParams{$matrix}{"FINE"} = $vcasnTmp; - last; - } - } - } - if ( $foundF ) { exit 0; } - -} while ask_continue(); - - - - - - - - - - - - - - - - -open(RESULTS_FH, '>', $sensorname . "/results.db") or die $!; -print RESULTS_FH "$_\t$file{$_}\n" foreach (keys %file); -close RESULTS_FH; diff --git a/scripts/qa/QAScript_v08.pl b/scripts/qa/QAScript_v08.pl new file mode 100755 index 0000000..f6f61f6 --- /dev/null +++ b/scripts/qa/QAScript_v08.pl @@ -0,0 +1,1858 @@ +#!/usr/bin/perl + +# MIMOSIS-1 QA Script ... version 0.8 +# +# Authors: Benedict Arnoldi-Meadows and Benedikt Gutsche + +use strict; +use warnings; +use HADES::TrbNet; +use Mimosis; +use Time::HiRes qw( usleep ); +use POSIX; +use Data::Dump qw( dump ); +use List::Util qw( min max ); +use threads; +use IO::Handle; +use IO::Socket; +use File::Temp qw( tempfile ); +use File::Copy qw( cp ); +use Cwd qw(); +use Chart::Gnuplot; + +# reassign STDOUT, STDERR +open my $log_fh, '>>', 'log.txt'; +*STDERR = $log_fh; + + +sub ask_continue +{ + print "Repeat test? [y/N]: "; + my $answer = ; + chomp $answer; + + return 0 if $answer eq "" || $answer eq "n" || $answer eq "N"; + return 1; +} + +sub rep_prog +{ + print "Repeat reprogramming? [y/N]: "; + my $answer = ; + chomp $answer; + + return 0 if $answer eq "" || $answer eq "n" || $answer eq "N"; + return 1; +} + + +sub doStartSh +{ + my $currentWd = Cwd::cwd(); + chdir("/d/jspc37/mimosis/scripts"); + system("/d/jspc37/mimosis/scripts/start.sh"); + chdir($currentWd); + +# Mimosis::mimosis_trb_reset(); +# Mimosis::mimosis_trb_word_align(); +} + +my $proxyType = "S"; # Acceptable values: "F" for Frankfurt and "S" for Strasbourg, not implemented yet: "P" for probe station +my $fpgalink = 0xa000; +my $peer = "192.168.0.56"; +my $port = "5025"; +my $bbCh = 2; + +my $SoftwareVersion = "v0.85"; + +my $ZeroElectronVPHSetting = 95; +my $singleaccessmode = 0; # std: 0 +my $slow = 100; +my $slow2 = 100000; +my $adcSlow = 100000; +my $vphStepSize = 5; + +my $mimVersion = "M21"; # or "M21"; + +my $modFound; + +my %fineVCASNParams = (); + +Mimosis::set_fpga($fpgalink); +Mimosis::set_printall(0); + +if ($proxyType eq "F") { + Mimosis::set_adcToIkfProxy(); +} + +# my $fpgalink = 0xa100; +# my $peer = "192.168.0.56"; +# my $port = "5050"; +# my $bbCh = 3; +# Mimosis::set_adcToIkfProxy(); +Mimosis::set_singleAccess($singleaccessmode); + +my $sensorname; +my $workenv = "/d/jspc37/mimosis/scripts/qa/"; +my $backbias; +my %file; # Hash where everything gets stored before written to file +my $irraddeg; +my $adc_addr = 0x48; +my $adc_wreg = 0x1; +my $adc_cmd_powering = 0xf380; +my $adc_cmd_powering_ana = 0xc380; +my $adc_rreg = 0x0; +# my $adcConv = ( 2 * 4096 ) / (2**16 * 10); +my $settingsDACRegTest = "/d/jspc37/mimosis/scripts/conf/CONF_DACRegisterTest.pl"; + +my $VPHFSlope; +my $VPHOffsetElectron; +imy $VPHOffset; + + my %matrixParams = ( + A => { + VCASN => 0x48, + YSPAN => 4, + XSTART => 0, + XSTOP => 127, + }, + B => { + VCASN => 0x49, + YSPAN => 2, + XSTART => 128, + XSTOP => 511, + }, + C => { + VCASN => 0x4a, + YSPAN => 2, + XSTART => 512, + XSTOP => 894, + }, + D => { + VCASN => 0x4b, + YSPAN => 4, + XSTART => 895, + XSTOP => 1023, + }, + ); + +my %DACList = ( + IBIAS => { ADDR => 0x40, MONITOR => 0x25, MONVAL => 1, TYPE => 'CURRENT', RESET => 0x40, }, + ITHR => { ADDR => 0x41, MONITOR => 0x25, MONVAL => 3, TYPE => 'CURRENT', RESET => 0x34, }, + IDB => { ADDR => 0x42, MONITOR => 0x25, MONVAL => 2, TYPE => 'CURRENT', RESET => 0x1c, }, + VRESET => { ADDR => 0x43, MONITOR => 0x26, MONVAL => 6, TYPE => 'VOLTAGE', RESET => 0xab, }, + VPL => { ADDR => 0x44, MONITOR => 0x26, MONVAL => 2, TYPE => 'VOLTAGE', RESET => 0x57, }, + VPH => { ADDR => 0x45, MONITOR => 0x26, MONVAL => 1, TYPE => 'VOLTAGE', RESET => 0x68, }, + VPHFINE => { ADDR => 0x46, MONITOR => 0x26, MONVAL => 1, TYPE => 'VOLTAGE', RESET => 0x0, }, + VCASP => { ADDR => 0x47, MONITOR => 0x26, MONVAL => 4, TYPE => 'VOLTAGE', RESET => 0x43, }, + VCASNA => { ADDR => 0x48, MONITOR => 0x26, MONVAL => 7, TYPE => 'VOLTAGE', RESET => 0x53, }, + VCASNB => { ADDR => 0x49, MONITOR => 0x26, MONVAL => 8, TYPE => 'VOLTAGE', RESET => 0x53, }, + VCASNC => { ADDR => 0x4a, MONITOR => 0x26, MONVAL => 9, TYPE => 'VOLTAGE', RESET => 0x53, }, + VCASND => { ADDR => 0x4b, MONITOR => 0x26, MONVAL => 10, TYPE => 'VOLTAGE', RESET => 0x53, }, + VCASN2 => { ADDR => 0x4c, MONITOR => 0x26, MONVAL => 3, TYPE => 'VOLTAGE', RESET => 0x53, }, + VCLIP => { ADDR => 0x4d, MONITOR => 0x26, MONVAL => 5, TYPE => 'VOLTAGE', RESET => 0x32, }, + IBUFBIAS => { ADDR => 0x4e, MONITOR => undef, MONVAL => undef, TYPE => 'CURRENT', RESET => 0x7d, }, + ); + + +printf("Using %x\n", $fpgalink); + +sub logtoFile +{ + my $filename = "resultstest.db"; + my $stringToBeWritten = @_[0]; + $stringToBeWritten = $stringToBeWritten . "\n"; + + my $currentWd = Cwd::cwd(); + chdir($workenv . $sensorname); + open(FH, '>>', $filename) or die $!; + print FH $stringToBeWritten; + close(FH); + + chdir( $currentWd ); + +} + +sub findMod +{ + print "\n"; + print "#############################################################################\n"; + print "### Find Mod ###\n"; + print "#############################################################################\n"; + print "\n"; + + Mimosis::mimosis_pulse( + ystart => 250, + ystop => 253, + yspan => 4, + xstart => 0, + xstop => 127, + modexp => 3, + ); + + print("Press enter, if pulsing found on Matrix A.\n"); + ; + + $modFound = Mimosis::mimosis_find_mod( + Mimosis::get_mbsStream() , + $fpgalink, + 250, 253, 0, 127, 3) unless defined $modFound; +} + + + +trb_init_ports() or die trb_strerror(); + +print "\n"; +print "############################################################################\n"; +print "### INIT ###\n"; +print "############################################################################\n"; +print "\n"; + + +# Perform loop until a good name is found, +# i.e. it has never been assigned or is not empty +while ( 1 ) { + + print "Enter the sensor name: "; + $sensorname = ; + chomp $sensorname; + + # Check for bad names + if (-d $sensorname or $sensorname eq "") { + + print "Sensor name already chosen or illegal. Choose new one...\n"; + + } else { + + mkdir($sensorname); + last; + } +} + + +# Trap sig int +$SIG{INT} = sub { +# +# open(RESULTS_FH, '>', "results.db") or die $!; +# print RESULTS_FH "$_\t$file{$_}\n" foreach (keys %file); +# close RESULTS_FH; + die "\nAbort.\n" +}; + +logtoFile("SensorName\t$sensorname"); +logtoFile("SoftwareVersion\t$SoftwareVersion"); +logtoFile("ProxyType\t$proxyType"); + +# $file{"SensorName"} = $sensorname; + +# $file{"SoftwareVersion"} = $SoftwareVersion; + +# $file{"ProxyType"} = $proxyType; + + +while ( 1 ) { + + print "TID dose [kRad]: "; + $irraddeg = ; + chomp $irraddeg; + + # Check if numeric and within good current range + if ($irraddeg =~ /^\d{1,4}$/ ) { + last; + } elsif ($irraddeg eq "") { + $irraddeg = 1000; + last; + } else { + print "Invalid value (letters).\n"; + } +} + + +do { + my $socket = IO::Socket::INET->new( + PeerAddr => $peer, + PeerPort => $port, + Proto => "tcp", + Type => SOCK_STREAM ) + or die "ERROR: Cannot connect: $@"; + + usleep 1e5; print $socket "INST OUT$bbCh\n"; + usleep 1e5; print $socket "MEAS:VOLT?\n"; + $backbias = <$socket>; + chomp $backbias; + $backbias = 1000 * $backbias; + print "Back bias: $backbias mV\n"; + +} while ask_continue(); + + +sub bb_test { + + + print "\n"; + print "#############################################################################\n"; + print "### BB TEST ###\n"; + print "#############################################################################\n"; + print "\n"; + + open(BB_FH, '>', $sensorname . "/bb.csv") or die $!; + + do { + my $socket = IO::Socket::INET->new( + PeerAddr => $peer, + PeerPort => $port, + Proto => "tcp", + Type => SOCK_STREAM, + ) + or die "ERROR: Cannot connect: $@"; + + # Save current BB seting for later + usleep 1e0; print $socket "INST OUT$bbCh\n"; + usleep 1e5; print $socket "MEAS:VOLT?\n"; + my $tmp = <$socket>; + chomp $tmp; + + for (my $i = 0; $i <= 6.0; $i += 0.5) { + + usleep 1e6; print $socket "VOLT $i\n"; + usleep 1e6; print $socket "MEAS:VOLT?\n"; my $volt = <$socket>; + usleep 1e6; print $socket "MEAS:CURR?\n"; my $curr = <$socket>; + + chomp $volt; + chomp $curr; + + print BB_FH "$volt\t$curr\n"; + print("Backbias: $volt, current: $curr \n"); + if ( ($curr > 0.01 and $irraddeg == 0) or ($curr > 0.02 and $irraddeg > 0)) { + die "Maximum backbias current exceeded!"; + } + } + + # Reset BB to what it was before + usleep 1e5; print $socket "VOLT $tmp\n"; + + } while ask_continue(); + + close BB_FH; + +} + +sub powering_tests { + + print "\n"; + print "###########################################################################\n"; + print "### POWERING TEST DIGITAL ###\n"; + print "###########################################################################\n"; + print "\n"; + + #Find out current drawn by sensor on digital and perform data checks. + my $lowleveldig = 100; # Minimum digital current for passing as ok + my $highleveldig = 200; # Maximum digital current for passing as ok + my $digitalcur = 0; + + + do { + + if ($proxyType eq "F") { + + Mimosis::adc_i2c_command( + $adc_addr, + $adc_wreg, + $adc_cmd_powering, + 0, 0, 1 + ); + + usleep($adcSlow); + + $digitalcur = + Mimosis::adc_i2c_command( + $adc_addr, + $adc_rreg, + 0x0, + 1, 0, 1 ); + + usleep($adcSlow); + + $digitalcur *= 1/80; + + } + + else { + + print("Please enter the value on the voltmeter labeled DIGITAL: "); + $digitalcur = ; + chomp $digitalcur; + + } + + # Check if numeric and within good current range + if ( $digitalcur <= $highleveldig && + $digitalcur >= $lowleveldig ) + { + logtoFile("DigitalCurrent\tS\t$digitalcur mA"); +# $file{"Digitalcurrent"} = $digitalcur; + print "Digital current: $digitalcur mA.\n"; + + } else { + logtoFile("DigitalCurrent\tF\t$digitalcur mA"); + print "Digital current not in range: $digitalcur mA.\n"; +# $file{"Digitalcurrent"} = "F"; + } + + } while ask_continue(); + + + + + + print "\n"; + print "############################################################################\n"; + print "### POWERING TEST ANALOG ###\n"; + print "############################################################################\n"; + print "\n"; + + #Find out current drawn by sensor on analog and perform data checks. + my $lowlevelana = 10; # Minimum analog current for passing as ok + my $highlevelana = 35; # Maximum analog current for passing as ok + my $analogcur = 0; + + + do { + + if ($proxyType eq "F") { + + Mimosis::adc_i2c_command( + $adc_addr, + $adc_wreg, + $adc_cmd_powering_ana, + 0, 0, 1 + ); + + usleep($adcSlow); + + $analogcur = + Mimosis::adc_i2c_command( + $adc_addr, + $adc_rreg, + 0x0, + 1, 0, 1 ); + + usleep($adcSlow); + + + $analogcur *= 1 / 800; + + + } + + else { + + print("Please enter the value on the voltmeter labeled ANALOG: "); + $analogcur = ; + chomp $analogcur; + + } + + # Check if numeric and within good current range + if( $analogcur <= $highlevelana && + $analogcur >= $lowlevelana ) + { + logtoFile("AnalogCurrent\tS\t$analogcur mA"); +# $file{"Analogcurrent"} = $analogcur; + print "Analog current: $analogcur mA.\n"; + + } else { + logtoFile("AnalogCurrent\tF\t$analogcur mA"); + print "Analog current not in range: $analogcur mA.\n"; +# $file{"Analogcurrent"} = "F"; + } + + } while ask_continue(); + +} + +sub reg_std_addr { + + print "\n"; + print "############################################################################\n"; + print "### REGISTER TEST - STD ADDR ###\n"; + print "############################################################################\n"; + print "\n"; + + my %regliststd = ( + 0x0021 => 0x6e, # TRIMDAC + 0x0029 => 0x11, # PLL + 0x002a => 0x38, # PLLLOCK + 0x002c => 0x15, # SLVSTX + 0x002d => 0x08, # SLVSRX + 0x0043 => 0xab, # VRESET + 0x004e => 0x7d, # IBUFBIAS + ); + + Mimosis::mimosis_instr_write(0xe0); # Send global reset to sensor + usleep($slow2); + + do { + + my $errCt = 0; + + # Mimosis::mimosis_instr_write(0xe0); # Send global reset to sensor + # usleep($slow2); + + while( my ($reg, $val) = each(%regliststd) ) { + + # Get test value + my $testVal = + Mimosis::mimosis_register_read( $reg ); + + # Compare + if ($testVal != $val) { + print("$testVal != $val\n"); + $errCt = $errCt + 1; + } + print("Register $reg, read: $testVal, should be: $val\n") unless $testVal == $val; + +# $file{'Register Read: ' . $reg} = +# $testVal == $val ? "GOOD" : "BAD"; + } + + if ($errCt == 0) { + + print("No problems detected.\n"); +# $file{"Registerread"} = "S"; + logtoFile("RegisterRead\tS"); + + } + + else { + + print("Problems in Register Read test detected.\n"); +# $file{"Registerread"} = "F"; + logtoFile("RegisterRead\tS"); + + } + + } while ask_continue(); + +} + +sub dac_reg_test { +print( Cwd::cwd() ); + + Mimosis::mimosis_load_file( file => $settingsDACRegTest ); + + + do { + chdir("/d/jspc37/mimosis/scripts/qa/dataTrash"); + my $errorCounter = 0; + foreach my $dacToBeMonitored (keys %Mimosis::DAC) { # DAC to be changed + + print("Reading DAC $dacToBeMonitored.\n"); + + my $monval = $Mimosis::DAC{$dacToBeMonitored}{'MONVAL'}; + my $monitor = $Mimosis::DAC{$dacToBeMonitored}{'MONITOR'}; + my $type = $Mimosis::DAC{$dacToBeMonitored}{'TYPE'}; + + if ($dacToBeMonitored ne 'IBUFBIAS') { + + foreach my $dacToBeChanged (keys %Mimosis::DAC) { + + my $trueMonVal = $DACList{$dacToBeChanged}{'MONVAL'}; + my $trueMonitor = $DACList{$dacToBeChanged}{'MONITOR'}; + my $trueType = $DACList{$dacToBeChanged}{'TYPE'}; + my $dacRegToBeChanged = $DACList{$dacToBeChanged}{'ADDR'}; + + $Mimosis::DAC{$dacToBeChanged}{'MONVAL'} = $monval; + $Mimosis::DAC{$dacToBeChanged}{'MONITOR'} = $monitor; + $Mimosis::DAC{$dacToBeChanged}{'TYPE'} = $type; + + usleep(10000); + + if ($dacToBeMonitored ne $dacToBeChanged && ($dacToBeChanged ne 'IBUFBIAS') && not ($dacToBeMonitored eq 'VPHFINE' && $dacToBeChanged eq 'VPH') ) { + +# print("DAC Monitored: $dacToBeMonitored, monval: $monval, monitor: $monitor, DAC changed: $dacToBeChanged, true monval: $trueMonVal, true monitor: $trueMonitor, monitored monval: $Mimosis::DAC{$dacToBeChanged}{'MONVAL'}, monitored monitor: $Mimosis::DAC{$dacToBeChanged}{'MONITOR'} \n"); + + my %test = Mimosis::mimosis_dacscan( + dacs => [$dacToBeChanged], + start => 195, + stop => 201, + ); + + my $notoverwritten = 1; + + do { + + Mimosis::mimosis_load_file( file => $settingsDACRegTest ); + usleep(10000); + my $val = Mimosis::mimosis_register_read( $dacRegToBeChanged ); + + if ($val == 5) {$notoverwritten = 0;} + + } while $notoverwritten; + + my $res = $test{$dacToBeChanged}{'Y'}[4]; + + my $VphType = 0; + + if ($monitor == 0x26 && ($monval == 1 || $monval == 2 || $monval == 6) ) { + $VphType = 1; + } + + if (($res < 8000) and (($res > 650 && $VphType == 1) or ($res > 100 && $VphType == 0)) ) { + $errorCounter = $errorCounter + 1; + print("Problem! Dac monitored: $dacToBeMonitored \t DAC changed: $dacToBeChanged\t Voltage: $res \n"); + } + + } + + $Mimosis::DAC{$dacToBeChanged}{'MONVAL'} = $trueMonVal; + $Mimosis::DAC{$dacToBeChanged}{'MONITOR'} = $trueMonitor; + $Mimosis::DAC{$dacToBeChanged}{'TYPE'} = $trueType; + usleep(10000); + + } + + } + + } + + chdir("/d/jspc37/mimosis/scripts/qa"); +# print("$errorCounter \n"); + if ($errorCounter <= 0) {logtoFile("DACRWTest\tS");} + else {logtoFile("DACRWTest\tF");} +# $file{'DAC Reg R/W Test: '} = +# ($errorCounter <= 0) ? "GOOD" : "BAD"; + $errorCounter <= 0 ? print("DAC REG TEST GOOD\n") : print("DAC REG TEST BAD\n"); + } while ask_continue(); + +} + +sub std_rw_test { + + print "\n"; + print "############################################################################\n"; + print "### REGISTER TEST - STD R&W ###\n"; + print "############################################################################\n"; + print "\n"; + + + # Test of read/write operation + + my %reglistgenconfrw = ( + 0x0020 => 0x02, # RUNMODE + 0x0025 => 0x00, # MONCURR + 0x0026 => 0x00, # MONVOLT + 0x0027 => 0x00, # CLKGEN1 + 0x0028 => 0x00, # CLKGEN2 + 0x0029 => 0x11, # PLL + 0x002a => 0x38, # PLLLOCK + 0x002c => 0x15, # SLVSTX + 0x002d => 0x08, # SLVSRX + 0x002e => 0x00, # OUTPUT + ); + + my %testwordsgenconfrw = ( + 0x00, + 0xff, + 0xaa, + 0x55, + 0xdb, + 0x44, + 0xcd, + 0x85, + ); + + + do { + + my $errCt = 0; + + while( my ($reg, $val) = each(%reglistgenconfrw) ) { + + # Save original value into register + my $tmp = Mimosis::mimosis_register_read( + #$fpgalink, + $reg, + ); #usleep($slow2); # + + while (my $testword = each(%testwordsgenconfrw)) { + + # Write test value + Mimosis::mimosis_register_write( + #$fpgalink, + $reg, + $testword, + ); #usleep($slow2); # write value into register + + # Get test value + my $testVal = Mimosis::mimosis_register_read( + #$fpgalink, + $reg, + ); #usleep($slow2); # + + + + # Compare + #print("$testVal != $testword\n") unless $testVal == $testword; + if ($testVal != $testword) { + print("$testVal != $testword\n"); + $errCt = $errCt + 1; + } + } + + # Write original value back into register + Mimosis::mimosis_register_write( + #$fpgalink, + $reg, + $tmp, + ); #usleep($slow2); + } + + if ($errCt == 0) { + + print("No problems detected.\n"); +# $file{"RegisterRW"} = "S"; + logtoFile("RegisterRW\tS"); + + } + + else { + + print("Problems in Register R/W test detected.\n"); +# $file{"RegisterRW"} = "F"; + logtoFile("RegisterRW\tF"); + + } + + } while ask_continue(); + +} + +sub chip_id { + + print "\n"; + print "#############################################################################\n"; + print "### CHIPID TEST ###\n"; + print "#############################################################################\n"; + print "\n"; + + + my @chipids = ( 0x0, 0x1 ); #, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 ); + + my $gpioReg = 0xd580; + my $testreg = 0x0020; # Pixel control register for testing + my $testval = 0x1; + my $shouldKill = 0; + my $errCt = 0; + my $potGold = 1; + my $idNotWorking = 0xA; + + do { + foreach my $id (@chipids) { + + # Reset all + my $bitmaskClear = 0x1 << 30; + + trb_register_clearbit( + $fpgalink, + $gpioReg, + $bitmaskClear + ); + + usleep($slow2); + + # Set desired bits + my $bitmaskSet = $id << 30; + + trb_register_setbit( + $fpgalink, + $gpioReg, + $bitmaskSet + ); usleep($slow2); + + Mimosis::set_chipid($id); + + my $tmp = + Mimosis::mimosis_register_read( + $testreg, + ); + + usleep($slow2); + + Mimosis::mimosis_register_write( + $testreg, + $testval, + ); + + usleep(100000); + + my $testTmp = + Mimosis::mimosis_register_read( + $testreg, + ); + + usleep($slow2); + + if ( (( $testTmp & 0xff ) != $testval ) && $id == 0x0 ) { + + $potGold = 0; + + } + + if ( ( $testTmp & 0xff ) != $testval ) { + + print "Chip-ID $id not working.\n"; + #$file{"CHIP-ID_$id"} = "F"; + $shouldKill += 1; + $errCt = $errCt + 1; + $idNotWorking = $id; + + } else { + + print "Chip-ID $id good.\n"; + } + } + + if ($potGold == 1 && $errCt == 0) { + + print("No problems detected.\n"); +# $file{"ChipIDTest"} = "1"; + logtoFile("ChipIDTest\t1"); + + } + + elsif ($errCt == 1) { + +# $file{"ChipIDTest"} = "2\t$idNotWorking"; + logtoFile("ChipIDTest\t2\t$idNotWorking"); + + } + + else { + + print("Problems in chip ID test detected.\n"); +# $file{"ChipIDTest"} = "F"; + logtoFile("ChipIDTest\tF"); + + } + } while ask_continue(); + + # die "Found broken chip ids. Exiting.\n" if $shouldKill; + + # Reset chipid to 0x1 + Mimosis::set_chipid(0x1); + + trb_register_setbit( + $fpgalink, + $gpioReg, + 0x1 << 30 + ); + + usleep($slow2); + + #system("./../start.sh"); + #sleep(2); + +} + +sub link_test { + + print "\n"; + print "############################################################################\n"; + print "### LINK TEST ###\n"; + print "############################################################################\n"; + print "\n"; + + do { + doStartSh(); + } while rep_prog(); + + do { + +# my $cntBadLinks = 0; +# +# for my $i (0 .. 7) { +# +# my $reg = trb_register_read( $fpgalink, 0xa000 + $i ); +# $reg = ( $reg->{$fpgalink} & 0x7f00 ) >> 8; +# +# $cntBadLinks += 1 if $reg >= 70; +# +# $file{"Link_$i"} = $reg >= 70 ? "$reg\tBAD" : "$reg\tGOOD"; +# } +# +# # die "Bad links. Exiting.\n" if $cntBadLinks > 0; +# print "Bad links.\n" if $cntBadLinks > 0; + + trb_init_ports() or die trb_strerror(); + my $reg0 = trb_register_read( $fpgalink, 0xa000 ); + $reg0 = ( $reg0->{$fpgalink} & 0x7f00 ) >> 8; + + my $reg1 = trb_register_read( $fpgalink, 0xa001 ); + $reg1 = ( $reg1->{$fpgalink} & 0x7f00 ) >> 8; + + my $reg2 = trb_register_read( $fpgalink, 0xa002 ); + $reg2 = ( $reg2->{$fpgalink} & 0x7f00 ) >> 8; + + my $reg3 = trb_register_read( $fpgalink, 0xa003 ); + $reg3 = ( $reg3->{$fpgalink} & 0x7f00 ) >> 8; + + my $reg4 = trb_register_read( $fpgalink, 0xa004 ); + $reg4 = ( $reg4->{$fpgalink} & 0x7f00 ) >> 8; + + my $reg5 = trb_register_read( $fpgalink, 0xa005 ); + $reg5 = ( $reg5->{$fpgalink} & 0x7f00 ) >> 8; + + my $reg6 = trb_register_read( $fpgalink, 0xa006 ); + $reg6 = ( $reg6->{$fpgalink} & 0x7f00 ) >> 8; + + my $reg7 = trb_register_read( $fpgalink, 0xa007 ); + $reg7 = ( $reg7->{$fpgalink} & 0x7f00 ) >> 8; + + if ($reg4 >= 30) { + + print("Max 1 Link. Sensor rated faulty.\n"); +# $file{"LinkTest"} = "F"; + logtoFile("LinkTest\tF"); + + } + + elsif ($reg2 >= 30 or $reg6 >= 30) { + + print("Max 2 Links. Sensor rated bronze wrt link tests.\n"); +# $file{"LinkTest"} = "3"; + logtoFile("LinkTest\t3"); + + } + + elsif ($reg1 >= 30 or $reg3 >= 30 or $reg5 >= 30 or $reg7 >= 30) { + + print("Max 4 Links. Sensor rated silver wrt link tests.\n"); +# $file{"LinkTest"} = "2"; + logtoFile("LinkTest\t2"); + + } + + else { + + print("All 8 Links available. Sensor rated gold wrt link tests.\n"); +# $file{"LinkTest"} = "1"; + logtoFile("LinkTest\t1"); + + } + + } while ask_continue(); + +} + + +sub fast_dac_scan { + + print "\n"; + print "############################################################################\n"; + print "### FAST DACSCAN TEST ###\n"; + print "############################################################################\n"; + print "\n"; + + + chdir($sensorname); + mkdir("DACScan"); + chdir("DACScan"); + + do { + my @DACFAST = ('VPH', 'VPL', 'VPHFINE'); + + my %results = Mimosis::mimosis_dacscan( + dacs => \@DACFAST, + step => 10, + ); + + + my $picName = "fastdacscan.png"; + + my $chart = Chart::Gnuplot->new( + output => $picName, + terminal => "pngcairo", + title => "DAC-Scan", + xlabel => "Setting [LSB]", + ylabel => "Voltage output [mV]", + ); + + + my @dataArr; + + $chart->polygon( + vertices => [ + "0, 1100", + "250, 1290", + "250, 1115", + "0, 900", + "0, 1000", + ], + fill => { + density => 0.3, + color => "#A9A9A0", + }, + ); + + $chart->polygon( + vertices => [ + "0, 370", + "250, 1950", + "250, 1670", + "0, 320", + "0, 370", + ], + fill => { + density => 0.3, + color => "#A9A9A0", + }, + ); + + for my $dac ( keys %results ) { + + my $dataSet = Chart::Gnuplot::DataSet->new( + xdata => $results{$dac}{X}, + ydata => $results{$dac}{Y}, + title => "Plotting a line from Perl arrays", + style => "linespoints", + ); + + push(@dataArr, $dataSet); + } + + $chart->plot2d(@dataArr); + + system("display $picName"); + + chdir(".."); + + + print "Please enter rapid DAC scan result classification.\n"; + print "S = satisfactory if in grey areas\n"; + print "F = unsatisfactory and exiting.\n"; + + while ( 1 ) { + + print "Rapid DAC scan classification: "; + my $rapiddacclass = ; + chomp $rapiddacclass; + + if ( $rapiddacclass eq "S" || + $rapiddacclass eq "s" ) { + +# $file{"RapidDACTest"} = "S"; + logtoFile("RapidDACTest\tS"); + last; + + } elsif ( $rapiddacclass eq "F" || + $rapiddacclass eq "f" ) { + +# $file{"RapidDACTest"} = "F"; + logtoFile("RapidDACTest\tF"); + exit 0; + + } else { + print "Invalid classification. Try again.\n"; + } + } + + } while ask_continue(); + +} + +sub full_dac_scan { + + print "\n"; + print "############################################################################\n"; + print "### DACSCAN TEST ###\n"; + print "############################################################################\n"; + print "\n"; + + chdir($sensorname); + chdir("DACScan"); + + do { + my %names = ( + 'IBIAS' => 0x0040, + 'ITHR' => 0x0041, + 'IDB' => 0x0042, + 'VRESET' => 0x0043, + 'VPL' => 0x0044, + 'VPH' => 0x0045, + 'VPHFINE' => 0x0046, + 'VCASP' => 0x0047, + 'VCASNA' => 0x0048, + 'VCASNB' => 0x0049, + 'VCASNC' => 0x004a, + 'VCASND' => 0x004b, + 'VCASN2' => 0x004c, + 'VCLIP' => 0x004d, + # 'IBUFBIAS' => 0x004e, + ); + + print("Performing DAC scans. This may take a minute...\n"); + + my %dacVals = Mimosis::mimosis_dacscan( + # step => 50, + ); + + + my @VPHList = @{$dacVals{'VPH'}{'Y'}}; + my @VPLList = @{$dacVals{'VPL'}{'Y'}}; + my @VPHFINEList = @{$dacVals{'VPHFINE'}{'Y'}}; + my @VRESETList = @{$dacVals{'VRESET'}{'Y'}}; + my @VCASNAList = @{$dacVals{'VCASNA'}{'Y'}}; + my @VCASNBList = @{$dacVals{'VCASNB'}{'Y'}}; + my @VCASNCList = @{$dacVals{'VCASNC'}{'Y'}}; + my @VCASNDList = @{$dacVals{'VCASND'}{'Y'}}; + my @VCASN2List = @{$dacVals{'VCASN2'}{'Y'}}; + my @VCLIPList = @{$dacVals{'VCLIP'}{'Y'}}; + my @VCASPList = @{$dacVals{'VCASP'}{'Y'}}; + my @IBIASList = @{$dacVals{'IBIAS'}{'Y'}}; + my @ITHRList = @{$dacVals{'ITHR'}{'Y'}}; + my @IDBList = @{$dacVals{'IDB'}{'Y'}}; + + + my $picName = "full-dacscan.png"; + + my $chartPng = Chart::Gnuplot->new( + output => $picName, + terminal => "pngcairo", + title => "DAC-Scan", + xlabel => "Setting [LSB]", + ylabel => "Voltage output [mV]", + ); + + my @dataArr; + + for my $dac ( keys %dacVals) { + + my $dataSet = Chart::Gnuplot::DataSet->new( + xdata => $dacVals{$dac}{X}, + ydata => $dacVals{$dac}{Y}, + title => $dac, + style => "lines", + ); + + push(@dataArr, $dataSet); + } + + $chartPng->plot2d(@dataArr); + + system("display $picName"); + + + for my $i (0 .. scalar( @VPHFINEList ) - 1) { + $VPHFINEList[$i] = $VPHFINEList[$i] - $VPHList[0]; + } + + + my $sensorQuality = 4; + + $VPHOffset = $VPHList[0]; + my $VPLOffset = $VPLList[0]; + my $VRESETOffset = $VRESETList[0]; + my $VPHFOffset = $VPHFINEList[0]; + my $VPH210 = $VPHList[211]; + my $VPL210 = $VPLList[211]; + my $VRESET210 = $VRESETList[211]; + my $VPHF210 = $VPHFINEList[211] - $VPHFOffset; + + my $acceptableVPHOffsetLowerLimit = 300; + my $acceptableVPHOffsetHigherLimit = 430; + my $goodDNLLimit = 1; + my $goodINLLimit = 5; + + + if ( ($acceptableVPHOffsetLowerLimit <= $VPHOffset) && + ($acceptableVPHOffsetHigherLimit >= $VPHOffset) && + ($acceptableVPHOffsetLowerLimit <= $VPLOffset) && + ($acceptableVPHOffsetHigherLimit >= $VPLOffset) && + ($acceptableVPHOffsetLowerLimit <= $VRESETOffset) && + ($acceptableVPHOffsetHigherLimit >= $VRESETOffset) && + ($VPH210 >= 1410) && + ($VPL210 >= 1410) && + ($VRESET210 >= 1410) && + ($VPHF210 >= 180) ) { + + $sensorQuality = 3; + + if ( max(@VCASNAList) > 1100 && + max(@VCASNBList) > 1100 && + max(@VCASNCList) > 1100 && + max(@VCASNDList) > 1100 && + max(@VCASN2List) > 1100 && + max(@VCLIPList) > 550 && + max(@VCASPList) > 550 && + max(@IBIASList) >= 260 && + max(@ITHRList) >= 260 && + max(@IDBList) >= 260 ) { + + $sensorQuality = 2; + + my $arrRef = [ 3,3,3,3 + ]; + + sub calcAbsDNLAbsINL { + + my @dac = @{$_[0]}; + + my $gain = ($dac[199] - $dac[24]) / 175.0; + + my @dnl = ( 0 ); + my @inl = ( 0 ); + + for my $i (21 .. 201) { + + my $currentDNL = ( ($dac[$i] - $dac[$i-1]) / $gain ) - 1; + push(@dnl, $currentDNL); + push(@inl, $inl[$i-21]+$currentDNL); + } + + @dnl = reverse @dnl; + @inl = reverse @inl; + return ( \@inl, \@dnl ); + } + + + my ( $ibiasinlRef, $ibiasdnlRef ) = calcAbsDNLAbsINL(\@IBIASList); + my @IBIASINL = @{$ibiasinlRef}; + my @IBIASDNL = @{$ibiasdnlRef}; + + my ( $ithrinlRef, $ithrdnlRef ) = calcAbsDNLAbsINL(\@ITHRList); + my @ITHRINL = @{$ithrinlRef}; + my @ITHRDNL = @{$ithrdnlRef}; + + my ( $idbinlRef, $idbdnlRef ) = calcAbsDNLAbsINL(\@IDBList); + my @IDBINL = @{$idbinlRef}; + my @IDBDNL = @{$idbdnlRef}; + + my ( $vphinlRef, $vphdnlRef ) = calcAbsDNLAbsINL(\@VPHList); + my @VPHINL = @{$vphinlRef}; + my @VPHDNL = @{$vphdnlRef}; + + my ( $vplinlRef, $vpldnlRef ) = calcAbsDNLAbsINL(\@VPLList); + my @VPLINL = @{$vplinlRef}; + my @VPLDNL = @{$vpldnlRef}; + + my ( $vresetinlRef, $vresetdnlRef ) = calcAbsDNLAbsINL(\@VRESETList); + my @VRESETINL = @{$vresetinlRef}; + my @VRESETDNL = @{$vresetdnlRef}; + + my ( $vphfineinlRef, $vphfinednlRef ) = calcAbsDNLAbsINL(\@VPHFINEList); + my @VPHFINEINL = @{$vphfineinlRef}; + my @VPHFINEDNL = @{$vphfinednlRef}; + + my ( $vcasnainlRef, $vcasnadnlRef ) = calcAbsDNLAbsINL(\@VCASNAList); + my @VCASNAINL = @{$vcasnainlRef}; + my @VCASNADNL = @{$vcasnadnlRef}; + + my ( $vcasnbinlRef, $vcasnbdnlRef ) = calcAbsDNLAbsINL(\@VCASNBList); + my @VCASNBINL = @{$vcasnbinlRef}; + my @VCASNBDNL = @{$vcasnbdnlRef}; + + my ( $vcasncinlRef, $vcasncdnlRef ) = calcAbsDNLAbsINL(\@VCASNCList); + my @VCASNCINL = @{$vcasncinlRef}; + my @VCASNCDNL = @{$vcasncdnlRef}; + + my ( $vcasndinlRef, $vcasnddnlRef ) = calcAbsDNLAbsINL(\@VCASNDList); + my @VCASNDINL = @{$vcasndinlRef}; + my @VCASNDDNL = @{$vcasnddnlRef}; + + my ( $vcasn2inlRef, $vcasn2dnlRef ) = calcAbsDNLAbsINL(\@VCASN2List); + my @VCASN2INL = @{$vcasn2inlRef}; + my @VCASN2DNL = @{$vcasn2dnlRef}; + + my ( $vcaspinlRef, $vcaspdnlRef ) = calcAbsDNLAbsINL(\@VCASPList); + my @VCASPINL = @{$vcaspinlRef}; + my @VCASPDNL = @{$vcaspdnlRef}; + + my ( $vclipinlRef, $vclipdnlRef ) = calcAbsDNLAbsINL(\@VCLIPList); + my @VCLIPINL = @{$vclipinlRef}; + my @VCLIPDNL = @{$vclipdnlRef}; + + my $goodDNL = 0; + + if ( $IBIASDNL[2] < $goodDNLLimit + && $ITHRDNL[2] < $goodDNLLimit + && $IDBDNL[2] < $goodDNLLimit + && $VCASNADNL[2] < $goodDNLLimit + && $VCASNBDNL[2] < $goodDNLLimit + && $VCASNCDNL[2] < $goodDNLLimit + && $VCASNDDNL[2] < $goodDNLLimit + && $VCASN2DNL[2] < $goodDNLLimit + && $VCASPDNL[2] < $goodDNLLimit + && $VCLIPDNL[2] < $goodDNLLimit + && $VPHDNL[2] < $goodDNLLimit + && $VPLDNL[2] < $goodDNLLimit + && $VRESETDNL[2] < $goodDNLLimit + && $VPHFINEDNL[2] < $goodDNLLimit + ) { + $goodDNL = 1; + } + + my $goodINL = 0; + + if ( $IBIASINL[2] < $goodINLLimit + && $ITHRINL[2] < $goodINLLimit + && $IDBINL[2] < $goodINLLimit + && $VCASNAINL[2] < $goodINLLimit + && $VCASNBINL[2] < $goodINLLimit + && $VCASNCINL[2] < $goodINLLimit + && $VCASNDINL[2] < $goodINLLimit + && $VCASN2INL[2] < $goodINLLimit + && $VCASPINL[2] < $goodINLLimit + && $VCLIPINL[2] < $goodINLLimit + && $VPHINL[2] < 2 + && $VPLINL[2] < 2 + && $VRESETINL[2] < 2 + && $VPHFINEINL[2] < 2 + ) { + $goodINL = 1; + } + + if ($goodDNL && $goodINL) { + $sensorQuality = 1; + } + } + } + + $VPHFSlope = ($VPHFINEList[255] - $VPHFINEList[0]) / 255.0; + # $VPHFSlope = 1.; + $VPHOffsetElectron = 150; + $ZeroElectronVPHSetting = 95; + + for my $i (0 .. scalar(@VPHList)) { + + if ( ($VPHList[$i] gt ($VPLList[70] - 6)) # or ($VPHList[$i] lt ($VPLList[70] + 6)) + ) { + + $ZeroElectronVPHSetting = $i; + $VPHOffsetElectron = $VPHList[$i] - $VPLList[70]; + last; + } + } + + print("ZeroSetting\t$ZeroElectronVPHSetting\t$VPHOffsetElectron\n"); + + print("Sensor Quality for DACs: $sensorQuality\n"); + + chdir(".."); + +# $file{"DACQuality"} = $sensorQuality; +# $file{"VPHFSlope"} = $VPHFSlope; +# $file{"VPHSetting0Electrons"} = "$ZeroElectronVPHSetting\t$VPHOffsetElectron"; + + logtoFile("DACQuality\t$sensorQuality"); + logtoFile("VPHFSlope\t$VPHFSlope"); + logtoFile("VPHSetting0Electrons\t$ZeroElectronVPHSetting\t$VPHOffsetElectron"); + + + } while ask_continue(); + + chdir(".."); + +} + +sub fit_thr { + my ($fitterfname, $fittervphOffsetElectron, $fittervphfSlope, $fittervphStepSize, $fittermaxPulse) = @_; + Mimosis::mimosis_make_fit( $fitterfname , $fittervphOffsetElectron, $fittervphfSlope, $fittervphStepSize, $fittermaxPulse); + # system("/usr/bin/python3 /d/jspc37/mimosis/scripts/pulse/fit-raw.py $fname $dirName $vphOffsetElectron $vphfSlope"); +} + +sub scurve_fast_test { + + + my ( $scurvefastVPHOffsetElectron, $scurvefastVPHOffset, $scurvefastVPHFSlope, $scurvefastvphStepSize, $scurvemaxPulse ) = @_; + + chdir($sensorname); + + print "\n"; + print "############################################################################\n"; + print "### FAST SCURVE TEST ###\n"; + print "############################################################################\n"; + print "\n"; + + $matrixParams{'A'}{'LOWERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 95 : + (( $backbias == 1000 && $irraddeg >= 1000 ) ? 60 : (( $backbias == 1000 && $irraddeg == 0 ) ? 70 : (( $backbias == 3000 && $irraddeg == 0 ) ? 110 : 50 ))); + + $matrixParams{'A'}{'UPPERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 120 : + (( $backbias == 1000 && $irraddeg >= 1000 ) ? 100 : (( $backbias == 1000 && $irraddeg == 0 ) ? 115 : (( $backbias == 3000 && $irraddeg == 0 ) ? 165 : 200 ))); + + + $matrixParams{'B'}{'LOWERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 100 : + (( $backbias == 1000 && $irraddeg >= 1000 ) ? 75 : (( $backbias == 1000 && $irraddeg == 0 ) ? 95 : (( $backbias == 3000 && $irraddeg == 0 ) ? 130 : 50 ))); + + $matrixParams{'B'}{'UPPERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 150 : + (( $backbias == 1000 && $irraddeg >= 1000 ) ? 125 : (( $backbias == 1000 && $irraddeg == 0 ) ? 140 : (( $backbias == 3000 && $irraddeg == 0 ) ? 185 : 200 ))); + + + $matrixParams{'C'}{'LOWERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 100 : + (( $backbias == 1000 && $irraddeg >= 1000 ) ? 75 : (( $backbias == 1000 && $irraddeg == 0 ) ? 95 : (( $backbias == 3000 && $irraddeg == 0 ) ? 130 : 50 ))); + + $matrixParams{'C'}{'UPPERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 150 : + (( $backbias == 1000 && $irraddeg >= 1000 ) ? 125 : (( $backbias == 1000 && $irraddeg == 0 ) ? 140 : (( $backbias == 3000 && $irraddeg == 0 ) ? 185 : 200 ))); + + + $matrixParams{'D'}{'LOWERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 95 : + (( $backbias == 1000 && $irraddeg >= 1000 ) ? 60 : (( $backbias == 1000 && $irraddeg == 0 ) ? 75 : (( $backbias == 3000 && $irraddeg == 0 ) ? 115 : 50 ))); + + $matrixParams{'D'}{'UPPERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 120 : + (( $backbias == 1000 && $irraddeg >= 1000 ) ? 100 : (( $backbias == 1000 && $irraddeg == 0 ) ? 140 : (( $backbias == 3000 && $irraddeg == 0 ) ? 180 : 200 ))); + + + do { + chdir("/d/jspc37/mimosis/scripts/qa/" . $sensorname); + my $settingsScurves = "../CONF_scurves.pl"; + + cp($settingsScurves, "$sensorname/$settingsScurves"); + + Mimosis::mimosis_load_file( file => $settingsScurves ); + + Mimosis::mimosis_register_write( + 0x45, + $scurvefastVPHOffset, + ); + + Mimosis::mimosis_register_write( + 0x4d, + int( 45 + $backbias/1000.0 * 12.0 + 0.5 ), + ); + + Mimosis::mimosis_register_write( + 0x4c, + 180, + ); + + Mimosis::mimosis_register_write(0x46, 255); + Mimosis::mimosis_register_write(0x45, $scurvefastVPHOffset); + Mimosis::mimosis_register_write(0x44, 70); + + if ($mimVersion eq "M21") { + + Mimosis::mimosis_register_write(0x0063, 1); # DPSTARTA LSB + Mimosis::mimosis_register_write(0x0073, 2); # DPSTARTB LSB + Mimosis::mimosis_register_write(0x0064, 2); # DPTOKENA LSB + Mimosis::mimosis_register_write(0x0074, 3); # DPTOKENB LSB + Mimosis::mimosis_register_write(0x0065, 99); # DPENDA LSB + Mimosis::mimosis_register_write(0x0075, 100); # DPENDB LSB + + print("MIMOSIS 2.1\n") + + } + + + print "Press Enter, to start pulsing.\n"; + ; + + + foreach my $matrix ( sort keys %matrixParams ) { + + Mimosis::mimosis_load_file( file => $settingsScurves ); + + Mimosis::mimosis_register_write( + 0x45, + $scurvefastVPHOffset, + ); + + Mimosis::mimosis_register_write( + 0x4d, + int( 45 + $backbias/1000.0 * 12.0 + 0.5 ), + ); + + Mimosis::mimosis_register_write( + 0x4c, + 180, + ); + + Mimosis::mimosis_register_write(0x46, 255); + Mimosis::mimosis_register_write(0x45, $scurvefastVPHOffset); + Mimosis::mimosis_register_write(0x44, 70); + + my $yspan = $matrixParams{$matrix}{'YSPAN'}; + my $xstart = $matrixParams{$matrix}{'XSTART'}; + my $xstop = $matrixParams{$matrix}{'XSTOP'}; + + Mimosis::mimosis_instr_write( 0x3f ); + Mimosis::mimosis_instr_write( 0x04 ); + Mimosis::mimosis_instr_write( 0x3e ); + + Mimosis::mimosis_pulse( + ystart => 250, + ystop => 253, + yspan => $yspan, + xstart => $xstart, + xstop => $xstop, + modexp => 3, + ); + +# $modFound = Mimosis::mimosis_find_mod( Mimosis::get_mbsStream() , $fpgalink, 250, 253, $xstart, $xstop, 3) unless defined $modFound; + + my $ll = $matrixParams{$matrix}{'LOWERLIMIT'}; + my $ul = $matrixParams{$matrix}{'UPPERLIMIT'}; + + print "Find proper VCASN in Go4. Suggested range: $ll - $ul\n"; + + my $foundF = 0; + + while ( 1 ) { + + print "Enter the appropriate VCASN$matrix value or \'F\' if bad: " ; + + my $vcasnTmp = ; + chomp $vcasnTmp; + + if ( $vcasnTmp eq "F" or + $vcasnTmp eq "f" ) { + +# $file{"CoarseSCurves,MATRIX-$matrix"} = "F"; + logtoFile("CoarseSCurves,MATRIX-$matrix\tF"); + + $foundF = 1; + last; + + } else { + +# $file{"CoarseSCurves,MATRIX-$matrix"} = $vcasnTmp; + logtoFile("CoarseSCurves,MATRIX-$matrix\t$vcasnTmp"); + $matrixParams{$matrix}{"VCASNCOARSE"} = $vcasnTmp; + last; + } + } + + exit 0 if $foundF; + } + + + + print "Press Enter, to start scuves\n"; + ; + + foreach my $matrix ( sort keys %matrixParams ) { + + + Mimosis::mimosis_register_write(0x46, 255); + Mimosis::mimosis_register_write(0x45, $scurvefastVPHOffset); + Mimosis::mimosis_register_write(0x44, 70); + + if ($matrix eq "A") { + + Mimosis::mimosis_register_write(0x49, 1); + Mimosis::mimosis_register_write(0x4A, 1); + Mimosis::mimosis_register_write(0x4B, 1); + } + + if ($matrix eq "B") { + + Mimosis::mimosis_register_write(0x48, 1); + Mimosis::mimosis_register_write(0x4A, 1); + Mimosis::mimosis_register_write(0x4B, 1); + } + + if ($matrix eq "C") { + + Mimosis::mimosis_register_write(0x48, 1); + Mimosis::mimosis_register_write(0x49, 1); + Mimosis::mimosis_register_write(0x4B, 1); + } + + if ($matrix eq "D") { + + Mimosis::mimosis_register_write(0x48, 1); + Mimosis::mimosis_register_write(0x49, 1); + Mimosis::mimosis_register_write(0x4A, 1); + } + + my $matrixDir = "MATRIX-" . $matrix; + mkdir($matrixDir); + chdir($matrixDir); + + my $yspan = $matrixParams{$matrix}{'YSPAN'}; + my $xstart = $matrixParams{$matrix}{'XSTART'}; + my $xstop = $matrixParams{$matrix}{'XSTOP'}; + my $vcasnstart = $matrixParams{$matrix}{"VCASNCOARSE"} - 5; # - 6; #-5 + my $vcasnstop = $matrixParams{$matrix}{"VCASNCOARSE"} + 5; # 3+ 3; #+5 + + Mimosis::mimosis_scurves( + ystart => 250, + ystop => 253, + yspan => $yspan, + xstart => $xstart, + xstop => $xstop, + vcasnreg => 'VCASN' . $matrix, + vcasnstart => $vcasnstart, + vcasnstop => $vcasnstop, + # vcasnstep => 2, + setstep => $scurvefastvphStepSize, + setcount => $scurvemaxPulse, + modfound => $modFound, + ); + + opendir my $dir, "." or die "Cannot open directory: $!"; + my @files = readdir $dir; + + foreach my $f ( @files ) { + + if ( $f =~ /VCASN/ ) { + + my $dirName = Cwd::cwd() . "/$f"; + + chdir($dirName); + + $matrixParams{$matrix}{"THREAD"} = + fit_thr( + "$dirName/$f.csv", + $scurvefastVPHOffsetElectron, + $scurvefastVPHFSlope, + $scurvefastvphStepSize, + $scurvemaxPulse ); + + chdir(".."); + } + } + + closedir $dir; + chdir(".."); + } + + + + + print "Wait for fits to finish.\n"; + + + print("Approximate a VCASN for each submatrix where the GMDT is closest to 150 e!\n"); + + my $foundF = 0; + + foreach my $matrix ( sort keys %matrixParams ) { + + while ( 1 ) { + + print "Enter the appropriate VCASN$matrix value or \'F\' if bad: " ; + + my $vcasnTmp = ; + chomp $vcasnTmp; + + if ( $vcasnTmp eq "F" or + $vcasnTmp eq "f" ) { + +# $file{"RapidSCurves,MATRIX-$matrix"} = "F"; + logtoFile("RapidSCurves,MATRIX-$matrix\tF"); + + $foundF = 1; + last; + + } else { + +# $file{"SCurvesFull,MATRIX-$matrix"} = $vcasnTmp; + logtoFile("SCurvesFull,MATRIX-$matrix\t$vcasnTmp"); + $matrixParams{$matrix}{"VCASNFINAL"} = $vcasnTmp; + last; + } + } + } + if ( $foundF ) { exit 0; } + + } while ask_continue(); + +} + +sub scurve_full_test { + + my ( $scurvefullVPHOffsetElectron, $scurvefullVPHOffset, $scurvefullVPHFSlope, $scurvefullvphStepSize, $scurvemaxPulse ) = @_; + + chdir($sensorname); + mkdir("FinalSCurves"); + chdir("FinalSCurves"); + + print "\n"; + print "############################################################################\n"; + print "### FULL SCURVE TEST ###\n"; + print "############################################################################\n"; + print "\n"; + + do { + my $settingsScurves = "../CONF_scurves.pl"; + + cp($settingsScurves, "$sensorname/$settingsScurves"); + + Mimosis::mimosis_load_file( file => $settingsScurves ); + + + Mimosis::mimosis_register_write( + 0x45, + $scurvefullVPHOffset, + ); + + Mimosis::mimosis_register_write( + 0x4d, + int( 45 + $backbias/1000.0 * 12.0 + 0.5 ), + ); + + Mimosis::mimosis_register_write( + 0x4c, + 180, + ); + + Mimosis::mimosis_register_write(0x46, 255); + Mimosis::mimosis_register_write(0x45, $scurvefullVPHOffset); + Mimosis::mimosis_register_write(0x44, 70); + + + + print "Press Enter, to start scuves\n"; + ; + + foreach my $matrix ( sort keys %matrixParams ) { + + Mimosis::mimosis_register_write(0x46, 255); + Mimosis::mimosis_register_write(0x45, $scurvefullVPHOffset); + Mimosis::mimosis_register_write(0x44, 70); + + if ($matrix eq "A") { + + Mimosis::mimosis_register_write(0x49, 1); + Mimosis::mimosis_register_write(0x4A, 1); + Mimosis::mimosis_register_write(0x4B, 1); + } + + if ($matrix eq "B") { + + Mimosis::mimosis_register_write(0x48, 1); + Mimosis::mimosis_register_write(0x4A, 1); + Mimosis::mimosis_register_write(0x4B, 1); + } + + if ($matrix eq "C") { + + Mimosis::mimosis_register_write(0x48, 1); + Mimosis::mimosis_register_write(0x49, 1); + Mimosis::mimosis_register_write(0x4B, 1); + } + + if ($matrix eq "D") { + + Mimosis::mimosis_register_write(0x48, 1); + Mimosis::mimosis_register_write(0x49, 1); + Mimosis::mimosis_register_write(0x4A, 1); + } + + my $matrixDir = "MATRIX-" . $matrix; + mkdir($matrixDir); + chdir($matrixDir); + + my $yspan = $matrixParams{$matrix}{'YSPAN'}; + my $xstart = $matrixParams{$matrix}{'XSTART'}; + my $xstop = $matrixParams{$matrix}{'XSTOP'}; + my $vcasnstart = $matrixParams{$matrix}{"VCASNFINAL"}; + my $vcasnstop = $matrixParams{$matrix}{"VCASNFINAL"} + 1; + + Mimosis::mimosis_scurves( + ystart => 0, + ystop => 503, + yspan => $yspan, + xstart => $xstart, + xstop => $xstop, + vcasnreg => 'VCASN' . $matrix, + vcasnstart => $vcasnstart, + vcasnstop => $vcasnstop, + vcasnstep => 2, + setstep => $scurvefullvphStepSize, + setcount => $scurvemaxPulse, + modfound => $modFound, + ); + + opendir my $dir, "." or die "Cannot open directory: $!"; + my @files = readdir $dir; + + foreach my $f ( @files ) { + + if ( $f =~ /VCASN/ ) { + + my $dirName = Cwd::cwd() . "/$f"; + + chdir($dirName); + + $matrixParams{$matrix}{"THREAD"} = + fit_thr( + "$dirName/$f.csv", + $scurvefullVPHOffsetElectron, + $scurvefullVPHFSlope, + $scurvefullvphStepSize, + $scurvemaxPulse ); + + chdir(".."); + } + } + + closedir $dir; + chdir(".."); + } + + + + + print "Wait for fits to finish.\n"; + + } while ask_continue(); + +} + +do { + +# Mimosis::mimosis_trb_reset(); +# Mimosis::mimosis_trb_word_align(); + doStartSh(); +} while ask_continue(); + +# bb_test(); +# +# powering_tests(); +# +# reg_std_addr(); +# +# do { +# doStartSh(); +# } while rep_prog(); +# +# dac_reg_test(); +# +# do { +# doStartSh(); +# } while rep_prog(); +# +# Mimosis::mimosis_load_file( file => $settingsDACRegTest ); +# +# std_rw_test(); +# +# if ($proxyType eq "F") { +# chip_id(); +# } +# +# link_test(); +# +# do { +# doStartSh(); +# } while rep_prog(); +# +# fast_dac_scan(); + +full_dac_scan(); + +do { + doStartSh(); +} while rep_prog(); + +findMod(); + +scurve_fast_test($VPHOffsetElectron, $ZeroElectronVPHSetting, $VPHFSlope, 5, 100); + +scurve_full_test($VPHOffsetElectron, $ZeroElectronVPHSetting, $VPHFSlope, 5, 100); + + +# open(RESULTS_FH, '>', $sensorname . "/results.db") or die $!; +# print RESULTS_FH "$_\t$file{$_}\n" foreach (keys %file); +# close RESULTS_FH; diff --git a/scripts/qa/QAScript_v09.pl b/scripts/qa/QAScript_v09.pl new file mode 100755 index 0000000..420234d --- /dev/null +++ b/scripts/qa/QAScript_v09.pl @@ -0,0 +1,2109 @@ +#!/usr/bin/perl + +# MIMOSIS-1 QA Script ... version 0.9 +# +# Authors: Benedict Arnoldi-Meadows and Benedikt Gutsche + +use strict; +use warnings; +use HADES::TrbNet; +use Mimosis; +use Time::HiRes qw( usleep ); +use POSIX; +use Data::Dump qw( dump ); +use List::Util qw( min max ); +use threads; +use IO::Handle; +use IO::Socket; +use File::Temp qw( tempfile ); +use File::Copy qw( cp ); +use Cwd qw(); +use Chart::Gnuplot; + +# reassign STDOUT, STDERR +open my $log_fh, '>>', 'log.txt'; +*STDERR = $log_fh; + + +sub ask_continue +{ + print "Repeat test? [y/N]: "; + my $answer = ; + chomp $answer; + + return 0 if $answer eq "" || $answer eq "n" || $answer eq "N"; + return 1; +} + +sub rep_prog +{ + print "Repeat reprogramming? [y/N]: "; + my $answer = ; + chomp $answer; + + return 0 if $answer eq "" || $answer eq "n" || $answer eq "N"; + return 1; +} + + +sub doStartSh +{ +# my $currentWd = Cwd::cwd(); +# chdir("/d/jspc37/mimosis/scripts"); +# system("/d/jspc37/mimosis/scripts/start.sh"); +# chdir($currentWd); + my @vals; + + my $counter = 0; + my $satisfactory = 0; + + do { + Mimosis::mimosis_trb_reset(); + @vals = Mimosis::mimosis_trb_word_align(); + + if ( (($_ & 0xFFFF) == 0xFCAA) foreach (@vals) ) {$satisfactory = 1;} + else {print("Reporgramming sensor...\n");} + $counter += 1; + + } while (($counter < 10) or ($satisfactory == 1)); + +} + +my $proxyType = "S"; # Acceptable values: "F" for Frankfurt and "S" for Strasbourg, not implemented yet: "P" for probe station +my $fpgalink = 0xa000; +my $peer = "192.168.0.56"; +my $port = "5025"; +my $bbCh = 2; + +my $start = 70; +my $end = 170; + +my $SoftwareVersion = "v0.9"; + +my $ZeroElectronVPHSetting = 95; +my $singleaccessmode = 1; # std: 0 +my $slow = 100; +my $slow2 = 100000; +my $adcSlow = 100000; +my $vphStepSize = 5; + +my $mimVersion = "M1"; # or "M21"; + +my $modFound; + +my %fineVCASNParams = (); + +Mimosis::set_fpga($fpgalink); +Mimosis::set_printall(0); + +if ($proxyType eq "F") { + Mimosis::set_adcToIkfProxy(); +} + +# my $fpgalink = 0xa100; +# my $peer = "192.168.0.56"; +# my $port = "5050"; +# my $bbCh = 3; +# Mimosis::set_adcToIkfProxy(); +Mimosis::set_singleAccess($singleaccessmode); + +my $sensorname; +my $workenv = "/d/jspc37/mimosis/scripts/qa/"; +my $backbias; +my %file; # Hash where everything gets stored before written to file +my $irraddeg; +my $adc_addr = 0x48; +my $adc_wreg = 0x1; +my $adc_cmd_powering = 0xf380; +my $adc_cmd_powering_ana = 0xc380; +my $adc_rreg = 0x0; +# my $adcConv = ( 2 * 4096 ) / (2**16 * 10); +my $settingsDACRegTest = "/d/jspc37/mimosis/scripts/conf/CONF_DACRegisterTest.pl"; + +my $VPHFSlope; +my $VPHOffsetElectron; +my $VPHOffset; + + my %matrixParams = ( + A => { + VCASN => 0x48, + YSPAN => 4, + XSTART => 0, + XSTOP => 127, + }, + B => { + VCASN => 0x49, + YSPAN => 2, + XSTART => 128, + XSTOP => 511, + }, + C => { + VCASN => 0x4a, + YSPAN => 2, + XSTART => 512, + XSTOP => 894, + }, + D => { + VCASN => 0x4b, + YSPAN => 4, + XSTART => 895, + XSTOP => 1023, + }, + ); + +my %DACList = ( + IBIAS => { ADDR => 0x40, MONITOR => 0x25, MONVAL => 1, TYPE => 'CURRENT', RESET => 0x40, }, + ITHR => { ADDR => 0x41, MONITOR => 0x25, MONVAL => 3, TYPE => 'CURRENT', RESET => 0x34, }, + IDB => { ADDR => 0x42, MONITOR => 0x25, MONVAL => 2, TYPE => 'CURRENT', RESET => 0x1c, }, + VRESET => { ADDR => 0x43, MONITOR => 0x26, MONVAL => 6, TYPE => 'VOLTAGE', RESET => 0xab, }, + VPL => { ADDR => 0x44, MONITOR => 0x26, MONVAL => 2, TYPE => 'VOLTAGE', RESET => 0x57, }, + VPH => { ADDR => 0x45, MONITOR => 0x26, MONVAL => 1, TYPE => 'VOLTAGE', RESET => 0x68, }, + VPHFINE => { ADDR => 0x46, MONITOR => 0x26, MONVAL => 1, TYPE => 'VOLTAGE', RESET => 0x0, }, + VCASP => { ADDR => 0x47, MONITOR => 0x26, MONVAL => 4, TYPE => 'VOLTAGE', RESET => 0x43, }, + VCASNA => { ADDR => 0x48, MONITOR => 0x26, MONVAL => 7, TYPE => 'VOLTAGE', RESET => 0x53, }, + VCASNB => { ADDR => 0x49, MONITOR => 0x26, MONVAL => 8, TYPE => 'VOLTAGE', RESET => 0x53, }, + VCASNC => { ADDR => 0x4a, MONITOR => 0x26, MONVAL => 9, TYPE => 'VOLTAGE', RESET => 0x53, }, + VCASND => { ADDR => 0x4b, MONITOR => 0x26, MONVAL => 10, TYPE => 'VOLTAGE', RESET => 0x53, }, + VCASN2 => { ADDR => 0x4c, MONITOR => 0x26, MONVAL => 3, TYPE => 'VOLTAGE', RESET => 0x53, }, + VCLIP => { ADDR => 0x4d, MONITOR => 0x26, MONVAL => 5, TYPE => 'VOLTAGE', RESET => 0x32, }, + IBUFBIAS => { ADDR => 0x4e, MONITOR => undef, MONVAL => undef, TYPE => 'CURRENT', RESET => 0x7d, }, + ); + + +printf("Using %x\n", $fpgalink); + +sub logtoFile +{ + my $filename = "results.db"; + my $stringToBeWritten = @_[0]; + $stringToBeWritten = $stringToBeWritten . "\n"; + + my $currentWd = Cwd::cwd(); + chdir($workenv . $sensorname); + open(FH, '>>', $filename) or die $!; + print FH $stringToBeWritten; + close(FH); + + chdir( $currentWd ); + +} + +sub findMod +{ + print "\n"; + print "#############################################################################\n"; + print "### Find Mod ###\n"; + print "#############################################################################\n"; + print "\n"; + + Mimosis::mimosis_pulse( + ystart => 250, + ystop => 253, + yspan => 4, + xstart => 0, + xstop => 127, + modexp => 3, + ); + + print("Press enter, if pulsing found on Matrix A.\n"); + ; + + $modFound = Mimosis::mimosis_find_mod( + Mimosis::get_mbsStream() , + $fpgalink, + 250, 253, 0, 127, 3) unless defined $modFound; +} + + + +trb_init_ports() or die trb_strerror(); + +print "\n"; +print "############################################################################\n"; +print "### INIT ###\n"; +print "############################################################################\n"; +print "\n"; + + +# Perform loop until a good name is found, +# i.e. it has never been assigned or is not empty +while ( 1 ) { + + print "Enter the sensor name: "; + $sensorname = ; + chomp $sensorname; + + # Check for bad names + if (-d $sensorname or $sensorname eq "") { + + print "Sensor name already chosen or illegal. Choose new one...\n"; + + } else { + + mkdir($sensorname); + last; + } +} + + +# Trap sig int +$SIG{INT} = sub { +# +# open(RESULTS_FH, '>', "results.db") or die $!; +# print RESULTS_FH "$_\t$file{$_}\n" foreach (keys %file); +# close RESULTS_FH; + die "\nAbort.\n" +}; + +logtoFile("SensorName\t$sensorname"); +logtoFile("SoftwareVersion\t$SoftwareVersion"); +logtoFile("ProxyType\t$proxyType"); + +# $file{"SensorName"} = $sensorname; + +# $file{"SoftwareVersion"} = $SoftwareVersion; + +# $file{"ProxyType"} = $proxyType; + + +while ( 1 ) { + + print "TID dose [kRad]: "; + $irraddeg = ; + chomp $irraddeg; + + # Check if numeric and within good current range + if ($irraddeg =~ /^\d{1,4}$/ ) { + last; + } elsif ($irraddeg eq "") { + $irraddeg = 1000; + last; + } else { + print "Invalid value (letters).\n"; + } +} + + +do { + my $socket = IO::Socket::INET->new( + PeerAddr => $peer, + PeerPort => $port, + Proto => "tcp", + Type => SOCK_STREAM ) + or die "ERROR: Cannot connect: $@"; + + usleep 1e5; print $socket "INST OUT$bbCh\n"; + usleep 1e5; print $socket "MEAS:VOLT?\n"; + $backbias = <$socket>; + chomp $backbias; + $backbias = 1000 * $backbias; + print "Back bias: $backbias mV\n"; + +} while ask_continue(); + + +sub bb_test { + + + print "\n"; + print "#############################################################################\n"; + print "### BB RAMP ###\n"; + print "#############################################################################\n"; + print "\n"; + + open(BB_FH, '>', $sensorname . "/bb.csv") or die $!; + + do { + my $socket = IO::Socket::INET->new( + PeerAddr => $peer, + PeerPort => $port, + Proto => "tcp", + Type => SOCK_STREAM, + ) + or die "ERROR: Cannot connect: $@"; + + # Save current BB seting for later + usleep 1e0; print $socket "INST OUT$bbCh\n"; + usleep 1e5; print $socket "MEAS:VOLT?\n"; + my $tmp = <$socket>; + chomp $tmp; + + for (my $i = 0; $i <= 6.0; $i += 0.5) { + + usleep 1e6; print $socket "VOLT $i\n"; + usleep 1e6; print $socket "MEAS:VOLT?\n"; my $volt = <$socket>; + usleep 1e6; print $socket "MEAS:CURR?\n"; my $curr = <$socket>; + + chomp $volt; + chomp $curr; + + print BB_FH "$volt\t$curr\n"; + print("Backbias: $volt, current: $curr \n"); + if ( ($curr > 0.01 and $irraddeg == 0) or ($curr > 0.02 and $irraddeg > 0)) { + die "Maximum backbias current exceeded!"; + } + } + + # Reset BB to what it was before + usleep 1e5; print $socket "VOLT $tmp\n"; + + } while ask_continue(); + + close BB_FH; + +} + +sub powering_tests { + + print "\n"; + print "###########################################################################\n"; + print "### POWERING TEST DIGITAL ###\n"; + print "###########################################################################\n"; + print "\n"; + + #Find out current drawn by sensor on digital and perform data checks. + my $lowleveldig = 100; # Minimum digital current for passing as ok + my $highleveldig = 200; # Maximum digital current for passing as ok + my $digitalcur = 0; + + + do { + + if ($proxyType eq "F") { + + Mimosis::adc_i2c_command( + $adc_addr, + $adc_wreg, + $adc_cmd_powering, + 0, 0, 1 + ); + + usleep($adcSlow); + + $digitalcur = + Mimosis::adc_i2c_command( + $adc_addr, + $adc_rreg, + 0x0, + 1, 0, 1 ); + + usleep($adcSlow); + + $digitalcur *= 1/80; + + } + + else { + + print("Please enter the value on the voltmeter labeled DIGITAL: "); + $digitalcur = ; + chomp $digitalcur; + + } + + # Check if numeric and within good current range + if ( $digitalcur <= $highleveldig && + $digitalcur >= $lowleveldig ) + { + logtoFile("DigitalCurrent\tS\t$digitalcur mA"); +# $file{"Digitalcurrent"} = $digitalcur; + print "Digital current: $digitalcur mA.\n"; + + } else { + logtoFile("DigitalCurrent\tF\t$digitalcur mA"); + print "Digital current not in range: $digitalcur mA.\n"; +# $file{"Digitalcurrent"} = "F"; + } + + } while ask_continue(); + + + + + + print "\n"; + print "############################################################################\n"; + print "### POWERING TEST ANALOG ###\n"; + print "############################################################################\n"; + print "\n"; + + #Find out current drawn by sensor on analog and perform data checks. + my $lowlevelana = 10; # Minimum analog current for passing as ok + my $highlevelana = 35; # Maximum analog current for passing as ok + my $analogcur = 0; + + + do { + + if ($proxyType eq "F") { + + Mimosis::adc_i2c_command( + $adc_addr, + $adc_wreg, + $adc_cmd_powering_ana, + 0, 0, 1 + ); + + usleep($adcSlow); + + $analogcur = + Mimosis::adc_i2c_command( + $adc_addr, + $adc_rreg, + 0x0, + 1, 0, 1 ); + + usleep($adcSlow); + + + $analogcur *= 1 / 800; + + + } + + else { + + print("Please enter the value on the voltmeter labeled ANALOG: "); + $analogcur = ; + chomp $analogcur; + + } + + # Check if numeric and within good current range + if( $analogcur <= $highlevelana && + $analogcur >= $lowlevelana ) + { + logtoFile("AnalogCurrent\tS\t$analogcur mA"); +# $file{"Analogcurrent"} = $analogcur; + print "Analog current: $analogcur mA.\n"; + + } else { + logtoFile("AnalogCurrent\tF\t$analogcur mA"); + print "Analog current not in range: $analogcur mA.\n"; +# $file{"Analogcurrent"} = "F"; + } + + } while ask_continue(); + +} + +sub reg_std_addr { + + print "\n"; + print "############################################################################\n"; + print "### REGISTER TEST - STD ADDR ###\n"; + print "############################################################################\n"; + print "\n"; + + my %regliststd = ( + 0x0021 => 0x6e, # TRIMDAC + 0x0029 => 0x11, # PLL + 0x002a => 0x38, # PLLLOCK + 0x002c => 0x15, # SLVSTX + 0x002d => 0x08, # SLVSRX + 0x0043 => 0xab, # VRESET + 0x004e => 0x7d, # IBUFBIAS + ); + + Mimosis::mimosis_instr_write(0xe0); # Send global reset to sensor + usleep($slow2); + + do { + + my $errCt = 0; + + # Mimosis::mimosis_instr_write(0xe0); # Send global reset to sensor + # usleep($slow2); + + while( my ($reg, $val) = each(%regliststd) ) { + + # Get test value + my $testVal = + Mimosis::mimosis_register_read( $reg ); + + # Compare + if ($testVal != $val) { + print("$testVal != $val\n"); + $errCt = $errCt + 1; + } + print("Register $reg, read: $testVal, should be: $val\n") unless $testVal == $val; + +# $file{'Register Read: ' . $reg} = +# $testVal == $val ? "GOOD" : "BAD"; + } + + if ($errCt == 0) { + + print("No problems detected.\n"); +# $file{"Registerread"} = "S"; + logtoFile("RegisterRead\tS"); + + } + + else { + + print("Problems in Register Read test detected.\n"); +# $file{"Registerread"} = "F"; + logtoFile("RegisterRead\tS"); + + } + + } while ask_continue(); + +} + +sub dac_reg_test { +print( Cwd::cwd() ); + + Mimosis::mimosis_load_file( file => $settingsDACRegTest ); + + + do { + chdir("/d/jspc37/mimosis/scripts/qa/dataTrash"); + my $errorCounter = 0; + foreach my $dacToBeMonitored (keys %Mimosis::DAC) { # DAC to be changed + + print("Reading DAC $dacToBeMonitored.\n"); + + my $monval = $Mimosis::DAC{$dacToBeMonitored}{'MONVAL'}; + my $monitor = $Mimosis::DAC{$dacToBeMonitored}{'MONITOR'}; + my $type = $Mimosis::DAC{$dacToBeMonitored}{'TYPE'}; + + if ($dacToBeMonitored ne 'IBUFBIAS') { + + foreach my $dacToBeChanged (keys %Mimosis::DAC) { + + my $trueMonVal = $DACList{$dacToBeChanged}{'MONVAL'}; + my $trueMonitor = $DACList{$dacToBeChanged}{'MONITOR'}; + my $trueType = $DACList{$dacToBeChanged}{'TYPE'}; + my $dacRegToBeChanged = $DACList{$dacToBeChanged}{'ADDR'}; + + $Mimosis::DAC{$dacToBeChanged}{'MONVAL'} = $monval; + $Mimosis::DAC{$dacToBeChanged}{'MONITOR'} = $monitor; + $Mimosis::DAC{$dacToBeChanged}{'TYPE'} = $type; + + usleep(10000); + + if ($dacToBeMonitored ne $dacToBeChanged && ($dacToBeChanged ne 'IBUFBIAS') && not ($dacToBeMonitored eq 'VPHFINE' && $dacToBeChanged eq 'VPH') ) { + +# print("DAC Monitored: $dacToBeMonitored, monval: $monval, monitor: $monitor, DAC changed: $dacToBeChanged, true monval: $trueMonVal, true monitor: $trueMonitor, monitored monval: $Mimosis::DAC{$dacToBeChanged}{'MONVAL'}, monitored monitor: $Mimosis::DAC{$dacToBeChanged}{'MONITOR'} \n"); + + my %test = Mimosis::mimosis_dacscan( + dacs => [$dacToBeChanged], + start => 195, + stop => 201, + ); + + my $notoverwritten = 1; + + do { + + Mimosis::mimosis_load_file( file => $settingsDACRegTest ); + usleep(10000); + my $val = Mimosis::mimosis_register_read( $dacRegToBeChanged ); + + if ($val == 5) {$notoverwritten = 0;} + + } while $notoverwritten; + + my $res = $test{$dacToBeChanged}{'Y'}[4]; + + my $VphType = 0; + + if ($monitor == 0x26 && ($monval == 1 || $monval == 2 || $monval == 6) ) { + $VphType = 1; + } + + if (($res < 8000) and (($res > 650 && $VphType == 1) or ($res > 100 && $VphType == 0)) ) { + $errorCounter = $errorCounter + 1; + print("Problem! Dac monitored: $dacToBeMonitored \t DAC changed: $dacToBeChanged\t Voltage: $res \n"); + } + + } + + $Mimosis::DAC{$dacToBeChanged}{'MONVAL'} = $trueMonVal; + $Mimosis::DAC{$dacToBeChanged}{'MONITOR'} = $trueMonitor; + $Mimosis::DAC{$dacToBeChanged}{'TYPE'} = $trueType; + usleep(10000); + + } + + } + + } + + chdir("/d/jspc37/mimosis/scripts/qa"); +# print("$errorCounter \n"); + if ($errorCounter <= 0) {logtoFile("DACRWTest\tS");} + else {logtoFile("DACRWTest\tF");} +# $file{'DAC Reg R/W Test: '} = +# ($errorCounter <= 0) ? "GOOD" : "BAD"; + $errorCounter <= 0 ? print("DAC REG TEST GOOD\n") : print("DAC REG TEST BAD\n"); + } while ask_continue(); + +} + +sub std_rw_test { + + print "\n"; + print "############################################################################\n"; + print "### REGISTER TEST - STD R&W ###\n"; + print "############################################################################\n"; + print "\n"; + + + # Test of read/write operation + + my %reglistgenconfrw = ( + 0x0020 => 0x02, # RUNMODE + 0x0025 => 0x00, # MONCURR + 0x0026 => 0x00, # MONVOLT + 0x0027 => 0x00, # CLKGEN1 + 0x0028 => 0x00, # CLKGEN2 + 0x0029 => 0x11, # PLL + 0x002a => 0x38, # PLLLOCK + 0x002c => 0x15, # SLVSTX + 0x002d => 0x08, # SLVSRX + 0x002e => 0x00, # OUTPUT + ); + + my %testwordsgenconfrw = ( + 0x00, + 0xff, + 0xaa, + 0x55, + 0xdb, + 0x44, + 0xcd, + 0x85, + ); + + + do { + + my $errCt = 0; + + while( my ($reg, $val) = each(%reglistgenconfrw) ) { + + # Save original value into register + my $tmp = Mimosis::mimosis_register_read( + #$fpgalink, + $reg, + ); #usleep($slow2); # + + while (my $testword = each(%testwordsgenconfrw)) { + + # Write test value + Mimosis::mimosis_register_write( + #$fpgalink, + $reg, + $testword, + ); #usleep($slow2); # write value into register + + # Get test value + my $testVal = Mimosis::mimosis_register_read( + #$fpgalink, + $reg, + ); #usleep($slow2); # + + + + # Compare + #print("$testVal != $testword\n") unless $testVal == $testword; + if ($testVal != $testword) { + print("$testVal != $testword\n"); + $errCt = $errCt + 1; + } + } + + # Write original value back into register + Mimosis::mimosis_register_write( + #$fpgalink, + $reg, + $tmp, + ); #usleep($slow2); + } + + if ($errCt == 0) { + + print("No problems detected.\n"); +# $file{"RegisterRW"} = "S"; + logtoFile("RegisterRW\tS"); + + } + + else { + + print("Problems in Register R/W test detected.\n"); +# $file{"RegisterRW"} = "F"; + logtoFile("RegisterRW\tF"); + + } + + } while ask_continue(); + +} + +sub chip_id { + + print "\n"; + print "#############################################################################\n"; + print "### CHIPID TEST ###\n"; + print "#############################################################################\n"; + print "\n"; + + + my @chipids = ( 0x0, 0x1 ); #, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 ); + + my $gpioReg = 0xd580; + my $testreg = 0x0020; # Pixel control register for testing + my $testval = 0x1; + my $shouldKill = 0; + my $errCt = 0; + my $potGold = 1; + my $idNotWorking = 0xA; + + do { + foreach my $id (@chipids) { + + # Reset all + my $bitmaskClear = 0x1 << 30; + + trb_register_clearbit( + $fpgalink, + $gpioReg, + $bitmaskClear + ); + + usleep($slow2); + + # Set desired bits + my $bitmaskSet = $id << 30; + + trb_register_setbit( + $fpgalink, + $gpioReg, + $bitmaskSet + ); usleep($slow2); + + Mimosis::set_chipid($id); + + my $tmp = + Mimosis::mimosis_register_read( + $testreg, + ); + + usleep($slow2); + + Mimosis::mimosis_register_write( + $testreg, + $testval, + ); + + usleep(100000); + + my $testTmp = + Mimosis::mimosis_register_read( + $testreg, + ); + + usleep($slow2); + + if ( (( $testTmp & 0xff ) != $testval ) && $id == 0x0 ) { + + $potGold = 0; + + } + + if ( ( $testTmp & 0xff ) != $testval ) { + + print "Chip-ID $id not working.\n"; + #$file{"CHIP-ID_$id"} = "F"; + $shouldKill += 1; + $errCt = $errCt + 1; + $idNotWorking = $id; + + } else { + + print "Chip-ID $id good.\n"; + } + } + + if ($potGold == 1 && $errCt == 0) { + + print("No problems detected.\n"); +# $file{"ChipIDTest"} = "1"; + logtoFile("ChipIDTest\t1"); + + } + + elsif ($errCt == 1) { + +# $file{"ChipIDTest"} = "2\t$idNotWorking"; + logtoFile("ChipIDTest\t2\t$idNotWorking"); + + } + + else { + + print("Problems in chip ID test detected.\n"); +# $file{"ChipIDTest"} = "F"; + logtoFile("ChipIDTest\tF"); + + } + } while ask_continue(); + + # die "Found broken chip ids. Exiting.\n" if $shouldKill; + + # Reset chipid to 0x1 + Mimosis::set_chipid(0x1); + + trb_register_setbit( + $fpgalink, + $gpioReg, + 0x1 << 30 + ); + + usleep($slow2); + + #system("./../start.sh"); + #sleep(2); + +} + +sub link_test { + + print "\n"; + print "############################################################################\n"; + print "### LINK TEST ###\n"; + print "############################################################################\n"; + print "\n"; + + do { + doStartSh(); + } while rep_prog(); + + do { + +# my $cntBadLinks = 0; +# +# for my $i (0 .. 7) { +# +# my $reg = trb_register_read( $fpgalink, 0xa000 + $i ); +# $reg = ( $reg->{$fpgalink} & 0x7f00 ) >> 8; +# +# $cntBadLinks += 1 if $reg >= 70; +# +# $file{"Link_$i"} = $reg >= 70 ? "$reg\tBAD" : "$reg\tGOOD"; +# } +# +# # die "Bad links. Exiting.\n" if $cntBadLinks > 0; +# print "Bad links.\n" if $cntBadLinks > 0; + + trb_init_ports() or die trb_strerror(); + my $reg0 = trb_register_read( $fpgalink, 0xa000 ); + $reg0 = ( $reg0->{$fpgalink} & 0x7f00 ) >> 8; + + my $reg1 = trb_register_read( $fpgalink, 0xa001 ); + $reg1 = ( $reg1->{$fpgalink} & 0x7f00 ) >> 8; + + my $reg2 = trb_register_read( $fpgalink, 0xa002 ); + $reg2 = ( $reg2->{$fpgalink} & 0x7f00 ) >> 8; + + my $reg3 = trb_register_read( $fpgalink, 0xa003 ); + $reg3 = ( $reg3->{$fpgalink} & 0x7f00 ) >> 8; + + my $reg4 = trb_register_read( $fpgalink, 0xa004 ); + $reg4 = ( $reg4->{$fpgalink} & 0x7f00 ) >> 8; + + my $reg5 = trb_register_read( $fpgalink, 0xa005 ); + $reg5 = ( $reg5->{$fpgalink} & 0x7f00 ) >> 8; + + my $reg6 = trb_register_read( $fpgalink, 0xa006 ); + $reg6 = ( $reg6->{$fpgalink} & 0x7f00 ) >> 8; + + my $reg7 = trb_register_read( $fpgalink, 0xa007 ); + $reg7 = ( $reg7->{$fpgalink} & 0x7f00 ) >> 8; + + if ($reg4 >= 30) { + + print("Max 1 Link. Sensor rated faulty.\n"); +# $file{"LinkTest"} = "F"; + logtoFile("LinkTest\tF"); + + } + + elsif ($reg2 >= 30 or $reg6 >= 30) { + + print("Max 2 Links. Sensor rated bronze wrt link tests.\n"); +# $file{"LinkTest"} = "3"; + logtoFile("LinkTest\t3"); + + } + + elsif ($reg1 >= 30 or $reg3 >= 30 or $reg5 >= 30 or $reg7 >= 30) { + + print("Max 4 Links. Sensor rated silver wrt link tests.\n"); +# $file{"LinkTest"} = "2"; + logtoFile("LinkTest\t2"); + + } + + else { + + print("All 8 Links available. Sensor rated gold wrt link tests.\n"); +# $file{"LinkTest"} = "1"; + logtoFile("LinkTest\t1"); + + } + + } while ask_continue(); + +} + + +sub fast_dac_scan { + + print "\n"; + print "############################################################################\n"; + print "### FAST DACSCAN TEST ###\n"; + print "############################################################################\n"; + print "\n"; + + + chdir($sensorname); + mkdir("DACScan"); + chdir("DACScan"); + + do { + my @DACFAST = ('VPH', 'VPL', 'VPHFINE'); + + my %results = Mimosis::mimosis_dacscan( + dacs => \@DACFAST, + step => 10, + ); + + + my $picName = "fastdacscan.png"; + + my $chart = Chart::Gnuplot->new( + output => $picName, + terminal => "pngcairo", + title => "DAC-Scan", + xlabel => "Setting [LSB]", + ylabel => "Voltage output [mV]", + ); + + + my @dataArr; + + $chart->polygon( + vertices => [ + "0, 1100", + "250, 1290", + "250, 1115", + "0, 900", + "0, 1000", + ], + fill => { + density => 0.3, + color => "#A9A9A0", + }, + ); + + $chart->polygon( + vertices => [ + "0, 370", + "250, 1950", + "250, 1670", + "0, 320", + "0, 370", + ], + fill => { + density => 0.3, + color => "#A9A9A0", + }, + ); + + for my $dac ( keys %results ) { + + my $dataSet = Chart::Gnuplot::DataSet->new( + xdata => $results{$dac}{X}, + ydata => $results{$dac}{Y}, + title => "Plotting a line from Perl arrays", + style => "linespoints", + ); + + push(@dataArr, $dataSet); + } + + $chart->plot2d(@dataArr); + + system("display $picName"); + + chdir(".."); + + + print "Please enter rapid DAC scan result classification.\n"; + print "S = satisfactory if in grey areas\n"; + print "F = unsatisfactory and exiting.\n"; + + while ( 1 ) { + + print "Rapid DAC scan classification: "; + my $rapiddacclass = ; + chomp $rapiddacclass; + + if ( $rapiddacclass eq "S" || + $rapiddacclass eq "s" ) { + +# $file{"RapidDACTest"} = "S"; + logtoFile("RapidDACTest\tS"); + last; + + } elsif ( $rapiddacclass eq "F" || + $rapiddacclass eq "f" ) { + +# $file{"RapidDACTest"} = "F"; + logtoFile("RapidDACTest\tF"); + exit 0; + + } else { + print "Invalid classification. Try again.\n"; + } + } + + } while ask_continue(); + +} + +sub full_dac_scan { + + print "\n"; + print "############################################################################\n"; + print "### DACSCAN TEST ###\n"; + print "############################################################################\n"; + print "\n"; + + chdir($sensorname); + chdir("DACScan"); + + do { + my %names = ( + 'IBIAS' => 0x0040, + 'ITHR' => 0x0041, + 'IDB' => 0x0042, + 'VRESET' => 0x0043, + 'VPL' => 0x0044, + 'VPH' => 0x0045, + 'VPHFINE' => 0x0046, + 'VCASP' => 0x0047, + 'VCASNA' => 0x0048, + 'VCASNB' => 0x0049, + 'VCASNC' => 0x004a, + 'VCASND' => 0x004b, + 'VCASN2' => 0x004c, + 'VCLIP' => 0x004d, + # 'IBUFBIAS' => 0x004e, + ); + + print("Performing DAC scans. This may take a minute...\n"); + + my %dacVals = Mimosis::mimosis_dacscan( + # step => 50, + ); + + + my @VPHList = @{$dacVals{'VPH'}{'Y'}}; + my @VPLList = @{$dacVals{'VPL'}{'Y'}}; + my @VPHFINEList = @{$dacVals{'VPHFINE'}{'Y'}}; + my @VRESETList = @{$dacVals{'VRESET'}{'Y'}}; + my @VCASNAList = @{$dacVals{'VCASNA'}{'Y'}}; + my @VCASNBList = @{$dacVals{'VCASNB'}{'Y'}}; + my @VCASNCList = @{$dacVals{'VCASNC'}{'Y'}}; + my @VCASNDList = @{$dacVals{'VCASND'}{'Y'}}; + my @VCASN2List = @{$dacVals{'VCASN2'}{'Y'}}; + my @VCLIPList = @{$dacVals{'VCLIP'}{'Y'}}; + my @VCASPList = @{$dacVals{'VCASP'}{'Y'}}; + my @IBIASList = @{$dacVals{'IBIAS'}{'Y'}}; + my @ITHRList = @{$dacVals{'ITHR'}{'Y'}}; + my @IDBList = @{$dacVals{'IDB'}{'Y'}}; + + + my $picName = "full-dacscan.png"; + + my $chartPng = Chart::Gnuplot->new( + output => $picName, + terminal => "pngcairo", + title => "DAC-Scan", + xlabel => "Setting [LSB]", + ylabel => "Voltage output [mV]", + ); + + my @dataArr; + + for my $dac ( keys %dacVals) { + + my $dataSet = Chart::Gnuplot::DataSet->new( + xdata => $dacVals{$dac}{X}, + ydata => $dacVals{$dac}{Y}, + title => $dac, + style => "lines", + ); + + push(@dataArr, $dataSet); + } + + $chartPng->plot2d(@dataArr); + + system("display $picName"); + + + for my $i (0 .. scalar( @VPHFINEList ) - 1) { + $VPHFINEList[$i] = $VPHFINEList[$i] - $VPHList[0]; + } + + + my $sensorQuality = 4; + + $VPHOffset = $VPHList[0]; + my $VPLOffset = $VPLList[0]; + my $VRESETOffset = $VRESETList[0]; + my $VPHFOffset = $VPHFINEList[0]; + my $VPH210 = $VPHList[211]; + my $VPL210 = $VPLList[211]; + my $VRESET210 = $VRESETList[211]; + my $VPHF210 = $VPHFINEList[211] - $VPHFOffset; + + my $acceptableVPHOffsetLowerLimit = 300; + my $acceptableVPHOffsetHigherLimit = 430; + my $goodDNLLimit = 1; + my $goodINLLimit = 5; + + + if ( ($acceptableVPHOffsetLowerLimit <= $VPHOffset) && + ($acceptableVPHOffsetHigherLimit >= $VPHOffset) && + ($acceptableVPHOffsetLowerLimit <= $VPLOffset) && + ($acceptableVPHOffsetHigherLimit >= $VPLOffset) && + ($acceptableVPHOffsetLowerLimit <= $VRESETOffset) && + ($acceptableVPHOffsetHigherLimit >= $VRESETOffset) && + ($VPH210 >= 1410) && + ($VPL210 >= 1410) && + ($VRESET210 >= 1410) && + ($VPHF210 >= 180) ) { + + $sensorQuality = 3; + + if ( max(@VCASNAList) > 1100 && + max(@VCASNBList) > 1100 && + max(@VCASNCList) > 1100 && + max(@VCASNDList) > 1100 && + max(@VCASN2List) > 1100 && + max(@VCLIPList) > 550 && + max(@VCASPList) > 550 && + max(@IBIASList) >= 260 && + max(@ITHRList) >= 260 && + max(@IDBList) >= 260 ) { + + $sensorQuality = 2; + + my $arrRef = [ 3,3,3,3 + ]; + + sub calcAbsDNLAbsINL { + + my @dac = @{$_[0]}; + + my $gain = ($dac[199] - $dac[24]) / 175.0; + + my @dnl = ( 0 ); + my @inl = ( 0 ); + + for my $i (21 .. 201) { + + my $currentDNL = ( ($dac[$i] - $dac[$i-1]) / $gain ) - 1; + push(@dnl, $currentDNL); + push(@inl, $inl[$i-21]+$currentDNL); + } + + @dnl = reverse @dnl; + @inl = reverse @inl; + return ( \@inl, \@dnl ); + } + + + my ( $ibiasinlRef, $ibiasdnlRef ) = calcAbsDNLAbsINL(\@IBIASList); + my @IBIASINL = @{$ibiasinlRef}; + my @IBIASDNL = @{$ibiasdnlRef}; + + my ( $ithrinlRef, $ithrdnlRef ) = calcAbsDNLAbsINL(\@ITHRList); + my @ITHRINL = @{$ithrinlRef}; + my @ITHRDNL = @{$ithrdnlRef}; + + my ( $idbinlRef, $idbdnlRef ) = calcAbsDNLAbsINL(\@IDBList); + my @IDBINL = @{$idbinlRef}; + my @IDBDNL = @{$idbdnlRef}; + + my ( $vphinlRef, $vphdnlRef ) = calcAbsDNLAbsINL(\@VPHList); + my @VPHINL = @{$vphinlRef}; + my @VPHDNL = @{$vphdnlRef}; + + my ( $vplinlRef, $vpldnlRef ) = calcAbsDNLAbsINL(\@VPLList); + my @VPLINL = @{$vplinlRef}; + my @VPLDNL = @{$vpldnlRef}; + + my ( $vresetinlRef, $vresetdnlRef ) = calcAbsDNLAbsINL(\@VRESETList); + my @VRESETINL = @{$vresetinlRef}; + my @VRESETDNL = @{$vresetdnlRef}; + + my ( $vphfineinlRef, $vphfinednlRef ) = calcAbsDNLAbsINL(\@VPHFINEList); + my @VPHFINEINL = @{$vphfineinlRef}; + my @VPHFINEDNL = @{$vphfinednlRef}; + + my ( $vcasnainlRef, $vcasnadnlRef ) = calcAbsDNLAbsINL(\@VCASNAList); + my @VCASNAINL = @{$vcasnainlRef}; + my @VCASNADNL = @{$vcasnadnlRef}; + + my ( $vcasnbinlRef, $vcasnbdnlRef ) = calcAbsDNLAbsINL(\@VCASNBList); + my @VCASNBINL = @{$vcasnbinlRef}; + my @VCASNBDNL = @{$vcasnbdnlRef}; + + my ( $vcasncinlRef, $vcasncdnlRef ) = calcAbsDNLAbsINL(\@VCASNCList); + my @VCASNCINL = @{$vcasncinlRef}; + my @VCASNCDNL = @{$vcasncdnlRef}; + + my ( $vcasndinlRef, $vcasnddnlRef ) = calcAbsDNLAbsINL(\@VCASNDList); + my @VCASNDINL = @{$vcasndinlRef}; + my @VCASNDDNL = @{$vcasnddnlRef}; + + my ( $vcasn2inlRef, $vcasn2dnlRef ) = calcAbsDNLAbsINL(\@VCASN2List); + my @VCASN2INL = @{$vcasn2inlRef}; + my @VCASN2DNL = @{$vcasn2dnlRef}; + + my ( $vcaspinlRef, $vcaspdnlRef ) = calcAbsDNLAbsINL(\@VCASPList); + my @VCASPINL = @{$vcaspinlRef}; + my @VCASPDNL = @{$vcaspdnlRef}; + + my ( $vclipinlRef, $vclipdnlRef ) = calcAbsDNLAbsINL(\@VCLIPList); + my @VCLIPINL = @{$vclipinlRef}; + my @VCLIPDNL = @{$vclipdnlRef}; + + my $goodDNL = 0; + + if ( $IBIASDNL[2] < $goodDNLLimit + && $ITHRDNL[2] < $goodDNLLimit + && $IDBDNL[2] < $goodDNLLimit + && $VCASNADNL[2] < $goodDNLLimit + && $VCASNBDNL[2] < $goodDNLLimit + && $VCASNCDNL[2] < $goodDNLLimit + && $VCASNDDNL[2] < $goodDNLLimit + && $VCASN2DNL[2] < $goodDNLLimit + && $VCASPDNL[2] < $goodDNLLimit + && $VCLIPDNL[2] < $goodDNLLimit + && $VPHDNL[2] < $goodDNLLimit + && $VPLDNL[2] < $goodDNLLimit + && $VRESETDNL[2] < $goodDNLLimit + && $VPHFINEDNL[2] < $goodDNLLimit + ) { + $goodDNL = 1; + } + + my $goodINL = 0; + + if ( $IBIASINL[2] < $goodINLLimit + && $ITHRINL[2] < $goodINLLimit + && $IDBINL[2] < $goodINLLimit + && $VCASNAINL[2] < $goodINLLimit + && $VCASNBINL[2] < $goodINLLimit + && $VCASNCINL[2] < $goodINLLimit + && $VCASNDINL[2] < $goodINLLimit + && $VCASN2INL[2] < $goodINLLimit + && $VCASPINL[2] < $goodINLLimit + && $VCLIPINL[2] < $goodINLLimit + && $VPHINL[2] < 2 + && $VPLINL[2] < 2 + && $VRESETINL[2] < 2 + && $VPHFINEINL[2] < 2 + ) { + $goodINL = 1; + } + + if ($goodDNL && $goodINL) { + $sensorQuality = 1; + } + } + } + + $VPHFSlope = ($VPHFINEList[255] - $VPHFINEList[0]) / 255.0; + # $VPHFSlope = 1.; + $VPHOffsetElectron = 150; + $ZeroElectronVPHSetting = 95; + + for my $i (0 .. scalar(@VPHList)) { + + if ( ($VPHList[$i] gt ($VPLList[70] - 6)) # or ($VPHList[$i] lt ($VPLList[70] + 6)) + ) { + + $ZeroElectronVPHSetting = $i; + $VPHOffsetElectron = $VPHList[$i] - $VPLList[70]; + last; + } + } + + print("ZeroSetting\t$ZeroElectronVPHSetting\t$VPHOffsetElectron\n"); + + print("Sensor Quality for DACs: $sensorQuality\n"); + + chdir(".."); + +# $file{"DACQuality"} = $sensorQuality; +# $file{"VPHFSlope"} = $VPHFSlope; +# $file{"VPHSetting0Electrons"} = "$ZeroElectronVPHSetting\t$VPHOffsetElectron"; + + logtoFile("DACQuality\t$sensorQuality"); + logtoFile("VPHFSlope\t$VPHFSlope"); + logtoFile("VPHSetting0Electrons\t$ZeroElectronVPHSetting\t$VPHOffsetElectron"); + + + } while ask_continue(); + + chdir(".."); + +} + +sub fit_thr { + my ($fitterfname, $fittervphOffsetElectron, $fittervphfSlope, $fittervphStepSize, $fittermaxPulse) = @_; + Mimosis::mimosis_make_quick_fit( $fitterfname , $fittervphOffsetElectron, $fittervphfSlope, $fittervphStepSize, $fittermaxPulse, $start, $end); + # system("/usr/bin/python3 /d/jspc37/mimosis/scripts/pulse/fit-raw.py $fname $dirName $vphOffsetElectron $vphfSlope"); +} + +sub scurve_fast_test { + + + my ( $scurvefastVPHOffsetElectron, $scurvefastVPHOffset, $scurvefastVPHFSlope, $scurvefastvphStepSize, $scurvemaxPulse ) = @_; + + chdir($sensorname); + + print "\n"; + print "############################################################################\n"; + print "### FAST SCURVE TEST ###\n"; + print "############################################################################\n"; + print "\n"; + + $matrixParams{'A'}{'LOWERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 95 : + (( $backbias == 1000 && $irraddeg >= 1000 ) ? 60 : (( $backbias == 1000 && $irraddeg == 0 ) ? 70 : (( $backbias == 3000 && $irraddeg == 0 ) ? 110 : 50 ))); + + $matrixParams{'A'}{'UPPERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 120 : + (( $backbias == 1000 && $irraddeg >= 1000 ) ? 100 : (( $backbias == 1000 && $irraddeg == 0 ) ? 115 : (( $backbias == 3000 && $irraddeg == 0 ) ? 165 : 200 ))); + + + $matrixParams{'B'}{'LOWERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 100 : + (( $backbias == 1000 && $irraddeg >= 1000 ) ? 75 : (( $backbias == 1000 && $irraddeg == 0 ) ? 95 : (( $backbias == 3000 && $irraddeg == 0 ) ? 130 : 50 ))); + + $matrixParams{'B'}{'UPPERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 150 : + (( $backbias == 1000 && $irraddeg >= 1000 ) ? 125 : (( $backbias == 1000 && $irraddeg == 0 ) ? 140 : (( $backbias == 3000 && $irraddeg == 0 ) ? 185 : 200 ))); + + + $matrixParams{'C'}{'LOWERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 100 : + (( $backbias == 1000 && $irraddeg >= 1000 ) ? 75 : (( $backbias == 1000 && $irraddeg == 0 ) ? 95 : (( $backbias == 3000 && $irraddeg == 0 ) ? 130 : 50 ))); + + $matrixParams{'C'}{'UPPERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 150 : + (( $backbias == 1000 && $irraddeg >= 1000 ) ? 125 : (( $backbias == 1000 && $irraddeg == 0 ) ? 140 : (( $backbias == 3000 && $irraddeg == 0 ) ? 185 : 200 ))); + + + $matrixParams{'D'}{'LOWERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 95 : + (( $backbias == 1000 && $irraddeg >= 1000 ) ? 60 : (( $backbias == 1000 && $irraddeg == 0 ) ? 75 : (( $backbias == 3000 && $irraddeg == 0 ) ? 115 : 50 ))); + + $matrixParams{'D'}{'UPPERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 120 : + (( $backbias == 1000 && $irraddeg >= 1000 ) ? 100 : (( $backbias == 1000 && $irraddeg == 0 ) ? 140 : (( $backbias == 3000 && $irraddeg == 0 ) ? 180 : 200 ))); + + + do { + chdir("/d/jspc37/mimosis/scripts/qa/" . $sensorname); + my $settingsScurves = "../CONF_scurves.pl"; + + cp($settingsScurves, "$sensorname/$settingsScurves"); + + Mimosis::mimosis_load_file( file => $settingsScurves ); + + Mimosis::mimosis_register_write( + 0x45, + $scurvefastVPHOffset, + ); + + Mimosis::mimosis_register_write( + 0x4d, + int( 45 + $backbias/1000.0 * 12.0 + 0.5 ), + ); + + Mimosis::mimosis_register_write( + 0x4c, + 180, + ); + + Mimosis::mimosis_register_write(0x46, 255); + Mimosis::mimosis_register_write(0x45, $scurvefastVPHOffset); + Mimosis::mimosis_register_write(0x44, 70); + + if ($mimVersion eq "M21") { + + Mimosis::mimosis_register_write(0x0063, 1); # DPSTARTA LSB + Mimosis::mimosis_register_write(0x0073, 2); # DPSTARTB LSB + Mimosis::mimosis_register_write(0x0064, 2); # DPTOKENA LSB + Mimosis::mimosis_register_write(0x0074, 3); # DPTOKENB LSB + Mimosis::mimosis_register_write(0x0065, 99); # DPENDA LSB + Mimosis::mimosis_register_write(0x0075, 100); # DPENDB LSB + + print("MIMOSIS 2.1\n") + + } + + + print "Press Enter, to start pulsing.\n"; + ; + + + foreach my $matrix ( sort keys %matrixParams ) { + + Mimosis::mimosis_load_file( file => $settingsScurves ); + + Mimosis::mimosis_register_write( + 0x45, + $scurvefastVPHOffset, + ); + + Mimosis::mimosis_register_write( + 0x4d, + int( 45 + $backbias/1000.0 * 12.0 + 0.5 ), + ); + + Mimosis::mimosis_register_write( + 0x4c, + 180, + ); + + Mimosis::mimosis_register_write(0x46, 255); + Mimosis::mimosis_register_write(0x45, $scurvefastVPHOffset); + Mimosis::mimosis_register_write(0x44, 70); + + my $yspan = $matrixParams{$matrix}{'YSPAN'}; + my $xstart = $matrixParams{$matrix}{'XSTART'}; + my $xstop = $matrixParams{$matrix}{'XSTOP'}; + + Mimosis::mimosis_instr_write( 0x3f ); + Mimosis::mimosis_instr_write( 0x04 ); + Mimosis::mimosis_instr_write( 0x3e ); + + Mimosis::mimosis_pulse( + ystart => 250, + ystop => 253, + yspan => $yspan, + xstart => $xstart, + xstop => $xstop, + modexp => 3, + ); + +# $modFound = Mimosis::mimosis_find_mod( Mimosis::get_mbsStream() , $fpgalink, 250, 253, $xstart, $xstop, 3) unless defined $modFound; + + my $ll = $matrixParams{$matrix}{'LOWERLIMIT'}; + my $ul = $matrixParams{$matrix}{'UPPERLIMIT'}; + + print "Find proper VCASN in Go4. Suggested range: $ll - $ul\n"; + + my $foundF = 0; + + while ( 1 ) { + + print "Enter the appropriate VCASN$matrix value or \'F\' if bad: " ; + + my $vcasnTmp = ; + chomp $vcasnTmp; + + if ( $vcasnTmp eq "F" or + $vcasnTmp eq "f" ) { + +# $file{"CoarseSCurves,MATRIX-$matrix"} = "F"; + logtoFile("CoarseSCurves,MATRIX-$matrix\tF"); + + $foundF = 1; + last; + + } else { + +# $file{"CoarseSCurves,MATRIX-$matrix"} = $vcasnTmp; + logtoFile("CoarseSCurves,MATRIX-$matrix\t$vcasnTmp"); + $matrixParams{$matrix}{"VCASNCOARSE"} = $vcasnTmp; + last; + } + } + + exit 0 if $foundF; + } + + + + print "Press Enter, to start scuves\n"; + ; + + foreach my $matrix ( sort keys %matrixParams ) { + + + Mimosis::mimosis_register_write(0x46, 255); + Mimosis::mimosis_register_write(0x45, $scurvefastVPHOffset); + Mimosis::mimosis_register_write(0x44, 70); + + if ($matrix eq "A") { + + Mimosis::mimosis_register_write(0x49, 1); + Mimosis::mimosis_register_write(0x4A, 1); + Mimosis::mimosis_register_write(0x4B, 1); + } + + if ($matrix eq "B") { + + Mimosis::mimosis_register_write(0x48, 1); + Mimosis::mimosis_register_write(0x4A, 1); + Mimosis::mimosis_register_write(0x4B, 1); + } + + if ($matrix eq "C") { + + Mimosis::mimosis_register_write(0x48, 1); + Mimosis::mimosis_register_write(0x49, 1); + Mimosis::mimosis_register_write(0x4B, 1); + } + + if ($matrix eq "D") { + + Mimosis::mimosis_register_write(0x48, 1); + Mimosis::mimosis_register_write(0x49, 1); + Mimosis::mimosis_register_write(0x4A, 1); + } + + my $matrixDir = "MATRIX-" . $matrix; + mkdir($matrixDir); + chdir($matrixDir); + + my $yspan = $matrixParams{$matrix}{'YSPAN'}; + my $xstart = $matrixParams{$matrix}{'XSTART'}; + my $xstop = $matrixParams{$matrix}{'XSTOP'}; + my $vcasnstart = $matrixParams{$matrix}{"VCASNCOARSE"} - 6; # - 6; #-5 + my $vcasnstop = $matrixParams{$matrix}{"VCASNCOARSE"} + 3; # 3+ 3; #+5 + + Mimosis::mimosis_scurves( + ystart => 230, + ystop => 273, + yspan => $yspan, + xstart => $xstart, + xstop => $xstop, + vcasnreg => 'VCASN' . $matrix, + vcasnstart => $vcasnstart, + vcasnstop => $vcasnstop, + vcasnstep => 2, + setstart => $start, + setstop => $end, + setstep => $scurvefastvphStepSize, + setcount => $scurvemaxPulse, + modfound => $modFound, + ); + + opendir my $dir, "." or die "Cannot open directory: $!"; + my @files = readdir $dir; + + foreach my $f ( @files ) { + + if ( $f =~ /VCASN/ ) { + + my $dirName = Cwd::cwd() . "/$f"; + + chdir($dirName); + + $matrixParams{$matrix}{"THREAD"} = + fit_thr( + "$dirName/$f.csv", + $scurvefastVPHOffsetElectron, + $scurvefastVPHFSlope, + $scurvefastvphStepSize, + $scurvemaxPulse ); + + chdir(".."); + } + } + + closedir $dir; + chdir(".."); + } + + + + + print "Wait for fits to finish.\n"; + + + print("Approximate a VCASN for each submatrix where the GMDT is closest to 120 e!\n"); + + my $foundF = 0; + + foreach my $matrix ( sort keys %matrixParams ) { + + while ( 1 ) { + + print "Enter the appropriate VCASN$matrix value or \'F\' if bad: " ; + + my $vcasnTmp = ; + chomp $vcasnTmp; + + if ( $vcasnTmp eq "F" or + $vcasnTmp eq "f" ) { + +# $file{"RapidSCurves,MATRIX-$matrix"} = "F"; + logtoFile("RapidSCurves,MATRIX-$matrix\tF"); + + $foundF = 1; + last; + + } else { + +# $file{"SCurvesFull,MATRIX-$matrix"} = $vcasnTmp; + logtoFile("SCurvesFull,MATRIX-$matrix\t$vcasnTmp"); + $matrixParams{$matrix}{"VCASNFINAL"} = $vcasnTmp; + last; + } + } + } + if ( $foundF ) { exit 0; } + + } while ask_continue(); + +} + +sub find_dead { + + my ($filename, $deadPixMaxPulse) = @_; + + my $file = $filename; + + open(FH, ">>", "DeadPixelsExtracted.csv") or + die "File couldn't be opened"; + + open my $info, $file or die "Could not open $file: $!"; + + while( my $line = <$info>) { + + my @parts = split('\t', $line); + if ($parts[2] le (0.9 * $deadPixMaxPulse)) { + + print FH $line; + + } + + } + close FH or "couldn't close"; + +} + +sub find_dead_pix { + + my ( $scurvefullVPHOffset, $scurvemaxPulse ) = @_; + + chdir($sensorname); + mkdir("DeadPixels"); + chdir("DeadPixels"); + + print "\n"; + print "############################################################################\n"; + print "### DEAD PIXELS TEST ###\n"; + print "############################################################################\n"; + print "\n"; + + do { + my $settingsScurves = "../CONF_scurves.pl"; + + cp($settingsScurves, "$sensorname/$settingsScurves"); + + Mimosis::mimosis_load_file( file => $settingsScurves ); + + + Mimosis::mimosis_register_write( + 0x45, + $scurvefullVPHOffset, + ); + + Mimosis::mimosis_register_write( + 0x4d, + int( 45 + $backbias/1000.0 * 12.0 + 0.5 ), + ); + + Mimosis::mimosis_register_write( + 0x4c, + 180, + ); + + Mimosis::mimosis_register_write(0x46, 255); + Mimosis::mimosis_register_write(0x45, $scurvefullVPHOffset); + Mimosis::mimosis_register_write(0x44, 70); + + + + print "Press Enter, to start scuves\n"; + ; + + foreach my $matrix ( sort keys %matrixParams ) { + + Mimosis::mimosis_register_write(0x46, 255); + Mimosis::mimosis_register_write(0x45, $scurvefullVPHOffset); + Mimosis::mimosis_register_write(0x44, 70); + + if ($matrix eq "A") { + + Mimosis::mimosis_register_write(0x49, 1); + Mimosis::mimosis_register_write(0x4A, 1); + Mimosis::mimosis_register_write(0x4B, 1); + } + + if ($matrix eq "B") { + + Mimosis::mimosis_register_write(0x48, 1); + Mimosis::mimosis_register_write(0x4A, 1); + Mimosis::mimosis_register_write(0x4B, 1); + }find_dead_pix + + if ($matrix eq "C") { + + Mimosis::mimosis_register_write(0x48, 1); + Mimosis::mimosis_register_write(0x49, 1); + Mimosis::mimosis_register_write(0x4B, 1); + } + + if ($matrix eq "D") { + + Mimosis::mimosis_register_write(0x48, 1); + Mimosis::mimosclose FH or "couldn't close"; is_register_write(0x49, 1); + Mimosis::mimosis_register_write(0x4A, 1); + } + + my $matrixDir = "MATRIX-" . $matrix; + mkdir($matrixDir); + chdir($matrixDir); + + my $yspan = $matrixParams{$matrix}{'YSPAN'}; + my $xstart = $matrixParams{$matrix}{'XSTART'}; + my $xstop = $matrixParams{$matrix}{'XSTOP'}; + my $vcasnstart = $matrixParams{$matrix}{"VCASNFINAL"}; + my $vcasnstop = $matrixParams{$matrix}{"VCASNFINAL"} + 1; + + Mimosis::mimosis_scurves( + ystart => 0, + ystop => 503, + yspan => $yspan, + xstart => $xstart, + xstop => $xstop, + vcasnreg => 'VCASN' . $matrix, + vcasnstart => $vcasnstart, + vcasnstop => $vcasnstop, + vcasnstep => 2, + setstart => 250, + setstop => 253, + setstep => 5, + setcount => $scurvemaxPulse, + modfound => $modFound, + ); + + opendir my $dir, "." or die "Cannot open directory: $!"; + my @files = readdir $dir; + + foreach my $f ( @files ) { + + if ( $f =~ /VCASN/ ) { + + my $dirName = Cwd::cwd() . "/$f"; + + chdir($dirName); + + $matrixParams{$matrix}{"THREAD"} = + find_dead("$dirName/$f.csv", $scurvemaxPulse); + + chdir(".."); + } + } + + closedir $dir; + chdir(".."); + } + + print "Done.\n"; + + } while ask_continue(); + + +} + +sub scurve_full_test { + + my ( $scurvefullVPHOffsetElectron, $scurvefullVPHOffset, $scurvefullVPHFSlope, $scurvefullvphStepSize, $scurvemaxPulse ) = @_; + + chdir($sensorname); + mkdir("FinalSCurves"); + chdir("FinalSCurves"); + + print "\n"; + print "############################################################################\n"; + print "### FULL SCURVE TEST ###\n"; + print "############################################################################\n"; + print "\n"; + + do { + my $settingsScurves = "../CONF_scurves.pl"; + + cp($settingsScurves, "$sensorname/$settingsScurves"); + + Mimosis::mimosis_load_file( file => $settingsScurves ); + + + Mimosis::mimosis_register_write( + 0x45, + $scurvefullVPHOffset, + ); + + Mimosis::mimosis_register_write( + 0x4d, + int( 45 + $backbias/1000.0 * 12.0 + 0.5 ), + ); + + Mimosis::mimosis_register_write( + 0x4c, + 180, + ); + + Mimosis::mimosis_register_write(0x46, 255); + Mimosis::mimosis_register_write(0x45, $scurvefullVPHOffset); + Mimosis::mimosis_register_write(0x44, 70); + + + + print "Press Enter, to start scuves\n"; + ; + + foreach my $matrix ( sort keys %matrixParams ) { + + Mimosis::mimosis_register_write(0x46, 255); + Mimosis::mimosis_register_write(0x45, $scurvefullVPHOffset); + Mimosis::mimosis_register_write(0x44, 70); + + if ($matrix eq "A") { + + Mimosis::mimosis_register_write(0x49, 1); + Mimosis::mimosis_register_write(0x4A, 1); + Mimosis::mimosis_register_write(0x4B, 1); + } + + if ($matrix eq "B") { + + Mimosis::mimosis_register_write(0x48, 1); + Mimosis::mimosis_register_write(0x4A, 1); + Mimosis::mimosis_register_write(0x4B, 1); + } + + if ($matrix eq "C") { + + Mimosis::mimosis_register_write(0x48, 1); + Mimosis::mimosis_register_write(0x49, 1); + Mimosis::mimosis_register_write(0x4B, 1); + } + + if ($matrix eq "D") { + + Mimosis::mimosis_register_write(0x48, 1); + Mimosis::mimosis_register_write(0x49, 1); + Mimosis::mimosis_register_write(0x4A, 1); + } + + my $matrixDir = "MATRIX-" . $matrix; + mkdir($matrixDir); + chdir($matrixDir); + + my $yspan = $matrixParams{$matrix}{'YSPAN'}; + my $xstart = $matrixParams{$matrix}{'XSTART'}; + my $xstop = $matrixParams{$matrix}{'XSTOP'}; + my $vcasnstart = $matrixParams{$matrix}{"VCASNFINAL"}; + my $vcasnstop = $matrixParams{$matrix}{"VCASNFINAL"} + 1; + + Mimosis::mimosis_scurves( + ystart => 0, + ystop => 503, + yspan => $yspan, + xstart => $xstart, + xstop => $xstop, + vcasnreg => 'VCASN' . $matrix, + vcasnstart => $vcasnstart, + vcasnstop => $vcasnstop, + vcasnstep => 2, + setstep => $scurvefullvphStepSize, + setcount => $scurvemaxPulse, + modfound => $modFound, + ); + + opendir my $dir, "." or die "Cannot open directory: $!"; + my @files = readdir $dir; + + foreach my $f ( @files ) { + + if ( $f =~ /VCASN/ ) { + + my $dirName = Cwd::cwd() . "/$f"; + + chdir($dirName); + + $matrixParams{$matrix}{"THREAD"} = + fit_thr( + "$dirName/$f.csv", + $scurvefullVPHOffsetElectron, + $scurvefullVPHFSlope, + $scurvefullvphStepSize, + $scurvemaxPulse ); + + chdir(".."); + } + } + + closedir $dir; + chdir(".."); + } + + + + + print "Wait for fits to finish.\n"; + + } while ask_continue(); + +} + +sub analyzeNoisyPixels { + + my ( $frameNumber ) = @_; + + + +} + +sub find_noisy_pix { + +my ( $scurvefullVPHOffset, $maxFrames ) = @_; + + chdir($sensorname); + mkdir("NoisyPixels"); + chdir("NoisyPixels"); + + print "\n"; + print "############################################################################\n"; + print "### NOISY PIXEL TEST ###\n"; + print "############################################################################\n"; + print "\n"; + + do { + my $settingsScurves = "../CONF_scurves.pl"; + + cp($settingsScurves, "$sensorname/$settingsScurves"); + + Mimosis::mimosis_load_file( file => $settingsScurves ); + + + Mimosis::mimosis_register_write( + 0x45, + $scurvefullVPHOffset, + ); + + Mimosis::mimosis_register_write( + 0x4d, + int( 45 + $backbias/1000.0 * 12.0 + 0.5 ), + ); + + Mimosis::mimosis_register_write( + 0x4c, + 180, + ); + + Mimosis::mimosis_register_write(0x46, 30); + Mimosis::mimosis_register_write(0x45, $scurvefullVPHOffset); + Mimosis::mimosis_register_write(0x44, 70); + + Mimosis::mimosis_register_write(0x46, 255); + Mimosis::mimosis_register_write(0x45, $scurvefullVPHOffset); + Mimosis::mimosis_register_write(0x44, 70); + + Mimosis::mimosis_register_write(0x48, $matrixParams{"A"}{"VCASNFINAL"}); + Mimosis::mimosis_register_write(0x49, $matrixParams{"B"}{"VCASNFINAL"}); + Mimosis::mimosis_register_write(0x4A, $matrixParams{"C"}{"VCASNFINAL"}); + Mimosis::mimosis_register_write(0x4B, $matrixParams{"D"}{"VCASNFINAL"}); + + + + print "Press Enter, to start scuves\n"; + ; + + Mimosis::mimosis_pixel_dump( $fpgalink, $maxFrames ); + analyzeNoisyPixels( $maxFrames ); + + print "Done.\n"; + + } while ask_continue(); + +} + +do { + doStartSh(); +} while ask_continue(); + +bb_test(); + +powering_tests(); + +link_test(); + +if ($proxyType eq "F") { + chip_id(); +} + +reg_std_addr(); + +do { + doStartSh(); +} while rep_prog(); + +dac_reg_test(); + +do { + doStartSh(); +} while rep_prog(); + +Mimosis::mimosis_load_file( file => $settingsDACRegTest ); + +std_rw_test(); + +do { + doStartSh(); +} while rep_prog(); + +fast_dac_scan(); + +full_dac_scan(); + +do { + doStartSh(); +} while rep_prog(); + +findMod(); + +scurve_fast_test($VPHOffsetElectron, $ZeroElectronVPHSetting, $VPHFSlope, 5, 100); + +# scurve_full_test($VPHOffsetElectron, $ZeroElectronVPHSetting, $VPHFSlope, 5, 100); + +find_dead_pix($ZeroElectronVPHSetting, 500); + +find_noisy_pix(); + + +# open(RESULTS_FH, '>', $sensorname . "/results.db") or die $!; +# print RESULTS_FH "$_\t$file{$_}\n" foreach (keys %file); +# close RESULTS_FH; diff --git a/scripts/qa/good_range_odac.txt b/scripts/qa/good_range_odac.txt deleted file mode 100644 index eb3e6cd..0000000 --- a/scripts/qa/good_range_odac.txt +++ /dev/null @@ -1,3 +0,0 @@ -0 320 370 -220 1569 1850 -250 1670 1950 diff --git a/scripts/qa/good_range_vphf.txt b/scripts/qa/good_range_vphf.txt deleted file mode 100644 index 28ddb00..0000000 --- a/scripts/qa/good_range_vphf.txt +++ /dev/null @@ -1,6 +0,0 @@ -0 1000 1100 -50 1045 1155 -100 1090 1210 -150 1135 1265 -200 1180 1320 -250 1225 1375 diff --git a/scripts/qa/oldScripts/QAScript.pl b/scripts/qa/oldScripts/QAScript.pl new file mode 100755 index 0000000..eb8daf8 --- /dev/null +++ b/scripts/qa/oldScripts/QAScript.pl @@ -0,0 +1,1595 @@ +#!/usr/bin/perl + +# MIMOSIS-1 QA Script ... version 0.7 +# +# Authors: Benedict Arnoldi-Meadows and Benedikt Gutsche + +use strict; +use warnings; +use HADES::TrbNet; +use Mimosis; +use Time::HiRes qw( usleep ); +use POSIX; +use Data::Dump qw( dump ); +use List::Util qw( min max ); +use threads; +use IO::Handle; +use IO::Socket; +use File::Temp qw( tempfile ); +use File::Copy qw( cp ); +use Cwd qw(); +use Chart::Gnuplot; + + + +sub ask_continue +{ + print "Repeat test? [y/N]: "; + my $answer = ; + chomp $answer; + + return 0 if $answer eq "" || $answer eq "n" || $answer eq "N"; + return 1; +} + + +my $ZeroElectronVPHSetting = 95; +my $singleaccessmode = 0; +my $slow = 100; +my $slow2 = 100000; +my $adcSlow = 100000; +my $vphStepSize = 5; + +my %fineVCASNParams = (); + + + +my $fpgalink = 0xa000; +my $peer = "192.168.0.61"; +my $port = "5025"; +my $bbCh = 2; +Mimosis::set_fpga($fpgalink); +Mimosis::set_printall(1); +# Mimosis::set_adcToIkfProxy(); + +# my $fpgalink = 0xa100; +# my $peer = "192.168.0.56"; +# my $port = "5050"; +# my $bbCh = 3; +# Mimosis::set_adcToIkfProxy(); +# Mimosis::set_singleAccess(1); + + +printf("Using %x\n", $fpgalink); + + +trb_init_ports() or die trb_strerror(); + +print "\n"; +print "############################################################################\n"; +print "### INIT ###\n"; +print "############################################################################\n"; +print "\n"; + + +my $sensorname; + +# Perform loop until a good name is found, +# i.e. it has never been assigned or is not empty +while ( 1 ) { + + print "Enter the sensor name: "; + $sensorname = ; + chomp $sensorname; + + # Check for bad names + if (-d $sensorname or $sensorname eq "") { + + print "Sensor name already chosen or illegal. Choose new one...\n"; + + } else { + + mkdir($sensorname); + last; + } +} + + +# Hash where everything gets stored before written to file +my %file; + +# Trap sig int +$SIG{INT} = sub { +# + open(RESULTS_FH, '>', "results.db") or die $!; + print RESULTS_FH "$_\t$file{$_}\n" foreach (keys %file); + close RESULTS_FH; + die "\nAbort.\n" +}; + + +$file{"SensorName"} = $sensorname; + + + + +my $irraddeg; + +while ( 1 ) { + + print "TID dose [kRad]: "; + $irraddeg = ; + chomp $irraddeg; + + # Check if numeric and within good current range + if ($irraddeg =~ /^\d{1,4}$/ ) { + last; + } elsif ($irraddeg eq "") { + $irraddeg = 1000; + last; + } else { + print "Invalid value (letters).\n"; + } +} + + + + + +my $backbias; + +do { + my $socket = IO::Socket::INET->new( + PeerAddr => $peer, + PeerPort => $port, + Proto => "tcp", + Type => SOCK_STREAM ) + or die "ERROR: Cannot connect: $@"; + + usleep 1e5; print $socket "INST OUT$bbCh\n"; + usleep 1e5; print $socket "MEAS:VOLT?\n"; + $backbias = <$socket>; + chomp $backbias; + $backbias = 1000 * $backbias; + print "Back bias: $backbias mV\n"; + +} while ask_continue(); + +# goto MFETESTS; + goto SCURVES; + + +sub bb_test { + + +print "\n"; +print "#############################################################################\n"; +print "### BB TEST ###\n"; +print "#############################################################################\n"; +print "\n"; + +open(BB_FH, '>', $sensorname . "/bb.csv") or die $!; + +BBTEST: +do { + my $socket = IO::Socket::INET->new( + PeerAddr => $peer, + PeerPort => $port, + Proto => "tcp", + Type => SOCK_STREAM, + ) + or die "ERROR: Cannot connect: $@"; + + # Save current BB seting for later + usleep 1e0; print $socket "INST OUT$bbCh\n"; + usleep 1e5; print $socket "MEAS:VOLT?\n"; + my $tmp = <$socket>; + chomp $tmp; + + for (my $i = 0; $i <= 5.0; $i += 0.5) { + + usleep 1e5; print $socket "VOLT $i\n"; + usleep 1e5; print $socket "MEAS:VOLT?\n"; my $volt = <$socket>; + usleep 1e5; print $socket "MEAS:CURR?\n"; my $curr = <$socket>; + + chomp $volt; + chomp $curr; + + print BB_FH "$volt\t$curr\n"; + } + + # Reset BB to what it was before + usleep 1e5; print $socket "VOLT $tmp\n"; + +} while ask_continue(); + +close BB_FH; + +} + +bb_test(); + + +__END__ + +POWERINGTEST: + + +print "\n"; +print "###########################################################################\n"; +print "### POWERING TEST DIGITAL ###\n"; +print "###########################################################################\n"; +print "\n"; + +#Find out current drawn by sensor on digital and perform data checks. +my $lowleveldig = 100; # Minimum digital current for passing as ok +my $highleveldig = 200; # Maximum digital current for passing as ok + + +do { + my $adc_addr = 0x48; + my $adc_wreg = 0x1; + my $adc_cmd = 0xc380; #CHANGE ME + my $adc_rreg = 0x0; + my $adcConv = ( 2 * 4096 ) / (2**16 * 10); + + Mimosis::adc_i2c_command( + $adc_addr, + $adc_wreg, + $adc_cmd, + 0, 0, 1 + ); + + usleep($adcSlow); + + my $digitalcur = + Mimosis::adc_i2c_command( + $adc_addr, + $adc_rreg, + 0x0, + 1, 0, 1 ); + + usleep($adcSlow); + + $digitalcur *= $adcConv; + + # Check if numeric and within good current range + if ( $digitalcur <= $highleveldig && + $digitalcur >= $lowleveldig ) + { + $file{"Digitalcurrent"} = $digitalcur; + print "Digital current: $digitalcur mA.\n"; + + } else { + + print "Digital current not in range: $digitalcur.\n"; + $file{"Digitalcurrent"} = "F"; + } + +} while ask_continue(); + + + + + +print "\n"; +print "############################################################################\n"; +print "### POWERING TEST ANALOG ###\n"; +print "############################################################################\n"; +print "\n"; + +#Find out current drawn by sensor on analog and perform data checks. +my $lowlevelana = 5; # Minimum analog current for passing as ok +my $highlevelana = 20; # Maximum analog current for passing as ok + + +do { + my $adc_addr = 0x48; + my $adc_wreg = 0x1; + my $adc_cmd = 0xf380; #CHANGE ME + my $adc_rreg = 0x0; + my $adcConv = ( 2 * 4096 ) / (2**16 * 100); + + Mimosis::adc_i2c_command( + $adc_addr, + $adc_wreg, + $adc_cmd, + 0, 0, 1 + ); + + usleep($adcSlow); + + my $analogcur = + Mimosis::adc_i2c_command( + $adc_addr, + $adc_rreg, + 0x0, + 1, 0, 1 ); + + usleep($adcSlow); + + $analogcur *= $adcConv; + + # Check if numeric and within good current range + if( $analogcur <= $highlevelana && + $analogcur >= $lowlevelana ) + { + $file{"Analogcurrent"} = $analogcur; + print "Analog current: $analogcur mA.\n"; + + } else { + + print "Analog current not in range: $analogcur.\n"; + $file{"Analogcurrent"} = "F"; + } + +} while ask_continue(); + + + + +print "\n"; +print "############################################################################\n"; +print "### REGISTER TEST - STD ADDR ###\n"; +print "############################################################################\n"; +print "\n"; + +my %regliststd = ( + 0x0021 => 0x6e, # TRIMDAC + 0x0029 => 0x11, # PLL + 0x002a => 0x38, # PLLLOCK + 0x002c => 0x15, # SLVSTX + 0x002d => 0x08, # SLVSRX + 0x0043 => 0xab, # VRESET + 0x004e => 0x7d, # IBUFBIAS +); + +Mimosis::mimosis_instr_write(0xe0); # Send global reset to sensor# +#usleep($slow2); + +do { + + # Mimosis::mimosis_instr_write(0xe0); # Send global reset to sensor + # usleep($slow2); + + while( my ($reg, $val) = each(%regliststd) ) { + + # Get test value + my $testVal = + Mimosis::mimosis_register_read( $reg ); + + # Compare + print("$testVal != $val\n") unless $testVal == $val; + + $file{'Register Read: ' . $reg} = + $testVal == $val ? "GOOD" : "BAD"; + } + + system("./../start.sh"); + +} while ask_continue(); + + +DACREGTEST: + +print "\n"; +print "############################################################################\n"; +print "### REGISTER TEST - DAC ADDR ###\n"; +print "############################################################################\n"; +print "\n"; + +# my %reglistdac = ( +# 0x0040 => 0x40, +# 0x0041 => 0x34, +# 0x0042 => 0x1c, +# 0x0043 => 0xAB, +# 0x0044 => 0x57, +# 0x0045 => 0x68, +# 0x0046 => 0x0 , +# 0x0047 => 0x43, +# 0x0048 => 0x53, +# 0x0049 => 0x53, +# 0x004A => 0x53, +# 0x004B => 0x53, +# 0x004C => 0x53, +# 0x004D => 0x32, +#); + + + +# foreach my $dacOuter (keys %Mimosis::DAC) { +# +# foreach my $dacInner (keys %Mimosis::DAC) { +# +# my $monval = $Mimosis::DAC{$dacInner}{'MONVAL'}; +# my $monitor = $Mimosis::DAC{$dacInner}{'MONITOR'}; +# +# if( defined $monval ) { +# +# my $dacRegOuter = $Mimosis::DAC{$dacOuter}{'ADDR'}; +# my $dacRegInner = $Mimosis::DAC{$dacInner}{'ADDR'}; +# +# Mimosis::mimosis_register_write( $dacRegInner, 100 ); +# Mimosis::mimosis_register_write( $dacRegOuter, 0 ); +# +# print "$dacOuter $dacInner $monitor $monval\n"; +# +# my $tmpVal = $Mimosis::DAC{$dacOuter}{'MONVAL'}; +# my $tmpMon = $Mimosis::DAC{$dacOuter}{'MONITOR'}; +# +# $Mimosis::DAC{$dacOuter}{'MONVAL'} = $monval; +# $Mimosis::DAC{$dacOuter}{'MONITOR'} = $monitor; +# +# my %test = Mimosis::mimosis_dacscan( +# dacs => [$dacOuter, ], +# start => 100, +# stop => 102, +# ); +# +# my $res = $test{$dacOuter}{'Y'}[0]; +# +# print("$res\n") if $res > 100; +# +# $Mimosis::DAC{$dacOuter}{'MONVAL'} = $tmpVal; +# $Mimosis::DAC{$dacOuter}{'MONITOR'} = $tmpMon; +# } +# } +#} + +my $settingsDACRegTest = "../CONF_DACRegisterTest.pl"; +Mimosis::mimosis_load_file( file => $settingsDACRegTest ); + + +do { + my $errorCounter = 0; + foreach my $dacOuter (keys %Mimosis::DAC) { # DAC to be changed + + foreach my $dacInner (keys %Mimosis::DAC) { # DAC to be monitored + + my $monval = $Mimosis::DAC{$dacInner}{'MONVAL'}; + my $monitor = $Mimosis::DAC{$dacInner}{'MONITOR'}; + + if( defined $monval ) { + + my $dacRegOuter = $Mimosis::DAC{$dacOuter}{'ADDR'}; + my $dacRegInner = $Mimosis::DAC{$dacInner}{'ADDR'}; + + Mimosis::mimosis_register_write( $dacRegInner, 0 ); + Mimosis::mimosis_register_write( $dacRegOuter, 200 ); + + # print "$dacOuter $dacInner $monitor $monval\n"; + + my $tmpVal = $Mimosis::DAC{$dacOuter}{'MONVAL'}; + my $tmpMon = $Mimosis::DAC{$dacOuter}{'MONITOR'}; + + $Mimosis::DAC{$dacOuter}{'MONVAL'} = $monval; #dacInner + $Mimosis::DAC{$dacOuter}{'MONITOR'} = $monitor; #dacInner + + my %test = Mimosis::mimosis_dacscan( + dacs => [$dacOuter], + start => 100, + stop => 102, + ); + + Mimosis::mimosis_register_write( $dacRegOuter, 0 ); + + my $res = $test{$dacOuter}{'Y'}[0]; + $errorCounter = $errorCounter + 1 if $res > 500; + print("$res \n"); + + $Mimosis::DAC{$dacOuter}{'MONVAL'} = $tmpVal; + $Mimosis::DAC{$dacOuter}{'MONITOR'} = $tmpMon; + } + } + } + + print($errorCounter); + $file{'DAC Reg R/W Test: '} = + ($errorCounter <= 14) ? "GOOD" : "BAD"; + $errorCounter <= 14 ? print("DAC REG TEST GOOD\n") : print("DAC REG TEST BAD\n"); +} while ask_continue(); + +# FIXME Problem with writing to file + +#Mimosis::mimosis_instr_write($fpgalink, 0xe0); # Send proper settings back to sensor FIXME Find Benes Value +#usleep($slow2); + +Mimosis::mimosis_load_file( file => $settingsDACRegTest ); + + +print "\n"; +print "############################################################################\n"; +print "### REGISTER TEST - STD R&W ###\n"; +print "############################################################################\n"; +print "\n"; + + +# Test of read/write operation + +my %reglistgenconfrw = ( + 0x0020 => 0x02, # RUNMODE + 0x0025 => 0x00, # MONCURR + 0x0026 => 0x00, # MONVOLT + 0x0027 => 0x00, # CLKGEN1 + 0x0028 => 0x00, # CLKGEN2 + 0x0029 => 0x11, # PLL + 0x002a => 0x38, # PLLLOCK + 0x002c => 0x15, # SLVSTX + 0x002d => 0x08, # SLVSRX + 0x002e => 0x00, # OUTPUT +); + +my %testwordsgenconfrw = ( + 0x00, + 0xff, + 0xaa, + 0x55, + 0xdb, + 0x44, + 0xcd, + 0x85, +); + + +do { + + while( my ($reg, $val) = each(%reglistgenconfrw) ) { + + # Save original value into register + my $tmp = Mimosis::mimosis_register_read( + #$fpgalink, + $reg, + ); #usleep($slow2); # + + while (my $testword = each(%testwordsgenconfrw)) { + + # Write test value + Mimosis::mimosis_register_write( + #$fpgalink, + $reg, + $testword, + ); #usleep($slow2); # write value into register + + # Get test value + my $testVal = Mimosis::mimosis_register_read( + #$fpgalink, + $reg, + #$singleaccessmode + ); #usleep($slow2); # + + + + # Compare + print("$testVal != $testword\n") unless $testVal == $testword; + } + + # Write original value back into register + Mimosis::mimosis_register_write( + #$fpgalink, + $reg, + $tmp, + #$singleaccessmode + ); #usleep($slow2); + } + +} while ask_continue(); + + +print "\n"; +print "#############################################################################\n"; +print "### CHIPID TEST ###\n"; +print "#############################################################################\n"; +print "\n"; + + +my @chipids = ( 0x0, 0x1 ); + +my $gpioReg = 0xd580; +my $testreg = 0x0020; # Pixel control register for testing +my $testval = 0x1; +my $shouldKill = 0; + +do { + foreach my $id (@chipids) { + + # Reset all + my $bitmaskClear = 0x1 << 30; + + trb_register_clearbit( + $fpgalink, + $gpioReg, + $bitmaskClear + ); + + usleep($slow2); + + # Set desired bits + my $bitmaskSet = $id << 30; + + trb_register_setbit( + $fpgalink, + $gpioReg, + $bitmaskSet + ); usleep($slow2); + + Mimosis::set_chipid($id); + + my $tmp = + Mimosis::mimosis_register_read( + $testreg, + ); + + usleep($slow2); + + Mimosis::mimosis_register_write( + $testreg, + $testval, + ); + + usleep(100000); + + my $testTmp = + Mimosis::mimosis_register_read( + $testreg, + ); + + usleep($slow2); + + if ( ( $testTmp&0xff ) != $testval ) { + + print "Chip-ID $id not working.\n"; + $file{"CHIP-ID_$id"} = "F"; + $shouldKill += 1; + + } else { + + $file{"CHIP-ID_$id"} = "S"; + } + } +} while ask_continue(); + +# die "Found broken chip ids. Exiting.\n" if $shouldKill; + +# Reset chipid to 0x1 +Mimosis::set_chipid(0x1); + +trb_register_setbit( + $fpgalink, + $gpioReg, + 0x1 << 30 + ); + +usleep($slow2); + +#system("./../start.sh"); +#sleep(2); + + +print "\n"; +print "############################################################################\n"; +print "### LINK TEST ###\n"; +print "############################################################################\n"; +print "\n"; + + +do { + my $currentWd = Cwd::cwd(); + chdir("/d/jspc37/mimosis/scripts"); + system("/d/jspc37/mimosis/scripts/start.sh"); + chdir($currentWd); + + my $cntBadLinks = 0; + + for my $i (0 .. 7) { + + my $reg = trb_register_read( $fpgalink, 0xa000 + $i ); + $reg = ( $reg->{$fpgalink} & 0x7f00 ) >> 8; + + $cntBadLinks += 1 if $reg >= 70; + + $file{"Link_$i"} = $reg >= 70 ? "$reg\tBAD" : "$reg\tGOOD"; + } + + # die "Bad links. Exiting.\n" if $cntBadLinks > 0; + print "Bad links.\n" if $cntBadLinks > 0; + +} while ask_continue(); + + + + + + + + + + + +print "\n"; +print "############################################################################\n"; +print "### FAST DACSCAN TEST ###\n"; +print "############################################################################\n"; +print "\n"; + + +chdir($sensorname); + +do { + my @DACFAST = ('VPH', 'VPL', 'VPHFINE'); + + my %results = Mimosis::mimosis_dacscan( + dacs => \@DACFAST, + step => 10, + ); + + + my $picName = "fastdacscan.png"; + + my $chart = Chart::Gnuplot->new( + output => $picName, + terminal => "pngcairo", + title => "DAC-Scan", + xlabel => "Setting [LSB]", + ylabel => "Voltage output [mV]", + ); + + + my @dataArr; + + $chart->polygon( + vertices => [ + "0, 1100", + "250, 1375", + "250, 1225", + "0, 1000", + "0, 1100", + ], + fill => { + density => 0.3, + color => "#A9A9A0", + }, + ); + + $chart->polygon( + vertices => [ + "0, 370", + "250, 1950", + "250, 1670", + "0, 320", + "0, 370", + ], + fill => { + density => 0.3, + color => "#A9A9A0", + }, + ); + + for my $dac ( keys %results ) { + + my $dataSet = Chart::Gnuplot::DataSet->new( + xdata => $results{$dac}{X}, + ydata => $results{$dac}{Y}, + title => "Plotting a line from Perl arrays", + style => "linespoints", + ); + + push(@dataArr, $dataSet); + } + + $chart->plot2d(@dataArr); + + system("display $picName"); + + + print "Please enter rapid DAC scan result classification.\n"; + print "S = satisfactory if in grey areas\n"; + print "F = unsatisfactory and exiting.\n"; + + while ( 1 ) { + + print "Rapid DAC scan classification: "; + my $rapiddacclass = ; + chomp $rapiddacclass; + + if ( $rapiddacclass eq "S" || + $rapiddacclass eq "s" ) { + + $file{"RapidDACTest"} = "S"; + last; + + } elsif ( $rapiddacclass eq "F" || + $rapiddacclass eq "f" ) { + + $file{"RapidDACTest"} = "F"; + exit 0; + + } else { + print "Invalid classification. Try again.\n"; + } + } + +} while ask_continue(); + + + + + +print "\n"; +print "############################################################################\n"; +print "### DACSCAN TEST ###\n"; +print "############################################################################\n"; +print "\n"; + +my $VPHFSlope; +my $VPHOffsetElectron; + +do { + my %names = ( + 'IBIAS' => 0x0040, + 'ITHR' => 0x0041, + 'IDB' => 0x0042, + 'VRESET' => 0x0043, + 'VPL' => 0x0044, + 'VPH' => 0x0045, + 'VPHFINE' => 0x0046, + 'VCASP' => 0x0047, + 'VCASNA' => 0x0048, + 'VCASNB' => 0x0049, + 'VCASNC' => 0x004a, + 'VCASND' => 0x004b, + 'VCASN2' => 0x004c, + 'VCLIP' => 0x004d, + # 'IBUFBIAS' => 0x004e, + ); + + my %dacVals = Mimosis::mimosis_dacscan( + # step => 50, + ); + + + my @VPHList = @{$dacVals{'VPH'}{'Y'}}; + my @VPLList = @{$dacVals{'VPL'}{'Y'}}; + my @VPHFINEList = @{$dacVals{'VPHFINE'}{'Y'}}; + my @VRESETList = @{$dacVals{'VRESET'}{'Y'}}; + my @VCASNAList = @{$dacVals{'VCASNA'}{'Y'}}; + my @VCASNBList = @{$dacVals{'VCASNB'}{'Y'}}; + my @VCASNCList = @{$dacVals{'VCASNC'}{'Y'}}; + my @VCASNDList = @{$dacVals{'VCASND'}{'Y'}}; + my @VCASN2List = @{$dacVals{'VCASN2'}{'Y'}}; + my @VCLIPList = @{$dacVals{'VCLIP'}{'Y'}}; + my @VCASPList = @{$dacVals{'VCASP'}{'Y'}}; + my @IBIASList = @{$dacVals{'IBIAS'}{'Y'}}; + my @ITHRList = @{$dacVals{'ITHR'}{'Y'}}; + my @IDBList = @{$dacVals{'IDB'}{'Y'}}; + + + my $picName = "full-dacscan.png"; + + my $chartPng = Chart::Gnuplot->new( + output => $picName, + terminal => "pngcairo", + title => "DAC-Scan", + xlabel => "Setting [LSB]", + ylabel => "Voltage output [mV]", + ); + + my @dataArr; + + for my $dac ( keys %dacVals) { + + my $dataSet = Chart::Gnuplot::DataSet->new( + xdata => $dacVals{$dac}{X}, + ydata => $dacVals{$dac}{Y}, + title => $dac, + style => "lines", + ); + + push(@dataArr, $dataSet); + } + + $chartPng->plot2d(@dataArr); + + system("display $picName"); + + + for my $i (0 .. scalar( @VPHFINEList ) - 1) { + $VPHFINEList[$i] = $VPHFINEList[$i] - $VPHList[0]; + } + + + my $sensorQuality = 4; + + my $VPHOffset = $VPHList[0]; + my $VPLOffset = $VPLList[0]; + my $VRESETOffset = $VRESETList[0]; + my $VPHFOffset = $VPHFINEList[0]; + my $VPH210 = $VPHList[211]; + my $VPL210 = $VPLList[211]; + my $VRESET210 = $VRESETList[211]; + my $VPHF210 = $VPHFINEList[211] - $VPHFOffset; + + my $acceptableVPHOffsetLowerLimit = 300; + my $acceptableVPHOffsetHigherLimit = 430; + my $goodDNLLimit = 1; + my $goodINLLimit = 5; + + + if ( ($acceptableVPHOffsetLowerLimit <= $VPHOffset) && + ($acceptableVPHOffsetHigherLimit >= $VPHOffset) && + ($acceptableVPHOffsetLowerLimit <= $VPLOffset) && + ($acceptableVPHOffsetHigherLimit >= $VPLOffset) && + ($acceptableVPHOffsetLowerLimit <= $VRESETOffset) && + ($acceptableVPHOffsetHigherLimit >= $VRESETOffset) && + ($VPH210 >= 1410) && + ($VPL210 >= 1410) && + ($VRESET210 >= 1410) && + ($VPHF210 >= 180) ) { + + $sensorQuality = 3; + + if ( max(@VCASNAList) > 1100 && + max(@VCASNBList) > 1100 && + max(@VCASNCList) > 1100 && + max(@VCASNDList) > 1100 && + max(@VCASN2List) > 1100 && + max(@VCLIPList) > 550 && + max(@VCASPList) > 550 && + max(@IBIASList) >= 260 && + max(@ITHRList) >= 260 && + max(@IDBList) >= 260 ) { + + $sensorQuality = 2; + + my $arrRef = [ 3,3,3,3 + ]; + + sub calcAbsDNLAbsINL { + + my @dac = @{$_[0]}; + + my $gain = ($dac[199] - $dac[24]) / 175.0; + + my @dnl = ( 0 ); + my @inl = ( 0 ); + + for my $i (21 .. 201) { + + my $currentDNL = ( ($dac[$i] - $dac[$i-1]) / $gain ) - 1; + push(@dnl, $currentDNL); + push(@inl, $inl[$i-21]+$currentDNL); + } + + @dnl = reverse @dnl; + @inl = reverse @inl; + return ( \@inl, \@dnl ); + } + + + my ( $ibiasinlRef, $ibiasdnlRef ) = calcAbsDNLAbsINL(\@IBIASList); + my @IBIASINL = @{$ibiasinlRef}; + my @IBIASDNL = @{$ibiasdnlRef}; + + my ( $ithrinlRef, $ithrdnlRef ) = calcAbsDNLAbsINL(\@ITHRList); + my @ITHRINL = @{$ithrinlRef}; + my @ITHRDNL = @{$ithrdnlRef}; + + my ( $idbinlRef, $idbdnlRef ) = calcAbsDNLAbsINL(\@IDBList); + my @IDBINL = @{$idbinlRef}; + my @IDBDNL = @{$idbdnlRef}; + + my ( $vphinlRef, $vphdnlRef ) = calcAbsDNLAbsINL(\@VPHList); + my @VPHINL = @{$vphinlRef}; + my @VPHDNL = @{$vphdnlRef}; + + my ( $vplinlRef, $vpldnlRef ) = calcAbsDNLAbsINL(\@VPLList); + my @VPLINL = @{$vplinlRef}; + my @VPLDNL = @{$vpldnlRef}; + + my ( $vresetinlRef, $vresetdnlRef ) = calcAbsDNLAbsINL(\@VRESETList); + my @VRESETINL = @{$vresetinlRef}; + my @VRESETDNL = @{$vresetdnlRef}; + + my ( $vphfineinlRef, $vphfinednlRef ) = calcAbsDNLAbsINL(\@VPHFINEList); + my @VPHFINEINL = @{$vphfineinlRef}; + my @VPHFINEDNL = @{$vphfinednlRef}; + + my ( $vcasnainlRef, $vcasnadnlRef ) = calcAbsDNLAbsINL(\@VCASNAList); + my @VCASNAINL = @{$vcasnainlRef}; + my @VCASNADNL = @{$vcasnadnlRef}; + + my ( $vcasnbinlRef, $vcasnbdnlRef ) = calcAbsDNLAbsINL(\@VCASNBList); + my @VCASNBINL = @{$vcasnbinlRef}; + my @VCASNBDNL = @{$vcasnbdnlRef}; + + my ( $vcasncinlRef, $vcasncdnlRef ) = calcAbsDNLAbsINL(\@VCASNCList); + my @VCASNCINL = @{$vcasncinlRef}; + my @VCASNCDNL = @{$vcasncdnlRef}; + + my ( $vcasndinlRef, $vcasnddnlRef ) = calcAbsDNLAbsINL(\@VCASNDList); + my @VCASNDINL = @{$vcasndinlRef}; + my @VCASNDDNL = @{$vcasnddnlRef}; + + my ( $vcasn2inlRef, $vcasn2dnlRef ) = calcAbsDNLAbsINL(\@VCASN2List); + my @VCASN2INL = @{$vcasn2inlRef}; + my @VCASN2DNL = @{$vcasn2dnlRef}; + + my ( $vcaspinlRef, $vcaspdnlRef ) = calcAbsDNLAbsINL(\@VCASPList); + my @VCASPINL = @{$vcaspinlRef}; + my @VCASPDNL = @{$vcaspdnlRef}; + + my ( $vclipinlRef, $vclipdnlRef ) = calcAbsDNLAbsINL(\@VCLIPList); + my @VCLIPINL = @{$vclipinlRef}; + my @VCLIPDNL = @{$vclipdnlRef}; + + my $goodDNL = 0; + + if ( $IBIASDNL[2] < $goodDNLLimit + && $ITHRDNL[2] < $goodDNLLimit + && $IDBDNL[2] < $goodDNLLimit + && $VCASNADNL[2] < $goodDNLLimit + && $VCASNBDNL[2] < $goodDNLLimit + && $VCASNCDNL[2] < $goodDNLLimit + && $VCASNDDNL[2] < $goodDNLLimit + && $VCASN2DNL[2] < $goodDNLLimit + && $VCASPDNL[2] < $goodDNLLimit + && $VCLIPDNL[2] < $goodDNLLimit + && $VPHDNL[2] < $goodDNLLimit + && $VPLDNL[2] < $goodDNLLimit + && $VRESETDNL[2] < $goodDNLLimit + && $VPHFINEDNL[2] < $goodDNLLimit + ) { + $goodDNL = 1; + } + + my $goodINL = 0; + + if ( $IBIASINL[2] < $goodINLLimit + && $ITHRINL[2] < $goodINLLimit + && $IDBINL[2] < $goodINLLimit + && $VCASNAINL[2] < $goodINLLimit + && $VCASNBINL[2] < $goodINLLimit + && $VCASNCINL[2] < $goodINLLimit + && $VCASNDINL[2] < $goodINLLimit + && $VCASN2INL[2] < $goodINLLimit + && $VCASPINL[2] < $goodINLLimit + && $VCLIPINL[2] < $goodINLLimit + && $VPHINL[2] < 2 + && $VPLINL[2] < 2 + && $VRESETINL[2] < 2 + && $VPHFINEINL[2] < 2 + ) { + $goodINL = 1; + } + + if ($goodDNL && $goodINL) { + $sensorQuality = 1; + } + } + } + + $VPHFSlope = ($VPHFINEList[255] - $VPHFINEList[0]) / 255.0; + # $VPHFSlope = 1.; + $VPHOffsetElectron = 150; + $ZeroElectronVPHSetting = 95; + + for my $i (0 .. scalar(@VPHList)) { + + if ( ($VPHList[$i] gt ($VPLList[70] - 6)) # or ($VPHList[$i] lt ($VPLList[70] + 6)) + ) { + + $ZeroElectronVPHSetting = $i; + $VPHOffsetElectron = $VPHList[$i] - $VPLList[70]; + last; + } + } + + print("ZeroSetting\t$ZeroElectronVPHSetting\t$VPHOffsetElectron\n"); + + print("Sensor Quality for DACs: $sensorQuality\n"); + + $file{"DACQuality"} = $sensorQuality; + $file{"VPHFSlope"} = $VPHFSlope; + $file{"VPHSetting0Electrons"} = "$ZeroElectronVPHSetting\t$VPHOffsetElectron"; + +} while ask_continue(); + + + +SCURVES: + +sub fit_thr { + my ($fname, $vphOffsetElectron, $vphfSlope, $vphStepSize, $maxPulse) = @_; + Mimosis::mimosis_make_fit($fname , $vphOffsetElectron, $vphfSlope, $vphStepSize, $maxPulse); + # system("/usr/bin/python3 /d/jspc37/mimosis/scripts/pulse/fit-raw.py $fname $dirName $vphOffsetElectron $vphfSlope"); +} + +sub scurve_fast_test { + + +my ( $VPHOffset, $vphOffsetElectron, $vphStepSize ) = @_; + +my %matrixParams = ( + A => { + VCASN => 0x48, + YSPAN => 4, + XSTART => 0, + XSTOP => 127, + }, +# B => { +# VCASN => 0x49, +# YSPAN => 2, +# XSTART => 128, +# XSTOP => 511, +# }, +# C => { +# VCASN => 0x4a, +# YSPAN => 2, +# XSTART => 512, +# XSTOP => 894, +# }, +# D => { +# VCASN => 0x4b, +# YSPAN => 4, +# XSTART => 895, +# XSTOP => 1023, +# }, + ); + +print "\n"; +print "############################################################################\n"; +print "### SCURVE TEST ###\n"; +print "############################################################################\n"; +print "\n"; + +$matrixParams{'A'}{'LOWERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 95 : +(( $backbias == 1000 && $irraddeg >= 1000 ) ? 60 : (( $backbias == 1000 && $irraddeg == 0 ) ? 70 : (( $backbias == 3000 && $irraddeg == 0 ) ? 110 : 50 ))); + +$matrixParams{'A'}{'UPPERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 120 : +(( $backbias == 1000 && $irraddeg >= 1000 ) ? 100 : (( $backbias == 1000 && $irraddeg == 0 ) ? 115 : (( $backbias == 3000 && $irraddeg == 0 ) ? 165 : 200 ))); + + +# $matrixParams{'B'}{'LOWERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 100 : +# (( $backbias == 1000 && $irraddeg >= 1000 ) ? 75 : (( $backbias == 1000 && $irraddeg == 0 ) ? 95 : (( $backbias == 3000 && $irraddeg == 0 ) ? 130 : 50 ))); +# +# $matrixParams{'B'}{'UPPERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 150 : +# (( $backbias == 1000 && $irraddeg >= 1000 ) ? 125 : (( $backbias == 1000 && $irraddeg == 0 ) ? 140 : (( $backbias == 3000 && $irraddeg == 0 ) ? 185 : 200 ))); +# +# +# $matrixParams{'C'}{'LOWERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 100 : +# (( $backbias == 1000 && $irraddeg >= 1000 ) ? 75 : (( $backbias == 1000 && $irraddeg == 0 ) ? 95 : (( $backbias == 3000 && $irraddeg == 0 ) ? 130 : 50 ))); +# +# $matrixParams{'C'}{'UPPERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 150 : +# (( $backbias == 1000 && $irraddeg >= 1000 ) ? 125 : (( $backbias == 1000 && $irraddeg == 0 ) ? 140 : (( $backbias == 3000 && $irraddeg == 0 ) ? 185 : 200 ))); +# +# +# $matrixParams{'D'}{'LOWERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 95 : +# (( $backbias == 1000 && $irraddeg >= 1000 ) ? 60 : (( $backbias == 1000 && $irraddeg == 0 ) ? 75 : (( $backbias == 3000 && $irraddeg == 0 ) ? 115 : 50 ))); +# +# $matrixParams{'D'}{'UPPERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 120 : +# (( $backbias == 1000 && $irraddeg >= 1000 ) ? 100 : (( $backbias == 1000 && $irraddeg == 0 ) ? 140 : (( $backbias == 3000 && $irraddeg == 0 ) ? 180 : 200 ))); + + +do { + my $settingsScurves = "../CONF_scurves.pl"; + + cp($settingsScurves, "$sensorname/$settingsScurves"); + + Mimosis::mimosis_load_file( file => $settingsScurves ); + + + Mimosis::mimosis_register_write( + 0x45, + $ZeroElectronVPHSetting, + ); + + Mimosis::mimosis_register_write( + 0x4d, + int( 45 + $backbias/1000.0 * 12.0 + 0.5 ), + ); + + + + print "Press Enter, to start pulsing.\n"; + ; + + + foreach my $matrix ( sort keys %matrixParams ) { + + my $yspan = $matrixParams{$matrix}{'YSPAN'}; + my $xstart = $matrixParams{$matrix}{'XSTART'}; + my $xstop = $matrixParams{$matrix}{'XSTOP'}; + + Mimosis::mimosis_instr_write( 0x3f ); + Mimosis::mimosis_instr_write( 0x04 ); + Mimosis::mimosis_instr_write( 0x3e ); + + Mimosis::mimosis_register_write(0x46, 255); + + Mimosis::mimosis_pulse( + ystart => 250, + ystop => 253, + yspan => $yspan, + xstart => $xstart, + xstop => $xstop, + modexp => 3, + ); + + my $ll = $matrixParams{$matrix}{'LOWERLIMIT'}; + my $ul = $matrixParams{$matrix}{'UPPERLIMIT'}; + + print "Find proper VCASN in Go4. Suggested range: $ll - $ul\n"; + + my $foundF = 0; + + while ( 1 ) { + + print "Enter the appropriate VCASN$matrix value or \'F\' if bad: " ; + + my $vcasnTmp = ; + chomp $vcasnTmp; + + if ( $vcasnTmp eq "F" or + $vcasnTmp eq "f" ) { + + $file{"CoarseSCurves,MATRIX-$matrix"} = "F"; + + $foundF = 1; + last; + + } else { + + $file{"CoarseSCurves,MATRIX-$matrix"} = $vcasnTmp; + $matrixParams{$matrix}{"VCASNCOARSE"} = $vcasnTmp; + last; + } + } + + exit 0 if $foundF; + } + + + + print "Press Enter, to start scuves\n"; + ; + + foreach my $matrix ( sort keys %matrixParams ) { + + my $matrixDir = "MATRIX-" . $matrix; + mkdir($matrixDir); + chdir($matrixDir); + + my $yspan = $matrixParams{$matrix}{'YSPAN'}; + my $xstart = $matrixParams{$matrix}{'XSTART'}; + my $xstop = $matrixParams{$matrix}{'XSTOP'}; + my $vcasnstart = $matrixParams{$matrix}{"VCASNCOARSE"} - 1; #-5 + my $vcasnstop = $matrixParams{$matrix}{"VCASNCOARSE"} + 1; #+5 + + Mimosis::mimosis_scurves( + ystart => 250, + ystop => 253, + yspan => $yspan, + xstart => $xstart, + xstop => $xstop, + vcasnreg => 'VCASN' . $matrix, + vcasnstart => $vcasnstart, + vcasnstop => $vcasnstop, + setstep => $vphStepSize, + ); + + opendir my $dir, "." or die "Cannot open directory: $!"; + my @files = readdir $dir; + + foreach my $f ( @files ) { + + if ( $f =~ /VCASN/ ) { + + my $dirName = Cwd::cwd() . "/$f"; + + chdir($dirName); + + $matrixParams{$matrix}{"THREAD"} = + threads->create( \&fit_thr, + "$dirName/$f.csv", + $VPHOffsetElectron, + $VPHFSlope, + $vphStepSize, + 4000 ); + + chdir(".."); + } + } + + closedir $dir; + chdir(".."); + } + + + + + print "Wait for fits to finish.\n"; + + foreach my $matrix ( keys %matrixParams ) { + $matrixParams{$matrix}{"THREAD"}->join(); + } + + + + + print("Approximate a VCASN for each submatrix where the GMDT is closest to 150 e!\n"); + + my $foundF = 0; + + foreach my $matrix ( sort keys %matrixParams ) { + + while ( 1 ) { + + print "Enter the appropriate VCASN$matrix value or \'F\' if bad: " ; + + my $vcasnTmp = ; + chomp $vcasnTmp; + + if ( $vcasnTmp eq "F" or + $vcasnTmp eq "f" ) { + + $file{"RapidSCurves,MATRIX-$matrix"} = "F"; + + $foundF = 1; + last; + + } else { + + $file{"SCurvesFull,MATRIX-$matrix"} = $vcasnTmp; + $matrixParams{$matrix}{"VCASNFINAL"} = $vcasnTmp; + last; + } + } + } + if ( $foundF ) { exit 0; } + +} while ask_continue(); + +} + + + + + + +do { + print "\n"; + print "############################################################################\n"; + print "### SCURVE TEST, FINAL ###\n"; + print "############################################################################\n"; + print "\n"; + + +# my $lowerlimitA = $matrixParams{"A"}{"PREV-VCASN"} - 2; +# my $upperlimitA = + 2; + +# my $lowerlimitB = $prevFoundB - 2; +# my $upperlimitB = $prevFoundB + 2; + +# my $lowerlimitC = $prevFoundC - 2; +# my $upperlimitC = $prevFoundC + 2; +# +# my $lowerlimitD = $prevFoundD - 2; +# my $upperlimitD = $prevFoundD + 2; + + + #Mimosis::mimosis_register_write( 0x45, $SixtyElectronVPHSetting ); + + my $settingsScurves = "../CONF_scurves.pl"; + + cp($settingsScurves, "$sensorname/$settingsScurves"); + + Mimosis::mimosis_load_file( + file => $settingsScurves + ); + + #Mimosis::mimosis_register_write( + #0x4D, + #int( 45 + $backbias/1000.0 * 12.0 + 0.5 ) + #); + + + foreach my $matrix ( sort keys %matrixParams ) { + + my $matrixDir = "MATRIXFINAL-" . $matrix; + mkdir($matrixDir); + chdir($matrixDir); + + Mimosis::mimosis_register_write( + 0x45, + $ZeroElectronVPHSetting, + ); + + Mimosis::mimosis_register_write( + 0x4D, + int( 45 + $backbias/1000.0 * 12.0 + 0.5 ), + ); + + my $vcasnSetting + $matrixParams{$matrix}{"VCASNFINAL"}; + + print("VCASNFINAL SETTING: $vcasnSetting\n"); + + my $yspan = $matrixParams{$matrix}{'YSPAN'}; + my $xstart = $matrixParams{$matrix}{'XSTART'}; + my $xstop = $matrixParams{$matrix}{'XSTOP'}; + my $vcasnstart = $matrixParams{$matrix}{"VCASNFINAL"}; + my $vcasnstop = $matrixParams{$matrix}{"VCASNFINAL"}; + + Mimosis::mimosis_scurves( + ystart => 0, + ystop => 503, + yspan => $yspan, + xstart => $xstart, + xstop => $xstop, + vcasnreg => 'VCASN' . $matrix, + vcasnstart => $vcasnstart, + vcasnstop => $vcasnstop, + ); + + opendir my $dir, "." or die "Cannot open directory: $!"; + my @files = readdir $dir; + + foreach my $f ( @files ) { + + if ( $f =~ /VCASN/ ) { + + my $dirName = Cwd::cwd() . "/$f"; + $matrixParams{$matrix}{"THREAD"} = threads->create(\&fit_thr, "$f.csv", $dirName, $VPHOffsetElectron, $VPHFSlope); + } + } + + closedir $dir; + + chdir(".."); + } + + + + print "Wait for fits to finish.\n"; + foreach my $matrix ( sort keys %matrixParams ) { + $matrixParams{$matrix}{"THREAD"}->join(); + } + + + print("Give VCASN for each submatrix where the GMDT is closest to 150 e!\n"); + + my $foundF = 0; + + foreach my $matrix ( sort keys %matrixParams ) { + + while ( 1 ) { + + print "Enter the appropriate VCASN$matrix value or \'F\' if bad:" ; + + my $vcasnTmp = ; + chomp $vcasnTmp; + + if ( $vcasnTmp eq "F" or + $vcasnTmp eq "f" ) { + + $file{"FineSCurves,MATRIX-$matrix"} = "F"; + + $foundF = 1; + last; + + } else { + + $file{"FineSCurves,MATRIX-$matrix"} = $vcasnTmp; + $matrixParams{$matrix}{"FINE"} = $vcasnTmp; + last; + } + } + } + if ( $foundF ) { exit 0; } + +} while ask_continue(); + +MFETESTS: + +print "\n"; +print "############################################################################\n"; +print "### REGISTER TEST - MFE REGS ###\n"; +print "############################################################################\n"; +print "\n"; + +# Test of read/write operation + +my %reglistmferw = ( + 0x4040 => 0x00, +); + +my %testwordsmferw = ( + 0x00, + 0xff, + 0xaa, + 0x55, + 0x71, + 0xb8, +); + +my $framelengthmsb = Mimosis::mimosis_register_read( + #$fpgalink, + 0x017B, + ); #usleep($slow2); # + +my $framelengthlsb = Mimosis::mimosis_register_read( + #$fpgalink, + 0x007B, + ); #usleep($slow2); # +Mimosis::mimosis_register_write( + #$fpgalink, + 0x017b, + 0xFF, + ); #usleep($slow2); # write value into register + +Mimosis::mimosis_register_write( + #$fpgalink, + 0x007b, + 0xFF, + ); #usleep($slow2); # write value into register + + +do { + + while( my ($reg, $val) = each(%reglistmferw) ) { + + # Save original value into register + my $tmp = Mimosis::mimosis_register_read( + #$fpgalink, + $reg, + ); #usleep($slow2); # + + while (my $testword = each(%testwordsmferw)) { + + # Write test value + Mimosis::mimosis_register_write( + #$fpgalink, + $reg, + $testword, + ); #usleep($slow2); # write value into register + + # Get test value + my $testVal = Mimosis::mimosis_register_read( + #$fpgalink, + $reg, + #$singleaccessmode + ); #usleep($slow2); # + + + + # Compare + print("$testVal != $testword\n") unless $testVal == $testword; + } + + # Write original value back into register + Mimosis::mimosis_register_write( + #$fpgalink, + $reg, + $tmp, + #$singleaccessmode + ); #usleep($slow2); + } + +} while ask_continue(); + +Mimosis::mimosis_register_write( + #$fpgalink, + 0x017b, + $framelengthmsb, + ); #usleep($slow2); # write value into register + +Mimosis::mimosis_register_write( + #$fpgalink, + 0x007b, + $framelengthlsb, + ); #usleep($slow2); # write value into register + + +__END__ + +open(RESULTS_FH, '>', $sensorname . "/results.db") or die $!; +print RESULTS_FH "$_\t$file{$_}\n" foreach (keys %file); +close RESULTS_FH; diff --git a/scripts/qa/oldScripts/QAScript.pl.save b/scripts/qa/oldScripts/QAScript.pl.save new file mode 100755 index 0000000..7c36089 --- /dev/null +++ b/scripts/qa/oldScripts/QAScript.pl.save @@ -0,0 +1,1578 @@ +##!/usr/bin/perl + +# MIMOSIS-1 QA Script ... version 0.5 +# +# Authors: Benedict Arnoldi-Meadows and Benedikt Gutsche + +use strict; +use warnings; +use HADES::TrbNet; +use Mimosis; +use Time::HiRes qw( usleep ); +use POSIX; +use Data::Dump qw( dump ); +use List::Util qw( min max ); +use threads; +use IO::Handle; +use IO::Socket; +use File::Temp qw( tempfile ); +use File::Copy qw( cp ); +use Cwd qw(); +use Chart::Gnuplot; + + + +sub ask_continue +{ + print "Repeat test? [y/N]: "; + my $answer = ; + chomp $answer; + + return 0 if $answer eq "" || $answer eq "n" || $answer eq "N"; + return 1; +} + + +my $ZeroElectronVPHSetting = 95; +my $singleaccessmode = 0; +my $slow = 100; +my $slow2 = 100000; +my $adcSlow = 100000; +my $vphStepSize = 5; + +my %fineVCASNParams = (); + + + +my $fpgalink = 0xa000; +my $peer = "192.168.0.61"; +my $port = "5025"; +my $bbCh = 2; +Mimosis::set_fpga($fpgalink); +Mimosis::set_printall(1); +#Mimosis::set_adcToIkfProxy(); + +# my $fpgalink = 0xa100; +# my $peer = "192.168.0.56"; +# my $port = "5050"; +# my $bbCh = 3; +# Mimosis::set_adcToIkfProxy(); +# Mimosis::set_singleAccess(1); + + +printf("Using %x\n", $fpgalink); + + +trb_init_ports() or die trb_strerror(); + +print "\n"; +print "############################################################################\n"; +print "### INIT ###\n"; +print "############################################################################\n"; +print "\n"; + + +my $sensorname; + +# Perform loop until a good name is found, +# i.e. it has never been assigned or is not empty +while ( 1 ) { + + print "Enter the sensor name: "; + $sensorname = ; + chomp $sensorname; + + # Check for bad names + if (-d $sensorname or $sensorname eq "") { + + print "Sensor name already chosen or illegal. Choose new one...\n"; + + } else { + + mkdir($sensorname); + last; + } +} + + +# Hash where everything gets stored before written to file +my %file; + +# Trap sig int +$SIG{INT} = sub { +# + open(RESULTS_FH, '>', "results.db") or die $!; + print RESULTS_FH "$_\t$file{$_}\n" foreach (keys %file); + close RESULTS_FH; + die "\nAbort.\n" +}; + + +$file{"SensorName"} = $sensorname; + + + + +my $irraddeg; + +while ( 1 ) { + + print "TID dose [kRad]: "; + $irraddeg = ; + chomp $irraddeg; + + # Check if numeric and within good current range + if ($irraddeg =~ /^\d{1,4}$/ ) { + last; + } elsif ($irraddeg eq "") { + $irraddeg = 1000; + last; + } else { + print "Invalid value (letters).\n"; + } +} + + + + + +my $backbias; + +do { + my $socket = IO::Socket::INET->new( + PeerAddr => $peer, + PeerPort => $port, + Proto => "tcp", + Type => SOCK_STREAM ) + or die "ERROR: Cannot connect: $@"; + + usleep 1e5; print $socket "INST OUT$bbCh\n"; + usleep 1e5; print $socket "MEAS:VOLT?\n"; + $backbias = <$socket>; + chomp $backbias; + $backbias = 1000 * $backbias; + print "Back bias: $backbias mV\n"; + +} while ask_continue(); + + + +print "\n"; +print "#############################################################################\n"; +print "### CHIPID TEST ###\n"; +print "#############################################################################\n"; +print "\n"; + +# goto MFETESTS; + goto POWERINGTEST; + + + +my @chipids = ( 0x0, 0x1 ); + +my $gpioReg = 0xd580; +my $testreg = 0x0020; # Pixel control register for testing +my $testval = 0x1; +my $shouldKill = 0; + +do { + foreach my $id (@chipids) { + + # Reset all + my $bitmaskClear = 0x1 << 30; + + trb_register_clearbit( + $fpgalink, + $gpioReg, + $bitmaskClear + ); + + usleep($slow2); + + # Set desired bits + my $bitmaskSet = $id << 30; + + trb_register_setbit( + $fpgalink, + $gpioReg, + $bitmaskSet + ); usleep($slow2); + + Mimosis::set_chipid($id); + + my $tmp = + Mimosis::mimosis_register_read( + $testreg, + ); + + usleep($slow2); + + Mimosis::mimosis_register_write( + $testreg, + $testval, + ); + + usleep(100000); + + my $testTmp = + Mimosis::mimosis_register_read( + $testreg, + ); + + usleep($slow2); + + if ( ( $testTmp&0xff ) != $testval ) { + + print "Chip-ID $id not working.\n"; + $file{"CHIP-ID_$id"} = "F"; + $shouldKill += 1; + + } else { + + $file{"CHIP-ID_$id"} = "S"; + } + } +} while ask_continue(); + +# die "Found broken chip ids. Exiting.\n" if $shouldKill; + +# Reset chipid to 0x1 +Mimosis::set_chipid(0x1); + +trb_register_setbit( + $fpgalink, + $gpioReg, + 0x1 << 30 + ); + +usleep($slow2); + + + + + +print "\n"; +print "############################################################################\n"; +print "### REGISTER TEST - STD ADDR ###\n"; +print "############################################################################\n"; +print "\n"; + +my %regliststd = ( + 0x0021 => 0x6e, # TRIMDAC + 0x0029 => 0x11, # PLL + 0x002a => 0x38, # PLLLOCK + 0x002c => 0x15, # SLVSTX + 0x002d => 0x08, # SLVSRX + 0x0043 => 0xab, # VRESET + 0x004e => 0x7d, # IBUFBIAS +); + +Mimosis::mimosis_instr_write(0xe0); # Send global reset to sensor# +#usleep($slow2); + +do { + + # Mimosis::mimosis_instr_write(0xe0); # Send global reset to sensor + # usleep($slow2); + + while( my ($reg, $val) = each(%regliststd) ) { + + # Get test value + my $testVal = + Mimosis::mimosis_register_read( $reg ); + + # Compare + print("$testVal != $val\n") unless $testVal == $val; + + $file{'Register Read: ' . $reg} = + $testVal == $val ? "GOOD" : "BAD"; + } + + system("./../start.sh"); + +} while ask_continue(); + + +DACREGTEST: + +print "\n"; +print "############################################################################\n"; +print "### REGISTER TEST - DAC ADDR ###\n"; +print "############################################################################\n"; +print "\n"; + +# my %reglistdac = ( +# 0x0040 => 0x40, +# 0x0041 => 0x34, +# 0x0042 => 0x1c, +# 0x0043 => 0xAB, +# 0x0044 => 0x57, +# 0x0045 => 0x68, +# 0x0046 => 0x0 , +# 0x0047 => 0x43, +# 0x0048 => 0x53, +# 0x0049 => 0x53, +# 0x004A => 0x53, +# 0x004B => 0x53, +# 0x004C => 0x53, +# 0x004D => 0x32, +#); + + + +# foreach my $dacOuter (keys %Mimosis::DAC) { +# +# foreach my $dacInner (keys %Mimosis::DAC) { +# +# my $monval = $Mimosis::DAC{$dacInner}{'MONVAL'}; +# my $monitor = $Mimosis::DAC{$dacInner}{'MONITOR'}; +# +# if( defined $monval ) { +# +# my $dacRegOuter = $Mimosis::DAC{$dacOuter}{'ADDR'}; +# my $dacRegInner = $Mimosis::DAC{$dacInner}{'ADDR'}; +# +# Mimosis::mimosis_register_write( $dacRegInner, 100 ); +# Mimosis::mimosis_register_write( $dacRegOuter, 0 ); +# +# print "$dacOuter $dacInner $monitor $monval\n"; +# +# my $tmpVal = $Mimosis::DAC{$dacOuter}{'MONVAL'}; +# my $tmpMon = $Mimosis::DAC{$dacOuter}{'MONITOR'}; +# +# $Mimosis::DAC{$dacOuter}{'MONVAL'} = $monval; +# $Mimosis::DAC{$dacOuter}{'MONITOR'} = $monitor; +# +# my %test = Mimosis::mimosis_dacscan( +# dacs => [$dacOuter, ], +# start => 100, +# stop => 102, +# ); +# +# my $res = $test{$dacOuter}{'Y'}[0]; +# +# print("$res\n") if $res > 100; +# +# $Mimosis::DAC{$dacOuter}{'MONVAL'} = $tmpVal; +# $Mimosis::DAC{$dacOuter}{'MONITOR'} = $tmpMon; +# } +# } +#} + +my $settingsDACRegTest = "../CONF_DACRegisterTest.pl"; +Mimosis::mimosis_load_file( file => $settingsDACRegTest ); + + +do { + my $errorCounter = 0; + foreach my $dacOuter (keys %Mimosis::DAC) { # DAC to be changed + + foreach my $dacInner (keys %Mimosis::DAC) { # DAC to be monitored + + my $monval = $Mimosis::DAC{$dacInner}{'MONVAL'}; + my $monitor = $Mimosis::DAC{$dacInner}{'MONITOR'}; + + if( defined $monval ) { + + my $dacRegOuter = $Mimosis::DAC{$dacOuter}{'ADDR'}; + my $dacRegInner = $Mimosis::DAC{$dacInner}{'ADDR'}; + + Mimosis::mimosis_register_write( $dacRegInner, 0 ); + Mimosis::mimosis_register_write( $dacRegOuter, 200 ); + + # print "$dacOuter $dacInner $monitor $monval\n"; + + my $tmpVal = $Mimosis::DAC{$dacOuter}{'MONVAL'}; + my $tmpMon = $Mimosis::DAC{$dacOuter}{'MONITOR'}; + + $Mimosis::DAC{$dacOuter}{'MONVAL'} = $monval; #dacInner + $Mimosis::DAC{$dacOuter}{'MONITOR'} = $monitor; #dacInner + + my %test = Mimosis::mimosis_dacscan( + dacs => [$dacOuter], + start => 100, + stop => 102, + ); + + Mimosis::mimosis_register_write( $dacRegOuter, 0 ); + + my $res = $test{$dacOuter}{'Y'}[0]; + $errorCounter = $errorCounter + 1 if $res > 500; + print("$res \n"); + + $Mimosis::DAC{$dacOuter}{'MONVAL'} = $tmpVal; + $Mimosis::DAC{$dacOuter}{'MONITOR'} = $tmpMon; + } + } + } + + print($errorCounter); + $file{'DAC Reg R/W Test: '} = + ($errorCounter <= 14) ? "GOOD" : "BAD"; + $errorCounter <= 14 ? print("DAC REG TEST GOOD\n") : print("DAC REG TEST BAD\n"); +} while ask_continue(); + +# FIXME Problem with writing to file + +#Mimosis::mimosis_instr_write($fpgalink, 0xe0); # Send proper settings back to sensor FIXME Find Benes Value +#usleep($slow2); + + +print "\n"; +print "############################################################################\n"; +print "### REGISTER TEST - STD R&W ###\n"; +print "############################################################################\n"; +print "\n"; + + +# Test of read/write operation + +my %reglistgenconfrw = ( + 0x0020 => 0x02, # RUNMODE + 0x0025 => 0x00, # MONCURR + 0x0026 => 0x00, # MONVOLT + 0x0027 => 0x00, # CLKGEN1 + 0x0028 => 0x00, # CLKGEN2 + 0x0029 => 0x11, # PLL + 0x002a => 0x38, # PLLLOCK + 0x002c => 0x15, # SLVSTX + 0x002d => 0x08, # SLVSRX + 0x002e => 0x00, # OUTPUT +); + +my %testwordsgenconfrw = ( + 0x00, + 0xff, + 0xaa, + 0x55, + 0xdb, + 0x44, + 0xcd, + 0x85, +); + + +do { + + while( my ($reg, $val) = each(%reglistgenconfrw) ) { + + # Save original value into register + my $tmp = Mimosis::mimosis_register_read( + #$fpgalink, + $reg, + ); #usleep($slow2); # + + while (my $testword = each(%testwordsgenconfrw)) { + + # Write test value + Mimosis::mimosis_register_write( + #$fpgalink, + $reg, + $testword, + ); #usleep($slow2); # write value into register + + # Get test value + my $testVal = Mimosis::mimosis_register_read( + #$fpgalink, + $reg, + #$singleaccessmode + ); #usleep($slow2); # + + + + # Compare + print("$testVal != $testword\n") unless $testVal == $testword; + } + + # Write original value back into register + Mimosis::mimosis_register_write( + #$fpgalink, + $reg, + $tmp, + #$singleaccessmode + ); #usleep($slow2); + } + +} while ask_continue(); + +#system("./../start.sh"); +#sleep(2); + + +# print "\n"; +# print "############################################################################\n"; +# print "### LINK TEST ###\n"; +# print "############################################################################\n"; +# print "\n"; + +# do { +# my $currentWd = Cwd::cwd(); +# chdir("/d/jspc37/mimosis/scripts"); +# system("/d/jspc37/mimosis/scripts/start.sh"); +# chdir($currentWd); + +# my $cntBadLinks = 0; + +# for my $i (0 .. 7) { + +# my $reg = trb_register_read( $fpgalink, 0xa000 + $i ); +# $reg = ( $reg->{$fpgalink} & 0x7f00 ) >> 8; + +# $cntBadLinks += 1 if $reg >= 70; + +# $file{"Link_$i"} = $reg >= 70 ? "$reg\tBAD" : "$reg\tGOOD"; +# } + +# # die "Bad links. Exiting.\n" if $cntBadLinks > 0; +# print "Bad links.\n" if $cntBadLinks > 0; + +# } while ask_continue(); + + + + + +print "\n"; +print "#############################################################################\n"; +print "### BB TEST ###\n"; +print "#############################################################################\n"; +print "\n"; + +open(BB_FH, '>', $sensorname . "/bb.csv") or die $!; + +BBTEST: +do { + my $socket = IO::Socket::INET->new( + PeerAddr => $peer, + PeerPort => $port, + Proto => "tcp", + Type => SOCK_STREAM, + ) + or die "ERROR: Cannot connect: $@"; + + # Save current BB seting for later + usleep 1e0; print $socket "INST OUT$bbCh\n"; + usleep 1e5; print $socket "MEAS:VOLT?\n"; + my $tmp = <$socket>; + chomp $tmp; + + for (my $i = 0; $i <= 5.0; $i += 0.5) { + + usleep 1e5; print $socket "VOLT $i\n"; + usleep 1e5; print $socket "MEAS:VOLT?\n"; my $volt = <$socket>; + usleep 1e5; print $socket "MEAS:CURR?\n"; my $curr = <$socket>; + + chomp $volt; + chomp $curr; + + print BB_FH "$volt\t$curr\n"; + } + + # Reset BB to what it was before + usleep 1e5; print $socket "VOLT $tmp\n"; + +} while ask_continue(); + +close BB_FH; + + +POWERINGTEST: + + +print "\n"; +print "###########################################################################\n"; +print "### POWERING TEST DIGITAL ###\n"; +print "###########################################################################\n"; +print "\n"; + +#Find out current drawn by sensor on digital and perform data checks. +my $lowleveldig = 100; # Minimum digital current for passing as ok +my $highleveldig = 200; # Maximum digital current for passing as ok + + +do { + my $adc_addr = 0x48; + my $adc_wreg = 0x1; + my $adc_cmd = 0xc380; #CHANGE ME + my $adc_rreg = 0x0; + my $adcConv = ( 2 * 4096 ) / (2**16 * 10); + + Mimosis::adc_i2c_command( + $adc_addr, + $adc_wreg, + $adc_cmd, + 0, 0, 1 + ); + + usleep($adcSlow); + + my $digitalcur = + Mimosis::adc_i2c_command( + $adc_addr, + $adc_rreg, + 0x0, + 1, 0, 1 ); + + usleep($adcSlow); + + $digitalcur *= $adcConv; + + # Check if numeric and within good current range + if ( $digitalcur <= $highleveldig && + $digitalcur >= $lowleveldig ) + { + $file{"Digitalcurrent"} = $digitalcur; + print "Digital current: $digitalcur mA.\n"; + + } else { + + print "Digital current not in range: $digitalcur.\n"; + $file{"Digitalcurrent"} = "F"; + } + +} while ask_continue(); + + + + + +print "\n"; +print "############################################################################\n"; +print "### POWERING TEST ANALOG ###\n"; +print "############################################################################\n"; +print "\n"; + +#Find out current drawn by sensor on analog and perform data checks. +my $lowlevelana = 5; # Minimum analog current for passing as ok +my $highlevelana = 30; # Maximum analog current for passing as ok + + +do { + my $adc_addr = 0x48; + my $adc_wreg = 0x1; + my $adc_cmd = 0xf380; #CHANGE ME + my $adc_rreg = 0x0; + my $adcConv = ( 2 * 4096 ) / (2**16 * 100); + + Mimosis::adc_i2c_command( + $adc_addr, + $adc_wreg, + $adc_cmd, + 0, 0, 1 + ); + + usleep($adcSlow); + + my $analogcur = + Mimosis::adc_i2c_command( + $adc_addr, + $adc_rreg, + 0x0, + 1, 0, 1 ); + + usleep($adcSlow); + + $analogcur *= $adcConv; + + # Check if numeric and within good current range + if( $analogcur <= $highlevelana && + $analogcur >= $lowlevelana ) + { + $file{"Analogcurrent"} = $analogcur; + print "Analog current: $analogcur mA.\n"; + + } else { + + print "Analog current not in range: $analogcur.\n"; + $file{"Analogcurrent"} = "F"; + } + +} while ask_continue(); + + +# print "$_\t$file{$_}\n" foreach (keys %file); + + + + + +print "\n"; +print "############################################################################\n"; +print "### FAST DACSCAN TEST ###\n"; +print "############################################################################\n"; +print "\n"; + + +chdir($sensorname); + +do { + my @DACFAST = ('VPH', 'VPL', 'VPHFINE'); + + my %results = Mimosis::mimosis_dacscan( + dacs => \@DACFAST, + step => 10, + ); + + + my $picName = "fastdacscan.png"; + + my $chart = Chart::Gnuplot->new( + output => $picName, + terminal => "pngcairo", + title => "DAC-Scan", + xlabel => "Setting [LSB]", + ylabel => "Voltage output [mV]", + ); + + + my @dataArr; + + $chart->polygon( + vertices => [ + "0, 1100", + "250, 1375", + "250, 1225", + "0, 1000", + "0, 1100", + ], + fill => { + density => 0.3, + color => "#A9A9A0", + }, + ); + + $chart->polygon( + vertices => [ + "0, 370", + "250, 1950", + "250, 1670", + "0, 320", + "0, 370", + ], + fill => { + density => 0.3, + color => "#A9A9A0", + }, + ); + + for my $dac ( keys %results ) { + + my $dataSet = Chart::Gnuplot::DataSet->new( + xdata => $results{$dac}{X}, + ydata => $results{$dac}{Y}, + title => "Plotting a line from Perl arrays", + style => "linespoints", + ); + + push(@dataArr, $dataSet); + } + + $chart->plot2d(@dataArr); + + system("display $picName"); + + + print "Please enter rapid DAC scan result classification.\n"; + print "S = satisfactory if in grey areas\n"; + print "F = unsatisfactory and exiting.\n"; + + while ( 1 ) { + + print "Rapid DAC scan classification: "; + my $rapiddacclass = ; + chomp $rapiddacclass; + + if ( $rapiddacclass eq "S" || + $rapiddacclass eq "s" ) { + + $file{"RapidDACTest"} = "S"; + last; + + } elsif ( $rapiddacclass eq "F" || + $rapiddacclass eq "f" ) { + + $file{"RapidDACTest"} = "F"; + exit 0; + + } else { + print "Invalid classification. Try again.\n"; + } + } + +} while ask_continue(); + + + + + +print "\n"; +print "############################################################################\n"; +print "### DACSCAN TEST ###\n"; +print "############################################################################\n"; +print "\n"; + +my $VPHFSlope; +my $VPHOffsetElectron; + +do { + my %names = ( + 'IBIAS' => 0x0040, + 'ITHR' => 0x0041, + 'IDB' => 0x0042, + 'VRESET' => 0x0043, + 'VPL' => 0x0044, + 'VPH' => 0x0045, + 'VPHFINE' => 0x0046, + 'VCASP' => 0x0047, + 'VCASNA' => 0x0048, + 'VCASNB' => 0x0049, + 'VCASNC' => 0x004a, + 'VCASND' => 0x004b, + 'VCASN2' => 0x004c, + 'VCLIP' => 0x004d, + # 'IBUFBIAS' => 0x004e, + ); + + my %dacVals = Mimosis::mimosis_dacscan( + # step => 50, + ); + + + my @VPHList = @{$dacVals{'VPH'}{'Y'}}; + my @VPLList = @{$dacVals{'VPL'}{'Y'}}; + my @VPHFINEList = @{$dacVals{'VPHFINE'}{'Y'}}; + my @VRESETList = @{$dacVals{'VRESET'}{'Y'}}; + my @VCASNAList = @{$dacVals{'VCASNA'}{'Y'}}; + my @VCASNBList = @{$dacVals{'VCASNB'}{'Y'}}; + my @VCASNCList = @{$dacVals{'VCASNC'}{'Y'}}; + my @VCASNDList = @{$dacVals{'VCASND'}{'Y'}}; + my @VCASN2List = @{$dacVals{'VCASN2'}{'Y'}}; + my @VCLIPList = @{$dacVals{'VCLIP'}{'Y'}}; + my @VCASPList = @{$dacVals{'VCASP'}{'Y'}}; + my @IBIASList = @{$dacVals{'IBIAS'}{'Y'}}; + my @ITHRList = @{$dacVals{'ITHR'}{'Y'}}; + my @IDBList = @{$dacVals{'IDB'}{'Y'}}; + + + my $picName = "full-dacscan.png"; + + my $chartPng = Chart::Gnuplot->new( + output => $picName, + terminal => "pngcairo", + title => "DAC-Scan", + xlabel => "Setting [LSB]", + ylabel => "Voltage output [mV]", + ); + + my @dataArr; + + for my $dac ( keys %dacVals) { + + my $dataSet = Chart::Gnuplot::DataSet->new( + xdata => $dacVals{$dac}{X}, + ydata => $dacVals{$dac}{Y}, + title => $dac, + style => "lines", + ); + + push(@dataArr, $dataSet); + } + + $chartPng->plot2d(@dataArr); + + system("display $picName"); + + + for my $i (0 .. scalar( @VPHFINEList ) - 1) { + $VPHFINEList[$i] = $VPHFINEList[$i] - $VPHList[0]; + } + + + my $sensorQuality = 4; + + my $VPHOffset = $VPHList[0]; + my $VPLOffset = $VPLList[0]; + my $VRESETOffset = $VRESETList[0]; + my $VPHFOffset = $VPHFINEList[0]; + my $VPH210 = $VPHList[211]; + my $VPL210 = $VPLList[211]; + my $VRESET210 = $VRESETList[211]; + my $VPHF210 = $VPHFINEList[211] - $VPHFOffset; + + + if ( (300 <= $VPHOffset) && + (375 >= $VPHOffset) && + (300 <= $VPLOffset) && + (375 >= $VPLOffset) && + (300 <= $VRESETOffset) && + (375 >= $VRESETOffset) && + ($VPH210 >= 1410) && + ($VPL210 >= 1410) && + ($VRESET210 >= 1410) && + ($VPHFOffset <= 20) && + ($VPHF210 >= 190) ) { + + $sensorQuality = 3; + + if ( max(@VCASNAList) > 1100 && + max(@VCASNBList) > 1100 && + max(@VCASNCList) > 1100 && + max(@VCASNDList) > 1100 && + max(@VCASN2List) > 1100 && + max(@VCLIPList) > 550 && + max(@VCASPList) > 550 && + max(@IBIASList) >= 260 && + max(@ITHRList) >= 260 && + max(@IDBList) >= 260 ) { + + $sensorQuality = 2; + + my $arrRef = [ 3,3,3,3 + ]; + + sub calcAbsDNLAbsINL { + + my @dac = @{$_[0]}; + + my $gain = ($dac[199] - $dac[24]) / 175.0; + + my @dnl = ( 0 ); + my @inl = ( 0 ); + + for my $i (21 .. 201) { + + my $currentDNL = ( ($dac[$i] - $dac[$i-1]) / $gain ) - 1; + push(@dnl, $currentDNL); + push(@inl, $inl[$i-21]+$currentDNL); + } + + @dnl = reverse @dnl; + @inl = reverse @inl; + return ( \@inl, \@dnl ); + } + + + my ( $ibiasinlRef, $ibiasdnlRef ) = calcAbsDNLAbsINL(\@IBIASList); + my @IBIASINL = @{$ibiasinlRef}; + my @IBIASDNL = @{$ibiasdnlRef}; + + my ( $ithrinlRef, $ithrdnlRef ) = calcAbsDNLAbsINL(\@ITHRList); + my @ITHRINL = @{$ithrinlRef}; + my @ITHRDNL = @{$ithrdnlRef}; + + my ( $idbinlRef, $idbdnlRef ) = calcAbsDNLAbsINL(\@IDBList); + my @IDBINL = @{$idbinlRef}; + my @IDBDNL = @{$idbdnlRef}; + + my ( $vphinlRef, $vphdnlRef ) = calcAbsDNLAbsINL(\@VPHList); + my @VPHINL = @{$vphinlRef}; + my @VPHDNL = @{$vphdnlRef}; + + my ( $vplinlRef, $vpldnlRef ) = calcAbsDNLAbsINL(\@VPLList); + my @VPLINL = @{$vplinlRef}; + my @VPLDNL = @{$vpldnlRef}; + + my ( $vresetinlRef, $vresetdnlRef ) = calcAbsDNLAbsINL(\@VRESETList); + my @VRESETINL = @{$vresetinlRef}; + my @VRESETDNL = @{$vresetdnlRef}; + + my ( $vphfineinlRef, $vphfinednlRef ) = calcAbsDNLAbsINL(\@VPHFINEList); + my @VPHFINEINL = @{$vphfineinlRef}; + my @VPHFINEDNL = @{$vphfinednlRef}; + + my ( $vcasnainlRef, $vcasnadnlRef ) = calcAbsDNLAbsINL(\@VCASNAList); + my @VCASNAINL = @{$vcasnainlRef}; + my @VCASNADNL = @{$vcasnadnlRef}; + + my ( $vcasnbinlRef, $vcasnbdnlRef ) = calcAbsDNLAbsINL(\@VCASNBList); + my @VCASNBINL = @{$vcasnbinlRef}; + my @VCASNBDNL = @{$vcasnbdnlRef}; + + my ( $vcasncinlRef, $vcasncdnlRef ) = calcAbsDNLAbsINL(\@VCASNCList); + my @VCASNCINL = @{$vcasncinlRef}; + my @VCASNCDNL = @{$vcasncdnlRef}; + + my ( $vcasndinlRef, $vcasnddnlRef ) = calcAbsDNLAbsINL(\@VCASNDList); + my @VCASNDINL = @{$vcasndinlRef}; + my @VCASNDDNL = @{$vcasnddnlRef}; + + my ( $vcasn2inlRef, $vcasn2dnlRef ) = calcAbsDNLAbsINL(\@VCASN2List); + my @VCASN2INL = @{$vcasn2inlRef}; + my @VCASN2DNL = @{$vcasn2dnlRef}; + + my ( $vcaspinlRef, $vcaspdnlRef ) = calcAbsDNLAbsINL(\@VCASPList); + my @VCASPINL = @{$vcaspinlRef}; + my @VCASPDNL = @{$vcaspdnlRef}; + + my ( $vclipinlRef, $vclipdnlRef ) = calcAbsDNLAbsINL(\@VCLIPList); + my @VCLIPINL = @{$vclipinlRef}; + my @VCLIPDNL = @{$vclipdnlRef}; + + my $goodDNL = 0; + + if ( $IBIASDNL[2] < 1 + && $ITHRDNL[2] < 1 + && $IDBDNL[2] < 1 + && $VCASNADNL[2] < 1 + && $VCASNBDNL[2] < 1 + && $VCASNCDNL[2] < 1 + && $VCASNDDNL[2] < 1 + && $VCASN2DNL[2] < 1 + && $VCASPDNL[2] < 1 + && $VCLIPDNL[2] < 1 + && $VPHDNL[2] < 1 + && $VPLDNL[2] < 1 + && $VRESETDNL[2] < 1 + && $VPHFINEDNL[2] < 1 + ) { + $goodDNL = 1; + } + + my $goodINL = 0; + + if ( $IBIASINL[2] < 5 + && $ITHRINL[2] < 5 + && $IDBINL[2] < 5 + && $VCASNAINL[2] < 5 + && $VCASNBINL[2] < 5 + && $VCASNCINL[2] < 5 + && $VCASNDINL[2] < 5 + && $VCASN2INL[2] < 5 + && $VCASPINL[2] < 5 + && $VCLIPINL[2] < 5 + && $VPHINL[2] < 1 + && $VPLINL[2] < 1 + && $VRESETINL[2] < 1 + && $VPHFINEINL[2] < 1 + ) { + $goodINL = 1; + } + + if ($goodDNL && $goodINL) { + $sensorQuality = 1; + } + } + } + + $VPHFSlope = ($VPHFINEList[255] - $VPHFINEList[0]) / 255.0; + # $VPHFSlope = 1.; + $VPHOffsetElectron = 150; + $ZeroElectronVPHSetting = 95; + + for my $i (0 .. scalar(@VPHList)) { + + if ( ($VPHList[$i] gt ($VPLList[70] - 6)) # or ($VPHList[$i] lt ($VPLList[70] + 6)) + ) { + + $ZeroElectronVPHSetting = $i; + $VPHOffsetElectron = $VPHList[$i] - $VPLList[70]; + last; + } + } + + print("ZeroSetting\t$ZeroElectronVPHSetting\t$VPHOffsetElectron\n"); + + print("Sensor Quality for DACs: $sensorQuality\n"); + + $file{"DACQuality"} = $sensorQuality; + $file{"VPHFSlope"} = $VPHFSlope; + $file{"VPHSetting0Electrons"} = "$ZeroElectronVPHSetting\t$VPHOffsetElectron"; + +} while ask_continue(); + + + +SCURVES: + +sub fit_thr { + my ($fname, $vphOffsetElectron, $vphfSlope, $vphStepSize) = @_; + Mimosis::mimosis_make_fit($fname, $vphOffsetElectron, $VPHFSlope, $vphStepSize); + # system("/usr/bin/python3 /d/jspc37/mimosis/scripts/pulse/fit-raw.py $fname $dirName $vphOffsetElectron $vphfSlope"); +} + + + +my %matrixParams = ( + A => { + VCASN => 0x48, + YSPAN => 4, + XSTART => 0, + XSTOP => 127, + }, +# B => { +# VCASN => 0x49, +# YSPAN => 2, +# XSTART => 128, +# XSTOP => 511, +# }, +# C => { +# VCASN => 0x4a, +# YSPAN => 2, +# XSTART => 512, +# XSTOP => 894, +# }, +# D => { +# VCASN => 0x4b, +# YSPAN => 4, +# XSTART => 895, +# XSTOP => 1023, +# }, + ); + +print "\n"; +print "############################################################################\n"; +print "### SCURVE TEST ###\n"; +print "############################################################################\n"; +print "\n"; + +$matrixParams{'A'}{'LOWERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 95 : +(( $backbias == 1000 && $irraddeg >= 1000 ) ? 60 : (( $backbias == 1000 && $irraddeg == 0 ) ? 70 : (( $backbias == 3000 && $irraddeg == 0 ) ? 110 : 50 ))); + +$matrixParams{'A'}{'UPPERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 120 : +(( $backbias == 1000 && $irraddeg >= 1000 ) ? 100 : (( $backbias == 1000 && $irraddeg == 0 ) ? 115 : (( $backbias == 3000 && $irraddeg == 0 ) ? 165 : 200 ))); + + +# $matrixParams{'B'}{'LOWERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 100 : +# (( $backbias == 1000 && $irraddeg >= 1000 ) ? 75 : (( $backbias == 1000 && $irraddeg == 0 ) ? 95 : (( $backbias == 3000 && $irraddeg == 0 ) ? 130 : 50 ))); +# +# $matrixParams{'B'}{'UPPERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 150 : +# (( $backbias == 1000 && $irraddeg >= 1000 ) ? 125 : (( $backbias == 1000 && $irraddeg == 0 ) ? 140 : (( $backbias == 3000 && $irraddeg == 0 ) ? 185 : 200 ))); +# +# +# $matrixParams{'C'}{'LOWERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 100 : +# (( $backbias == 1000 && $irraddeg >= 1000 ) ? 75 : (( $backbias == 1000 && $irraddeg == 0 ) ? 95 : (( $backbias == 3000 && $irraddeg == 0 ) ? 130 : 50 ))); +# +# $matrixParams{'C'}{'UPPERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 150 : +# (( $backbias == 1000 && $irraddeg >= 1000 ) ? 125 : (( $backbias == 1000 && $irraddeg == 0 ) ? 140 : (( $backbias == 3000 && $irraddeg == 0 ) ? 185 : 200 ))); +# +# +# $matrixParams{'D'}{'LOWERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 95 : +# (( $backbias == 1000 && $irraddeg >= 1000 ) ? 60 : (( $backbias == 1000 && $irraddeg == 0 ) ? 75 : (( $backbias == 3000 && $irraddeg == 0 ) ? 115 : 50 ))); +# +# $matrixParams{'D'}{'UPPERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 120 : +# (( $backbias == 1000 && $irraddeg >= 1000 ) ? 100 : (( $backbias == 1000 && $irraddeg == 0 ) ? 140 : (( $backbias == 3000 && $irraddeg == 0 ) ? 180 : 200 ))); + + +do { + my $settingsScurves = "../CONF_scurves.pl"; + + cp($settingsScurves, "$sensorname/$settingsScurves"); + + Mimosis::mimosis_load_file( file => $settingsScurves ); + + + Mimosis::mimosis_register_write( + 0x45, + $ZeroElectronVPHSetting, + ); + + Mimosis::mimosis_register_write( + 0x4d, + int( 45 + $backbias/1000.0 * 12.0 + 0.5 ), + ); + + + + print "Press Enter, to start pulsing.\n"; + ; + + + foreach my $matrix ( sort keys %matrixParams ) { + + my $yspan = $matrixParams{$matrix}{'YSPAN'}; + my $xstart = $matrixParams{$matrix}{'XSTART'}; + my $xstop = $matrixParams{$matrix}{'XSTOP'}; + + Mimosis::mimosis_instr_write( 0x3f ); + Mimosis::mimosis_instr_write( 0x04 ); + Mimosis::mimosis_instr_write( 0x3e ); + + Mimosis::mimosis_register_write(0x46, 255); + + Mimosis::mimosis_pulse( + ystart => 250, + ystop => 253, + yspan => $yspan, + xstart => $xstart, + xstop => $xstop, + modexp => 3, + ); + + my $ll = $matrixParams{$matrix}{'LOWERLIMIT'}; + my $ul = $matrixParams{$matrix}{'UPPERLIMIT'}; + + print "Find proper VCASN in Go4. Suggested range: $ll - $ul\n"; + + my $foundF = 0; + + while ( 1 ) { + + print "Enter the appropriate VCASN$matrix value or \'F\' if bad: " ; + + my $vcasnTmp = ; + chomp $vcasnTmp; + + if ( $vcasnTmp eq "F" or + $vcasnTmp eq "f" ) { + + $file{"CoarseSCurves,MATRIX-$matrix"} = "F"; + + $foundF = 1; + last; + + } else { + + $file{"CoarseSCurves,MATRIX-$matrix"} = $vcasnTmp; + $matrixParams{$matrix}{"VCASNCOARSE"} = $vcasnTmp; + last; + } + } + + exit 0 if $foundF; + } + + + + print "Press Enter, to start scuves\n"; + ; + + foreach my $matrix ( sort keys %matrixParams ) { + + my $matrixDir = "MATRIX-" . $matrix; + mkdir($matrixDir); + chdir($matrixDir); + + my $yspan = $matrixParams{$matrix}{'YSPAN'}; + my $xstart = $matrixParams{$matrix}{'XSTART'}; + my $xstop = $matrixParams{$matrix}{'XSTOP'}; + my $vcasnstart = $matrixParams{$matrix}{"VCASNCOARSE"} - 1; #-5 + my $vcasnstop = $matrixParams{$matrix}{"VCASNCOARSE"} + 1; #+5 + + Mimosis::mimosis_scurves( + ystart => 250, + ystop => 253, + yspan => $yspan, + xstart => $xstart, + xstop => $xstop, + vcasnreg => 'VCASN' . $matrix, + vcasnstart => $vcasnstart, + vcasnstop => $vcasnstop, + setstep => $vphStepSize, + ); + + opendir my $dir, "." or die "Cannot open directory: $!"; + my @files = readdir $dir; + + foreach my $f ( @files ) { + + if ( $f =~ /VCASN/ ) { + + my $dirName = Cwd::cwd() . "/$f"; + + chdir($dirName); + + $matrixParams{$matrix}{"THREAD"} = + threads->create( \&fit_thr, + "$f.csv", + $VPHOffsetElectron, + $VPHFSlope, + $vphStepSize); + + chdir(".."); + } + } + + closedir $dir; + chdir(".."); + } + + + + + print "Wait for fits to finish.\n"; + + foreach my $matrix ( keys %matrixParams ) { + $matrixParams{$matrix}{"THREAD"}->join(); + } + + + + + print("Approximate a VCASN for each submatrix where the GMDT is closest to 150 e!\n"); + + my $foundF = 0; + + foreach my $matrix ( sort keys %matrixParams ) { + + while ( 1 ) { + + print "Enter the appropriate VCASN$matrix value or \'F\' if bad: " ; + + my $vcasnTmp = ; + chomp $vcasnTmp; + + if ( $vcasnTmp eq "F" or + $vcasnTmp eq "f" ) { + + $file{"RapidSCurves,MATRIX-$matrix"} = "F"; + + $foundF = 1; + last; + + } else { + + $file{"SCurvesFull,MATRIX-$matrix"} = $vcasnTmp; + $matrixParams{$matrix}{"VCASNFINAL"} = $vcasnTmp; + last; + } + } + } + if ( $foundF ) { exit 0; } + +} while ask_continue(); + + + + + + + + +do { + print "\n"; + print "############################################################################\n"; + print "### SCURVE TEST, FINAL ###\n"; + print "############################################################################\n"; + print "\n"; + + +# my $lowerlimitA = $matrixParams{"A"}{"PREV-VCASN"} - 2; +# my $upperlimitA = + 2; + +# my $lowerlimitB = $prevFoundB - 2; +# my $upperlimitB = $prevFoundB + 2; + +# my $lowerlimitC = $prevFoundC - 2; +# my $upperlimitC = $prevFoundC + 2; +# +# my $lowerlimitD = $prevFoundD - 2; +# my $upperlimitD = $prevFoundD + 2; + + + #Mimosis::mimosis_register_write( 0x45, $SixtyElectronVPHSetting ); + + my $settingsScurves = "../CONF_scurves.pl"; + + cp($settingsScurves, "$sensorname/$settingsScurves"); + + Mimosis::mimosis_load_file( + file => $settingsScurves + ); + + #Mimosis::mimosis_register_write( + #0x4D, + #int( 45 + $backbias/1000.0 * 12.0 + 0.5 ) + #); + + + foreach my $matrix ( sort keys %matrixParams ) { + + my $matrixDir = "MATRIXFINAL-" . $matrix; + mkdir($matrixDir); + chdir($matrixDir); + + Mimosis::mimosis_register_write( + 0x45, + $ZeroElectronVPHSetting, + ); + + Mimosis::mimosis_register_write( + 0x4D, + int( 45 + $backbias/1000.0 * 12.0 + 0.5 ), + ); + + my $vcasnSetting + $matrixParams{$matrix}{"VCASNFINAL"}; + + print("VCASNFINAL SETTING: $vcasnSetting\n"); + + my $yspan = $matrixParams{$matrix}{'YSPAN'}; + my $xstart = $matrixParams{$matrix}{'XSTART'}; + my $xstop = $matrixParams{$matrix}{'XSTOP'}; + my $vcasnstart = $matrixParams{$matrix}{"VCASNFINAL"}; + my $vcasnstop = $matrixParams{$matrix}{"VCASNFINAL"}; + + Mimosis::mimosis_scurves( + ystart => 0, + ystop => 503, + yspan => $yspan, + xstart => $xstart, + xstop => $xstop, + vcasnreg => 'VCASN' . $matrix, + vcasnstart => $vcasnstart, + vcasnstop => $vcasnstop, + ); + + opendir my $dir, "." or die "Cannot open directory: $!"; + my @files = readdir $dir; + + foreach my $f ( @files ) { + + if ( $f =~ /VCASN/ ) { + + my $dirName = Cwd::cwd() . "/$f"; + $matrixParams{$matrix}{"THREAD"} = threads->create(\&fit_thr, "$f.csv", $dirName, $VPHOffsetElectron, $VPHFSlope); + } + } + + closedir $dir; + + chdir(".."); + } + + + + print "Wait for fits to finish.\n"; + foreach my $matrix ( sort keys %matrixParams ) { + $matrixParams{$matrix}{"THREAD"}->join(); + } + + + print("Give VCASN for each submatrix where the GMDT is closest to 150 e!\n"); + + my $foundF = 0; + + foreach my $matrix ( sort keys %matrixParams ) { + + while ( 1 ) { + + print "Enter the appropriate VCASN$matrix value or \'F\' if bad:" ; + + my $vcasnTmp = ; + chomp $vcasnTmp; + + if ( $vcasnTmp eq "F" or + $vcasnTmp eq "f" ) { + + $file{"FineSCurves,MATRIX-$matrix"} = "F"; + + $foundF = 1; + last; + + } else { + + $file{"FineSCurves,MATRIX-$matrix"} = $vcasnTmp; + $matrixParams{$matrix}{"FINE"} = $vcasnTmp; + last; + } + } + } + if ( $foundF ) { exit 0; } + +} while ask_continue(); + +MFETESTS: + +print "\n"; +print "############################################################################\n"; +print "### REGISTER TEST - MFE REGS ###\n"; +print "############################################################################\n"; +print "\n"; + +# Test of read/write operation + +my %reglistmferw = ( + 0x4040 => 0x00, +); + +my %testwordsmferw = ( + 0x00, + 0xff, + 0xaa, + 0x55, + 0x71, + 0xb8, +); + +my $framelengthmsb = Mimosis::mimosis_register_read( + #$fpgalink, + 0x017B, + ); #usleep($slow2); # + +my $framelengthlsb = Mimosis::mimosis_register_read( + #$fpgalink, + 0x007B, + ); #usleep($slow2); # +Mimosis::mimosis_register_write( + #$fpgalink, + 0x017b, + 0xFF, + ); #usleep($slow2); # write value into register + +Mimosis::mimosis_register_write( + #$fpgalink, + 0x007b, + 0xFF, + ); #usleep($slow2); # write value into register + + +do { + + while( my ($reg, $val) = each(%reglistmferw) ) { + + # Save original value into register + my $tmp = Mimosis::mimosis_register_read( + #$fpgalink, + $reg, + ); #usleep($slow2); # + + while (my $testword = each(%testwordsmferw)) { + + # Write test value + Mimosis::mimosis_register_write( + #$fpgalink, + $reg, + $testword, + ); #usleep($slow2); # write value into register + + # Get test value + my $testVal = Mimosis::mimosis_register_read( + #$fpgalink, + $reg, + #$singleaccessmode + ); #usleep($slow2); # + + + + # Compare + print("$testVal != $testword\n") unless $testVal == $testword; + } + + # Write original value back into register + Mimosis::mimosis_register_write( + #$fpgalink, + $reg, + $tmp, + #$singleaccessmode + ); #usleep($slow2); + } + +} while ask_continue(); + +Mimosis::mimosis_register_write( + #$fpgalink, + 0x017b, + $framelengthmsb, + ); #usleep($slow2); # write value into register + +Mimosis::mimosis_register_write( + #$fpgalink, + 0x007b, + $framelengthlsb, + ); #usleep($slow2); # write value into register + + +__END__ + +open(RESULTS_FH, '>', $sensorname . "/results.db") or die $!; +print RESULTS_FH "$_\t$file{$_}\n" foreach (keys %file); +close RESULTS_FH; diff --git a/scripts/qa/oldScripts/QAScript_before22Jun24.pl b/scripts/qa/oldScripts/QAScript_before22Jun24.pl new file mode 100755 index 0000000..a3df6b4 --- /dev/null +++ b/scripts/qa/oldScripts/QAScript_before22Jun24.pl @@ -0,0 +1,1578 @@ +#!/usr/bin/perl + +# MIMOSIS-1 QA Script ... version 0.5 +# +# Authors: Benedict Arnoldi-Meadows and Benedikt Gutsche + +use strict; +use warnings; +use HADES::TrbNet; +use Mimosis; +use Time::HiRes qw( usleep ); +use POSIX; +use Data::Dump qw( dump ); +use List::Util qw( min max ); +use threads; +use IO::Handle; +use IO::Socket; +use File::Temp qw( tempfile ); +use File::Copy qw( cp ); +use Cwd qw(); +use Chart::Gnuplot; + + + +sub ask_continue +{ + print "Repeat test? [y/N]: "; + my $answer = ; + chomp $answer; + + return 0 if $answer eq "" || $answer eq "n" || $answer eq "N"; + return 1; +} + + +my $ZeroElectronVPHSetting = 95; +my $singleaccessmode = 0; +my $slow = 100; +my $slow2 = 100000; +my $adcSlow = 100000; +my $vphStepSize = 5; + +my %fineVCASNParams = (); + + + +my $fpgalink = 0xa000; +my $peer = "192.168.0.61"; +my $port = "5025"; +my $bbCh = 2; +Mimosis::set_fpga($fpgalink); +Mimosis::set_printall(1); +#Mimosis::set_adcToIkfProxy(); + +# my $fpgalink = 0xa100; +# my $peer = "192.168.0.56"; +# my $port = "5050"; +# my $bbCh = 3; +# Mimosis::set_adcToIkfProxy(); +# Mimosis::set_singleAccess(1); + + +printf("Using %x\n", $fpgalink); + + +trb_init_ports() or die trb_strerror(); + +print "\n"; +print "############################################################################\n"; +print "### INIT ###\n"; +print "############################################################################\n"; +print "\n"; + + +my $sensorname; + +# Perform loop until a good name is found, +# i.e. it has never been assigned or is not empty +while ( 1 ) { + + print "Enter the sensor name: "; + $sensorname = ; + chomp $sensorname; + + # Check for bad names + if (-d $sensorname or $sensorname eq "") { + + print "Sensor name already chosen or illegal. Choose new one...\n"; + + } else { + + mkdir($sensorname); + last; + } +} + + +# Hash where everything gets stored before written to file +my %file; + +# Trap sig int +$SIG{INT} = sub { +# + open(RESULTS_FH, '>', "results.db") or die $!; + print RESULTS_FH "$_\t$file{$_}\n" foreach (keys %file); + close RESULTS_FH; + die "\nAbort.\n" +}; + + +$file{"SensorName"} = $sensorname; + + + + +my $irraddeg; + +while ( 1 ) { + + print "TID dose [kRad]: "; + $irraddeg = ; + chomp $irraddeg; + + # Check if numeric and within good current range + if ($irraddeg =~ /^\d{1,4}$/ ) { + last; + } elsif ($irraddeg eq "") { + $irraddeg = 1000; + last; + } else { + print "Invalid value (letters).\n"; + } +} + + + + + +my $backbias; + +do { + my $socket = IO::Socket::INET->new( + PeerAddr => $peer, + PeerPort => $port, + Proto => "tcp", + Type => SOCK_STREAM ) + or die "ERROR: Cannot connect: $@"; + + usleep 1e5; print $socket "INST OUT$bbCh\n"; + usleep 1e5; print $socket "MEAS:VOLT?\n"; + $backbias = <$socket>; + chomp $backbias; + $backbias = 1000 * $backbias; + print "Back bias: $backbias mV\n"; + +} while ask_continue(); + + + +print "\n"; +print "#############################################################################\n"; +print "### CHIPID TEST ###\n"; +print "#############################################################################\n"; +print "\n"; + +# goto MFETESTS; + goto POWERINGTEST; + + + +my @chipids = ( 0x0, 0x1 ); + +my $gpioReg = 0xd580; +my $testreg = 0x0020; # Pixel control register for testing +my $testval = 0x1; +my $shouldKill = 0; + +do { + foreach my $id (@chipids) { + + # Reset all + my $bitmaskClear = 0x1 << 30; + + trb_register_clearbit( + $fpgalink, + $gpioReg, + $bitmaskClear + ); + + usleep($slow2); + + # Set desired bits + my $bitmaskSet = $id << 30; + + trb_register_setbit( + $fpgalink, + $gpioReg, + $bitmaskSet + ); usleep($slow2); + + Mimosis::set_chipid($id); + + my $tmp = + Mimosis::mimosis_register_read( + $testreg, + ); + + usleep($slow2); + + Mimosis::mimosis_register_write( + $testreg, + $testval, + ); + + usleep(100000); + + my $testTmp = + Mimosis::mimosis_register_read( + $testreg, + ); + + usleep($slow2); + + if ( ( $testTmp&0xff ) != $testval ) { + + print "Chip-ID $id not working.\n"; + $file{"CHIP-ID_$id"} = "F"; + $shouldKill += 1; + + } else { + + $file{"CHIP-ID_$id"} = "S"; + } + } +} while ask_continue(); + +# die "Found broken chip ids. Exiting.\n" if $shouldKill; + +# Reset chipid to 0x1 +Mimosis::set_chipid(0x1); + +trb_register_setbit( + $fpgalink, + $gpioReg, + 0x1 << 30 + ); + +usleep($slow2); + + + + + +print "\n"; +print "############################################################################\n"; +print "### REGISTER TEST - STD ADDR ###\n"; +print "############################################################################\n"; +print "\n"; + +my %regliststd = ( + 0x0021 => 0x6e, # TRIMDAC + 0x0029 => 0x11, # PLL + 0x002a => 0x38, # PLLLOCK + 0x002c => 0x15, # SLVSTX + 0x002d => 0x08, # SLVSRX + 0x0043 => 0xab, # VRESET + 0x004e => 0x7d, # IBUFBIAS +); + +Mimosis::mimosis_instr_write(0xe0); # Send global reset to sensor# +#usleep($slow2); + +do { + + # Mimosis::mimosis_instr_write(0xe0); # Send global reset to sensor + # usleep($slow2); + + while( my ($reg, $val) = each(%regliststd) ) { + + # Get test value + my $testVal = + Mimosis::mimosis_register_read( $reg ); + + # Compare + print("$testVal != $val\n") unless $testVal == $val; + + $file{'Register Read: ' . $reg} = + $testVal == $val ? "GOOD" : "BAD"; + } + + system("./../start.sh"); + +} while ask_continue(); + + +DACREGTEST: + +print "\n"; +print "############################################################################\n"; +print "### REGISTER TEST - DAC ADDR ###\n"; +print "############################################################################\n"; +print "\n"; + +# my %reglistdac = ( +# 0x0040 => 0x40, +# 0x0041 => 0x34, +# 0x0042 => 0x1c, +# 0x0043 => 0xAB, +# 0x0044 => 0x57, +# 0x0045 => 0x68, +# 0x0046 => 0x0 , +# 0x0047 => 0x43, +# 0x0048 => 0x53, +# 0x0049 => 0x53, +# 0x004A => 0x53, +# 0x004B => 0x53, +# 0x004C => 0x53, +# 0x004D => 0x32, +#); + + + +# foreach my $dacOuter (keys %Mimosis::DAC) { +# +# foreach my $dacInner (keys %Mimosis::DAC) { +# +# my $monval = $Mimosis::DAC{$dacInner}{'MONVAL'}; +# my $monitor = $Mimosis::DAC{$dacInner}{'MONITOR'}; +# +# if( defined $monval ) { +# +# my $dacRegOuter = $Mimosis::DAC{$dacOuter}{'ADDR'}; +# my $dacRegInner = $Mimosis::DAC{$dacInner}{'ADDR'}; +# +# Mimosis::mimosis_register_write( $dacRegInner, 100 ); +# Mimosis::mimosis_register_write( $dacRegOuter, 0 ); +# +# print "$dacOuter $dacInner $monitor $monval\n"; +# +# my $tmpVal = $Mimosis::DAC{$dacOuter}{'MONVAL'}; +# my $tmpMon = $Mimosis::DAC{$dacOuter}{'MONITOR'}; +# +# $Mimosis::DAC{$dacOuter}{'MONVAL'} = $monval; +# $Mimosis::DAC{$dacOuter}{'MONITOR'} = $monitor; +# +# my %test = Mimosis::mimosis_dacscan( +# dacs => [$dacOuter, ], +# start => 100, +# stop => 102, +# ); +# +# my $res = $test{$dacOuter}{'Y'}[0]; +# +# print("$res\n") if $res > 100; +# +# $Mimosis::DAC{$dacOuter}{'MONVAL'} = $tmpVal; +# $Mimosis::DAC{$dacOuter}{'MONITOR'} = $tmpMon; +# } +# } +#} + +my $settingsDACRegTest = "../CONF_DACRegisterTest.pl"; +Mimosis::mimosis_load_file( file => $settingsDACRegTest ); + + +do { + my $errorCounter = 0; + foreach my $dacOuter (keys %Mimosis::DAC) { # DAC to be changed + + foreach my $dacInner (keys %Mimosis::DAC) { # DAC to be monitored + + my $monval = $Mimosis::DAC{$dacInner}{'MONVAL'}; + my $monitor = $Mimosis::DAC{$dacInner}{'MONITOR'}; + + if( defined $monval ) { + + my $dacRegOuter = $Mimosis::DAC{$dacOuter}{'ADDR'}; + my $dacRegInner = $Mimosis::DAC{$dacInner}{'ADDR'}; + + Mimosis::mimosis_register_write( $dacRegInner, 0 ); + Mimosis::mimosis_register_write( $dacRegOuter, 200 ); + + # print "$dacOuter $dacInner $monitor $monval\n"; + + my $tmpVal = $Mimosis::DAC{$dacOuter}{'MONVAL'}; + my $tmpMon = $Mimosis::DAC{$dacOuter}{'MONITOR'}; + + $Mimosis::DAC{$dacOuter}{'MONVAL'} = $monval; #dacInner + $Mimosis::DAC{$dacOuter}{'MONITOR'} = $monitor; #dacInner + + my %test = Mimosis::mimosis_dacscan( + dacs => [$dacOuter], + start => 100, + stop => 102, + ); + + Mimosis::mimosis_register_write( $dacRegOuter, 0 ); + + my $res = $test{$dacOuter}{'Y'}[0]; + $errorCounter = $errorCounter + 1 if $res > 500; + print("$res \n"); + + $Mimosis::DAC{$dacOuter}{'MONVAL'} = $tmpVal; + $Mimosis::DAC{$dacOuter}{'MONITOR'} = $tmpMon; + } + } + } + + print($errorCounter); + $file{'DAC Reg R/W Test: '} = + ($errorCounter <= 14) ? "GOOD" : "BAD"; + $errorCounter <= 14 ? print("DAC REG TEST GOOD\n") : print("DAC REG TEST BAD\n"); +} while ask_continue(); + +# FIXME Problem with writing to file + +#Mimosis::mimosis_instr_write($fpgalink, 0xe0); # Send proper settings back to sensor FIXME Find Benes Value +#usleep($slow2); + + +print "\n"; +print "############################################################################\n"; +print "### REGISTER TEST - STD R&W ###\n"; +print "############################################################################\n"; +print "\n"; + + +# Test of read/write operation + +my %reglistgenconfrw = ( + 0x0020 => 0x02, # RUNMODE + 0x0025 => 0x00, # MONCURR + 0x0026 => 0x00, # MONVOLT + 0x0027 => 0x00, # CLKGEN1 + 0x0028 => 0x00, # CLKGEN2 + 0x0029 => 0x11, # PLL + 0x002a => 0x38, # PLLLOCK + 0x002c => 0x15, # SLVSTX + 0x002d => 0x08, # SLVSRX + 0x002e => 0x00, # OUTPUT +); + +my %testwordsgenconfrw = ( + 0x00, + 0xff, + 0xaa, + 0x55, + 0xdb, + 0x44, + 0xcd, + 0x85, +); + + +do { + + while( my ($reg, $val) = each(%reglistgenconfrw) ) { + + # Save original value into register + my $tmp = Mimosis::mimosis_register_read( + #$fpgalink, + $reg, + ); #usleep($slow2); # + + while (my $testword = each(%testwordsgenconfrw)) { + + # Write test value + Mimosis::mimosis_register_write( + #$fpgalink, + $reg, + $testword, + ); #usleep($slow2); # write value into register + + # Get test value + my $testVal = Mimosis::mimosis_register_read( + #$fpgalink, + $reg, + #$singleaccessmode + ); #usleep($slow2); # + + + + # Compare + print("$testVal != $testword\n") unless $testVal == $testword; + } + + # Write original value back into register + Mimosis::mimosis_register_write( + #$fpgalink, + $reg, + $tmp, + #$singleaccessmode + ); #usleep($slow2); + } + +} while ask_continue(); + +#system("./../start.sh"); +#sleep(2); + + +# print "\n"; +# print "############################################################################\n"; +# print "### LINK TEST ###\n"; +# print "############################################################################\n"; +# print "\n"; + +# do { +# my $currentWd = Cwd::cwd(); +# chdir("/d/jspc37/mimosis/scripts"); +# system("/d/jspc37/mimosis/scripts/start.sh"); +# chdir($currentWd); + +# my $cntBadLinks = 0; + +# for my $i (0 .. 7) { + +# my $reg = trb_register_read( $fpgalink, 0xa000 + $i ); +# $reg = ( $reg->{$fpgalink} & 0x7f00 ) >> 8; + +# $cntBadLinks += 1 if $reg >= 70; + +# $file{"Link_$i"} = $reg >= 70 ? "$reg\tBAD" : "$reg\tGOOD"; +# } + +# # die "Bad links. Exiting.\n" if $cntBadLinks > 0; +# print "Bad links.\n" if $cntBadLinks > 0; + +# } while ask_continue(); + + + + + +print "\n"; +print "#############################################################################\n"; +print "### BB TEST ###\n"; +print "#############################################################################\n"; +print "\n"; + +open(BB_FH, '>', $sensorname . "/bb.csv") or die $!; + +BBTEST: +do { + my $socket = IO::Socket::INET->new( + PeerAddr => $peer, + PeerPort => $port, + Proto => "tcp", + Type => SOCK_STREAM, + ) + or die "ERROR: Cannot connect: $@"; + + # Save current BB seting for later + usleep 1e0; print $socket "INST OUT$bbCh\n"; + usleep 1e5; print $socket "MEAS:VOLT?\n"; + my $tmp = <$socket>; + chomp $tmp; + + for (my $i = 0; $i <= 5.0; $i += 0.5) { + + usleep 1e5; print $socket "VOLT $i\n"; + usleep 1e5; print $socket "MEAS:VOLT?\n"; my $volt = <$socket>; + usleep 1e5; print $socket "MEAS:CURR?\n"; my $curr = <$socket>; + + chomp $volt; + chomp $curr; + + print BB_FH "$volt\t$curr\n"; + } + + # Reset BB to what it was before + usleep 1e5; print $socket "VOLT $tmp\n"; + +} while ask_continue(); + +close BB_FH; + + +POWERINGTEST: + + +print "\n"; +print "###########################################################################\n"; +print "### POWERING TEST DIGITAL ###\n"; +print "###########################################################################\n"; +print "\n"; + +#Find out current drawn by sensor on digital and perform data checks. +my $lowleveldig = 100; # Minimum digital current for passing as ok +my $highleveldig = 200; # Maximum digital current for passing as ok + + +do { + my $adc_addr = 0x48; + my $adc_wreg = 0x1; + my $adc_cmd = 0xc380; #CHANGE ME + my $adc_rreg = 0x0; + my $adcConv = ( 2 * 4096 ) / (2**16 * 10); + + Mimosis::adc_i2c_command( + $adc_addr, + $adc_wreg, + $adc_cmd, + 0, 0, 1 + ); + + usleep($adcSlow); + + my $digitalcur = + Mimosis::adc_i2c_command( + $adc_addr, + $adc_rreg, + 0x0, + 1, 0, 1 ); + + usleep($adcSlow); + + $digitalcur *= $adcConv; + + # Check if numeric and within good current range + if ( $digitalcur <= $highleveldig && + $digitalcur >= $lowleveldig ) + { + $file{"Digitalcurrent"} = $digitalcur; + print "Digital current: $digitalcur mA.\n"; + + } else { + + print "Digital current not in range: $digitalcur.\n"; + $file{"Digitalcurrent"} = "F"; + } + +} while ask_continue(); + + + + + +print "\n"; +print "############################################################################\n"; +print "### POWERING TEST ANALOG ###\n"; +print "############################################################################\n"; +print "\n"; + +#Find out current drawn by sensor on analog and perform data checks. +my $lowlevelana = 5; # Minimum analog current for passing as ok +my $highlevelana = 30; # Maximum analog current for passing as ok + + +do { + my $adc_addr = 0x48; + my $adc_wreg = 0x1; + my $adc_cmd = 0xf380; #CHANGE ME + my $adc_rreg = 0x0; + my $adcConv = ( 2 * 4096 ) / (2**16 * 100); + + Mimosis::adc_i2c_command( + $adc_addr, + $adc_wreg, + $adc_cmd, + 0, 0, 1 + ); + + usleep($adcSlow); + + my $analogcur = + Mimosis::adc_i2c_command( + $adc_addr, + $adc_rreg, + 0x0, + 1, 0, 1 ); + + usleep($adcSlow); + + $analogcur *= $adcConv; + + # Check if numeric and within good current range + if( $analogcur <= $highlevelana && + $analogcur >= $lowlevelana ) + { + $file{"Analogcurrent"} = $analogcur; + print "Analog current: $analogcur mA.\n"; + + } else { + + print "Analog current not in range: $analogcur.\n"; + $file{"Analogcurrent"} = "F"; + } + +} while ask_continue(); + + +# print "$_\t$file{$_}\n" foreach (keys %file); + + + + + +print "\n"; +print "############################################################################\n"; +print "### FAST DACSCAN TEST ###\n"; +print "############################################################################\n"; +print "\n"; + + +chdir($sensorname); + +do { + my @DACFAST = ('VPH', 'VPL', 'VPHFINE'); + + my %results = Mimosis::mimosis_dacscan( + dacs => \@DACFAST, + step => 10, + ); + + + my $picName = "fastdacscan.png"; + + my $chart = Chart::Gnuplot->new( + output => $picName, + terminal => "pngcairo", + title => "DAC-Scan", + xlabel => "Setting [LSB]", + ylabel => "Voltage output [mV]", + ); + + + my @dataArr; + + $chart->polygon( + vertices => [ + "0, 1100", + "250, 1375", + "250, 1225", + "0, 1000", + "0, 1100", + ], + fill => { + density => 0.3, + color => "#A9A9A0", + }, + ); + + $chart->polygon( + vertices => [ + "0, 370", + "250, 1950", + "250, 1670", + "0, 320", + "0, 370", + ], + fill => { + density => 0.3, + color => "#A9A9A0", + }, + ); + + for my $dac ( keys %results ) { + + my $dataSet = Chart::Gnuplot::DataSet->new( + xdata => $results{$dac}{X}, + ydata => $results{$dac}{Y}, + title => "Plotting a line from Perl arrays", + style => "linespoints", + ); + + push(@dataArr, $dataSet); + } + + $chart->plot2d(@dataArr); + + system("display $picName"); + + + print "Please enter rapid DAC scan result classification.\n"; + print "S = satisfactory if in grey areas\n"; + print "F = unsatisfactory and exiting.\n"; + + while ( 1 ) { + + print "Rapid DAC scan classification: "; + my $rapiddacclass = ; + chomp $rapiddacclass; + + if ( $rapiddacclass eq "S" || + $rapiddacclass eq "s" ) { + + $file{"RapidDACTest"} = "S"; + last; + + } elsif ( $rapiddacclass eq "F" || + $rapiddacclass eq "f" ) { + + $file{"RapidDACTest"} = "F"; + exit 0; + + } else { + print "Invalid classification. Try again.\n"; + } + } + +} while ask_continue(); + + + + + +print "\n"; +print "############################################################################\n"; +print "### DACSCAN TEST ###\n"; +print "############################################################################\n"; +print "\n"; + +my $VPHFSlope; +my $VPHOffsetElectron; + +do { + my %names = ( + 'IBIAS' => 0x0040, + 'ITHR' => 0x0041, + 'IDB' => 0x0042, + 'VRESET' => 0x0043, + 'VPL' => 0x0044, + 'VPH' => 0x0045, + 'VPHFINE' => 0x0046, + 'VCASP' => 0x0047, + 'VCASNA' => 0x0048, + 'VCASNB' => 0x0049, + 'VCASNC' => 0x004a, + 'VCASND' => 0x004b, + 'VCASN2' => 0x004c, + 'VCLIP' => 0x004d, + # 'IBUFBIAS' => 0x004e, + ); + + my %dacVals = Mimosis::mimosis_dacscan( + # step => 50, + ); + + + my @VPHList = @{$dacVals{'VPH'}{'Y'}}; + my @VPLList = @{$dacVals{'VPL'}{'Y'}}; + my @VPHFINEList = @{$dacVals{'VPHFINE'}{'Y'}}; + my @VRESETList = @{$dacVals{'VRESET'}{'Y'}}; + my @VCASNAList = @{$dacVals{'VCASNA'}{'Y'}}; + my @VCASNBList = @{$dacVals{'VCASNB'}{'Y'}}; + my @VCASNCList = @{$dacVals{'VCASNC'}{'Y'}}; + my @VCASNDList = @{$dacVals{'VCASND'}{'Y'}}; + my @VCASN2List = @{$dacVals{'VCASN2'}{'Y'}}; + my @VCLIPList = @{$dacVals{'VCLIP'}{'Y'}}; + my @VCASPList = @{$dacVals{'VCASP'}{'Y'}}; + my @IBIASList = @{$dacVals{'IBIAS'}{'Y'}}; + my @ITHRList = @{$dacVals{'ITHR'}{'Y'}}; + my @IDBList = @{$dacVals{'IDB'}{'Y'}}; + + + my $picName = "full-dacscan.png"; + + my $chartPng = Chart::Gnuplot->new( + output => $picName, + terminal => "pngcairo", + title => "DAC-Scan", + xlabel => "Setting [LSB]", + ylabel => "Voltage output [mV]", + ); + + my @dataArr; + + for my $dac ( keys %dacVals) { + + my $dataSet = Chart::Gnuplot::DataSet->new( + xdata => $dacVals{$dac}{X}, + ydata => $dacVals{$dac}{Y}, + title => $dac, + style => "lines", + ); + + push(@dataArr, $dataSet); + } + + $chartPng->plot2d(@dataArr); + + system("display $picName"); + + + for my $i (0 .. scalar( @VPHFINEList ) - 1) { + $VPHFINEList[$i] = $VPHFINEList[$i] - $VPHList[0]; + } + + + my $sensorQuality = 4; + + my $VPHOffset = $VPHList[0]; + my $VPLOffset = $VPLList[0]; + my $VRESETOffset = $VRESETList[0]; + my $VPHFOffset = $VPHFINEList[0]; + my $VPH210 = $VPHList[211]; + my $VPL210 = $VPLList[211]; + my $VRESET210 = $VRESETList[211]; + my $VPHF210 = $VPHFINEList[211] - $VPHFOffset; + + + if ( (300 <= $VPHOffset) && + (375 >= $VPHOffset) && + (300 <= $VPLOffset) && + (375 >= $VPLOffset) && + (300 <= $VRESETOffset) && + (375 >= $VRESETOffset) && + ($VPH210 >= 1410) && + ($VPL210 >= 1410) && + ($VRESET210 >= 1410) && + ($VPHFOffset <= 20) && + ($VPHF210 >= 190) ) { + + $sensorQuality = 3; + + if ( max(@VCASNAList) > 1100 && + max(@VCASNBList) > 1100 && + max(@VCASNCList) > 1100 && + max(@VCASNDList) > 1100 && + max(@VCASN2List) > 1100 && + max(@VCLIPList) > 550 && + max(@VCASPList) > 550 && + max(@IBIASList) >= 260 && + max(@ITHRList) >= 260 && + max(@IDBList) >= 260 ) { + + $sensorQuality = 2; + + my $arrRef = [ 3,3,3,3 + ]; + + sub calcAbsDNLAbsINL { + + my @dac = @{$_[0]}; + + my $gain = ($dac[199] - $dac[24]) / 175.0; + + my @dnl = ( 0 ); + my @inl = ( 0 ); + + for my $i (21 .. 201) { + + my $currentDNL = ( ($dac[$i] - $dac[$i-1]) / $gain ) - 1; + push(@dnl, $currentDNL); + push(@inl, $inl[$i-21]+$currentDNL); + } + + @dnl = reverse @dnl; + @inl = reverse @inl; + return ( \@inl, \@dnl ); + } + + + my ( $ibiasinlRef, $ibiasdnlRef ) = calcAbsDNLAbsINL(\@IBIASList); + my @IBIASINL = @{$ibiasinlRef}; + my @IBIASDNL = @{$ibiasdnlRef}; + + my ( $ithrinlRef, $ithrdnlRef ) = calcAbsDNLAbsINL(\@ITHRList); + my @ITHRINL = @{$ithrinlRef}; + my @ITHRDNL = @{$ithrdnlRef}; + + my ( $idbinlRef, $idbdnlRef ) = calcAbsDNLAbsINL(\@IDBList); + my @IDBINL = @{$idbinlRef}; + my @IDBDNL = @{$idbdnlRef}; + + my ( $vphinlRef, $vphdnlRef ) = calcAbsDNLAbsINL(\@VPHList); + my @VPHINL = @{$vphinlRef}; + my @VPHDNL = @{$vphdnlRef}; + + my ( $vplinlRef, $vpldnlRef ) = calcAbsDNLAbsINL(\@VPLList); + my @VPLINL = @{$vplinlRef}; + my @VPLDNL = @{$vpldnlRef}; + + my ( $vresetinlRef, $vresetdnlRef ) = calcAbsDNLAbsINL(\@VRESETList); + my @VRESETINL = @{$vresetinlRef}; + my @VRESETDNL = @{$vresetdnlRef}; + + my ( $vphfineinlRef, $vphfinednlRef ) = calcAbsDNLAbsINL(\@VPHFINEList); + my @VPHFINEINL = @{$vphfineinlRef}; + my @VPHFINEDNL = @{$vphfinednlRef}; + + my ( $vcasnainlRef, $vcasnadnlRef ) = calcAbsDNLAbsINL(\@VCASNAList); + my @VCASNAINL = @{$vcasnainlRef}; + my @VCASNADNL = @{$vcasnadnlRef}; + + my ( $vcasnbinlRef, $vcasnbdnlRef ) = calcAbsDNLAbsINL(\@VCASNBList); + my @VCASNBINL = @{$vcasnbinlRef}; + my @VCASNBDNL = @{$vcasnbdnlRef}; + + my ( $vcasncinlRef, $vcasncdnlRef ) = calcAbsDNLAbsINL(\@VCASNCList); + my @VCASNCINL = @{$vcasncinlRef}; + my @VCASNCDNL = @{$vcasncdnlRef}; + + my ( $vcasndinlRef, $vcasnddnlRef ) = calcAbsDNLAbsINL(\@VCASNDList); + my @VCASNDINL = @{$vcasndinlRef}; + my @VCASNDDNL = @{$vcasnddnlRef}; + + my ( $vcasn2inlRef, $vcasn2dnlRef ) = calcAbsDNLAbsINL(\@VCASN2List); + my @VCASN2INL = @{$vcasn2inlRef}; + my @VCASN2DNL = @{$vcasn2dnlRef}; + + my ( $vcaspinlRef, $vcaspdnlRef ) = calcAbsDNLAbsINL(\@VCASPList); + my @VCASPINL = @{$vcaspinlRef}; + my @VCASPDNL = @{$vcaspdnlRef}; + + my ( $vclipinlRef, $vclipdnlRef ) = calcAbsDNLAbsINL(\@VCLIPList); + my @VCLIPINL = @{$vclipinlRef}; + my @VCLIPDNL = @{$vclipdnlRef}; + + my $goodDNL = 0; + + if ( $IBIASDNL[2] < 1 + && $ITHRDNL[2] < 1 + && $IDBDNL[2] < 1 + && $VCASNADNL[2] < 1 + && $VCASNBDNL[2] < 1 + && $VCASNCDNL[2] < 1 + && $VCASNDDNL[2] < 1 + && $VCASN2DNL[2] < 1 + && $VCASPDNL[2] < 1 + && $VCLIPDNL[2] < 1 + && $VPHDNL[2] < 1 + && $VPLDNL[2] < 1 + && $VRESETDNL[2] < 1 + && $VPHFINEDNL[2] < 1 + ) { + $goodDNL = 1; + } + + my $goodINL = 0; + + if ( $IBIASINL[2] < 5 + && $ITHRINL[2] < 5 + && $IDBINL[2] < 5 + && $VCASNAINL[2] < 5 + && $VCASNBINL[2] < 5 + && $VCASNCINL[2] < 5 + && $VCASNDINL[2] < 5 + && $VCASN2INL[2] < 5 + && $VCASPINL[2] < 5 + && $VCLIPINL[2] < 5 + && $VPHINL[2] < 1 + && $VPLINL[2] < 1 + && $VRESETINL[2] < 1 + && $VPHFINEINL[2] < 1 + ) { + $goodINL = 1; + } + + if ($goodDNL && $goodINL) { + $sensorQuality = 1; + } + } + } + + $VPHFSlope = ($VPHFINEList[255] - $VPHFINEList[0]) / 255.0; + # $VPHFSlope = 1.; + $VPHOffsetElectron = 150; + $ZeroElectronVPHSetting = 95; + + for my $i (0 .. scalar(@VPHList)) { + + if ( ($VPHList[$i] gt ($VPLList[70] - 6)) # or ($VPHList[$i] lt ($VPLList[70] + 6)) + ) { + + $ZeroElectronVPHSetting = $i; + $VPHOffsetElectron = $VPHList[$i] - $VPLList[70]; + last; + } + } + + print("ZeroSetting\t$ZeroElectronVPHSetting\t$VPHOffsetElectron\n"); + + print("Sensor Quality for DACs: $sensorQuality\n"); + + $file{"DACQuality"} = $sensorQuality; + $file{"VPHFSlope"} = $VPHFSlope; + $file{"VPHSetting0Electrons"} = "$ZeroElectronVPHSetting\t$VPHOffsetElectron"; + +} while ask_continue(); + + + +SCURVES: + +sub fit_thr { + my ($fname, $vphOffsetElectron, $vphfSlope, $vphStepSize) = @_; + Mimosis::mimosis_make_fit($fname, $vphOffsetElectron, $VPHFSlope, $vphStepSize); + # system("/usr/bin/python3 /d/jspc37/mimosis/scripts/pulse/fit-raw.py $fname $dirName $vphOffsetElectron $vphfSlope"); +} + + + +my %matrixParams = ( + A => { + VCASN => 0x48, + YSPAN => 4, + XSTART => 0, + XSTOP => 127, + }, +# B => { +# VCASN => 0x49, +# YSPAN => 2, +# XSTART => 128, +# XSTOP => 511, +# }, +# C => { +# VCASN => 0x4a, +# YSPAN => 2, +# XSTART => 512, +# XSTOP => 894, +# }, +# D => { +# VCASN => 0x4b, +# YSPAN => 4, +# XSTART => 895, +# XSTOP => 1023, +# }, + ); + +print "\n"; +print "############################################################################\n"; +print "### SCURVE TEST ###\n"; +print "############################################################################\n"; +print "\n"; + +$matrixParams{'A'}{'LOWERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 95 : +(( $backbias == 1000 && $irraddeg >= 1000 ) ? 60 : (( $backbias == 1000 && $irraddeg == 0 ) ? 70 : (( $backbias == 3000 && $irraddeg == 0 ) ? 110 : 50 ))); + +$matrixParams{'A'}{'UPPERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 120 : +(( $backbias == 1000 && $irraddeg >= 1000 ) ? 100 : (( $backbias == 1000 && $irraddeg == 0 ) ? 115 : (( $backbias == 3000 && $irraddeg == 0 ) ? 165 : 200 ))); + + +# $matrixParams{'B'}{'LOWERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 100 : +# (( $backbias == 1000 && $irraddeg >= 1000 ) ? 75 : (( $backbias == 1000 && $irraddeg == 0 ) ? 95 : (( $backbias == 3000 && $irraddeg == 0 ) ? 130 : 50 ))); +# +# $matrixParams{'B'}{'UPPERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 150 : +# (( $backbias == 1000 && $irraddeg >= 1000 ) ? 125 : (( $backbias == 1000 && $irraddeg == 0 ) ? 140 : (( $backbias == 3000 && $irraddeg == 0 ) ? 185 : 200 ))); +# +# +# $matrixParams{'C'}{'LOWERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 100 : +# (( $backbias == 1000 && $irraddeg >= 1000 ) ? 75 : (( $backbias == 1000 && $irraddeg == 0 ) ? 95 : (( $backbias == 3000 && $irraddeg == 0 ) ? 130 : 50 ))); +# +# $matrixParams{'C'}{'UPPERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 150 : +# (( $backbias == 1000 && $irraddeg >= 1000 ) ? 125 : (( $backbias == 1000 && $irraddeg == 0 ) ? 140 : (( $backbias == 3000 && $irraddeg == 0 ) ? 185 : 200 ))); +# +# +# $matrixParams{'D'}{'LOWERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 95 : +# (( $backbias == 1000 && $irraddeg >= 1000 ) ? 60 : (( $backbias == 1000 && $irraddeg == 0 ) ? 75 : (( $backbias == 3000 && $irraddeg == 0 ) ? 115 : 50 ))); +# +# $matrixParams{'D'}{'UPPERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 120 : +# (( $backbias == 1000 && $irraddeg >= 1000 ) ? 100 : (( $backbias == 1000 && $irraddeg == 0 ) ? 140 : (( $backbias == 3000 && $irraddeg == 0 ) ? 180 : 200 ))); + + +do { + my $settingsScurves = "../CONF_scurves.pl"; + + cp($settingsScurves, "$sensorname/$settingsScurves"); + + Mimosis::mimosis_load_file( file => $settingsScurves ); + + + Mimosis::mimosis_register_write( + 0x45, + $ZeroElectronVPHSetting, + ); + + Mimosis::mimosis_register_write( + 0x4d, + int( 45 + $backbias/1000.0 * 12.0 + 0.5 ), + ); + + + + print "Press Enter, to start pulsing.\n"; + ; + + + foreach my $matrix ( sort keys %matrixParams ) { + + my $yspan = $matrixParams{$matrix}{'YSPAN'}; + my $xstart = $matrixParams{$matrix}{'XSTART'}; + my $xstop = $matrixParams{$matrix}{'XSTOP'}; + + Mimosis::mimosis_instr_write( 0x3f ); + Mimosis::mimosis_instr_write( 0x04 ); + Mimosis::mimosis_instr_write( 0x3e ); + + Mimosis::mimosis_register_write(0x46, 255); + + Mimosis::mimosis_pulse( + ystart => 250, + ystop => 253, + yspan => $yspan, + xstart => $xstart, + xstop => $xstop, + modexp => 3, + ); + + my $ll = $matrixParams{$matrix}{'LOWERLIMIT'}; + my $ul = $matrixParams{$matrix}{'UPPERLIMIT'}; + + print "Find proper VCASN in Go4. Suggested range: $ll - $ul\n"; + + my $foundF = 0; + + while ( 1 ) { + + print "Enter the appropriate VCASN$matrix value or \'F\' if bad: " ; + + my $vcasnTmp = ; + chomp $vcasnTmp; + + if ( $vcasnTmp eq "F" or + $vcasnTmp eq "f" ) { + + $file{"CoarseSCurves,MATRIX-$matrix"} = "F"; + + $foundF = 1; + last; + + } else { + + $file{"CoarseSCurves,MATRIX-$matrix"} = $vcasnTmp; + $matrixParams{$matrix}{"VCASNCOARSE"} = $vcasnTmp; + last; + } + } + + exit 0 if $foundF; + } + + + + print "Press Enter, to start scuves\n"; + ; + + foreach my $matrix ( sort keys %matrixParams ) { + + my $matrixDir = "MATRIX-" . $matrix; + mkdir($matrixDir); + chdir($matrixDir); + + my $yspan = $matrixParams{$matrix}{'YSPAN'}; + my $xstart = $matrixParams{$matrix}{'XSTART'}; + my $xstop = $matrixParams{$matrix}{'XSTOP'}; + my $vcasnstart = $matrixParams{$matrix}{"VCASNCOARSE"} - 1; #-5 + my $vcasnstop = $matrixParams{$matrix}{"VCASNCOARSE"} + 1; #+5 + + Mimosis::mimosis_scurves( + ystart => 250, + ystop => 253, + yspan => $yspan, + xstart => $xstart, + xstop => $xstop, + vcasnreg => 'VCASN' . $matrix, + vcasnstart => $vcasnstart, + vcasnstop => $vcasnstop, + setstep => $vphStepSize, + ); + + opendir my $dir, "." or die "Cannot open directory: $!"; + my @files = readdir $dir; + + foreach my $f ( @files ) { + + if ( $f =~ /VCASN/ ) { + + my $dirName = Cwd::cwd() . "/$f"; + + chdir($dirName); + + $matrixParams{$matrix}{"THREAD"} = + threads->create( \&fit_thr, + "$f.csv", + $VPHOffsetElectron, + $VPHFSlope, + $vphStepSize); + + chdir(".."); + } + } + + closedir $dir; + chdir(".."); + } + + + + + print "Wait for fits to finish.\n"; + + foreach my $matrix ( keys %matrixParams ) { + $matrixParams{$matrix}{"THREAD"}->join(); + } + + + + + print("Approximate a VCASN for each submatrix where the GMDT is closest to 150 e!\n"); + + my $foundF = 0; + + foreach my $matrix ( sort keys %matrixParams ) { + + while ( 1 ) { + + print "Enter the appropriate VCASN$matrix value or \'F\' if bad: " ; + + my $vcasnTmp = ; + chomp $vcasnTmp; + + if ( $vcasnTmp eq "F" or + $vcasnTmp eq "f" ) { + + $file{"RapidSCurves,MATRIX-$matrix"} = "F"; + + $foundF = 1; + last; + + } else { + + $file{"SCurvesFull,MATRIX-$matrix"} = $vcasnTmp; + $matrixParams{$matrix}{"VCASNFINAL"} = $vcasnTmp; + last; + } + } + } + if ( $foundF ) { exit 0; } + +} while ask_continue(); + + + + + + + + +do { + print "\n"; + print "############################################################################\n"; + print "### SCURVE TEST, FINAL ###\n"; + print "############################################################################\n"; + print "\n"; + + +# my $lowerlimitA = $matrixParams{"A"}{"PREV-VCASN"} - 2; +# my $upperlimitA = + 2; + +# my $lowerlimitB = $prevFoundB - 2; +# my $upperlimitB = $prevFoundB + 2; + +# my $lowerlimitC = $prevFoundC - 2; +# my $upperlimitC = $prevFoundC + 2; +# +# my $lowerlimitD = $prevFoundD - 2; +# my $upperlimitD = $prevFoundD + 2; + + + #Mimosis::mimosis_register_write( 0x45, $SixtyElectronVPHSetting ); + + my $settingsScurves = "../CONF_scurves.pl"; + + cp($settingsScurves, "$sensorname/$settingsScurves"); + + Mimosis::mimosis_load_file( + file => $settingsScurves + ); + + #Mimosis::mimosis_register_write( + #0x4D, + #int( 45 + $backbias/1000.0 * 12.0 + 0.5 ) + #); + + + foreach my $matrix ( sort keys %matrixParams ) { + + my $matrixDir = "MATRIXFINAL-" . $matrix; + mkdir($matrixDir); + chdir($matrixDir); + + Mimosis::mimosis_register_write( + 0x45, + $ZeroElectronVPHSetting, + ); + + Mimosis::mimosis_register_write( + 0x4D, + int( 45 + $backbias/1000.0 * 12.0 + 0.5 ), + ); + + my $vcasnSetting + $matrixParams{$matrix}{"VCASNFINAL"}; + + print("VCASNFINAL SETTING: $vcasnSetting\n"); + + my $yspan = $matrixParams{$matrix}{'YSPAN'}; + my $xstart = $matrixParams{$matrix}{'XSTART'}; + my $xstop = $matrixParams{$matrix}{'XSTOP'}; + my $vcasnstart = $matrixParams{$matrix}{"VCASNFINAL"}; + my $vcasnstop = $matrixParams{$matrix}{"VCASNFINAL"}; + + Mimosis::mimosis_scurves( + ystart => 0, + ystop => 503, + yspan => $yspan, + xstart => $xstart, + xstop => $xstop, + vcasnreg => 'VCASN' . $matrix, + vcasnstart => $vcasnstart, + vcasnstop => $vcasnstop, + ); + + opendir my $dir, "." or die "Cannot open directory: $!"; + my @files = readdir $dir; + + foreach my $f ( @files ) { + + if ( $f =~ /VCASN/ ) { + + my $dirName = Cwd::cwd() . "/$f"; + $matrixParams{$matrix}{"THREAD"} = threads->create(\&fit_thr, "$f.csv", $dirName, $VPHOffsetElectron, $VPHFSlope); + } + } + + closedir $dir; + + chdir(".."); + } + + + + print "Wait for fits to finish.\n"; + foreach my $matrix ( sort keys %matrixParams ) { + $matrixParams{$matrix}{"THREAD"}->join(); + } + + + print("Give VCASN for each submatrix where the GMDT is closest to 150 e!\n"); + + my $foundF = 0; + + foreach my $matrix ( sort keys %matrixParams ) { + + while ( 1 ) { + + print "Enter the appropriate VCASN$matrix value or \'F\' if bad:" ; + + my $vcasnTmp = ; + chomp $vcasnTmp; + + if ( $vcasnTmp eq "F" or + $vcasnTmp eq "f" ) { + + $file{"FineSCurves,MATRIX-$matrix"} = "F"; + + $foundF = 1; + last; + + } else { + + $file{"FineSCurves,MATRIX-$matrix"} = $vcasnTmp; + $matrixParams{$matrix}{"FINE"} = $vcasnTmp; + last; + } + } + } + if ( $foundF ) { exit 0; } + +} while ask_continue(); + +MFETESTS: + +print "\n"; +print "############################################################################\n"; +print "### REGISTER TEST - MFE REGS ###\n"; +print "############################################################################\n"; +print "\n"; + +# Test of read/write operation + +my %reglistmferw = ( + 0x4040 => 0x00, +); + +my %testwordsmferw = ( + 0x00, + 0xff, + 0xaa, + 0x55, + 0x71, + 0xb8, +); + +my $framelengthmsb = Mimosis::mimosis_register_read( + #$fpgalink, + 0x017B, + ); #usleep($slow2); # + +my $framelengthlsb = Mimosis::mimosis_register_read( + #$fpgalink, + 0x007B, + ); #usleep($slow2); # +Mimosis::mimosis_register_write( + #$fpgalink, + 0x017b, + 0xFF, + ); #usleep($slow2); # write value into register + +Mimosis::mimosis_register_write( + #$fpgalink, + 0x007b, + 0xFF, + ); #usleep($slow2); # write value into register + + +do { + + while( my ($reg, $val) = each(%reglistmferw) ) { + + # Save original value into register + my $tmp = Mimosis::mimosis_register_read( + #$fpgalink, + $reg, + ); #usleep($slow2); # + + while (my $testword = each(%testwordsmferw)) { + + # Write test value + Mimosis::mimosis_register_write( + #$fpgalink, + $reg, + $testword, + ); #usleep($slow2); # write value into register + + # Get test value + my $testVal = Mimosis::mimosis_register_read( + #$fpgalink, + $reg, + #$singleaccessmode + ); #usleep($slow2); # + + + + # Compare + print("$testVal != $testword\n") unless $testVal == $testword; + } + + # Write original value back into register + Mimosis::mimosis_register_write( + #$fpgalink, + $reg, + $tmp, + #$singleaccessmode + ); #usleep($slow2); + } + +} while ask_continue(); + +Mimosis::mimosis_register_write( + #$fpgalink, + 0x017b, + $framelengthmsb, + ); #usleep($slow2); # write value into register + +Mimosis::mimosis_register_write( + #$fpgalink, + 0x007b, + $framelengthlsb, + ); #usleep($slow2); # write value into register + + +__END__ + +open(RESULTS_FH, '>', $sensorname . "/results.db") or die $!; +print RESULTS_FH "$_\t$file{$_}\n" foreach (keys %file); +close RESULTS_FH; diff --git a/scripts/qa/oldScripts/QAScript_new.pl b/scripts/qa/oldScripts/QAScript_new.pl new file mode 100755 index 0000000..298b595 --- /dev/null +++ b/scripts/qa/oldScripts/QAScript_new.pl @@ -0,0 +1,1581 @@ +#!/usr/bin/perl + +# MIMOSIS-1 QA Script ... version 0.8 +# +# Authors: Benedict Arnoldi-Meadows and Benedikt Gutsche + +use strict; +use warnings; +use HADES::TrbNet; +use Mimosis; +use Time::HiRes qw( usleep ); +use POSIX; +use Data::Dump qw( dump ); +use List::Util qw( min max ); +use threads; +use IO::Handle; +use IO::Socket; +use File::Temp qw( tempfile ); +use File::Copy qw( cp ); +use Cwd qw(); +use Chart::Gnuplot; + + +sub ask_continue +{ + print "Repeat test? [y/N]: "; + my $answer = ; + chomp $answer; + + return 0 if $answer eq "" || $answer eq "n" || $answer eq "N"; + return 1; +} + +sub rep_prog +{ + print "Repeat reprogramming? [y/N]: "; + my $answer = ; + chomp $answer; + + return 0 if $answer eq "" || $answer eq "n" || $answer eq "N"; + return 1; +} + +sub doStartSh +{ + my $currentWd = Cwd::cwd(); + chdir("/d/jspc37/mimosis/scripts"); + system("/d/jspc37/mimosis/scripts/start.sh"); + chdir($currentWd); +} + +my $proxyType = "F"; # Acceptable values: "F" for Frankfurt and "S" for Strasbourg, not implemented yet: "P" for probe station +my $fpgalink = 0xa001; +my $peer = "192.168.0.56"; +my $port = "5025"; +my $bbCh = 2; + +my $ZeroElectronVPHSetting = 95; +my $singleaccessmode = 0; +my $slow = 100; +my $slow2 = 100000; +my $adcSlow = 100000; +my $vphStepSize = 5; + +my %fineVCASNParams = (); + +Mimosis::set_fpga($fpgalink); +Mimosis::set_printall(0); + +if ($proxyType == "F") { + Mimosis::set_adcToIkfProxy(); +} + +# my $fpgalink = 0xa100; +# my $peer = "192.168.0.56"; +# my $port = "5050"; +# my $bbCh = 3; +# Mimosis::set_adcToIkfProxy(); +# Mimosis::set_singleAccess(1); + +my $sensorname; +my $backbias; +my %file; # Hash where everything gets stored before written to file +my $irraddeg; +my $adc_addr = 0x48; +my $adc_wreg = 0x1; +my $adc_cmd_powering = 0xc380; +my $adc_cmd_powering_ana = 0xc380; +my $adc_rreg = 0x0; +my $adcConv = ( 2 * 4096 ) / (2**16 * 10); +my $settingsDACRegTest = "/d/jspc37/mimosis/scripts/conf/CONF_DACRegisterTest.pl"; + +my $VPHFSlope; +my $VPHOffsetElectron; +my $VPHOffset; + + my %matrixParams = ( + A => { + VCASN => 0x48, + YSPAN => 4, + XSTART => 0, + XSTOP => 127, + }, + B => { + VCASN => 0x49, + YSPAN => 2, + XSTART => 128, + XSTOP => 511, + }, + C => { + VCASN => 0x4a, + YSPAN => 2, + XSTART => 512, + XSTOP => 894, + }, + D => { + VCASN => 0x4b, + YSPAN => 4, + XSTART => 895, + XSTOP => 1023, + }, + ); + +my %DACList = ( + IBIAS => { ADDR => 0x40, MONITOR => 0x25, MONVAL => 1, TYPE => 'CURRENT', RESET => 0x40, }, + ITHR => { ADDR => 0x41, MONITOR => 0x25, MONVAL => 3, TYPE => 'CURRENT', RESET => 0x34, }, + IDB => { ADDR => 0x42, MONITOR => 0x25, MONVAL => 2, TYPE => 'CURRENT', RESET => 0x1c, }, + VRESET => { ADDR => 0x43, MONITOR => 0x26, MONVAL => 6, TYPE => 'VOLTAGE', RESET => 0xab, }, + VPL => { ADDR => 0x44, MONITOR => 0x26, MONVAL => 2, TYPE => 'VOLTAGE', RESET => 0x57, }, + VPH => { ADDR => 0x45, MONITOR => 0x26, MONVAL => 1, TYPE => 'VOLTAGE', RESET => 0x68, }, + VPHFINE => { ADDR => 0x46, MONITOR => 0x26, MONVAL => 1, TYPE => 'VOLTAGE', RESET => 0x0, }, + VCASP => { ADDR => 0x47, MONITOR => 0x26, MONVAL => 4, TYPE => 'VOLTAGE', RESET => 0x43, }, + VCASNA => { ADDR => 0x48, MONITOR => 0x26, MONVAL => 7, TYPE => 'VOLTAGE', RESET => 0x53, }, + VCASNB => { ADDR => 0x49, MONITOR => 0x26, MONVAL => 8, TYPE => 'VOLTAGE', RESET => 0x53, }, + VCASNC => { ADDR => 0x4a, MONITOR => 0x26, MONVAL => 9, TYPE => 'VOLTAGE', RESET => 0x53, }, + VCASND => { ADDR => 0x4b, MONITOR => 0x26, MONVAL => 10, TYPE => 'VOLTAGE', RESET => 0x53, }, + VCASN2 => { ADDR => 0x4c, MONITOR => 0x26, MONVAL => 3, TYPE => 'VOLTAGE', RESET => 0x53, }, + VCLIP => { ADDR => 0x4d, MONITOR => 0x26, MONVAL => 5, TYPE => 'VOLTAGE', RESET => 0x32, }, + IBUFBIAS => { ADDR => 0x4e, MONITOR => undef, MONVAL => undef, TYPE => 'CURRENT', RESET => 0x7d, }, + ); + + +printf("Using %x\n", $fpgalink); + + +trb_init_ports() or die trb_strerror(); + +print "\n"; +print "############################################################################\n"; +print "### INIT ###\n"; +print "############################################################################\n"; +print "\n"; + + +# Perform loop until a good name is found, +# i.e. it has never been assigned or is not empty +while ( 1 ) { + + print "Enter the sensor name: "; + $sensorname = ; + chomp $sensorname; + + # Check for bad names + if (-d $sensorname or $sensorname eq "") { + + print "Sensor name already chosen or illegal. Choose new one...\n"; + + } else { + + mkdir($sensorname); + last; + } +} + + +# Trap sig int +$SIG{INT} = sub { +# + open(RESULTS_FH, '>', "results.db") or die $!; + print RESULTS_FH "$_\t$file{$_}\n" foreach (keys %file); + close RESULTS_FH; + die "\nAbort.\n" +}; + + +$file{"SensorName"} = $sensorname; + + +while ( 1 ) { + + print "TID dose [kRad]: "; + $irraddeg = ; + chomp $irraddeg; + + # Check if numeric and within good current range + if ($irraddeg =~ /^\d{1,4}$/ ) { + last; + } elsif ($irraddeg eq "") { + $irraddeg = 1000; + last; + } else { + print "Invalid value (letters).\n"; + } +} + + +do { + my $socket = IO::Socket::INET->new( + PeerAddr => $peer, + PeerPort => $port, + Proto => "tcp", + Type => SOCK_STREAM ) + or die "ERROR: Cannot connect: $@"; + + usleep 1e5; print $socket "INST OUT$bbCh\n"; + usleep 1e5; print $socket "MEAS:VOLT?\n"; + $backbias = <$socket>; + chomp $backbias; + $backbias = 1000 * $backbias; + print "Back bias: $backbias mV\n"; + +} while ask_continue(); + + +sub bb_test { + + + print "\n"; + print "#############################################################################\n"; + print "### BB TEST ###\n"; + print "#############################################################################\n"; + print "\n"; + + open(BB_FH, '>', $sensorname . "/bb.csv") or die $!; + + do { + my $socket = IO::Socket::INET->new( + PeerAddr => $peer, + PeerPort => $port, + Proto => "tcp", + Type => SOCK_STREAM, + ) + or die "ERROR: Cannot connect: $@"; + + # Save current BB seting for later + usleep 1e0; print $socket "INST OUT$bbCh\n"; + usleep 1e5; print $socket "MEAS:VOLT?\n"; + my $tmp = <$socket>; + chomp $tmp; + + for (my $i = 0; $i <= 5.0; $i += 0.5) { + + usleep 1e6; print $socket "VOLT $i\n"; + usleep 1e6; print $socket "MEAS:VOLT?\n"; my $volt = <$socket>; + usleep 1e6; print $socket "MEAS:CURR?\n"; my $curr = <$socket>; + + chomp $volt; + chomp $curr; + + print BB_FH "$volt\t$curr\n"; + print("Backbias: $volt, current: $curr \n"); + if ( ($curr > 0.01 and $irraddeg == 0) or ($curr > 0.02 and $irraddeg > 0)) { + die "Maximum backbias current exceeded!"; + } + } + + # Reset BB to what it was before + usleep 1e5; print $socket "VOLT $tmp\n"; + + } while ask_continue(); + + close BB_FH; + +} + +sub powering_tests { + + print "\n"; + print "###########################################################################\n"; + print "### POWERING TEST DIGITAL ###\n"; + print "###########################################################################\n"; + print "\n"; + + #Find out current drawn by sensor on digital and perform data checks. + my $lowleveldig = 100; # Minimum digital current for passing as ok + my $highleveldig = 200; # Maximum digital current for passing as ok + + + do { + + if ($proxyType == "F") { + + Mimosis::adc_i2c_command( + $adc_addr, + $adc_wreg, + $adc_cmd_powering, + 0, 0, 1 + ); + + usleep($adcSlow); + + my $digitalcur = + Mimosis::adc_i2c_command( + $adc_addr, + $adc_rreg, + 0x0, + 1, 0, 1 ); + + usleep($adcSlow); + + $digitalcur *= $adcConv; + + } + + else { + + print("Please enter the value on the voltmeter labeled DIGITAL: "); + $digitalcur = ; + chomp $digitalcur; + + } + + # Check if numeric and within good current range + if ( $digitalcur <= $highleveldig && + $digitalcur >= $lowleveldig ) + { + $file{"Digitalcurrent"} = $digitalcur; + print "Digital current: $digitalcur mA.\n"; + + } else { + + print "Digital current not in range: $digitalcur.\n"; + $file{"Digitalcurrent"} = "F"; + } + + } while ask_continue(); + + + + + + print "\n"; + print "############################################################################\n"; + print "### POWERING TEST ANALOG ###\n"; + print "############################################################################\n"; + print "\n"; + + #Find out current drawn by sensor on analog and perform data checks. + my $lowlevelana = 5; # Minimum analog current for passing as ok + my $highlevelana = 20; # Maximum analog current for passing as ok + + + do { + + if ($proxyType == "F") { + + Mimosis::adc_i2c_command( + $adc_addr, + $adc_wreg, + $adc_cmd_powering_ana, + 0, 0, 1 + ); + + usleep($adcSlow); + + my $analogcur = + Mimosis::adc_i2c_command( + $adc_addr, + $adc_rreg, + 0x0, + 0, 0, 1 ); # 1, 0, 1 ); + + usleep($adcSlow); + + $analogcur *= $adcConv; + + } + + else { + + print("Please enter the value on the voltmeter labeled ANALOG: "); + $analogcur = ; + chomp $analogcur; + + } + + # Check if numeric and within good current range + if( $analogcur <= $highlevelana && + $analogcur >= $lowlevelana ) + { + $file{"Analogcurrent"} = $analogcur; + print "Analog current: $analogcur mA.\n"; + + } else { + + print "Analog current not in range: $analogcur.\n"; + $file{"Analogcurrent"} = "F"; + } + + } while ask_continue(); + +} + +sub reg_std_addr { + + print "\n"; + print "############################################################################\n"; + print "### REGISTER TEST - STD ADDR ###\n"; + print "############################################################################\n"; + print "\n"; + + my %regliststd = ( + 0x0021 => 0x6e, # TRIMDAC + 0x0029 => 0x11, # PLL + 0x002a => 0x38, # PLLLOCK + 0x002c => 0x15, # SLVSTX + 0x002d => 0x08, # SLVSRX + 0x0043 => 0xab, # VRESET + 0x004e => 0x7d, # IBUFBIAS + ); + + Mimosis::mimosis_instr_write(0xe0); # Send global reset to sensor# + usleep($slow2); + + do { + + my $errCt = 0; + + # Mimosis::mimosis_instr_write(0xe0); # Send global reset to sensor + # usleep($slow2); + + while( my ($reg, $val) = each(%regliststd) ) { + + # Get test value + my $testVal = + Mimosis::mimosis_register_read( $reg ); + + # Compare + if ($testVal != $val) { + print("$testVal != $val\n"); + $errCt = $errCt + 1; + } + print("$testVal != $val\n") unless $testVal == $val; + +# $file{'Register Read: ' . $reg} = +# $testVal == $val ? "GOOD" : "BAD"; + } + + if ($errCt == 0) { + + print("No problems detected.\n"); + $file{"Registerread"} = "S"; + + } + + else { + + print("Problems in Register Read test detected.\n"); + $file{"Registerread"} = "F"; + + } + + } while ask_continue(); + +} + +sub dac_reg_test { +print( Cwd::cwd() ); + + Mimosis::mimosis_load_file( file => $settingsDACRegTest ); + + + do { + chdir("/d/jspc37/mimosis/scripts/qa/dataTrash"); + my $errorCounter = 0; + foreach my $dacToBeMonitored (keys %Mimosis::DAC) { # DAC to be changed + + my $monval = $Mimosis::DAC{$dacToBeMonitored}{'MONVAL'}; + my $monitor = $Mimosis::DAC{$dacToBeMonitored}{'MONITOR'}; + my $type = $Mimosis::DAC{$dacToBeMonitored}{'TYPE'}; + + if ($dacToBeMonitored ne 'IBUFBIAS') { + + foreach my $dacToBeChanged (keys %Mimosis::DAC) { + + my $trueMonVal = $DACList{$dacToBeChanged}{'MONVAL'}; + my $trueMonitor = $DACList{$dacToBeChanged}{'MONITOR'}; + my $trueType = $DACList{$dacToBeChanged}{'TYPE'}; + my $dacRegToBeChanged = $DACList{$dacToBeChanged}{'ADDR'}; + + $Mimosis::DAC{$dacToBeChanged}{'MONVAL'} = $monval; + $Mimosis::DAC{$dacToBeChanged}{'MONITOR'} = $monitor; + $Mimosis::DAC{$dacToBeChanged}{'TYPE'} = $type; + + usleep(10000); + + if ($dacToBeMonitored ne $dacToBeChanged && ($dacToBeChanged ne 'IBUFBIAS') && not ($dacToBeMonitored eq 'VPHFINE' && $dacToBeChanged eq 'VPH') ) { + +# print("DAC Monitored: $dacToBeMonitored, monval: $monval, monitor: $monitor, DAC changed: $dacToBeChanged, true monval: $trueMonVal, true monitor: $trueMonitor, monitored monval: $Mimosis::DAC{$dacToBeChanged}{'MONVAL'}, monitored monitor: $Mimosis::DAC{$dacToBeChanged}{'MONITOR'} \n"); + + my %test = Mimosis::mimosis_dacscan( + dacs => [$dacToBeChanged], + start => 195, + stop => 201, + ); + + my $notoverwritten = 1; + + do { + + Mimosis::mimosis_load_file( file => $settingsDACRegTest ); + usleep(10000); + my $val = Mimosis::mimosis_register_read( $dacRegToBeChanged ); + + if ($val == 5) {$notoverwritten = 0;} + + } while $notoverwritten; + + my $res = $test{$dacToBeChanged}{'Y'}[4]; + + my $VphType = 0; + + if ($monitor == 0x26 && ($monval == 1 || $monval == 2 || $monval == 6) ) { + $VphType = 1; + } + + if (($res < 8000) and (($res > 700 && $VphType == 1) or ($res > 100 && $VphType == 0)) ) { + $errorCounter = $errorCounter + 1; + print("Problem! Dac monitored: $dacToBeMonitored \t DAC changed: $dacToBeChanged\t Voltage: $res \n"); + } + + } + + $Mimosis::DAC{$dacToBeChanged}{'MONVAL'} = $trueMonVal; + $Mimosis::DAC{$dacToBeChanged}{'MONITOR'} = $trueMonitor; + $Mimosis::DAC{$dacToBeChanged}{'TYPE'} = $trueType; + usleep(10000); + + } + + } + + } + + chdir("/d/jspc37/mimosis/scripts/qa"); + print("$errorCounter \n"); + $file{'DAC Reg R/W Test: '} = + ($errorCounter <= 0) ? "GOOD" : "BAD"; + $errorCounter <= 0 ? print("DAC REG TEST GOOD\n") : print("DAC REG TEST BAD\n"); + } while ask_continue(); + +} + +sub std_rw_test { + + print "\n"; + print "############################################################################\n"; + print "### REGISTER TEST - STD R&W ###\n"; + print "############################################################################\n"; + print "\n"; + + + # Test of read/write operation + + my %reglistgenconfrw = ( + 0x0020 => 0x02, # RUNMODE + 0x0025 => 0x00, # MONCURR + 0x0026 => 0x00, # MONVOLT + 0x0027 => 0x00, # CLKGEN1 + 0x0028 => 0x00, # CLKGEN2 + 0x0029 => 0x11, # PLL + 0x002a => 0x38, # PLLLOCK + 0x002c => 0x15, # SLVSTX + 0x002d => 0x08, # SLVSRX + 0x002e => 0x00, # OUTPUT + ); + + my %testwordsgenconfrw = ( + 0x00, + 0xff, + 0xaa, + 0x55, + 0xdb, + 0x44, + 0xcd, + 0x85, + ); + + + do { + + my $errCt = 0; + + while( my ($reg, $val) = each(%reglistgenconfrw) ) { + + # Save original value into register + my $tmp = Mimosis::mimosis_register_read( + #$fpgalink, + $reg, + ); #usleep($slow2); # + + while (my $testword = each(%testwordsgenconfrw)) { + + # Write test value + Mimosis::mimosis_register_write( + #$fpgalink, + $reg, + $testword, + ); #usleep($slow2); # write value into register + + # Get test value + my $testVal = Mimosis::mimosis_register_read( + #$fpgalink, + $reg, + #$singleaccessmode + ); #usleep($slow2); # + + + + # Compare + #print("$testVal != $testword\n") unless $testVal == $testword; + if ($testVal != $testword) { + print("$testVal != $testword\n"); + $errCt = $errCt + 1; + } + } + + # Write original value back into register + Mimosis::mimosis_register_write( + #$fpgalink, + $reg, + $tmp, + #$singleaccessmode + ); #usleep($slow2); + } + + if ($errCt == 0) { + + print("No problems detected.\n"); + $file{"RegisterRW"} = "S"; + + } + + else { + + print("Problems in Register R/W test detected.\n"); + $file{"RegisterRW"} = "F"; + + } + + } while ask_continue(); + +} + +sub chip_id { + + print "\n"; + print "#############################################################################\n"; + print "### CHIPID TEST ###\n"; + print "#############################################################################\n"; + print "\n"; + + + my @chipids = ( 0x0, 0x1 ); + + my $gpioReg = 0xd580; + my $testreg = 0x0020; # Pixel control register for testing + my $testval = 0x1; + my $shouldKill = 0; + my $errCt = 0; + + do { + foreach my $id (@chipids) { + + # Reset all + my $bitmaskClear = 0x1 << 30; + + trb_register_clearbit( + $fpgalink, + $gpioReg, + $bitmaskClear + ); + + usleep($slow2); + + # Set desired bits + my $bitmaskSet = $id << 30; + + trb_register_setbit( + $fpgalink, + $gpioReg, + $bitmaskSet + ); usleep($slow2); + + Mimosis::set_chipid($id); + + my $tmp = + Mimosis::mimosis_register_read( + $testreg, + ); + + usleep($slow2); + + Mimosis::mimosis_register_write( + $testreg, + $testval, + ); + + usleep(100000); + + my $testTmp = + Mimosis::mimosis_register_read( + $testreg, + ); + + usleep($slow2); + + if ( ( $testTmp&0xff ) != $testval ) { + + print "Chip-ID $id not working.\n"; + #$file{"CHIP-ID_$id"} = "F"; + $shouldKill += 1; + $errCt = $errCt + 1; + + } else { + + #$file{"CHIP-ID_$id"} = "S"; + } + } + + if ($errCt == 0) { + + print("No problems detected.\n"); + $file{"ChipIDTest"} = "S"; + + } + + else { + + print("Problems in chip ID test detected.\n"); + $file{"ChipIDTest"} = "F"; + + } + } while ask_continue(); + + # die "Found broken chip ids. Exiting.\n" if $shouldKill; + + # Reset chipid to 0x1 + Mimosis::set_chipid(0x1); + + trb_register_setbit( + $fpgalink, + $gpioReg, + 0x1 << 30 + ); + + usleep($slow2); + + #system("./../start.sh"); + #sleep(2); + +} + +sub link_test { + + print "\n"; + print "############################################################################\n"; + print "### LINK TEST ###\n"; + print "############################################################################\n"; + print "\n"; + + do { + doStartSh(); + } while rep_prog(); + + do { + doStartSh(); + + my $cntBadLinks = 0; + + for my $i (0 .. 7) { + + my $reg = trb_register_read( $fpgalink, 0xa000 + $i ); + $reg = ( $reg->{$fpgalink} & 0x7f00 ) >> 8; + + $cntBadLinks += 1 if $reg >= 70; + + $file{"Link_$i"} = $reg >= 70 ? "$reg\tBAD" : "$reg\tGOOD"; + } + + # die "Bad links. Exiting.\n" if $cntBadLinks > 0; + print "Bad links.\n" if $cntBadLinks > 0; + + } while ask_continue(); + +} + + +sub fast_dac_scan { + + print "\n"; + print "############################################################################\n"; + print "### FAST DACSCAN TEST ###\n"; + print "############################################################################\n"; + print "\n"; + + + chdir($sensorname); + mkdir("DACScan"); + chdir("DACScan"); + + do { + my @DACFAST = ('VPH', 'VPL', 'VPHFINE'); + + my %results = Mimosis::mimosis_dacscan( + dacs => \@DACFAST, + step => 10, + ); + + + my $picName = "fastdacscan.png"; + + my $chart = Chart::Gnuplot->new( + output => $picName, + terminal => "pngcairo", + title => "DAC-Scan", + xlabel => "Setting [LSB]", + ylabel => "Voltage output [mV]", + ); + + + my @dataArr; + + $chart->polygon( + vertices => [ + "0, 1100", + "250, 1290", + "250, 1115", + "0, 900", + "0, 1000", + ], + fill => { + density => 0.3, + color => "#A9A9A0", + }, + ); + + $chart->polygon( + vertices => [ + "0, 370", + "250, 1950", + "250, 1670", + "0, 320", + "0, 370", + ], + fill => { + density => 0.3, + color => "#A9A9A0", + }, + ); + + for my $dac ( keys %results ) { + + my $dataSet = Chart::Gnuplot::DataSet->new( + xdata => $results{$dac}{X}, + ydata => $results{$dac}{Y}, + title => "Plotting a line from Perl arrays", + style => "linespoints", + ); + + push(@dataArr, $dataSet); + } + + $chart->plot2d(@dataArr); + + system("display $picName"); + + chdir(".."); + + + print "Please enter rapid DAC scan result classification.\n"; + print "S = satisfactory if in grey areas\n"; + print "F = unsatisfactory and exiting.\n"; + + while ( 1 ) { + + print "Rapid DAC scan classification: "; + my $rapiddacclass = ; + chomp $rapiddacclass; + + if ( $rapiddacclass eq "S" || + $rapiddacclass eq "s" ) { + + $file{"RapidDACTest"} = "S"; + last; + + } elsif ( $rapiddacclass eq "F" || + $rapiddacclass eq "f" ) { + + $file{"RapidDACTest"} = "F"; + exit 0; + + } else { + print "Invalid classification. Try again.\n"; + } + } + + } while ask_continue(); + +} + +sub full_dac_scan { + + print "\n"; + print "############################################################################\n"; + print "### DACSCAN TEST ###\n"; + print "############################################################################\n"; + print "\n"; + + chdir($sensorname); + chdir("DACScan"); + + do { + my %names = ( + 'IBIAS' => 0x0040, + 'ITHR' => 0x0041, + 'IDB' => 0x0042, + 'VRESET' => 0x0043, + 'VPL' => 0x0044, + 'VPH' => 0x0045, + 'VPHFINE' => 0x0046, + 'VCASP' => 0x0047, + 'VCASNA' => 0x0048, + 'VCASNB' => 0x0049, + 'VCASNC' => 0x004a, + 'VCASND' => 0x004b, + 'VCASN2' => 0x004c, + 'VCLIP' => 0x004d, + # 'IBUFBIAS' => 0x004e, + ); + + my %dacVals = Mimosis::mimosis_dacscan( + # step => 50, + ); + + + my @VPHList = @{$dacVals{'VPH'}{'Y'}}; + my @VPLList = @{$dacVals{'VPL'}{'Y'}}; + my @VPHFINEList = @{$dacVals{'VPHFINE'}{'Y'}}; + my @VRESETList = @{$dacVals{'VRESET'}{'Y'}}; + my @VCASNAList = @{$dacVals{'VCASNA'}{'Y'}}; + my @VCASNBList = @{$dacVals{'VCASNB'}{'Y'}}; + my @VCASNCList = @{$dacVals{'VCASNC'}{'Y'}}; + my @VCASNDList = @{$dacVals{'VCASND'}{'Y'}}; + my @VCASN2List = @{$dacVals{'VCASN2'}{'Y'}}; + my @VCLIPList = @{$dacVals{'VCLIP'}{'Y'}}; + my @VCASPList = @{$dacVals{'VCASP'}{'Y'}}; + my @IBIASList = @{$dacVals{'IBIAS'}{'Y'}}; + my @ITHRList = @{$dacVals{'ITHR'}{'Y'}}; + my @IDBList = @{$dacVals{'IDB'}{'Y'}}; + + + my $picName = "full-dacscan.png"; + + my $chartPng = Chart::Gnuplot->new( + output => $picName, + terminal => "pngcairo", + title => "DAC-Scan", + xlabel => "Setting [LSB]", + ylabel => "Voltage output [mV]", + ); + + my @dataArr; + + for my $dac ( keys %dacVals) { + + my $dataSet = Chart::Gnuplot::DataSet->new( + xdata => $dacVals{$dac}{X}, + ydata => $dacVals{$dac}{Y}, + title => $dac, + style => "lines", + ); + + push(@dataArr, $dataSet); + } + + $chartPng->plot2d(@dataArr); + + system("display $picName"); + + + for my $i (0 .. scalar( @VPHFINEList ) - 1) { + $VPHFINEList[$i] = $VPHFINEList[$i] - $VPHList[0]; + } + + + my $sensorQuality = 4; + + $VPHOffset = $VPHList[0]; + my $VPLOffset = $VPLList[0]; + my $VRESETOffset = $VRESETList[0]; + my $VPHFOffset = $VPHFINEList[0]; + my $VPH210 = $VPHList[211]; + my $VPL210 = $VPLList[211]; + my $VRESET210 = $VRESETList[211]; + my $VPHF210 = $VPHFINEList[211] - $VPHFOffset; + + my $acceptableVPHOffsetLowerLimit = 300; + my $acceptableVPHOffsetHigherLimit = 430; + my $goodDNLLimit = 1; + my $goodINLLimit = 5; + + + if ( ($acceptableVPHOffsetLowerLimit <= $VPHOffset) && + ($acceptableVPHOffsetHigherLimit >= $VPHOffset) && + ($acceptableVPHOffsetLowerLimit <= $VPLOffset) && + ($acceptableVPHOffsetHigherLimit >= $VPLOffset) && + ($acceptableVPHOffsetLowerLimit <= $VRESETOffset) && + ($acceptableVPHOffsetHigherLimit >= $VRESETOffset) && + ($VPH210 >= 1410) && + ($VPL210 >= 1410) && + ($VRESET210 >= 1410) && + ($VPHF210 >= 180) ) { + + $sensorQuality = 3; + + if ( max(@VCASNAList) > 1100 && + max(@VCASNBList) > 1100 && + max(@VCASNCList) > 1100 && + max(@VCASNDList) > 1100 && + max(@VCASN2List) > 1100 && + max(@VCLIPList) > 550 && + max(@VCASPList) > 550 && + max(@IBIASList) >= 260 && + max(@ITHRList) >= 260 && + max(@IDBList) >= 260 ) { + + $sensorQuality = 2; + + my $arrRef = [ 3,3,3,3 + ]; + + sub calcAbsDNLAbsINL { + + my @dac = @{$_[0]}; + + my $gain = ($dac[199] - $dac[24]) / 175.0; + + my @dnl = ( 0 ); + my @inl = ( 0 ); + + for my $i (21 .. 201) { + + my $currentDNL = ( ($dac[$i] - $dac[$i-1]) / $gain ) - 1; + push(@dnl, $currentDNL); + push(@inl, $inl[$i-21]+$currentDNL); + } + + @dnl = reverse @dnl; + @inl = reverse @inl; + return ( \@inl, \@dnl ); + } + + + my ( $ibiasinlRef, $ibiasdnlRef ) = calcAbsDNLAbsINL(\@IBIASList); + my @IBIASINL = @{$ibiasinlRef}; + my @IBIASDNL = @{$ibiasdnlRef}; + + my ( $ithrinlRef, $ithrdnlRef ) = calcAbsDNLAbsINL(\@ITHRList); + my @ITHRINL = @{$ithrinlRef}; + my @ITHRDNL = @{$ithrdnlRef}; + + my ( $idbinlRef, $idbdnlRef ) = calcAbsDNLAbsINL(\@IDBList); + my @IDBINL = @{$idbinlRef}; + my @IDBDNL = @{$idbdnlRef}; + + my ( $vphinlRef, $vphdnlRef ) = calcAbsDNLAbsINL(\@VPHList); + my @VPHINL = @{$vphinlRef}; + my @VPHDNL = @{$vphdnlRef}; + + my ( $vplinlRef, $vpldnlRef ) = calcAbsDNLAbsINL(\@VPLList); + my @VPLINL = @{$vplinlRef}; + my @VPLDNL = @{$vpldnlRef}; + + my ( $vresetinlRef, $vresetdnlRef ) = calcAbsDNLAbsINL(\@VRESETList); + my @VRESETINL = @{$vresetinlRef}; + my @VRESETDNL = @{$vresetdnlRef}; + + my ( $vphfineinlRef, $vphfinednlRef ) = calcAbsDNLAbsINL(\@VPHFINEList); + my @VPHFINEINL = @{$vphfineinlRef}; + my @VPHFINEDNL = @{$vphfinednlRef}; + + my ( $vcasnainlRef, $vcasnadnlRef ) = calcAbsDNLAbsINL(\@VCASNAList); + my @VCASNAINL = @{$vcasnainlRef}; + my @VCASNADNL = @{$vcasnadnlRef}; + + my ( $vcasnbinlRef, $vcasnbdnlRef ) = calcAbsDNLAbsINL(\@VCASNBList); + my @VCASNBINL = @{$vcasnbinlRef}; + my @VCASNBDNL = @{$vcasnbdnlRef}; + + my ( $vcasncinlRef, $vcasncdnlRef ) = calcAbsDNLAbsINL(\@VCASNCList); + my @VCASNCINL = @{$vcasncinlRef}; + my @VCASNCDNL = @{$vcasncdnlRef}; + + my ( $vcasndinlRef, $vcasnddnlRef ) = calcAbsDNLAbsINL(\@VCASNDList); + my @VCASNDINL = @{$vcasndinlRef}; + my @VCASNDDNL = @{$vcasnddnlRef}; + + my ( $vcasn2inlRef, $vcasn2dnlRef ) = calcAbsDNLAbsINL(\@VCASN2List); + my @VCASN2INL = @{$vcasn2inlRef}; + my @VCASN2DNL = @{$vcasn2dnlRef}; + + my ( $vcaspinlRef, $vcaspdnlRef ) = calcAbsDNLAbsINL(\@VCASPList); + my @VCASPINL = @{$vcaspinlRef}; + my @VCASPDNL = @{$vcaspdnlRef}; + + my ( $vclipinlRef, $vclipdnlRef ) = calcAbsDNLAbsINL(\@VCLIPList); + my @VCLIPINL = @{$vclipinlRef}; + my @VCLIPDNL = @{$vclipdnlRef}; + + my $goodDNL = 0; + + if ( $IBIASDNL[2] < $goodDNLLimit + && $ITHRDNL[2] < $goodDNLLimit + && $IDBDNL[2] < $goodDNLLimit + && $VCASNADNL[2] < $goodDNLLimit + && $VCASNBDNL[2] < $goodDNLLimit + && $VCASNCDNL[2] < $goodDNLLimit + && $VCASNDDNL[2] < $goodDNLLimit + && $VCASN2DNL[2] < $goodDNLLimit + && $VCASPDNL[2] < $goodDNLLimit + && $VCLIPDNL[2] < $goodDNLLimit + && $VPHDNL[2] < $goodDNLLimit + && $VPLDNL[2] < $goodDNLLimit + && $VRESETDNL[2] < $goodDNLLimit + && $VPHFINEDNL[2] < $goodDNLLimit + ) { + $goodDNL = 1; + } + + my $goodINL = 0; + + if ( $IBIASINL[2] < $goodINLLimit + && $ITHRINL[2] < $goodINLLimit + && $IDBINL[2] < $goodINLLimit + && $VCASNAINL[2] < $goodINLLimit + && $VCASNBINL[2] < $goodINLLimit + && $VCASNCINL[2] < $goodINLLimit + && $VCASNDINL[2] < $goodINLLimit + && $VCASN2INL[2] < $goodINLLimit + && $VCASPINL[2] < $goodINLLimit + && $VCLIPINL[2] < $goodINLLimit + && $VPHINL[2] < 2 + && $VPLINL[2] < 2 + && $VRESETINL[2] < 2 + && $VPHFINEINL[2] < 2 + ) { + $goodINL = 1; + } + + if ($goodDNL && $goodINL) { + $sensorQuality = 1; + } + } + } + + $VPHFSlope = ($VPHFINEList[255] - $VPHFINEList[0]) / 255.0; + # $VPHFSlope = 1.; + $VPHOffsetElectron = 150; + $ZeroElectronVPHSetting = 95; + + for my $i (0 .. scalar(@VPHList)) { + + if ( ($VPHList[$i] gt ($VPLList[70] - 6)) # or ($VPHList[$i] lt ($VPLList[70] + 6)) + ) { + + $ZeroElectronVPHSetting = $i; + $VPHOffsetElectron = $VPHList[$i] - $VPLList[70]; + last; + } + } + + print("ZeroSetting\t$ZeroElectronVPHSetting\t$VPHOffsetElectron\n"); + + print("Sensor Quality for DACs: $sensorQuality\n"); + + chdir(".."); + + $file{"DACQuality"} = $sensorQuality; + $file{"VPHFSlope"} = $VPHFSlope; + $file{"VPHSetting0Electrons"} = "$ZeroElectronVPHSetting\t$VPHOffsetElectron"; + + } while ask_continue(); + + chdir(".."); + +} + +sub fit_thr { + my ($fitterfname, $fittervphOffsetElectron, $fittervphfSlope, $fittervphStepSize, $fittermaxPulse) = @_; + Mimosis::mimosis_make_fit( $fitterfname , $fittervphOffsetElectron, $fittervphfSlope, $fittervphStepSize, $fittermaxPulse); + # system("/usr/bin/python3 /d/jspc37/mimosis/scripts/pulse/fit-raw.py $fname $dirName $vphOffsetElectron $vphfSlope"); +} + +sub scurve_fast_test { + + + my ( $scurvefastVPHOffsetElectron, $scurvefastVPHOffset, $scurvefastVPHFSlope, $scurvefastvphStepSize, $scurvemaxPulse ) = @_; + + chdir($sensorname); + + print "\n"; + print "############################################################################\n"; + print "### FAST SCURVE TEST ###\n"; + print "############################################################################\n"; + print "\n"; + + $matrixParams{'A'}{'LOWERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 95 : + (( $backbias == 1000 && $irraddeg >= 1000 ) ? 60 : (( $backbias == 1000 && $irraddeg == 0 ) ? 70 : (( $backbias == 3000 && $irraddeg == 0 ) ? 110 : 50 ))); + + $matrixParams{'A'}{'UPPERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 120 : + (( $backbias == 1000 && $irraddeg >= 1000 ) ? 100 : (( $backbias == 1000 && $irraddeg == 0 ) ? 115 : (( $backbias == 3000 && $irraddeg == 0 ) ? 165 : 200 ))); + + + $matrixParams{'B'}{'LOWERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 100 : + (( $backbias == 1000 && $irraddeg >= 1000 ) ? 75 : (( $backbias == 1000 && $irraddeg == 0 ) ? 95 : (( $backbias == 3000 && $irraddeg == 0 ) ? 130 : 50 ))); + + $matrixParams{'B'}{'UPPERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 150 : + (( $backbias == 1000 && $irraddeg >= 1000 ) ? 125 : (( $backbias == 1000 && $irraddeg == 0 ) ? 140 : (( $backbias == 3000 && $irraddeg == 0 ) ? 185 : 200 ))); + + + $matrixParams{'C'}{'LOWERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 100 : + (( $backbias == 1000 && $irraddeg >= 1000 ) ? 75 : (( $backbias == 1000 && $irraddeg == 0 ) ? 95 : (( $backbias == 3000 && $irraddeg == 0 ) ? 130 : 50 ))); + + $matrixParams{'C'}{'UPPERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 150 : + (( $backbias == 1000 && $irraddeg >= 1000 ) ? 125 : (( $backbias == 1000 && $irraddeg == 0 ) ? 140 : (( $backbias == 3000 && $irraddeg == 0 ) ? 185 : 200 ))); + + + $matrixParams{'D'}{'LOWERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 95 : + (( $backbias == 1000 && $irraddeg >= 1000 ) ? 60 : (( $backbias == 1000 && $irraddeg == 0 ) ? 75 : (( $backbias == 3000 && $irraddeg == 0 ) ? 115 : 50 ))); + + $matrixParams{'D'}{'UPPERLIMIT'} = ( $backbias == 3000 && $irraddeg >= 1000 ) ? 120 : + (( $backbias == 1000 && $irraddeg >= 1000 ) ? 100 : (( $backbias == 1000 && $irraddeg == 0 ) ? 140 : (( $backbias == 3000 && $irraddeg == 0 ) ? 180 : 200 ))); + + + do { + chdir("/d/jspc37/mimosis/scripts/qa/" . $sensorname); + my $settingsScurves = "../CONF_scurves.pl"; + + cp($settingsScurves, "$sensorname/$settingsScurves"); + + Mimosis::mimosis_load_file( file => $settingsScurves ); + + + Mimosis::mimosis_register_write( + 0x45, + $scurvefastVPHOffset, + ); + + Mimosis::mimosis_register_write( + 0x4d, + int( 45 + $backbias/1000.0 * 12.0 + 0.5 ), + ); + + Mimosis::mimosis_register_write( + 0x4c, + 180, + ); + + Mimosis::mimosis_register_write(0x46, 255); + Mimosis::mimosis_register_write(0x45, $scurvefastVPHOffset); + Mimosis::mimosis_register_write(0x44, 70); + + + + print "Press Enter, to start pulsing.\n"; + ; + + + foreach my $matrix ( sort keys %matrixParams ) { + + my $yspan = $matrixParams{$matrix}{'YSPAN'}; + my $xstart = $matrixParams{$matrix}{'XSTART'}; + my $xstop = $matrixParams{$matrix}{'XSTOP'}; + + Mimosis::mimosis_instr_write( 0x3f ); + Mimosis::mimosis_instr_write( 0x04 ); + Mimosis::mimosis_instr_write( 0x3e ); + + Mimosis::mimosis_pulse( + ystart => 250, + ystop => 253, + yspan => $yspan, + xstart => $xstart, + xstop => $xstop, + modexp => 3, + ); + + my $ll = $matrixParams{$matrix}{'LOWERLIMIT'}; + my $ul = $matrixParams{$matrix}{'UPPERLIMIT'}; + + print "Find proper VCASN in Go4. Suggested range: $ll - $ul\n"; + + my $foundF = 0; + + while ( 1 ) { + + print "Enter the appropriate VCASN$matrix value or \'F\' if bad: " ; + + my $vcasnTmp = ; + chomp $vcasnTmp; + + if ( $vcasnTmp eq "F" or + $vcasnTmp eq "f" ) { + + $file{"CoarseSCurves,MATRIX-$matrix"} = "F"; + + $foundF = 1; + last; + + } else { + + $file{"CoarseSCurves,MATRIX-$matrix"} = $vcasnTmp; + $matrixParams{$matrix}{"VCASNCOARSE"} = $vcasnTmp; + last; + } + } + + exit 0 if $foundF; + } + + + + print "Press Enter, to start scuves\n"; + ; + + foreach my $matrix ( sort keys %matrixParams ) { + + my $matrixDir = "MATRIX-" . $matrix; + mkdir($matrixDir); + chdir($matrixDir); + + my $yspan = $matrixParams{$matrix}{'YSPAN'}; + my $xstart = $matrixParams{$matrix}{'XSTART'}; + my $xstop = $matrixParams{$matrix}{'XSTOP'}; + my $vcasnstart = $matrixParams{$matrix}{"VCASNCOARSE"} - 5; #-5 + my $vcasnstop = $matrixParams{$matrix}{"VCASNCOARSE"} + 5; #+5 + + Mimosis::mimosis_scurves( + ystart => 250, + ystop => 253, + yspan => $yspan, + xstart => $xstart, + xstop => $xstop, + vcasnreg => 'VCASN' . $matrix, + vcasnstart => $vcasnstart, + vcasnstop => $vcasnstop, + setstep => $scurvefastvphStepSize, + setcount => $scurvemaxPulse, + ); + + opendir my $dir, "." or die "Cannot open directory: $!"; + my @files = readdir $dir; + + foreach my $f ( @files ) { + + if ( $f =~ /VCASN/ ) { + + my $dirName = Cwd::cwd() . "/$f"; + + chdir($dirName); + + $matrixParams{$matrix}{"THREAD"} = + fit_thr( + "$dirName/$f.csv", + $scurvefastVPHOffsetElectron, + $scurvefastVPHFSlope, + $scurvefastvphStepSize, + $scurvemaxPulse ); + + chdir(".."); + } + } + + closedir $dir; + chdir(".."); + } + + + + + print "Wait for fits to finish.\n"; + + + print("Approximate a VCASN for each submatrix where the GMDT is closest to 150 e!\n"); + + my $foundF = 0; + + foreach my $matrix ( sort keys %matrixParams ) { + + while ( 1 ) { + + print "Enter the appropriate VCASN$matrix value or \'F\' if bad: " ; + + my $vcasnTmp = ; + chomp $vcasnTmp; + + if ( $vcasnTmp eq "F" or + $vcasnTmp eq "f" ) { + + $file{"RapidSCurves,MATRIX-$matrix"} = "F"; + + $foundF = 1; + last; + + } else { + + $file{"SCurvesFull,MATRIX-$matrix"} = $vcasnTmp; + $matrixParams{$matrix}{"VCASNFINAL"} = $vcasnTmp; + last; + } + } + } + if ( $foundF ) { exit 0; } + + } while ask_continue(); + +} + +sub scurve_full_test { + + my ( $scurvefullVPHOffsetElectron, $scurvefullVPHOffset, $scurvefullVPHFSlope, $scurvefullvphStepSize, $scurvemaxPulse ) = @_; + + chdir($sensorname); + mkdir("FinalSCurves"); + chdir("FinalSCurves"); + + print "\n"; + print "############################################################################\n"; + print "### FULL SCURVE TEST ###\n"; + print "############################################################################\n"; + print "\n"; + + do { + my $settingsScurves = "../CONF_scurves.pl"; + + cp($settingsScurves, "$sensorname/$settingsScurves"); + + Mimosis::mimosis_load_file( file => $settingsScurves ); + + + Mimosis::mimosis_register_write( + 0x45, + $scurvefullVPHOffset, + ); + + Mimosis::mimosis_register_write( + 0x4d, + int( 45 + $backbias/1000.0 * 12.0 + 0.5 ), + ); + + Mimosis::mimosis_register_write( + 0x4c, + 180, + ); + + Mimosis::mimosis_register_write(0x46, 255); + Mimosis::mimosis_register_write(0x45, $scurvefullVPHOffset); + Mimosis::mimosis_register_write(0x44, 70); + + + + print "Press Enter, to start scuves\n"; + ; + + foreach my $matrix ( sort keys %matrixParams ) { + + my $matrixDir = "MATRIX-" . $matrix; + mkdir($matrixDir); + chdir($matrixDir); + + my $yspan = $matrixParams{$matrix}{'YSPAN'}; + my $xstart = $matrixParams{$matrix}{'XSTART'}; + my $xstop = $matrixParams{$matrix}{'XSTOP'}; + my $vcasnstart = $matrixParams{$matrix}{"VCASNFINAL"}; + my $vcasnstop = $matrixParams{$matrix}{"VCASNFINAL"}; + + Mimosis::mimosis_scurves( + ystart => 0, + ystop => 503, + yspan => $yspan, + xstart => $xstart, + xstop => $xstop, + vcasnreg => 'VCASN' . $matrix, + vcasnstart => $vcasnstart, + vcasnstop => $vcasnstop, + setstep => $scurvefullvphStepSize, + setcount => $scurvemaxPulse, + ); + + opendir my $dir, "." or die "Cannot open directory: $!"; + my @files = readdir $dir; + + foreach my $f ( @files ) { + + if ( $f =~ /VCASN/ ) { + + my $dirName = Cwd::cwd() . "/$f"; + + chdir($dirName); + + $matrixParams{$matrix}{"THREAD"} = + fit_thr( + "$dirName/$f.csv", + $scurvefullVPHOffsetElectron, + $scurvefullVPHFSlope, + $scurvefullvphStepSize, + $scurvemaxPulse ); + + chdir(".."); + } + } + + closedir $dir; + chdir(".."); + } + + + + + print "Wait for fits to finish.\n"; + + } while ask_continue(); + +} + + +bb_test(); + +powering_tests(); + +reg_std_addr(); + +do { + doStartSh(); +} while rep_prog(); + +dac_reg_test(); + +do { + doStartSh(); +} while rep_prog(); + +Mimosis::mimosis_load_file( file => $settingsDACRegTest ); + +std_rw_test(); + +if ($proxyType == "F") { + chip_id(); +} + +do { + doStartSh(); +} while rep_prog(); + +fast_dac_scan(); + +full_dac_scan(); + +do { + doStartSh(); +} while rep_prog(); + +scurve_fast_test($VPHOffsetElectron, $ZeroElectronVPHSetting, $VPHFSlope, 5, 100); + +scurve_full_test($VPHOffsetElectron, $ZeroElectronVPHSetting, $VPHFSlope, 5, 100); + + +open(RESULTS_FH, '>', $sensorname . "/results.db") or die $!; +print RESULTS_FH "$_\t$file{$_}\n" foreach (keys %file); +close RESULTS_FH;