esrf

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

#Macros to control a Keithley 428 current amplifier

#%NAME%
# ID21K428.MAC - Macros to control a Keithley 428 current amplifier via GPIB
#%DESCRIPTION%
#  This macro file allows definition and control of the Keithley 428 in SPEC.
#  As this is implemented at the macro level not all commands will work
#%EXAMPLE%
#%DL%
#%DT%  k428add : add a k428 with the parameters
#                   * mnemonic
#                   * gpib addr
#%XDL%
#%END%

#%UU% [K428 mnemonic name] [k428 gpib addr]
#%MDESC% Adds the given K428 to the already defined K428 amplifiers
#
def k428_setup '{
    global K428_LIST
    global K428_SILENT

    list_test K428_LIST
}'

#%UU% k428-mnemonic k428-gpib-address
#%MDESC%
#   Add definitions for a 428 amplifier
def k428add  'k428_add("$1", "$2")'


#%IU% (k428-mnemonic,k428-gpibaddr)
#%MDESC%
#   Add definitions for a k428 amplifier
def k428_add(mne, gpibaddr) '{
    local fnId ; fnId = "k428_add"
    local n, arr ret
    n = split(gpibaddr, arr, ":")
    if (n != 2) {
        printf("%s> ERROR gpibadd must be \"unit:address\" (quotes required) [%s]\n", \
            fnId, gpibaddr)
    }

    if (k428_exists(gpibaddr) != -1) {
        if (list_check(K428_LIST, mne) == 0) {
            list_add(K428_LIST,mne)
        }

        list_setpar(K428_LIST,mne,"gpibaddr",gpibaddr)
        list_setpar(K428_LIST, mne, "enable", 1)

        ret = k428_read(mne)

        if (ret == -1) {
            list_setpar(K428_LIST, mne, "enable", 0)
        }

        setup_tail("k428", sprintf("k428_%s %s", mne, mne))
    } else {
        printf("K428 amplifier is not connected to gpib addr. \"%s\"\n", gpibaddr)
        exit
    }
}'

def k428unsetup '{
    list_remove(K428_LIST, "$2")
}'

def k428_exists(gpibaddr) '{
    local k428_addr

    k428_addr = gpibaddr+0
    return(gpib_put(k428_addr, "U4X"))
}'

def k428_read(mne) '{
    local k428_str k428_addr

    if (!k428_isconfig(mne) || !k428_isenable(mne)) {
        return(-1)
    }

    k428_addr = list_getpar(K428_LIST, mne, "gpibaddr")+0
    k428_str = gpib_get(k428_addr)
    list_setpar(K428_LIST,mne,"current",k428_str)
    k428_str = gpib_put(k428_addr, "U0X")
    if (k428_str == "-1") {
        printf("Cannot access K428 \"%s\"  at address \"%d\"", mne, k428_addr)
    } else {
        k428_str = gpib_get(k428_addr)
        k428_str = substr(k428_str, \
                  index(k428_str,"C")+1, \
                  length(k428_str)-index(k428_str,"C"))
        list_setpar(K428_LIST,mne,"zerocheck",substr(k428_str,0,1))
        k428_str = substr(k428_str, \
                  index(k428_str,"P")+1, \
                  length(k428_str)-index(k428_str,"P"))
        list_setpar(K428_LIST,mne,"filteronoff",substr(k428_str,0,1))
        k428_str = substr(k428_str, \
                  index(k428_str,"R")+1, \
                  length(k428_str)-index(k428_str,"R"))
        k428_aux = substr(k428_str,0,2)
        if (index(k428_aux, "0") == 1)
          k428_aux = substr(k428_aux, 2,1)
        list_setpar(K428_LIST,mne,"gain",k428_aux+0)
        k428_str = substr(k428_str, \
                  index(k428_str,"T")+1, \
                  length(k428_str)-index(k428_str,"T"))
        k428_aux = substr(k428_str,1,1)
        list_setpar(K428_LIST,mne,"risetime",k428_aux+0)
        k428_str = substr(k428_str, \
                  index(k428_str,"W")+1, \
                  length(k428_str)-index(k428_str,"W"))
        list_setpar(K428_LIST,mne,"x10gainonoff",substr(k428_str,0,1))
    }
}'

def k428getallparam(mne) '{
    global res_k428param[]

    k428_read(mne)
    res_k428param[0] = list_getpar(K428_LIST,mne,"gain")
    res_k428param[1] = list_getpar(K428_LIST,mne,"x10gainonoff")
    res_k428param[2] = list_getpar(K428_LIST,mne,"filteronoff")
    res_k428param[3] = list_getpar(K428_LIST,mne,"risetime")
    res_k428param[5] = list_getpar(K428_LIST,mne,"zerocheck")
}'


def k428setparam '{
  local k428_mne k428_comm k428_val
    global K428_sup K428_gain K428_refgain K428_refoffset

    if (($# != 3)&&($# != 2)) {
        p "Usage: k428setparam [k428 mne.] [parameter] [value]"
        p "       parameters                 value"
        p "       0 => set gain              3->10 (10e3->10e10)"
        p "       1 => x10 gain on/off       1/0"
        p "       2 => filter on/off         1/0"
        p "       3 => set filter rise time  0..9"
        p "                                  (10us 30us 100us 300us "
        p "                                  1ms 3ms 10ms 30 ms 100ms 300ms) "
        p "       4 => zero correct          none"
        p "       5 => zero check on/off     1/0"
        p "       6 => current suppress       off(0)/on(1)/auto(2)"
        exit
    }

      k428_mne = "$1"
      k428_comm = $2
      k428_val = $3


    if (k428_isconfig(k428_mne) && k428_isenable(k428_mne))
        _k428setparam(k428_mne, k428_comm, k428_val)
}'

def _k428setparam(k428_mne, k428_comm, k428_val) '{
    local k428_addr

    k428_addr = list_getpar(K428_LIST, k428_mne, "gpibaddr")

    if (k428_comm == 0) {
        if ((k428_val < 3) || (k428_val >= 11)) {
          printf("gain must be an integer between 3 and 10\n")
          exit
        }
        k428_gain = k428_val
        k428_str = sprintf("R%dX", int(k428_val))
        if (gpib_put(k428_addr, k428_str) == -1) {
          printf("k428 \"%s\" did not answer\n", k428_mne)
          exit
        }

        #   in any case, controller will ignore if any
        k428_refgain =  list_getpar(K428_LIST,k428_mne,"refgain")
        k428_refoffset =  list_getpar(K428_LIST,k428_mne,"refoffset")

        if ( k428_refgain > 0) {
            _k428_val = k428_refgain - k428_gain
            _k428_newcur = k428_refoffset * exp10(_k428_val)
            list_setpar(K428_LIST,k428_mne,"offset",_k428_newcur)
            k428_str = sprintf("S%g,0X", _k428_newcur)
            if (!K428_SILENT) {
                print "setting  offset " _k428_newcur " for keithley " k428_mne
            }
            if (gpib_put(k428_addr, k428_str) == -1) {
                printf("k428 \"%s\" did not answer\n", k428_mne)
                exit
            }
        }
    }

    if (k428_comm == 1) {
        if ((k428_val != 0) && (k428_val != 1)) {
          printf("x10 gain on/off values are 1 or 0\n")
          exit
        }
        k428_str = sprintf("W%dX", k428_val)
        if (gpib_put(k428_addr, k428_str) == -1) {
          printf("k428 \"%s\" did not answer\n", k428_mne)
          exit
        }
    }

    if (k428_comm == 2) {
        if ((k428_val != 0) && (k428_val != 1)) {
            printf("filter on/off values are 1 or 0\n")
            exit
        }
        k428_str = sprintf("P%dX", k428_val)
        if (gpib_put(k428_addr, k428_str) == -1) {
            printf("k428 \"%s\" did not answer\n", k428_mne)
            exit
        }
    }

    if (k428_comm == 3) {
        if ((k428_val < 0) || (k428_val >= 10)) {
            printf("rise time value is an integer between 0 and 9\n")
            exit
        }
        k428_str = sprintf("T%dX", int(k428_val))
        if (gpib_put(k428_addr, k428_str) == -1) {
            printf("k428 \"%s\" did not answer\n", k428_mne)
            exit
        }
    }

    if (k428_comm == 4) {
        if (gpib_put(k428_addr, "C2X") == -1) {
            printf("k428 \"%s\" did not answer\n", k428_mne)
            exit
        }
    }

    if (k428_comm == 5) {
        if ((k428_val != 0) && (k428_val != 1)) {
            printf("zero check on/off values are 1 or 0\n")
            exit
        }
        K428_sup = k428_val
        k428_str = sprintf("C%dX", k428_val)
        if (gpib_put(k428_addr, k428_str) == -1) {
            printf("k428 \"%s\" did not answer\n", k428_mne)
            exit
        }
    }

    if (k428_comm == 6) {
        if ((k428_val != 0) && (k428_val != 1) && (k428_val != 2)) {
            printf("current suppress values are values are 0, 1 or 2\n")
            exit
        }
        K428_sup = k428_val
        k428_str = sprintf("N%d", k428_val)
        if (gpib_put(k428_addr, k428_str) == -1) {
        printf("k428 \"%s\" did not answer\n", k428_mne)
        exit
        }
    }

    if (!K428_SILENT) {
        k428_read(k428_mne)
        printf("   Mnem. gpibaddr  gain  10xgain  filt.  filt.risetime  0check Suppress Current\n\n")
        k428singleshow(k428_mne)
    }

}'

def k428show '{
    local k428_n k428_offs
    global K428_gain

    k428_n = list_n(K428_LIST)
    if (k428_n != 0) {
        printf("   Mnem. gpibaddr  gain  10xgain  filt.  filt.risetime  0check Suppress Current\n\n")
        for (i=1;i<=k428_n;i++) {
            k428_mne = list_item(K428_LIST, i)
            k428singleshow(k428_mne)
        }
    } else {
        printf("No k428 Amplifier defined\n")
    }
}'

def k428singleshow(k428_mne)'{
    local k428_n k428_offs

    k428_read(k428_mne)
    k428_addr = list_getpar(K428_LIST, k428_mne, "gpibaddr")

    if (list_getpar(K428_LIST,k428_mne,"zerocheck") == 0) {        k428_0ch  = "OFF"
    } else if (list_getpar(K428_LIST,k428_mne,"zerocheck") == 1) {
        k428_0ch  = "ON"
    } else {
        k428_0ch = "0 Corr."
    }

    if (list_getpar(K428_LIST,k428_mne,"suppress") == 0) {
        k428_sup  = "OFF"
    } else if (list_getpar(K428_LIST,k428_mne,"suppress") == 1) {
        k428_sup  = "ON"
    } else if (list_getpar(K428_LIST,k428_mne,"suppress") == 2) {
        k428_sup  = "AUTO"
    } else {
        k428_sup = "?"
    }

    k428_filt = (list_getpar(K428_LIST,k428_mne,"filteronoff")==0?"OFF":"ON")
    k428_gain = sprintf("10e%d",list_getpar(K428_LIST,k428_mne,"gain"))
    k428_rt   =k428_getrisetimestr(list_getpar(K428_LIST,k428_mne,"risetime"))
    k428_x10g = (list_getpar(K428_LIST,k428_mne,"x10gainonoff")==0?"OFF":"ON")
    k428_curr = sprintf("%s",list_getpar(K428_LIST,k428_mne,"current"))
    k428_offs =  list_getpar(K428_LIST,k428_mne,"offset")
    printf("%8s       %2d  %4s      %3s    %3s          %5s     %3s  %4s %13s\n", \
        k428_mne, k428_addr, k428_gain, k428_x10g, k428_filt, k428_rt, \
        k428_0ch,k428_sup,k428_curr)
    K428_gain = list_getpar(K428_LIST,k428_mne,"gain")
}'

def k428_getrisetimestr(val) '{

    if (val == 0)
       return("10us")

    if (val == 1)
       return("30us")

    if (val == 2)
       return("100us")

    if (val == 3)
       return("300us")

    if (val == 4)
       return("1ms")

    if (val == 5)
       return("3ms")

    if (val == 6)
       return("10ms")

    if (val == 7)
       return("30ms")

    if (val == 8)
       return("100ms")

    if (val == 9)
       return("300ms")
}'

#%UU% <mne> <gain> <value>
#MDESC%
# this is the offset current to apply, according to that gain.
#%BR% For the other gain, a multiple factor will be applied (factor of 10
# if gain+1, factor of 100 if gain+2 ... divide by 10 if gain-1 ...)
def k428_offset'{
    local k428_refgain k428_refoffset k428_gain k428_offs
    local _k428_val  _k428_val1 _k428_newcur k428_str k428_mne k428_str
    local k428_addr


    if ($# != 3) {
        p "you must provide : <mne> <gain> <value>"
        exit
    }

    k428_mne = "$1"
    k428_refgain = $2
    k428_refoffset = $3

    if (k428_isconfig(k428_mne) && k428_isenable(k428_mne)) {

        if ((k428_refgain < 3) || (k428_refgain >= 11)) {
            printf("gain must be an integer between 3 and 10\n")
            exit
        }

        list_setpar(K428_LIST,k428_mne,"refgain",k428_refgain)
        list_setpar(K428_LIST,k428_mne,"refoffset",k428_refoffset)

        k428_read(k428_mne)
        k428_gain = list_getpar(K428_LIST,k428_mne,"gain")

        _k428_val = k428_refgain - k428_gain
        _k428_newcur = k428_refoffset * exp10(_k428_val)
        k428_offs = _k428_newcur
        list_setpar(K428_LIST,k428_mne,"offset",k428_offs)

        #  apply it anyway
        k428_addr = list_getpar(K428_LIST, k428_mne, "gpibaddr")
        k428_str = sprintf("S%g,0X", _k428_newcur)
        if (gpib_put(k428_addr, k428_str) == -1) {
            printf("k428 \"%s\" did not answer\n", k428_mne)
            exit
        }
    }
}'

def k428_scan_header'{
  local k428_n ii k428_mne k428_addr k428_gain k428_sup k428_cur

  k428_n = list_n(K428_LIST)
  for (ii=1; ii<=k428_n; ii++) {
      k428_mne = list_item(K428_LIST, ii)
      k428_read(k428_mne)
      k428_addr = list_getpar(K428_LIST, k428_mne, "gpibaddr")
      k428_gain = list_getpar(K428_LIST, k428_mne, "gain")
      k428_sup = list_getpar(K428_LIST, k428_mne, "suppress")
      k428_cur =  list_getpar(K428_LIST, k428_mne, "current")
     printf("#C keithley %s %s %d %s\n",k428_mne,k428_gain,k428_sup,k428_cur)
  }

}'

def k428scanon'{
   cdef ("Fheader","k428_scan_header;","_k428")
}'

def k428scanoff'{
   cdef ("Fheader","","_k428","delete")
}'

def k428_isconfig(mne) '{
    return (list_check(K428_LIST, mne))
}'

def k428_isenable(mne) '{
    return (list_getpar(K428_LIST, mne, "enable"))
}'