esrf

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

#%TITLE% SDLIN.MAC
#%NAME%
#  Sodilec bos/s sdlin power supply.
#%DESCRIPTION%
# Those macros deal with the Sodilec BOS/S power supply basic remote
# control and feature also its output control as a pseudo motor.
#%SETUP%
# RS232 (9600 Baud) or GPIB.
#
#%WARNING%
# Tue 26 Jun 2012 17:27:10 %BR%
# ID26 was Unable to use GPIB INTERFACE of sodilec power supply of the pool/id15
# USE rs232...
#
#%SETUP%
# sdsetup "RS232" "0" 0.3 "CURRENT" 0 10
#
#%END%


need pseudo.mac

######################################################################
###############################         ##############################
###############################  SETUP  ##############################
###############################         ##############################
######################################################################

#%UU% [interface] [address] [sleep_time] [control] [min] [max]
#%MDESC% Device setup and software initialisation:
#%PRE%
# - interface : "%B%RS232%B%" or "%B%GPIB%B%";
# - address   : If RS232, it is in fact the serial line number from config.
# - sleep time: time waited after a command is sent to the controller.
# - control   : either "%B%CURRENT%B%" or "%B%VOLTAGE%B%".
# - min, max  : Limits are in percentage of DAC output full scale.
#%PRE%
# The controller is put into remote control. Default is RS232 and CURRENT
# control.
def sdsetup '{
    global SD SD_DEV SD_COM  SD_SLEEPT SD_LMI0 SD_LMI1
    global SD_CNTL SD_LMV0 SD_LMV1
    global SD_OLD[]

    SD["RS232"]   = 0
    SD["GPIB"]    = 1
    SD["CURRENT"] = 0
    SD["VOLTAGE"] = 1

    if ($#) {
        SD_COM    = "$1"
        SD_DEV    = "$2"
        ### SD_SLEEPT = (SD["$1"]==1) ? SD_SLEEPT : ($3>=0 ? $3:SD_SLEEPT)
        SD_SLEEPT = "$3"
        SD_CNTL   = "$4"
        sdinit
        sdlim  $5  $6
    }
    else {
        menu("SDLIN MENU","sdsetup_menu","","sdinit")
    }

    setup_tail("sd")		# General Setup service
}'


#%UU%
#%MDESC%#
#    Turns the controller into remote and current/voltage control
# (default is current), and reads in the firmware version.
def sdinit '{

    # Switches to remote mode
    sdremot

    if (SD[SD_CNTL]){
        sdlin_dbg("Switches to voltage" ,1)
        sd_io("sv")
    }
    else{
        sdlin_dbg("Switches to current" ,1)
        sd_io("si")
    }

    # REad firmware infos
    sd_io("?M")

    print ""
    print SD_RESP
}'


#%IU%
#%MDESC%
#    Setup menu.
def sdsetup_menu '{
    local n

    n= "\n"

    menuoptval(-40, n, "Interface", SD_COM, "I")
    menuvartogg("SD_COM", "RS232", "GPIB")

    if (SD[SD_COM]==1){
        menuoptval(-40, n, "Address", SD_DEV, "A")
    }
    else{
        menuoptval(-40, n, "Serial line number (config)", SD_DEV, "S")
    }

    menuvargetv("SD_DEV")

    if (1!=SD[SD_COM]) {
        menuoptval(-40, n, "Polling intervals (s) for the Line", SD_SLEEPT, "P")
        menuvargetv("SD_SLEEPT")
    }

    print ""

    menuoptval(-40, n, "Control", SD_CNTL, "C")
    menuvartogg("SD_CNTL", "CURRENT", "VOLTAGE")
    menuoptbutton(-40, n, "Limits", "L")

    if (SD[SD_CNTL]) {
        txt = "(%% of voltage full scale)\n"
        menuprint(20,  0, "min:", SD_LMV0)
        menuprint(0, txt, "max:", SD_LMV1)
    }
    else {
        txt = "(%% of current full scale)\n"
        menuprint(20,  0, "min:", SD_LMI0)
        menuprint(0, txt, "max:", SD_LMI1)
    }

    menuaction("sdlim")
}'


#%UU%
#%MDESC%
#    Changes output limits, in percentage of full scale.
def sdlim '{
    if (SD[SD_CNTL]) {
        if ($#) {
            SD_LMV0=$1 ; SD_LMV1=$2 
        }
        else {
            SD_LMV0 = getval("Min. % full scale Limit",SD_LMV0)
            SD_LMV1 = getval("Max. % full scale Limit",SD_LMV1)
        }
        sd_io(sprintf("PL+",SD_LMV1))
        sd_io(sprintf("PL-",SD_LMV0))
    }
    else {
        if ($#) {
            SD_LMI0=$1 ; SD_LMI1=$2 
        }
        else {
            SD_LMI0 = getval("Min. % full scale Limit",SD_LMI0)
            SD_LMI1 = getval("Max. % full scale Limit",SD_LMI1)
        }
        sd_io(sprintf("PL+",SD_LMI1))
        sd_io(sprintf("PL-",SD_LMI0))
    }
}'


#%UU%
#%MDESC%
#    Removes sdlin software from SPEC memory.
def sdunsetup '{
    sdoff
    unglobal SD SD_DEV SD_COM  SD_SLEEPT SD_LMI0 SD_LMI1
    unglobal SD_RESP SD_CNTL SD_LMV0 SD_LMV1
    unglobal SD_MNE SDPOLF
    unglobal SD_OLD SD_SETPOINT
}'


#%UU%
#%MDESC%
#    Disconnects sdlin control from the standard macros.
def sdoff '{
    cdef ("","",SD_MNE[0],"delete")
}'


#%UU%
#%MDESC%
#    Connect sdlin control to the standard macros .(ct, scans...)
def sdon '{
    cdef ("user_getpangles", sprintf("sd_getfield %s SDPOLF;", SD_MNE[0]), SD_MNE[0], 1)
    cdef ("user_checkall",   sprintf("sd_mvsetpt %s SDPOLF;",  SD_MNE[0]), SD_MNE[0], 1)
    cdef ("user_finished1",  sprintf("sd_wait %s SDPOLF;",     SD_MNE[0]), SD_MNE[0], 1)
}'


######################################################################
################################       ###############################
################################  I/O  ###############################
################################       ###############################
######################################################################


#%IU% (<command>)
#%MDESC%
#    Sends <command> to the controller and eventually reads back its response.
def sd_io(cmd) '{
    global SD_RESP

    sd_put(SD_DEV, cmd)

    sdlin_dbg(sprintf("sd_io(%s)", cmd), 1)

    sleep(SD_SLEEPT)

    SD_RESP = sd_get(SD_DEV)
    return(SD_RESP)
}'


#%IU% (address,command)
#%MDESC%
#    Sends command to the controller.
def sd_put(add, cmd) '{

    if (SD[SD_COM] == 1){
        gpib_put(add, sprintf("%s\r", cmd))
    }
    else{
        ser_put (add, sprintf("%s\r", cmd))
    }
}'


#%IU% (address)
#%MDESC% Reads back response from the controller.

def sd_get(add) '{
    local response

    if (SD[SD_COM] == 1){
        return gpib_get(add, "\r")
    }
    else {
        ser_get(add,"\r");ser_get(add,"\r")
        response = ser_get(add,"\r")
        ser_get(add,">")
        return response
    }
}'


#%UU%
#%MDESC%
#    Empties RS232 line.
def sdflush '{
    if (0==SD[SD_COM]){
        SD_RESP = ser_get(SD_DEV)
    }
}'



######################################################################
##############################          ##############################
##############################  PSEUDO  ##############################
##############################          ##############################
######################################################################


#%UU% [mnemonic]
#%MDESC%
#    Sets power supply output as a pseudo motor.
def sdpseudodef '{

    global SD_MNE SDPOLF

    SDPOLF = 1

    cdef ("", "", SD_MNE[0], "delete")

    if ($# > 0) {
        SD_MNE[0] = "$1";
    }
    else {
        print "    put 0 for none"
        SD_MNE[0]=getval("motor mnemonic to drive SETPOINT",SD_MNE[0])
    }

    print ""

    if ("0" != SD_MNE[0]) {
        if (motor_num(SD_MNE[0])<0) {
            printf("SDLIN: put motor %s in config\n",SD_MNE[0])
        }
        cdef ("user_getpangles", sprintf("sd_getfield %s SDPOLF;", SD_MNE[0]), SD_MNE[0], 1)
        cdef ("user_checkall",   sprintf("sd_mvsetpt %s SDPOLF;",  SD_MNE[0]), SD_MNE[0], 1)
        cdef ("user_finished1",  sprintf("sd_wait %s SDPOLF;",     SD_MNE[0]), SD_MNE[0], 1)
    }

    if (0 == (whatis("pseudodef")&2)) {
      print "WARNING: macros set \"pseudo.mac\" not loaded."
      print "       \"scans\" may not work properly."
      print "        (..Typing \"jdo pseudo.mac\" may help..)"
    }
}'


#%IU% <mnemonic> <polarity_care>
#%MDESC%
#    Hooked to standard %B%move_em%B%.
#Changes power supply output setpoint. If polarity_care flag is 0, changes only the output magnitude.
def sd_mvsetpt '{
    local _msg  _cmd  _mot_num  _pol_care

    _mot_num  = $1
    _pol_care = "$2"

    _msg = "sd_mvsetpt \$1="$1 "  \$2=" $2 "  A[$1]=" A[_mot_num] " mot_num=" _mot_num
    sdlin_dbg(_msg, 1)

    if (A[_mot_num] != SD_OLD[_mot_num]) {
        if (_pol_care){
            _pos = A[_mot_num]
            _cmd ="pc"_pos
            sd_io(_cmd)
            SD_OLD[_mot_num] = A[_mot_num]
        }
        else{
            _cmd = sprintf("pc%s", fabs(A[_mot_num]))
            sd_io(_cmd)
        }
    }

    #TODO STH
    #if (SD_SETPOINT<-1.1 || SD_SETPOINT>1.1) {
    #  print "Maximum permitted current +/- 1.1 A (water cooling on)"
    #  exit
    #}
}'


#%IU% <mnemonic> <polarity_care>
#%MDESC%
#    Hooked to standard %B%get_angles%B%.
# Reads in power supply output. If polarity_care flag is 0, reads only the output magnitude.
def sd_getfield '{

    global  SD_SETPOINT

    sd_io("mi")
    sscanf(SD_RESP, "%g", val)

    if ($2){
        A[$1] = val
    }
    else{
        A[$1] = fabs(val)
    }

    SD_SETPOINT = SDM_OLD[$1] = A[$1]
}'


########### NOT COMPLETE ???

#%IU% <mnemonic> <polarity_care>
#%MDESC%
#    Hooked to standard %B%move_poll%B%.
# Waits for the power supply output to reach the setpoint. If
# polarity_care flag is 0, checks only the output magnitude.

def sd_wait '{
    if (A[$1]!=SD_OLD[$1]) sleep(1)
}'


#%UU% <setpoint>
#%MDESC% Sets power supply output setpoint.
def sdset '{

    global SD_SETPOINT

    SD_SETPOINT = $1

    if (1!=$#) {
        print "usage: $0 <setpoint>"
        exit
    }

    if (SD_SETPOINT<-2 || SD_SETPOINT>2){
        print "Maximum permitted current +/- 1.1 A (water cooling on)"
        exit
    }

    sd_io(sprintf("pc%g",$1))
}'


#%UU%
#%MDESC%
#    Turns the controller into local control.
def sdlocal '{
    # SET LOCAL
    sd_io("sl")
}'


#%UU%
#%MDESC%
#    Turns the controller into remote control.
def sdremot    '{
    global SD_SETPOINT SD_DEV

    SD_SETPOINT = 0

    sd_get(SD_DEV)

    # SET REMOTE
    sd_io("sr")
}'


#%UU%
#%MDESC%
#    Turns the controller into voltage control.
def sdvoltcont '{

    # SET V CONTROL
    sd_io("sv")
}'


#%UU%
#%MDESC%
#    Turns the controller into current control.
def sdcurrcont '{

    # SET I CONTROL
    sd_io("si")
}'


#%UU%
#%MDESC%
#    Reads in measured output voltage.
def sdmeasvolt '{
    sd_io("mv")
}'


#%UU%
#%MDESC%
#    Reads in measured output current.
def sdmeascurr '{
    sd_io("mi")
}'





###############################################################
####################                            ###############
####################   DEBUG AND INFO MESSAGES  ###############
####################                            ###############
###############################################################


global SDLIN_PAR[]

#%IU% (<msg>)
#%MDESC%
#    Prints a message in green.
def sdlin_msg(msg) '{
    cprint(sprintf ("[SDLIN]--%s\n", msg), 2)
}'


#%IU% (<debug_msg>, <level>)
#%MDESC%
#     Prints a debug message if debug level is activated.
def sdlin_dbg(debug_msg, level) '{

    if (SDLIN_PAR["debug"] >= level) {

        if (level == 0){
            #                                                      3  0 = orange on black
            cprint(sprintf ("[SDLIN]--DEBUG[0]--%s\n", debug_msg), 3, 0)
        }
        if (level == 1){
            #                                                      2  0 = green on black
            cprint(sprintf ("[SDLIN]--DEBUG[1]--%s\n", debug_msg), 3, 0)
        }
        else if (level == 2){
            #                                                      3  0  1 = bold yellow on black
            cprint(sprintf ("[SDLIN]--DEBUG[2]--%s\n", debug_msg), 3, 0, 1)
        }
        else if(level >2){
            #                                                              7  0  = white on black
            cprint(sprintf ("[SDLIN]--DEBUG[%d]--%s\n", level, debug_msg), 7, 0)
        }
    }
}'


#%UU% [<debug_level>]
#%MDESC%
#    Activates or desactivates the printing of debug messages.
def sdlin_debug '{
    global SDLIN_PAR[]

    _nb_param = $#

    if(_nb_param){
        SDLIN_PAR["debug"] = $1>2 ? 2 : $1
        printf("[SDLIN]--debug level : ")
        cprint(SDLIN_PAR["debug"], 1,0,1)
    }
    else{
        printf("[SDLIN]--debug level : ")
        cprint(SDLIN_PAR["debug"], 1,0,1)
        print "\nusage : $0 [ <debug level (in 0..2)> ]"
        print ""
    }
}'


#%IU% (<err_msg>)
#%MDESC%
#
def sdlin_err(err_msg) '{
    cprint(sprintf ("[XXX-ERROR]--%s\n", err_msg), 1)
}'



#%MACROS%
#%IMACROS%
#%DEPENDENCIES%
#%PRE%
#  - The file %B%sdlin.mac%B% has to be read in
#    this file needs: %B%menu.mac%B%
#%PRE%
#%AUTHOR%
#  SDLIN.MAC - Jeroen GOEDKOOP - Marie-Claire LAGIER - 96/9/10
#%TOC%