#%TITLE% can9660.mac
#%NAME%
# Simple macros to control the "digital" DSP Canberra 9660.
#%CATEGORY% Detection, MCA
#%DESCRIPTION%
# Simple macros to control the "digital" DSP Canberra 9660.
#%BR%
#%BR%
# All addresses and ID are explained in the document %LINK% http://www.canberra.com
# Software Design
# Document for 2060/9660 Module %LINK% by Canberra Industries, Inc.
#
# registers really used are:
#%PRE%
# 1 6 7 8 e f 10 11 12 13 14 15 16 17 18 19 1a
# 1b 1c 1d 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2f 30 31 32 33 34 35
# 36 37 38 39 3a 3b 3c 3d 3e 3f 46 54 55 56 57 58
#%PRE%
# so unused ones are:
#%PRE%
# 2 3 4 5 9 a b c d e f 2e 40 41 42 43 44 45 47 to 53
#%PRE%
#
#%BR% %BR%
# The macro name prefix AS refers to Andrea DAROCZYNE SOMOGYI
#%BR% %BR%
# Modifications history:
#%DL%
# %DT%Jan 2002 %DD% HW Creation
# %DT%Feb 2002 %DD% HW better input, saver calculations and more possibilities
# %DT%Feb 2002 %DD% HW more options
# %DT%2002/02/19 %DD% HW add save and restore configuration using files.
# use can9660save_config and can9660restore_config.
# %DT%2003/07 %DD% HW add Stabilizer setup.
# %DT%2003/11 %DD% HW change CAN9660 array structure, make the save and restore
# stuff work. Bugfix of the AS_CAN9660_calc_gain() macro.
# Values are now user friendly, they are not entered as
# integer, but in whatever their unit is.
#%XDL%
#%LOG%
# $Revision: 2.3 $
#%END%
#------------------------------------------------------------------------------
#%UU%
#%MDESC% menu macro to set some parameters in Canberra 9660 DSP
def can9660menu '{
if (!(whatis("CAN9660") & 0x01000000)) {
printf ("Please run can9660setup first!")
exit
}
global MENU_OPTION
MENU_OPTION["holger"] = ""
# check for old and new version CAN9660 array
if (CAN9660["version"] != 2) {
local icb_addr, device
device = CAN9660["dev"]
icb_addr = CAN9660["icb_adr"]
unglobal CAN9660 # delete the old associative array
global CAN9660
CAN9660["version"] = 2 # and put sth so it will work next time.
CAN9660["dev"] = device
CAN9660["icb_adr"] = icb_addr
AS_CAN9660_preset()
}
# AS_CAN9660_read_interesting() # is now done menu by menu
AS_CAN9660_menu_helper()
}'
#-----------------------------------------------------------
#%IU%
#%MDESC% no description, needed as exitmacro value to the menu() function
def AS_CAN9660_menu_helper() '{
menu(sprintf("%60s", "Canberra 9660 setup (Bliss/Holger)"), \
"AS_CAN9660_display()", "", "")
}' # Ends macro AS_CAN9660_menu_helper
#------------------------------------------------------------------------------
#%IU%()
#%MDESC% menu driven macro function called by can9660menu. Don't use this
#macro directly.
def AS_CAN9660_display() '{
if(!CAN9660["read for gain"]) {
printf(" Reading parameters from DSP")
CAN9660["AMP_CGAIN"] = CAN9660["AMP_CGAIN"]["old"] = \
AS_CAN9660_readtableval(CAN9660["AMP_CGAIN"]["addr"])
CAN9660["AMP_FGAIN"] = CAN9660["AMP_FGAIN"]["old"] = \
AS_CAN9660_readtableval(CAN9660["AMP_FGAIN"]["addr"]) * 1.6 / 0x1000
CAN9660["AMP_SFGAIN"] = CAN9660["AMP_SFGAIN"]["old"] = \
AS_CAN9660_readtableval(CAN9660["AMP_SFGAIN"]["addr"]) * 0.03 / 0x1000
CAN9660["COINC"] = CAN9660["COINC"]["old"] = \
AS_CAN9660_readtableval(CAN9660["COINC"]["addr"])
CAN9660["read for gain"] = 1
print
}
CAN9660["AMP_GAIN"] = CAN9660["AMP_GAIN"]["old"] = \
AS_CAN9660_calc_gain(CAN9660["AMP_CGAIN"], CAN9660["AMP_FGAIN"], \
CAN9660["AMP_SFGAIN"])
# calculate current gain
CAN9660["CUR_GAIN"] = CAN9660["AMP_GAIN"]
if(CAN9660["warn"])
menuwarning("New values need writing to the controller!")
#---------------------------------------------------------------
menuprint(-30, "\n", "Current gain:", CAN9660["CUR_GAIN"])
menuoptbutton(0, "\n","Gain Setup Menu")
menuaction ("menu(sprintf(\"%60s\", \"Canberra 9660 gain setup\"), \
\"AS_CAN9660_gain_display()\", \"\", \"AS_CAN9660_menu_helper()\")")
menuoptbutton(0, "\n","Fast Discriminator Setup Menu")
menuaction ("menu(sprintf(\"%60s\", \"Canberra 9660 Fast Discriminator setup\"), \
\"AS_CAN9660_fdisc_display()\", \"\", \"AS_CAN9660_menu_helper()\")")
menuoptbutton(0, "\n","ADC Setup Menu")
menuaction ("menu(sprintf(\"%60s\", \"Canberra 9660 ADC setup\"), \
\"AS_CAN9660_ADC_display()\", \"\", \"AS_CAN9660_menu_helper()\")")
menuoptbutton(0, "\n","Filter Setup Menu")
menuaction ("menu(sprintf(\"%60s\", \"Canberra 9660 filter setup\"), \
\"AS_CAN9660_filter_display()\", \"\", \"AS_CAN9660_menu_helper()\")")
menuoptbutton(0, "\n","Stabilizer Setup Menu")
menuaction ("menu(sprintf(\"%60s\", \"Canberra 9660 Stabilizer setup\"), \
\"AS_CAN9660_Stabilizer_display1()\", \"\", \"AS_CAN9660_menu_helper()\")")
menuoptbutton(0, "\n","Stabilizer Reset")
menuaction ("AS_CAN9660_Stabilizer_reset()")
if(CAN9660["warn"]) {
menuprb(MENU_SEP)
menuoptbutton(0, "\n","Write current values to the DSP", "W")
menuaction ("print \"Writing to the DSP\";AS_CAN9660_write_interesting(); exit")
}
}'
#-----------------------------------------------------------
#%IU%
#%MDESC% no description
def AS_CAN9660_gain_helper1() '{
local gstring, n
local float array tab[3]
if (CAN9660["AMP_GAIN"] != CAN9660["AMP_GAIN"]["old"]) {
tab = AS_CAN9660_find_gain(CAN9660["AMP_GAIN"])
AS_CAN9660_info tab
CAN9660["AMP_CGAIN"] = tab[0]
AS_CAN9660_info CAN9660["AMP_CGAIN"]
CAN9660["AMP_FGAIN"] = tab[1]
AS_CAN9660_info CAN9660["AMP_FGAIN"]
CAN9660["AMP_SFGAIN"] = tab[2]
AS_CAN9660_info sprintf("gain parts is %d %f %f\n", \
CAN9660["AMP_CGAIN"], CAN9660["AMP_FGAIN"], CAN9660["AMP_SFGAIN"])
CAN9660["AMP_GAIN"]["old"] = CAN9660["AMP_GAIN"]
CAN9660["warn"] = 1
}
}' # Ends macro AS_CAN9660_gain_helper1
#-----------------------------------------------------------
#%IU%
#%MDESC% no description
def AS_CAN9660_gain_helper2() '{
if (CAN9660["AMP_FGAIN"] < 0.4) CAN9660["AMP_FGAIN"] = 0.4
if (CAN9660["AMP_FGAIN"] > 1.6) CAN9660["AMP_FGAIN"] = 1.6
if (CAN9660["AMP_SFGAIN"] > 0.03) CAN9660["AMP_SFGAIN"] = 0.03
if (CAN9660["AMP_SFGAIN"] < 0) CAN9660["AMP_SFGAIN"] = 0
CAN9660["AMP_GAIN"] = AS_CAN9660_calc_gain(CAN9660["AMP_CGAIN"], \
CAN9660["AMP_FGAIN"], CAN9660["AMP_SFGAIN"])
}' # Ends macro AS_CAN9660_gain_helper2
#------------------------------------------------------------------------------
#%IU%()
#%MDESC% menu driven macro function called by can9660menu. Don't use this
#macro directly.
def AS_CAN9660_gain_display() '{
local gstring, n, i, tab[]
# CAN9660["AMP_CGAIN"] must contain 0 to 5
# Next if is for keyboard entries on any value
if(!CAN9660["read for gain"]) {
printf(" Reading parameters from DSP")
CAN9660["AMP_CGAIN"] = CAN9660["AMP_CGAIN"]["old"] = \
AS_CAN9660_readtableval(CAN9660["AMP_CGAIN"]["addr"])
CAN9660["AMP_FGAIN"] = CAN9660["AMP_FGAIN"]["old"] = \
AS_CAN9660_readtableval(CAN9660["AMP_FGAIN"]["addr"]) * 1.6 / 0x1000
CAN9660["AMP_SFGAIN"] = CAN9660["AMP_SFGAIN"]["old"] = \
AS_CAN9660_readtableval(CAN9660["AMP_SFGAIN"]["addr"]) * 0.03 / 0x1000
CAN9660["COINC"] = CAN9660["COINC"]["old"] = \
AS_CAN9660_readtableval(CAN9660["COINC"]["addr"])
CAN9660["read for gain"] = 1
print
}
if(CAN9660["warn"])
menuwarning("New values need writing to the controller!")
CAN9660["AMP_GAIN"] = CAN9660["AMP_GAIN"]["old"] = \
AS_CAN9660_calc_gain(CAN9660["AMP_CGAIN"], CAN9660["AMP_FGAIN"], \
CAN9660["AMP_SFGAIN"])
# calculate current gain
CAN9660["CUR_GAIN"] = CAN9660["AMP_GAIN"]
for (i = 0; i < 6; i++) {
helpvar[i] = int(CAN9660["G"][i])
}
menuoptgroupselect1(0,"\n"," Change Amplifier Coarse Gain:", helpvar, \
CAN9660["AMP_CGAIN"],6,"CAN9660[\"AMP_CGAIN\"]",4)
# that are 6 options from 1 to 6. only add actions to those options
for (i=MENU_OPT-5; i<=MENU_OPT; i++) # this is needed as we need to calculate the overall gain.
MENU_ACTION[i]=sprintf("%s CAN9660[\"warn\"] = 1;AS_CAN9660_gain_helper2();", MENU_ACTION[i])
print
menuoptval(0,"\n","Enter Amplifier Fine Gain", \
CAN9660["AMP_FGAIN"])
menuvargetv ("CAN9660[\"AMP_FGAIN\"]")
menuaction("CAN9660[\"warn\"] = 1;AS_CAN9660_gain_helper2()")
menuoptval(0,"\n","Enter Amplifier Super Fine Gain", \
CAN9660["AMP_SFGAIN"])
menuvargetv ("CAN9660[\"AMP_SFGAIN\"]")
menuaction("CAN9660[\"warn\"] = 1;AS_CAN9660_gain_helper2()")
menuprint(72, "\n", " Calculated GAIN value", CAN9660["AMP_GAIN"])
menuoptval(0,"\n","Enter Amplifier Gain Value", \
CAN9660["AMP_GAIN"])
menuvargetv ("CAN9660[\"AMP_GAIN\"]")
menuaction("CAN9660[\"warn\"] = 1;AS_CAN9660_gain_helper1()")
menuoptval(0,"\n","Coincidence Mode: Sets the devices gating mode", \
CAN9660["COINC"]?"Coinc.":"AntiC.")
menuvartogg ("CAN9660[\"COINC\"]")
menuaction("CAN9660[\"warn\"] = 1")
#---------------------------------------------------------------
menuprb(MENU_SEP)
menuoptbutton(0, "\n"," Write current values to the DSP", "W")
menuaction ("print \"Writing to the DSP\";AS_CAN9660_write_interesting(); exit")
}'
#------------------------------------------------------------------------------
#%IU%()
#%MDESC% menu driven macro function called by can9660menu. Don't use this
#macro directly.
def AS_CAN9660_fdisc_display() '{
if(CAN9660["warn"])
menuwarning("New values need writing to the controller!")
if(!CAN9660["read for fdisc"]) {
printf(" Reading parameters from DSP")
CAN9660["MISC_FDM"] = CAN9660["MISC_FDM"]["old"] = \
AS_CAN9660_readtableval(CAN9660["MISC_FDM"]["addr"])
CAN9660["MISC_FD"] = CAN9660["MISC_FD"]["old"] = \
AS_CAN9660_readtableval(CAN9660["MISC_FD"]["addr"]) / 10
CAN9660["MISC_INPP"] = CAN9660["MISC_INPP"]["old"] = \
AS_CAN9660_readtableval(CAN9660["MISC_INPP"]["addr"])
CAN9660["MISC_INHP"] = CAN9660["MISC_INHP"]["old"] = \
AS_CAN9660_readtableval(CAN9660["MISC_INHP"]["addr"])
CAN9660["read for fdisc"] = 1
print
}
menuoptval(3,"\n","Fast Discriminator Mode", \
CAN9660["MISC_FDM"]?"Manual":"Auto")
menuvartogg ("CAN9660[\"MISC_FDM\"]")
menuaction("CAN9660[\"warn\"] = 1")
if (CAN9660["MISC_FDM"] == 1) {
menuoptval(3,"%\n","Fast Discriminator Settings", \
CAN9660["MISC_FD"])
menuvargetv ("CAN9660[\"MISC_FD\"]")
menuaction("if (CAN9660[\"MISC_FD\"] < 0) CAN9660[\"MISC_FD\"] = 0;\
if (CAN9660[\"MISC_FD\"] > 100) CAN9660[\"MISC_FD\"] = 100;\
CAN9660[\"warn\"] = 1")
} else {
menuoptskip (MENU_OPT)
print
}
menuoptval(3,"\n","Input signal polarity", \
CAN9660["MISC_INPP"]?"Negative":"Positive")
menuvartogg ("CAN9660[\"MISC_INPP\"]")
menuaction("CAN9660[\"warn\"] = 1")
menuoptval(3,"\n","Inhibit signal polarity", \
CAN9660["MISC_INHP"]?"Negative":"Positive")
menuvartogg ("CAN9660[\"MISC_INHP\"]")
menuaction("CAN9660[\"warn\"] = 1")
#---------------------------------------------------------------
menuprb(MENU_SEP)
menuoptbutton(0, "\n"," Write current values to the DSP", "W")
menuaction ("print \"Writing to the DSP\";AS_CAN9660_write_interesting(); exit")
}'
#------------------------------------------------------------------------------
#%IU%()
#%MDESC% menu driven macro function called by can9660menu. Don't use this
#macro directly.
def AS_CAN9660_ADC_display() '{
if(CAN9660["warn"])
menuwarning("New values need writing to the controller!")
if(!CAN9660["read for ADC"]) {
printf(" Reading parameters from DSP")
CAN9660["ADC_LLD"] = AS_CAN9660_readtableval(CAN9660["ADC_LLD"]["addr"])
# make this a percentage
CAN9660["ADC_LLD"] = CAN9660["ADC_LLD"]["old"] = CAN9660["ADC_LLD"] * 100 / 0x7FFF
CAN9660["ADC_CGAIN"] = CAN9660["ADC_CGAIN"]["old"] = \
AS_CAN9660_readtableval(CAN9660["ADC_CGAIN"]["addr"])
CAN9660["ADC_OFFSET"] = CAN9660["ADC_OFFSET"]["old"] = \
AS_CAN9660_readtableval(CAN9660["ADC_OFFSET"]["addr"]) * 128
CAN9660["ADC_ZERO"] = CAN9660["ADC_ZERO"]["old"] = \
(AS_CAN9660_readtableval(CAN9660["ADC_ZERO"]["addr"]) - 3125) / 1000
CAN9660["read for ADC"] = 1
print
}
local helpvar
helpvar[0] = 256; helpvar[1] = 512; helpvar[2] = 1024; helpvar[3] = 2048
helpvar[4] = 4096; helpvar[5] = 8192; helpvar[6] = 16384
menuoptgroupselect1(0,""," Choose ADC Conversion Gain, current:", helpvar, \
CAN9660["ADC_CGAIN"],7,"CAN9660[\"ADC_CGAIN\"]",4)
# that are 3 options
for (i=MENU_OPT-6; i<=MENU_OPT; i++) # this is needed as we need to calculate the overall gain.
MENU_ACTION[i]=sprintf("%s CAN9660[\"warn\"] = 1;", MENU_ACTION[i])
print "\n\n"
print " The ADC Digital Offset in 128 channel increments."
menuoptval(0,"\n","Choose Digital Offset value", \
CAN9660["ADC_OFFSET"])
menuvargetv ("CAN9660[\"ADC_OFFSET\"]")
menuaction("if (CAN9660[\"ADC_OFFSET\"] < 0) CAN9660[\"ADC_OFFSET\"] = 0;\
if (CAN9660[\"ADC_OFFSET\"] > 16126) CAN9660[\"ADC_OFFSET\"] = 16126;\
CAN9660[\"warn\"] = 1")
print
print " The ADC Low Level Discriminator can be chosen as a"
local groupsize
groupsize = mca_par("group_size")
menuprint(0,"%\n", sprintf(" percentage of the of the device\'s full scale\
(%d).", groupsize), CAN9660["ADC_LLD"])
menuoptval(3,"%\n","Choose Low Level Discriminator Value", \
CAN9660["ADC_LLD"])
menuvargetv ("CAN9660[\"ADC_LLD\"]")
menuaction("if (CAN9660[\"ADC_LLD\"] < 0) CAN9660[\"ADC_LLD\"] = 0;\
if (CAN9660[\"ADC_LLD\"] > 100) CAN9660[\"ADC_LLD\"] = 100;\
CAN9660[\"warn\"] = 1")
print
print " The ADC Zero DAC value can be chosen between -3.125% to +3.125%."
menuoptval(3,"\n","Choose ADC Zero DAC Value", CAN9660["ADC_ZERO"])
menuvargetv ("CAN9660[\"ADC_ZERO\"]")
menuaction("if (CAN9660[\"ADC_ZERO\"] < -3.125) CAN9660[\"ADC_ZERO\"] = -3.125;\
if (CAN9660[\"ADC_ZERO\"] > 3.125) CAN9660[\"ADC_ZERO\"] = 3.125;\
CAN9660[\"warn\"] = 1")
#---------------------------------------------------------------
menuprb(MENU_SEP)
menuoptbutton(0, "\n"," Write current values to the DSP", "W")
menuaction ("print \"Writing to the DSP\";AS_CAN9660_write_interesting(); exit")
}'
#------------------------------------------------------------------------------
#%IU%()
#%MDESC% menu driven macro function called by can9660menu. Don't use this
#macro directly.
def AS_CAN9660_filter_display() '{
# CAN9660["FILTER_FT"] is the console entry value, multiply with 10 at write
# time.
if(CAN9660["warn"])
menuwarning("New values need writing to the controller!")
if(!CAN9660["read for filter"]) {
printf(" Reading parameters from DSP")
CAN9660["FILTER_FT"] = \
AS_CAN9660_readtableval(CAN9660["FILTER_FT"]["addr"]) / 10
CAN9660["FILTER_FT"]["old"] = CAN9660["FILTER_FT"]
# Rise time related stuff
CAN9660["FILTER_RT"] = \
AS_CAN9660_readtableval(CAN9660["FILTER_RT"]["addr"]) / 10
CAN9660["FILTER_RT"]["old"] = CAN9660["FILTER_RT"]
CAN9660["FILTER_PZ"] = \
AS_CAN9660_readtableval(CAN9660["FILTER_PZ"]["addr"])
if (CAN9660["FILTER_PZ"] != 0) {
CAN9660["FILTER_PZ"] = CAN9660["FILTER_PZ"] * 40 / 0xfff + 1.7
}
CAN9660["FILTER_PZ"]["old"] = CAN9660["FILTER_PZ"]
CAN9660["FILTER_PZM"] = \
AS_CAN9660_readtableval(CAN9660["FILTER_PZM"]["addr"])
CAN9660["FILTER_PZM"]["old"] = CAN9660["FILTER_PZM"]
CAN9660["read for filter"] = 1
print
}
print " The Flat Top Time can be chosen between 0 to 3 usec."
menuoptval(0,"usec\n","Choose Flat Top Time Value", \
CAN9660["FILTER_FT"])
menuvargetv ("CAN9660[\"FILTER_FT\"]")
menuaction("if (CAN9660[\"FILTER_FT\"] > 3) CAN9660[\"FILTER_FT\"] = 3; \
if (CAN9660[\"FILTER_FT\"] < 0) CAN9660[\"FILTER_FT\"] = 0; \
CAN9660[\"warn\"] = 1")
print
print " The Rise Time can be chosen between 0.4 to 28 usec."
menuoptval(0,"usec\n","Choose Rise Time Value", \
CAN9660["FILTER_RT"])
menuvargetv ("CAN9660[\"FILTER_RT\"]")
menuaction("if (CAN9660[\"FILTER_RT\"] > 28) CAN9660[\"FILTER_RT\"] = 28; \
if (CAN9660[\"FILTER_RT\"] < 0.4) CAN9660[\"FILTER_RT\"] = 0.4; \
CAN9660[\"warn\"] = 1")
print
local helpvar
helpvar[0] = "RC Auto"; helpvar[1] = "RC Manual"; helpvar[2] = "TRP"
menuoptgroupselect1(0,""," Preamp type:", helpvar, \
CAN9660["FILTER_PZM"],3,"CAN9660[\"FILTER_PZM\"]",4)
# that are 3 options
for (i=MENU_OPT-2; i<=MENU_OPT; i++) # this is needed as we need to calculate the overall gain.
MENU_ACTION[i]=sprintf("%s CAN9660[\"warn\"] = 1;", MENU_ACTION[i])
print "\n\n"
if (CAN9660["FILTER_PZM"] == 1) {
print " The Pole Zero DAC value can be chosen between 1.7 to 40 usec. 0 is off."
menuoptval(0,"usec\n","Choose Pole Zero DAC Value", \
CAN9660["FILTER_PZ"]?CAN9660["FILTER_PZ"]:"off")
menuvargetv ("CAN9660[\"FILTER_PZ\"]")
menuaction("if (CAN9660[\"FILTER_PZ\"] != 0) { if (CAN9660[\"FILTER_PZ\"] > 40) CAN9660[\"FILTER_PZ\"] = 40; \
if (CAN9660[\"FILTER_PZ\"] < 1.7) CAN9660[\"FILTER_PZ\"] = 1.7}; \
CAN9660[\"warn\"] = 1")
} else print "\n\n"
#---------------------------------------------------------------
menuprb(MENU_SEP)
menuoptbutton(0, "\n"," Write current values to the DSP", "W")
menuaction("print \"Writing to the DSP\";AS_CAN9660_write_interesting();exit")
}'
#------------------------------------------------------------------------------
#%IU%()
#%MDESC% menu driven macro function called by can9660menu. Don't use this
#macro directly.
def AS_CAN9660_Stabilizer_display1() '{
if(CAN9660["warn"])
menuwarning("New values need writing to the controller!")
if(!CAN9660["read for stabilizer1"]) {
printf(" Reading parameters from DSP")
CAN9660["STABLZ_GCOR"] = AS_CAN9660["STABLZ_GCOR"]["old"] = \
AS_CAN9660_readtableval(CAN9660["STABLZ_GCOR"]["addr"])
CAN9660["STABLZ_ZCOR"] = AS_CAN9660["STABLZ_ZCOR"]["old"] = \
AS_CAN9660_readtableval(CAN9660["STABLZ_ZCOR"]["addr"])
CAN9660["STABLZ_GMOD"] = AS_CAN9660["STABLZ_GMOD"]["old"] = \
AS_CAN9660_readtableval(CAN9660["STABLZ_GMOD"]["addr"])
CAN9660["STABLZ_GOVR"] = CAN9660["STABLZ_GMOD"] & 0x80
CAN9660["STABLZ_GOVF"] = CAN9660["STABLZ_GMOD"] & 0x40
CAN9660["STABLZ_GMOD"] = CAN9660["STABLZ_GMOD"] & 0x03
CAN9660["STABLZ_ZMOD"] = AS_CAN9660["STABLZ_ZMOD"]["old"] = \
AS_CAN9660_readtableval(CAN9660["STABLZ_ZMOD"]["addr"])
CAN9660["STABLZ_ZOVR"] = CAN9660["STABLZ_ZMOD"] & 0x80
CAN9660["STABLZ_ZOVF"] = CAN9660["STABLZ_ZMOD"] & 0x40
CAN9660["STABLZ_ZMOD"] = CAN9660["STABLZ_ZMOD"] & 0x03
CAN9660["STABLZ_GDIV"] = AS_CAN9660["STABLZ_GDIV"]["old"] = \
AS_CAN9660_readtableval(CAN9660["STABLZ_GDIV"]["addr"])
CAN9660["STABLZ_ZDIV"] = AS_CAN9660["STABLZ_ZDIV"]["old"] = \
AS_CAN9660_readtableval(CAN9660["STABLZ_ZDIV"]["addr"])
CAN9660["STABLZ_GSPC"] = AS_CAN9660["STABLZ_GSPC"]["old"] = \
AS_CAN9660_readtableval(CAN9660["STABLZ_GSPC"]["addr"])
CAN9660["STABLZ_ZSPC"] = AS_CAN9660["STABLZ_ZSPC"]["old"] = \
AS_CAN9660_readtableval(CAN9660["STABLZ_ZSPC"]["addr"])
CAN9660["read for stabilizer1"] = 1
print
}
menuoptval(0,"\n","Stabilizer Gain Correction Range: Ge (+/- 1%), Nal (+/- 10%)", \
CAN9660["STABLZ_GCOR"]?"Nal":"Ge")
menuvartogg ("CAN9660[\"STABLZ_GCOR\"]")
menuaction("CAN9660[\"warn\"] = 1")
menuoptval(0,"\n","Stabilizer Zero Correction Range: Ge (+/- 1%), Nal (+/- 10%)", \
CAN9660["STABLZ_ZCOR"]?"Nal":"Ge")
menuvartogg ("CAN9660[\"STABLZ_ZCOR\"]")
menuaction("CAN9660[\"warn\"] = 1")
print
local helpvar
helpvar[0] = " OFF"; helpvar[1] = "ON"; helpvar[2] = "HOLD"
menuoptgroupselect1(0,""," Gain Correction Mode:", helpvar, \
CAN9660["STABLZ_GMOD"],3,"CAN9660[\"STABLZ_GMOD\"]",4)
# that are 3 options
for (i=MENU_OPT-2; i<=MENU_OPT; i++) # this is needed as we need to calculate the overall gain.
MENU_ACTION[i]=sprintf("%s CAN9660[\"warn\"] = 1;", MENU_ACTION[i])
print "\n"
local helpvar
helpvar[0] = " OFF"; helpvar[1] = "ON"; helpvar[2] = "HOLD"
menuoptgroupselect1(0,""," Zero Correction Mode:", helpvar, \
CAN9660["STABLZ_ZMOD"],3,"CAN9660[\"STABLZ_ZMOD\"]",4)
# that are 3 options
for (i=MENU_OPT-2; i<=MENU_OPT; i++) # this is needed as we need to calculate the overall gain.
MENU_ACTION[i]=sprintf("%s CAN9660[\"warn\"] = 1;", MENU_ACTION[i])
print "\n\n"
if (CAN9660["STABLZ_GOVR"]) {
menuwarning("Stabilizers gain range is in OverRange condition!")
menuwarning("Gain mode was switched to HOLD!")
}
if (CAN9660["STABLZ_ZOVR"]) {
menuwarning("Stabilizers zero correction range is in OverRange condition!")
menuwarning("Zero correction mode was switched to HOLD!")
}
if (CAN9660["STABLZ_GOVF"]) {
menuwarning("Stabilizers gain registers are in OverFlow condition,")
menuwarning(" due to excessibley high input rate or window selection!")
}
if (CAN9660["STABLZ_ZOVF"]) {
menuwarning("Stabilizers zero correction registers are in OverFlow condition,")
menuwarning(" due to excessibley high input rate or window selection!")
}
printf(" %s\n","Gain and Zero Correction Divider: expressed as 2^N, ")
printf(" %s\n","where N = 0 through 9, representing a divider factor of 1 through 512")
menuoptval(9,"\n","Choose for Gain Correction", CAN9660["STABLZ_GDIV"])
menuvargetv ("CAN9660[\"STABLZ_GDIV\"]")
menuaction("CAN9660[\"warn\"] = 1")
menuoptval(0,"\n","Choose for Zero correction", CAN9660["STABLZ_ZDIV"])
menuvargetv ("CAN9660[\"STABLZ_ZDIV\"]")
menuaction("CAN9660[\"warn\"] = 1")
print
printf(" %s\n","Gain and Zero Spacing expressed as 2 through 512 channels")
menuoptval(0,"\n","Choose for Gain Spacing", CAN9660["STABLZ_GSPC"])
menuvargetv ("CAN9660[\"STABLZ_GSPC\"]")
menuaction("CAN9660[\"warn\"] = 1")
menuoptval(0,"\n","Choose for Zero Spacing", CAN9660["STABLZ_ZSPC"])
menuvargetv ("CAN9660[\"STABLZ_ZSPC\"]")
menuaction("CAN9660[\"warn\"] = 1")
#---------------------------------------------------------------
menuprb(MENU_SEP)
menuoptbutton(70, "\n","Continue to the next page!", "C")
menuaction ("menu(sprintf(\"%60s\", \"Canberra 9660 Stabilizer setup\"), \
\"AS_CAN9660_Stabilizer_display2()\", \"\", \"AS_CAN9660_menu_helper()\")")
if(CAN9660["warn"]) {
menuprb(MENU_SEP)
menuoptbutton(70, "\n","Write current values to the DSP", "W")
menuaction ("print \"Writing to the DSP\";AS_CAN9660_write_interesting(); exit")
}
}'
#------------------------------------------------------------------------------
#%IU%()
#%MDESC% menu driven macro function called by can9660menu. Don't use this
#macro directly.
def AS_CAN9660_Stabilizer_display2() '{
if(CAN9660["warn"])
menuwarning("New values need writing to the controller!")
if(!CAN9660["read for stabilizer2"]) {
printf(" Reading parameters from DSP")
CAN9660["STABLZ_GWIN"] = AS_CAN9660["STABLZ_GWIN"]["old"] = \
AS_CAN9660_readtableval(CAN9660["STABLZ_GWIN"]["addr"])
CAN9660["STABLZ_ZWIN"] = AS_CAN9660["STABLZ_ZWIN"]["old"] = \
AS_CAN9660_readtableval(CAN9660["STABLZ_ZWIN"]["addr"])
CAN9660["STABLZ_GCENT"] = AS_CAN9660["STABLZ_GCENT"]["old"] = \
AS_CAN9660_readtableval(CAN9660["STABLZ_GCENT"]["addr"])
CAN9660["STABLZ_ZCENT"] = AS_CAN9660["STABLZ_ZCENT"]["old"] = \
AS_CAN9660_readtableval(CAN9660["STABLZ_ZCENT"]["addr"])
CAN9660["STABLZ_GRAT"] = AS_CAN9660["STABLZ_GRAT"]["old"] = \
AS_CAN9660_readtableval(CAN9660["STABLZ_GRAT"]["addr"])
CAN9660["STABLZ_ZRAT"] = AS_CAN9660["STABLZ_ZRAT"]["old"] = \
AS_CAN9660_readtableval(CAN9660["STABLZ_ZRAT"]["addr"])
CAN9660["STABLZ_GAIN"] = AS_CAN9660["STABLZ_GAIN"]["old"] = \
AS_CAN9660_readtableval(CAN9660["STABLZ_GAIN"]["addr"])
CAN9660["STABLZ_ZERO"] = AS_CAN9660["STABLZ_ZERO"]["old"] = \
AS_CAN9660_readtableval(CAN9660["STABLZ_ZERO"]["addr"])
CAN9660["read for stabilizer2"] = 1
print
}
printf(" %s\n","Gain and Zero Window expressed as 1 through 128 channels")
menuoptval(0,"\n","Choose Gain Window", CAN9660["STABLZ_GWIN"])
menuvargetv ("CAN9660[\"STABLZ_GWIN\"]")
menuaction("CAN9660[\"warn\"] = 1")
menuoptval(0,"\n","Choose Zero Window", CAN9660["STABLZ_ZWIN"])
menuvargetv ("CAN9660[\"STABLZ_ZWIN\"]")
menuaction("CAN9660[\"warn\"] = 1")
printf(" %s\n","Gain and Zero Centroid, ranging from 10 to 16376")
menuoptval(0,"\n","Choose Gain Centroid", CAN9660["STABLZ_GCENT"])
menuvargetv ("CAN9660[\"STABLZ_GCENT\"]")
menuaction("CAN9660[\"warn\"] = 1")
menuoptval(0,"\n","Choose Zero Centroid", CAN9660["STABLZ_ZCENT"])
menuaction("CAN9660[\"warn\"] = 1")
printf(" %s\n","Gain and Zero Ratio Value. Ratio between upper and lower window counts,")
printf(" %s\n","that stabilizer will attmept to maintain. Value will range from 1 to 10000,")
printf(" %s\n","representing a ratio value of 0.01 to 100.00. Default will be at 100 for")
printf(" %s\n","1.00. The ratio is caluculated from the upper and lower windows as follows:")
printf(" %s\n"," ratio = upper / lower * 100")
menuoptval(0,"\n","Choose Gain Ratio Value", CAN9660["STABLZ_GRAT"])
menuvargetv ("CAN9660[\"STABLZ_GRAT\"]")
menuaction("CAN9660[\"warn\"] = 1")
menuoptval(0,"\n","Choose Zero Ratio Value", CAN9660["STABLZ_ZRAT"])
menuvargetv ("CAN9660[\"STABLZ_ZRAT\"]")
menuaction("CAN9660[\"warn\"] = 1")
printf(" %s\n","Actual Gain and Zero correction values")
menuoptval(0,"\n","Choose Gain Correction Value (0 to 1FFFh)", CAN9660["STABLZ_GAIN"])
menuvargetv ("CAN9660[\"STABLZ_GAIN\"]")
menuaction("CAN9660[\"warn\"] = 1")
menuoptval(0,"\n","Choose Zero Correction Value (0 to FFFh", CAN9660["STABLZ_ZERO"])
menuvargetv ("CAN9660[\"STABLZ_ZERO\"]")
menuaction("CAN9660[\"warn\"] = 1")
#---------------------------------------------------------------
if(CAN9660["warn"]) {
menuprb(MENU_SEP)
menuoptbutton(70, "\n","Write current values to the DSP", "W")
menuaction ("print \"Writing to the DSP\";AS_CAN9660_write_interesting(); exit")
}
}'
#------------------------------------------------------------------------------
#%IU%()
#%MDESC% menu driven macro function called by can9660menu. Don't use this
#macro directly.
def AS_CAN9660_Stabilizer_reset() '{
AS_CAN9660_writetableval(0x23, 1) # write 1 into, write only register
# AS_CAN9660_read_interesting()
}'
#-----------------------------------------------------------
#%IU%(gain)
#%MDESC% tries to find the closest settings for DSP to have the desired
# gain. This macro function returns a string with the three values
# cgain, fgain and sfgain. Please see description of macro
# AS_CAN9660_calc_gain() for detailed explaination on how to calculate
#the gain.
def AS_CAN9660_find_gain(gain) '{
local i, cgain, fgain, sfgain
local float array tab[3]
for (i = 0; i <= 5; i ++) {
if (gain < CAN9660["G"][i] * 1.6) {
tab[0] = i
AS_CAN9660_info sprintf("setting i %d, %d", i, CAN9660["G"][tab[0]])
break
}
}
AS_CAN9660_info sprintf("setting tab[0] to: %d\n", tab[0])
tab[1] = gain / CAN9660["G"][tab[0]]
AS_CAN9660_info sprintf("fgain %f", tab[1])
if(tab[1] < 0.4 ) tab[1] = 0.4
tab[1] = int(tab[1] * 0x1000 / 1.6) # calculate the value written to
# the controller to use its possible precision, otherwise
# the super fine gain will always be 0
AS_CAN9660_info sprintf("fgain 0x%04x", tab[1])
tab[2] = gain - CAN9660["G"][tab[0]] * (tab[1] * 1.6 / 0x1000)
# now we have the difference between calculated and desired value.
tab[2] = tab[2] / CAN9660["G"][tab[0]] # now the factor
AS_CAN9660_info sprintf("sfgain %f", tab[2])
if (tab[2] < 0) tab[2] = 0; if (tab[2] > 0.03) tab[2] = 0.03
tab[2] = int(tab[2] * 0x1000 / 0.03) # calculate the value written to
# the controller to use its possible precision
AS_CAN9660_info sprintf("sfgain 0x%04x", tab[2])
tab[1] = tab[1] * 1.6 / 0x1000 # and return trip
tab[2] = tab[2] * 0.03 / 0x1000 # and return trip
AS_CAN9660_info AS_CAN9660_calc_gain(tab[0], tab[1], tab[2])
AS_CAN9660_info sprintf("returning array: %d %f %f", tab[0], tab[1], tab[2])
return tab[]
}' # Ends macro AS_find_gain
#-----------------------------------------------------------
#%IU%(cgain, fgain, sfgain)
#%MDESC% calculates the real gain out of coarse, fine and super fine
# gain. This macro function returns the calculated gain.
#%BR%
# %BR%
# Formula: Gain = Coarse Gain * (Fine Gain + Super Fine Gain)
#%BR%
#Coarse Gain can be: 5, 15, 40, 120, 330, 960
#%BR%
#Fine gain is 0x100 to 0xfff representing *0.4 to *1.6
#%BR%
#Super fine gain is 0x000 to 0xfff representing 0 to 0.03
def AS_CAN9660_calc_gain(cgain, fgain, sfgain) '{
local gain
gain = CAN9660["G"][cgain] * (fgain + sfgain)
AS_CAN9660_info "AS_CAN9660_calc_gain", CAN9660["G"][cgain], fgain, sfgain, (fgain + sfgain), gain
return gain
}' # Ends macro AS_CAN9660_calc_gain
def AS_CAN9660_int_calc_gain(cgain, fgain, sfgain) '{
local gain
p fgain
fgain = fgain * 1.6 / 0x1000
p fgain
p sfgain
sfgain = sfgain * 0.03 / 0x1000
p sfgain
gain = CAN9660["G"][cgain] * (fgain + sfgain)
return gain
}' # Ends macro AS_CAN9660_calc_gain
#-----------------------------------------------------------
#%UU% <mca device name> <icb address>
#%MDESC% Sets up a canberra 9660 DSP on ICB address <icb address>. The MCA
#device name is taken as unit 0 from SPEC.
def can9660setup '{
local i, tmp
if (!(whatis("CAN9660") & 0x01000000)) {
printf ("\nFirst time running $0 !\n")
global CAN9660
if (CAN9660["config_dir"] == "")
CAN9660["config_dir"] = BLISSADM"/local/spec/userconf/dsp"
CAN9660["version"] = 2
AS_CAN9660_preset()
}
# check for old and new version CAN9660 array
if (CAN9660["version"] != 2) {
unglobal CAN9660 # delete the old associative array
global CAN9660
CAN9660["version"] = 2 # and put sth so it will work next time.
AS_CAN9660_preset()
}
if ($# >= 1) {
CAN9660["dev"] = mca_spar($1, "device_id")
if ( tmp == "?" ) {
eprint "Sorry, no MCA on number", $1, "available!"
delete CAN9660["dev"]
exit
}
} else {
for (i=0; i < MCAS; i ++) {
tmp = mca_spar(i, "device_id")
if (tmp != "?")
if (yesno(sprintf("Do you want to use MCA %s", tmp),1)) {
CAN9660["dev"] = tmp
break
}
}
if ( i == MCAS || CAN9660["dev"] == 0 ) {
eprint "Sorry, no MCA available or none chosen!"
delete CAN9660["dev"]
exit
}
}
print "\n\nUsing MCA device", CAN9660["dev"], "to talk to DSP9660"
if ($# >= 2) {
CAN9660["icb_adr"] = $2
} else {
CAN9660["icb_adr"] = getval("ICB address of DSP module",CAN9660["icb_adr"])
}
CAN9660["Verbose"] = 1
AS_CAN9660_verbose # force definition of info function :-)
delete CAN9660["read for ADC"]
delete CAN9660["read for fdisc"]
delete CAN9660["read for gain"]
delete CAN9660["read for stabilizer1"]
delete CAN9660["read for stabilizer2"]
delete CAN9660["read for filter"]
}'
#-----------------------------------------------------------
#%IU%()
#%MDESC% Don't use this macro directly. Presets the data structure used
#by the macros for the canberra 9660 DSP
def AS_CAN9660_preset() '{
# no access to the device here, as device and icb are not defined yet.
# icb address might be changed in setup.
if (!(whatis("CAN9660") & 0x04000000)) {
printf ("Please run can9660setup first")
exit
}
CAN9660["Verbose"] = 1
CAN9660["warn"] = 0
# CAN9660["dev"] = mca_par("device_id")
CAN9660["icb_adr"] = 2 # probably on ID18F
CAN9660["G"][0] = 5
CAN9660["G"][1] = 15
CAN9660["G"][2] = 40
CAN9660["G"][3] = 120
CAN9660["G"][4] = 330
CAN9660["G"][5] = 960
# put the addresses here
CAN9660["AMP_CGAIN"]["addr"] = 1
CAN9660["AMP_FGAIN"]["addr"] = 0x2a
CAN9660["AMP_SFGAIN"]["addr"] = 0x2b
CAN9660["COINC"]["addr"] = 0x11
CAN9660["MISC_FDM"]["addr"] = 0x13
CAN9660["MISC_FD"]["addr"] = 0x34
CAN9660["MISC_INPP"]["addr"] = 0x0e
CAN9660["MISC_INHP"]["addr"] = 0x0f
CAN9660["FILTER_FT"]["addr"] = 0x36
CAN9660["FILTER_RT"]["addr"] = 0x35
CAN9660["FILTER_PZ"]["addr"] = 0x07
CAN9660["FILTER_PZM"]["addr"] = 0x08
CAN9660["ADC_LLD"]["addr"] = 0x30
CAN9660["ADC_CGAIN"]["addr"] = 0x31
CAN9660["ADC_OFFSET"]["addr"] = 0x33
CAN9660["ADC_ZERO"]["addr"] = 0x2c
CAN9660["STABLZ_GCOR"]["addr"] = 0x22
CAN9660["STABLZ_ZCOR"]["addr"] = 0x2d
CAN9660["STABLZ_GMOD"]["addr"] = 0x20
CAN9660["STABLZ_ZMOD"]["addr"] = 0x21
CAN9660["STABLZ_GDIV"]["addr"] = 0x37
CAN9660["STABLZ_ZDIV"]["addr"] = 0x38
CAN9660["STABLZ_GSPC"]["addr"] = 0x1c
CAN9660["STABLZ_ZSPC"]["addr"] = 0x1d
CAN9660["STABLZ_GWIN"]["addr"] = 0x1a
CAN9660["STABLZ_ZWIN"]["addr"] = 0x1b
CAN9660["STABLZ_GCENT"]["addr"] = 0x18
CAN9660["STABLZ_ZCENT"]["addr"] = 0x19
CAN9660["STABLZ_GRAT"]["addr"] = 0x28
CAN9660["STABLZ_ZRAT"]["addr"] = 0x29
CAN9660["STABLZ_GAIN"]["addr"] = 0x3e
CAN9660["STABLZ_ZERO"]["addr"] = 0x3f
# put the old values found by AS here in the field "init"
CAN9660["ADC_CGAIN"]["init"] = 5
CAN9660["ADC_LLD"]["init"] = 99
CAN9660["ADC_OFFSET"]["init"] = 0
CAN9660["ADC_ZERO"]["init"] = 3125
CAN9660["AMP_CGAIN"]["init"] = 1
CAN9660["AMP_FGAIN"]["init"] = 2583
CAN9660["AMP_SFGAIN"]["init"] = 3250
CAN9660["COINC"]["init"] = 0
CAN9660["FILTER_FT"]["init"] = 8
CAN9660["FILTER_PZ"]["init"] = 0
CAN9660["FILTER_PZM"]["init"] = 0
CAN9660["FILTER_RT"]["init"] = 56
CAN9660["MISC_FD"]["init"] = 10
CAN9660["MISC_FDM"]["init"] = 0
CAN9660["MISC_INHP"]["init"] = 0
CAN9660["MISC_INPP"]["init"] = 0
CAN9660["STABLZ_GAIN"]["init"] = 4096
CAN9660["STABLZ_GCENT"]["init"] = 8323
CAN9660["STABLZ_GCOR"]["init"] = 0
CAN9660["STABLZ_GDIV"]["init"] = 0
CAN9660["STABLZ_GMOD"]["init"] = 0
CAN9660["STABLZ_GRAT"]["init"] = 100
CAN9660["STABLZ_GSPC"]["init"] = 64
CAN9660["STABLZ_GWIN"]["init"] = 8
CAN9660["STABLZ_ZCENT"]["init"] = 512
CAN9660["STABLZ_ZCOR"]["init"] = 0
CAN9660["STABLZ_ZDIV"]["init"] = 0
CAN9660["STABLZ_ZERO"]["init"] = 0
CAN9660["STABLZ_ZMOD"]["init"] = 0
CAN9660["STABLZ_ZRAT"]["init"] = 100
CAN9660["STABLZ_ZSPC"]["init"] = 64
CAN9660["STABLZ_ZWIN"]["init"] = 8
}'
#%IU%()
#%MDESC% Writes all the interesting values to the controller. Don't use
#this macro directly. Presets the data structure used by the macros for
#the canberra 9660 DSP
def AS_CAN9660_write_interesting() '{
if (!(whatis("CAN9660") & 0x04000000)) {
printf ("Please run can9660setup first")
exit
}
printf("Writing parameters back to DSP ")
# Gain related stuff
if (CAN9660["AMP_CGAIN"]["old"] != CAN9660["AMP_CGAIN"])
AS_CAN9660_writetableval(CAN9660["AMP_CGAIN"]["addr"], CAN9660["AMP_CGAIN"])
if (CAN9660["AMP_FGAIN"]["old"] != CAN9660["AMP_FGAIN"])
AS_CAN9660_writetableval(CAN9660["AMP_FGAIN"]["addr"], CAN9660["AMP_FGAIN"] * 0x1000 / 1.6)
if (CAN9660["AMP_SFGAIN"]["old"] != CAN9660["AMP_SFGAIN"])
AS_CAN9660_writetableval(CAN9660["AMP_SFGAIN"]["addr"], CAN9660["AMP_SFGAIN"] * 0x1000 / 0.03)
if (CAN9660["COINC"]["old"] != CAN9660["COINC"])
AS_CAN9660_writetableval(CAN9660["COINC"]["addr"], CAN9660["COINC"])
# fast discriminator stuff
if (CAN9660["MISC_FDM"]["old"] != CAN9660["MISC_FDM"])
AS_CAN9660_writetableval(CAN9660["MISC_FDM"]["addr"], CAN9660["MISC_FDM"])
if (CAN9660["MISC_FD"]["old"] != CAN9660["MISC_FD"])
AS_CAN9660_writetableval(CAN9660["MISC_FD"]["addr"], CAN9660["MISC_FD"])
if (CAN9660["MISC_INPP"]["old"] != CAN9660["MISC_INPP"])
AS_CAN9660_writetableval(CAN9660["MISC_INPP"]["addr"], CAN9660["MISC_INPP"])
if (CAN9660["MISC_INHP"]["old"] != CAN9660["MISC_INHP"])
AS_CAN9660_writetableval(CAN9660["MISC_INHP"]["addr"], CAN9660["MISC_INHP"])
# Filter related stuff
if (CAN9660["FILTER_FT"]["old"] != CAN9660["FILTER_FT"])
AS_CAN9660_writetableval(CAN9660["FILTER_FT"]["addr"], int(CAN9660["FILTER_FT"] * 10))
if (CAN9660["FILTER_RT"]["old"] != CAN9660["FILTER_RT"])
AS_CAN9660_writetableval(CAN9660["FILTER_RT"]["addr"], int(CAN9660["FILTER_RT"] * 10))
if (CAN9660["FILTER_PZM"]["old"] != CAN9660["FILTER_PZM"])
AS_CAN9660_writetableval(CAN9660["FILTER_PZM"]["addr"], CAN9660["FILTER_PZM"])
if (CAN9660["FILTER_PZ"]["old"] != CAN9660["FILTER_PZ"]) {
local x
if (CAN9660["FILTER_PZ"] != 0) {
x = int((CAN9660["FILTER_PZ"] - 1.7) * 0xfff / 40)
} else x = 0
AS_CAN9660_writetableval(CAN9660["FILTER_PZ"]["addr"], x)
}
# ADC related stuff
if (CAN9660["ADC_LLD"]["old"] != CAN9660["ADC_LLD"])
AS_CAN9660_writetableval(CAN9660["ADC_LLD"]["addr"], CAN9660["ADC_LLD"] * 0x7FFF / 100)
if (CAN9660["ADC_CGAIN"]["old"] != CAN9660["ADC_CGAIN"])
AS_CAN9660_writetableval(CAN9660["ADC_CGAIN"]["addr"], CAN9660["ADC_CGAIN"])
if (CAN9660["ADC_OFFSET"]["old"] != CAN9660["ADC_OFFSET"])
AS_CAN9660_writetableval(CAN9660["ADC_OFFSET"]["addr"], CAN9660["ADC_OFFSET"] / 128)
if (CAN9660["ADC_ZERO"]["old"] != CAN9660["ADC_ZERO"])
AS_CAN9660_writetableval(CAN9660["ADC_ZERO"]["addr"], CAN9660["ADC_ZERO"] * 1000 + 3125)
# Stabilizer setup
if (CAN9660["STABLZ_GCOR"]["old"] != CAN9660["STABLZ_GCOR"])
AS_CAN9660_writetableval(CAN9660["STABLZ_GCOR"]["addr"], CAN9660["STABLZ_GCOR"])
if (CAN9660["STABLZ_ZCOR"]["old"] != CAN9660["STABLZ_ZCOR"])
AS_CAN9660_writetableval(CAN9660["STABLZ_ZCOR"]["addr"], CAN9660["STABLZ_ZCOR"])
if (CAN9660["STABLZ_GMOD"]["old"] != CAN9660["STABLZ_GMOD"])
AS_CAN9660_writetableval(CAN9660["STABLZ_GMOD"]["addr"], CAN9660["STABLZ_GMOD"])
if (CAN9660["STABLZ_ZMOD"]["old"] != CAN9660["STABLZ_ZMOD"])
AS_CAN9660_writetableval(CAN9660["STABLZ_ZMOD"]["addr"], CAN9660["STABLZ_ZMOD"])
if (CAN9660["STABLZ_GDIV"]["old"] != CAN9660["STABLZ_GDIV"])
AS_CAN9660_writetableval(CAN9660["STABLZ_GDIV"]["addr"], CAN9660["STABLZ_GDIV"])
if (CAN9660["STABLZ_ZDIV"]["old"] != CAN9660["STABLZ_ZDIV"])
AS_CAN9660_writetableval(CAN9660["STABLZ_ZDIV"]["addr"], CAN9660["STABLZ_ZDIV"])
if (CAN9660["STABLZ_GSPC"]["old"] != CAN9660["STABLZ_GSPC"])
AS_CAN9660_writetableval(CAN9660["STABLZ_GSPC"]["addr"], CAN9660["STABLZ_GSPC"])
if (CAN9660["STABLZ_ZSPC"]["old"] != CAN9660["STABLZ_ZSPC"])
AS_CAN9660_writetableval(CAN9660["STABLZ_ZSPC"]["addr"], CAN9660["STABLZ_ZSPC"])
if (CAN9660["STABLZ_GWIN"]["old"] != CAN9660["STABLZ_GWIN"])
AS_CAN9660_writetableval(CAN9660["STABLZ_GWIN"]["addr"], CAN9660["STABLZ_GWIN"])
if (CAN9660["STABLZ_ZWIN"]["old"] != CAN9660["STABLZ_ZWIN"])
AS_CAN9660_writetableval(CAN9660["STABLZ_ZWIN"]["addr"], CAN9660["STABLZ_ZWIN"])
if (CAN9660["STABLZ_GCENT"]["old"] != CAN9660["STABLZ_GCENT"])
AS_CAN9660_writetableval(CAN9660["STABLZ_GCENT"]["addr"], CAN9660["STABLZ_GCENT"])
if (CAN9660["STABLZ_ZCENT"]["old"] != CAN9660["STABLZ_ZCENT"])
AS_CAN9660_writetableval(CAN9660["STABLZ_ZCENT"]["addr"], CAN9660["STABLZ_ZCENT"])
if (CAN9660["STABLZ_GRAT"]["old"] != CAN9660["STABLZ_GRAT"])
AS_CAN9660_writetableval(CAN9660["STABLZ_GRAT"]["addr"], CAN9660["STABLZ_GRAT"])
if (CAN9660["STABLZ_ZRAT"]["old"] != CAN9660["STABLZ_ZRAT"])
AS_CAN9660_writetableval(CAN9660["STABLZ_ZRAT"]["addr"], CAN9660["STABLZ_ZRAT"])
if (CAN9660["STABLZ_GAIN"]["old"] != CAN9660["STABLZ_GAIN"])
AS_CAN9660_writetableval(CAN9660["STABLZ_GAIN"]["addr"], CAN9660["STABLZ_GAIN"])
if (CAN9660["STABLZ_ZERO"]["old"] != CAN9660["STABLZ_ZERO"])
AS_CAN9660_writetableval(CAN9660["STABLZ_ZERO"]["addr"], CAN9660["STABLZ_ZERO"])
delete CAN9660["read for ADC"]
delete CAN9660["read for fdisc"]
delete CAN9660["read for gain"]
delete CAN9660["read for stabilizer1"]
delete CAN9660["read for stabilizer2"]
delete CAN9660["read for filter"]
CAN9660["warn"] = 0
}'
#%IU%()
#%MDESC% Writes all the values to the controller. Presets the data structure
#used by the macros for the canberra 9660 DSP
def AS_CAN9660_write_force() '{
local x
if (!(whatis("CAN9660") & 0x04000000)) {
printf ("Please run can9660setup first")
exit
}
# Gain related stuff
AS_CAN9660_writetableval(CAN9660["AMP_CGAIN"]["addr"], CAN9660["AMP_CGAIN"])
AS_CAN9660_writetableval(CAN9660["AMP_FGAIN"]["addr"], CAN9660["AMP_FGAIN"] * 0x1000 / 1.6)
AS_CAN9660_writetableval(CAN9660["AMP_SFGAIN"]["addr"], CAN9660["AMP_SFGAIN"] * 0x1000 / 0.03)
AS_CAN9660_writetableval(CAN9660["COINC"]["addr"], CAN9660["COINC"])
# fast discriminator stuff
AS_CAN9660_writetableval(CAN9660["MISC_FDM"]["addr"], CAN9660["MISC_FDM"])
AS_CAN9660_writetableval(CAN9660["MISC_FD"]["addr"], CAN9660["MISC_FD"])
AS_CAN9660_writetableval(CAN9660["MISC_INPP"]["addr"], CAN9660["MISC_INPP"])
AS_CAN9660_writetableval(CAN9660["MISC_INHP"]["addr"], CAN9660["MISC_INHP"])
# Filter related stuff
AS_CAN9660_writetableval(CAN9660["FILTER_FT"]["addr"], int(CAN9660["FILTER_FT"] * 10))
AS_CAN9660_writetableval(CAN9660["FILTER_RT"]["addr"], int(CAN9660["FILTER_RT"] * 10))
AS_CAN9660_writetableval(CAN9660["FILTER_PZM"]["addr"], CAN9660["FILTER_PZM"])
if (CAN9660["FILTER_PZ"] != 0) {
x = int((CAN9660["FILTER_PZ"] - 1.7) * 0xfff / 40)
} else {
x = 0
}
AS_CAN9660_writetableval(CAN9660["FILTER_PZ"]["addr"], x)
# ADC related stuff
AS_CAN9660_writetableval(CAN9660["ADC_LLD"]["addr"], CAN9660["ADC_LLD"] * 0x7FFF / 100)
AS_CAN9660_writetableval(CAN9660["ADC_CGAIN"]["addr"], CAN9660["ADC_CGAIN"])
AS_CAN9660_writetableval(CAN9660["ADC_OFFSET"]["addr"], CAN9660["ADC_OFFSET"] / 128)
AS_CAN9660_writetableval(CAN9660["ADC_ZERO"]["addr"], CAN9660["ADC_ZERO"] * 1000 + 3125)
# Stabilizer setup
AS_CAN9660_writetableval(CAN9660["STABLZ_GCOR"]["addr"], CAN9660["STABLZ_GCOR"])
AS_CAN9660_writetableval(CAN9660["STABLZ_ZCOR"]["addr"], CAN9660["STABLZ_ZCOR"])
AS_CAN9660_writetableval(CAN9660["STABLZ_GMOD"]["addr"], CAN9660["STABLZ_GMOD"])
AS_CAN9660_writetableval(CAN9660["STABLZ_ZMOD"]["addr"], CAN9660["STABLZ_ZMOD"])
AS_CAN9660_writetableval(CAN9660["STABLZ_GDIV"]["addr"], CAN9660["STABLZ_GDIV"])
AS_CAN9660_writetableval(CAN9660["STABLZ_ZDIV"]["addr"], CAN9660["STABLZ_ZDIV"])
AS_CAN9660_writetableval(CAN9660["STABLZ_GSPC"]["addr"], CAN9660["STABLZ_GSPC"])
AS_CAN9660_writetableval(CAN9660["STABLZ_ZSPC"]["addr"], CAN9660["STABLZ_ZSPC"])
AS_CAN9660_writetableval(CAN9660["STABLZ_GWIN"]["addr"], CAN9660["STABLZ_GWIN"])
AS_CAN9660_writetableval(CAN9660["STABLZ_ZWIN"]["addr"], CAN9660["STABLZ_ZWIN"])
AS_CAN9660_writetableval(CAN9660["STABLZ_GCENT"]["addr"], CAN9660["STABLZ_GCENT"])
AS_CAN9660_writetableval(CAN9660["STABLZ_ZCENT"]["addr"], CAN9660["STABLZ_ZCENT"])
AS_CAN9660_writetableval(CAN9660["STABLZ_GRAT"]["addr"], CAN9660["STABLZ_GRAT"])
AS_CAN9660_writetableval(CAN9660["STABLZ_ZRAT"]["addr"], CAN9660["STABLZ_ZRAT"])
AS_CAN9660_writetableval(CAN9660["STABLZ_GAIN"]["addr"], CAN9660["STABLZ_GAIN"])
AS_CAN9660_writetableval(CAN9660["STABLZ_ZERO"]["addr"], CAN9660["STABLZ_ZERO"])
delete CAN9660["read for ADC"]
delete CAN9660["read for fdisc"]
delete CAN9660["read for gain"]
delete CAN9660["read for stabilizer1"]
delete CAN9660["read for stabilizer2"]
delete CAN9660["read for filter"]
CAN9660["warn"] = 0
}'
#%IU%
#%MDESC% Only for test purposes. Sets the verbose option used
#by the macros for the canberra 9660 DSP
def AS_CAN9660_verbose '{
if (!(whatis("CAN9660") & 0x01000000)) {
printf ("Please run can9660setup first")
exit
}
CAN9660["Verbose"] = CAN9660["Verbose"] ? 0 : 1
if (CAN9660["Verbose"]) rdef AS_CAN9660_info "print"
else rdef AS_CAN9660_info "\#\$\*"
}'
#%IU%
#%MDESC% Documented to send a reset
def AS_CAN9660_reset '{
icb_write(CAN9660["dev"], CAN9660["icb_adr"], 0, 0x08)
icb_write(CAN9660["dev"], CAN9660["icb_adr"], 0, 0x04)
}'
#%IU%
#%MDESC% Documented to send a device ready
def AS_CAN9660_ready '{
icb_write(CAN9660["dev"], CAN9660["icb_adr"], 0, 0x10)
}'
#%IU%
#%MDESC% Send a device ready and restore the values initially
# set by Andrea S.
def AS_CAN9660_init '{
can9660_reset
can9660_ready
for (key in CAN9660){
split(key, tab, "\034")
if (tab[1] == "addr")
CAN9660[tab[0]]["addr"] = CAN9660[tab[0]]["init"]
}
}'
#-----------------------------------------------------------
#%IU%
#%MDESC% read register 6 of the DSP module and decode the various bits.
def AS_CAN9660_modulestatus '{
local numregs
numregs = 7
local ubyte array CAN9660regs[numregs]
icb_mread (CAN9660["dev"], CAN9660["icb_adr"], 6, 6, CAN9660regs)
# find the contents of reg 6 in CAN9660regs[6]
AS_CAN9660_info sprintf("register 6 contains 0x%02x\n", CAN9660regs[6])
if (CAN9660regs[6] & (1<<7)) {
print "DSP module: DXIP (data transfer to the module inf progress)."
}
if (CAN9660regs[6] & (1<<6)) {
print "DSP module: RDAV/WDONE double function bit:"
print " RDAV : Register data available for reading."
print " WDONE: Write operation hwas been completed."
print "This bit will be cleared after reading."
}
if (CAN9660regs[6] & (1<<3)) {
print "DSP module: ABUSY (Process is busy. Currently performing \
lengthy task)."
}
if (CAN9660regs[6] & (1<<2)) {
print "DSP module: MBUSY (Module is busy. Currently executing \
command)."
}
if (CAN9660regs[6] & (1<<1)) {
print "DSP module: MERR (Module error. Will be set by one of the \
following:"
print " Stabilizer Gain-Mode was ON and overrange condition \
occured."
print " Stabilizer Zero-Mode was ON and overrange condition \
occured."
}
if (CAN9660regs[6] & 1) {
print "DSP module: FAIL (Internal hardware failure occurred)."
}
}'
##def icb_read (device, addr, reg) must be taken from can9635.mac
if (!(whatis("icb_read") & 2)) {
print "***\nicb_read is not defined, please use can9635.mac for \
that!\n***"
}
##def icb_write (device, addr, reg, value) must be taken
# from can9635.mac
if (!(whatis("icb_write") & 2)) {
print "***\nicb_write is not defined, please use can9635.mac for \
that!\n***"
}
##def icb_mread (device, addr, from_reg, to_reg, outarr) must be taken
# from can9635.mac
if (!(whatis("icb_mread") & 2)) {
print "***\nicb_mread is not defined, please use can9635.mac for \
that!\n***"
}
##def icb_mwrite (device, addr, from_reg, to_reg, inarr) must be taken
# from can9635.mac
if (!(whatis("icb_mwrite") & 2)) {
print "***\nicb_mwrite is not defined, please use can9635.mac for \
that!\n***"
}
#-----------------------------------------------------------
#%IU%(data table index)
#%MDESC% read a value from the DSP data space.
# To read such a value, you must write registers 2 to 5 (5 always last )
# with the appropriate contents, then check R6 for the RDAV bit and the
# re-read the R2-5 to find the result in the same registers. The RDAV
# bit is self clearing, one read will clear it.
def AS_CAN9660_readtableval(tablenum) '{
local numregs, i, value
numregs = 7; value = 0
local ubyte array CAN9660regs[numregs+1]
if (!(whatis("CAN9660") & 0x01000000)) {
printf ("Please run can9660setup first")
exit
}
CAN9660regs[2] = 0x08 # bit #3 indicates read operation
CAN9660regs[3] = tablenum
CAN9660regs[4] = 0
CAN9660regs[5] = 0
AS_CAN9660_info sprintf("registers 2 to 5: 0x%02x 0x%02x 0x%02x 0x%02x \n", \
CAN9660regs[2], CAN9660regs[3], CAN9660regs[4], CAN9660regs[5])
# now send registers 2 to 5.
icb_mwrite(CAN9660["dev"], CAN9660["icb_adr"], 2, 5, CAN9660regs)
AS_CAN9660_info "wrote reg 2 to 5"
# read register 6
icb_mread (CAN9660["dev"], CAN9660["icb_adr"], 6, 6, CAN9660regs)
if(set_sim(-1)) CAN9660regs[6] = 0x40
AS_CAN9660_info sprintf("read reg 6 0x%02x\n", CAN9660regs[6])
i = 1
# check for the RDAV bit.
while(!(CAN9660regs[6] & 0x40)) {
icb_mread (CAN9660["dev"], CAN9660["icb_adr"], 6, 6, CAN9660regs)
AS_CAN9660_info sprintf("read reg 6 0x%02x\n", CAN9660regs[6])
sleep(0.1) # wait for 100ms
i ++ # increment the counter to see how many times all this takes.
}
AS_CAN9660_info sprintf("needed %d times to read the RDAV bit.\n", i)
icb_mread (CAN9660["dev"], CAN9660["icb_adr"], 0, 6, CAN9660regs)
AS_CAN9660_info "read reg 0 to 6"
# now the contents of table, the value should be register 5 plus
# R4 << 8 plus R3 << 16 plus R2 << 24
# only 28 bits are however significant !
AS_CAN9660_info sprintf("registers 0 to 6: 0x%02x 0x%02x 0x%02x \
0x%02x 0x%02x 0x%02x 0x%02x \n", CAN9660regs[0], CAN9660regs[1], \
CAN9660regs[2], CAN9660regs[3], CAN9660regs[4], CAN9660regs[5], \
CAN9660regs[6])
value = CAN9660regs[5] + (CAN9660regs[4] <<8) + \
(CAN9660regs[3] <<16) + (CAN9660regs[2] <<24)
value = value & 0x1FFFFFFF
AS_CAN9660_info value
printf(".")
return(value)
}' # Ends macro AS_CAN9660_readtableval
#-----------------------------------------------------------
#%IU%(data table index, value to write)
#%MDESC% write a value from the DSP data space.
# To write such a value, you must write registers 2 to 5 (5 always last )
# with the appropriate contents, then check R6 for the WDONE bit. The
# RDAV bit is self clearing, one read will clear it.
def AS_CAN9660_writetableval(tablenum, value) '{
local numregs, i
numregs = 7
local ubyte array CAN9660regs[numregs+1]
if (!(whatis("CAN9660") & 0x01000000)) {
printf ("Please run can9660setup first")
exit
}
CAN9660regs[2] = 0 # absence of bit #3 indicates write operation
CAN9660regs[3] = tablenum
CAN9660regs[4] = (value & 0xffff) >> 8
CAN9660regs[5] = value & 0xff
AS_CAN9660_info sprintf("registers 2 to 5: 0x%02x 0x%02x 0x%02x 0x%02x \n", \
CAN9660regs[2], CAN9660regs[3], CAN9660regs[4], CAN9660regs[5])
# now send registers 2 to 5.
AS_CAN9660_info sprintf("value to write is 0x%08x\n", value)
icb_mwrite(CAN9660["dev"], CAN9660["icb_adr"], 2, 5, CAN9660regs)
AS_CAN9660_info "wrote reg 2 to 5"
# read register 6
icb_mread (CAN9660["dev"], CAN9660["icb_adr"], 6, 6, CAN9660regs)
AS_CAN9660_info sprintf("read reg 6 0x%02x\n", CAN9660regs[6])
i = 1
if(set_sim(-1)) CAN9660regs[6] = 0x40
# check for the WDONE bit.
while(!(CAN9660regs[6] & 0x40)) {
icb_mread (CAN9660["dev"], CAN9660["icb_adr"], 6, 6, CAN9660regs)
AS_CAN9660_info sprintf("read reg 6 0x%02x\n", CAN9660regs[6])
sleep(0.1) # wait for 100ms
i ++ # increment the counter to see how many times all this takes.
}
AS_CAN9660_info sprintf("needed %d times to read the WDONE bit.\n", i)
printf(".")
}' # Ends macro AS_CAN9660_writetableval
#%UU% [filename] [overwrite]
#%MDESC% Save the DSP parameters to an
#ASCII file, so they can be reloaded later by the "can9660restore_config" macro.
#The file is in the directory ~blissadm/local/spec/userconf/dsp and has the
#name, that you choose.
#%BR%
#If no name is specified as first argument, the user is prompted for
#one. If the file exists, the user will be prompted to confirm overwriting,
#unless a second argument is present.
def can9660save_config '{
local dir file fullname command overwrite answer
if (!(whatis("CAN9660") & 0x01000000)) {
printf ("Please run can9660setup first")
exit
}
dir = CAN9660["config_dir"]
if ($# == 0) {
print "Save CAN9660 DSP values."
print "Already used filenames are:"
unix(command = "ls "dir)
file = getval("Enter filename","")
} else
file = "$1"
if($# == 2) overwrite=1
else if (yesno(sprintf("Overwrite file %s", file), 1))
overwrite=1
else overwrite=0
if (file_info(dir,"isdir") != 1) unix (command="mkdir -p "dir)
fullname = sprintf("%s/%s", dir, file)
if (file_info(fullname, "-e")) {
if (overwrite)
unix (command = "rm -f "fullname)
else {
print "WARNING: File", file, "not written!"
return 1
}
}
on(fullname); offt
for (i in CAN9660) {
local x[]
split(i, x, "\034")
if (x[1] == "addr") print "CAN9660[\"" x[0] "\"] =",CAN9660[x[0]]
}
close (fullname); ont
print "CAN9660 DSP values stored in:"
print fullname
}'
#%UU% [filename]
#%MDESC% Restore the parameters stored in the file given by the only argument
#or entered by the user on request.
#%BR%
#The values will not immediately written to the controller, but will replace the
#values shown in the menus at the next call of can9660menu. If you choose not to
#write the values to the controller, they will persist, until you either write
#them to the controller or perform a new can9660setup. This will not destroy the
#existing data, but force the reading of the controller, which will provide you
# again with the life values.
def can9660restore_config '{
local file fullname dir
if (!(whatis("CAN9660") & 0x01000000)) {
printf ("Please run can9660setup first")
exit
}
dir = CAN9660["config_dir"]
if ($# == 0) {
print "Restore CAN9660 DSP values."
print "Available files are:"
unix(command = "ls "dir)
file = getval("Enter filename","")
} else
file = "$1"
if (file == "-1")
file = CAN9660["config_file"]
if (file != "" ) {
fullname = sprintf("%s/%s", dir, file)
if (file_info(fullname,"-e") == 1) {
global CAN9660
qdofile(fullname)
CAN9660["read for ADC"] = 1
CAN9660["read for fdisc"] = 1
CAN9660["read for gain"] = 1
CAN9660["read for stabilizer1"] = 1
CAN9660["read for stabilizer2"] = 1
CAN9660["read for filter"] = 1
eprint "DSP parameters have been restored. Use can9660menu to adjust"
eprint "them to your needs!"
} else
eprint "No such file", fullname ". Can\'t restore CAN9660 DSP values"
} else
eprint "No filename given ---> no action!"
}'
#%MACROS%
#%IMACROS%
#%TOC%
#%AUTHOR% Holger
|