esrf

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

#%TITLE% WCCOMM.MAC
#
#%NAME%
#  WCCOMM.MAC - Macros to communicate with WAGO onbaord programs.
#
#%DESCRIPTION%
#
#%END%


#%UU%
#%MDESC%
#  Edit and upload the configuration file into the controller
#
def wc_init '{
   local silent

   if ($# != 1) {
      print "Usage: $0 wc_name"
      exit
   }
   silent = -1
   _wc_init("$1")
}'

#%IU%
#%MDESC%
#
def _wc_init(wcname) '{
   global WC[] WC_ERR[] WC_TYPE[] WC_NRUNIT WC_U 
   local file
   local ds



   _wc_loaderr

   for (WC_U = 1; WC_U <= WC_NRUNIT; WC_U++) 
      if (WC[WC_U]["name"] == wcname)
         break 

   WC[WC_U]["name"] = wcname
 
   ds=SPECBL "/" wcname "/wc"
   ESRF_ERR = -1
   if ((state_str = esrf_io(ds, "DevStatus")) < 0) {
      WC[WC_U]["id"] =  modb_addnode (wcname, 1, wcname)
      WC[WC_U]["mode"] = "spec"
   } else if (index(state_str, "WAGODS")) {
      esrf_io(ds, "DevSetDebug", 4)
      WC[WC_U]["mode"] = "wagoDS"
      WC[WC_U]["ds"] =  ds
   } else {
      return(-1)
   }

   if (WC_U > WC_NRUNIT)
      WC_NRUNIT = WC_U

}'


#%IU%
#%MDESC%
#
def _wc_loaderr '{
   WC_ERR[1]  = "Communication timeout"
   WC_ERR[2]  = "Bad command"
   WC_ERR[3]  = "Bad parameter(s)"
   WC_ERR[4]  = "Bad instance number"
   WC_ERR[5]  = "Instance is not enabled"
   WC_ERR[6]  = "No more instances available"
   WC_ERR[7]  = "Bad Function"
   WC_ERR[8]  = "Bad channel"
   WC_ERR[9]  = "No more channels available"
   WC_ERR[10] = "Error X"
   WC_ERR[11] = "Error X"
   WC_ERR[12] = "Error X"
}'



#%IU%(wago_name)
#%MDESC%
#
def wc_name2unit(wcname) '{
   for (WC_U = 1; WC_U <= WC_NRUNIT; WC_U++) 
      if (WC[WC_U]["name"] == wcname)
         break 

   return WC_U
}'

#%IU%(wago_unit)
#%MDESC%
#
def wc_get_unit(param) '{
   local msg

   if (WC_NRUNIT == 0) {
      print "There is no configured WAGO unit"
      exit
   }
   else if (param != 0)
      WC_U = param
   else if (WC_NRUNIT == 1)
      WC_U = 1
   else {
      msg = sprintf("Enter the WAGO unit [1-%d]", WC_NRUNIT);
      WC_U = getval(msg, 1)
   }
  
   if ((WC_U == 0) || (WC_U > WC_NRUNIT)) {
      print "Invalid unit", WC_U
      exit
   }

   return WC_U
}'


#%UU% <unit> <command> <p0> [<p1> <p2> ...
#%MDESC%
#
def wccomm '{
   local nres res[]

   _wccomm $*
}'

#%IU%
#%MDESC%
#
def _wccomm '{
   local i comm npar par[]

   if ($# < 2) {
      print "Usage: $0 <unit> <command> <p0> [<p1> <p2> ...]"
      exit
   }

   wc_get_unit($1)

   npar = $# - 2
   par[0] = $3
   par[1] = $4
   par[2] = $5
   par[3] = $6
   par[4] = $7
   par[5] = $8

   if ((nres = send_wccomm(WC_U, $2, npar, par, res)) < 0) {
      if (silent != -1)
         printf("ERROR %d: %s.\n", -nres, WC_ERR[-nres])
   } else if (!nres) {
      if (!silent)
         print "OK."
   } else {
      if (!silent) {
         printf("OK. : ")
         for (i = 0; i < nres; i++)
            printf(" 0x%04X", res[i] & 0xFFFF)
         print
      }
   }
}'


#%IU%
#%MDESC%
#
def send_wccomm(unit, comm, npar, par, res) '{

 # Note MP 28Jan03: Wago seems to have limited the nb of words that can
 # be sent over the modbus. Normally we should not have to limit to 100
 constant WC_NPAR_MAX 100
 constant WC_NRES_MAX 100

 local short array wcd[4 + WC_NRES_MAX]
 local i outcmd nres tout

 # NOTE 11Sep2004 MP: send_wccomm() can be called with unit=="wcid32a" for
 # instance by autof.mac macros. Therefore add this name to unit conversion
 # to be backward compatible.
 if(int(unit) != unit) {
   wc_name2unit(unit)
   unit=WC_U
 }

 if (WC[unit]["mode"] == "wagoDS") {

   # can not use wcd because its dimension is passed by spec to esrf_io()
   local wcd[]
   wcd[0] = (comm &= 0xFFFF)
   if (npar) {
      for (i = 0; i < npar ; i++)
         wcd[1 + i] = par[i]
   }
   if((nres = esrf_io(WC[unit]["ds"],"DevWcComm",wcd,res)) == -1) { exit }
  
 } else {
   modb_write_reg(WC[unit]["id"], 256, 0)
   for (tout = time() + 1;;) {
      modb_read_inpregs(WC[unit]["id"], 256, 4 + WC_NRES_MAX, wcd)
      if (wcd[2] == 0)
         break
      else if (time() > tout) {
         print "WC Timeout sending command", comm
         return(-1)
      }
   }
   wcd[0] = 0xA5A5
   wcd[1] = (comm &= 0xFFFF)
   wcd[2] = npar
   if (npar) {
      for (i = 0; i < npar ; i++)
         wcd[3 + i] = par[i]
   }
   modb_write_regs(WC[unit]["id"], 256, 3 + npar, wcd)

   for (tout = time() + 1;;) {
      modb_read_inpregs(WC[unit]["id"], 256, 4 + WC_NRES_MAX, wcd)
      outcmd = wcd[2] & 0xFFFF
      nres =  wcd[3] 
      if (nres > WC_NRES_MAX) {
         print "WC Too many results:", nres
         return(-1)
      }
#p i++, wcd
      if (outcmd != 0) {
         if (outcmd == comm)
            break
         else
            return(-wcd[4])

      } else if (time() > tout) {
         print "WC Timeout"
         return(-1)
      }
   }
   nres =  wcd[3] 
   if (nres) {
      for (i = 0; i < nres; i++)
         res[i] = wcd[4 + i]
   }
 }
 return(nres)
}'


#%MACROS%
#%IMACROS%
#%DEPENDENCIES%
# None
#%AUTHOR%
# P.Fajardo, MP
# %BR%$Revision: 1.1 $ / $Date: 2004/09/28 07:05:07 $
#%TOC%