esrf

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

#%TITLE% piezo_gcs.mac $Revision: 1.2 $
#%NAME%
# Macros to control a KEPCO Bipolar amplifier powersupply connected via GPIB line.
#%DESCRIPTION%
#  This macro file allows to connect a kepco to  macro motors in SPEC.
#
#  %BR%Controllers currently supported are:
#%DL%
#%DT%kepco BOP 50-8M (GPIB)%DD%
#%XDL%
#
#  For debug purpose mainly, it's also possible to configure a macro
#  counter that will read the position of a kepco axis. But to avoid
#  duplicating parameters, the counter has no parameter and takes them
#  from its corresponding macro motor. In order to guess the motor
#  to use, the name of the counter must be the same as the motor with
#  %B%\"_c\"%B% added at the end.
#  For instance: %B%\"nnn_x_c\"%B% for %B%\"nnn_x\"%B%
#
#%END%
#
#%SETUP%
#  In order to configure a macro motor:
#  %DL%
#    %DT% 1)
#         You must have a "MOTORS" defined with:
#         %BR%
#         %DL%
#           %DT% DEVICE
#           set to "kepco"
#           %DT% TYPE
#           set to "Macro Motor"
#           %DT% ADDR
#           set to the GPIB_Address of the controller
#           %DT% NUM
#           must be set also
#         %XDL%
#    %DT% 2)
#         Per kepco axis you must define a motor with:
#         %BR%
#         %DL%
#           %DT% Controller
#           set to "MAC_MOT"
#           %DT% Unit
#           field must be set to the "MOTOR" entry.
#         %XDL%
#    %DT% 3)
#         In the config file add for %B%each%B% motor (%B%WARNING%B%: these
#         parameters are critical and can damage your hardware if wrong. They
#         are specific to each axis and not to the controller. Therefore
#         check with Electronics Group the value and %B%DO%B% %B%NOT%B%
#         copy/paste these values)
#         %BR%
#         %DL%
#           %DT%MOTPAR:source = vout|iout
#           Voltage source or Intensity source pseudo motor
#           %DT%MOTPAR:nada =
#         %XDL%
#
#  %XDL%
#
#  In order to configure a macro counter:
#  %DL%
#    %DT% 1)
#         You must have a "SCALERS" defined with:
#         %BR%
#         %DL%
#           %DT% DEVICE
#           set to "kepco_c"
#           %DT% TYPE
#           set to "Macro Counter"
#           %DT% NUM
#           must be set also
#         %XDL%
#    %DT% 2)
#         Per kepco axis you must define a counter with:
#         %BR%
#         %DL%
#           %DT% Device
#           set to "MAC_CNT"
#           %DT% Mnemonic
#           must the motor mne plus "_c"
#           %DT% Unit
#           do not mind
#           %DT% Chan
#           do not mind
#         %XDL%
#
#  %XDL%


#%END%
#
#%HISTORY%
#$Log: kepco.mac,v $
#Revision 1.2  2010/11/23 12:36:53  guilloud
#* test mode and set CURR or VOLT.
#
#Revision 1.1  2010/11/19 09:48:43  claustre
#Initial revision
#
#Revision
#Initial Revision
#
#
#%END%
#

constant KEPCO_HEAD "KEPCO BOP: "

global KEPCO[]
global KEPCO_C[]

#%UU% [personal msg]
#%MDESC%
# Switch on or off the print of debug messages
#
def kepcodebug '{
    global KEPCO[]

    if(KEPCO["debug"]) {
        rdef kepco__debug \'#\$#\'
        print KEPCO_HEAD"debug mode is OFF"
        KEPCO["debug"] = 0
    } else {
        rdef kepco__debug \'print "KEPCO BOP:","$*"\'
            print KEPCO_HEAD"debug mode is ON"
            KEPCO["debug"] = 1
    }
}'

# No debug by default
def kepco__debug \'#\$#\'


#%IU%
#%MDESC%
# Check if controller was well configured
#
def kepco_checkctl '{
    if(KEPCO["on"] != 1) {
        print KEPCO_HEAD"ERROR: no controller, try \"reconfig\""
        exit
    }
}'


#%IU%
#%MDESC%
# Convert channel from digit to single ASCII char
#
#def kepco_getch(ch) '{
#  local nr

#  if(ch==0) { nr="A" } else
#  if(ch==1) { nr="B" } else
#  if(ch==2) { nr="C" } else {
#   print KEPCO_HEAD"ERROR: \""mne"\" wrong channel, only 3 axis supported"
#   KEPCO["on"]=0
#   nr="?"
#  }
#  kepco__debug "channel : \""nr"\""
#  return nr
#}'



#%IU%
#%MDESC%
# MACRO MOTOR:
# Called by spec after reading the config file
#
def kepco_config(num,type,p1,p2,p3) '{
    global KEPCO[]

    # p1==?? p2==number of motors supported
    if(type=="ctrl") {
        local ver subver

        # check that the spec handles ADDR config parameter (i.e. >= 5.06.04-4)
        #  ver[0]=0
        #  split(VERSION,ver,".")
        #  split(ver[2],subver,"-")
        #  if((ver[0]<5) || (ver[1]<6) || (subver[0]<4) || (subver[1]<4)) {
        #   print KEPCO_HEAD"ERROR: upgrade your spec version"
        #   return
        #  }

        kepco__debug "config(): new controller"

        # check that the controller is switched on
        if(!gpib_cntl(kepco_ADDR,"responsive")) {
            print KEPCO_HEAD"ERROR: no controller found at address "kepco_ADDR
            KEPCO["on"]=0
            return
        }
        KEPCO["on"]=1

        if(KEPCO["kep"]=="CURR"){
            kepco__debug "config(): switch controller in current mode"
            gpib_put(kepco_ADDR,"FUNC:MODE CURR")
            sleep(0.1)
        }
        else if(KEPCO["kep"]=="VOLT"){
            kepco__debug "config(): switch controller in voltage mode"
            gpib_put(kepco_ADDR,"FUNC:MODE VOLT")
            sleep(0.1)
        }
        else {
            print "ERROR kepco_config : unknown mode :" KEPCO["kep"]
        }

        kepco__debug "config(): activate the output"
        gpib_put(kepco_ADDR,"OUTPUT ON")
    }


    # p1==unit p2==module p3==channel
    if(type=="mot") {
        local nr
        local mne
        local source
        local dev

        kepco_checkctl
        mne = motor_mne(num)

        # get and check piezo parameters for that axis
        source  = motor_par(num,"source")

        if(source == 0 ||( source != "vout" && source != "iout")) {
            print KEPCO_HEAD"ERROR: \""mne"\" wrong \"source\" parameter"
            print KEPCO_HEAD "Hint: check \"SETUP\" in \"help local kepco\""
            KEPCO["on"]=0
            return
        }

        if (source == "vout") {
            KEPCO[mne]= "VOLT"
        } else if (source == "iout") {
            KEPCO[mne]= "CURR"
        }

        # configure the axis
    }
}'



#%IU%(motor_num)
#%MDESC%
# MACRO MOTOR:
# return the position read from the controller
#
def kepco_getpos(num) '{
    local dev   ch    nr    aux   pos

    mne = motor_mne(num)
    dev = motor_par(num,"address")

    gpib_put(dev, sprintf("%s?", KEPCO[mne]))
    aux = gpib_get(dev, "")
    pos = aux + 0.0
    return(pos)
}'

#%IU%
#%MDESC%
# MACRO MOTOR:
# Called by spec on motor operation.
#
def kepco_cmd(num,key,p1,p2) '{
    local mne
    local addr
    local dev
    local ch
    local nr

    if(num == "..") { return }


    #
    # return the current motor position in mm or deg
    #
    if (key == "position") {
        local pos
        pos = kepco_getpos(num)
        kepco__debug "position() : pos    :  "pos" micron"
        return(pos)
    }


    #
    # start a motion (p1==abs pos, p2==rel pos, with pos in A or V)
    #
    if (key == "start_one") {
        local aux

        mne = motor_mne(num)
        dev = motor_par(num,"address")

        kepco__debug "start_one(): pos     :  "p1" KEPCO[mne]"
        gpib_put(dev, sprintf("%s %g\n", KEPCO[mne], p1))

        if((t=motor_par(num,"deadtime")) != 0) {
            kepco__debug "start_one(): sleeping:  "t" seconds"
            sleep(t)
        }
    }

    # stop a single motor
    #
    if (key == "abort_one") {

        kepco__debug "abort_one()"

        mne = motor_mne(num)
        dev = motor_par(num,"address")

        #  gpib_put(dev, sprintf("STP %s\n", nr))
        return
    }

}'



#%IU%
#%MDESC%
# MACRO MOTOR:
# Called by spec after reading the config file
#
def kepco_c_config(num,type,p1,p2,p3) '{
    global  KEPCO_C[]

    #
    #

    if(type=="ctrl") {
        KEPCO_C["on"]=1
    }

    #
    #
    #
    if(type=="cnt") {
        local mne
        local mot_mne mot_num

        mne=cnt_mne(num)
        mot_mne=substr(mne,1,index(mne,"_c")-1)
        if((mot_num=motor_num(mot_mne)) == -1) {
            print KEPCO_HEAD"ERROR: \""mne"\" invalid counter name"
            print "The name must the same as the motor name but with \"_c\" added"
            KEPCO_C["on"]=0
            return
        }
        KEPCO_C[mne]["mot_num"]=mot_num
    }
}'



#%IU%
#%MDESC%
# MACRO MOTOR:
# Called by spec on counter operation.
#
def kepco_c_cmd(num,key,p1,p2) '{
    global  KEPCO_C[]

    if (key == "counts") {
        local pos
        local mot_num
        local mne
        mne=cnt_mne(num)
        mot_num=KEPCO_C[mne]["mot_num"]
        pos = kepco_getpos(mot_num)
        return(pos)
    }
}'

#
#%MACROS%
#%IMACROS%
#%AUTHOR% L.C. BLISS 2006
#%TOC%