"""#%TITLE% birmingham_magnet.mac
#%NAME%
# Macros for the use of a 17T superconducting magnet controller from Birmingham (????).
#%DESCRIPTION%
# Use of the Birmingham superconducting magnet controller.
#%SETUP%
# In the config editor in the "Motor and Counter Device Configuration" page (hit "D") create a motor
# controller like follows:
# %BR%
#MOTORS\0\0\0\0\0\0\0\0\0\0DEVICE\0\0\0\0\0\0\0\0\0\0ADDR\0\0<>MODE\0\0NUM\0\0\0\0\0\0\0\0\0\0\0\0\0<>TYPE%BR%
#\0\0\0YES\0\0\0\0\0\0\0\0\0\0BIRMSM\0\0\0\0\0\0\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\0Macro\0Motors
# %BR%
#Then create the macro motor:
#%PRE%
#Number:\0<>Controller\0\0\0\0\0\0\0\0\0\0\00:\0MAC_MOT
#%BR%
#Unit/[Module/]Channel\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\00/0\0(first\0num\0is\0index\0num\0of\0controller)
#%BR%
#Name\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\0\0\0\0birm
#%BR%
#Mnemonic\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\0birm
#%BR%
#Steps\0per\0degree/mm\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\010000
#%BR%
#Sign\0of\0user\0*\0dial\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\01
#%BR%
#Backlash\0[steps]\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\00
#%BR%
#Steady-state\0rate\0[Hz]\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\01
#%BR%
#Base\0rate\0[Hz]\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\01
#%BR%
#Acceleration\0time\0[msec]\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\01
#%BR%
#Motor\0accumulator\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\00
#%BR%
#Restrictions\0<>\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0NONE
#%BR%
#
#%BR%
#Dial\0=\0accumulator\0/\0steps
#%BR%
#\0\0High\0limit\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\017.0000
#%BR%
#\0\0Current\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\00.0000
#%BR%
#\0\0Low\0limit\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0-17.0000
#%BR%
#User\0=\0sign\0*\0dial\0+\0offset
#%BR%
#\0\0Offset\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\00.0000
#%BR%
#\0\0`High'\0limit\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\017.0000
#%BR%
#\0\0Current\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\00.0000
#%BR%
#\0\0`Low'\0limit\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0-17.0000
#%PRE%
#%BR%
# It is advisable to set the backlash for the macro motors to 0.
#%ATTENTION%
# %DL%
# %DT% Channel numbers are :
# %DD% 0 for magnet field
# %DD% 1 for Current Temp Heat Exchanger
# %DD% 2 for Current Temp Probe
# %DD% 3 for Needle Valve Position
# %DD% 4 for Needle Valve Pressure Target
# %DD% 5 for Needle Valve Actual Pressure
# %DD% 6 for helium level
# %DD% 7 for atto position
# %XDL%
# %DL%
#%END%
# Modifications history:
# 10/04/2013 Creation
"""
#-----------------------------------------------------------
#%IU%(serialline, parity, speed)
#%MDESC% Setting serial line parameters
def _birmsm__set_serial_parameters(serialline, parity, speed) '{
"""
/*
* symbolic defines - used by server and client alike
*/
#define SL_RAW 0 /* raw read/write mode */
#define SL_NCHAR 1 /* character read/write mode */
#define SL_LINE 2 /* line read mode */
#define SL_NONE 0
#define SL_ODD 1
#define SL_EVEN 3
#define SL_DATA8 0
#define SL_DATA7 1
#define SL_DATA6 2
#define SL_DATA5 3
#define SL_STOP1 0
#define SL_STOP15 1
#define SL_STOP2 2
#define SL_TIMEOUT 3 /* timeout parameter */
#define SL_PARITY 4 /* number of parity bits parameter */
#define SL_CHARLENGTH 5 /* number of data bits parameter */
#define SL_STOPBITS 6 /* number of stop bits parameter */
#define SL_BAUDRATE 7 /* baud rate parameter */
#define SL_NEWLINE 8 /* new line character parameter */
"""
global ESRF_ERR
local params[], device, lspeed, lparity, lbytes
device = serialline
#device = ser_par(serialline, "device_id")
if (index(device, "/dev/")) {
eprint "_birmsm__set_serial_parameters(): can`t set parameters on local serial line", \
device
return(-1)
}
if (!speed) { lspeed = 9600 }
else { lspeed = speed }
if (index(parity, "even")) { lparity = 3; lbytes = 1 }
else if (index(parity, "odd")) { lparity = 1; lbytes = 1 }
else { lparity = 0; lbytes = 0 }
# setting the parameters as wished by the Tango DS
params[ 0] = 3 # SL_TIMEOUT /* timeout parameter */
params[ 1] = 500 # timeout value
params[ 2] = 4 # SL_PARITY /* number of parity bits parameter */
params[ 3] = lparity # even parity
params[ 4] = 5 # SL_CHARLENGTH /* number of data bits parameter */
params[ 5] = lbytes # 7 data bits
params[ 6] = 6 # SL_STOPBITS /* number of stop bits parameter */
params[ 7] = 0 # 1 stop bit
params[ 8] = 7 # SL_BAUDRATE /* baud rate parameter */
params[ 9] = lspeed # baud
params[10] = 8 # SL_NEWLINE /* new line character parameter */
params[11] = 10 # LF
ESRF_ERR = -1
taco_io(device, "DevSerSetLongParameter", params)
if (ESRF_ERR){
__BIRMSM_debug "_birmsm__set_serial_parameters: taco_io(\"" device "\", \"DevSerSetParameter\", params) failed!"
return(0)
} else {
return(1)
}
}
'
#%IU%
#%MDESC%
# Called by spec,
def BIRMSM_config(mnum,type,unit,mod,chan) '{
local addr mma
global __BIRMSM_ADDR
__BIRMSM_ADDR = addr = BIRMSM_ADDR # keep address for other macros
__BIRMSM_debug "address", addr, __BIRMSM_ADDR
__BIRMSM_debug "BIRMSM_config", mnum,type,unit,mod,chan
# __BIRMSM_ADDR should contain sth like id12/serial/toto
# in case of error (server or hardware) the setting to .error.
# will make spec disable this macromotor.
# if ( mnum == "..") {
# if (!(whatis("__BIRMSM_SIMU") & 0x5000000)) {
# if (!_birmsm__set_serial_parameters(addr, "odd", 9600)) {
# return ".error."
# }
# # must be smaller than TRANSIENT_CallTimedoutTimeout (3000 mS)
# TACO_ERR = 0
# taco_io(addr, "DevSerSetTimeout", 2900)
# if (TACO_ERR != 0) {
# return(".error.")
# }
# }
# }
__birmsh_io(addr, "setpersist ON")
return(0)
}
'
#%IU%
#%MDESC%
# Called by spec
def BIRMSM_cmd(mnum, cmd, p1, p2, p3) '{
local addr, module, channel, strin
addr = __BIRMSM_ADDR
__BIRMSM_debug "BIRMSM_cmd:", mnum,cmd, p1, p2, p3
if (mnum == "..") {
return
}
if (cmd == "start_one") {
# start counter, when it is one
if (p2 == 0) {
return
}
channel = motor_par(mnum, "channel")
if (channel == 0) { # deal with magnet field
strin = "abort"
__BIRMSM_debug strin
if (__BIRMSM_io(addr, strin) == ".error.") return ".error."
strin = "setfield " p1
__BIRMSM_debug strin
if (__BIRMSM_io(addr, strin) == ".error.") return ".error."
}
else if (channel == 1) { # deal with Current Temp Heat Exchanger
strin = "set1 " p1
__BIRMSM_debug strin
if (__BIRMSM_io(addr, strin) == ".error.") return ".error."
}
else if (channel == 2) { # deal with Current Temp Probe
strin = "set2 " p1
__BIRMSM_debug strin
if (__BIRMSM_io(addr, strin) == ".error.") return ".error."
}
else if (channel == 3) { # deal with Needle Valve Position
strin = "setposition " p1
__BIRMSM_debug strin
if (__BIRMSM_io(addr, strin) == ".error.") return ".error."
}
else if (channel == 4) { # deal with Needle Valve Pressure Target
strin = "setpressure " p1
__BIRMSM_debug strin
if (__BIRMSM_io(addr, strin) == ".error.") return ".error."
}
else if (channel == 7) { # deal with atto positions
local strin
strin = "setangle " p1
__BIRMSM_debug strin
if (__BIRMSM_io(addr, strin) == ".error.") return ".error."
}
#else if (channel == 5) { # DO NOT deal with Needle Valve Actual Pressure
#else if (channel == 6) { # DO NOT deal with helium level
}
else if (cmd == "get_status") {
if (channel == 0) { # deal with magnet field
channel = motor_par(mnum, "channel")
local strin, strout, aux[]
strin = "ready"
__BIRMSM_debug strin
strout = __BIRMSM_io(addr, strin)
split(strout, aux, ":")
__BIRMSM_debug strout, "---->", aux[2], "<----"
if (aux[2] == "OFF\n")
return 2
}
else
return 0
}
else if ((cmd == "position") || (cmd == "counts")) {
local field, strout, aux[]
if (cmd == "position")
channel = motor_par(mnum, "channel")
else if (cmd == "counts")
channel = counter_par(mnum, "channel")
if (channel == 0) { # deal with magnet field
local field, strout, aux[]
strin = "output"
__BIRMSM_debug strin
if ((strout = __BIRMSM_io(addr, strin)) == ".error.") return ".error."
__BIRMSM_debug strout
strout = substr(strout, 11)
split(strout, aux, ",")
if (sscanf(aux[0], "%f", field) != 1) {
eprint "answer from \"output\" can`t be scanned for field value", aux[0]
return ".error."
}
__BIRMSM_debug "position/counts return", field
return field
}
else if (channel == 1) { # deal with Current Temp Heat Exchanger
strin = "sensA"
__BIRMSM_debug strin
if ((strout = __BIRMSM_io(addr, strin)) == ".error.") return ".error."
__BIRMSM_debug strout
split(strout, aux, ":")
return aux[2] * 1.0
}
else if (channel == 2) { # deal with Current Temp Probe
strin = "sensB"
__BIRMSM_debug strin
if ((strout = __BIRMSM_io(addr, strin)) == ".error.") return ".error."
__BIRMSM_debug strout
split(strout, aux, ":")
return aux[2] * 1.0
}
else if (channel == 3) { # deal with Needle Valve Position
strin = "nv"
__BIRMSM_debug strin
if ((strout = __BIRMSM_io(addr, strin)) == ".error.") return ".error."
__BIRMSM_debug strout
split(strout, aux, ":")
return aux[2] * 1.0
}
else if (channel == 4) { # deal with Needle Valve Pressure Target
strin = "pressure"
__BIRMSM_debug strin
if ((strout = __BIRMSM_io(addr, strin)) == ".error.") return ".error."
__BIRMSM_debug strout
split(strout, aux, ":")
return aux[2] * 1.0
}
else if (channel == 5) { # deal with Needle Valve Actual Pressure
strin = "pressure"
__BIRMSM_debug strin
if ((strout = __BIRMSM_io(addr, strin)) == ".error.") return ".error."
__BIRMSM_debug strout
split(strout, aux, ":")
return aux[3] * 1.0
}
else if (channel == 6) { # deal with helium level
strin = "helevel"
__BIRMSM_debug strin
if ((strout = __BIRMSM_io(addr, strin)) == ".error.") return ".error."
__BIRMSM_debug strout
split(strout, aux, ":")
return aux[2] * 1.0
}
else if (channel == 7) { # deal with atto position
strin = "attoangle"
__BIRMSM_debug strin
if ((strout = __BIRMSM_io(addr, strin)) == ".error.") return ".error."
__BIRMSM_debug strout
split(strout, aux, ":")
return aux[2] * 1.0
}
}
}
'
if (!(whatis("__BIRMSM_debug") & 2)) rdef __BIRMSM_debug \'#$*\'
#%UU%
#%MDESC% toggle debug mode for the present macros.
def BIRMSMdebug '{
if ((whatis("__BIRMSM_debug")>>16) <= 5) { # just a # sign -> off
rdef __BIRMSM_debug "eprint"
print "birsm debug is ON"
} else {
rdef __BIRMSM_debug \'#$*\'
print "birsm debug is OFF"
}
}
'
if (!(whatis("__BIRMSM_info") & 2)) rdef __BIRMSM_info \'eprint\'
#%UU%
#%MDESC% toggle info mode for the present macros.
def BIRMSM_info '{
if ((whatis("__BIRMSM_info")>>16) <= 3) { # just a # sign -> off
rdef __BIRMSM_info "eprint"
print "BIRMSM info is ON"
} else {
rdef __BIRMSM_info \'#\$*\'
print "BIRMSM info is OFF"
}
}
'
#%UU%
#%MDESC% toggle info mode for the present macros.
def __BIRMSM_simuf(cmd) '{
global __BIRMSM_SIMU[]
local answ
__BIRMSM_debug "BIRMSM SIMU cmd", cmd
local aux[], n
if (cmd == "output")
answ = sprintf("output:OK:%fT,%fA", __BIRMSM_SIMU["field"]*1.0, __BIRMSM_SIMU["field"]*12.3)
else if (index(cmd, "setfield") == 1) {
split(cmd, aux, " ")
__BIRMSM_SIMU["field"] = aux[1] * 1.0
answ = "setfield:OK"
}
else if (cmd == "heater")
answ = sprintf("heater:OK:%d", __BIRMSM_SIMU["heater"])
else if (cmd == "persistent")
answ = sprintf("persistent:OK:%fT,%fA", __BIRMSM_SIMU["field"]*1.0, __BIRMSM_SIMU["field"]*12.3)
else if (index(cmd, "setpersist") == 1) { # startswith
split(cmd, aux, " ")
if (aux[1] == "ON") __BIRMSM_SIMU["heater"] = 0
answ = "setpersist:OK"
}
else if (cmd == "persistentmode")
answ = sprintf("persistentmode:OK:%s", __BIRMSM_SIMU["heater"] ? "ON":"OFF")
else if (cmd == "ready")
answ = "ready:OK:ON"
else if (cmd == "abort")
answ = "abort:OK"
else if (cmd == "getstatus")
answ = "blablablablabla"
else if (index(cmd, "set1") == 1) {
split(cmd, aux, " ")
__BIRMSM_SIMU["heat exchanger"] = aux[1] * 1.0
answ = "set1:OK"
}
else if (cmd == "sensA") answ = sprintf("sensA:OK:%f", __BIRMSM_SIMU["heat exchanger"])
else if (index(cmd, "set2") == 1) {
split(cmd, aux, " ")
__BIRMSM_SIMU["probe"] = aux[1] * 1.0
answ = "set2:OK"
}
else if (cmd == "sensB") answ = sprintf("sensB:OK:%f", __BIRMSM_SIMU["probe"])
else if (index(cmd, "setpressure") == 1) {
split(cmd, aux, " ")
__BIRMSM_SIMU["NV target pressure"] = aux[1] * 1.0
answ = "setpressure:OK"
}
else if (cmd == "pressure") answ = sprintf("pressure:OK:%f", __BIRMSM_SIMU["NV target pressure"])
else if (index(cmd, "setposition") == 1) {
split(cmd, aux, " ")
__BIRMSM_SIMU["NV position"] = aux[1] * 1.0
answ = "setposition:OK"
}
else if (cmd == "nv") answ = sprintf("nv:OK:%f", __BIRMSM_SIMU["NV position"])
else if (cmd == "helevel") answ = sprintf("helevel:OK:%d", 43)
else if (index(cmd, "setangle") == 1) {
split(cmd, aux, " ")
__BIRMSM_SIMU["attoangle"] = aux[1] * 1.0
answ = "setangle:OK"
}
else if (cmd == "attoangle") answ = sprintf("attoangle:OK:%f", __BIRMSM_SIMU["attoangle"])
else answ = cmd ":OK"
#
__BIRMSM_debug "BIRMSM simulation answer:", answ
return(answ)
}
'
#%IU%(addr, cmd)
#%MDESC% Called by spec, write command to controller and read answer.
def __BIRMSM_io(addr, cmd) '{
local answ
if (!(whatis("__BIRMSM_SIMU") & 0x5000000)) {
if (__BIRMSM_put(addr, cmd) == ".error.") {
return(".error.")
}
# a sleep here should be unnecessary, if the timeout is set correctly
# sleep(1)
return __BIRMSM_get(addr)
}
else {
answ = __BIRMSM_simuf(cmd)
}
return(answ)
}
'
#%IU%(addr, cmd)
#%MDESC% Called by spec, write command to controller, no answer expected.
# return .error. in case of error
def __BIRMSM_put(addr, cmd) '{
local answer
if (!(whatis("__BIRMSM_SIMU") & 0x5000000)) {
__BIRMSM_debug "__BIRMSM_put(\"" addr "\", \"" cmd "\")"
local str
str = cmd "\n"
ser_par(addr, "flush", 2)
answer = ser_put(addr, str)
__BIRMSM_debug "__BIRMSM_put: ser_put answers", answer
if (answer == 0) {
return ".error."
}
}
else {
__BIRMSM_simuf(cmd)
}
return 0
}
'
#%IU%(addr)
#%MDESC% Called by spec, read an answer
def __BIRMSM_get(addr) '{
if (!(whatis("__BIRMSM_SIMU") & 0x5000000)) {
local answer
answer = ser_get(addr, "\n")
__BIRMSM_debug "__BIRMSM_get(\"" addr "\") = ", answer
if (answer == "") {
return ".error."
}
return answer
}
return 0
}
'
# some programmer help
#%UU%
#%MDESC% toggle debug mode for the present macros.
def BIRMSM_simu '{
if (!(whatis("__BIRMSM_SIMU") & 0x5000000)) {
global __BIRMSM_SIMU[]
__BIRMSM_SIMU["active"] = 1
__BIRMSM_SIMU["heater"] = 0
print "BIRMSM simulation is ON"
} else {
unglobal __BIRMSM_SIMU
print "BIRMSM simulation is OFF"
}
}
'
#%UU% [output|voltage|heater|ramprate|units|target|persistent|ready|getstatus]
#%MDESC% miscellaneous calls to the controller
def BIRMSM_command'{
local send
send = "$*"
__BIRMSM_debug "\"$*\""
print __BIRMSM_io(__BIRMSM_ADDR, send)
}'
#%UU%
#%MDESC% miscellaneous calls to the controller
def BIRMSM_heater'{
local str, strout, aux[], status
str = "ON OFF OFF AT FIELD NO MATCH"
strout = __BIRMSM_io(addr, "heater")
split(strout, aux, ":")
status = aux[2] + 0
split(str, aux, " ")
print "Main coil heater status is:", aux[status]
}'
#%MACROS%
#%IMACROS%
#%DEPENDENCIES%
#The file birmingham_magnet.mac havs to be read in.
#%AUTHOR% BLISS - ESRF, H. Witsch%BR%
#$Revision: 1.1 $
#%TOC%
|