#%TITLE% ICEPAP.MAC
#
#%NAME%
# Macros to control ISG ICEPAP motor controller as a macro motor
# and to configure macro counters to read DRIVERs temperatures
# (obsolete: use ice.mac instead)
#
#%CATEGORY% Positioning, Obsolete
#
#%DESCRIPTION%
#%DL%
#%DT%Configuring macro motors %DD%
# %DL%
# %DT% 1)
# You must have an entry in "MOTORS" table for each icepap MASTER
# %DL%
# %DT% -
# The "DEVICE" field must be set to "icepap"
# %DT% -
# The "ADDR" must be set to the MASTER network name.
# The communication port can optionaly be specified also
# (ex: "isgtmp5:5000")
# %DT% -
# The "NUM" should be set to 128
# %DT% -
# The "TYPE" field must be set to "Macro Motors"
# %XDL%
# %DT% 2)
# For each axis you must define a motor with:
# %DL%
# %DT% -
# The "Controller" field set to "MAC_MOT"
# %DT% -
# The "Unit" field must be set to the MOTORS entry.
# %DT% -
# The "Module" field must be set to the ICEPAP rack numer (seen on
# the red 7 segments display of the top left hand card)
# %DT% -
# The "Chan" field must be set to the DRIVER address (ex: 5 for
# the 5th DRIVER of crate 0 or ex: 23 for the 3rd DRIVER of crate 2)
# %DT% -
# Example: "0/1/2" refers to the first icepap controller declared,
# and the 2nd DRIVER of the rack having the number "1" on its display.
# %DT% -
# The "Generic parameter 1" parameter (type "m" to access it) is the
# motor type (ex: "pk267"). For the moment the motor types and
# their parameters are defined in:
# ~blissadm/local/spec/userconf/icepap_catalogue
# %DT% -
# The "Generic parameter 2" and nexts can be any of the following
# options:
# %DL%
# %DT% -
# "SWOFF" to disable limitswitches
# %DT% -
# "DIRINV" to reverse the motor direction according to limitswitches
# %XDL%
# %XDL%
# %XDL%
#
#%DT%Configuring macro counters to read a single DRIVER %DD%
# %DL%
# %DT% 1)
# You must have a "SCALER" define with "icepapcnt" as "DEVICE" and
# "Macro Counter" as "TYPE".
# %DT% 2)
# You must define a counter with "MAC_CNT" as "Device".
# %DL%
# %DT% -
# The "Unit" field must be set to the SCALER entry.
# %DT% -
# The "Chan" field must be set to the DRIVER address (ex: 5 for
# the 5th DRIVER of crate 0 or ex: 23 for the 3rd DRIVER of crate 2)
# %XDL%
# %XDL%
#
#%DT%Configuring macro counters to read several DRIVERs %DD%
# %DL%
# %DT% 1)
# You must have a "SCALER" define with "icepapcalc" as "DEVICE" and
# "Macro Counter" as "TYPE"
# %DT% 2)
# For each counter declared:
# %DL%
# %DT% -
# The "Device" field set to "MAC_CNT"
# %DT% -
# The "Unit" field must be set to the SCALER entry.
# %DT% -
# The "Chan" field is not used.
# %DT% -
# The "Misc 1" parameter (type "s" to access it) is the
# crate number (ex: 0)
# %DT% -
# The "Misc 2" parameter is the type of calculation
# done on the DRIVERs temperatures of the crate. Possible values are
# "max", "min", "avg"
# %XDL%
# %XDL%
#
#%XDL%
#
#%END%
#
print "--------------------------- WARNING ----------------------------"
print "----------------------- OBSOLETE MACROS -----------------------"
print "--------------- you should use ice.mac instead -----------------"
print "--------------------------- WARNING ----------------------------"
#
# ----------------------- MACRO MOTOR implementation -----------------------
#
constant ICEPAP_CATALOGUE "/users/blissadm/local/spec/userconf/icepap_catalogue"
constant ICEPAP_LOCKFILE "/users/blissadm/local/spec/userconf/icepap_lock"
#%UU% [personal msg]
#%MDESC%
# Switch on or off the print of debug messages
#
def icepapdebug '{
global ICEPAP[]
if(ICEPAP["debug"]) {
rdef icepap__debug \'#\$#\'
print "ICEPAP debug mode is OFF"
ICEPAP["debug"]=0
} else {
rdef icepap__debug \'print "ICEPAP:","$*"\'
print "ICEPAP debug mode is ON"
ICEPAP["debug"]=1
}
}'
#%IU%
#%MDESC%
# Reset socket communication and MASTER FIFOs
#
def icepap_fiforst(dev) '{
_icepap_wr(dev,"","_FIFORST")
sock_par(dev,"flush")
}'
#%IU%
#%MDESC%
# Call on <Ctrl-C>
#
def icepap_cleanup(dev) '{
# give time to sockets
sleep(.05)
icepap_fiforst(dev)
}'
#%IU%
#%MDESC%
# Needed to initialize debug print out macro the first time the
# file is loaded.
def icepapdebug_init '{
if(!(whatis("ICEPAP") & 0x05000000)) {
global ICEPAP[]
ICEPAP["debug"]=1
icepapdebug
}
}'
icepapdebug_init
#%IU%(string, case)
#%MDESC%
# Convert to lower (case==1) or to upper (case==0) case the string passed
#
def icepap__tocase(str, case) '{
string array str_a[length(str)]
local l
str_a = str
l = length(str)-1
for(;l>=0;l--) {
if(case)
str_a[l]=str_a[l]+(str_a[l]>=asc("A") && str_a[l]<=asc("Z"))*0x20;
else
str_a[l]=str_a[l]-(str_a[l]>=asc("a") && str_a[l]<=asc("z"))*0x20;
}
return(sprintf("%s", str_a))
}'
#%IU%(string)
#%MDESC%
# Return the lower string of the string passed
#
def icepap__tolower(str) '{return((str!="")?icepap__tocase(str, 1):"")}'
#%IU%(string)
#%MDESC%
# Return the upper string of the string passed
#
def icepap__toupper(str) '{return((str!="")?icepap__tocase(str, 0):"")}'
#%IU%
#%MDESC%
# Read the catalogue of motor parameters from a file
#
def icepap_read_cat() '{
global ICEPAP_CAT[]
local l line c
local entry motor_ref
local param, val
if(getline(ICEPAP_CATALOGUE, "open") < 0){
printf("ICEPAP ERROR: Can\'t open file \"%s\"\n", ICEPAP_CATALOGUE)
return -1
}
# Erase any previous catalogue (cf can not do unglobal+global)
for(param in ICEPAP_CAT) delete ICEPAP_CAT[param];
ICEPAP_CAT["nconf"] = 0
l = 0
while ((line = getline(ICEPAP_CATALOGUE)) != -1) {
l++
c = substr(line, 1, 1)
if (asc(c) < 32 || c == "#") continue;
if (sscanf(line,"motor %s",motor_ref) == 1) {
motor_ref=icepap__toupper(motor_ref)
icepap__debug "found new catalogue entry: " motor_ref
ICEPAP_CAT[motor_ref] = ICEPAP_CAT["nconf"]++
entry=1
while(entry) {
line = getline(ICEPAP_CATALOGUE)
l++
if((line == -1) || (line == "\n")) {
icepap__debug "end of entry: " motor_ref
entry=0
continue
}
c = substr(line, 1, 1)
if (asc(c) < 32 || c == "#") continue;
if(sscanf(line, "%s %s",param, val) != 2) {
printf("ICEPAP ERROR: syntax error at line %d in file \"%s\"\n", \
l, ICEPAP_CATALOGUE)
return
}
param=icepap__toupper(param)
ICEPAP_CAT[motor_ref][param] = val
}
}
}
getline(ICEPAP_CATALOGUE, "close")
return 0
}'
#%IU%(ans)
#%MDESC%
# Check if the answer given contains an ERROR and if yes
# request the error message
#
def icepap_chkerr(dev,ans) '{
if(index(ans,"ERROR") == 1) {
ans= _icepap_wrrd(dev,0,"?ERR 1")
print ans;
}
}'
#%IU%(device,crate,board,motor_ref,mne)
#%MDESC%
# Set for a motor its parameter according to catalogue. The motor
# is specified by crate and board. The mne field is for debug print out only.
# The device is the network name of the MASTER.
#
def icepap_set_mot(dev,crate,board,motor_ref,mne) '{
global ICEPAP_CAT[]
global ICEPAP[]
local addr ack_addr
local cmd
local cmd_ans
local param val val_sd
local ans id err
if(mne=="") mne="TEST";
motor_ref=icepap__toupper(motor_ref)
if(!(motor_ref in ICEPAP_CAT)) {
printf("ICEPAP ERROR: \"%s\": unknown motor type \"%s\"\n",mne,motor_ref)
printf("Hint: update file \"%s\"\n", ICEPAP_CATALOGUE)
return
}
if((crate<0) || (crate>15)) {
print "ICEPAP: \""mne"\": invalid module/crate "crate" (valid: 0 to 15)"
return
}
if((board<1) || (board>8))
{
print "ICEPAP: \""mne"\": invalid channel/board "board" (valid: 1 to 8)"
return
}
addr=crate*10 + board
ack_addr = "#" addr
# get a communication to the ICEPAP master
ans=_icepap_query(dev,addr,"?ID")
if(sscanf(ans,"%s",id) != 1) {
printf("ICEPAP ERROR: %s: addr: %s: unable to get driver ID\n",mne,addr)
return
}
# TODO: check that the id has not changed (in case the driver has been
# physically replaced and need to be reconfigured)
ICEPAP[mne]["id"]=id
# If SD parameter is not given in catalogue, the default value is 2Volts
val_sd=2.0
# clear DRIVER error messages
# MP 30/01/07 TODO
# _icepap_query(dev,addr,"?FERRMSG")
# configure low level motor params
for(param in ICEPAP_CAT[motor_ref]) {
val=ICEPAP_CAT[motor_ref][param]
if(param=="SD") {
val_sd=val
continue
}
cmd=param" "val
_icepap_wrrd(dev,ack_addr,cmd)
}
# enable the axis
cmd="SD "val_sd
_icepap_wrrd(dev,ack_addr,cmd)
_icepap_wrrd(dev,ack_addr,"CLR")
_icepap_wrrd(dev,ack_addr,"EN")
# check that the configuration took place correctly
# MP 30/01/07 TODO
# ans=_icepap_query(dev,addr,"?FERRMSG")
# TODO
# if(index(ans," FERR") != 1) {
# printf("ICEPAP ERROR: %s: addr: %s: unable to get first error\n",mne,addr)
# icepap_fiforst(dev)
# return
# } else {
# err=substr(ans,7)
# if(err != "OK") {
# printf("ICEPAP ERROR: %s: addr: %s: error on driver config\n",mne,addr)
# print err
# return
# }
# }
}'
#%IU%
#%MDESC%
# MACRO MOTOR:
# Check that spec is not too old to support controller parameters in
# the config file. Return 0 if > = 5.06.04-4
#
def icepap_specver() '{
local ver subver
ver[0]=0
split(VERSION,ver,".")
split(ver[2],subver,"-")
p ver
p subver
if((int(ver[0])<5)||(int(ver[1])<6)||(int(subver[0])<4)||(int(subver[1])<4)) {
return -1
}
return 0
}'
#%IU%
#%MDESC%
# MACRO MOTOR:
# Called by spec after reading the config file
#
def icepap_config(num,type,p1,p2,p3) '{
global ICEPAP[]
global ICEPAP_CAT[]
local dev
local i
# p1==?? p2==number of motors supported
if(type=="ctrl") {
icepap__debug "config(): new controller"
for(i in ICEPAP) { delete ICEPAP[i] }
ICEPAP["on"] = 0
ICEPAP["dev"]=""
if(icepap_read_cat() != 0) {
return
}
# get the MASTER
dev=icepap_ADDR
if(dev=="") {
printf("ICEPAP ERROR: missing ADDR field\n")
return
}
if(index(dev,":") == 0) { dev=sprintf("%s:5000",dev) }
ICEPAP["dev"]=dev
cdef ("cleanup_always",sprintf("icepap_cleanup(\"%s\");",dev) ,"ICEPAP")
ICEPAP["on"] = 1
}
# p1==unit p2==module p3==channel
if(type=="mot") {
local mne
local motor_ref
local opts
local dev
local addr
local i
local ret
# If the controller was not well configured then give up
if(ICEPAP["on"] != 1) { return }
# get the motor mnemonic string
mne=motor_mne(num)
# get the MASTER
ICEPAP[mne]["dev"]=""
dev=motor_par(num,"address")
if(dev==0) { return }
if(index(dev,":") == 0) { dev=sprintf("%s:5000",dev) }
ICEPAP[mne]["dev"]=dev
# NOTE MP 24Jan05: it is currently not possible to pass a string through p1
# but SPEC internally stores the "Generic Parmeter" as a string therefore
# asking it to SPEC with motor_par() is a work arround
motor_ref=motor_par(num,"misc_par_1")
icepap__debug "\""mne"\": motor type == misc_par_1: \"" motor_ref"\""
# check if the configuration of that motor has been locked
# in this case do not overwrite the configuration
ret=_icepap_islock(sprintf("%d/%d",p2,p3))
if(ret == 0)
icepap_set_mot(dev,p2,p3,motor_ref,mne);
else if(ret == 1)
printf("ICEPAP WARNING: motor configuration locked for %s\n",mne);
ICEPAP[mne]["addr"]=p2*10+p3
addr=ICEPAP[mne]["addr"]
_icepap_wr(dev,addr, "ESW 1")
_icepap_wr(dev,addr, "TDIR 0")
i=2
while((opts=motor_par(num,sprintf("misc_par_%d",i++))) != 0)
{
opts = icepap__toupper(opts)
if(opts == "SWOFF") { _icepap_wr(dev,addr, "ESW 0") }
else if(opts == "DIRINV") { _icepap_wr(dev,addr,"TDIR 1") }
}
}
}'
#%IU%
#%MDESC%
# MACRO MOTOR:
# Called by spec after reading the config file, after calling _config()
# and only if parameters are set in the config file for a motor.
#
def icepap_par(num,key,todo,p1) '{
global ICEPAP[]
local mne
mne=motor_mne(num)
}'
#%IU%
#%MDESC%
# MACRO MOTOR:
# Called by spec on motor operation.
#
def icepap_cmd(num,key,p1,p2) '{
local dev
local mne
local addr
if(num == "..") { return }
# If the controller was not well configured then give up
if(ICEPAP["on"] != 1) { return }
# get the motor mnemonic string
mne=motor_mne(num)
# get the MASTER
if(!("dev" in ICEPAP[mne])) { return }
dev=ICEPAP[mne]["dev"]
if(dev=="") { return }
# NOTE MP 2Aug05: when starting from fresh, SPEC calls
# icepap_cmd("position") before calling icepap_config() and
# therefore nothing is usable at that moment
if(!("addr" in ICEPAP[mne])) return;
addr=ICEPAP[mne]["addr"]
#
# return the current motor position in mm or deg
#
if (key == "position") {
local pos
local ans
ans= _icepap_query(dev,addr,"?P")
if(sscanf(ans,"%f",pos) != 1) {
printf("ICEPAP ERROR: %s: addr: %s: unable to get position\n",mne,addr)
return(0)
}
pos = pos / motor_par(num,"step_size")
icepap__debug sprintf("\"%s\": pos %d",mne,pos)
return(pos)
}
#
# start a motion (p1==abs pos, p2==rel pos, with pos in mm or deg)
#
if (key == "start_one") {
local pos
local cmd
local stp
local v0
local vsr
local a0
stp=motor_par(num,"step_size")
# minimum check on motion parameters
v0= _icepap_query(dev,addr,"?V0")
if(v0<=0)
{
p "ICEPAP ERROR: base rate must be >0 : "v0
exit
}
vsr= _icepap_query(dev,addr,"?VSR")
if(vsr<v0)
{
p "ICEPAP ERROR: velocity must be >= base rate : "vsr
exit
}
a0= _icepap_query(dev,addr,"?A0")
if((a0<=0) || (a0>20000))
{
p "ICEPAP ERROR: acceleration must be >0 and < 20000stp/sec2 : "a0
exit
}
cmd=sprintf("DIR %d",(p2>0))
_icepap_wr(dev,addr,cmd)
pos=fabs(p2)*stp
if((pos-int(pos)) >= 0.5) pos += 0.5;
pos=int(pos)
cmd=sprintf("GO %d",pos)
_icepap_wr(dev,addr,cmd)
return
}
#
# Check if the driver is powered and ready to use
#
if (key == "prestart_one") {
local ret
local ans
local i
#
#TODO: ?OVL != 0 print out warning msg and give up
#
return(0)
}
#
# return the current motor status
#
if (key == "get_status") {
local ret
local ans
local sta sta_neg sta_pos
local oldfashion
oldfashion=1
if(oldfashion)
{
# get moving status
ret = 0
sta = 0
ans=_icepap_query(dev,addr,"?ST")
if(sscanf(ans,"%d",sta) != 1) {
printf("ICEPAP ERROR: %s: addr: %s: unable to get status\n",mne,addr)
return(0);
}
if(sta == 1) ret |= 0x02;
# get limitswitches status
ans=_icepap_query(dev,addr,"?SW")
if(sscanf(ans,"%d %d",sta_neg,sta_pos) != 2) {
printf("ICEPAP ERROR: %s: addr: %s: unable to get limitswitches\n",mne,addr)
return(0);
}
if(sta_neg == 1) ret |= 0x04;
if(sta_pos == 1) ret |= 0x08;
}
else
{
# ICEPAP DRIVER DSP needs at least 20mS to update dual RAM
sleep(0.05)
ret = 0
ans=_icepap_query(dev,"",sprintf("?STAT %d",addr))
if(sscanf(ans,"%d",sta) != 1) {
printf("ICEPAP ERROR: %s: addr: %s: unable to get status\n",mne,addr)
return(0);
}
# get moving status
if(sta & (1<<10)) ret |= 0x02;
# get limitswitches status
if(sta & (1<<19)) ret |= 0x04;
if(sta & (1<<18)) ret |= 0x08;
}
return(ret)
}
#
# stop a single motor
#
if (key == "abort_one") {
_icepap_wr(dev,addr,"STOP")
return
}
#
# set position (p1=mm)
#
if (key == "set_position") {
_icepap_wr(dev,addr,sprintf("P %d",p1*motor_par(num,"step_size")))
return
}
#
# set acceleration (p1=ms p2=steps/sec^2)
#
if (key == "acceleration") {
_icepap_wr(dev,addr,sprintf("A0 %d",p2))
return
}
#
# set base_rate (p1=rate in Hz)
#
if (key == "base_rate") {
_icepap_wr(dev,addr,sprintf("V0 %d",p1))
return
}
#
# set slew_rate (p1=rate in Hz)
#
if (key == "slew_rate") {
_icepap_wr(dev,addr,sprintf("VSR %d",p1))
return
}
}'
#%UU% [hostname[:port]]
#%MDESC%
# Reset all the racks of the specified ICEPAP MASTER
#
def icepap_reset'{
global ICEPAP[]
local dev
if($# < 1) {
dev=getval("Icepap MASTER network name",ICEPAP["dev"])
} else {
dev="$1"
}
if(!index(dev,":")) { dev = dev":5000" }
ICEPAP["dev"]=dev
_icepap_wr(dev,"",":RACKRST")
}'
#%UU% axis
#%MDESC%
# CONFIG LOCK:
# Add a lock on the specified axis (ex: 0/2)
#
def icepap_lock '{
local a
local u c
local line
if($# != 1) {
print "USAGE: $0 axis"
print " Ex: $0 0/2"
exit
}
a="$1"
_icepap_lock(a,1)
}'
#%UU% axis
#%MDESC%
# CONFIG LOCK:
# Remove a lock on the specified axis (ex: 0/2)
#
def icepap_unlock '{
local a
local u c
local line
if($# != 1) {
print "USAGE: $0 axis"
print " Ex: $0 0/2"
exit
}
a="$1"
_icepap_lock(a,0)
}'
#%IU%
#%MDESC%
# CONFIG LOCK:
# Check that lock file exist and create empty if not
#
def _icepap_islockfile() '{
if(file_info(ICEPAP_LOCKFILE, "-w") == 0){
printf("ICEPAP WARNING: touching \"%s\"\n",ICEPAP_LOCKFILE)
if(unix(sprintf("touch %s",ICEPAP_LOCKFILE)) != 0) {
print "ICEPAP ERROR: error creating file "ICEPAP_LOCKFILE
return -1
}
}
close(ICEPAP_LOCKFILE)
if(getline(ICEPAP_LOCKFILE, "open") < 0){
printf("ICEPAP ERROR: Can\'t open file \"%s\"\n", ICEPAP_LOCKFILE)
return -1
}
return 0
}'
#%IU%(axis,lock)
#%MDESC%
# CONFIG LOCK:
# Add or remove (lock=1 or 0) a lock on the specified axis (ex: 0/2)
#
def _icepap_lock(arg,lock) '{
local a
local u c
local line
local nline
local found
if(sscanf(arg,"%d/%d",u,c)!=2) {
print "ICEPAP ERROR: bad axis syntax (Ex: \"0/2\")"
return -1
}
a=sprintf("%d/%d\n",u,c)
if(_icepap_islockfile() != 0)
return -1;
line =""
nline=""
found=0
while ((line = getline(ICEPAP_LOCKFILE)) != -1)
{
if(lock)
{
if(line == a) {
print "AXIS already locked"
close(ICEPAP_LOCKFILE)
return -1
}
} else {
if(line == a) {
printf("ICEPAP : removing lock on axis %s\n",a)
found=1
} else {
nline=sprintf("%s%s",nline,line)
}
}
}
if(lock) {
printf("ICEPAP : adding lock on axis %s\n",a)
fprintf(ICEPAP_LOCKFILE,"%s",a)
close(ICEPAP_LOCKFILE)
return 0
}
if(found == 0) {
print "ICEPAP ERROR: axis was not locked"
close(ICEPAP_LOCKFILE)
return -1
}
unix(sprintf("\\rm -f %s",ICEPAP_LOCKFILE))
unix(sprintf("touch %s",ICEPAP_LOCKFILE))
open(ICEPAP_LOCKFILE)
fprintf(ICEPAP_LOCKFILE,"%s",nline)
close(ICEPAP_LOCKFILE)
return 0
}'
#%IU%(axis)
#%MDESC%
# CONFIG LOCK:
# Return 1 if a lock exist for the specified axis (ex: 0/2)
# Return 0 if there is no lock.
# Return -1 in case of error.
#
def _icepap_islock(arg) '{
local a
local u c
local line
local nline
local found
if(sscanf(arg,"%d/%d",u,c)!=2) {
print "ICEPAP ERROR: bad axis syntax (Ex: \"0/2\")"
return -1
}
a=sprintf("%d/%d\n",u,c)
if(_icepap_islockfile() != 0)
return -1;
line =""
found=0
while ((line = getline(ICEPAP_LOCKFILE)) != -1)
{
if(line == a) {
found=1
break
}
}
close(ICEPAP_LOCKFILE)
return(found)
}'
#
# ----------------------- MACRO COUNTER implementation -----------------------
#
#%IU%(hostname:port, address)
#%MDESC%
# MACRO COUNTER:
# Read the temperature on the specified address
# Returns 0 in case of error
#
def _icepapcnt_gettemp(dev,addr) '{
local ans
local t
ans= _icepap_query(dev,addr,"?TEMP")
if(sscanf(ans,"%d",t) != 1) {
printf("ICEPAP ERROR: %s: addr: %s: unable to get temp\n",mne,addr)
icepap_chkerr(dev,ans)
icepap_fiforst(dev)
return(0)
}
return(t)
}'
#%IU%
#%MDESC%
# MACRO COUNTER:
# Called by spec after reading the config file
#
def icepapcnt_config(num,type,p1,p2,p3) '{
global ICEPAP_CNT[]
local mne
local dev
if(type=="ctrl") {
return
}
# p1 is the unit
# p2 is always 0
# p3 is the channel which is the two digits address
if(type=="cnt") {
mne=cnt_mne(num)
ICEPAP_CNT[mne]["addr"]=p3
# get the MASTER
ICEPAP_CNT[mne]["dev"]=""
dev=counter_par(num,"address")
if(dev==0) {
printf("ICEPAPCNT ERROR: missing ADDR field\n")
return
}
if(index(dev,":") == 0) { dev=sprintf("%s:5000",dev) }
ICEPAP_CNT[mne]["dev"]=dev
}
}'
#%IU%
#%MDESC%
# MACRO COUNTER:
# Called by spec on counter operation.
#
def icepapcnt_cmd(num,key,p1,p2) '{
global ICEPAP_CNT[]
local mne
local addr
local dev
if (key == "counts") {
mne=cnt_mne(num)
addr=ICEPAP_CNT[mne]["addr"]
# get the MASTER
if(!("dev" in ICEPAP_CNT[mne])) { return }
dev=ICEPAP_CNT[mne]["dev"]
if(dev=="") { return }
S[num]=_icepapcnt_gettemp(dev,addr)
}
}'
#
# ----------------------- MACRO COUNTER implementation -----------------------
#
#%IU%
#%MDESC%
# MACRO COUNTER:
# Called by spec after reading the config file
#
def icepapcalc_config(num,typ,p1,p2,p3) '{
global ICEPAP_CALC[]
local mne
local crate
local type
local dev
if(typ=="ctrl") {
ICEPAP_CALC["min_crate"]=0
ICEPAP_CALC["max_crate"]=0
return
}
# p1 is the unit
# p2 is always 0
# p3 is the channel which is the two digits address
if(typ=="cnt") {
mne =cnt_mne(num)
crate=counter_par(num,"misc_par_1")
if((crate<0) || (crate>16)) {
p "\tERROR: counter "mne" unusable: invalid crate as \"misc_par_1\""
p "\tHINT: type \"help local icepap\""
return
}
type =counter_par(num,"misc_par_2")
if((type!="min") && (type!="max") && (type!="avg")) {
p "\tERROR: counter "mne" unusable: invalid type as \"misc_par_2\""
p "\tmust be \"max\" \"min\" or \"avg\""
p "\tHINT: type \"help local icepap\""
return
}
ICEPAP_CALC[mne]["crate"]=crate
ICEPAP_CALC[mne]["type"] =type
if(crate>ICEPAP_CALC["max_crate"]) { ICEPAP_CALC["max_crate"]=crate }
if(crate<ICEPAP_CALC["min_crate"]) { ICEPAP_CALC["min_crate"]=crate }
# get the MASTER
ICEPAP_CALC["dev"]=""
dev=counter_par(num,"address")
if(dev==0) {
printf("ICEPAPCALC ERROR: missing ADDR field\n")
return
}
if(index(dev,":") == 0) { dev=sprintf("%s:5000",dev) }
ICEPAP_CALC["dev"]=dev
}
}'
#%IU%
#%MDESC%
# MACRO COUNTER:
# Called by spec on counter operation.
#
def icepapcalc_cmd(num,key,p1,p2) '{
global ICEPAP_CALC[]
local mne
local addr
local crate
local type
local t j c
local t_min t_max t_tot t_avg n_tot
local dev
if (key == "prestart_all") {
# get the MASTER
if(!("dev" in ICEPAP_CALC)) { return }
dev=ICEPAP_CALC["dev"]
if(dev=="") { return }
for(crate=ICEPAP_CALC["min_crate"];crate<=ICEPAP_CALC["max_crate"];crate++) {
t_max=0
t_min=0
t_tot=0
n_tot=0
for(j=1;j<=8;j++) {
addr=sprintf("%d%d",crate,j)
t=_icepapcnt_gettemp(dev,addr)
if(!t) { continue }
if(!t_min) { t_min=t }
if(t>t_max) { t_max=t }
if(t<t_min) { t_min=t }
t_tot += t
n_tot++
}
t_avg=t_tot/n_tot
ICEPAP_CALC[crate]["min"]=t_min
ICEPAP_CALC[crate]["max"]=t_max
ICEPAP_CALC[crate]["avg"]=t_avg
ICEPAP_CALC[crate]["n"] =n_tot
}
}
if (key == "counts") {
mne =cnt_mne(num)
type =ICEPAP_CALC[mne]["type"]
crate =ICEPAP_CALC[mne]["crate"]
S[num]=ICEPAP_CALC[crate][type]
}
}'
#
# ----------------------- direct accces macros -------------------------
#
#%UU% [hostname[:port]]
#%MDESC%
# Console implementation to communicate to icepap MASTER
#
def icepap '{
global ICEPAP[]
local dev
local line c fc
local ncomm
local his[]
local nhis
local chis
if($# < 1) {
dev=getval("Icepap MASTER network name",ICEPAP["dev"])
} else {
dev="$1"
}
if(!index(dev,":")) { dev = dev":5000" }
ICEPAP["dev"]=dev
rdef cleanup_once sprintf("_icepap_close(\"%s\")",dev)
if(sock_put(dev, "help\n") == -1) { exit }
sleep(0.1)
sock_par(dev,"timeout",0.1)
p "\n" sock_get(dev) "\n"
if(sock_put(dev, "sockhelp\n") == -1) { exit }
sleep(0.1)
sock_par(dev,"timeout",0.1)
p "\n" sock_get(dev) "\n"
ncomm = 1
nhis = 0
chis = 0
while(1) {
line = ""
printf("%d.ICEPAP console> ",ncomm);
while(1) {
c = input(-1)
if (c == "\n") {
printf("\n")
tty_cntl("cd")
break
} else if ((c == "\b" || c == "\177") && line) {
line = substr(line, 0, length(line)-1)
printf("\b \b")
} else if (asc(c) == 27) {
sleep(0.01)
c = input(-1)
sleep(0.01)
c = input(-1)
if(asc(c) == 0x41) {
if(chis) {
line = his[--chis]
printf("\r")
tty_cntl("cd")
printf("%d.ICEPAP console> %s",ncomm,line);
}
} else if(asc(c) == 0x42) {
if(chis<nhis) {
line = his[++chis]
printf("\r")
tty_cntl("cd")
printf("%d.ICEPAP console> %s",ncomm,line);
}
}
} else if (c >= " " && c <= "z") {
line = line c
printf(c)
}
}
line = icepap__toupper(line)
if(line) {
his[nhis]=line
nhis++
chis=nhis
line = line "\n"
sock_put(dev, line)
ncomm++
sleep(0.1)
}
if((line == "QUIT\n") || (line == "CLOSE\n")) {
sock_par(dev,"close")
exit
}
fc = substr(line,1,1)
if((fc=="?") || (fc=="#"))
{
# get answer of query commands
sock_par(dev,"timeout",2)
p sock_get(dev) "\n"
}
else
{
# some commands may have answer even if they are not query commands
sock_par(dev,"timeout",0.5)
p sock_get(dev) "\n"
}
}
}'
#%UU% [hostname[:port] [file] [addr] [options]]
#%MDESC%
# Program a the ICEPAP module with the specified binary file
#
def icepap_prog '{
global ICEPAP[]
local dev
local fname
local addr
local bin_l
local bin_chksum
local cmd
local opt
local sl
if($# < 1) {
dev=getval("Icepap MASTER network name or SL",ICEPAP["dev"])
} else {
dev="$1"
}
sl = (dev + 0 == dev)?1:0
if(!sl && !index(dev,":")) { dev = dev":5000" }
ICEPAP["dev"]=dev
if($# < 2) {
fname=sprintf("%s/%s",BLISSADM,"local/userconf/icepap/icepapfw0.0")
fname=getval("Binary program file",fname)
} else {
fname="$2"
}
if(file_info(fname,"-r") == 0) {
print "ERROR: unable to read file \""fname"\""
exit
}
if($# < 3) {
addr=getval("What to program (\"ALL\"|\"DRIVERS\"|\"COMM\"|\"NONE\"|addr) ",\
"NONE")
} else {
addr="$3"
}
addr = icepap__toupper(addr)
if($# < 4) {
opt=getval("Options (\"SAVE\"|\"SL\"|\"FORCE\"|\"NONE\") ","SAVE")
} else {
opt="$4"
if($#>4) { opt=opt " $5" }
if($#>5) { opt=opt " $6" }
if($#>6) { opt=opt " $7" }
if($#>7) { opt=opt " $8" }
}
opt = icepap__toupper(opt)
# Get a connection to ICEPAP
if(!sl) { _icepap_check(dev) }
bin_l = (file_info(fname,"size")/2) & 0xffffffff
local ushort array icepapfw[bin_l]
fmt_read(fname,"raw",icepapfw)
# ASCII Cmd to inform that binary data is coming
if(addr=="NONE") { addr="" }
if(opt =="NONE") { opt ="" }
cmd = sprintf("*PROG %s %s",addr, opt)
printf("\tCommand sent : \"%s\"\n", cmd)
if(sl) { ser_put(dev,sprintf("%s\n",cmd)) } else { _icepap_wr(dev,"",cmd) }
# 2 words startup mark (ex: 0xa5aa555a)
local ulong array datal[1]
datal[0]=0xa5aa555a
if(sl) { ser_put(dev, datal) } else { sock_put(dev, datal) }
# 2 words for the binary data length
datal[0]=bin_l
if(sl) { ser_put(dev, datal) } else { sock_put(dev, datal) }
# 2 words for the checksum
bin_chksum = (array_op("sum",icepapfw)) & 0xffffffff
printf("\tCheck sum : 0x%08X\n", bin_chksum)
datal[0]=bin_chksum
if(sl) { ser_put(dev, datal) } else { sock_put(dev, datal) }
# chaud devant !!!
printf("\tTransferring : %d words\n\t", bin_l)
if(sl) { bench ser_put(dev, icepapfw) } else { bench sock_put(dev, icepapfw) }
if(!sl) { sock_par(dev,"close") }
print "Binary data transferred"
}'
#%UU% [hostname:port]
#%MDESC%
# Reset the MASTER DSP
#
def icepap_mdspreset '{
global ICEPAP[]
local dev
if($# < 1) {
dev=getval("Icepap MASTER network name",ICEPAP["dev"])
} else {
dev="$1"
}
if(!index(dev,":")) { dev = dev":5000" }
ICEPAP["dev"]=dev
sock_put(dev,"_dsprst\n")
print "MASTER DSP reseted"
}'
#%UU% [hostname:port [driver]]
#%MDESC%
# Program one or all DRIVER DSP numbered from 1 to 8
# using the backplane serial line and the DDSP programm taken
# from MDSP flash (no binary transferred)
#
def icepap_ddsppgm_sl '{
local dev
local board
if($# < 1) {
dev=getval("Icepap MASTER network name","isgtmp5:5000")
} else {
dev="$1"
}
_icepap_check(dev)
# Ya un couillon au clavier ?
board=0
if($# < 2) {
board=getval("Icepap DRIVER to program from 1 to 8 (0 for all)",board)
} else {
board=$2
}
if((board<0) || (board>8))
{
print "ICEPAP: invalid channel/board "board" (valid: 1 to 8 or 0 for all)"
return
}
# ok, on peut bosser
if (board) { p "\tProgramming board: "board }
else { p "\tProgramming all boards" }
sock_put(dev,sprintf("PROG %d\n",board))
p "\tBe patient....."
p "\tHint: check messages on DSP serial line console of MASTER"
}'
#%IU%(hostname:port)
#%MDESC%
# Do not touch, needed by the "raleur"
#
def _icepap_check(dev) '{
local ans
# Allo? Gaston? Tes la?
sock_par(dev,"close")
if(!sock_par(dev,"connect"))
{
print "ICEPAP ERROR: communication program not running on MASTER"
print "Hint: reset MASTER or run \"icepap_sock\" on ",dev
exit
}
sock_par(dev,"timeout",3)
ans=_icepap_wrrd(dev,"","?_SOCKPING")
if(ans != "OK") {
print "ICEPAP ERROR: bad response from MASTER"
print "Hint: reset MASTER or run \"icepap_sock\" on ",dev
exit
}
}'
#%IU%(hostname:port)
#%MDESC%
#
def _icepap_close(dev) '{
sock_put(dev,"CLOSE\n");
sock_par(dev,"close");
}'
#%IU%(dev,addr,cmd)
#%MDESC%
#
def _icepap_wr(dev,addr,cmd) '{
local str
if(addr != "" && addr != "#") str=addr":"cmd; else str=cmd;
if (addr == "#") str = "#" str
str=str"\n"
sock_put(dev,str);
}'
#%IU%(dev,addr,cmd)
#%MDESC%
#
def _icepap_wrrd(dev,addr,cmd) '{
local ret
_icepap_wr(dev,addr,cmd)
ret=sock_get(dev);
return(ret)
}'
#%IU%(dev,addr,cmd)
#%MDESC%
#
def _icepap_query(dev,addr,cmd) '{
local ans[]
local cmd_ans
local n
local ret
local i
ret=""
cmd_ans=_icepap_wrrd(dev,addr,cmd)
n=split(cmd_ans,ans)
if(n<2) {
printf("ICEPAP ERROR: bad answer from ICEPAP\n")
return(ret)
}
if(index(ans[1],"ERROR")) {
printf("ICEPAP ERROR: from ICEPAP: %s\n",cmd_ans)
return(ret)
}
ret=substr(cmd_ans,index(cmd_ans," "))
return(ret)
}'
#
# ----------------------- test macros -------------------------
#
#%IU% hostname:port crate board
#%MDESC%
# Custom debug sequence
# (H.GONZALEZ)
#
def icepaptst '{
local board
local crate
local addr
local usage
usage ="USAGE: $0 hostname:port crate board\n"
usage = usage" hostname:port of MASTER (ex: \"isgtmp5:5000\")\n"
usage = usage" crate from 0 to 15 (look a MASTER front panel)\n"
usage = usage" board from 1 to 8\n"
# Ya un couillon au clavier ?
if($# != 3)
{
printf("%s",usage)
exit
}
dev ="$1"
crate= $2
board= $3
if((crate<0) || (crate>15) || (board<1) || (board>8))
{
printf("%s",usage)
exit
}
addr=crate*10 + board
_icepap_check(dev)
# ok, on peut bosser
sock_put(dev,sprintf("%d:?ID\n",addr));
p sock_get(dev)
sock_put(dev,sprintf("%d:?TEMP\n",addr));
p sock_get(dev)
sock_put(dev,sprintf("%d:CLR\n",addr));
icepap_set_mot(dev,crate,board,"0.25")
mvr m$2 $3
mvr m$2 -$3
icepap_set_mot(dev,crate,board,"0.5")
mvr m$2 $3
mvr m$2 -$3
icepap_set_mot(dev,crate,board,"1")
mvr m$2 $3
mvr m$2 -$3
icepap_set_mot(dev,crate,board,"2")
mvr m$2 $3
mvr m$2 -$3
icepap_set_mot(dev,crate,board,"4")
mvr m$2 $3
mvr m$2 -$3
}'
#%IU% hostname:port
#%MDESC%
# Intensive test loop on the specified Icepap MASTER (ex: "isgtmp5:5000")
#
def icepap_massacre '{
global ICEPAP[]
local dev
local ans
local i b
if($# != 1) {
dev=getval("Icepap MASTER network name",ICEPAP["dev"])
} else {
dev="$1"
}
if(!index(dev,":")) { dev = dev":5000" }
ICEPAP["dev"]=dev
for(i=0;;i++) {
p "----------------------- "date()" loop: "i
p "prog DSP en RAM"
sock_put(dev,"dsppgm\n")
sleep(5)
p "reset DSP == prog DSP en FLASH"
sock_put(dev,"dsprst\n")
sleep(3)
p "reset FIFO == test mailbox + IRQ DSP"
icepap_fiforst(dev)
sleep(3)
p "testing FIFO"
sock_put(dev,"?ID\n")
ans=sock_get(dev)
if(sscanf(ans, " ID %d",b) != 1) {
p "ERROR on FIFO"
cmd=sprintf("echo \"Error on FIFO\nloop %d\n%s\" | mailx -s \"pb\" jclement@esrf.fr ", i, date())
unix(cmd)
exit
}
p ans
}
}'
#%MACROS%
#%IMACROS%
#%AUTHOR% MP BLISS (Original 8/05).
# %BR%$Revision: 1.3 $ / $Date: 2008/07/17 14:29:34 $
#%TOC%
|