esrf

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

#%TITLE% N354CORE.MAC 
#
#%NAME%
# Macros to control ISG/CSEL controller based on TRITON Linux and XILINX
#
#%CATEGORY% Acquisition, Isg
#
#%END%
#



#%IU%(string, case)
#%MDESC%
# Convert to lower (case==1) or to upper (case==0) case the string passed
#
def n354__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 n354__tolower(str) '{return((str!="")?n354__tocase(str, 1):"")}'


#%IU%(string)
#%MDESC%
# Return the upper string of the string passed
#
def n354__toupper(str) '{return((str!="")?n354__tocase(str, 0):"")}'



#%IU%(ans)
#%MDESC%
# Check if the answer given contains an ERROR and if yes
# request the error message
#
def n354_chkerr(dev,ans) '{
   if(index(ans,"ERROR") == 1) {
    ans= _n354_wrrd(dev,0,"?ERR 1")
    print ans;
   }
}'






#
# ----------------------- direct accces macros -------------------------
#

#%UU% [hostname[:port]]
#%MDESC%
# Console implementation to communicate to APD TRITON
#
def n354 '{
 global APD[]
 global APD_NCOMM
 global APD_HIST[]
 global APD_NHIST
 global APD_CHIST
 local  dev
 local  line c fc
 local  args[]
 

 if($# < 1) {
  dev=getval("APD CONTROLER network name",APD["dev"])
 } else {
  dev="$1"
 }

 if(!index(dev,":")) { dev = dev":5001" }
 APD["dev"]=dev


 cdef("cleanup_once",sprintf("_n354_close(\"%s\")",dev),"APD")

 if(sock_put(dev, "?help\n") == -1) { exit }
 sleep(0.1)
 sock_par(dev,"timeout",0.1)
 p "\n" sock_get(dev) "\n"
 
 while(1) {
  line = ""
  printf("%d.APD console> ",APD_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.05)
      c = input(-1)
      sleep(0.01)
      c = input(-1)
      if(asc(c) == 0x41) {
       if(APD_CHIST) { 
        line = APD_HIST[--APD_CHIST] 
        printf("\r")
        tty_cntl("cd")
        printf("%d.APD console> %s",APD_NCOMM,line);
       }
      } else if(asc(c) == 0x42) {
       if(APD_CHIST<APD_NHIST) { 
        line = APD_HIST[++APD_CHIST] 
        printf("\r")
        tty_cntl("cd")
        printf("%d.APD console> %s",APD_NCOMM,line);
       }
      }
    } else if (c >= " " && c <= "z") {
      line = line c
      printf(c)
    }
    sleep(0.01)
  }

  if(line) {
   APD_HIST[APD_NHIST]=line
   APD_NHIST++
   APD_CHIST=APD_NHIST
  }

  if(split(line,args))
  {
   if(whatis(args[0]) & 0x00000002)
   {
    eval(line)
    continue
   }
  }

  if(line) {
   line = n354__toupper(line)
   line = line "\n"
   sock_put(dev, line)
   APD_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"
  }

 }
}'

#%IU%(string, n)
#%MDESC%
# Parse the string to get the APD device to talk to.
# Try to get as nth argument (starting from 1) in the string, 
# if not prompt the user.
#
def _n354_getdev(str, i) '{
 local args[]
 local n
 local dev

 n=split(str,args)

 if(n < i) {
  dev=getval("APD network name",APD["dev"])
 } else {
  dev=args[i-1]
 }

 if(!index(dev,":")) { dev = dev":5001" }
 APD["dev"]=dev

 return(dev)
}'




#%IU%(string, n)
#%MDESC%
# Parse the string to get the APD tocho file.
# Try to get as nth argument (starting from 1) in the string, 
# if not prompt the user.
#
def _n354_getfname(str, i) '{
 local args[]
 local n
 local fname
 local fdir
 local uxcom
 local aux
 local m
 local flist[]
 local f


 n=split(str,args)

 if(n < i) {
  fdir ="/segfs/linux/drivers/arm/triton/apd/BIT"
  if(!file_info(fdir)) fdir=sprintf("%s/%s",BLISSADM,"local/N354");
  
  uxcom = "cd " fdir "; ls -rt *.bit"
  unix(uxcom, aux)
  m = split(aux, flist, "\n")
  for(m--;m;m--)
  {
   f=flist[m]
   if(f=="") continue;
   if(file_info(sprintf("%s/%s",fdir,f),"isdir")) continue;
   break;
  }

  fname=sprintf("%s/%s",fdir,flist[m])
  fname=getval("Binary program file",fname)
 } else {
  fname=args[i-1]
 }

 if(file_info(fname,"-r") == 0) {
  print "ERROR: unable to read file \""fname"\""
  exit
 } 

 return(fname)
}'



#%IU%(string, n)
#%MDESC%
# Parse the string to get the addr for programming.
# Try to get as nth argument (starting from 1) in the string, 
# if not prompt the user.
#
def _n354_getaddr(str, i) '{
 local args[]
 local n
 local addr

 n=split(str,args)

 if(n < i) {
  addr=getval("What to program (\"ALL\"|\"DRIVERS\"|\"COMM\"|\"NONE\"|addr) ",\
     "NONE")
 } else {
  addr=args[i-1]
 }
 addr = n354__toupper(addr)
 if(addr=="NONE") { addr="" }

 return(addr)
}'


#%IU%(string, n)
#%MDESC%
# Parse the string to get the options for programming.
# Try to get as nth argument (starting from 1) in the string, 
# if not prompt the user. 
# Any remaining argument is also return as option.
#
def _n354_getopts(str, i) '{
 local args[]
 local n
 local opt

 n=split(str,args)

 if(n < i) {
  opt=getval("Options (\"SAVE\"|\"SL\"|\"FORCE\"|\"NONE\") ","SAVE")
 } else {
  opt=args[i-1]
  for(;i<n;i++) { opt=opt " " args[i] }
 }
 opt = n354__toupper(opt)
 if(opt =="NONE") { opt ="" }

 return(opt)
}'


#%IU%(string, n)
#%MDESC%
# Parse the string to get the rack addresses for programming.
# Try to get as nth argument (starting from 1) in the string, 
# if not prompt the user. 
# Any remaining argument is also return as option.
#
def _n354_getracks(str, i) '{
 local args[]
 local n
 local racks

 n=split(str,args)

 if(n < i) {
  racks=getval("List of racks (ex: 0 3)",0)
 } else {
  racks=args[i-1]
  for(;i<n;i++) { racks=racks " " args[i] }
 }
 racks = n354__toupper(racks)

 return(racks)
}'




#%UU% hostname[:port] [file] 
#%MDESC%
# Program a the APD module with the specified binary file
#
def n354_prog '{
 global APD[]
 local dev
 local fname
 local addr
 local cmd
 local opt
 local cmd_ans
 

 # Get args or prompt them to the user
 dev   = _n354_getdev  ("$*", 1)
 fname = _n354_getfname("$*", 2)


 # Get a connection to APD
 _n354_check(dev)

 cmd = sprintf("*PROGBIT %s %s",addr, opt)
 printf("\tCommand sent  : \"%s\"\n", cmd)
 _n354_wr(dev,"",cmd)


 # Send the binary data
 _n354_wrbin(dev,fname)

}'




#%IU%(dev,fname)
#%MDESC%
# Send the contain of the file to the APD using the ISG
# binary transfert protocole.
#
def _n354_wrbin(dev,fname) '{
 local bin_l
 local bin_chksum


 bin_l = (file_info(fname,"size")/2) & 0xffffffff

 local ushort array apdfw[bin_l]
 fmt_read(fname,"raw",apdfw)

 # 2 words startup mark (ex: 0xa5aa555a)
 local ulong array datal[1]
 datal[0]=0xa5aa555a
 sock_put(dev, datal) 


 # 2 words for the binary data length
 datal[0]=bin_l
 sock_put(dev, datal)


 # 2 words for the checksum 
 bin_chksum = (array_op("sum",apdfw)) & 0xffffffff
 printf("\tCheck sum     : 0x%08X\n", bin_chksum)
 datal[0]=bin_chksum
 sock_put(dev, datal)

 # chaud devant !!!
 printf("\tTransferring  : %d words\n", bin_l)
 sock_put(dev, apdfw)

 sock_par(dev,"close") 
}'




#%IU%(hostname:port)
#%MDESC%
# Do not touch, needed by the "raleur"
#
def _n354_check(dev) '{
 local  ans


 # Allo? Gaston? Tes la?
 sock_par(dev,"close")
 if(!sock_par(dev,"connect"))
 {
  print "APD ERROR: communication program not running on CONTROLER"
  print "Hint: reset CONTROLER or run \"n354_sock\" on ",dev
  exit
 }
 sock_par(dev,"timeout",3)
 ans=_n354_wrrd(dev,"","?PING")
 if(ans != "OK") {
  print "APD ERROR: bad response from CONTROLER"
  print "Hint: reset CONTROLER or run \"n354_sock\" on ",dev
  exit
 }

}'



#%IU%(hostname:port)
#%MDESC%
#
def _n354_close(dev) '{
 sock_put(dev,"_SOCKCLOSE\n");
 sock_par(dev,"close");
}'


#%IU%(dev,addr,cmd)
#%MDESC%
#
def _n354_wr(dev,addr,cmd) '{
 local str


 if(addr != "" && addr != "#") str=addr":"cmd; else str=cmd;
 if (addr == "#") str = "#" str
 str=str"\n"
 sock_par(dev,"flush")
 sock_put(dev,str);
}'


#%IU%(dev,addr,cmd)
#%MDESC%
#
def _n354_wrrd(dev,addr,cmd) '{
 local ret
 
 _n354_wr(dev,addr,cmd)
 ret=sock_get(dev);
 return(ret)
}'


#%IU%(dev,addr,cmd)
#%MDESC%
#
def _n354_query(dev,addr,cmd) '{
  local ans[]
  local cmd_ans
  local n
  local ret
  local i


  ret=""

  cmd_ans=_n354_wrrd(dev,addr,cmd)
  n=split(cmd_ans,ans)
  if(n<2) {
   printf("APD ERROR: bad answer from DSP\n")
   return(cmd_ans)
  }
  
  if(index(ans[1],"ERROR")) {
   printf("APD ERROR: from DSP: %s\n",cmd_ans)
   return(cmd_ans)
  }

  ret=substr(cmd_ans,index(cmd_ans," ")+1)
  return(ret)

}'









#%MACROS%
#%IMACROS%
#%AUTHOR% MP BLISS (Original 11/08).
# %BR%$Revision: 1.1 $ / $Date: 2009/11/06 12:03:18 $
#%TOC%