esrf

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

#%TITLE% newport_agilis.mac
#%NAME% newport_agilis.mac - Macros to control the Newport Agilis piezo
# motor controller AG-M100. This one has been modified to be connected to a
# serial line. Normally, they have only USB.
#$Revision: 1.0 $
#%DESCRIPTION%
# First declare a serial line
#\0SERIAL\0\0\0\0\0\0\0\0DEVICE\0<>TYPE\0\0<>BAUD\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0<>MODE
#\00\0\0YES\0\0\0\0/dev/ttyS0\0\0\0\0\0<>\0\0115200\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0raw
#%BR%
# To define a macro motor controller you must define 
# a motor controller in config, ADDR is the serial line index number.
#
#\0\0\0MOTORS\0\0\0\0\0\0\0DEVICE\0\0\0\0ADDR\0\0\0<>MODE\0\0\0\0\0\0NUM\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0<>TYPE
#\0\0\0\0\0\0YES\0\0\0\0\0\0\0laser\0\0\0\0\04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\01\0\0\0\0\0\0\0\0\0\0Macro\0Motors
#
# Then declare a motor with that controller.
#
#%B%make\0this\0window\0bigger\0for\0better\0reading!%B%

#%SETUP%
# The defaults for the serial line :%BR%
# Baud Rate = 115200%BR%
# Data Bits = 8%BR%
# Parity = None%BR%
# Stop Bits = 1%BR%
# Flow Control = None%BR%
# Termination Character = CR/LF%BR%
#%END%


need spec_utils


#-----------------------------------------------------------
#%IU%()
#%MDESC% Setting a couple of preset values. 
def __agilis_globals() '{
    global __AGILIS_ERRORS[], __AGILIS_STATUS[]

    __AGILIS_ERRORS["CC"]["-1"] = "Unknown command (only available on AG-UC8)."
    __AGILIS_ERRORS["CC"]["-2"] = "Must not specify any channel."
    __AGILIS_ERRORS["CC"]["-3"] = "Wrong format for nn (must be integer)."
    __AGILIS_ERRORS["CC"]["-4"] = "Wrong value for nn (must be between 0 and 4 included)."
    __AGILIS_ERRORS["CC"]["-5"] = "Not allowed in local mode (controller must be in remote)."
    __AGILIS_ERRORS["CC"]["-6"] = "Not allowed state (both axes must be in state 0)."

    __AGILIS_ERRORS["MR"]["-2"] = "Axis must not be specified."
    __AGILIS_ERRORS["MR"]["-3"] = "Parameter must not be specified."
    __AGILIS_ERRORS["MR"]["-6"] = "The two axis must be in state 0."

    __AGILIS_ERRORS["PR"]["-2"] = "Axis out of range (must be 1 or 2)."
    __AGILIS_ERRORS["PR"]["-3"] = "Wrong format for nn (must be integer)."
    __AGILIS_ERRORS["PR"]["-5"] = "Not allowed in local mode (controller must be in remote mode)."
    __AGILIS_ERRORS["PR"]["-6"] = "Not allowed state (controller must be in state 0)."

    __AGILIS_ERRORS["RS"]["-2"] = "Axis must not be specified."
    __AGILIS_ERRORS["RS"]["-3"] = "Parameter must not be specified."

    __AGILIS_ERRORS["SU"]["-2"] = "Axis out of range (must be 1 or 2)."
    __AGILIS_ERRORS["SU"]["-3"] = "Wrong format for nn (must be integer)."
    __AGILIS_ERRORS["SU"]["-4"] = "Wrong value for nn (must be an integer between -50 and 50, not zero)."
    __AGILIS_ERRORS["SU"]["-5"] = "Not allowed in local mode (controller must be in remote mode)"
    __AGILIS_ERRORS["SU"]["-6"] = "Not allowed state (controller must be in state 0)"

    __AGILIS_ERRORS["ST"]["-2"] = "Axis out of range (must be 1 or 2)."
    __AGILIS_ERRORS["ST"]["-3"] = "Parameter must not be specified."
    __AGILIS_ERRORS["ST"]["-5"] = "Not allowed in local mode (controller must be in remote mode)."

    __AGILIS_ERRORS["TS"]["-3"] = "Parameter must not be specified."

    __AGILIS_ERRORS["TP"]["-2"] = "Axis out of range (must be 1 or 2)."
    __AGILIS_ERRORS["TP"]["-3"] = "Parameter must not be specified."
    __AGILIS_ERRORS["TP"]["-5"] = "Not allowed in local mode (controller must be in remote mode)."
    __AGILIS_ERRORS["TP"]["-6"] = "Not allowed state (axis must not be in state 3)."

    __AGILIS_STATUS["TS"]["1"]  = "Stepping (currently executing a PR command)"
    __AGILIS_STATUS["TS"]["2"]  = "Jogging (currently executing a JA command with command parameter different than 0)."
    __AGILIS_STATUS["TS"]["3"]  = "Moving to limit (currently executing MV, MA, PA commands)"
}
'

# leave those macros alone, if they`re already defined.
if (!(whatis("__npagilisdebug") & 2)) rdef __npagilisdebug \'#$*\'
if (!(whatis("__agilis_simu") & 2)) rdef __agilis_simu \'#$*\'

#%UU%
#%MDESC% toggle debug mode for the present macros.
def agilis_debug '{
    if ((whatis("__npagilisdebug")>>16) <= 5) { # just a # sign -> off
        rdef __npagilisdebug "eprint \"Agilis: \", "
        print "agilis debug is ON"
    } else {
        rdef __npagilisdebug \'#$*\'
        print "agilis debug is OFF"
    }
}
'

#%UU%
#%MDESC% toggle simulation mode for the present macros.
def agilis_sim '{
    local onoff
    if ((whatis("__agilis_simu")>>16) >= 5) {
        unglobal  __AGILIS
        cdef("prompt_mac","","agilis_simu", "delete")
        rdef __agilis_simu \'#$*\'
        onoff = 0
    }
    else {
        global __AGILIS[]
        __AGILIS[1]["SU"] = 16
        __AGILIS[2]["SU"] = 16
        cdef("prompt_mac",\
         "tty_cntl(\"md\");printf(\"AGILIS simulation\"); tty_cntl(\"me\");",\
            "agilis_simu")
        rdef __agilis_simu \'return __agilis_simulation\'
        onoff = 1
    }
    print "agilis simulation is", onoff ? "on" : "off"
}
'



#-----------------------------------------------------------
#%IU%(addr)
#%MDESC% Setting a couple of preset values. Device and controller ID.
def __agilis_set_serial_parameters(addr) '{
    global ESRF_ERR

    local __tab[], macro, func
    macro = "newport_agilis.mac"
    func  = "__agilis_set_serial_parameters()"

    __npagilisdebug "Setting serial line parameters", addr
    __agilis_simu()
    if (ser_par(addr, "timeout=1,baud=115200,stop_bits=1,data_bits=8")\
         == -1) {
        local __errstr
        __errstr = macro " ---> " func 
        __errstr = __errstr " --> ERROR --> ser_par: Can`t set serial "
        __errstr = __errstr "parameters."
        __agilis_err(__errstr)
    }
    return(0)
}
'

def __agilis_err(__errstr) '{
    __errstr = __errstr "\n"
    cprint(__errstr, 3, 1, 1)
}
'


def __agilis_put(addr, send) '{
    __agilis_simu(send)
    local nchar, str
    local cmd, macro, func
    macro   =   "newport_agilis.mac"
    func    =   "__agilis_put()"
    str     =   send "\r\n"
    __npagilisdebug func, send
    nchar = ser_put(addr, str)
    if (length(str) != nchar) {
        local __errstr
        __errstr = macro " ---> " func " --> ERROR --> ser_put(" 
        __errstr = __errstr addr ", "  send ") Not enough characters sent!"
        __agilis_err(__errstr)
        return ".error."
    }
}
'

def __agilis_get(addr) '{
    __agilis_simu()
    local __l, cmd, macro, func, retval, chksum, loops, __answer
    macro   =   "newport_agilis.mac"
    func    =   "__agilis_get()"
    loops   = 200
    __npagilisdebug func
    __answer = ser_get(addr, "\r\n")
    if (__answer == -1) {
        local __errstr
        __errstr = macro " ---> " func " --> ERROR --> ser_put(" 
        __errstr = __errstr addr ", \"\\r\\n\")"
        __agilis_err(__errstr)
        return ".error."
    }
    # cut off \r\n
    __answer = substr(__answer, 1, length(__answer) -2)
    __npagilisdebug "answer: \"" __answer "\""
    return __answer
}
'

#%IU%(addr, send)
#%MDESC%
def __agilis_putget(addr, send) '{
    __agilis_simu(send)
    local macro, func, retval, __answer, __error, __errstr

    macro   =   "newport_agilis.mac"
    func    =   "__agilis_putget()"
    __npagilisdebug func, send

    if (__agilis_put(addr, send) == ".error.") {
        __errstr = macro " ---> " func " --> ERROR --> couldn`t send!"
        __agilis_err(__errstr)
        return ".error."
    }

    if ((__answer = __agilis_get(addr)) == ".error.") {
        __errstr = macro " ---> " func " --> ERROR --> no answer"
        __agilis_err(__errstr)
        return ".error."
    }

    __npagilisdebug func, "answer: ", __answer
    return __answer
}
'


#%IU%(addr, send)
#%MDESC%Does the packing of the command with the checksum and the unpacking of
# the answer.
def __agilis_checkerror(addr, cmd) '{
    local macro, func, retval, __answer, __error, __errstr

    macro   =   "newport_agilis.mac"
    func    =   "__agilis_checkerror()"
    __npagilisdebug func, cmd

    if (__agilis_put(addr, "TE") == ".error.") {
        __errstr = macro " ---> " func " --> ERROR --> couldn`t send \"TE\"!"
        __agilis_err(__errstr)
        return ".error."
    }

    if ((__error = __agilis_get(addr)) == ".error.") {
        __errstr = macro " ---> " func " --> ERROR --> no answer after \"TE\""
        __agilis_err(__errstr)
        return ".error."
    }

    __npagilisdebug "__error is \"" __error "\""
    if (__error == "TE0") {
        return
    }
    else {
        __error  = substr(__error, 3)
        __errstr = "Agilis: ERROR on " cmd " " __AGILIS_ERRORS[cmd][__error]
        __agilis_err(__errstr)
        return ".error."
    }
}
'


def __agilis_simulation(send) '{
    __npagilisdebug "__agilis_simu", send
    local __cmd chan __answer
    __answer = ""
    __AGILIS["last"]    =   send
    if (send == "")     return "0"
    if (send == "TS")   return "0"
    if (send == "TE")   return "0"
    if (send == "MR")   return ""

    if (index(send, "CC") == 1) {
        __AGILIS["crtl"] = substr(send,1,1)
        return ""
    }
    chan = substr(send,1,1)
    __npagilisdebug "__agilis_simu channel", chan
    if (index(send, "PR") == 2) {
        __AGILIS[chan]["posi"] = substr(send, 4)
        __npagilisdebug "\t\tposition is", __AGILIS[chan]["posi"]
    }
    if (index(send, "TP") == 2) {
        __answer = __AGILIS[chan]["posi"]
        __npagilisdebug "\t\treturned position is", __AGILIS[chan]["posi"]
    }
    if (index(send, "SU") == 2) {
        if (substr(send,4,1) == "+") {
            __answer    = __AGILIS[chan]["SU"]
        }
        else {
            __AGILIS[chan]["SU"] = substr(send,4)
        }
    }
    __npagilisdebug "\t\tanswer is", __answer
    return __answer
}
'

#%IU%
#%DESC% 
def __agilis_status(addr, axis, quiet) '{
    local __cmd, __answer, __errstr
    local macro, func, __errstr
    macro   =   "newport_agilis.mac"
    func    =   "__agilis_status()"
    __cmd   =   axis "TS"
    __npagilisdebug "agilis_status: "
    __answer = __agilis_putget(addr, __cmd)
    if (__answer == ".error.") {
        __errstr = macro " ---> " func 
        __errstr = __errstr " --> ERROR on \"TS\"."
        __agilis_err(__errstr)
        return ".error."
    }
    __answer = substr(__answer, 4)
    __npagilisdebug "agilis_status: answer is", __answer
    if (quiet) return __answer
    if (__answer == "0") {
        return 0
    }
    else {
        __errstr = macro " ---> " func " --> Status: "
        __errstr = __errstr __AGILIS_STATUS["TS"][__answer]
        __agilis_err(__errstr)
        return ".error."
    }
    if (__agilis_checkerror(addr, "TS") == ".error.") {
        __errstr = macro " --> " func 
        __errstr = __errstr " --> ERROR --> Checking error."
        __agilis_err(__errstr)
        return ".error."
    }
}
'

#%IU%
#%DESC% changes the Agilis channel (which in Spec is the module), only if
# necessary. CC command is refused, when used during a movement.
def __agilis_change_module(addr, module) '{
    global __AGILIS_MODULE
    __npagilisdebug "__agilis_change_module", __AGILIS_MODULE, module
    local __cmd, __answer, __errstr
    if (module == __AGILIS_MODULE) {
        return
    }
    __cmd = "CC" module
    if (__agilis_put(agilis_ADDR, __cmd) == ".error.") {
        __errstr = macro " ---> " func " prestart_one --> ERROR on " __cmd "."
        __agilis_err(__errstr)
        return ".error."
    }
    if (__agilis_checkerror(agilis_ADDR, "CC") == ".error.") {
        __errstr = macro " --> " func 
        __errstr = __errstr " --> ERROR --> Checking error."
        __agilis_err(__errstr)
        return ".error."
    }
    __AGILIS_MODULE = module
}
'

    
#%IU%
#%DESC% 
def __agilis_config(mnum, type, unit, module, channel) '{
    __npagilisdebug "Configuring", mnum, type, unit, module, channel
    local macro, func, __errstr
    macro   =   "newport_agilis.mac"
    func    =   "__agilis_config()"

    if (whatis("__AGILIS_ERRORS") != 0x5000004) {
        __agilis_globals()
    }

    if (type == "ctrl") {
        if (__agilis_set_serial_parameters(agilis_ADDR) != 0) {
            __errstr = macro " --> " func
            __errstr = __errstr " --> ERROR --> Setting parameters failed"
            __agilis_err(__errstr)
            return ".error."
        }
        if (__agilis_put(agilis_ADDR, "MR") == ".error.") {
            __errstr = macro " --> " func 
            __errstr = __errstr " --> ERROR --> Setting controller to remote "
            __errstr = __errstr "mode \"MR\"."
            __agilis_err(__errstr)
            return ".error."
        }
        if (__agilis_checkerror(agilis_ADDR, "MR") == ".error.") {
            __errstr = macro " --> " func 
            __errstr = __errstr " --> ERROR --> Checking error."
            __agilis_err(__errstr)
            return ".error."
        }
    }
    else if (type == "mot") {
        if ((module < 1) || (module > 4)) {
            __errstr = macro " --> " func
            __errstr = __errstr " --> ERROR -->\n Channel is not one of 1,2,3,4"
            __errstr = __errstr " Motor will be unusable.\n"
            __agilis_err(__errstr)
            return ".error."
        }
        if ((channel < 1) || (channel > 2)) {
            __errstr = macro " --> " func
            __errstr = __errstr " --> ERROR -->\n Axis is not one of 1,2"
            __errstr = __errstr " Motor will be unusable."
            __agilis_err(__errstr)
            return ".error."
        }
    }            
}
'

    
#%IU%
#%DESC% Spec Macro Motor function
def __agilis_cmd(mnum, cmd, p1, p2) '{
    __npagilisdebug "Command: mnum", mnum, "cmd", cmd, ", p1", p1, ", p2", p2
    if ( mnum == ".." ) {
        ser_par(agilis_ADDR, "flush", 2)
        return
    }
    local macro, func, __errstr
    macro   =   "newport_agilis.mac"
    func    =   "__agilis_cmd()"

    local module, chan
    chan = motor_par(mnum, "channel")
    module = motor_par(mnum, "module")
    if (cmd == "position" ) {
        __npagilisdebug "Command position: "
        __cmd = chan "TP"
        if ((__pos = __agilis_putget(agilis_ADDR, __cmd)) == ".error.") {
            __errstr = macro " ---> " func " prestart_one --> ERROR on " __cmd "."
            __agilis_err(__errstr)
            return ".error."
        }
        __npagilisdebug "TP returned", __pos
        if (__agilis_checkerror(agilis_ADDR, "TP") == ".error.") {
            __errstr = macro " --> " func 
            __errstr = __errstr " --> ERROR --> Checking error."
            __agilis_err(__errstr)
            return ".error."
        }
        
        __pos = substr(__pos, 4)
        __npagilisdebug "position is",  __pos
        return __pos
    }
    else 
    if ( (cmd == "prestart_one") || (cmd == "preread_one") ) {
        local __cmd, __answer, __errstr
        __npagilisdebug "Command", cmd
        if (__agilis_change_module(agilis_ADDR, module) == ".error.") {
            return ".error."
        }
    }
    else if ( cmd == "start_one") {
        __npagilisdebug "Command start_one: "
        __cmd = chan "PR" p2
        if (__agilis_put(agilis_ADDR, __cmd) == ".error.") {
            __errstr = macro " ---> " func " --> ERROR on \"TS\"."
            __agilis_err(__errstr)
            return ".error."
        }
        if (__agilis_checkerror(agilis_ADDR, "PR") == ".error.") {
            __errstr = macro " --> " func 
            __errstr = __errstr " --> ERROR --> Checking error."
            __agilis_err(__errstr)
            return ".error."
        }
    }
    else if ( cmd == "abort_one") {
        __npagilisdebug "Command abort_one: "
        __cmd = chan "ST"
        if (__agilis_put(agilis_ADDR, __cmd) == ".error.") {
            __errstr = macro " ---> " func " --> ERROR on \"TS\"."
            __agilis_err(__errstr)
            return ".error."
        }
        if (__agilis_checkerror(agilis_ADDR) == ".error.") {
            __errstr = macro " --> " func 
            __errstr = __errstr " --> ERROR --> Checking error."
            __agilis_err(__errstr)
            return ".error."
        }
    }
    else if ( cmd == "get_status") {
        __npagilisdebug "Command get_status: "
        return __agilis_status(agilis_ADDR, chan, 1) * 2
    }
    else if ( cmd == "set_position") {
        if (p1 != 0) {
            __errstr = macro " --> " func 
            __errstr = __errstr " --> ERROR --> Can`t set other than 0."
            __agilis_err(__errstr)
            return ".error."
        }
        __cmd = chan "ZP"
        if (__agilis_put(agilis_ADDR, __cmd) == ".error.") {
            __errstr = macro " ---> " func " --> ERROR on \"TS\"."
            __agilis_err(__errstr)
            return ".error."
        }
        if (__agilis_checkerror(agilis_ADDR) == ".error.") {
            __errstr = macro " --> " func 
            __errstr = __errstr " --> ERROR --> Checking error."
            __agilis_err(__errstr)
            return ".error."
        }
    }
}
'

#%UU% mne [step size]
#%MDESC% Set step amplitude or get step amplitude setting for the motor designated
# with mne.
def agilis_setstepsize '{
    if (!$#) {
        eprint "Please give motor mnemonic as argument"
        exit
    }
    _check0 "$1"
    local chan, module, addr, __cmd, __errst, mne, mnum, __answer
    mnum    = motor_num("$1")
    module  = motor_par(mnum, "module")
    chan    = motor_par(mnum, "channel")
    addr    = motor_par(mnum, "addr")
    mne     = "$1"
    if ($# == 1) {
        __npagilisdebug "agilis_setstepsize: ", mne
        if (__agilis_change_module(addr, module) == ".error.") {
            __errstr = macro " ---> " func " --> ERROR on CC."
            __agilis_err(__errstr)
            return ".error."
        }
        __cmd = chan "SU+"
        if ((__answer = __agilis_putget(addr, __cmd)) == ".error.") {
            __errstr = macro " ---> " func " --> ERROR"
            __agilis_err(__errstr)
            return ".error."
        }
        if (__agilis_checkerror(addr) == ".error.") {
            __errstr = macro " --> " func 
            __errstr = __errstr " --> ERROR --> Checking error."
            __agilis_err(__errstr)
            return ".error."
        }
        print "Current step size for motor", mne, "(" module "/" chan "):", __answer
    }
    else {
        if (__agilis_change_module(addr, module) == ".error.") {
            __errstr = macro " ---> " func " --> ERROR on CC."
            __agilis_err(__errstr)
            return ".error."
        }
        __cmd = chan "SU" "$2"
        if ((__answer = __agilis_putget(addr, __cmd)) == ".error.") {
            __errstr = macro " ---> " func " --> ERROR"
            __agilis_err(__errstr)
            return ".error."
        }
        if (__agilis_checkerror(addr) == ".error.") {
            __errstr = macro " --> " func 
            __errstr = __errstr " --> ERROR --> Checking error."
            __agilis_err(__errstr)
            return ".error."
        }
    }
}
'    
#%MACROS%
#%IMACROS%
#%END%
#%BUGS% Bugs ? What bugs ??
#%AUTHOR%
#Holger (BLISS) for ID18.
#%TOC%