esrf

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

#%TITLE% etelmac.mac
#%DESCRIPTION% set of macros for the management of Maxe-like motors
# (the spec MAXE controller), but with new commands (not in the original MAXE
#server) to read position, move to a target and set position. With these new
#commands (DevSetValue, RevReadValue, DevLoatMot, the arguments are provided 
#in 'double' instead of 'float'
#%BR% BE CAREFULL: WITH THIS NEW MAXE SERVER, IT HAS NOT BEEN POSSIBLE TO KEEP
#THE DEVSTORE COMMAND AS BEFORE. IT TAKES NOW AN ARRAY OF 2 DOUBLE [axis,offet]
#INSTEAD OF DEVMOTORFLOAT.
#%BR%THE CONSEQUENCE IS TO CHANGE THE HOME_ETEL COMMAND WHICH CALLS DEVSTORE

#%BR% Configuration for the macro controllers
#%BR%
#%BR%\0\0\0\0\0\0\0\0\0MOTORS\0\0DEVICE\0\0\0\0\0\0\0ADDR\0\0<>MODE\0\0\0NUM\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0<>TYPE
#%BR%\0\0\0\0\0\0\0\0\0\0\0\0YES\0\0\0etelmac\0\0\0\0\0idxx/maxe/1\0\0\0\0\0\05\0\0\0\0\0\0\0\0\0\0\0Macro Motor
#%BR%\0\0\0\0\0\0\0\0\0\0\0\0YES\0\0\0etelmac\0\0\0\0\0idxx/maxe/2\0\0\0\0\0\03\0\0\0\0\0\0\0\0\0\0\0Macro Motor
#%BR%...

#%UU%
#%MDESC% toggle the debug mode
if (!(whatis("__etelmac_debug")  & 2)) rdef __etelmac_debug \'#$*\'
def etelmac_debug '{
  if ((whatis("__etelmac_debug")>>16) <= 3) { # macro length is 3 bytes: comment
     rdef __etelmac_debug "eprint"
     print "MAXE macro debug mode is ON"
  }
  else {
     rdef __etelmac_debug \'#\$*\'
     print "MAXE macro debug mode is OFF"
  }
}'



#%IU%
#%MDESC%
# MACRO MOTOR: 
# Called by spec after reading the config file
#
def etelmac_config(num,cmd,p1,p2,p3) '{
   local  dev

   __etelmac_debug ">>> etelmac_config: ",num,cmd,p1,p2,p3

   # called for each macro-hardware controller 
   # p1:unit p2: nbchan
   if(cmd=="ctrl") {
      __etelmac_debug ">>>                  new controller " etelmac_ADDR

      # get the device name
      dev=etelmac_ADDR
      if(dev=="") {
         printf("etelmac ERROR: missing ADDR field in config\n")
         return 
      }
   }

   # called for each macro motor channel
   # p1:unit p2:module p3:channel
   if(cmd=="mot") {
      #nothing
   }
   
   #returns nothing or .error.
}'



#%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 etelmac_par(num,key,todo,p1) '{
   local mne dev ch

   __etelmac_debug ">>> etelmac_par:    ",num, key, todo, p1

   # get the motor mnemonic string
   mne=motor_mne(num)
   # get the device
   dev=etelmac_ADDR
   if(dev=="") { return }
   # get the address
   ch=motor_par(mne,"channel")
  
   return

}'


#%IU%
#%MDESC%
# MACRO MOTOR: 
# Called by spec on motor operation. It manages:
#%BR% 
#%BR%- position
#%BR%- start_one 
#%BR%- get_status 
#%BR%- abort_one 
#%BR%- slew_rate 
#%BR%- base_rate 
#%BR%- acceleration 
#%BR%- search 
#%BR%- home_slew_rate 
#%BR%- set_position 

def etelmac_cmd(num,key,p1,p2) '{
   local dev mne ch

   __etelmac_debug ">>> etelmac_cmd:    ",num, key, todo, p1, p2

   if(num == "..") { return }

   # get the motor mnemonic string
   mne=motor_mne(num)
   # get the device
   dev=etelmac_ADDR
   if(dev=="") { return }
   # get the address
   ch=motor_par(mne,"channel")
      __etelmac_debug "                     channel: " ch 

 #
 # return the current dial motor position (mm or degree)
 #
   if (key == "position") {
      local pos sts 
  
      __etelmac_debug ">>> etelmac_cmd:     acting"
      sts = motor_par(num,"step_size")
      __etelmac_debug "                     " sts " steps/mm"
  
      ESRF_ERR = -1
      pos = taco_io(dev,"DevReadValue",ch)
      if (ESRF_ERR != 0) {p ESRF_ERR_MSG; return ".error."}
      if (sts == 0) {
         p "step_size: " sts " : cannot calculate dial value"
      }
      __etelmac_debug "                     reading " pos " steps"
      #need to convert in user unit
      if (sts !=0){
         __etelmac_debug "                     return  " pos/sts " userunit"
         return pos/sts
      }
      else {
         return ".error."
      }
   }

#
#       sets the dial position (mm or degree)
#
   if (key == "set_position") {
      local pos sts ret 
      double array posarg[2]
  
      __etelmac_debug ">>> etelmac_cmd:     acting"
      sts = motor_par(num,"step_size")
      __etelmac_debug "                     " sts " steps/mm"
      __etelmac_debug "                     " p1 " nm "

      ESRF_ERR = -1
      pos = p1*sts
      posarg[0] = ch
      posarg[1] = pos
      ret = taco_io(dev,"DevLoadMot",posarg)
      if (ESRF_ERR != 0) {p ESRF_ERR_MSG; return ".error."}
   }

#
# start a motion. p1: dial abs. pos., p2: dial rel. pos.
#
   if (key == "start_one") {
      local pos sts ret 
      double array poasarg[2]
  
      __etelmac_debug ">>> etelmac_cmd:     acting"
      sts = motor_par(num,"step_size")
      __etelmac_debug "                     " sts " steps/mm"
      __etelmac_debug "                     " p1 " nm "
  
      # need to convert in steps
      ESRF_ERR = -1
      pos = p1*sts
      posarg[0] = ch
      posarg[1] = pos
      ret = taco_io(dev,"DevSetValue",posarg)
      if (ESRF_ERR != 0) {p ESRF_ERR_MSG; return ".error."}
      #returns nothing
   }
 
#
# return motor status
#
#0x02: moving
#0x04: low limit
#0x08: high limit
#0x10: emergency stop
#0x20: motor fault
#0: otherwise
#
#Maxe status: DevReadState
#
#DEVALARM:      DPAP alarm (45)
#DEVMOVING:     moving (9)
#DEVON:         not moving (2)
#DEVFAULT:      driver returns an error (23)
#
#if status is DEVON, then, check the limits
#
   if (key == "get_status") {
      local ret retarr
    
      __etelmac_debug ">>> etelmac_cmd:     acting"
      retarr[0]=0
      ESRF_ERR = 0
      ret = taco_io(dev,"DevReadState",ch,retarr)
      if (ESRF_ERR != 0) {p ESRF_ERR_MSG; return ".error."}
      # moving
      if (retarr[0] == 9) {
         # no need to check more
         __etelmac_debug ">>>                  moving"
         return 0x02
      } 
      # fault
      if (retarr[0] == 23){
         __etelmac_debug ">>>                  fault"
         return 0x20
      }
      #alarm  
      if (retarr[0] == 45) {
         __etelmac_debug ">>>                  DPAP alarm"
         return 0x20
      }
      # on
      if (retarr[0] == 2) {
         # devon, do now check the limit
         ESRF_ERR = 0
         ret = taco_io(dev,"DevReadSwitches",ch)
         if (ESRF_ERR != 0) {p ESRF_ERR_MSG; return ".error."}
         if (ret == 0) {
            # limitsoff
            __etelmac_debug ">>>                  on"
            return 0
         }
         else if (ret == 1) {
            # negatlimit
            __etelmac_debug ">>>                  negat limit"
            p "etelmac: negative limit on device " dev "channel " ch
            return 0x04
         }
         else {
            # positlimit or both
            p "etelmac: positive limit on device " dev "channel " ch
            __etelmac_debug ">>>                  positlimit"
            return 0x08
         }
      }
      else {
         p "etelmac: unexpected status value from device " dev 
         return ".error."
      }
    
   }

#
# abort a motion
#   
   if (key == "abort_one") {
      local pos
  
      __etelmac_debug ">>> etelmac_cmd:     acting"
      ESRF_ERR = -1
      pos = taco_io(dev,"DevAbortCommand",ch)
      if (ESRF_ERR != 0) {p ESRF_ERR_MSG; return ".error."}
      #returns nothing
   }

#
# velocity  -  called when doing the motion
#
   if (key == "slew_rate") {
      __etelmac_debug ">>> etelmac_par:     acting"
      ESRF_ERR = -1
      esrf_io(dev,"DevSetVelocity",ch,p1)
      if (ESRF_ERR != 0) {p ESRF_ERR_MSG}
   }

#
# base rate - called when doing the motion
#
   if (key == "base_rate") {
      __etelmac_debug ">>> etelmac_par:     acting"
      ESRF_ERR = -1
      esrf_io(dev,"DevSetFirstStepRate",ch,p1)
      if (ESRF_ERR != 0) {p ESRF_ERR_MSG;return ".error."}
   } 


#
# acceleration [p1 in msec, p2 in steps/sec/sec] - called when doing the motion
# 
   if (key == "acceleration") {
       __etelmac_debug ">>> etelmac_par:     acting"
       ESRF_ERR = -1
       # take p2 parameter as we give steps/sec/sec
       esrf_io(dev,"DevSetAcceleration",ch,p2)
       if (ESRF_ERR != 0) {p ESRF_ERR_MSG}
    }

#
# home_slew_rate - called when doing the motion
# 
   if (key == "home_slew_rate") {
       __etelmac_debug ">>> etelmac_par:     acting"
       ESRF_ERR = -1
       esrf_io(dev,"DevSetHomeSlewRate",ch,p1)
       if (ESRF_ERR != 0) {p ESRF_ERR_MSG}
    }

#
# search        - home search
# 
   if (key == "search") {
       __etelmac_debug ">>> etelmac_par:     acting"
       ESRF_ERR = -1
       # p1: home/home+/home-/lim+/lim-
       # Note: lim+ or lim- search can be done using DevSetContinuous
       # and is not presently implemented in the Maxe spec - C code
       if (p1 == "home") {
          esrf_io(dev,"DevMoveReference",ch,0)
          if (ESRF_ERR != 0) {p ESRF_ERR_MSG}
       }
       else if (p1 == "home+") {
          esrf_io(dev,"DevMoveReference",ch,1)
          if (ESRF_ERR != 0) {p ESRF_ERR_MSG}
       }
       else if (p1 == "home-") {
          esrf_io(dev,"DevMoveReference",ch,-1)
          if (ESRF_ERR != 0) {p ESRF_ERR_MSG}
       }
       else if (p1 == "lim+") {
          esrf_io(dev,"DevSetContinuous",ch,1)
          if (ESRF_ERR != 0) {p ESRF_ERR_MSG}
       }
       else if (p1 == "home-") {
          esrf_io(dev,"DevSetContinuous",ch,-1)
          if (ESRF_ERR != 0) {p ESRF_ERR_MSG}
       }
    }

}'



#%MACROS%
#%IMACROS%
#%AUTHOR%MCD
# %BR%$Revision: 1.1 $ / $Date: 2013/01/25 10:18:13 $
#%TOC%