esrf

Beamline Instrument Software Support
SPEC Macro documentation: [ Macro Index | BCU Home ]

#%TITLE% can9635.mac
#%NAME% 
#   Macros to control the digital ADC Canberra 9635
#%CATEGORY% Detection, MCA
#%DESCRIPTION% 
#  Simple macros to control the "digital" ADC Canberra 9635.
#  Use "can9635menu" to set the parameters, "can9635status" to see them and 
# "can9635init" to put them to some default values.
#
#%LOG%
#
#$Log: can9635.mac,v $
#Revision 1.4  2008/02/18 09:50:38  rey
#Only documentation changes
#
#Revision 1.3  2005/12/13 08:33:15  papillon
#* Changes to integrate MUSST ICB
#
#Revision 1.2  2001/03/13 18:43:15  beteva
#changed to handle more than one ADC.
#
#%END%

#%UU% [mca_no (mca_no ...)]
#%MDESC% Sets up Canberra 9635 ADC(s) -  MCA number %B%mca_no%B% as in the
#SPEC config.
def can9635setup '{
global CAN9635_DEV CAN9635_NO CAN9635_STATE
global CAN9635_LLD CAN9635_ULD CAN9635_ZERO CAN9635_OFFSET
global CAN9635_RANGE CAN9635_GAIN CAN9635_MODE CAN9635_ADCGAIN
global ICB[]
local idx mca_no icb_addr inp

if ($#) {
   CAN9635_NO = (split("$*",inp))
   for (idx = 0; idx < CAN9635_NO; idx++)
      _can9635setup(inp[idx])
  } else {
   CAN9635_NO = getval("How many ADC (9635) to setup: ", CAN9635_NO)
   for (idx = 0; idx < CAN9635_NO; idx++) {
      mca_no = input ("MCA number as in the config: ")
      _can9635setup(mca_no)
      _can9635read(mca_no)
     }
  }
}'

#%IU% (mca_no)
#%MDESC% Get the MCA %B%mca_no%B% device name.
def _can9635setup(mca_no) '{
global CAN9635_ICB_ADR
   CAN9635_ICB_ADR[mca_no] = 0
   if (mca_spar(mca_no, "controller")=="MUSSTMCA")
      CAN9635_DEV[mca_no]= mca_no
   else
      CAN9635_DEV[mca_no] = mca_spar(mca_no,"device_id")


}'

#%UU% [mca_no]
#%MDESC% Sets the canberra ADC module to some default state.
def can9635init '{
local mca_no

  if ($# != 1) {
     if (CAN9635_NO == 1)
       mca_no = 0
     else
       mca_no = input ("MCA number as in the config: ")
    }
  else
    mca_no = $1

_can9635init(mca_no)
}'

#%IU% (mca_no)
#%MDESC% Sets the canberra ADC module to some default state.
def _can9635init(mca_no) '{

_can9635_reset (mca_no)

_can9635_setgain(mca_no, 8192, 0)
_can9635_setrange(mca_no, 8192, 0)
_can9635_setlld (mca_no, 0.63, 0)
_can9635_setuld (mca_no, 10.5, 0)
_can9635_setzero (mca_no, -.39, 0)
_can9635_setadcgain (mca_no, 0, 0)
_can9635_setoffset (mca_no, 255, 0)

# Set operation mode
ICB[2] = 0xf4
_icb_write(mca_no, 2, 1, ICB)
_can9635_readmode(mca_no)
#ADC ready
ICB[0] = 0x10
_icb_write(mca_no, 0, 1, ICB)
}'

#%UU% [mca_no]
#%MDESC% Simple menu to send commands to the canberra adc without having to
#remember the individual routines.
def can9635menu '{
  local answer mca_no

  if ($# != 1) {
     if (CAN9635_NO == 1)
       mca_no = 0
     else
       mca_no = input ("MCA number as in the config: ")
    }
  else
    mca_no = $1

  for (;;) {
    _can9635status (mca_no)
    ans = "e"
    ans = getval ("\n(g)gain, (r)ange (l)LD, (u)LD, (z)ero, (a)dcgain (o)ffset (m)ode, (e)xit", ans)
    if (ans == "g") {
      _can9635_setgain (mca_no, CAN9635_GAIN[mca_no], 1)
    } else if (ans == "r") {
      _can9635_setrange (mca_no, CAN9635_RANGE[mca_no], 1)
    } else if (ans == "l") {
      _can9635_setlld (mca_no, CAN9635_LLD[mca_no], 1)
    } else if (ans == "u") {
      _can9635_setuld (mca_no, CAN9635_ULD[mca_no], 1)
    } else if (ans == "z") {
      _can9635_setzero (mca_no, CAN9635_ZERO[mca_no], 1)
    } else if (ans == "a") {
      _can9635_setadcgain (mca_no, CAN9635_ADCGAIN[mca_no], 1)
    } else if (ans == "o") {
      _can9635_setoffset (mca_no, CAN9635_OFFSET[mca_no], 1)
    } else if (ans == "m") {
      can9635_setmode mca_no
    } else
      break
  }
}'

#%UU% [mca_no lld]
#%MDESC% Set the LLD (Lower Level Discriminator) for minimum input acceptance
#voltage, range 0 to +10 V dc. Resolution 1 part in 4096 or 2.5 mV/step.
def can9635_setlld '{
local mca_no val

 if (CAN9635_NO == 1) {
    mca_no = 0
    if ($# == 1)
      val = $1
    else
      val = getval ("Lower Level Discriminator (0-10V)", CAN9635_LLD[mca_no])
   } else {
    if ($# == 2) {
       mca_no = $1
       val = $2
      } else {
        mca_no = input ("MCA number as in the config: ")
        val = getval ("Lower Level Discriminator (0-10V)", CAN9635_LLD[mca_no])
      }
   }
  if (_can9635_setlld (mca_no, val) == -1)
    print "ERROR : Range for LLD is 0-10V"
  else
    printf ("ADC %d LLD set to %.2f\n", mca_no, val)
}'

#%IU% (mca_no, val, flag)
#%MDESC% Set the LLD to %B%val%B% for %B%mca_no%B% ADC. If the %B%flag%B% is
#nonzero, ask for the value. Return -1 if error.
def _can9635_setlld (mca_no, val, flag) '{
local icb[]

  if (flag == 1)
    val = getval ("Lower Level Discriminator (0-10V)", CAN9635_LLD[mca_no])
  if (val < 0 || val > 10 )
    return (-1)

  CAN9635_LLD[mca_no] = val

  _can9635_conv_to_reg ("lld", val, icb)
  if (_icb_write(mca_no, 4, 2, icb) < 0)
    return (-1)
  icb[13] = 0
  return (_icb_write(mca_no, 13, 1, icb))
}'

#%UU% [mca_no uld]
#%MDESC% Set the ULD (Upper Level Discriminator) for maximum input acceptance
#voltage; range 0 to +10.5 V dc. Resolution 1 part in 4096 or 2.6 mV/step.
def can9635_setuld '{
local mca_no val

 if (CAN9635_NO == 1) {
    mca_no = 0
    if ($# == 1)
      val = $1
    else
      val = getval ("Upper Level Discriminator (0-10.5V)", CAN9635_ULD[mca_no])
   } else {
    if ($# == 2) {
       mca_no = $1
       val = $2
      } else {
        mca_no = input ("MCA number as in the config: ")
        val = getval ("Upper Level Discriminator (0-10.5V)", CAN9635_ULD[mca_no])
      }
   }
  if (_can9635_setuld (mca_no, val, flag) == -1)
    print "ERROR : Range for ULD is 0-10.5V"
  else
    printf ("ADC %d ULD set to %.2f\n", mca_no, val)
}'

#%IU% (mca_no, val, flag)
#%MDESC% Set the ULD to %B%val%B% for %B%mca_no%B% ADC. If the %B%flag%B% is
#nonzero, ask for the value. Return -1 if error.
def _can9635_setuld (mca_no, val, flag) '{
local icb[]

  if (flag != 0)
    val = getval ("Upper Level Discriminator (0-10.5V)", CAN9635_ULD[mca_no])

  if (val < 0 || val > 10.5 )
    return (-1)

  CAN9635_ULD[mca_no] = val

  _can9635_conv_to_reg ("uld", val, icb)
  if (_icb_write(mca_no, 6, 2, icb) < 0)
    return (-1)
  icb[13] = 0
  return (_icb_write(mca_no, 13, 1, icb))
}'

#%UU% [mca_no zero]
#%MDESC% Set the analog zero level; adjustment range +-3% of the ADC full
#scale range. Resolution 1 part in 4096 or 0.0015%/step.
def can9635_setzero '{
local mca_no val

 if (CAN9635_NO == 1) {
    mca_no = 0
    if ($# == 1)
      val = $1
    else
      val = getval ("Zero (-5..5V)", CAN9635_ZERO[mca_no])
   } else {
    if ($# == 2) {
       mca_no = $1
       val = $2
      } else {
        mca_no = input ("MCA number as in the config: ")
        val = getval ("Zero (-5..5V)", CAN9635_ZERO[mca_no])
      }
   }

  if ( _can9635_setzero (mca_no, val, flag) == -1)
    print "ERROR : Range for Zero is -5V - 5V"
  else
    printf ("ADC %d zero set to %.2f\n", mca_no, val)
}'

#%IU% (mca_no, val, flag)
#%MDESC% Set analog zero level to %B%val%B% for %B%mca_no%B% ADC. If the
#%B%flag%B% is nonzero, ask for the value. Return -1 if error.
def _can9635_setzero(mca_no, val, flag) '{
local icb[]

  if (flag == 1)
    val = getval ("Zero (-5..5V)", CAN9635_ZERO[mca_no])

  if (val < -5 || val > 5)
    return (-1)

  CAN9635_ZERO[mca_no] = val
  _can9635_conv_to_reg ("zero", val, icb)
  if (_icb_write(mca_no, 8, 2, icb) < 0)
    return (-1)
  icb[13] = 0
  return (_icb_write(mca_no, 13, 1, icb))
}'

#%UU% [mca_no range]
#%MDESC% Set the range - 256, 512, 1024, 2048, 4096 or 8192 channels
#as the ADC's output limit.
def can9635_setrange '{
local mca_no val

 if (CAN9635_NO == 1) {
    mca_no = 0
    if ($# == 1)
      val = $1
    else
      val = getval ("Number of channels (256, .. 8192)", CAN9635_RANGE[mca_no])
   } else {
    if ($# == 2) {
       mca_no = $1
       val = $2
      } else {
        mca_no = input ("MCA number as in the config: ")
        val = getval ("Number of channels (256, .. 8192)", CAN9635_RANGE[mca_no])
      }
   }

  if (_can9635_setrange (mca_no, val) == -1)
    print "ERROR : Cannot set the range"
  else
    printf ("ADC %d range set to %d channels\n", mca_no, CAN9635_RANGE[mca_no])
}'

#%IU% (mca_no, val, flag)
#%MDESC% Set the range to %B%val%B% for %B%mca_no%B% ADC. If the
#%B%flag%B% is nonzero, ask for the value. Return -1 if error.
def _can9635_setrange(mca_no, val, flag) '{

  if (flag == 1)
    val = getval ("Number of channels (256, .. 8192)", CAN9635_RANGE[mca_no])

  CAN9635_RANGE[mca_no] = _nbch(val)
  
  _can9635_conv_to_reg ("range", CAN9635_RANGE[mca_no], ICB)
  return (_icb_write(mca_no, 3, 1, ICB))
}'

#%UU% [mca_no gain]
#%MDESC% Set the gain - 256, 512, 1024, 2048, 4096 or 8192 channels
#as the ADC's output limit.
def can9635_setgain '{
local mca_no val

 if (CAN9635_NO == 1) {
    mca_no = 0
    if ($# == 1)
      val = $1
    else
      val = getval ("Number of channels (256, .. 8192)", CAN9635_GAIN[mca_no])
   } else {
    if ($# == 2) {
       mca_no = $1
       val = $2
      } else {
        mca_no = input ("MCA number as in the config: ")
        val = getval ("Number of channels (256, .. 8192)", CAN9635_GAIN[mca_no])
      }
   }

  if (_can9635_setgain (mca_no, val) == -1)
    print "ERROR : Cannot set the gain"
  else
    printf ("ADC %d gain set to %d channels\n", mca_no, CAN9635_GAIN[mca_no])
}'

#%IU% (mca_no, val, flag)
#%MDESC% Set the gain to %B%val%B% for %B%mca_no%B% ADC. If the
#%B%flag%B% is nonzero, ask for the value. Return -1 if error.
def _can9635_setgain(mca_no, val, flag) '{

  if (flag == 1)
    val = getval ("Number of channels (256, .. 8192)", CAN9635_GAIN[mca_no])

  
  CAN9635_GAIN[mca_no] = _nbch(val)
  
  _can9635_conv_to_reg ("gain", CAN9635_GAIN[mca_no], ICB)
  return (_icb_write(mca_no, 3, 1, ICB))
}'

#%UU% [mca_no adc_gain]
#%MDESC% Set adc gain 
def can9635_setadcgain '{
local mca_no val

 if (CAN9635_NO == 1) {
    mca_no = 0
    if ($# == 1)
      val = $1
    else
      val = getval ("ADC Gain (0 - 0xffff..)", CAN9635_ADCGAIN[mca_no])
   } else {
    if ($# == 2) {
       mca_no = $1
       val = $2
      } else {
        mca_no = input ("MCA number as in the config: ")
        val = getval ("ADC Gain (0 - 0xffff..)", CAN9635_ADCGAIN[mca_no])
      }
   }

  if (_can9635_setadcgain (mca_no, val, flag) == -1)
    print "ERROR : Range for ADC Gain is 0 to 0xffff"
  else
    printf ("ADC %d Gain set to %d\n", mca_no, val)
}'

#%IU% (mca_no, val, flag)
#%MDESC% Set ADC Gain to %B%val%B% for
#%B%mca_no%B% (as in the config) ADC. Return -1 if error.
def _can9635_setadcgain(mca_no,val, flag) '{
local icb[]

  if (flag == 1)
    val = getval ("ADC Gain (..)", CAN9635_ADCGAIN[mca_no])

  if (val < 0 || val > 0xffff)
    return (-1)

  CAN9635_ADCGAIN[mca_no] = val
  _can9635_conv_to_reg ("adc_gain", val, icb)
  return (_icb_write(mca_no, 10, 2, icb))
}'

#%UU% [mca_no offset]
#%MDESC% Set the digital offset of 0 to 8064 channels in binary multiples
#of 128 channels.
def can9635_setoffset '{
local mca_no val

 if (CAN9635_NO == 1) {
    mca_no = 0
    if ($# == 1)
      val = $1
    else
      val = getval ("ADC Offset (0-255)", CAN9635_OFFSET[mca_no])
   } else {
    if ($# == 2) {
       mca_no = $1
       val = $2
      } else {
        mca_no = input ("MCA number as in the config: ")
        val = getval ("ADC Offset (0-255)", CAN9635_OFFSET[mca_no])
      }
   }

  if ( _can9635_setoffset (mca_no, val, flag) == -1)
    print "ERROR : Range for ADC Offset 0..255"
  else
    printf ("ADC %d Offset set to %d\n", mca_no, val)
}'

#%IU% (mca_no, val, flag)
#%MDESC% Set ADC Offset to %B%val%B% for %B%mca_no%B% ADC. If the
#%B%flag%B% is nonzero, ask for the value. Return -1 if error.
def _can9635_setoffset(mca_no, val, flag) '{
local icb[]

  if (flag == 1)
    val = getval ("ADC Offset (0-255)", CAN9635_OFFSET[mca_no])
    
  if (val < 0 || val > 0xff)
    return (-1)

  CAN9635_OFFSET[mca_no] = val
  icb[12] = val
  return (_icb_write(mca_no, 12, 1, icb))

}'

#%IU% (mca_no)
#%MDESC% Reset the %B%mca_no%B% ADC.
def _can9635_reset (mca_no) '{
local i icb[]
  icb[0] = 0x08
  _icb_write(mca_no, 0, 1, icb)
  icb[0] = 0x04
  _icb_write(mca_no, 0, 1, icb)
}'
#%UU% [mca_no]
#%MDESC% Sets the canberra ADC mode as follows%BR%
#Pileup Rejection: LTC/PUR - non-LTC/PUR;%BR%
#Data Transfer: Overlapped - Non-overlapped;%BR%
#Peak Detect: Delayed - Automatic;%BR%
#Coincidence Mode: Anticoincidence - Coincidence;%BR%
#Coincidence Timing: Late - Early;%BR%
#Conversion Mode: SVA - PHA;
def can9635_setmode '{
local mca_no i mask val reg

  if ($# != 1) {
     if (CAN9635_NO == 1)
       mca_no = 0
     else
       mca_no = input ("MCA number as in the config: ")
    }
  else
    mca_no = $1

  if (_icb_read(mca_no, 2, 1,ICB) == 0) {
    reg = ICB[2]
    mask = 1
    p "Enter mode: "
    for (i=0; i<6; i++) {
       val = (mask&(ICB[2])>>2)>>i
       val = getval (sprintf ("\t0 (%s) - 1 (%s)",\
	CAN9635_MTAB [i][0], CAN9635_MTAB [i][1]),val)
       reg = _can9635_setreg(reg,i,val)
       mask <<= 1
      }
    ICB[2] = reg
    _icb_write(mca_no, 2, 1, ICB)
   }
  else
   p "Error setting the mode"
}'

#%IU% (reg, bit, value)
#%MDESC%Change to %B%value%B% the %B%bit%B% of the register %B%reg%B%.
#Return the reg value.
def _can9635_setreg(reg, bit, value) '{
  if (value == 1)
    reg = reg | (value << (bit+2))
  else if (value == 0)
    reg = reg & ~(1 << (bit+2))
  return (reg)
}'

#%IU% (mca_no)
#%MDESC% read the mode from the %B%mca_no%B% ADC. Return -1 if error,
#a string otherwise.
def _can9635_readmode(mca_no) '{
global CAN9635_MTAB
local mask bit mode

  CAN9635_MTAB [0][0]="LTC/PUR"; CAN9635_MTAB[0][1]="non-LTC/PUR"
  CAN9635_MTAB [1][0]="Overlapped"; CAN9635_MTAB[1][1]="Non-overlapped"
  CAN9635_MTAB [2][0]="Delayed"; CAN9635_MTAB[2][1]="Automatic"
  CAN9635_MTAB [3][0]="Late"; CAN9635_MTAB[3][1]="Early"
  CAN9635_MTAB [4][0]="Anticoincidence"
  CAN9635_MTAB[4][1]="Coincidence"
  CAN9635_MTAB [5][0]="SVA"; CAN9635_MTAB[5][1]="PHA"

  if (_icb_read(mca_no, 2, 1,ICB) < 0)
    return (-1)

  CAN9635_MODE[mca_no] = ""
  mask = 1
  for (bit = 0; bit<6; bit++) {
     CAN9635_MODE[mca_no] = sprintf("%s[%s] ", CAN9635_MODE[mca_no],\
	CAN9635_MTAB[bit][(mask&(ICB[2])>>2)>> bit])
     mask <<= 1
    }
  return(CAN9635_MODE[mca_no])
}'

#%UU% [mca_no]
#%MDESC% Read all parameters from the ADC.
def can9635read '{
local mca_no

  if ($# != 1) {
     if (CAN9635_NO == 1)
       mca_no = 0
     else
       mca_no = input ("MCA number as in the config: ")
    }
  else
    mca_no = $1

  _can9635read(mca_no)
}'

#%IU% (mca_no)
#%MDESC% Read all parameters from the %B%mca_no%B% ADC. Return -1 if error.
def _can9635read(mca_no) '{

  if (_icb_read(mca_no, 0, 13, ICB) < 0)
    return (-1)

  CAN9635_STATE[mca_no] =  ICB[0]
  CAN9635_GAIN[mca_no] = _can9635_conv_from_reg ("gain", ICB)
  CAN9635_RANGE[mca_no] = _can9635_conv_from_reg ("range", ICB)
  CAN9635_LLD[mca_no] = _can9635_conv_from_reg ("lld", ICB)
  CAN9635_ULD[mca_no] = _can9635_conv_from_reg ("uld", ICB)
  CAN9635_ZERO[mca_no] = _can9635_conv_from_reg ("zero", ICB)
  CAN9635_ADCGAIN[mca_no] = _can9635_conv_from_reg ("adc_gain", ICB)
  CAN9635_OFFSET[mca_no] = ICB[12]
  _can9635_readmode(mca_no)
  return (0)
}'

#%UU% [mca_no]
#%MDESC% Read and print all the parameters from the ADC.
def can9635status '{
local mca_no

  if ($# != 1) {
     if (CAN9635_NO == 1)
       mca_no = 0
     else
       mca_no = input ("MCA number as in the config: ")
    }
  else
    mca_no = $1

  printf ("Reading all parameters from ADC (ICB addr %d) MCA %s\n",\
	CAN9635_ICB_ADR[mca_no], CAN9635_DEV[mca_no])
  _can9635status(mca_no)

}'

#%IU% (mca_no)
#%MDESC% Read and print all parameters from the %B%mca_no%B% ADC.
def _can9635status(mca_no) '{
  if (_can9635read(mca_no) == 0) {
     printf("\n  Gain: %4d chan; Range: %4d chan;\n", \
	CAN9635_GAIN[mca_no] , CAN9635_RANGE[mca_no])
     printf("  LLD: %5.2f V;    ULD: %5.2f V;     Zero at: %.2f V;\n", \
        CAN9635_LLD[mca_no], CAN9635_ULD[mca_no], CAN9635_ZERO[mca_no])
     printf("  Offset: %4d;    ADC Gain: %3d;    State: %3d;\n",\
      CAN9635_OFFSET[mca_no], CAN9635_ADCGAIN[mca_no], CAN9635_STATE[mca_no])
     printf("  Mode: %s\n",CAN9635_MODE[mca_no])
   }
}'


#%IU% (type, value, reg_arr)
#%MDESC% convert to register contents from physical %B%value%B% depending of
#the %B%type%B% - "gain", "range", "lld", "uld", "zero" and "adc_gain".
#The result is written in %B%reg_arr%B% indexed by the number of the register.
def _can9635_conv_to_reg (type, value, reg_arr) '{

  if (type == "gain") {
    # GAIN 4096 RANGE 4096
    # register 3 range/offset [b0-b3]=gain [b4-b7]=range
    # [7-0] --> [256-32768]
    reg_arr[3] &= 0xf0
    reg_arr[3] |= (15 - log(value) / log(2)) & 0xf
  } else if (type == "range") {
    reg_arr[3] &= 0x0f
    reg_arr[3] |= ((15 - log(value) / log(2)) & 0xf) << 4
  } else if (type == "lld") {
    # register 4 [b0-b7]-->[d0-d7]
    # register 5 [b0-b3]-->[d8-d11]
    # 0->10V --> 0->4095
    reg_arr[4] = (value / 10 * 4095) & 0x00ff
    reg_arr[5] = ((value / 10 * 4095) & 0xff00) >> 8
  } else if (type == "uld") {
    # registre 6 [b0-b7]-->[d0-d7]
    # registre 7 [b0-b3]-->[d8-d11]
    # 0->10.5V --> 0->4095
    reg_arr[6] = (value / 10.5 * 4095) & 0x00ff
    reg_arr[7] = ((value / 10.5 * 4095) & 0xff00) >> 8
  } else if (type == "zero") {
    # registre 8 [b0-b7]-->[d0-d7]
    # registre 9 [b0-b3]-->[d8-d11]
    # -5-+5 --> 4095-0
    reg_arr[8] = ((5 - value) / 10 * 4095) & 0x00ff
    reg_arr[9] = (((5 - value) / 10 * 4095) & 0xff00) >> 8
  } else if (type == "adc_gain") {
    reg_arr[10] = value & 0x00ff
    reg_arr[11] = (value & 0xff00) >> 8
  }
}'

#%IU% (type, reg_arr)
#%MDESC% convert register content %B%reg_arr%B% to physical value, depending of
#the %B%type%B% - "gain", "range", "lld", "uld", "zero" or "adc_gain".
def _can9635_conv_from_reg (type, reg_arr) '{
  if (type == "gain") {
    # GAIN & RANGE 4096
    # register 3 gain/range [b0-b3]=gain [b4-b7]=range
    # [7-0] --> [256-32768]
    return (pow (2, 7 - reg_arr[3] & 0xf) * 256)
  } else if (type == "range") {
    return (pow (2, 7 - (reg_arr[3] >> 4) & 0xf) * 256)
  } else if (type == "lld") {
    # register 4 [b0-b7]-->[d0-d7]
    # register 5 [b0-b3]-->[d8-d11]
    # 0-10V --> 0-4095
    return ((reg_arr[4] + 256 * reg_arr[5]) / 4095 * 10)
  } else if (type == "uld") {
    # register 6 [b0-b7]-->[d0-d7]
    # register 7 [b0-b3]-->[d8-d11]
    # 0-10.5V --> 0-4095
    return ((reg_arr[6] + 256 * reg_arr[7]) / 4095 * 10.5)
  } else if (type == "zero") {
    # register 8 [b0-b7]-->[d0-d7]
    # register 9 [b0-b3]-->[d8-d11]
    # -5-+5 --> 4095-0
    return (5 - (reg_arr[8] + 256 * reg_arr[9]) / 4095 * 10)
  } else if (type == "adc_gain") {
    # register 10 [b0-b7]-->[d0-d7]
    # register 11 [b0-b3]-->[d8-d11]
    return (reg_arr[10] + 256 * reg_arr[11])
  }
}' 


#%IU% (mca_no, from_reg, no_reg, outarr)
#%MDESC% read values from the ICB bus for number of registers %B%no_reg%B%,
#starting from register number %B%from_reg%B% on MCA %B%mca_no%B% and put
#the result in the output array %B%outarr%B% . Return 0 if OK, -1 if error.
#The outarr is indexed with the number of the register (i.e. the value of
#register 7 is outarr[7]).
def _icb_read (mca_no, from_reg, no_reg, outarr) '{
  local i icb[] icbout[]
	
  icb[0] = no_reg
  for (i = 0 ; i < no_reg; i ++) 
    icb[i+1] = from_reg + i + 0x10*CAN9635_ICB_ADR[mca_no]

  if (CAN9635_DEV[mca_no]==mca_no) {
    for (i=0; i<no_reg; i++)
       icbout[i]= mca_spar(mca_no, "read", sprintf("?ICB %d", icb[i+1]))	
  }
  else {
    if (esrf_io(CAN9635_DEV[mca_no], "DevMcaReadICB", icb, icbout) < 0)
      return (-1)
  }

  for (i = 0; i < no_reg; i++)
    outarr[from_reg+i] = icbout[i]
  return (0)
}'


#%IU% (mca_no, from_reg, no_reg, inarr)
#%MDESC% write values from the input array %B%inarr%B% for number of
#registers %B%no_reg%B%, starting from register number %B%from_reg%B%
#on MCA %B%mca_no%B%. Return 0 if OK, -1 if error.
def _icb_write (mca_no, from_reg, no_reg, inarr) '{
local i icb[]
  icb[0] = no_reg 
  for (i = 0; i < no_reg; i++)  {
    icb[2*i + 1] = from_reg + i + 0x10*CAN9635_ICB_ADR[mca_no]
    icb[2*i + 2] = inarr[from_reg + i] 
  }

  if (CAN9635_DEV[mca_no]==mca_no) {
    for (i=0; i<no_reg; i++) {
      mca_spar(mca_no, "send", sprintf("ICB %d %d", icb[2*i+1], icb[2*i+2]))
    }
    return (0)
  }
  else 
    return (esrf_io(CAN9635_DEV[mca_no], "DevMcaSendICB", icb))
}'

#%IU% (nb_ch)
#%MDESC% set the number of channels %B%nb_ch%B% to be 256, 512, 1024,
#2048, 4096 or 8192 only.
def _nbch(nb_ch) '{
local shft
  if ((nb_ch <= 256) && (nb_ch > 0))
    return (256)
  if (nb_ch >= 8192)
    return (8192)
  shft = 13
  while (1) {
    if ((nb_ch > (1 << (shft-1))) && (nb_ch <= (1 << shft)))
       return (1 << shft)
    shft--;
   }
}'

#%MACROS%
#%IMACROS%
#%TOC%
#%AUTHOR%
#$Revision: 1.4 $, $Date: 2008/02/18 09:50:38 $