esrf

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

"""
#%TITLE% power_supply_scpi_mc.mac
#$Revision: 1.1 $
#%NAME%Macros for a the use of powersupplies, which use a SCPI protocol.
#%DESCRIPTION%
#%BR%
#Define a macro motor controller in config, ADDR is the TCP/IP or GPIB address.
#%BR%
#Now declare the motor controller:
#%BR% %BR%
# COUNTERS  DEVICE             ADDR   <>MODE   NUM           <>TYPE%BR%
#     YES   SCPIPS  deltaxxyyb:8462              2     Macro Motors
#%BR% %BR%
#Then declare a one or two counters with that controller.
#%END%
#NOTES:
#%PRE%
#*IDN? works fine.
#*RST resets power to 0, rather not!
#OUTP ON will switch the PS to a usable state.
#*OPC? operation completed ? Should be used for error catching. Then ask the status registers.
#For the motor mode, we chose to work in current mode. The voltage is kept
#constant by the power supply and limited to a maximum/minimum.
#Switch mode with FUNC:MODE CURR/VOLT.
#Then protect the ps and the magnet with a VOLT:PROT 10 (10 volt is max/min).
#One can set the minimum separately, but we should use both + and -.

#$Log: power_supply_scpi_mh.mac,v $
#Revision 1.1  2015/07/07 15:15:31  witsch
#Initial revision
#
#Revision 1.1  2015/07/07 15:14:46  witsch
#Initial revision
#
"""

if (!(whatis("__scpips_debug")  & 2)) rdef __scpips_debug \'#$*\'
if (!(whatis("__scpips_io")  & 2)) rdef __scpips_io() \'print "Please reconfig"\'
if (!(whatis("__scpips_put")  & 2)) rdef __scpips_put() \'print "Please reconfig"\'

#%UU%
#%MDESC% toggle debug mode for the present macros.
def scpips_debug '{
    if ((whatis("__scpips_debug")>>16) <= 4) { # just a # sign -> off
    rdef __scpips_debug "eprint"
        print "scpips debug is ON"
    } else {
    rdef __scpips_debug \'#$*\'
        print "scpips debug is OFF"
    }
}
'

#%IU%(obj, type, unit, mod, chan)
#%MDESC%Called by spec
def SCPIPS_config(obj, type, unit, mod, chan) '{
    __scpips_debug "SCPIPS config", obj, type, unit, mod, chan
    __scpips_debug "SCPIPS_ADDR=" SCPIPS_ADDR
    global __SCPIPS[]
    delete __SCPIPS["error"]
    local  answer, ident
    if (obj == "..") {
        # work out, what kind of connection we have: GPIB eg. 1:13
        # or TCP/IP, with a IP address/name and port, eg. deltaid06b:8462
        local aux[]
        if (split(SCPIPS_ADDR, aux, ":") != 2 ) {
            # that could just be a single number as a GPIB address with controller 0
            rdef __scpips_put \'__scpips_gpib_put\'
            rdef __scpips_io  \'__scpips_gpib_io\'
        } else
            if (((aux[0] * 1) != 0) && (aux[1] < 32)) {
                # that looks like GPIB
                rdef __scpips_put \'__scpips_gpib_put\'
                rdef __scpips_io  \'__scpips_gpib_io\'
            } else {
                rdef __scpips_put \'__scpips_tcp_put\'
                rdef __scpips_io  \'__scpips_tcp_io\'
            }

        if ((answer = __scpips_io(SCPIPS_ADDR, "*IDN?")) == "") {
            eprint "No connection with the SCPI power supply!"
            return(".error.")
        }
        else {
            print "SCPI Power Supply:", answer
        }
    }
}
'


#%IU%(mne, key, p1, p2, p3)
#%MDESC%Called by spec
def SCPIPS_cmd(mne, key, p1, p2, p3) '{
    __scpips_debug "SCPIPS command", mne, key, p1, p2, p3
    if (mne == "..") {
        return
    }
    local str, addr
    if (key == "counts") { # this is for the counter

        local chan, what
        chan = counter_par(mne, "channel")
        __scpips_debug "channel", chan
        if (chan == 0) {
            what = "voltage"
        } else if (chan == 1) {
            what = "current"
        } else {
            return ".error."
        }
        str = "meas:" what "?"
        __scpips_debug "command:", str
        answer = __scpips_io(SCPIPS_ADDR, str)
        __scpips_debug "answer", answer
        return(answer)
    }
}
'

#%IU%(addr, cmd)
#%MDESC% Called by spec, write command to controller and read answer.
def __scpips_gpib_io(addr, cmd) '{
    __scpips_debug "__scpips_gpib_io(\"" addr "\", \"" cmd "\")"
    if (__scpips_gpib_put(addr, cmd) == ".error.") {
        return(".error.")
    }
    local i, x, str, answer, error, aux[]
    if ((answer = gpib_get(addr, "\n")) == -1) {
        return(".error.")
    }
    # the answer can sometimes be
    #  000,"no error". Of course with the   at the beginning, the string
    # becomes empty in the sense of spec.
    if (__scpips_gpib_put(addr, "SYSTem:ERRor?") == ".error.") {
        return(".error.")
    }
    if ((errors = gpib_get(addr, "\n")) == -1) {
        return(".error.")
    }
    if (split(errors, aux, ",") == 2) {
        if (aux[0] != 0) {
            eprint "scpips PS ERROR:", aux[1]
            __SCPIPS["error"] = aux[0]
            return(".error.")
        }
    }
    __scpips_debug "Answer is", answer
    return(answer)
}
'


#%IU%(addr, cmd)
#%MDESC% Called by spec, write command to controller, no answer expected.
def __scpips_gpib_put(addr, cmd) '{
    local str
    str = cmd "\r\n"
    __scpips_debug "__scpips_gpib_put(\"" addr "\", \"" cmd "\")"
    if ((answ = gpib_put(addr, str)) == -1) {
        return(".error.")
    }
    return 0
}
'

#%IU%(addr, cmd)
#%MDESC% Called by spec, write command to controller and read answer.
def __scpips_tcp_io(addr, cmd) '{
    __scpips_debug "__scpips_tcp_io(\"" addr "\", \"" cmd "\")"
    if (__scpips_tcp_put(addr, cmd) == ".error.") {
        # if macro can`t write to socket, just return an error
        return(".error.")
    }
    local i, x, str, answer, error, aux[]
    if ((answer = sock_get(addr, "\n")) == "") {
        # if macro can`t read from socket, then we need to find out
        # if there is an error.
        if (__scpips_tcp_put(addr, "SYSTem:ERRor?") == ".error.") {
            return(".error.")
        }
        if ((errors = sock_get(addr, "\n")) == "") {
            # if macro can`t read answer from error commands
            # we`re really stuck, just return an error
            return(".error.")
        }
        __scpips_debug "Error answer:", errors
        if (split(errors, aux, ",") == 2) {
            if (aux[0] != 0) {
                eprint "scpips PS ERROR:", aux[1]
                __SCPIPS["error"] = aux[0]
                return(".error.")
            }
        }
    }
    __scpips_debug answer
    return(answer)
}
'


#%IU%(addr, cmd)
#%MDESC% Called by spec, write command to controller, no answer expected.
def __scpips_tcp_put(addr, cmd) '{
    local str
    str = cmd "\r\n"
    __scpips_debug "__scpips_tcp_put(\"" addr "\", \"" cmd "\")"
    if (sock_put(addr, str) == -1) {
        return(".error.")
    }
    return 0
}
'

"""
# this is an attempt to come around the problem with the macro motor macros
# being loaded at the end of the config/setup, thus not executing the
# SCPIPS_config function. Variable remain uninitialised. We need a reconfig
if (!whatis("__SCPIPS")) {
    eprint "\n\n\n"
    eprint "***************************************************************"
    eprint "Make sure to do a reconfig for the SCPIPS power supply macros!!!"
    eprint "***************************************************************"
    eprint "\n\n\n"
}
"""


#%MACROS%
#%IMACROS%
#%END%
#%BUGS% Bugs ? What bugs ??
#%AUTHOR%
#Holger (BLISS)
#%TOC%