From 9740530b14d8ba57aa45a1b42bf181820980ec77 Mon Sep 17 00:00:00 2001 From: kmpeters Date: Tue, 30 Apr 2013 15:58:02 +0000 Subject: [PATCH] Added xpsSlave.st --- README | 4 + motorApp/Db/xpsSlave.db | 41 +++++ motorApp/NewportSrc/Makefile | 1 + motorApp/NewportSrc/devNewport.dbd | 1 + motorApp/NewportSrc/seqPVmacros.h | 245 +++++++++++++++++++++++++++++ motorApp/NewportSrc/xpsSlave.st | 136 ++++++++++++++++ 6 files changed, 428 insertions(+) create mode 100644 motorApp/Db/xpsSlave.db create mode 100755 motorApp/NewportSrc/seqPVmacros.h create mode 100644 motorApp/NewportSrc/xpsSlave.st diff --git a/README b/README index fc3ed7c6..f2c30fcf 100644 --- a/README +++ b/README @@ -185,6 +185,10 @@ Modification Log for R6-8 Files modified: motorApp/NewportSrc/drvXPSAsyn.c motorApp/NewportSrc/drvXPSAsyn.h +5) Added xpsSlave.st to motorApp/NewportSrc to allow master/slave mode to be + used with any version of the XPS support. + + Modification Log for R6-7 ========================= diff --git a/motorApp/Db/xpsSlave.db b/motorApp/Db/xpsSlave.db new file mode 100644 index 00000000..ec1da696 --- /dev/null +++ b/motorApp/Db/xpsSlave.db @@ -0,0 +1,41 @@ +record(longout, "$(P)$(R):debug") +{ + field(DESC, "Debug level") + field(VAL, "5") + field(PINI, "YES") +} +record(bo, "$(P)$(R):ok") +{ + field(DESC, "Slave mode ok?") + field(ZNAM, "No") + field(ONAM, "Yes") + field(VAL, "0") +} + +record(bo, "$(P)$(R):init") +{ + field(DESC, "Initialize") + field(ZNAM, "Done") + field(ONAM, "Initializing") + field(VAL, "0") +} + +record(bo, "$(P)$(R):on") +{ + field(DESC, "Slave mode") + field(ZNAM, "Off") + field(ONAM, "On") + field(VAL, "0") +} + +record(ao, "$(P)$(R):ratio") +{ + field(DESC, "Gear ratio") + field(VAL, "1") +} + +record(ao, "$(P)$(R):ratioRdbk") +{ + field(DESC, "Gear ratio") + field(VAL, "1") +} diff --git a/motorApp/NewportSrc/Makefile b/motorApp/NewportSrc/Makefile index c513259b..211ea120 100644 --- a/motorApp/NewportSrc/Makefile +++ b/motorApp/NewportSrc/Makefile @@ -54,6 +54,7 @@ Newport_SRCS += XPSController.cpp Newport_SRCS += XPSAxis.cpp ifdef SNCSEQ Newport_SRCS += XPS_trajectoryScan.st +Newport_SRCS += xpsSlave.st endif # Newport_SRCS += hxp_drivers.cpp diff --git a/motorApp/NewportSrc/devNewport.dbd b/motorApp/NewportSrc/devNewport.dbd index ccc87569..fc31f1da 100644 --- a/motorApp/NewportSrc/devNewport.dbd +++ b/motorApp/NewportSrc/devNewport.dbd @@ -20,6 +20,7 @@ registrar(AG_UCRegister) registrar(AG_CONEXRegister) registrar(MM4005_trajectoryScanRegistrar) registrar(XPS_trajectoryScanRegistrar) +registrar(xpsSlaveRegistrar) registrar(SMC100Register) #variable(devXPSC8Debug) #variable(drvXPSC8Debug) diff --git a/motorApp/NewportSrc/seqPVmacros.h b/motorApp/NewportSrc/seqPVmacros.h new file mode 100755 index 00000000..33b8a1aa --- /dev/null +++ b/motorApp/NewportSrc/seqPVmacros.h @@ -0,0 +1,245 @@ +/*================================================================ + * + * seqPVmacros.h -- PV-related macros for EPICS State Notation + * Language (SNL) code development + * + * 2004-May-19 [jemian] merged all DEBUG_PRINTn macros into one macro + * 2003-Oct-01 [jemian] changed errlogPrintf to printf (can't use in interrupts) + * 2003-Mar-20 [jemian] changed pvSet to PVPUT (and pvSetStr to PVPUTSTR) + * 2003-Mar-19 [jemian] changed printf to errlogPrintf + * 2002-Sep-24 [tischler] added pvSetStr and DEBUG_PRINT (a la Jemian) + * 2002-Jun-04 [lazmo] renamed to seqPVmacros.h + * 2002-Mar-08 [lazmo] added pvSet() + * 2002-Feb-21 [lazmo] fixed comments + * 2001-Nov-24 [lazmo] added PVA & PVAA + * 2001-Oct-18 [lazmo] original + * + * Author: + * M. Laznovsky -- lazmo_at_slac.stanford.edu + * + *================================================================ + */ + +/*---------------------------------------------------------------- + * PV() -- declare a variable and the EPICS PV it's assigned to, with + * optional monitor & event flag. One line takes the place of + * the usual: + * + * int blah; + * assign blah ... + * monitor blah; + * evflag blahFLag; + * sync blah ... + * + * Format: + * + * PV( varType, varName, pvName, other ) + * + * Where: + * + * varType is int, short, float, etc. + * varName is the variable name, e.g. foo + * pvName is the associated PV, e.g. "XYZ:ETC:FOO" + * other is one of the following: + * NoMon + * Monitor + * EvFlag + * + * Examples: + * + * PV (int, gui_goo, "{STN}:GUI:GOO", NoMon); <-- no monitor + * PV (float, gui_fudge, "{STN}:GUI:FUDGE", Monitor); <-- w/monitor + * PV (short, gui_run, "{STN}:GUI:RUN", EvFlag); <-- w/monitor & event flag + * + *---------------------------------------------------------------- + */ + +#define PV(_TYPE_,_VAR_,_PV_,_OTHER_) \ + _TYPE_ _VAR_; \ + assign _VAR_ to _PV_ \ + _OTHER_ (_VAR_) + +/*---------------------------------------------------------------- + * PVA(), for single waveform rec or array of PVs + * + * "varName" becomes array of ; 3rd arg is number of elements + * + * examples: + * + * single waveform record: + * + * PVA (short, plot_x0, 32, "{STN}:DATA:PLOT:X0", NoMon); + * + * array of PVs: + * + * #define PVA_zap { \ + * "{STN}:GUI:ZAP1", \ + * "{STN}:GUI:ZAP2", \ + * "{STN}:GUI:ZAP3" \ + * } + * PVA (int, zap, 3, PVA_zap, EvFlag); + * + *---------------------------------------------------------------- + */ + +#define PVA(_TYPE_,_VAR_,_NELEM_,_PV_,_OTHER_) \ + _TYPE_ _VAR_ [ _NELEM_ ]; \ + assign _VAR_ to _PV_ \ + _OTHER_ (_VAR_) + +/*---------------------------------------------------------------- + * PVAA(), for arrays of waveform records + * + * "varName" becomes double-dimensioned array of + * 3rd arg is number of waveform records + * 4th arg is number of elements per record + * Need to define another macro first for "_PV_" + * + * example: + * + * #define PVAA_plotx { \ + * "{STN}:DATA:PLOT:X1", \ + * "{STN}:DATA:PLOT:X2", \ + * "{STN}:DATA:PLOT:X3" \ + * } + * PVAA (short, plotx, 3, 500, PVAA_plotx, NoMon); + * + *---------------------------------------------------------------- + */ + +#define PVAA(_TYPE_,_VAR_,_NREC_,_NELEM_,_PV_,_OTHER_) \ + _TYPE_ _VAR_ [ _NREC_ ] [ _NELEM_ ]; \ + assign _VAR_ to _PV_ \ + _OTHER_ (_VAR_) + +/*---------------------------------------------------------------- + * macros for last arg of PV* ("_OTHER_") + *---------------------------------------------------------------- + */ + +/* + * no monitor + */ +#define NoMon(_VAR_) /* this macro intentionally left blank :P */ + +/* + * monitor + */ +#define Monitor(_VAR_) ; monitor _VAR_ + +/* + * monitor & event flag; flag var will be named "_EvFlag" + */ +#define EvFlag(_VAR_) \ + Monitor (_VAR_); \ + evflag _VAR_##_mon; \ + sync _VAR_ _VAR_##_mon + +/*================================================================*/ +/*================================================================*/ + +/*---------------------------------------------------------------- + * PVPUT() -- variable assign and pvPut() in one + * + * Format: + * + * PVPUT( varName, expr ) + * + * Where: + * + * varName is the variable name, e.g. foo + * expr is any C expression + * + * Examples: + * + * PVPUT (foo, 3); + * expands to: + * foo = 3; + * pvPut(foo); + * + * PVPUT (bar, xyz + 2); + * expands to: + * bar = xyz + 2; + * pvPut(bar); + * + *---------------------------------------------------------------- + */ + +#define PVPUT(_VAR_,_EXPR_) \ + { \ + _VAR_ = ( _EXPR_ ); \ + pvPut(_VAR_); \ + } + +/*---------------------------------------------------------------- + * PVPUTSTR() -- string assign and pvPut() in one + * + * Format: + * + * PVPUTSTR( strName, string expr ) + * + * Where: + * + * strName is the variable name, e.g. foo + * string expr is any C expression that points to a string + * + * Example: + * + * PVPUTSTR (foo, "error message"); + * expands to: + * strcpy(foo,"error message"); + * pvPut(foo); + * + *---------------------------------------------------------------- + */ + +#define PVPUTSTR(_STR_,_EXPR_) \ + { \ + strcpy(_STR_,_EXPR_); \ + pvPut(_STR_); \ + } + +/*================================================================*/ +/*================================================================*/ + +/*---------------------------------------------------------------- + * DEBUG_PRINT() -- print a debug string for a particular debug level + * + * Format: + * + * DEBUG_PRINT( debug_level, string format, v1, v2, v3, v4 ) + * + * Where: + * + * debug_level is the debugging level, ie 3 + * string format is an sprintf format specifier + * v1, v2, v3, v4 are optional arguments for the sprintf format + * + * Example: + * + * DEBUG_PRINT (1, "ERROR, how did I get here?", 0, 0, 0, 0 ); + * + *---------------------------------------------------------------- + */ + +#if defined(NO_DEBUGGING_OUTPUT) +#define DEBUG_PRINT(DEBUG_LEVEL, FMT,V1,V2,V3,V4) ; +#else + +#define DEBUG_PRINT(DEBUG_LEVEL,FMT,V1,V2,V3,V4) \ + if (debug_flag >= DEBUG_LEVEL) { \ + printf("<%s,%d,%s,%d> ", \ + __FILE__, __LINE__, \ + SNLtaskName, DEBUG_LEVEL); \ + printf(FMT,V1,V2,V3,V4); \ + printf("\n"); \ + } + + +#endif + +/*================================================================*/ +/*================================================================*/ +/*================================================================*/ + +/* end */ diff --git a/motorApp/NewportSrc/xpsSlave.st b/motorApp/NewportSrc/xpsSlave.st new file mode 100644 index 00000000..9524e6e4 --- /dev/null +++ b/motorApp/NewportSrc/xpsSlave.st @@ -0,0 +1,136 @@ +program xpsSlave("name=xpsSlave,P=xxx:,R=xps:slave,IP=192.168.1.11,M=GROUP1.POSITIONER,S=GROUP2") + +/* Turn on run-time debug messages */ +option +d; +/* Make the generated code reentrant */ +option +r; +/* Suppress SNC warnings */ +/*option -w;*/ + +#include "seqPVmacros.h" +%%#include "XPS_C8_drivers.h" + +#define PORT 5001 +#define TIMEOUT 100.0 + +char* SNLtaskName; +char* ip; +char* master; +char* slave; +%%int xps_socket; +int val; +char* masterRdbk; +double ratioRdbk; + +/* PV definitions */ + +PV(int, debug_flag, "{P}{R}:debug.VAL", Monitor); +/* the ok PV is an indicator that slave mode has been configured. it should only be false after a power-cycle before initializing */ +PV(int, ok_pv, "{P}{R}:ok.VAL", NoMon); +PV(int, on_pv, "{P}{R}:on.VAL", EvFlag); +PV(int, init_pv, "{P}{R}:init.VAL", EvFlag); +PV(double, ratio_pv, "{P}{R}:ratio.VAL", Monitor); +PV(double, ratioRdbk_pv, "{P}{R}:ratioRdbk.VAL", NoMon); + +ss slave_main +{ + state init + { + when () + { + /* get macros */ + ip = macValueGet("IP"); + master = macValueGet("M"); + slave = macValueGet("S"); + SNLtaskName = macValueGet("name"); + + /* Connect to the XPS controller (save the xps_socket ID) */ + %%xps_socket = TCP_ConnectToServer(pVar->ip, PORT, TIMEOUT); + + DEBUG_PRINT(2, "init -> update", 0, 0, 0, 0); + + efClear(init_pv_mon); + efClear(on_pv_mon); + + } state update + } + + state update + { + when () + { + /* Check if slave mode is on and set the on_pv appropriately */ + %%pVar->val = SingleAxisSlaveParametersGet(xps_socket, pVar->slave, pVar->masterRdbk, &pVar->ratioRdbk); + DEBUG_PRINT(2, "update(): val = %i, masterRdbk = %s, ratioRdbk = %f", val, masterRdbk, ratioRdbk, 0); + + /* Set the ok indictor to 1 if slave parameters exist */ + if (val == 0) + { + PVPUT(ok_pv, 1); + } + else + { + PVPUT(ok_pv, 0); + } + + /* what is the initial value if the first poll fails? */ + /* display the ratio */ + PVPUT(ratioRdbk_pv, ratioRdbk); + + DEBUG_PRINT(2, "update -> idle", 0, 0, 0, 0); + + } state idle + + } + + state modeChange + { + when () + { + if (on_pv == 1) + { + %%pVar->val = SingleAxisSlaveModeEnable(xps_socket, pVar->slave); + DEBUG_PRINT(2, "on_pv == 1", 0, 0, 0, 0); + } + else + { + %%pVar->val = SingleAxisSlaveModeDisable(xps_socket, pVar->slave); + DEBUG_PRINT(2, "on_pv != 1", 0, 0, 0, 0); + } + DEBUG_PRINT(2, "modeChange -> idle", 0, 0, 0, 0); + } state idle + + } + + /* Should reinit wait until a move is done before changing the gear ratio? */ + state reinit + { + when () + { + %%pVar->val = SingleAxisSlaveParametersSet(xps_socket, pVar->slave, pVar->master, pVar->ratio_pv); + DEBUG_PRINT(2, "reinit(): val = %i", val, 0, 0, 0); + + /* reset the init PV */ + PVPUT(init_pv, 0); + efClear(init_pv_mon); + DEBUG_PRINT(2, "reinit -> update", 0, 0, 0, 0); + + } state update + } + + state idle + { + when ( efTestAndClear(on_pv_mon) && ok_pv == 1 ) + { + /* A mode toggle has been requested */ + DEBUG_PRINT(2, "idle -> modeChange", 0, 0, 0, 0); + } state modeChange + + when ( efTest(init_pv_mon) ) + { + /* A reinit has been requested */ + DEBUG_PRINT(2, "idle -> reinit", 0, 0, 0, 0); + } state reinit + + } +}