-#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)
+++ /dev/null
-#!/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 = <STDIN>;
- 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 = <STDIN>;
- 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 = <STDIN>;
- 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 = <STDIN>;
-# 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;
-];
- <STDIN>;
- 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 = <STDIN>;
- 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 = <STDIN>;
- 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 = <STDIN>;
- 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;
--- /dev/null
+#!/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 = <STDIN>;
+ 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 = <STDIN>;
+ 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");
+ <STDIN>;
+
+ $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 = <STDIN>;
+ 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 = <STDIN>;
+ 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 = <STDIN>;
+ 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 = <STDIN>;
+ 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 = <STDIN>;
+ 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";
+ <STDIN>;
+
+
+ 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 = <STDIN>;
+ 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";
+ <STDIN>;
+
+ 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 = <STDIN>;
+ 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";
+ <STDIN>;
+
+ 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;
--- /dev/null
+#!/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 = <STDIN>;
+ 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 = <STDIN>;
+ 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");
+ <STDIN>;
+
+ $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 = <STDIN>;
+ 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 = <STDIN>;
+ 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 = <STDIN>;
+ 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 = <STDIN>;
+ 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 = <STDIN>;
+ 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";
+ <STDIN>;
+
+
+ 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 = <STDIN>;
+ 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";
+ <STDIN>;
+
+ 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 = <STDIN>;
+ 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";
+ <STDIN>;
+
+ 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";
+ <STDIN>;
+
+ 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";
+ <STDIN>;
+
+ 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;
+++ /dev/null
-0 320 370
-220 1569 1850
-250 1670 1950
+++ /dev/null
-0 1000 1100
-50 1045 1155
-100 1090 1210
-150 1135 1265
-200 1180 1320
-250 1225 1375
--- /dev/null
+#!/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 = <STDIN>;
+ 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 = <STDIN>;
+ 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 = <STDIN>;
+ 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 = <STDIN>;
+ 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";
+ <STDIN>;
+
+
+ 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 = <STDIN>;
+ 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";
+ <STDIN>;
+
+ 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 = <STDIN>;
+ 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 = <STDIN>;
+ 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;
--- /dev/null
+##!/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 = <STDIN>;
+ 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 = <STDIN>;
+ 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 = <STDIN>;
+ 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 = <STDIN>;
+ 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";
+ <STDIN>;
+
+
+ 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 = <STDIN>;
+ 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";
+ <STDIN>;
+
+ 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 = <STDIN>;
+ 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 = <STDIN>;
+ 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;
--- /dev/null
+#!/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 = <STDIN>;
+ 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 = <STDIN>;
+ 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 = <STDIN>;
+ 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 = <STDIN>;
+ 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";
+ <STDIN>;
+
+
+ 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 = <STDIN>;
+ 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";
+ <STDIN>;
+
+ 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 = <STDIN>;
+ 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 = <STDIN>;
+ 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;
--- /dev/null
+#!/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 = <STDIN>;
+ 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 = <STDIN>;
+ 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 = <STDIN>;
+ 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 = <STDIN>;
+ 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 = <STDIN>;
+ 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 = <STDIN>;
+ 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 = <STDIN>;
+ 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";
+ <STDIN>;
+
+
+ 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 = <STDIN>;
+ 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";
+ <STDIN>;
+
+ 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 = <STDIN>;
+ 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";
+ <STDIN>;
+
+ 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;