esrf

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

# srssimsetup unit GPIB|SERIAL address 
def srssimsetup '{
  local unit msg str i retries

  global SRSSIM[]
  byte array srssim_buffer[1024]

  unit = ($# > 0) ? $1 : getval("Enter the SRS-SIM unit", 0)
  
  msg = sprintf("Unit %d comm. type [GPIB | SERIAL]", unit)
  str = SRSSIM[unit]["comm"]
  str = ($# > 1) ? "$2" : getval(msg, (str == 0) ? "GPIB" : str)
  if ((str != "GPIB") && (str != "SERIAL")) {
    print "Invalid SRS-SIM unit", unit, "communication type:", str
    exit
  }
  SRSSIM[unit]["comm"] = str
  msg = sprintf("Unit %d %s address", unit, str)
  SRSSIM[unit]["addr"] = ($# > 2) ? "$3" : getval(msg, SRSSIM[unit]["addr"])

  SRSSIM[unit]["init"] = 0

  if (SRSSIM[unit]["comm"] == "SERIAL") {
    if (srssim_low_comm(unit, "CONS 0", 0, 1) == -1)
      exit
    if (srssim_low_comm(unit, "TERM D,LF", 0, 1) == -1)
      exit
  } else {
    if (gpib_poll(SRSSIM[unit]["addr"]) == -1) {
      print "Unresponsive GPIB device at address", SRSSIM[unit]["addr"]
      exit
    }
    if (gpib_cntl(SRSSIM[unit]["addr"], "sdc") == -1) {
      print "Error sending GPIB Device Clear to address", SRSSIM[unit]["addr"]
      exit
    }
  }

  SRSSIM[unit]["init"] = 1
  if (unit >= SRSSIM["nrunit"])
    SRSSIM["nrunit"] = unit + 1

  for (i = 1; i <= 0xd; i++) {
    portkey = srssim_portkey(unit, i)
    if (SRSSIM[portkey]["init"] == 1)
      SRSSIM[portkey]["init"] = 0
  }

  str = srssim_cmd(unit, 0, "*IDN?")
  retries = 10
  for (i = 0; i < retries; i++) {
    if (str == -1)
      exit
    if (index(str, "Stanford_Research_Systems") > 0)
      break
    str = srssim_low_comm(unit, "", 1)
  }   
  if (i == retries) {
    printf("Error in %s comm. to unit %d addr. %d after %d retries\n", \
           SRSSIM[unit][comm], unit, SRSSIM[unit]["addr"],  retries)
    exit
  }

  str = srssim_cmd(unit, 0, "*IDN?")
  printf("Initialised unit %d:\n   %s\n", unit, str)

  if (srssim_register_module(sprintf("crate%d", unit), unit, 0) == -1)
    return 0
}'


def srssimunsetup '{
}'


def srssim_portkey(unit, port, key) '{
  local portkey

  portkey = sprintf("%d:%X", unit, port)
  if (key == 0)
    return portkey

  if ("module" in SRSSIM[portkey])
    portkey = SRSSIM[portkey]["module"]

  return (key in SRSSIM[portkey]) ? SRSSIM[portkey][key] : ""
}'


def srssimdebugon '{
  local unit
  unit = ($# > 0) ? $1 : getval("Enter the SRS-SIM unit", 0)
  SRSSIM[unit]["debug"] = 1
}'
  
def srssimdebugoff '{
  local unit
  unit = ($# > 0) ? $1 : getval("Enter the SRS-SIM unit", 0)
  SRSSIM[unit]["debug"] = 0
}'
  
def srssim_chr_repr(chr) '{
  local achr

  achr = asc(chr)
  if (chr == "\\")
    return "\\\\"
  else if ((achr >= 0x20) && (achar < 0x7f))
    return chr
  else if (chr == "\r")
    return "\\r"
  else if (chr == "\n")
    return "\\n"
  else if (chr == "\t")
    return "\\t"
  else if (chr == "\b")
    return "\\b"
  else
    return sprintf("\\x%02x", achr)
}'

def srssim_debug_str(cmd) '{
  local str i

  str = ""
  for (i = 1; i <= length(cmd); i++)
    str = sprintf("%s%s", str, srssim_chr_repr(substr(cmd, i, 1)))

  return str
}'

def srssim_check_unit_port(unit, port, portinit) '{
  local portkey

  if (SRSSIM[unit]["init"] != 1) {
    print "Error: SRS-SIM unit", unit, "not initialized"
    return -1
  }
  if ((port < 0) || (port > 0xd)) {
    print "Invalid port:", port, "- Must be between 0 and 13"
    return -1
  }

  portkey = srssim_portkey(unit, port)
  if (portinit && (SRSSIM[portkey]["init"] != 1)) {
    if (srssim_init_port(unit, port) == -1) {
      printf("Error: could not initialise SRS-SIM port %X at unit %d\n", \
             port, unit)
      return -1
    }
  }
  return 0
}'


def srssim_low_comm(unit, cmd, waitresp, nocheckinit) '{
  local str ret comm addr len chr

  global srssim_blen srssim_bptr

  if (!nocheckinit && (srssim_check_unit_port(unit, 0) == -1))
    return -1

  comm = SRSSIM[unit]["comm"]
  addr = SRSSIM[unit]["addr"] 
  if (cmd != "") {
    str = sprintf("%s\n", cmd)
    if (SRSSIM[unit]["debug"])
      printf("SRSSIM[%d]: Tx: \"%s\"\n", unit, srssim_debug_str(str))
    ret = (comm == "GPIB") ? gpib_put(addr, str) : ser_put(addr, str)
    if (ret == -1) {
      printf("Error sending %s command \"%s\" to unit %d (addr: %s)\n", \
             comm, srssim_debug_str(str), unit, addr)
      return -1
    }
  }

  ret = 0
  if (waitresp) {
    if (comm == "GPIB") {
      chr = 0
      str = ""
      while (chr != asc("\n")) {
        if ((srssim_blen == 0) || (srssim_bptr == srssim_blen)) {
          ret = gpib_get(addr, srssim_buffer)
          if (ret == -1)
            break
          srssim_blen = ret
          srssim_bptr = 0
        }
        while ((srssim_bptr < srssim_blen) && (chr != asc("\n"))) {
          chr = srssim_buffer[srssim_bptr++]
          str = sprintf("%s%c", str, chr)
        }
        ret = str
        if (srssim_blen == 0)
          break
      }
    } else
      ret = ser_get(addr, "\n")
    if (ret == -1) {
      printf("Error waiting %s response to \"%s\" on unit %d (addr: %s)\n", \
             comm, srssim_debug_str(str), unit, addr)
    } else if (SRSSIM[unit]["debug"]) {
      printf("SRSSIM[%d]: Rx: \"%s\"\n", unit, srssim_debug_str(ret))
    }
  }

  return ret
}'


def srssim_init_port(unit, port) '{
  local str portkey val idn

  if (srssim_check_unit_port(unit, port) == -1)
    return -1

  val = srssim_portkey(unit, port, "term")
  val = (val != "") ? val : "CR"
  if (srssim_cmd(unit, 0, sprintf("TERM %X,%s", port, val)) == -1)
    return -1

  val = srssim_portkey(unit, port, "baud")
  if (val != "")
    if (srssim_cmd(unit, 0, sprintf("BAUD %X,%s", port, val)) == -1)
      return -1
  
  idn = srssim_portkey(unit, port, "idn")
  
  if ((port >= 1) && (port <= 9)) {
    if (srssim_cmd(unit, port, "CONS 0") == -1)
      return -1
    if (srssim_cmd(unit, port, "TERM CR") == -1)
      return -1
    idn = "*IDN?" 
  }

  if (port > 0) {
    sleep(0.5)
    if (srssim_cmd(unit, 0, sprintf("FLSH %X", port)) == -1)
      return -1
  }

  if (idn != "") {
    str = srssim_cmd(unit, port, idn)
    if (str == -1)
      return -1

    printf("Initialised port %X at unit %d:\n   %s\n", port, unit, str)
  }

  portkey = srssim_portkey(unit, port)
  SRSSIM[portkey]["init"] = 1
  return 0
}'


def srssim_read_port(unit, port) '{
  local str i j phase nchr ret aux

  str = ""
  while (1) {
    ret = srssim_low_comm(unit, sprintf("GETN? %X,100", port), 1)
    if (ret == -1)
      return -1
    i = index(ret, "#")
    if (i == 0) {
      print "Error: \"#\" not found in response"
      return -1
    } else if (i > 1)
      print "Oops: found remaining characters from previous response"
    i++
    aux = substr(ret, i++, 1) + 0
    for (nchr = j = 0; j < aux; j++)
      nchr = nchr * 10 + int(substr(ret, i + j, 1))
    if (nchr == 0) {
      if (str != "")
        break
      continue
    }
    i += aux

    ret = substr(ret, i)
    i = 0
    while (1) {
      j = i
      i += length(ret)
      aux = (i > nchr) ? 1 : 0
      str = sprintf("%s%s", str, substr(ret, 1, i - j - aux))
      if (i == nchr + 1)
        break
      ret = srssim_low_comm(unit, "", 1)
      if (ret == -1) 
        return -1
    }
    if (i < nchr + 1)
      printf("Error: incomplete answer: read=%d, expected=%d\n", i, nchr)
  }

  return str
}'


def srssim_cmd(unit, port, cmd, forcewait, nofilter) '{
  local waitresp str portkey

  
  waitresp = (index(cmd, "?") > 0) || forcewait
  if (port == 0)
    return srssim_low_comm(unit, cmd, waitresp)

  waitresp |= (srssim_portkey(unit, port, "forcewait") == 1)

  if (srssim_check_unit_port(unit, port) == -1)
    return -1

  if (cmd != "") {
    str = sprintf("SNDT %X,\"%s\"", port, cmd)
    if (srssim_low_comm(unit, str, 0) == -1)
      return -1
  }

  if (!waitresp)
    return ""

  str = srssim_read_port(unit, port)
  if (!nofilter)
    str = srssim_filter_resp(unit, port, cmd, str)

  return str
}'


def srssim_filter_resp(unit, port, cmd, resp) '{
  local i

  if ((resp == -1) || (resp == ""))
    return resp

  if (srssim_portkey(unit, port, "nostrip") != 1) {
    while ((length(resp) > 0) && (index("\r\n", substr(resp, 1, 1)) > 0))
      resp = substr(resp, 2)
    while ((length(resp) > 0) && \
           (index("\r\n", substr(resp, length(resp))) > 0))
      resp = substr(resp, 1, length(resp) - 1)
  }

  if (srssim_portkey(unit, port, "echo") == 1) {
    i = index(resp, cmd)
    if (i == 0) {
      print "Oops: did not get echo from unit", unit, "port", port
      return resp
    } else if (i > 1) {
      print "Oops: got bytes before echo from unit", unit, "port", port
    }
    i += length(cmd)
    while ((i <= length(resp)) && (index("\r\n", substr(resp, i, 1)) > 0))
      i++
    resp = substr(resp, i)      
  }

  return resp
}'


def srssim_module_cmd(modname, cmd, forcewait, nofilter) '{
  local unit port

  if (!("unit" in SRSSIM[modname]) || !("port" in SRSSIM[modname])) {
    print "Error: SRS-SIM module", modname, "not defined"
    return -1
  }

  unit = SRSSIM[modname]["unit"]
  port = SRSSIM[modname]["port"]
  return srssim_cmd(unit, port, cmd, forcewait, nofilter)
}'


def srssim_register_module(modname, unit, port, pars, parsbefore) '{
  local i npar pararr[] ntok tokarr[] parstr portkey

  if ((modname == "") || (modname + 0 == modname)) {
    print "Invalid module name:", modname, "- It must start with a letter"
    return -1
  }
  
  parstr = ""
  npar = split(pars, pararr)
  for (i = parsbefore; i < npar; i++) {
    ntok = split(pararr[i], tok, "=")
    if (ntok > 2) {
      print "Error decoding module", modname, "parameters:", pararr[i]
      return -1
    }
    SRSSIM[modname][tok[0]] = (ntok > 1) ? tok[1] : 1
    parstr = sprintf("%s%s%s", parstr, (i > 0) ? " " : "", tok[0])
  }
  SRSSIM[modname]["unit"] = unit
  SRSSIM[modname]["port"] = port
  SRSSIM[modname]["pars"] = parstr

  portkey = srssim_portkey(unit, port)
  SRSSIM[portkey]["module"] = modname
  SRSSIM[portkey]["init"] = 0
 
  if (srssim_check_unit_port(unit, port, 1) == -1)
    return -1

  for (i = 0; i < SRSSIM["module"]["nrmod"]; i++)
    if (SRSSIM["module"][i] == modname)
      break
  SRSSIM["module"][i] = modname
  if (i == SRSSIM["module"]["nrmod"])
    SRSSIM["module"]["nrmod"]++

  setup_tail("srssim_module", modname)

  return 0
}'


def srssim_unregister_module(modname) '{
  local i j last npar pars[]

  last = -1
  for (i = 0; i < SRSSIM["module"]["nrmod"]; i++) {
    if (SRSSIM["module"][i] == modname) {
      npar = split(SRSSIM[modname]["pars"], pars)
      for (j = 0; j < npar; j++)
        delete SRSSIM[modname][pars[j]]
      delete SRSSIM[modname]["port"] SRSSIM[modname]["unit"]
      delete SRSSIM[modname]["pars"] SRSSIM["module"][i]

      if (i == SRSSIM["module"]["nrmod"] - 1)
        SRSSIM["module"]["nrmod"] = last + 1
      return 0
    } else if (i in SRSSIM["module"])
      last = i
  }

  return -1
}'


def srssim_moduleunsetup '{
  srssim_unregister_module("$1")
}'


def srssimaddmodule '{
  local modname unit port

  modname = ($# > 0) ? "$1" : getval("Enter SRS-SIM module name", "")
  unit = SRSSIM[modname]["unit"]
  unit = ($# > 1) ? $2 : getval("Enter the SRS-SIM unit number", unit)
  port = SRSSIM[modname]["port"]
  port = ($# > 2) ? $3 : getval("Enter the SRS-SIM port number", port)
  
  if (srssim_register_module(modname, unit, port, "") == -1)
    exit
}'


def srssim_low_interactive(modname, unit, port, endcmd) '{
  local cmd msg

  if (modname != "") {
    if (("unit" in SRSSIM[modname]) && ("port" in SRSSIM[modname])) {
      unit = SRSSIM[modname]["unit"]
      port = SRSSIM[modname]["port"]
    } else {
      print "Error: module", modname, "is not registered yet.", \
            "Use \"srssimaddmodule\""
      return -1
    }
  }

  if (srssim_check_unit_port(unit, port, 1) == -1)
    return -1

  printf("Entering interactive mode on port %X, unit %d.\n", port, unit)
  printf("Press Ctrl-C or type \"%s\" to end\n\n", endcmd)

  while (1) {
    cmd = input()
    if (cmd == "")
      continue
    else if (cmd == endcmd)
      break

    resp = srssim_cmd(unit, port, cmd)
    if (resp != "")
      print resp
  }

  return 0
}'

def srssiminteractive '{
  local modname unit port str

  str = "Enter the SRS-SIM module name or unit number"
  str = ($# > 0) ? "$1" : getval(str, 0)
  if (str == str + 0) {
    modname = ""
    unit = str
    port = ($# > 1) ? $2 : getval("Enter the port number", 0)
  } else    
    modname = str

  srssim_low_interactive(modname, unit, port, "__EndInteractive")
}'

def srssim_module_par(modname, cmd, format, pars) '{
  local  ret str meaning mean nmean val i

  meaning = (index(format, "%") == 0)
  if (meaning)
    nmean = split(format, mean)

  if (pars != "") {
    if (meaning) {
      for (i = 0; i < nmean; i++) {
        if (toupper(mean[i]) == toupper(pars)) {
          str = toupper(pars)
          break
        }
      }
      if (i == nmean) {
        print "Invalid", cmd, "value:", pars
        return -1
      }
    } else {
      str = sprintf("%s", sprintf(format, pars))
    }

    ret = srssim_module_cmd(modname, sprintf("%s %s", cmd, str))
    if (ret == -1)
      return ret
  }

  ret = srssim_module_cmd(modname, sprintf("%s?", cmd))
  if (ret == -1)
    return ret

  if (meaning) {
    if (ret < nmean) 
      ret = mean[ret]
    else
      print "Error: could not find meaning for", ret
  }

  return ret
}'


# srssimpidsetup name unit port inp=cnt_mne err=cnt_mne out=out_mne
def srssimpidsetup '{
  local modname unit port parsbefore pars inp err out i

  modname = ($# > 0) ? "$1" : getval("Enter SRS-SIM PID module name", "")
  unit = SRSSIM[modname]["unit"]
  unit = ($# > 1) ? $2 : getval("Enter the PID unit number", unit)
  port = SRSSIM[modname]["port"]
  port = ($# > 2) ? $3 : getval("Enter the PID port number", port)
  
  if ($# > 3) {
    parsbefore = 3 
    pars = sprintf("$*%stype=pid", ($# > 0) ? " " : "")
  } else {
    parsbefore = 0
    pars = "type=pid"
  }

  if (srssim_register_module(modname, unit, port, pars, parsbefore) == -1)
    exit

  i = "out" in SRSSIM[modname]
  if (i) {
    cdef("user_getcounts", sprintf("pid_getcounts %s; ", modname), modname)
  }

  setup_tail("srssim_pid_", modname)
}'

def srssim_pid_unsetup '{
  cdef("user_getcounts", "", "$1", "delete")
}'

def pid_getcounts '{
  local mne val
  if ("out" in SRSSIM["$1"]) {
    mne = SRSSIM["$1"]["out"]
    val = srssim_module_par("$1", "OMON", "%f", "")
    S[cnt_num(mne)] = val
  }
}'


def toupper(str) '{
  local slen idx chr fstr diff

  fstr = ""
  slen = length(str)
  for (idx = 0; idx < slen; idx++) {
    chr = substr(str, idx + 1, 1)
    diff = 0
    if ((asc(chr) >= asc("a")) && (asc(chr) <= asc("z")))
      diff = asc("a") - asc("A")
    fstr = sprintf("%s%c", fstr, asc(chr) - diff)
  }

  return fstr
}'


def pidsetp '{
  print srssim_module_par("pid", "SETP", "%f", "$*"), "V"
}'

def pidgain '{
  print srssim_module_par("pid", "GAIN", "%f", "$*"), ""
}'

def pidintg '{
  print srssim_module_par("pid", "INTG", "%f", "$*"), "V/s"
}'

def pidmout '{
  print srssim_module_par("pid", "MOUT", "%f", "$*"), "V"
}'

def pidout '{
  print srssim_module_par("pid", "AMAN", "MAN PID", "$*")
}'