From 37110604705551637de628c66dd5cd5b1acb009c Mon Sep 17 00:00:00 2001 From: Maps Date: Thu, 12 Dec 2024 12:11:14 +0100 Subject: [PATCH] changes in Mimosis module --- scripts/modules/Mimosis/Makefile | 6 +- scripts/modules/Mimosis/Mimosis.c | 59 +- scripts/modules/Mimosis/Mimosis.o | Bin 76432 -> 73600 bytes scripts/modules/Mimosis/Mimosis.xs | 23 +- scripts/modules/Mimosis/blib/lib/Mimosis.pm | 1048 ++++++++++++++++- scripts/modules/Mimosis/blib/lib/reg.pl | 90 +- scripts/modules/Mimosis/blib/man3/Mimosis.3pm | 2 +- scripts/modules/Mimosis/lib/Mimosis.pm | 1048 ++++++++++++++++- scripts/modules/Mimosis/reg.pl | 46 - 9 files changed, 2154 insertions(+), 168 deletions(-) delete mode 100755 scripts/modules/Mimosis/reg.pl diff --git a/scripts/modules/Mimosis/Makefile b/scripts/modules/Mimosis/Makefile index 7d93d54..0c6f4d6 100644 --- a/scripts/modules/Mimosis/Makefile +++ b/scripts/modules/Mimosis/Makefile @@ -191,8 +191,7 @@ PERL_ARCHIVEDEP = PERL_ARCHIVE_AFTER = -TO_INST_PM = lib/Mimosis.pm \ - reg.pl +TO_INST_PM = lib/Mimosis.pm # --- MakeMaker platform_constants section: @@ -1051,8 +1050,7 @@ ppd : pm_to_blib : $(FIRST_MAKEFILE) $(TO_INST_PM) $(NOECHO) $(ABSPERLRUN) -MExtUtils::Install -e 'pm_to_blib({@ARGV}, '\''$(INST_LIB)/auto'\'', q[$(PM_FILTER)], '\''$(PERM_DIR)'\'')' -- \ - 'lib/Mimosis.pm' 'blib/lib/Mimosis.pm' \ - 'reg.pl' '$(INST_LIB)/reg.pl' + 'lib/Mimosis.pm' 'blib/lib/Mimosis.pm' $(NOECHO) $(TOUCH) pm_to_blib diff --git a/scripts/modules/Mimosis/Mimosis.c b/scripts/modules/Mimosis/Mimosis.c index 01d798c..ff5831a 100644 --- a/scripts/modules/Mimosis/Mimosis.c +++ b/scripts/modules/Mimosis/Mimosis.c @@ -170,53 +170,6 @@ S_croak_xs_usage(const CV *const cv, const char *const params) #line 172 "Mimosis.c" -XS_EUPXS(XS_Mimosis_mimosis_register_write); /* prototype to pass -Wmissing-prototypes */ -XS_EUPXS(XS_Mimosis_mimosis_register_write) -{ - dVAR; dXSARGS; - if (items != 4) - croak_xs_usage(cv, "fpga, reg, data, singleaccess"); - { - int fpga = (int)SvIV(ST(0)) -; - int reg = (int)SvIV(ST(1)) -; - int data = (int)SvIV(ST(2)) -; - bool singleaccess = (bool)SvTRUE(ST(3)) -; -#line 28 "Mimosis.xs" - mimosis::register_write(fpga,reg,data,singleaccess); -#line 191 "Mimosis.c" - } - XSRETURN_EMPTY; -} - - -XS_EUPXS(XS_Mimosis_mimosis_register_read); /* prototype to pass -Wmissing-prototypes */ -XS_EUPXS(XS_Mimosis_mimosis_register_read) -{ - dVAR; dXSARGS; - if (items != 3) - croak_xs_usage(cv, "fpga, reg, singleaccess"); - { - int fpga = (int)SvIV(ST(0)) -; - int reg = (int)SvIV(ST(1)) -; - bool singleaccess = (bool)SvTRUE(ST(2)) -; - int RETVAL; - dXSTARG; -#line 37 "Mimosis.xs" - RETVAL = mimosis::register_read(fpga,reg,singleaccess); -#line 214 "Mimosis.c" - XSprePUSH; PUSHi((IV)RETVAL); - } - XSRETURN(1); -} - - XS_EUPXS(XS_Mimosis_mimosis_find_mod); /* prototype to pass -Wmissing-prototypes */ XS_EUPXS(XS_Mimosis_mimosis_find_mod) { @@ -240,9 +193,9 @@ XS_EUPXS(XS_Mimosis_mimosis_find_mod) ; int RETVAL; dXSTARG; -#line 52 "Mimosis.xs" +#line 31 "Mimosis.xs" RETVAL = mimosis::find_mod(source, fpga, yLow, yHig, xLow, xHig, modPulse); -#line 246 "Mimosis.c" +#line 199 "Mimosis.c" XSprePUSH; PUSHi((IV)RETVAL); } XSRETURN(1); @@ -260,7 +213,7 @@ XS_EUPXS(XS_Mimosis_mimosis_loop_vph) ; int fpga = (int)SvIV(ST(1)) ; - bool sa = (bool)SvTRUE(ST(2)) + int sa = (int)SvIV(ST(2)) ; int yLow = (int)SvIV(ST(3)) ; @@ -282,9 +235,9 @@ XS_EUPXS(XS_Mimosis_mimosis_loop_vph) ; int exp = (int)SvIV(ST(12)) ; -#line 74 "Mimosis.xs" +#line 53 "Mimosis.xs" mimosis::loop_vph(source, fpga, sa, yLow, yHig, xLow, xHig, vphSta, vphEnd, vphTra, maxCounts, mod, exp); -#line 288 "Mimosis.c" +#line 241 "Mimosis.c" } XSRETURN_EMPTY; } @@ -317,8 +270,6 @@ XS_EXTERNAL(boot_Mimosis) # endif #endif - newXS_deffile("Mimosis::mimosis_register_write", XS_Mimosis_mimosis_register_write); - newXS_deffile("Mimosis::mimosis_register_read", XS_Mimosis_mimosis_register_read); newXS_deffile("Mimosis::mimosis_find_mod", XS_Mimosis_mimosis_find_mod); newXS_deffile("Mimosis::mimosis_loop_vph", XS_Mimosis_mimosis_loop_vph); #if PERL_VERSION_LE(5, 21, 5) diff --git a/scripts/modules/Mimosis/Mimosis.o b/scripts/modules/Mimosis/Mimosis.o index 1b75c7842ddde4a4740bd30aa9b18b8890bbbc62..86e203b4340658171a062b39ce2519f59b3baf0c 100644 GIT binary patch literal 73600 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 diff --git a/scripts/modules/Mimosis/Mimosis.xs b/scripts/modules/Mimosis/Mimosis.xs index 1e9cd52..562b5a3 100755 --- a/scripts/modules/Mimosis/Mimosis.xs +++ b/scripts/modules/Mimosis/Mimosis.xs @@ -18,27 +18,6 @@ extern "C" { MODULE = Mimosis PACKAGE = Mimosis -void -mimosis_register_write(fpga,reg,data,singleaccess); - int fpga - int reg - int data - bool singleaccess - CODE: - mimosis::register_write(fpga,reg,data,singleaccess); - - -int -mimosis_register_read(fpga,reg,singleaccess); - int fpga - int reg - bool singleaccess - CODE: - RETVAL = mimosis::register_read(fpga,reg,singleaccess); - OUTPUT: - RETVAL - - int mimosis_find_mod(source, fpga, yLow, yHig, xLow, xHig, modPulse) char* source @@ -59,7 +38,7 @@ void mimosis_loop_vph(source, fpga, sa, yLow, yHig, xLow, xHig, vphSta, vphEnd, vphTra, maxCounts, mod, exp) char* source int fpga - bool sa + int sa int yLow int yHig int xLow diff --git a/scripts/modules/Mimosis/blib/lib/Mimosis.pm b/scripts/modules/Mimosis/blib/lib/Mimosis.pm index e9527e9..c805fb8 100755 --- a/scripts/modules/Mimosis/blib/lib/Mimosis.pm +++ b/scripts/modules/Mimosis/blib/lib/Mimosis.pm @@ -6,24 +6,31 @@ use warnings; require Exporter; +use HADES::TrbNet; + +use Time::HiRes qw(usleep); + +use Chart::Gnuplot; +use File::Copy; +use POSIX; + +use Data::Dump qw( dump ); +use Data::Dumper; + our @ISA = qw(Exporter); # Items to export into callers namespace by default. Note: do not export # names by default without a very good reason. Use EXPORT_OK instead. # Do not simply export all your public functions/methods/constants. -# This allows declaration use Mimosis ':all'; +# This allows declaration use Mimosis ':all'; # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK # will save memory. -our %EXPORT_TAGS = ( 'all' => [ qw( - -) ] ); +our %EXPORT_TAGS = ( 'all' => [ qw() ] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); -our @EXPORT = qw( - -); +our @EXPORT = qw(); our $VERSION = '0.01'; @@ -32,6 +39,1031 @@ XSLoader::load('Mimosis', $VERSION); # Preloaded methods go here. + +my $fpga = 0xa000; +my $chipid = 0x1; +my $singleAccess = 0; +my $sleepVal1 = 1000; +my $sleepVal2 = 1000000; + +my $fpgaHub = 0xc000; + +my $mbsStream = 'mbss://localhost:36789'; + +my $trbI2cSpeedReg = 0xde00; + +my $i2cSpeed = 0x1e; + + +my $printall = 0; + +my $trbAdcRegWrMem = 0xd681; +my $trbAdcRegRdMem = 0xd684; + +my $trbMimRegWrMem = 0xde01; +my $trbMimRegRdMem = 0xde04; + +my $adc_addr = 0x48; +my $adc_wreg = 0x1; +my $adc_rreg = 0x0; + +my $adc_cmdV = 0xa380; +my $adc_cmdI = 0x9380; + + +my $adcConv = ( 2 * 4096 ) / 2**16; + +my $collect_i2c_errors = 0; + + + +sub set_fpga { + $fpga = $_[0] if defined $_[0]; +} + + +sub get_fpga { + print "$fpga\n"; + return $fpga } + +sub set_chipid { + $chipid = $_[0] if defined $_[0]; +} + +sub get_chipid { return $chipid; } + +sub set_singleAccess { + $singleAccess = $_[0] if defined $_[0]; +} + +sub get_singleAccess { return $singleAccess; } + + + +sub set_sleepVal1 { + $sleepVal1 = $_[0] if defined $_[0]; +} + +sub get_sleepVal1 { return $sleepVal1; } + + +sub set_sleepVal2 { + $sleepVal2 = $_[0] if defined $_[0]; +} + +sub get_sleepVal2 { return $sleepVal2; } + + +sub set_fpgaHub { + $fpgaHub = $_[0] if defined $_[0]; +} + + +sub get_fpgaHub { + print "$fpgaHub\n"; + return $fpgaHub } + + + + +sub set_mbsStream { + $mbsStream = $_[0] if defined $_[0]; +} + +sub get_mbsStream { return $mbsStream; } + + +sub set_printall { + $printall = $_[0] if defined $_[0]; +} + +sub get_printall { return $printall; } + + +sub set_i2cSpeed { + $i2cSpeed = $_[0] if defined $_[0]; + trb_register_write( $fpga, $trbI2cSpeedReg, $i2cSpeed ); +} + +sub get_i2cSpeed { return $i2cSpeed; } + + +sub set_adcToIkfProxy { + $adc_cmdV = 0xe380; + $adc_cmdI = 0xd380; +} + +sub set_adcToIPHCProxy { + $adc_cmdV = 0xa380; + $adc_cmdI = 0x9380; +} + + + +sub make_require { + do "/d/jspc37/mimosis/scripts/TrbNetUart.pm"; + TNU_set_device("/dev/ttyUSB0"); +} + + + +sub set_collect_i2c_errors { + $collect_i2c_errors = $_[0] if defined $_[0]; +} + +sub get_collect_i2c_errors { return $collect_i2c_errors; } + + +our %DAC = ( + 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, }, + ); + + + +sub mimosis_trb_reset { + + my $trbMimRstReg = 0xde05; + trb_register_clearbit($fpga, $trbMimRstReg, 0x100); + usleep($sleepVal2); + trb_register_setbit($fpga, $trbMimRstReg, 0x100); + usleep($sleepVal2); +} + + + +sub mimosis_trb_word_align { + + my $trbMimInRst = 0x9010; + trb_register_setbit($fpga, $trbMimInRst, 1); + usleep($sleepVal2); + trb_register_clearbit($fpga, $trbMimInRst, 1); + usleep($sleepVal2); + + my $trbMimInpStat = 0x9000; + my $delpos = trb_register_read($fpga, $trbMimInpStat); + $delpos = ($delpos & 0x7f000000) >> 24; + + my $trbMimAlignCtrl = 0x9100; + trb_register_clearbit($fpga, $trbMimAlignCtrl, 0b100000000); + sleep(1); + trb_register_setbit($fpga, $trbMimAlignCtrl, 0b100000000); + usleep($sleepVal2); + + my @val = @{trb_register_read_mem($fpga, 0x9110, 0, 8)->{$fpga}}; + printf("%x\n", ($_ & 0xFFFF)) foreach ( @val ); + return(@val); +} + + + +my @i2c_errors; + + +sub collect_i2c_errors { + + my $regBuf = + trb_register_read( $fpga, $trbMimRegRdMem ); + + my $status = + (($regBuf->{$fpga}//0) >> 16 ) & 0xff; + + push ( @i2c_errors, $status ); +} + + + + +sub get_i2c_errors { + + my @tmp_i2c_errors = @i2c_errors; + @i2c_errors = (); + return @tmp_i2c_errors; +} + + + +sub adc_i2c_command { + + my ( + $addr, + $cmd, + $data, + $rw, + $skipCmd, + $wordByte + ) = @_; + + my $regData = + ( $data << 16 ) + ( $cmd << 8 ) + 0x80 + $addr; + + my $regFlag = + ( $rw << 8 ) + ( $skipCmd << 4 ) + $wordByte; + + if ( $rw == 0 ) { + + trb_register_write_mem( + $fpga, + $trbAdcRegWrMem, + 0, + [ $regFlag, $regData ], + 2 ); + + usleep($sleepVal1); + + } elsif ( $rw == 1 ) { + + trb_register_write_mem( + $fpga, + $trbAdcRegWrMem, + 0, + [ $regFlag, $regData ], + 2 ); + + usleep($sleepVal1); + + my $regReturn = + trb_register_read( $fpga, $trbAdcRegRdMem ); + + usleep($sleepVal1); + + return $regReturn->{$fpga} & 0xffff; + } +} + + + + +sub mimosis_i2c_command { + + my ( + $addr, + $cmd, + $data, + $rw, + $skipCmd, + $wordByte + ) = @_; + + my $regData = + ( $data << 16 ) + ( $cmd << 8 ) + ( $addr << 1 ); + + my $regFlag = + ( $rw << 8 ) + ( $skipCmd << 4 ) + $wordByte; + + my $regReturn; + my $regBuf; + + if ( $rw == 0 ) { + + trb_register_write_mem( + $fpga, + $trbMimRegWrMem, + 0, + [ $regFlag, $regData, 0x1 ], + 3 ); + + usleep($sleepVal1); + + $regBuf = + trb_register_read( $fpga, $trbMimRegRdMem ); + + } elsif ( $rw == 1 ) { + + trb_register_write_mem( + $fpga, + $trbMimRegWrMem, + 0, + [ $regFlag, $regData, 0x1 ], + 3 ); + + usleep($sleepVal1); + + $regBuf = + trb_register_read( $fpga, $trbMimRegRdMem ); + + usleep($sleepVal1); + + } + + if ( $printall ) { + + my $status = + (($regBuf->{$fpga}//0) >> 16 ) & 0xff; + printf("I2CStatus: 0x%02x\n", $status); + } + + collect_i2c_errors() if $collect_i2c_errors; + + if ( $rw == 1 ) { + + if ($fpga < 0xfe00) + { + return $regBuf->{$fpga} & 0xffff; + } + } + +} + + + + +sub mimosis_register_write { + + my ( + $mimReg, + $mimData, + ) = @_; + + my $addr = + ($chipid << 4) + 0x2; + + my $cmd = + ( $mimReg >> 8 ); + + my $data = + ( ( $mimReg & 0xff ) << 8 ) + $mimData; + + + if ( $singleAccess ) { + + mimosis_i2c_command( + $addr,0, $mimReg>>8, 0, 1, 0); + + mimosis_i2c_command( + $addr+1, 0, $mimReg, 0, 1, 0); + + mimosis_i2c_command( + $addr+2, 0, $mimData, 0, 1, 0); + + } else { + + mimosis_i2c_command( + $addr, $cmd, $data, 0, 0, 1); + } + +} + + + + +sub mimosis_register_read { + + my ( $mimReg ) = @_; + + my $addr = ( $chipid << 4 ) + 0x2; + my $cmd = ( $mimReg >> 8 ); + my $data = ( $mimReg & 0xff ); + + if ($singleAccess) { + + mimosis_i2c_command( + $addr, 0, $mimReg>>8, 0, 1, 0); + + mimosis_i2c_command( + $addr+1, 0, $mimReg, 0, 1, 0); + + } else { + + mimosis_i2c_command( + $addr, $cmd, $data, 0, 0, 0); + } + + $addr = ($chipid << 4) + 0x5; + + my $val = mimosis_i2c_command( + $addr, 0, 0, 1, 1, 0 ); + + return $val & 0xff; +} + + + + +sub mimosis_instr_write { + + my ( $cmd ) = @_; + + # CHIPID??? + trb_register_write_mem( + $fpga, $trbMimRegWrMem, 0, + [ 0x0, ( $cmd << 8 ) + ( 0x11 << 1 ), 0x1 ], + 3 ); + + usleep($sleepVal1); +} + + + + +sub mimosis_load_file { + + my %params = @_; + + my $file = $params{'file'}; + my $printwrong = defined $params{'printwrong'} ? 1 : 0; + + defined $file or die "Mimosis::mimosis_load_file: Must provide \$file."; + + my @config = do $file; + + foreach my $i (@config) { + + if ( defined( @$i[1] ) ) { + + mimosis_register_write( + @$i[0], @$i[1] ); + + if( $printall ) { + +# printf( "%x %x %x\n", +# $fpga, @$i[0], @$i[1] ); + + my $retVal = + trb_register_read($fpga, 0xde04); + + foreach my $k ( keys %{$retVal} ) { + + my $status = + (($retVal->{$k}//0) >> 16 ) & 0xff; + + printf("%x %x Status: %x\n", + $k, @$i[0], $status); + } + + } + } + } + + if ( $printall || $printwrong ) { + + foreach my $i (@config) { + + if ( defined( @$i[1] ) ) { + + my $val = + mimosis_register_read(@$i[0]); + + unless(($val & 0xff) == @$i[1]) { + + my $retVal = + trb_register_read($fpga, 0xde04); + + foreach my $k ( keys %{$retVal} ) { + + my $status = + (($retVal->{$k}//0) >> 16 ) & 0xff; + + printf("%x %x %x Status: %x\n", + $k, @$i[0], $val, $status); + } + } + } + } + } +} + + + + +sub mimosis_scan_single_dac { + + my %params = @_; + + my $dac = $params{'dac'}; + + my $start = + defined $params{'start'} ? + $params{'start'} : 0; + + my $stop = + defined $params{'stop'} ? + $params{'stop'} : 255; + + my $step = + defined $params{'step'} ? + $params{'step'} : 1; + + my $name = + defined $params{'name'} ? + $params{'name'} : ""; + + + my @resVals; + my @resTicks; + + $name .= "_" if $name ne ""; + + my $fName = $name . $dac . ".csv"; + open( FH, '>', $fName ) or die $!; + + mimosis_register_write( $Mimosis::DAC{$dac}{'MONITOR'}, $Mimosis::DAC{$dac}{'MONVAL'} ); + + for( my $set = $start; + $set <= $stop; + $set += $step ) { + + mimosis_register_write( $Mimosis::DAC{$dac}{'ADDR'}, $set ); + + my $adcCmd = + $Mimosis::DAC{$dac}{'TYPE'} eq "VOLTAGE" ? + $adc_cmdV : $adc_cmdI; + + + adc_i2c_command( + $adc_addr, $adc_wreg, $adcCmd, 0, 0, 1 ); + + usleep(8000); + + my $raw = adc_i2c_command( + $adc_addr, $adc_rreg, 0x0, 1, 0, 1 ); + + printf( FH "%x\t%d\t%f\n", + $Mimosis::DAC{$dac}{'ADDR'}, $set, $raw * $adcConv ); + + push ( @resVals, $raw*$adcConv ); + push ( @resTicks, $set ); + } + + mimosis_register_write( + $Mimosis::DAC{$dac}{'ADDR'}, + $Mimosis::DAC{$dac}{'RESET'} + ); + + close(FH); + + return ( \@resTicks, \@resVals ); +} + + + + +sub mimosis_dacscan { + + my %params = @_; + + my $dacArrRef = $params{'dacs'}; + my $start = $params{'start'}; + my $stop = $params{'stop'}; + my $step = $params{'step'}; + my $name = $params{'name'}; + + my @dacArr = + defined $params{'dacs'} ? + @{ $dacArrRef } : (); + @dacArr = %Mimosis::DAC unless scalar(@dacArr) > 0; + + + $start = 0 unless defined $start; + $stop = 255 unless defined $stop; + $step = 1 unless defined $step; + $name = "" unless defined $name; + + + my %results; + + for my $dac ( @dacArr ) { + + next if not defined $Mimosis::DAC{$dac}{'MONVAL'}; + + printf( "Scan: %s\n", $dac ) if $printall; + + ( $results{$dac}{X}, $results{$dac}{Y} ) = + mimosis_scan_single_dac( + dac => $dac, + start => $start, + stop => $stop, + step => $step, + name => $name, + ); + } + + $name .= "_" if $name ne ""; + + my $chart = Chart::Gnuplot->new( + output => $name . "dacscan.png", + terminal => "pngcairo", + title => "DAC-Scan", + xlabel => "Setting [LSB]", + ylabel => "Voltage output [mV]", + ); + + + my @dataArr; + + 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); + + return %results; +} + + + + +sub mimosis_select_pixel { + + my %params = @_; + my $yStart = $params{'ystart'}; + my $yStop = $params{'ystop'}; + my $yStep = $params{'ystep'}; + + my $xStart = $params{'xstart'}; + my $xStop = $params{'xstop'}; + my $xStep = $params{'xstep'}; + + $yStart = 0 unless defined $yStart; + $yStop = 503 unless defined $yStop; + $yStep = 1 unless defined $yStep; + + $xStart = 0 unless defined $xStart; + $xStop = 1023 unless defined $xStop; + $xStep = 1 unless defined $xStep; + + for ( my $y = $yStart; + $y <= $yStop; + $y += $yStep ) { + + my $regAddY = $y/8; + my $regBitY = 1<<( $y % 8 ); + my $regWordY = ($regAddY<<8) + 0x84; + + mimosis_register_write($regWordY, $regBitY ); + + my $currRegX = floor $xStart/16; + my $word82 = 0; + my $word81 = 0; + + for ( my $x = $xStart; + $x <= $xStop; + $x += $xStep ) { + + if( (($x/16) == $currRegX) + && ($x != $xStop) + ) { + + if ($x%2 == 1) { $word82 |= (1<<(floor($x/2)%8)); } + elsif ($x%2 == 0) { $word81 |= (1<<(floor($x/2)%8)); } + + } else { + + if ( ($x == $xStop) && + (($x/16) != $currRegX) + ) { + if ($x%2 == 1) { $word82 |= (1<<(floor($x/2)%8)); } + elsif ($x%2 == 0) { $word81 |= (1<<(floor($x/2)%8)); } + } + + if($word82 == $word81) { + + my $addr = ($currRegX<<8) + 0x83; + mimosis_register_write( $addr, $word81 ); + mimosis_instr_write( 0x05 ); + mimosis_register_write( $addr, 0 ); + + } else { + + my $addr81 = ($currRegX<<8) + 0x81; + my $addr82 = ($currRegX<<8) + 0x82; + + mimosis_register_write( $addr81, $word81 ); + mimosis_register_write( $addr82, $word82 ); + mimosis_instr_write( 0x05 ); + mimosis_register_write( $addr81, 0 ); + mimosis_register_write( $addr82, 0 ); + } + + $currRegX = floor $x/16; + $word81 = 0; + $word82 = 0; + + if ($x%2 == 1){ $word82 = (1<<(floor($x/2)%8)); } + elsif ($x%2 == 0){ $word81 = (1<<(floor($x/2)%8)); } + } + } + } + mimosis_register_write( 0x4087, 0x0 ); +} + + + + + +sub mimosis_scan_rows { + + my %params = @_; + + my $yStart = $params{'ystart'}; + my $yStop = $params{'ystop'}; + my $yStep = $params{'ystep'}; + my $ySpan = $params{'yspan'}; + + my $xStart = $params{'xstart'}; + my $xStop = $params{'xstop'}; + my $xStep = $params{'xstep'}; + + my $setStart = $params{'setstart'}; + my $setStop = $params{'setstop'}; + my $setStep = $params{'setstep'}; + my $setCount = $params{'setcount'}; + + my $modExp = $params{'modexp'}; + my $modFound = $params{'modfound'}; + + $ySpan = 2 unless defined $ySpan; + + $setStart = 0 unless defined $setStart; + $setStop = 255 unless defined $setStop; + $setStep = 1 unless defined $setStep; + $setCount= 4000 unless defined $setCount; + + $modExp = 3 unless defined $modExp; + + $modFound = mimosis_find_mod( + $mbsStream, + $fpga, + $yStart, + $yStart+$ySpan-1, + $xStart, + $xStop, + $modExp ) unless defined $modFound; + + + mimosis_register_write( 0x20, 0x40); + + + for( my $yLow = $yStart; + $yLow <= $yStop; + $yLow += $ySpan ) { + + my $yHigh = $yLow + $ySpan - 1; + + printf("Mark pixels: %d - %d, %d - %d\n", + $yLow, $yHigh, $xStart, $xStop); + + mimosis_select_pixel( + ystart => $yLow, + ystop => $yHigh, + ystep => $yStep, + xstart => $xStart, + xstop => $xStop, + xstep => $xStep, + ); + + mimosis_register_write( 0x46, 0); +# usleep(100000); # usleep(1000000); + + mimosis_loop_vph( + $mbsStream, # source + $fpga, # fpga + $singleAccess, # sa + $yLow, # yLow + $yHigh, # yHig + $xStart, # xLow + $xStop, # xHig + $setStart, # vphSta + $setStop, # vphEnd + $setStep, # vphTra + $setCount, # maxCounts + $modFound, # mod + $modExp, # exp + ); + + mimosis_instr_write( 0x3f ); + mimosis_instr_write( 0x04 ); + mimosis_instr_write( 0x3e ); + + mimosis_register_write( 0x46, 0); + } +} + + + + + +sub mimosis_scurves { + + my %params = @_; + + my $yStart = $params{'ystart'}; + my $yStop = $params{'ystop'}; + my $yStep = $params{'ystep'}; + my $ySpan = $params{'yspan'}; + + my $xStart = $params{'xstart'}; + my $xStop = $params{'xstop'}; + my $xStep = $params{'xstep'}; + + my $setStart = $params{'setstart'}; + my $setStop = $params{'setstop'}; + my $setStep = $params{'setstep'}; + my $setCount = $params{'setcount'}; + + my $vcasnRegStr = $params{'vcasnreg'}; + my $vcasnStart = $params{'vcasnstart'}; + my $vcasnStop = $params{'vcasnstop'}; + my $vcasnStep = $params{'vcasnstep'}; + + my $pixpulseAASc = $params{'pixpulseaa'}; + my $pixpulseABSc = $params{'pixpulseab'}; + my $pixpulseDASc = $params{'pixpulseda'}; + my $pixpulseDBSc = $params{'pixpulsedb'}; + + my $modExp = $params{'modexp'}; + my $modFound = $params{'modfound'}; + + $yStart = 0 unless defined $yStart; + $yStop = 503 unless defined $yStop; + $yStep = 1 unless defined $yStep; + $ySpan = 1 unless defined $ySpan; + + $xStart = 0 unless defined $xStart; + $xStop = 1023 unless defined $xStop; + $xStep = 1 unless defined $xStep; + + $setStart = 0 unless defined $setStart; + $setStop = 255 unless defined $setStop; + $setStep = 1 unless defined $setStep; + $setCount= 4000 unless defined $setCount; + + $pixpulseAASc = 25 unless defined $pixpulseAASc; + $pixpulseABSc = 75 unless defined $pixpulseABSc; + $pixpulseDASc = 0 unless defined $pixpulseDASc; + $pixpulseDBSc = 0 unless defined $pixpulseDBSc; + + mimosis_register_write(0x066, $pixpulseAASc&0x00ff ); + mimosis_register_write(0x166,($pixpulseAASc&0xff00)>>8); + mimosis_register_write(0x076, $pixpulseABSc&0x00ff ); + mimosis_register_write(0x176,($pixpulseABSc&0xff00)>>8); + mimosis_register_write(0x067, $pixpulseDASc&0x00ff ); + mimosis_register_write(0x167,($pixpulseDASc&0xff00)>>8); + mimosis_register_write(0x077, $pixpulseDBSc&0x00ff ); + mimosis_register_write(0x177,($pixpulseDBSc&0xff00)>>8); + + mimosis_instr_write( 0x3f ); + mimosis_instr_write( 0x04 ); + mimosis_instr_write( 0x3e ); + + mimosis_register_write( 0x20, 0x40 ); + + die "Invalid DAC given" if not exists $Mimosis::DAC{$vcasnRegStr}; + my $vcasnReg = $Mimosis::DAC{$vcasnRegStr}{'ADDR'}; + my $vcasnVal = mimosis_register_read( $vcasnReg ); + + $vcasnStart = $vcasnVal unless defined $vcasnStart; + $vcasnStop = $vcasnStart unless defined $vcasnStop; + $vcasnStep = 1 unless defined $vcasnStep; + + $modExp = 3 unless defined $modExp; + + Mimosis::mimosis_pulse( + ystart => $yStart, + ystop => $yStart + $yStep, + yspan => 1, + xstart => $xStart, + xstop => $xStop, + modexp => $modExp, + ); + + + $modFound = mimosis_find_mod( + $mbsStream, + $fpga, + $yStart, + $yStart+$ySpan-1, + $xStart, + $xStop, + # $modExp ); + $modExp ) unless defined $modFound; + + print "MODFOUND: $modFound\n"; + + mimosis_instr_write( 0x3f ); + mimosis_instr_write( 0x04 ); + mimosis_instr_write( 0x3e ); + + for ( my $vcasnSet = $vcasnStart; + $vcasnSet <= $vcasnStop; + $vcasnSet += $vcasnStep ) { + + mimosis_register_write( $vcasnReg, $vcasnSet ); + + print "DAC: $vcasnSet\n" if $printall; + + mimosis_scan_rows ( + ystart => $yStart, + ystop => $yStop, + ystep => $yStep, + yspan => $ySpan, + xstart => $xStart, + xstop => $xStop, + xstep => $xStep, + setstart => $setStart, + setstop => $setStop, + setstep => $setStep, + setcount => $setCount, + modexp => $modExp, + modfound => $modFound, + ); + + my $dirName = $vcasnRegStr . "-" . $vcasnSet; + mkdir($dirName); + my $pulsesFile = "scurve-pulses.csv"; + move($pulsesFile, $dirName . "/" . $dirName . ".csv"); + } +} + + + + + +sub mimosis_mask { + + my %params = @_; + + mimosis_register_write( 0x20, 0x42 ); + + mimosis_select_pixel( + xstart => $params{'xstart'}, + xstop => $params{'xstop'}, + xstep => $params{'xstep'}, + ystart => $params{'ystart'}, + ystop => $params{'ystop'}, + ystep => $params{'ystep'}, + ); +} + + + + +sub mimosis_pulse { + + my %params = @_; + + my $pixpulseAASc = $params{'pixpulseaa'}; + my $pixpulseABSc = $params{'pixpulseab'}; + my $pixpulseDASc = $params{'pixpulseda'}; + my $pixpulseDBSc = $params{'pixpulsedb'}; + my $modExp = $params{'modexp'}; + + $modExp = 3 unless defined $modExp; + mimosis_register_write( 0x7d, $modExp ); + + $pixpulseAASc = 25 unless defined $pixpulseAASc; + $pixpulseABSc = 75 unless defined $pixpulseABSc; + $pixpulseDASc = 0 unless defined $pixpulseDASc; + $pixpulseDBSc = 0 unless defined $pixpulseDBSc; + + mimosis_register_write(0x066, $pixpulseAASc&0x00ff ); + mimosis_register_write(0x166,($pixpulseAASc&0xff00)>>8); + mimosis_register_write(0x076, $pixpulseABSc&0x00ff ); + mimosis_register_write(0x176,($pixpulseABSc&0xff00)>>8); + mimosis_register_write(0x067, $pixpulseDASc&0x00ff ); + mimosis_register_write(0x167,($pixpulseDASc&0xff00)>>8); + mimosis_register_write(0x077, $pixpulseDBSc&0x00ff ); + mimosis_register_write(0x177,($pixpulseDBSc&0xff00)>>8); + + mimosis_instr_write( 0x3f ); + mimosis_instr_write( 0x04 ); + mimosis_instr_write( 0x3e ); + + mimosis_register_write( 0x20, 0x40 ); + + mimosis_select_pixel( + xstart => $params{'xstart'}, + xstop => $params{'xstop'}, + xstep => $params{'xstep'}, + ystart => $params{'ystart'}, + ystop => $params{'ystop'}, + ystep => $params{'ystep'}, + ); +} + + + 1; __END__ # Below is stub documentation for your module. You'd better edit it! @@ -53,6 +1085,8 @@ unedited. Blah blah blah. + + =head2 EXPORT None by default. diff --git a/scripts/modules/Mimosis/blib/lib/reg.pl b/scripts/modules/Mimosis/blib/lib/reg.pl index 235422f..d7b2920 100755 --- a/scripts/modules/Mimosis/blib/lib/reg.pl +++ b/scripts/modules/Mimosis/blib/lib/reg.pl @@ -17,30 +17,66 @@ my $val = 0x40; my $sa = 0; -# Mimosis::mimosis_register_write($fpga, $reg, $val, $sa); -# my $retval = Mimosis::mimosis_register_read($fpga, $reg, $sa); -# printf("%x\t%x\n",$val, $retval); - -# $val = 0x2; -# Mimosis::mimosis_register_write($fpga, $reg, $val, $sa); -# $retval = Mimosis::mimosis_register_read($fpga, $reg, $sa); -# printf("%x\t%x\n",$val, $retval); - - -{ - my $source = "mbss://localhost:36789"; - my $yLow = 250; - my $yHig = 253; - my $xLow = 0; - my $xHig = 127; - my $exp = 3; - my $mod = Mimosis::mimosis_find_mod($source, $fpga, $yLow, $yHig, $xLow, $xHig, $exp); - print "Mod: $mod\n"; - - my $vphSta = 0; - my $vphEnd = 255; - my $vphTra = 1; - my $maxCounts = 500; - - Mimosis::mimosis_loop_vph($source, $fpga, $sa, $yLow, $yHig, $xLow, $xHig, $vphSta, $vphEnd, $vphTra, $maxCounts, $mod, $exp); -} +# Mimosis::set_printall(1); + +# Mimosis::mimosis_dacscan("IBIAS"); + +# Mimosis::mimosis_select_pixel( +# xstart => 0, +# xstop => 10, +# xstep => 1, +# ystart => 100, +# ystop => 110, +# ystep => 1, +# ); + +my $yLow = 250; +my $yHig = 253; +my $xLow = 0; +my $xHig = 127; + + +Mimosis::mimosis_scurves( + ystart => $yLow, + ystop => $yHig, + yspan => 4, + + xstart => $xLow, + xstop => $xHig, + + vcasnreg => 0x48, + ); + + +# Mimosis::mimosis_scan_rows( +# ystart => $yLow, +# ystop => $yHig, +# ystep => 1, +# yspan => 4, +# xstart => $xLow, +# xstop => $xHig, +# xstep => 1, +# # setstart => 0, +# # setstop => 255, +# # setstep => 1, +# # setcount => 4, +# ); + + +# { +# my $source = "mbss://localhost:36789"; +# my $yLow = 250; +# my $yHig = 253; +# my $xLow = 0; +# my $xHig = 127; +# my $exp = 3; +# my $mod = Mimosis::mimosis_find_mod($source, $fpga, $yLow, $yHig, $xLow, $xHig, $exp); +# print "Mod: $mod\n"; + +# my $vphSta = 0; +# my $vphEnd = 255; +# my $vphTra = 1; +# my $maxCounts = 500; + +# Mimosis::mimosis_loop_vph($source, $fpga, $sa, $yLow, $yHig, $xLow, $xHig, $vphSta, $vphEnd, $vphTra, $maxCounts, $mod, $exp); +# } diff --git a/scripts/modules/Mimosis/blib/man3/Mimosis.3pm b/scripts/modules/Mimosis/blib/man3/Mimosis.3pm index 3bd8e8a..f7c0577 100644 --- a/scripts/modules/Mimosis/blib/man3/Mimosis.3pm +++ b/scripts/modules/Mimosis/blib/man3/Mimosis.3pm @@ -67,7 +67,7 @@ .\" ======================================================================== .\" .IX Title "Mimosis 3" -.TH Mimosis 3 "2024-05-28" "perl v5.26.1" "User Contributed Perl Documentation" +.TH Mimosis 3 "2024-12-03" "perl v5.26.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/scripts/modules/Mimosis/lib/Mimosis.pm b/scripts/modules/Mimosis/lib/Mimosis.pm index e9527e9..c805fb8 100755 --- a/scripts/modules/Mimosis/lib/Mimosis.pm +++ b/scripts/modules/Mimosis/lib/Mimosis.pm @@ -6,24 +6,31 @@ use warnings; require Exporter; +use HADES::TrbNet; + +use Time::HiRes qw(usleep); + +use Chart::Gnuplot; +use File::Copy; +use POSIX; + +use Data::Dump qw( dump ); +use Data::Dumper; + our @ISA = qw(Exporter); # Items to export into callers namespace by default. Note: do not export # names by default without a very good reason. Use EXPORT_OK instead. # Do not simply export all your public functions/methods/constants. -# This allows declaration use Mimosis ':all'; +# This allows declaration use Mimosis ':all'; # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK # will save memory. -our %EXPORT_TAGS = ( 'all' => [ qw( - -) ] ); +our %EXPORT_TAGS = ( 'all' => [ qw() ] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); -our @EXPORT = qw( - -); +our @EXPORT = qw(); our $VERSION = '0.01'; @@ -32,6 +39,1031 @@ XSLoader::load('Mimosis', $VERSION); # Preloaded methods go here. + +my $fpga = 0xa000; +my $chipid = 0x1; +my $singleAccess = 0; +my $sleepVal1 = 1000; +my $sleepVal2 = 1000000; + +my $fpgaHub = 0xc000; + +my $mbsStream = 'mbss://localhost:36789'; + +my $trbI2cSpeedReg = 0xde00; + +my $i2cSpeed = 0x1e; + + +my $printall = 0; + +my $trbAdcRegWrMem = 0xd681; +my $trbAdcRegRdMem = 0xd684; + +my $trbMimRegWrMem = 0xde01; +my $trbMimRegRdMem = 0xde04; + +my $adc_addr = 0x48; +my $adc_wreg = 0x1; +my $adc_rreg = 0x0; + +my $adc_cmdV = 0xa380; +my $adc_cmdI = 0x9380; + + +my $adcConv = ( 2 * 4096 ) / 2**16; + +my $collect_i2c_errors = 0; + + + +sub set_fpga { + $fpga = $_[0] if defined $_[0]; +} + + +sub get_fpga { + print "$fpga\n"; + return $fpga } + +sub set_chipid { + $chipid = $_[0] if defined $_[0]; +} + +sub get_chipid { return $chipid; } + +sub set_singleAccess { + $singleAccess = $_[0] if defined $_[0]; +} + +sub get_singleAccess { return $singleAccess; } + + + +sub set_sleepVal1 { + $sleepVal1 = $_[0] if defined $_[0]; +} + +sub get_sleepVal1 { return $sleepVal1; } + + +sub set_sleepVal2 { + $sleepVal2 = $_[0] if defined $_[0]; +} + +sub get_sleepVal2 { return $sleepVal2; } + + +sub set_fpgaHub { + $fpgaHub = $_[0] if defined $_[0]; +} + + +sub get_fpgaHub { + print "$fpgaHub\n"; + return $fpgaHub } + + + + +sub set_mbsStream { + $mbsStream = $_[0] if defined $_[0]; +} + +sub get_mbsStream { return $mbsStream; } + + +sub set_printall { + $printall = $_[0] if defined $_[0]; +} + +sub get_printall { return $printall; } + + +sub set_i2cSpeed { + $i2cSpeed = $_[0] if defined $_[0]; + trb_register_write( $fpga, $trbI2cSpeedReg, $i2cSpeed ); +} + +sub get_i2cSpeed { return $i2cSpeed; } + + +sub set_adcToIkfProxy { + $adc_cmdV = 0xe380; + $adc_cmdI = 0xd380; +} + +sub set_adcToIPHCProxy { + $adc_cmdV = 0xa380; + $adc_cmdI = 0x9380; +} + + + +sub make_require { + do "/d/jspc37/mimosis/scripts/TrbNetUart.pm"; + TNU_set_device("/dev/ttyUSB0"); +} + + + +sub set_collect_i2c_errors { + $collect_i2c_errors = $_[0] if defined $_[0]; +} + +sub get_collect_i2c_errors { return $collect_i2c_errors; } + + +our %DAC = ( + 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, }, + ); + + + +sub mimosis_trb_reset { + + my $trbMimRstReg = 0xde05; + trb_register_clearbit($fpga, $trbMimRstReg, 0x100); + usleep($sleepVal2); + trb_register_setbit($fpga, $trbMimRstReg, 0x100); + usleep($sleepVal2); +} + + + +sub mimosis_trb_word_align { + + my $trbMimInRst = 0x9010; + trb_register_setbit($fpga, $trbMimInRst, 1); + usleep($sleepVal2); + trb_register_clearbit($fpga, $trbMimInRst, 1); + usleep($sleepVal2); + + my $trbMimInpStat = 0x9000; + my $delpos = trb_register_read($fpga, $trbMimInpStat); + $delpos = ($delpos & 0x7f000000) >> 24; + + my $trbMimAlignCtrl = 0x9100; + trb_register_clearbit($fpga, $trbMimAlignCtrl, 0b100000000); + sleep(1); + trb_register_setbit($fpga, $trbMimAlignCtrl, 0b100000000); + usleep($sleepVal2); + + my @val = @{trb_register_read_mem($fpga, 0x9110, 0, 8)->{$fpga}}; + printf("%x\n", ($_ & 0xFFFF)) foreach ( @val ); + return(@val); +} + + + +my @i2c_errors; + + +sub collect_i2c_errors { + + my $regBuf = + trb_register_read( $fpga, $trbMimRegRdMem ); + + my $status = + (($regBuf->{$fpga}//0) >> 16 ) & 0xff; + + push ( @i2c_errors, $status ); +} + + + + +sub get_i2c_errors { + + my @tmp_i2c_errors = @i2c_errors; + @i2c_errors = (); + return @tmp_i2c_errors; +} + + + +sub adc_i2c_command { + + my ( + $addr, + $cmd, + $data, + $rw, + $skipCmd, + $wordByte + ) = @_; + + my $regData = + ( $data << 16 ) + ( $cmd << 8 ) + 0x80 + $addr; + + my $regFlag = + ( $rw << 8 ) + ( $skipCmd << 4 ) + $wordByte; + + if ( $rw == 0 ) { + + trb_register_write_mem( + $fpga, + $trbAdcRegWrMem, + 0, + [ $regFlag, $regData ], + 2 ); + + usleep($sleepVal1); + + } elsif ( $rw == 1 ) { + + trb_register_write_mem( + $fpga, + $trbAdcRegWrMem, + 0, + [ $regFlag, $regData ], + 2 ); + + usleep($sleepVal1); + + my $regReturn = + trb_register_read( $fpga, $trbAdcRegRdMem ); + + usleep($sleepVal1); + + return $regReturn->{$fpga} & 0xffff; + } +} + + + + +sub mimosis_i2c_command { + + my ( + $addr, + $cmd, + $data, + $rw, + $skipCmd, + $wordByte + ) = @_; + + my $regData = + ( $data << 16 ) + ( $cmd << 8 ) + ( $addr << 1 ); + + my $regFlag = + ( $rw << 8 ) + ( $skipCmd << 4 ) + $wordByte; + + my $regReturn; + my $regBuf; + + if ( $rw == 0 ) { + + trb_register_write_mem( + $fpga, + $trbMimRegWrMem, + 0, + [ $regFlag, $regData, 0x1 ], + 3 ); + + usleep($sleepVal1); + + $regBuf = + trb_register_read( $fpga, $trbMimRegRdMem ); + + } elsif ( $rw == 1 ) { + + trb_register_write_mem( + $fpga, + $trbMimRegWrMem, + 0, + [ $regFlag, $regData, 0x1 ], + 3 ); + + usleep($sleepVal1); + + $regBuf = + trb_register_read( $fpga, $trbMimRegRdMem ); + + usleep($sleepVal1); + + } + + if ( $printall ) { + + my $status = + (($regBuf->{$fpga}//0) >> 16 ) & 0xff; + printf("I2CStatus: 0x%02x\n", $status); + } + + collect_i2c_errors() if $collect_i2c_errors; + + if ( $rw == 1 ) { + + if ($fpga < 0xfe00) + { + return $regBuf->{$fpga} & 0xffff; + } + } + +} + + + + +sub mimosis_register_write { + + my ( + $mimReg, + $mimData, + ) = @_; + + my $addr = + ($chipid << 4) + 0x2; + + my $cmd = + ( $mimReg >> 8 ); + + my $data = + ( ( $mimReg & 0xff ) << 8 ) + $mimData; + + + if ( $singleAccess ) { + + mimosis_i2c_command( + $addr,0, $mimReg>>8, 0, 1, 0); + + mimosis_i2c_command( + $addr+1, 0, $mimReg, 0, 1, 0); + + mimosis_i2c_command( + $addr+2, 0, $mimData, 0, 1, 0); + + } else { + + mimosis_i2c_command( + $addr, $cmd, $data, 0, 0, 1); + } + +} + + + + +sub mimosis_register_read { + + my ( $mimReg ) = @_; + + my $addr = ( $chipid << 4 ) + 0x2; + my $cmd = ( $mimReg >> 8 ); + my $data = ( $mimReg & 0xff ); + + if ($singleAccess) { + + mimosis_i2c_command( + $addr, 0, $mimReg>>8, 0, 1, 0); + + mimosis_i2c_command( + $addr+1, 0, $mimReg, 0, 1, 0); + + } else { + + mimosis_i2c_command( + $addr, $cmd, $data, 0, 0, 0); + } + + $addr = ($chipid << 4) + 0x5; + + my $val = mimosis_i2c_command( + $addr, 0, 0, 1, 1, 0 ); + + return $val & 0xff; +} + + + + +sub mimosis_instr_write { + + my ( $cmd ) = @_; + + # CHIPID??? + trb_register_write_mem( + $fpga, $trbMimRegWrMem, 0, + [ 0x0, ( $cmd << 8 ) + ( 0x11 << 1 ), 0x1 ], + 3 ); + + usleep($sleepVal1); +} + + + + +sub mimosis_load_file { + + my %params = @_; + + my $file = $params{'file'}; + my $printwrong = defined $params{'printwrong'} ? 1 : 0; + + defined $file or die "Mimosis::mimosis_load_file: Must provide \$file."; + + my @config = do $file; + + foreach my $i (@config) { + + if ( defined( @$i[1] ) ) { + + mimosis_register_write( + @$i[0], @$i[1] ); + + if( $printall ) { + +# printf( "%x %x %x\n", +# $fpga, @$i[0], @$i[1] ); + + my $retVal = + trb_register_read($fpga, 0xde04); + + foreach my $k ( keys %{$retVal} ) { + + my $status = + (($retVal->{$k}//0) >> 16 ) & 0xff; + + printf("%x %x Status: %x\n", + $k, @$i[0], $status); + } + + } + } + } + + if ( $printall || $printwrong ) { + + foreach my $i (@config) { + + if ( defined( @$i[1] ) ) { + + my $val = + mimosis_register_read(@$i[0]); + + unless(($val & 0xff) == @$i[1]) { + + my $retVal = + trb_register_read($fpga, 0xde04); + + foreach my $k ( keys %{$retVal} ) { + + my $status = + (($retVal->{$k}//0) >> 16 ) & 0xff; + + printf("%x %x %x Status: %x\n", + $k, @$i[0], $val, $status); + } + } + } + } + } +} + + + + +sub mimosis_scan_single_dac { + + my %params = @_; + + my $dac = $params{'dac'}; + + my $start = + defined $params{'start'} ? + $params{'start'} : 0; + + my $stop = + defined $params{'stop'} ? + $params{'stop'} : 255; + + my $step = + defined $params{'step'} ? + $params{'step'} : 1; + + my $name = + defined $params{'name'} ? + $params{'name'} : ""; + + + my @resVals; + my @resTicks; + + $name .= "_" if $name ne ""; + + my $fName = $name . $dac . ".csv"; + open( FH, '>', $fName ) or die $!; + + mimosis_register_write( $Mimosis::DAC{$dac}{'MONITOR'}, $Mimosis::DAC{$dac}{'MONVAL'} ); + + for( my $set = $start; + $set <= $stop; + $set += $step ) { + + mimosis_register_write( $Mimosis::DAC{$dac}{'ADDR'}, $set ); + + my $adcCmd = + $Mimosis::DAC{$dac}{'TYPE'} eq "VOLTAGE" ? + $adc_cmdV : $adc_cmdI; + + + adc_i2c_command( + $adc_addr, $adc_wreg, $adcCmd, 0, 0, 1 ); + + usleep(8000); + + my $raw = adc_i2c_command( + $adc_addr, $adc_rreg, 0x0, 1, 0, 1 ); + + printf( FH "%x\t%d\t%f\n", + $Mimosis::DAC{$dac}{'ADDR'}, $set, $raw * $adcConv ); + + push ( @resVals, $raw*$adcConv ); + push ( @resTicks, $set ); + } + + mimosis_register_write( + $Mimosis::DAC{$dac}{'ADDR'}, + $Mimosis::DAC{$dac}{'RESET'} + ); + + close(FH); + + return ( \@resTicks, \@resVals ); +} + + + + +sub mimosis_dacscan { + + my %params = @_; + + my $dacArrRef = $params{'dacs'}; + my $start = $params{'start'}; + my $stop = $params{'stop'}; + my $step = $params{'step'}; + my $name = $params{'name'}; + + my @dacArr = + defined $params{'dacs'} ? + @{ $dacArrRef } : (); + @dacArr = %Mimosis::DAC unless scalar(@dacArr) > 0; + + + $start = 0 unless defined $start; + $stop = 255 unless defined $stop; + $step = 1 unless defined $step; + $name = "" unless defined $name; + + + my %results; + + for my $dac ( @dacArr ) { + + next if not defined $Mimosis::DAC{$dac}{'MONVAL'}; + + printf( "Scan: %s\n", $dac ) if $printall; + + ( $results{$dac}{X}, $results{$dac}{Y} ) = + mimosis_scan_single_dac( + dac => $dac, + start => $start, + stop => $stop, + step => $step, + name => $name, + ); + } + + $name .= "_" if $name ne ""; + + my $chart = Chart::Gnuplot->new( + output => $name . "dacscan.png", + terminal => "pngcairo", + title => "DAC-Scan", + xlabel => "Setting [LSB]", + ylabel => "Voltage output [mV]", + ); + + + my @dataArr; + + 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); + + return %results; +} + + + + +sub mimosis_select_pixel { + + my %params = @_; + my $yStart = $params{'ystart'}; + my $yStop = $params{'ystop'}; + my $yStep = $params{'ystep'}; + + my $xStart = $params{'xstart'}; + my $xStop = $params{'xstop'}; + my $xStep = $params{'xstep'}; + + $yStart = 0 unless defined $yStart; + $yStop = 503 unless defined $yStop; + $yStep = 1 unless defined $yStep; + + $xStart = 0 unless defined $xStart; + $xStop = 1023 unless defined $xStop; + $xStep = 1 unless defined $xStep; + + for ( my $y = $yStart; + $y <= $yStop; + $y += $yStep ) { + + my $regAddY = $y/8; + my $regBitY = 1<<( $y % 8 ); + my $regWordY = ($regAddY<<8) + 0x84; + + mimosis_register_write($regWordY, $regBitY ); + + my $currRegX = floor $xStart/16; + my $word82 = 0; + my $word81 = 0; + + for ( my $x = $xStart; + $x <= $xStop; + $x += $xStep ) { + + if( (($x/16) == $currRegX) + && ($x != $xStop) + ) { + + if ($x%2 == 1) { $word82 |= (1<<(floor($x/2)%8)); } + elsif ($x%2 == 0) { $word81 |= (1<<(floor($x/2)%8)); } + + } else { + + if ( ($x == $xStop) && + (($x/16) != $currRegX) + ) { + if ($x%2 == 1) { $word82 |= (1<<(floor($x/2)%8)); } + elsif ($x%2 == 0) { $word81 |= (1<<(floor($x/2)%8)); } + } + + if($word82 == $word81) { + + my $addr = ($currRegX<<8) + 0x83; + mimosis_register_write( $addr, $word81 ); + mimosis_instr_write( 0x05 ); + mimosis_register_write( $addr, 0 ); + + } else { + + my $addr81 = ($currRegX<<8) + 0x81; + my $addr82 = ($currRegX<<8) + 0x82; + + mimosis_register_write( $addr81, $word81 ); + mimosis_register_write( $addr82, $word82 ); + mimosis_instr_write( 0x05 ); + mimosis_register_write( $addr81, 0 ); + mimosis_register_write( $addr82, 0 ); + } + + $currRegX = floor $x/16; + $word81 = 0; + $word82 = 0; + + if ($x%2 == 1){ $word82 = (1<<(floor($x/2)%8)); } + elsif ($x%2 == 0){ $word81 = (1<<(floor($x/2)%8)); } + } + } + } + mimosis_register_write( 0x4087, 0x0 ); +} + + + + + +sub mimosis_scan_rows { + + my %params = @_; + + my $yStart = $params{'ystart'}; + my $yStop = $params{'ystop'}; + my $yStep = $params{'ystep'}; + my $ySpan = $params{'yspan'}; + + my $xStart = $params{'xstart'}; + my $xStop = $params{'xstop'}; + my $xStep = $params{'xstep'}; + + my $setStart = $params{'setstart'}; + my $setStop = $params{'setstop'}; + my $setStep = $params{'setstep'}; + my $setCount = $params{'setcount'}; + + my $modExp = $params{'modexp'}; + my $modFound = $params{'modfound'}; + + $ySpan = 2 unless defined $ySpan; + + $setStart = 0 unless defined $setStart; + $setStop = 255 unless defined $setStop; + $setStep = 1 unless defined $setStep; + $setCount= 4000 unless defined $setCount; + + $modExp = 3 unless defined $modExp; + + $modFound = mimosis_find_mod( + $mbsStream, + $fpga, + $yStart, + $yStart+$ySpan-1, + $xStart, + $xStop, + $modExp ) unless defined $modFound; + + + mimosis_register_write( 0x20, 0x40); + + + for( my $yLow = $yStart; + $yLow <= $yStop; + $yLow += $ySpan ) { + + my $yHigh = $yLow + $ySpan - 1; + + printf("Mark pixels: %d - %d, %d - %d\n", + $yLow, $yHigh, $xStart, $xStop); + + mimosis_select_pixel( + ystart => $yLow, + ystop => $yHigh, + ystep => $yStep, + xstart => $xStart, + xstop => $xStop, + xstep => $xStep, + ); + + mimosis_register_write( 0x46, 0); +# usleep(100000); # usleep(1000000); + + mimosis_loop_vph( + $mbsStream, # source + $fpga, # fpga + $singleAccess, # sa + $yLow, # yLow + $yHigh, # yHig + $xStart, # xLow + $xStop, # xHig + $setStart, # vphSta + $setStop, # vphEnd + $setStep, # vphTra + $setCount, # maxCounts + $modFound, # mod + $modExp, # exp + ); + + mimosis_instr_write( 0x3f ); + mimosis_instr_write( 0x04 ); + mimosis_instr_write( 0x3e ); + + mimosis_register_write( 0x46, 0); + } +} + + + + + +sub mimosis_scurves { + + my %params = @_; + + my $yStart = $params{'ystart'}; + my $yStop = $params{'ystop'}; + my $yStep = $params{'ystep'}; + my $ySpan = $params{'yspan'}; + + my $xStart = $params{'xstart'}; + my $xStop = $params{'xstop'}; + my $xStep = $params{'xstep'}; + + my $setStart = $params{'setstart'}; + my $setStop = $params{'setstop'}; + my $setStep = $params{'setstep'}; + my $setCount = $params{'setcount'}; + + my $vcasnRegStr = $params{'vcasnreg'}; + my $vcasnStart = $params{'vcasnstart'}; + my $vcasnStop = $params{'vcasnstop'}; + my $vcasnStep = $params{'vcasnstep'}; + + my $pixpulseAASc = $params{'pixpulseaa'}; + my $pixpulseABSc = $params{'pixpulseab'}; + my $pixpulseDASc = $params{'pixpulseda'}; + my $pixpulseDBSc = $params{'pixpulsedb'}; + + my $modExp = $params{'modexp'}; + my $modFound = $params{'modfound'}; + + $yStart = 0 unless defined $yStart; + $yStop = 503 unless defined $yStop; + $yStep = 1 unless defined $yStep; + $ySpan = 1 unless defined $ySpan; + + $xStart = 0 unless defined $xStart; + $xStop = 1023 unless defined $xStop; + $xStep = 1 unless defined $xStep; + + $setStart = 0 unless defined $setStart; + $setStop = 255 unless defined $setStop; + $setStep = 1 unless defined $setStep; + $setCount= 4000 unless defined $setCount; + + $pixpulseAASc = 25 unless defined $pixpulseAASc; + $pixpulseABSc = 75 unless defined $pixpulseABSc; + $pixpulseDASc = 0 unless defined $pixpulseDASc; + $pixpulseDBSc = 0 unless defined $pixpulseDBSc; + + mimosis_register_write(0x066, $pixpulseAASc&0x00ff ); + mimosis_register_write(0x166,($pixpulseAASc&0xff00)>>8); + mimosis_register_write(0x076, $pixpulseABSc&0x00ff ); + mimosis_register_write(0x176,($pixpulseABSc&0xff00)>>8); + mimosis_register_write(0x067, $pixpulseDASc&0x00ff ); + mimosis_register_write(0x167,($pixpulseDASc&0xff00)>>8); + mimosis_register_write(0x077, $pixpulseDBSc&0x00ff ); + mimosis_register_write(0x177,($pixpulseDBSc&0xff00)>>8); + + mimosis_instr_write( 0x3f ); + mimosis_instr_write( 0x04 ); + mimosis_instr_write( 0x3e ); + + mimosis_register_write( 0x20, 0x40 ); + + die "Invalid DAC given" if not exists $Mimosis::DAC{$vcasnRegStr}; + my $vcasnReg = $Mimosis::DAC{$vcasnRegStr}{'ADDR'}; + my $vcasnVal = mimosis_register_read( $vcasnReg ); + + $vcasnStart = $vcasnVal unless defined $vcasnStart; + $vcasnStop = $vcasnStart unless defined $vcasnStop; + $vcasnStep = 1 unless defined $vcasnStep; + + $modExp = 3 unless defined $modExp; + + Mimosis::mimosis_pulse( + ystart => $yStart, + ystop => $yStart + $yStep, + yspan => 1, + xstart => $xStart, + xstop => $xStop, + modexp => $modExp, + ); + + + $modFound = mimosis_find_mod( + $mbsStream, + $fpga, + $yStart, + $yStart+$ySpan-1, + $xStart, + $xStop, + # $modExp ); + $modExp ) unless defined $modFound; + + print "MODFOUND: $modFound\n"; + + mimosis_instr_write( 0x3f ); + mimosis_instr_write( 0x04 ); + mimosis_instr_write( 0x3e ); + + for ( my $vcasnSet = $vcasnStart; + $vcasnSet <= $vcasnStop; + $vcasnSet += $vcasnStep ) { + + mimosis_register_write( $vcasnReg, $vcasnSet ); + + print "DAC: $vcasnSet\n" if $printall; + + mimosis_scan_rows ( + ystart => $yStart, + ystop => $yStop, + ystep => $yStep, + yspan => $ySpan, + xstart => $xStart, + xstop => $xStop, + xstep => $xStep, + setstart => $setStart, + setstop => $setStop, + setstep => $setStep, + setcount => $setCount, + modexp => $modExp, + modfound => $modFound, + ); + + my $dirName = $vcasnRegStr . "-" . $vcasnSet; + mkdir($dirName); + my $pulsesFile = "scurve-pulses.csv"; + move($pulsesFile, $dirName . "/" . $dirName . ".csv"); + } +} + + + + + +sub mimosis_mask { + + my %params = @_; + + mimosis_register_write( 0x20, 0x42 ); + + mimosis_select_pixel( + xstart => $params{'xstart'}, + xstop => $params{'xstop'}, + xstep => $params{'xstep'}, + ystart => $params{'ystart'}, + ystop => $params{'ystop'}, + ystep => $params{'ystep'}, + ); +} + + + + +sub mimosis_pulse { + + my %params = @_; + + my $pixpulseAASc = $params{'pixpulseaa'}; + my $pixpulseABSc = $params{'pixpulseab'}; + my $pixpulseDASc = $params{'pixpulseda'}; + my $pixpulseDBSc = $params{'pixpulsedb'}; + my $modExp = $params{'modexp'}; + + $modExp = 3 unless defined $modExp; + mimosis_register_write( 0x7d, $modExp ); + + $pixpulseAASc = 25 unless defined $pixpulseAASc; + $pixpulseABSc = 75 unless defined $pixpulseABSc; + $pixpulseDASc = 0 unless defined $pixpulseDASc; + $pixpulseDBSc = 0 unless defined $pixpulseDBSc; + + mimosis_register_write(0x066, $pixpulseAASc&0x00ff ); + mimosis_register_write(0x166,($pixpulseAASc&0xff00)>>8); + mimosis_register_write(0x076, $pixpulseABSc&0x00ff ); + mimosis_register_write(0x176,($pixpulseABSc&0xff00)>>8); + mimosis_register_write(0x067, $pixpulseDASc&0x00ff ); + mimosis_register_write(0x167,($pixpulseDASc&0xff00)>>8); + mimosis_register_write(0x077, $pixpulseDBSc&0x00ff ); + mimosis_register_write(0x177,($pixpulseDBSc&0xff00)>>8); + + mimosis_instr_write( 0x3f ); + mimosis_instr_write( 0x04 ); + mimosis_instr_write( 0x3e ); + + mimosis_register_write( 0x20, 0x40 ); + + mimosis_select_pixel( + xstart => $params{'xstart'}, + xstop => $params{'xstop'}, + xstep => $params{'xstep'}, + ystart => $params{'ystart'}, + ystop => $params{'ystop'}, + ystep => $params{'ystep'}, + ); +} + + + 1; __END__ # Below is stub documentation for your module. You'd better edit it! @@ -53,6 +1085,8 @@ unedited. Blah blah blah. + + =head2 EXPORT None by default. diff --git a/scripts/modules/Mimosis/reg.pl b/scripts/modules/Mimosis/reg.pl deleted file mode 100755 index 235422f..0000000 --- a/scripts/modules/Mimosis/reg.pl +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/perl - -use ExtUtils::testlib; -use Mimosis; - -use HADES::TrbNet; - -use warnings; -use strict; - - -trb_init_ports() or die trb_strerror(); - -my $fpga = 0xa000; -my $reg = 0x20; -my $val = 0x40; -my $sa = 0; - - -# Mimosis::mimosis_register_write($fpga, $reg, $val, $sa); -# my $retval = Mimosis::mimosis_register_read($fpga, $reg, $sa); -# printf("%x\t%x\n",$val, $retval); - -# $val = 0x2; -# Mimosis::mimosis_register_write($fpga, $reg, $val, $sa); -# $retval = Mimosis::mimosis_register_read($fpga, $reg, $sa); -# printf("%x\t%x\n",$val, $retval); - - -{ - my $source = "mbss://localhost:36789"; - my $yLow = 250; - my $yHig = 253; - my $xLow = 0; - my $xHig = 127; - my $exp = 3; - my $mod = Mimosis::mimosis_find_mod($source, $fpga, $yLow, $yHig, $xLow, $xHig, $exp); - print "Mod: $mod\n"; - - my $vphSta = 0; - my $vphEnd = 255; - my $vphTra = 1; - my $maxCounts = 500; - - Mimosis::mimosis_loop_vph($source, $fpga, $sa, $yLow, $yHig, $xLow, $xHig, $vphSta, $vphEnd, $vphTra, $maxCounts, $mod, $exp); -} -- 2.43.0