Removed OmsSrc; Added motorOms submodule

This commit is contained in:
kpetersn
2019-04-03 15:42:44 -05:00
parent 9650b47614
commit 1e04d11d5c
28 changed files with 6 additions and 9178 deletions
+3
View File
@@ -1,3 +1,6 @@
[submodule "modules/motorNewport"]
path = modules/motorNewport
url = https://github.com/epics-motor/motorNewport.git
[submodule "modules/motorOms"]
path = modules/motorOms
url = https://github.com/epics-motor/motorOms.git
+1 -46
View File
@@ -1,4 +1,4 @@
# This example if for OMS VME8/44 controllers. Since OMS controllers
# This example is for controllers that
# communicate across the VME backplane, this example does not require
# ASYN.
@@ -23,51 +23,6 @@ dbLoadRecords("$(MOTOR)/db/motorUtil.db", "P=IOC:")
#!dbLoadRecords("$(TOP)/motorApp/Db/SoftMotorEx.db","user=IOC,motor=m1", startup)
# OMS VME driver setup parameters:
# (1)cards, (2)base address(short, 16-byte boundary),
# (3)interrupt vector (0=disable or 64 - 255), (4)interrupt level (1 - 6),
# (5)motor task polling rate (min=1Hz,max=60Hz)
#!omsSetup(1, 0xFC00, 180, 5, 10)
#!drvOMSdebug = 4
# OMS VME58 driver setup parameters:
# (1)cards, (2)base address(short, 4k boundary),
# (3)interrupt vector (0=disable or 64 - 255), (4)interrupt level (1 - 6),
# (5)motor task polling rate (min=1Hz,max=60Hz)
#!oms58Setup(1, 0x1000, 190, 5, 10)
#!drvOms58debug = 4
# OMS MAXv driver setup parameters:
# (1)number of cards in array.
# (2)VME Address Space - A(16,24,32).
# (3)Base Address (see README file).
# (4)interrupt vector (0=disable or 64 - 255).
# (5)interrupt level (2 - 6).
# (6)motor task polling rate (min=1Hz,max=60Hz).
#!MAXvSetup(1, 16, 0xF000, 200, 5, 10)
#!MAXvSetup(1, 24, 0xFF0000, 200, 5, 10)
#!MAXvSetup(1, 32, 0xFF000000, 200, 5, 10)
#!drvMAXvdebug=4
# OMS MAXv configuration string:
# (1) number of card being configured (0-14).
# (2) configuration string; axis type (PSO/PSE/PSM) MUST be set here.
# For example, set which TTL signal level defines
# an active limit switch. Set X,Y,Z,T to active low and set U,V,R,S
# to active high. Set all axes to open-loop stepper (PSO). See MAXv
# User's Manual for LTL/LTH and PSO/PSE/PSM commands.
# (3) SSI based absolute encoder bit flag. Bit #0 for Axis X, bit #1 for
# Axis Y, etc.. Set a bit flag to '1' for absolute encoder values; '0'
# for the standard incremental encoder values.
# (4) SSI based absolute encoder grey code flags (0/1 - yes/no, 0x12 -> UY)
#!str = malloc(200);
#!strcpy str, "AA; LMH,H,H,H,H,H,H,H;"
#!strcat str, "AX LTH PSO; AY LTH PSO; AZ LTL PSO; AT LTL PSO; AU LTL PSO; AV LTL PSO; AR LTL PSO; AS LTL PSO;"
#!MAXvConfig(0, str, 0, 0)
#!free(str)
# PMAC VME driver setup parameters:
# (1)cards, (2) VME Address Type (24,32)
# (3)Mailbox base address, (4)DPRAM base address,
-11
View File
@@ -161,17 +161,6 @@ dbLoadRecords("$(MOTOR)/db/motorUtil.db", "P=IOC:")
#!MDriveConfig(0, "a-Serial[0]")
#!drvMDrivedebug = 4
# OMS PC68/78 stand-alone serial driver setup parameters:
# (1) maximum number of controllers in system
# (2) motor task polling rate (min=1Hz,max=60Hz)
#!OmsPC68Setup(1, 10)
# OMS PC68/78 stand-alone serial driver configuration parameters:
# (1) Card# being configured
# (2) asyn port name
#!OmsPC68Config(0, "L0")
#!drvOmsPC68debug=4
# Kohzu SC-800 motor controller setup parameters:
# (1) maximum number of controllers in system
# (2) motor task polling rate (min=1Hz,max=60Hz)
+1
View File
@@ -3,6 +3,7 @@ include $(TOP)/configure/CONFIG
# Submodules
#SUBMODULES += motorVendor
SUBMODULES += motorOms
SUBMODULES += motorNewport
# Allow sites to add extra submodules
+1
Submodule modules/motorOms added at 052194c426
-360
View File
@@ -1,360 +0,0 @@
/* MAX_trajectoryScan.h
*
* This file is included in MAX_trajectoryScan.st.
*/
/* State codes for Build, Read and Execute. Careful, these must match the
* corresponding MBBI records, but there is no way to check this */
#define BUILD_STATE_DONE 0
#define BUILD_STATE_BUSY 1
#define READ_STATE_DONE 0
#define READ_STATE_BUSY 1
#define EXECUTE_STATE_DONE 0
#define EXECUTE_STATE_MOVE_START 1
#define EXECUTE_STATE_EXECUTING 2
#define EXECUTE_STATE_FLYBACK 3
/* Status codes for Build, Execute and Read */
#define STATUS_UNDEFINED 0
#define STATUS_SUCCESS 1
#define STATUS_FAILURE 2
#define STATUS_ABORT 3
#define STATUS_TIMEOUT 4
/* Time modes */
#define TIME_MODE_TOTAL 0
#define TIME_MODE_PER_ELEMENT 1
/* Move modes */
#define MOVE_MODE_RELATIVE 0
#define MOVE_MODE_ABSOLUTE 1
#define MOVE_MODE_HYBRID 2
/* The maximum number of axes per controller. If this is changed from 8
* then many assign statements in this file must be changed */
#define MAX_AXES 8
#define MSGSIZE 40
/* Define PVs */
int debugLevel; assign debugLevel to "{P}{R}DebugLevel.VAL";
monitor debugLevel;
int numAxes; assign numAxes to "{P}{R}NumAxes.VAL";
monitor numAxes;
int nelements; assign nelements to "{P}{R}Nelements.VAL";
monitor nelements;
int npulses; assign npulses to "{P}{R}Npulses.VAL";
monitor npulses;
int startPulses; assign startPulses to "{P}{R}StartPulses.VAL";
monitor startPulses;
int endPulses; assign endPulses to "{P}{R}EndPulses.VAL";
monitor endPulses;
int nactual; assign nactual to "{P}{R}Nactual.VAL";
int moveMode; assign moveMode to "{P}{R}MoveMode.VAL";
monitor moveMode;
double time_PV; assign time_PV to "{P}{R}Time.VAL";
monitor time_PV;
double timeScale; assign timeScale to "{P}{R}TimeScale.VAL";
monitor timeScale;
int timeMode; assign timeMode to "{P}{R}TimeMode.VAL";
monitor timeMode;
double accel; assign accel to "{P}{R}Accel.VAL";
monitor accel;
int build; assign build to "{P}{R}Build.VAL";
monitor build;
int buildState; assign buildState to "{P}{R}BuildState.VAL";
int buildStatus; assign buildStatus to "{P}{R}BuildStatus.VAL";
string buildMessage;assign buildMessage to "{P}{R}BuildMessage.VAL";
int simMode; assign simMode to "{P}{R}SimMode.VAL";
monitor simMode;
int execute; assign execute to "{P}{R}Execute.VAL";
monitor execute;
int execState; assign execState to "{P}{R}ExecState.VAL";
monitor execState;
int execStatus; assign execStatus to "{P}{R}ExecStatus.VAL";
string execMessage; assign execMessage to "{P}{R}ExecMessage.VAL";
int abort; assign abort to "{P}{R}Abort.VAL";
monitor abort;
int readback; assign readback to "{P}{R}Readback.VAL";
monitor readback;
int readState; assign readState to "{P}{R}ReadState.VAL";
int readStatus; assign readStatus to "{P}{R}ReadStatus.VAL";
string readMessage; assign readMessage to "{P}{R}ReadMessage.VAL";
double timeTrajectory[MAX_ELEMENTS];
assign timeTrajectory to "{P}{R}TimeTraj.VAL";
monitor timeTrajectory;
string trajectoryFile; assign trajectoryFile to "{P}{R}TrajectoryFile.VAL";
monitor trajectoryFile;
/*** BEGIN: Specific to MAX_trajectoryScan.st ***/
/* time since trajectory start */
double elapsedTime; assign elapsedTime to "{P}{R}ElapsedTime.VAL";
/* Number (0..15) of general purpose I/O bit to be used for output pulses (e.g., to trigger detector). */
int outBitNum; assign outBitNum to "{P}{R}OutBitNum.VAL";
monitor outBitNum;
/* Number (0..15) of general purpose I/O bit to be used for input start-trajectory pulse. */
int inBitNum; assign inBitNum to "{P}{R}InBitNum.VAL";
monitor inBitNum;
/* Used to calculate velocity-override percentages while trajectory is executing */
double overrideFactor; assign overrideFactor to "{P}{R}OverrideFactor";
monitor overrideFactor;
/* MAX controller's update frequency (one of 1024, 2048, 4096, or 8192 Hz) */
int updateFreq; assign updateFreq to "{P}{R}UpdateFreq.RVAL";
monitor updateFreq;
/* time in seconds from trajectory start */
double realTimeTrajectory[MAX_ELEMENTS];
assign realTimeTrajectory to "{P}{R}realTimeTrajectory.VAL";
/* raw values read from the controller, generally while a trajectory is executing */
int motorCurrentRaw[MAX_AXES];
int motorCurrentVRaw[MAX_AXES];
int motorCurrentARaw[MAX_AXES];
/* EPICS motor record resolution */
double epicsMotorMres[MAX_AXES];
assign epicsMotorMres to {"","","","","","","",""};
monitor epicsMotorMres;
/* EPICS motor-controller card number. (For now, we talk to the controller via drvMAX.cc) */
int epicsMotorCard[MAX_AXES];
assign epicsMotorCard to {"","","","","","","",""};
monitor epicsMotorCard;
/* EPICS motor record soft limits */
double epicsMotorHLM[MAX_AXES];
assign epicsMotorHLM to {"","","","","","","",""};
monitor epicsMotorHLM;
double epicsMotorLLM[MAX_AXES];
assign epicsMotorLLM to {"","","","","","","",""};
monitor epicsMotorLLM;
double motorMinSpeed[MAX_AXES];
assign motorMinSpeed to
{"{P}{R}M1MinSpeed.VAL",
"{P}{R}M2MinSpeed.VAL",
"{P}{R}M3MinSpeed.VAL",
"{P}{R}M4MinSpeed.VAL",
"{P}{R}M5MinSpeed.VAL",
"{P}{R}M6MinSpeed.VAL",
"{P}{R}M7MinSpeed.VAL",
"{P}{R}M8MinSpeed.VAL"};
double motorMaxSpeed[MAX_AXES];
assign motorMaxSpeed to
{"{P}{R}M1MaxSpeed.VAL",
"{P}{R}M2MaxSpeed.VAL",
"{P}{R}M3MaxSpeed.VAL",
"{P}{R}M4MaxSpeed.VAL",
"{P}{R}M5MaxSpeed.VAL",
"{P}{R}M6MaxSpeed.VAL",
"{P}{R}M7MaxSpeed.VAL",
"{P}{R}M8MaxSpeed.VAL"};
double motorStart[MAX_AXES];
assign motorStart to
{"{P}{R}M1Start.VAL",
"{P}{R}M2Start.VAL",
"{P}{R}M3Start.VAL",
"{P}{R}M4Start.VAL",
"{P}{R}M5Start.VAL",
"{P}{R}M6Start.VAL",
"{P}{R}M7Start.VAL",
"{P}{R}M8Start.VAL"};
int addAccelDecel; assign addAccelDecel to "{P}{R}AddAccelDecel.VAL";
monitor addAccelDecel;
evflag moveModeMon; sync moveMode moveModeMon;
int moveModePrev;
/*** END: Specific to MAX_trajectoryScan.st ***/
int moveAxis[MAX_AXES];
assign moveAxis to
{"{P}{R}M1Move.VAL",
"{P}{R}M2Move.VAL",
"{P}{R}M3Move.VAL",
"{P}{R}M4Move.VAL",
"{P}{R}M5Move.VAL",
"{P}{R}M6Move.VAL",
"{P}{R}M7Move.VAL",
"{P}{R}M8Move.VAL"};
monitor moveAxis;
double motorTrajectory[MAX_AXES][MAX_ELEMENTS];
assign motorTrajectory to
{"{P}{R}M1Traj.VAL",
"{P}{R}M2Traj.VAL",
"{P}{R}M3Traj.VAL",
"{P}{R}M4Traj.VAL",
"{P}{R}M5Traj.VAL",
"{P}{R}M6Traj.VAL",
"{P}{R}M7Traj.VAL",
"{P}{R}M8Traj.VAL"};
monitor motorTrajectory;
double motorReadbacks[MAX_AXES][MAX_PULSES];
assign motorReadbacks to
{"{P}{R}M1Actual.VAL",
"{P}{R}M2Actual.VAL",
"{P}{R}M3Actual.VAL",
"{P}{R}M4Actual.VAL",
"{P}{R}M5Actual.VAL",
"{P}{R}M6Actual.VAL",
"{P}{R}M7Actual.VAL",
"{P}{R}M8Actual.VAL"};
double motorError[MAX_AXES][MAX_PULSES];
assign motorError to
{"{P}{R}M1Error.VAL",
"{P}{R}M2Error.VAL",
"{P}{R}M3Error.VAL",
"{P}{R}M4Error.VAL",
"{P}{R}M5Error.VAL",
"{P}{R}M6Error.VAL",
"{P}{R}M7Error.VAL",
"{P}{R}M8Error.VAL"};
double motorCurrent[MAX_AXES];
assign motorCurrent to
{"{P}{R}M1Current.VAL",
"{P}{R}M2Current.VAL",
"{P}{R}M3Current.VAL",
"{P}{R}M4Current.VAL",
"{P}{R}M5Current.VAL",
"{P}{R}M6Current.VAL",
"{P}{R}M7Current.VAL",
"{P}{R}M8Current.VAL"};
double motorMDVS[MAX_AXES];
assign motorMDVS to
{"{P}{R}M1MDVS.VAL",
"{P}{R}M2MDVS.VAL",
"{P}{R}M3MDVS.VAL",
"{P}{R}M4MDVS.VAL",
"{P}{R}M5MDVS.VAL",
"{P}{R}M6MDVS.VAL",
"{P}{R}M7MDVS.VAL",
"{P}{R}M8MDVS.VAL"};
monitor motorMDVS;
double motorMDVA[MAX_AXES];
assign motorMDVA to
{"{P}{R}M1MDVA.VAL",
"{P}{R}M2MDVA.VAL",
"{P}{R}M3MDVA.VAL",
"{P}{R}M4MDVA.VAL",
"{P}{R}M5MDVA.VAL",
"{P}{R}M6MDVA.VAL",
"{P}{R}M7MDVA.VAL",
"{P}{R}M8MDVA.VAL"};
int motorMDVE[MAX_AXES];
assign motorMDVE to
{"{P}{R}M1MDVE.VAL",
"{P}{R}M2MDVE.VAL",
"{P}{R}M3MDVE.VAL",
"{P}{R}M4MDVE.VAL",
"{P}{R}M5MDVE.VAL",
"{P}{R}M6MDVE.VAL",
"{P}{R}M7MDVE.VAL",
"{P}{R}M8MDVE.VAL"};
double motorMVA[MAX_AXES];
assign motorMVA to
{"{P}{R}M1MVA.VAL",
"{P}{R}M2MVA.VAL",
"{P}{R}M3MVA.VAL",
"{P}{R}M4MVA.VAL",
"{P}{R}M5MVA.VAL",
"{P}{R}M6MVA.VAL",
"{P}{R}M7MVA.VAL",
"{P}{R}M8MVA.VAL"};
int motorMVE[MAX_AXES];
assign motorMVE to
{"{P}{R}M1MVE.VAL",
"{P}{R}M2MVE.VAL",
"{P}{R}M3MVE.VAL",
"{P}{R}M4MVE.VAL",
"{P}{R}M5MVE.VAL",
"{P}{R}M6MVE.VAL",
"{P}{R}M7MVE.VAL",
"{P}{R}M8MVE.VAL"};
double motorMAA[MAX_AXES];
assign motorMAA to
{"{P}{R}M1MAA.VAL",
"{P}{R}M2MAA.VAL",
"{P}{R}M3MAA.VAL",
"{P}{R}M4MAA.VAL",
"{P}{R}M5MAA.VAL",
"{P}{R}M6MAA.VAL",
"{P}{R}M7MAA.VAL",
"{P}{R}M8MAA.VAL"};
int motorMAE[MAX_AXES];
assign motorMAE to
{"{P}{R}M1MAE.VAL",
"{P}{R}M2MAE.VAL",
"{P}{R}M3MAE.VAL",
"{P}{R}M4MAE.VAL",
"{P}{R}M5MAE.VAL",
"{P}{R}M6MAE.VAL",
"{P}{R}M7MAE.VAL",
"{P}{R}M8MAE.VAL"};
/* We don't assign the EPICS motors here because there may be fewer than
* MAX_AXES actually in use. */
double epicsMotorPos[MAX_AXES];
assign epicsMotorPos to {"","","","","","","",""};
monitor epicsMotorPos;
int epicsMotorDir[MAX_AXES];
assign epicsMotorDir to {"","","","","","","",""};
monitor epicsMotorDir;
double epicsMotorOff[MAX_AXES];
assign epicsMotorOff to {"","","","","","","",""};
monitor epicsMotorOff;
double epicsMotorDone[MAX_AXES];
assign epicsMotorDone to {"","","","","","","",""};
monitor epicsMotorDone;
double epicsMotorVELO[MAX_AXES];
assign epicsMotorVELO to {"","","","","","","",""};
monitor epicsMotorVELO;
double epicsMotorVMAX[MAX_AXES];
assign epicsMotorVMAX to {"","","","","","","",""};
monitor epicsMotorVMAX;
double epicsMotorVMIN[MAX_AXES];
assign epicsMotorVMIN to {"","","","","","","",""};
monitor epicsMotorVMIN;
double epicsMotorACCL[MAX_AXES];
assign epicsMotorACCL to {"","","","","","","",""};
monitor epicsMotorACCL;
string epicsMotorOUT[MAX_AXES];
assign epicsMotorOUT to {"","","","","","","",""};
evflag buildMon; sync build buildMon;
evflag executeMon; sync execute executeMon;
evflag execStateMon; sync execState execStateMon;
evflag abortMon; sync abort abortMon;
evflag readbackMon; sync readback readbackMon;
evflag nelementsMon; sync nelements nelementsMon;
evflag motorMDVSMon; sync motorMDVS motorMDVSMon;
File diff suppressed because it is too large Load Diff
-53
View File
@@ -1,53 +0,0 @@
# Makefile
TOP = ../..
include $(TOP)/configure/CONFIG
#----------------------------------------
# ADD MACRO DEFINITIONS AFTER THIS LINE
# The following are used for debugging messages.
#!USR_CXXFLAGS += -DDEBUG
DBD += devOms.dbd
LIBRARY_IOC_DEFAULT += oms
# The following is required for the OMS PC68/78 (i.e., devOmsPC68) device driver.
ifdef ASYN
SRCS += devOmsPC68.cc drvOmsPC68.cc
endif
# The following is required for the OMS VME8/44 (i.e., devOMS) device driver.
SRCS += devOms.cc drvOms.cc
# The following is required for the OMS VME58 (i.e., devOms58) device driver.
SRCS += devOms58.cc drvOms58.cc
# OMS MAXv device driver support.
SRCS += devMAXv.cc drvMAXv.cc
# Trajectory support for MAXV controller
ifdef SNCSEQ
ifdef ASYN
SRCS += MAX_trajectoryScan.st
endif
endif
# The following is required for all OMS device drivers.
SRCS += devOmsCom.cc
oms_LIBS += motor
ifdef ASYN
oms_LIBS += asyn
endif
# MAXV_trajectoryScan.st needs the following:
ifdef SNCSEQ
oms_LIBS += seq pv
endif
oms_LIBS += $(EPICS_BASE_IOC_LIBS)
include $(TOP)/configure/RULES
#----------------------------------------
# ADD RULES AFTER THIS LINE
-304
View File
@@ -1,304 +0,0 @@
==============================================================================
MAXv MAXv MAXv MAXv
==============================================================================
For all MAXv motors.
--------------------
# OMS MAXv driver setup parameters:
# (1)number of cards in array.
# (2)VME Address Space - A(16,24,32).
# (3)Base Address (see README file).
# (4)interrupt vector (0=disable or 64 - 255).
# (5)interrupt level (1 - 6).
# (6)motor task polling rate (min=1Hz,max=60Hz).
#!MAXvSetup(1, 16, 0xF000, 190, 5, 10)
MAXv array base address
-----------------------
- defined the by 3rd argument to the MAXvSetup() call.
- must be both a valid address and on a valid address boundary for the selected
VME Address Space. A valid address for an A16 address must be 4 hex digits;
A24 - 6 hex digits; A32 - 8 hex digits.
Each MAXv occupies the following space for the selected VME address space.
VME space | A16 | A24 | A32 |
----------|--------|-----------|-------------|
MAXv size | 0x1000 | 0x01 0000 | 0x0100 0000 |
----------|--------|-----------|-------------|
valid MAXv| 0x0000 | 0x00 0000 | 0x0000 0000 |
addresses | 0x1000 | 0x01 0000 | 0x0100 0000 |
| 0x2000 | 0x02 0000 | 0x0200 0000 |
| ... | ... | ... |
| 0xE000 | 0x0E 0000 | 0x0E00 0000 |
| 0xF000 | 0x0F 0000 | 0x0F00 0000 |
| | 0x10 0000 | 0x1000 0000 |
| | ... | ... |
| | 0xFF 0000 | 0xFF00 0000 |
----------|--------|-----------|-------------|
EXAMPLE
-------
3 MAXv boards, A24 address space, base address = 0xA0 0000.
1st board's address - 0xA0 0000
2nd board's address - 0xA1 0000
3rd board's address - 0xA2 0000
MAXvSetup(3, 24, 0xA00000, 190, 5, 10)
NOTES:
- Unlike the other OMS models, the MAXv VME Address Modifiers (AM) do not
respond to both supervisory and non-privileged access. Hence, the MAXv's
AM's must match the CPU board's AM's exactly.
------------------------------ For APS only -----------------------------------
At the Advanced Photon Source (APS), the VxWorks Board Support Packages
(BSP's) are configured such that the AM must be set to "supervisory
(privileged) data access".
A16 - 0x2D
A24 - 0x3D
A32 - 0x0D
In addition, for APS only, the VxWorks BSP's are configured such that only
the following VME address spaces are available for the MAXv base address.
A16: 0x0000 - 0xFFFF
A24: 0x000000 - 0xFFFFFF
A32: 0xA0000000 - 0xBFFFFFFF
Note that CPU local memory mapping makes A32 0x80000000 - 0x9FFFFFFF
unavailable to all VMEbus devices.
------------------------------ For APS only -----------------------------------
- Configure the MAXv's limit switch sense by placing one of the following MAXv
controller commands in the 2nd argument of MAXvConfig(); the initialization
string. This command determines which TTL signal level defines an active
limit switch input:
LL - low (default).
LH - high.
- One of the following MAXv controller commands must appear in the
initialization string to configure the type of axis:
PSO - open loop stepper axis.
PSE - stepper axis with encoder.
PSM - servo axis
Note: Separate multiple commands in the initialization string with ";".
Example
-------
config0="AX LH PSM; AY LL PSO; AZ LL PSO; AT LL PSO; AU LH PSO; AV LH PSO; \
AR LH PSO; AS LH PSO;"
MAXvConfig(0, config0)
Configuring the MAXv for an open loop stepper motor (default).
--------------------------------------------------------------
Set J8 for stepper and add the command "PS0;" to the MAXvConfig()
initialization string.
Configuring the MAXv for a stepper motor with encoder.
------------------------------------------------------
Set J8 for stepper and add the command "PSE;" to the MAXvConfig()
initialization string.
Configuring the MAXv for a servo motor.
---------------------------------------
Set J8 for servo and add the command "PSM;" to MAXvConfig() initialization
string.
==============================================================================
VME8, VME44, VS4, VX2 VME8, VME44, VS4, VX2
==============================================================================
OMS array base address
--------------------------
- defined by the 3rd argument to the omsSetup() call.
- the VMEbus address of the 1st board in the array of OMS VME8, VME44, VS4 and
VX2 boards.
OMS incremental address
---------------------------
- increment each additional OMS board's VMEbus address by 0x10 from the array's
base address.
==============================================================================
VME58 VME58 VME58 VME58
==============================================================================
VME58 array base address
------------------------
- defined the by 2nd argument to the oms58Setup() call.
- the VMEbus address of the 1st board in the array of OMS VME58 boards.
VME58 incremental address
-------------------------
- increment each additional board's VMEbus address by 0x1000 from the array's
base address.
NOTE
----
1. The EPICS motor record does NOT support the encoder mode. The encoder mode
is enabled with the ER#,# and results in all distance, velocity and
acceleration parameters being input in encoder counts.
SSCAN THROUGH-PUT NOTES
-----------------------
The following results where done using the following;
- SSCAN support module R2.5.1, with scan.db configured as follows;
- Read(R1PV) set to "time".
- Drive(P1PV) set to motor record VAL field.
- #PTS(NPTS) set to 1000.
- Step Size(P1SI) set to MRES of the motor record.
- Motor record R5.7; configured as follows;
- Set slew velocity (VELO) = (500,000 * MRES).
- Set base velocity (VBAS) = (499,999 * MRES).
- Acceleration time (ACCL) does not matter.
- EPICS base R3.14.7
- WRS Tornado 2.2.1
- MVME5100
- VME8 with firmware version 1.97-8
- VME44 with firmware version 2.35-4E:
- VME58 with firmware version 2.16-8
- MAXv with firmware version 1.25
Controller | sysClkRate | interrupts | polling rate | ms/scan pt.
-----------|------------|------------|--------------|------------
VME8 | 60 | disabled | 1HZ | 1076.0
-----------|------------|------------|--------------|------------
VME44 | 60 | disabled | 1HZ | 1267.0
-----------|------------|------------|--------------|------------
VME58 | 60 | disabled | 1HZ | 808.5
-----------|------------|------------|--------------|------------
MAXv | 60 | disabled | 1HZ | 808.5
===========|============|============|==============|============
VME8 | 60 | disabled | 60HZ | 801.8
-----------|------------|------------|--------------|------------
VME44 | 60 | disabled | 60HZ | 990.6
-----------|------------|------------|--------------|------------
VME58 | 60 | disabled | 60HZ | 77.3
-----------|------------|------------|--------------|------------
MAXv | 60 | disabled | 60HZ | 77.4
===========|============|============|==============|============
VME8 | 4000 | disabled | 1HZ | 776.0
-----------|------------|------------|--------------|------------
VME44 | 4000 | disabled | 1HZ | 779.9
-----------|------------|------------|--------------|------------
VME58 | 4000 | disabled | 1HZ | 772.3
-----------|------------|------------|--------------|------------
MAXv | 4000 | disabled | 1HZ | 772.5
===========|============|============|==============|============
VME8 | 4000 | disabled | 60HZ | 18.8
-----------|------------|------------|--------------|------------
VME44 | 4000 | disabled | 60HZ | 22.1
-----------|------------|------------|--------------|------------
VME58 | 4000 | disabled | 60HZ | 14.9
-----------|------------|------------|--------------|------------
MAXv | 4000 | disabled | 60HZ | 15.2
===========|============|============|==============|============
VME8 | 60 | enabled | 1HZ | 38.8
-----------|------------|------------|--------------|------------
VME44 | 60 | enabled | 1HZ | 38.8
-----------|------------|------------|--------------|------------
VME58 | 60 | enabled | 1HZ | 77.5
-----------|------------|------------|--------------|------------
MAXv | 60 | enabled | 1HZ | 77.5
===========|============|============|==============|============
VME8 | 60 | enabled | 1HZ | 75.4 with VBAS/VELO removed
-----------|------------|------------|--------------|------------
VME44 | 60 | enabled | 1HZ | 80.1 with VBAS/VELO removed
-----------|------------|------------|--------------|------------
VME58 | 60 | enabled | 1HZ | 97.9 with VBAS/VELO removed
-----------|------------|------------|--------------|------------
MAXv | 60 | enabled | 1HZ | 84.9 with VBAS/VELO removed
===========|============|============|==============|============
VME8 | 60 | enabled | 60HZ | 38.7
-----------|------------|------------|--------------|------------
VME44 | 60 | enabled | 60HZ | 38.7
-----------|------------|------------|--------------|------------
VME58 | 60 | enabled | 60HZ | 77.5
-----------|------------|------------|--------------|------------
MAXv | 60 | enabled | 60HZ | 77.4
===========|============|============|==============|============
VME8 | 100 | enabled | 1HZ | 15.5
-----------|------------|------------|--------------|------------
VME44 | 100 | enabled | 1HZ | 23.2
-----------|------------|------------|--------------|------------
VME58 | 100 | enabled | 1HZ | 38.7
-----------|------------|------------|--------------|------------
MAXv | 100 | enabled | 1HZ | 38.7
===========|============|============|==============|============
VME8 | 4000 | enabled | 1HZ | 14.4
-----------|------------|------------|--------------|------------
VME44 | 4000 | enabled | 1HZ | 18.2
-----------|------------|------------|--------------|------------
VME58 | 4000 | enabled | 1HZ | 10.4
-----------|------------|------------|--------------|------------
MAXv | 4000 | enabled | 1HZ | 11.6
===========|============|============|==============|============
VME8 | 4000 | enabled | 60HZ | 14.4
-----------|------------|------------|--------------|------------
VME44 | 4000 | enabled | 60HZ | 18.2
-----------|------------|------------|--------------|------------
VME58 | 4000 | enabled | 60HZ | 10.4
-----------|------------|------------|--------------|------------
MAXv | 4000 | enabled | 60HZ | 11.6
===========|============|============|==============|============
VME8 | 4000 | enabled | 60HZ | 12.7 with VBAS/VELO removed
-----------|------------|------------|--------------|------------
VME44 | 4000 | enabled | 60HZ | 15.6 with VBAS/VELO removed
-----------|------------|------------|--------------|------------
VME58 | 4000 | enabled | 60HZ | 9.8 with VBAS/VELO removed
-----------|------------|------------|--------------|------------
MAXv | 4000 | enabled | 60HZ | 9.8 with VBAS/VELO removed
-----------|------------|------------|--------------|------------
The following results where done using the following;
- SSCAN support module R2.5.6, with scan.db configured as follows;
- Read(R1PV) set to "time".
- Drive(P1PV) set to motor record VAL field.
- #PTS(NPTS) set to 1000.
- Step Size(P1SI) set to MRES of the motor record.
- Motor record R6-3; configured as follows;
- Set slew velocity (VELO) = (500,000 * MRES).
- Set base velocity (VBAS) = (499,999 * MRES).
- Acceleration time (ACCL) does not matter.
- EPICS base R3.14.7
- WRS Tornado 2.2.2
- MVME5100
- VME58 with firmware version 2.42-8
- MAXv-8000 ver:1.31, s/n:000274, FPGA:B1:A6
- MAXv with #UR8192
- CROSS_COMPILER_TARGET_ARCHS = vxWorks-ppc604_long
Controller | sysClkRate | interrupts | ms/scan pt.
===========|============|============|============
VME58 | 60 | enabled | 83.4 ms
===========|============|============|============
VME58 | 100 | enabled | 50.1 ms
===========|============|============|============
VME58 | 200 | enabled | 30.1 ms
===========|============|============|============
VME58 | 4000 | enabled | 13.1 ms
===========|============|============|============
MAXv | 60 | enabled | 50.0 ms
===========|============|============|============
MAXv | 100 | enabled | 30.0 ms
===========|============|============|============
MAXv | 200 | enabled | 15.0 ms
===========|============|============|============
MAXv | 1000 | enabled | 5.1 ms
===========|============|============|============
MAXv | 4000 | enabled | 4.1 ms
-----------|------------|------------|------------
-106
View File
@@ -1,106 +0,0 @@
/*
FILENAME... devMAXV.cc
USAGE... Device level support for OMS MAXv model.
*/
/*
* Original Author: Ron Sluiter
* Date: 04/05/04
* Current Author: Ron Sluiter
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 04-05-05 rls Copied from devOms58.cc
*/
#include <errlog.h>
#include "motorRecord.h"
#include "devOmsCom.h"
#include "epicsExport.h"
extern int MAXv_num_cards;
extern struct driver_table MAXv_access;
/* ----------------Create the dsets for devMAXv----------------- */
static long MAXv_init(int);
static long MAXv_init_record(void *);
static long MAXv_start_trans(struct motorRecord *);
static RTN_STATUS MAXv_end_trans(struct motorRecord *);
struct motor_dset devMAXv =
{
{8, NULL, (DEVSUPFUN) MAXv_init, (DEVSUPFUN) MAXv_init_record, NULL},
motor_update_values,
MAXv_start_trans,
oms_build_trans,
MAXv_end_trans
};
extern "C" {epicsExportAddress(dset,devMAXv);}
static struct board_stat **MAXv_cards;
static const char errmsg[] = {"\n\n!!!ERROR!!! - Oms MAXv driver uninitialized.\n"};
static long MAXv_init(int after)
{
if (*(MAXv_access.init_indicator) == NO)
{
errlogSevPrintf(errlogMinor, "%s", errmsg);
return(ERROR);
}
else
return(motor_init_com(after, MAXv_num_cards, &MAXv_access, &MAXv_cards));
}
static long MAXv_init_record(void *arg)
{
struct motorRecord *mr = (struct motorRecord *) arg;
return(motor_init_record_com(mr, MAXv_num_cards, &MAXv_access, MAXv_cards));
}
static long MAXv_start_trans(struct motorRecord *mr)
{
struct motor_trans *trans;
long rtnval;
rtnval = motor_start_trans_com(mr, MAXv_cards);
/* Initialize a STOP_AXIS command termination string pointer. */
trans = (struct motor_trans *) mr->dpvt;
trans->motor_call.termstring = " ID";
return(rtnval);
}
static RTN_STATUS MAXv_end_trans(struct motorRecord *mr)
{
if (*(MAXv_access.init_indicator) == NO)
{
errlogSevPrintf(errlogMinor, "%s", errmsg);
return(ERROR);
}
else
return(motor_end_trans_com(mr, &MAXv_access));
}
-125
View File
@@ -1,125 +0,0 @@
/*
FILENAME... devOms.cc
USAGE... Device level support for OMS VME8 and VME44 models.
*/
/*
* Original Author: Jim Kowalkowski
* Date: 01/18/93
* Current Author: Ron Sluiter
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 01-18-93 jbk initialized
* ...
* .03 03-19-96 tmm v1.10: modified encoder-ratio calculation
* .04 11-26-96 jps allow for bumpless-reboot on position
* .04a 02-19-97 tmm fixed for EPICS 3.13
* .05 06-16-03 rls Converted to R3.14.x.
*/
#include <alarm.h>
#include <callback.h>
#include <dbDefs.h>
#include <dbAccess.h>
#include <dbCommon.h>
#include <devSup.h>
#include <drvSup.h>
#include <recSup.h>
#include <errlog.h>
#include "motorRecord.h"
#include "motor.h"
#include "drvOms.h"
#include "devOmsCom.h"
#include "epicsExport.h"
extern int oms44_num_cards;
extern struct driver_table oms_access;
/* ----------------Create the dsets for devOMS----------------- */
static long oms_init(int);
static long oms_init_record(void *);
static long oms_start_trans(struct motorRecord *);
static RTN_STATUS oms_end_trans(struct motorRecord *);
struct motor_dset devOMS =
{
{8, NULL, (DEVSUPFUN) oms_init, (DEVSUPFUN) oms_init_record, NULL},
motor_update_values,
oms_start_trans,
oms_build_trans,
oms_end_trans
};
extern "C" {epicsExportAddress(dset,devOMS);}
static struct board_stat **oms_cards;
static const char errmsg[] = {"\n\n!!!ERROR!!! - Oms driver uninitialized.\n"};
static long oms_init(int after)
{
if (*(oms_access.init_indicator) == NO)
{
errlogSevPrintf(errlogMinor, "%s", errmsg);
return(ERROR);
}
else
return(motor_init_com(after, oms44_num_cards, &oms_access, &oms_cards));
}
static long oms_init_record(void *arg)
{
struct motorRecord *mr = (struct motorRecord *) arg;
return(motor_init_record_com(mr, oms44_num_cards, &oms_access, oms_cards));
}
static long oms_start_trans(struct motorRecord *mr)
{
struct motor_trans *trans;
long rtnval;
rtnval = motor_start_trans_com(mr, oms_cards);
/* Initialize a STOP_AXIS command termination string pointer. */
trans = (struct motor_trans *) mr->dpvt;
trans->motor_call.termstring = " ID";
return(rtnval);
}
static RTN_STATUS oms_end_trans(struct motorRecord *mr)
{
if (*(oms_access.init_indicator) == NO)
{
errlogSevPrintf(errlogMinor, "%s", errmsg);
return(ERROR);
}
else
return(motor_end_trans_com(mr, &oms_access));
}
-22
View File
@@ -1,22 +0,0 @@
# Oregon Micro Systems VME8/44 driver support.
device(motor,VME_IO,devOMS,"OMS VME8/44")
driver(drvOms)
# Oregon Micro Systems VME58 driver support.
device(motor,VME_IO,devOms58,"OMS VME58")
driver(drvOms58)
registrar(oms58Registrar)
# Oregon Micro Systems MAXv driver support.
device(motor,VME_IO,devMAXv,"OMS MAXv")
driver(drvMAXv)
registrar(OmsMAXvRegister)
# Oregon Micro Systems PC68/78 RS-232 serial driver support.
device(motor,VME_IO,devOmsPC68,"OMS PC68/78")
driver(drvOmsPC68)
registrar(OmsPC68Register)
variable(drvOmsPC68debug)
registrar(MAX_trajectoryScanRegistrar)
-125
View File
@@ -1,125 +0,0 @@
/*
FILENAME... devOms58.c
USAGE... Motor record device level support for OMS VME58.
*/
/*
* Original Author: Jim Kowalkowski
* Current Author: Joe Sullivan
* Date: 11/14/94
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 01-18-93 jbk initialized
* .02 11-14-94 jps copy devOMS.c and modify to point to vme58 driver
* .03 03-19-96 tmm v1.10: modified encoder-ratio calculation
* .04 06-20-96 jps allow for bumpless-reboot on position
* .04a 02-19-97 tmm fixed for EPICS 3.13
* .05 06-16-03 rls Converted to R3.14.x.
*/
#include <alarm.h>
#include <callback.h>
#include <dbDefs.h>
#include <dbAccess.h>
#include <dbCommon.h>
#include <devSup.h>
#include <drvSup.h>
#include <recSup.h>
#include <errlog.h>
#include "motorRecord.h"
#include "motor.h"
#include "drvOms58.h"
#include "devOmsCom.h"
#include "epicsExport.h"
extern int oms58_num_cards;
extern struct driver_table oms58_access;
/* ----------------Create the dsets for devOMS----------------- */
static long oms_init(int);
static long oms_init_record(void *);
static long oms_start_trans(struct motorRecord *);
static RTN_STATUS oms_end_trans(struct motorRecord *);
struct motor_dset devOms58 =
{
{8, NULL, (DEVSUPFUN) oms_init, (DEVSUPFUN) oms_init_record, NULL},
motor_update_values,
oms_start_trans,
oms_build_trans,
oms_end_trans
};
extern "C" {epicsExportAddress(dset,devOms58);}
static struct board_stat **oms_cards;
static const char errmsg[] = {"\n\n!!!ERROR!!! - Oms58 driver uninitialized.\n"};
static long oms_init(int after)
{
if (*(oms58_access.init_indicator) == NO)
{
errlogSevPrintf(errlogMinor, "%s", errmsg);
return(ERROR);
}
else
return(motor_init_com(after, oms58_num_cards, &oms58_access, &oms_cards));
}
static long oms_init_record(void *arg)
{
struct motorRecord *mr = (struct motorRecord *) arg;
return(motor_init_record_com(mr, oms58_num_cards, &oms58_access, oms_cards));
}
static long oms_start_trans(struct motorRecord *mr)
{
struct motor_trans *trans;
long rtnval;
rtnval = motor_start_trans_com(mr, oms_cards);
/* Initialize a STOP_AXIS command termination string pointer. */
trans = (struct motor_trans *) mr->dpvt;
trans->motor_call.termstring = " ID";
return(rtnval);
}
static RTN_STATUS oms_end_trans(struct motorRecord *mr)
{
if (*(oms58_access.init_indicator) == NO)
{
errlogSevPrintf(errlogMinor, "%s", errmsg);
return(ERROR);
}
else
return(motor_end_trans_com(mr, &oms58_access));
}
-543
View File
@@ -1,543 +0,0 @@
/*
FILENAME... devOmsCom.cc
USAGE... Data and functions common to all OMS device level support.
*/
/*
* Original Author: Jim Kowalkowski
* Previous Author: Joe Sullivan
* Date: 11/14/94
* Current Author: Ron Sluiter
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 01-18-93 jbk initialized
* .02 11-14-94 jps copy devOMS.c and modify to point to vme58 driver
* .03 03-19-96 tmm v1.10: modified encoder-ratio calculation
* .04 06-20-96 jps allow for bumpless-reboot on position
* .04a 02-19-97 tmm fixed for EPICS 3.13
* .05 05-14-01 rls Support for jog velocity and acceleration commands.
* Added "CA" to home and jog commands so JVEL does not
* see done flag from previous operation.
* .06 03-27-02 rls Eliminated RES. All input positions, velocities and
* accelerations are in motor steps.
* .07 07-05-02 rls Work around for OMS bug that ignores MR+/-1.
* Use OMS UU command to support reference is always in
* motor steps.
* .08 06-04-03 rls Convert to R3.14.x.
* .09 06-04-03 rls extended device directive support PREM and POST.
* .10 06-16-03 rls Converted to R3.14.x.
* .11 06-16-04 rls Terminate "LP" command with ";" to prevent MAXv stale data.
* .12 08-27-04 rls Terminate "JG" command with ";" to prevent MAXv stale data.
* .13 03-21-05 rls OSI - built for solaris and linux hosts.
* .14 03-23-05 rls restrict acceleration to valid values.
* .15 08-18-06 rls Output "slew <= base" error message only one time.
* .16 02-16-07 rls Bug fix for overwriting PID parameter fields during
* normalization calculation.
* .17 05-14-08 rls Fixed stop acceleration calculation.
* .18 05-14-08 rls For MAXv, restore slew acceleration after STOP command.
* .19 06-11-08 rls For MAXv, fix error on ER command; replace UU1.0 with UF.
* .20 07-24-08 rls For MAXv, normalize PID values based on 32,767 maximum.
* .21 03-01-10 rls Some MR commands still ignored; change fraction to .9.
* .22 11-10-10 rls Error check for valid acceleration rate on STOP command.
* .23 10-26-11 rls Use MAXv motor type to support MRES and ERES with
* different polarity (signs).
* .24 11-29-12 rls Terminate UU command argument with a ';' character.
* Fixes "Command error" with MAXv ver:1.41 firmware.
* .25 03-13-15 rls Bug fix for incorrect deceleration calculation at end of
* JOG command.
*
*/
#include <string.h>
#include <stdio.h>
#include <errlog.h>
#include <math.h>
#include <epicsThread.h>
#include <epicsString.h>
#include <dbAccess.h>
#include <stdlib.h>
#include "motorRecord.h"
#include "motor.h"
#include "motordevCom.h"
#include "devOmsCom.h"
#include "drvMAXv.h"
/* WARNING... The following is a COPY of a motorRecord.cc definition.
If device support uses MIP definitions, then they should be moved
from motorRecord.cc to motor.h. In addition, for device support to
fully use MIP (e.g. correct accleration on STOP command), device
support needs record support to implement previous MIP (PMIP). */
#define MIP_JOG_STOP 0x2000 /* Stop jogging. */
/*
Command set used by record support. WARNING! this must match "motor_cmnd" in
motor.h
*/
struct motor_table
{
msg_types type;
const char *command;
int num_parms;
};
struct motor_table const oms_table[] =
{
{MOTION, " MA", 1}, /* MOVE_ABS */
{MOTION, " MR", 1}, /* MOVE_REL */
{MOTION, " CA HM", 1}, /* HOME_FOR */
{MOTION, " CA HR", 1}, /* HOME_REV */
{IMMEDIATE, " LP", 1}, /* LOAD_POS */
{IMMEDIATE, " VB", 1}, /* SET_VEL_BASE */
{IMMEDIATE, " VL", 1}, /* SET_VELO */
{IMMEDIATE, " AC", 1}, /* SET_ACCEL */
{IMMEDIATE, " GD", 0}, /* jps: from GO to GD */
{IMMEDIATE, " ER", 2}, /* SET_ENC_RATIO */
{INFO, " ", 0}, /* GET_INFO */
{MOVE_TERM, " ST", 0}, /* STOP_AXIS */
{VELOCITY, " CA JG", 1}, /* JOG */
{IMMEDIATE," KP", 1}, /* SET_PGAIN */
{IMMEDIATE," KI", 1}, /* SET_IGAIN */
{IMMEDIATE," KD", 1}, /* SET_DGAIN */
{IMMEDIATE," HN", 0}, /* ENABLE_TORQUE */
{IMMEDIATE," HF", 0}, /* DISABL_TORQUE */
{IMMEDIATE, "", 0}, /* PRIMITIVE */
{IMMEDIATE, "", 0}, /* SET_HIGH_LIMIT */
{IMMEDIATE, "", 0}, /* SET_LOW_LIMIT */
{VELOCITY, " JG", 1}, /* JOG_VELOCITY */
};
/*
FUNCTION... long oms_build_trans(motor_cmnd, double *, struct motorRecord *)
USAGE... Add a part to the transaction.
INPUT... command - index into oms_table[].
*parms - one or more input parameters; determined by
"num_parms" in oms_table.
*mr - motor record pointer.
LOGIC...
Initialize pointers; return value to OK.
Set highest command type priority.
IF transaction is NOT initialized (i.e., state != BUILD_STATE)
ERROR RETURN.
ENDIF
IF input command is a PRIMITIVE command, AND, the INIT field is not empty.
IF input command is a "device directive".
Find terminating '@'.
IF valid "device directive" (i.e, directive bracketed by '@'s).
IF "Driver Power Monitoring ON" directive.
Flush response buffer.
Read motor controller's GPIO configuration.
IF bit corresponding to current axis is configured as an
output bit.
Set "Driver Power Monitoring" indicator true.
ELSE
Output ERROR message.
ENDIF
ENDIF
Strip device directive and copy rest of INIT field to local buffer.
ELSE
Copy INIT field to local buffer.
ENDIF
ELSE
Copy INIT field to local buffer.
ENDIF
ELSE
IF input command is set HIGH or LOW travel limit.
Null command. Set transaction state to IDLE.
ELSE
IF input command is Proportional Gain, AND, gain < valid minimum.
Set the gain and the PCOF field to the minimum.
Set return indicator to ERROR.
ELSE IF input command is STOP_AXIS.
NOTE: This logic is here as a workaround for an OMS firmware
error. When a STOP command was issued during the target move,
the backlash acceleration would go into effect.
Prefix command with ACCL field acceleration.
ENDIF
IF command type is MOTION or VELOCITY.
Process PREM and POST fields.
ENDIF
IF Overtravel status indicator true, AND, input command is a MOVE.
NOTE: This logic is here as a workaround for the "Moving off a
limit switch" OMS firmware error.
IF incremental distance to target position is positive.
Set OMS controller "direction logic" positive.
ELSE
Set OMS controller "direction logic" negative.
ENDIF
ENDIF
Copy input command into output message.
Copy input command parameters into output message.
ENDIF
ENDIF
*/
RTN_STATUS oms_build_trans(motor_cmnd command, double *parms, struct motorRecord *mr)
{
struct motor_trans *trans = (struct motor_trans *) mr->dpvt;
struct mess_node *motor_call;
struct controller *brdptr;
struct MAXvController *MAXvCntrl = NULL;
char buffer[40];
msg_types cmnd_type;
RTN_STATUS rtnind;
static bool invalid_velmsg_latch = false;
bool MAXv = false;
int card, signal;
long valid_acc;
rtnind = OK;
motor_call = &trans->motor_call;
card = motor_call->card;
signal = motor_call->signal;
cmnd_type = oms_table[command].type;
if (cmnd_type > motor_call->type)
motor_call->type = cmnd_type;
/* concatenate onto the dpvt message field */
if (trans->state != BUILD_STATE)
return(rtnind = ERROR);
if ((brdptr = (*trans->tabptr->card_array)[card]) == NULL) /* Test for disabled board. */
return(rtnind = ERROR);
if (strncmp(brdptr->ident, "MAXv", 4) == 0)
{
MAXv = true;
MAXvCntrl = (struct MAXvController *) brdptr->DevicePrivate;
/* Error check; ER command only for MAXv PSE type motors. */
if (command == SET_ENC_RATIO && MAXvCntrl->typeID[signal] != PSE)
{
trans->state = IDLE_STATE; /* No command sent to the controller. */
return(rtnind);
}
}
if ((command == PRIMITIVE) && (mr->init != NULL) &&
(strlen(mr->init) != 0))
{
extern struct driver_table oms58_access;
/* Test for a "device directive" in the Initialization string. */
if ((mr->init[0] == '@') && (trans->tabptr == &oms58_access))
{
char *end = strrchr(&mr->init[1], '@');
if (end != NULL)
{
struct driver_table *tabptr = trans->tabptr;
int size = (end - &mr->init[0]) + 1;
strncpy(buffer, mr->init, size);
buffer[size] = (char) NULL;
if (strcmp(buffer, "@DPM_ON@") == 0)
{
int response, bitselect;
char respbuf[10];
(*tabptr->getmsg)(card, respbuf, -1);
(*tabptr->sendmsg)(card, "RB\r", (char*) NULL);
(*tabptr->getmsg)(card, respbuf, 1);
if (sscanf(respbuf, "%x", &response) == 0)
response = 0; /* Force an error. */
bitselect = (1 << motor_call->signal);
if ((response & bitselect) == 0)
trans->dpm = true;
else
errPrintf(0, __FILE__, __LINE__,
"Invalid VME58 configuration; RB = 0x%x\n", response);
}
end++;
strcpy(buffer, end);
}
else
strcpy(buffer, mr->init);
}
else
strcpy(buffer, mr->init);
strcat(motor_call->message, buffer);
strcat(motor_call->message, ";");
}
else
{
int first_one, itera;
if (command == SET_HIGH_LIMIT || command == SET_LOW_LIMIT)
trans->state = IDLE_STATE; /* No command sent to the controller. */
else
{
msta_field msta;
/* Silently enforce minimum range on KP command. */
if (command == SET_PGAIN && *parms < 0.00005)
{
*parms = 0.00005;
mr->pcof = 0.00005;
rtnind = ERROR;
}
else if (command == STOP_AXIS)
{
double acc;
/* Use MIP to determine which acc. rate to use. */
if (mr->mip & MIP_JOG_STOP)
acc = mr->jar / fabs(mr->mres);
else
acc = ((mr->velo - mr->vbas) / fabs(mr->mres)) / mr->accl;
valid_acc = NINT(acc);
/* For VME8/44 & MAXv, valid_acc < 8E6. For VME58, valid_acc < 1E9.
* Use 8E6 in common code. */
if (valid_acc < 1 || valid_acc > 8E6)
{
errPrintf(-1, __FILE__, __LINE__,
"Overriding invalid acceleration.\n");
valid_acc = (long) 200000; /* Using VME58 default. */
}
/* Put in acceleration. */
if (MAXv == true)
strcat(motor_call->message, "FL");
strcat(motor_call->message, oms_table[SET_ACCEL].command);
sprintf(buffer, "%ld", valid_acc);
strcat(motor_call->message, buffer);
if (MAXv == true)
strcat(motor_call->message, "; WQ");
}
if (cmnd_type == MOTION || cmnd_type == VELOCITY)
{
if (strlen(mr->prem) != 0)
{
char prem_buff[40];
/* Test for a "device directive" in the PREM string. */
if (mr->prem[0] == '@')
{
bool errind = false;
char *end = strchr(&mr->prem[1], '@');
if (end == NULL)
errind = true;
else
{
DBADDR addr;
double delay;
char *start, *tail;
int size = (end - &mr->prem[0]) + 1;
/* Copy device directive to prem_buff. */
strncpy(prem_buff, mr->prem, size);
prem_buff[size] = (char) NULL;
if (strncmp(prem_buff, "@PUT(", 5) != 0)
goto errorexit;
/* Point "start" to PV name argument. */
tail = NULL;
start = epicsStrtok_r(&prem_buff[5], ",", &tail);
if (tail == NULL)
goto errorexit;
if (dbNameToAddr(start, &addr)) /* Get address of PV. */
{
errPrintf(-1, __FILE__, __LINE__, "Invalid PV name: %s", start);
goto errorexit;
}
/* Point "start" to PV value argument. */
start = epicsStrtok_r(NULL, ",", &tail);
if (tail == NULL)
{
delay = 0.0;
tail = start;
start = epicsStrtok_r(NULL, ")", &tail);
if (tail == NULL)
goto errorexit;
}
else
{
char *last;
last = epicsStrtok_r(NULL, ")", &tail);
if (last == NULL)
goto errorexit;
delay = atof(last);
}
if (dbPutField(&addr, DBR_STRING, start, 1L))
{
errPrintf(-1, __FILE__, __LINE__, "invalid value: %s", start);
goto errorexit;
}
if (delay != 0.0)
{
if (delay > 10.0)
delay = 10.0;
epicsThreadSleep(delay);
}
}
if (errind == true)
errorexit: errMessage(-1, "Invalid device directive");
end++;
strcpy(prem_buff, end);
}
else
strcpy(prem_buff, mr->prem);
strcat(motor_call->message, " ");
strcat(motor_call->message, prem_buff);
strcat(motor_call->message, " ");
}
if (strlen(mr->post) != 0)
motor_call->postmsgptr = (char *) &mr->post;
}
/* Code to hide Oms58 moving off limit switch problem. */
msta.All = mr->msta;
if ((msta.Bits.RA_PLUS_LS || msta.Bits.RA_MINUS_LS) &&
(command == MOVE_ABS || command == MOVE_REL))
{
if (mr->rdif >= 0)
strcat(motor_call->message, " MP");
else
strcat(motor_call->message, " MM");
}
/* put in command */
strcat(motor_call->message, oms_table[command].command);
/* put in parameters */
for (first_one = YES, itera = 0; itera < oms_table[command].num_parms;
itera++)
{
if (first_one == YES)
first_one = NO;
else
strcat(motor_call->message, ",");
switch (command)
{
case SET_PGAIN:
case SET_IGAIN:
case SET_DGAIN:
if (MAXv == true)
sprintf(buffer, "%.1f;", (parms[itera] * 32767.0));
else
sprintf(buffer, "%.1f;", (parms[itera] * 1999.9));
break;
case SET_VELOCITY: /* OMS errors if VB = VL. */
{
long vbase, vel;
vbase = NINT(mr->vbas / fabs(mr->mres));
vel = NINT(parms[itera]);
if (vel <= vbase)
{
if (invalid_velmsg_latch == false)
{
invalid_velmsg_latch = true; /* Ouput msg. one time. */
errPrintf(-1, __FILE__, __LINE__,
"Overriding invalid velocity; slew <= base.\n");
}
vel = vbase + 1;
}
sprintf(buffer, "%ld", vel);
}
break;
case MOVE_REL:
{
/* Code around OMS bug that ignores MR+/-1. */
long relmove;
relmove = NINT(parms[itera]);
sprintf(buffer, "%ld.9", relmove);
}
break;
case SET_ACCEL: /* Prevent invalid acceleration values. */
{
valid_acc = NINT(parms[itera]);
if (valid_acc < 1 || valid_acc > 8E6)
{
errPrintf(-1, __FILE__, __LINE__,
"Overriding invalid acceleration.\n");
valid_acc = (long) 200000; /* Using VME58 default. */
}
sprintf(buffer, "%ld", valid_acc);
}
break;
default:
sprintf(buffer, "%ld", NINT(parms[itera]));
}
strcat(motor_call->message, buffer);
}
switch (command)
{
case SET_ENC_RATIO:
if (MAXv == true && parms[0] == parms[1])
sprintf(buffer, " UF");
else
sprintf(buffer, " UU%f;", fabs(parms[0]/parms[1]));
strcat(motor_call->message, buffer);
break;
case LOAD_POS:
if ((MAXv == true) && (MAXvCntrl != NULL) && (MAXvCntrl->typeID[signal] != PSO) && (MAXvCntrl->fwver > 1.29))
{
long int ref = NINT(parms[0]);
long int fdbk = ref;
if ((mr->mres > 0.0 && mr->eres < 0.0) ||
(mr->mres < 0.0 && mr->eres > 0.0))
fdbk *= -1;
sprintf(motor_call->message, "LO%ld LPE%ld;", ref, fdbk);
}
break;
case JOG:
case JOG_VELOCITY:
strcat(motor_call->message, ";");
default:
break;
}
}
}
return(rtnind);
}
-36
View File
@@ -1,36 +0,0 @@
/*
FILENAME.. devOmsCom.h
USAGE... This file contains OMS device information that is
common to all OMS device support modules.
*/
/*
* Original Author: Ron Sluiter
* Date: 12/22/98
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contract
* W-31-109-ENG-38 at Argonne National Laboratory.
*
* Beamline Controls & Data Acquisition Group
* Experimental Facilities Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
*/
#ifndef INCdevOmsComh
#define INCdevOmsComh 1
#include "motordevCom.h"
extern RTN_STATUS oms_build_trans(motor_cmnd, double *, struct motorRecord *);
#endif /* INCdevOmsComh */
-130
View File
@@ -1,130 +0,0 @@
/*
FILENAME... devOmsPC68.c
USAGE... Motor record device level support for OMS VME58.
*/
/*
* Original Author: Brian Tieman
* Current Author: Ron Sluiter
* Date: 04/24/06
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 04-25-06 copied from devOms.cc
*/
#include <alarm.h>
#include <callback.h>
#include <dbDefs.h>
#include <dbAccess.h>
#include <dbCommon.h>
#include <devSup.h>
#include <drvSup.h>
#include <recSup.h>
#include <errlog.h>
#include "motorRecord.h"
#include "motor.h"
#include "drvOmsPC68Com.h"
#include "devOmsCom.h"
#include "epicsExport.h"
#define STATIC static
extern int OmsPC68_num_cards;
extern struct driver_table OmsPC68_access;
/* ----------------Create the dsets for devOMS----------------- */
STATIC long oms_init(int);
STATIC long oms_init_record(void *);
STATIC long oms_start_trans(struct motorRecord *);
STATIC RTN_STATUS oms_end_trans(struct motorRecord *);
struct motor_dset devOmsPC68 =
{
{8, NULL, (DEVSUPFUN) oms_init, (DEVSUPFUN) oms_init_record, NULL},
motor_update_values,
oms_start_trans,
oms_build_trans,
oms_end_trans
};
extern "C" {epicsExportAddress(dset,devOmsPC68);}
STATIC struct board_stat **oms_cards;
STATIC const char errmsg[] = {"\n\n!!!ERROR!!! - OmsPC68 driver uninitialized.\n"};
//__________________________________________________________________________________________
STATIC long oms_init(int after)
{
if (*(OmsPC68_access.init_indicator) == NO)
{
errlogSevPrintf(errlogMinor, "%s", errmsg);
return(ERROR);
}
else
return(motor_init_com (after, OmsPC68_num_cards, &OmsPC68_access, &oms_cards));
}
//__________________________________________________________________________________________
STATIC long oms_init_record(void *arg)
{
struct motorRecord *mr = (struct motorRecord *) arg;
return(motor_init_record_com(mr, OmsPC68_num_cards, &OmsPC68_access, oms_cards));
}
//__________________________________________________________________________________________
STATIC long oms_start_trans(struct motorRecord *mr)
{
struct motor_trans *trans;
long rtnval;
rtnval = motor_start_trans_com(mr, oms_cards);
/* Initialize a STOP_AXIS command termination string pointer. */
trans = (struct motor_trans *) mr->dpvt;
trans->motor_call.termstring = " ID";
return(rtnval);
}
//__________________________________________________________________________________________
STATIC RTN_STATUS oms_end_trans(struct motorRecord *mr)
{
if (*(OmsPC68_access.init_indicator) == NO)
{
errlogSevPrintf(errlogMinor, "%s", errmsg);
return(ERROR);
}
else
return(motor_end_trans_com(mr, &OmsPC68_access));
}
//__________________________________________________________________________________________
File diff suppressed because it is too large Load Diff
-196
View File
@@ -1,196 +0,0 @@
/*
FILENAME... drvMAXv.h
USAGE... OMS driver level "include" information that is specific to OMS
model MAXv.
*/
/*
* Original Author: Ron Sluiter
* Date: 04/05/04
* Current Author: Ron Sluiter
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* 01 04-05-04 rls Copied for drvOms58.h
* 02 10-26-11 rls motor_init() sets motor typeID as boot-up. Used by device
* support to allow MRES and ERES to be opposite sign.
*
*/
#ifndef INCdrvMAXvh
#define INCdrvMAXvh 1
#include "drvOmsCom.h"
#include <epicsMutex.h>
/*
* MAXv default profile
*/
#define MAXv_NUM_CARDS 15
#define BUFFER_SIZE 1024
enum MotorTypes {PSO, // Stepper; w/o encoder
PSE, // Stepper; with encoder
PSM}; // Servo
struct MAXvController
{
MotorTypes typeID[8];
float fwver; /* firmware version */
epicsMutexId message_mutex;
};
/* MAXv DUAL-PORT MEMORY MAP */
/* Limit Switch Status - Offset = 0x40 */
typedef union
{
epicsUInt32 All;
struct
{
unsigned int s_minus :1;
unsigned int r_minus :1;
unsigned int v_minus :1;
unsigned int u_minus :1;
unsigned int t_minus :1;
unsigned int z_minus :1;
unsigned int y_minus :1;
unsigned int x_minus :1;
unsigned int s_plus :1;
unsigned int r_plus :1;
unsigned int v_plus :1;
unsigned int u_plus :1;
unsigned int t_plus :1;
unsigned int z_plus :1;
unsigned int y_plus :1;
unsigned int x_plus :1;
} Bits;
} LIMIT_SWITCH;
/* Home Switch Status - Offset = 0x44 */
typedef union
{
epicsUInt32 All;
struct
{
unsigned int home_s :1; /* status of S axis */
unsigned int home_r :1; /* status of R axis */
unsigned int home_v :1; /* status of V axis */
unsigned int home_u :1; /* status of U axis */
unsigned int home_t :1; /* status of T axis */
unsigned int home_z :1; /* status of Z axis */
unsigned int home_y :1; /* status of Y axis */
unsigned int home_x :1; /* status of X axis */
} Bits;
} HOME_SWITCH;
/* Firmware status - Offset = 0x48 */
typedef union
{
epicsUInt32 All;
struct
{
unsigned int na19 :13; /* N/A bits 19-31 */
unsigned int factoryparm_loaded :1;
unsigned int altparm_loaded :1;
unsigned int defaultparm_loaded :1;
unsigned int altprgm_err :1;
unsigned int altparm_chksum_err :1;
unsigned int prgm_err :1;
unsigned int parm_chksum_err :1;
unsigned int na10 :2; /* N/A bits 10-11 */
unsigned int program_error :1;
unsigned int flash_chksum_err :1;
unsigned int na3 :5; /* N/A bits 3-7 */
unsigned int running :1;
unsigned int initializing :1;
unsigned int not_downloaded :1;
} Bits;
} FIRMWARE_STATUS;
/* Status#1 - Offset = 0xFC0 */
typedef union
{
epicsUInt32 All;
struct
{
unsigned int na3 :5; /* N/A bits 27-31. */
unsigned int data_avail :1;
unsigned int text_response :1;
unsigned int cmndError :1; /* Command error dectect */
unsigned int slip :8;
unsigned int overtravel :8;
unsigned int done :8;
} Bits;
} STATUS1;
/* OMS VME dual port memory map */
struct MAXv_motor
{
epicsUInt32 cmndPos[8];
epicsUInt32 encPos[8];
LIMIT_SWITCH limit_switch;
HOME_SWITCH home_switch;
FIRMWARE_STATUS firmware_status;
epicsUInt32 direct_cmnd_mbox;
epicsUInt32 position_req_mbox;
epicsUInt32 coherent_cmndPos[8];
epicsUInt32 coherent_encPos[8];
epicsUInt32 msg_semaphore;
epicsUInt32 queue_flush_mbox;
epicsUInt32 gpio;
epicsUInt32 naA0[2]; /* N/A byte offset 0xA0 - 0xA7. */
epicsUInt32 absPos[8];
epicsUInt32 naC8[9]; /* N/A byte offset 0xC8 - 0xEB. */
epicsUInt32 flash_pgm_ptr;
epicsUInt32 outPutIndex;
epicsUInt32 outGetIndex;
epicsUInt32 inPutIndex;
epicsUInt32 inGetIndex;
epicsUInt8 outBuffer[BUFFER_SIZE];
epicsUInt8 inBuffer[BUFFER_SIZE];
epicsUInt8 utility[BUFFER_SIZE];
epicsUInt32 naD00[176]; /* N/A byte offset 0xD00 - 0xFBF. */
STATUS1 status1_flag;
STATUS1 status1_irq_enable;
epicsUInt32 status2_flag;
epicsUInt32 status2_irq_enable;
epicsUInt32 IACK_vector;
epicsUInt32 config_switch;
epicsUInt32 AM_register;
epicsUInt32 naFDC[7];
epicsUInt32 FIFO_status_cntrl;
epicsUInt32 FIFO_date;
};
#endif /* INCdrvMAXvh */
File diff suppressed because it is too large Load Diff
-107
View File
@@ -1,107 +0,0 @@
/*
FILENAME... drvOms.h
USAGE... This file contains OMS driver "include" information that is
specific to OMS models VME8 and VME44.
*/
/*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .00 10-23-03 rls - VX2 spurious interrupt fix; enable all interrupts, including
* transmit buffer empty.
* .01 10-28-03 rls - moved OMS specific "irqdatastr" from motordrvCom.h to here.
*/
#ifndef INCdrvOmsh
#define INCdrvOmsh 1
#include "drvOmsCom.h"
#include "epicsRingBytes.h"
/*
* VME8/44 default profile
*/
#define OMS_NUM_CARDS 8
#define OMS_NUM_CHANNELS 8
#define OMS_NUM_ADDRS 0xFC00
#define OMS_BRD_SIZE 0x10 /* card address boundary */
#define OMS_RESP_Q_SZ 0x100 /* maximum oms response message size */
/* status register */
#define STAT_IRQ 0x80
#define STAT_TRANS_BUF_EMPTY 0x40
#define STAT_INPUT_BUF_FULL 0x20
#define STAT_DONE 0x10
#define STAT_OVERTRAVEL 0x08
#define STAT_ENCODER_REQ 0x04
#define STAT_INIT 0x02
#define STAT_ERROR 0x01
/* done flag register */
#define DONE_X 0x01
#define DONE_Y 0x02
#define DONE_Z 0x04
#define DONE_T 0x08
#define DONE_U 0x10
#define DONE_V 0x20
#define DONE_R 0x40
#define DONE_S 0x80
/* interrupt control register */
#define IRQ_ENABLE 0x80
#define IRQ_TRANS_BUF 0x40
#define IRQ_INPUT_BUF 0x20
#define IRQ_DONE 0x10
#define IRQ_RESET_ID 0x01
#define IRQ_ENABLE_ALL (IRQ_ENABLE|IRQ_TRANS_BUF|IRQ_INPUT_BUF|IRQ_DONE)
struct vmex_motor
{
epicsUInt8 unused0;
epicsUInt8 data;
epicsUInt8 unused1;
epicsUInt8 done;
epicsUInt8 unused2;
epicsUInt8 control;
epicsUInt8 unused3;
epicsUInt8 status;
epicsUInt8 unused4;
epicsUInt8 vector;
epicsUInt8 unused5[6];
};
struct irqdatastr /* Used only for VME44. */
{
/* Interrupt Handling control elements */
int irqErrno; /* Error indicator from isr */
epicsUInt8 irqEnable;
epicsRingBytesId recv_rng; /* message receiving control */
epicsEvent *recv_sem;
epicsRingBytesId send_rng; /* message transmitting control */
};
#endif /* INCdrvOmsh */
File diff suppressed because it is too large Load Diff
-263
View File
@@ -1,263 +0,0 @@
/*
FILENAME... drvOms58.h
USAGE... OMS driver level "include" information that is specific to OMS
model VME58.
*/
/*
* Original Author: Jim Kowalkowski
* Current Author: Joe Sullivan
* Date: 11/14/94
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 01-18-93 jbk initialized
* .02 11-14-94 jps copy drvOms.c and modify to point to vme58 driver
* ...
* .06 12-07-94 jps first released version w/interrupt supprt
* .07 12-20-94 jps rearrange the device init routines
* .08 05-03-96 jps convert 32bit card accesses to 16bit - vme58PCB
* version D does not support 32bit accesses.
* .09 05-09-97 jps increase maximum card count to 15
* .10 08-22-01 rls "int" type specifications for all bit-fields.
* .11 03-21-05 rls replace VxWorks specific "uint16_t" with "epicsUInt16".
* .12 01-26-11 rls added reboot flag in DPRAM R/W reserved area.
*
*/
#ifndef INCdrvOms58h
#define INCdrvOms58h 1
#include "drvOmsCom.h"
/*
* VME58 default profile
*/
#define OMS_NUM_CARDS 15
#define OMS_NUM_CHANNELS 8
#define OMS_NUM_ADDRS 0x4000
#define OMS_BRD_SIZE 0x1000 /* card address boundary */
#define BUFFER_SIZE 256
/* Board control register structures */
/* VME58 DUAL-PORT MEMORY MAP */
typedef struct
{
epicsUInt16 encPos[2];
epicsUInt16 cmndPos[2];
epicsUInt16 cmndVel[2];
epicsUInt16 accel[2];
epicsUInt16 maxVel[2];
epicsUInt16 baseVel[2];
epicsUInt16 dFltrGain[2];
epicsUInt16 dFltrPole[2];
epicsUInt16 dFltrZero[2];
epicsUInt16 reserved[46];
} MOTOR_DATA_REGS;
/* Definitions for VME58 I/O Registers */
/* Control Register - Offset = 0x0FE1 */
typedef union
{
epicsUInt8 All;
struct
{
unsigned int intReqEna :1; /* Master interrupt request enable */
unsigned int ioIntEna :1; /* I/O bits 0 and 1 interrupt enable */
unsigned int directInEna:1; /* Interrupt request to the VME58 ? */
unsigned int doneIntEna :1; /* Done detect interrupt enable */
unsigned int otIntEna :1; /* Overtravel detect interrupt enable */
unsigned int slipIntEna :1; /* Encoder slip detect interrupt enable */
unsigned int :1; /* Unused */
unsigned int update :1; /* Data area update request */
} Bits;
} CNTRL_REG;
/* Status Register - Offset = 0x0FE3 */
typedef union
{
epicsUInt8 All;
struct
{
unsigned int interrupt :1; /* Interrupt dectect */
unsigned int directIn :1; /* Direct input interrupt detect */
unsigned int directOut :1; /* Direct ouput interrupt detect */
unsigned int done :1; /* Motion done detect */
unsigned int overtravel :1; /* Overtravel detect */
unsigned int encoderSlip:1; /* Encoder slip detect */
unsigned int cardOK :1; /* Powerup initilization complete */
unsigned int cmndError :1; /* Command error dectect */
} Bits;
} STATUS_REG;
/* I/O Register(0-7) - Offset = 0x0FE5 */
typedef union
{
epicsUInt8 All;
struct
{
unsigned int io_7 :1; /* Bit 7 */
unsigned int io_6 :1; /* Bit 6 */
unsigned int io_5 :1; /* Bit 5 */
unsigned int io_4 :1; /* Bit 4 */
unsigned int io_3 :1; /* Bit 3 */
unsigned int io_2 :1; /* Bit 2 */
unsigned int io_1 :1; /* Bit 1 */
unsigned int io_0 :1; /* Bit 0 */
} Bits;
} IO_LOW_REG;
/* Slip Flag Register - Offset = 0x0FE7 */
typedef union
{
epicsUInt8 All;
struct
{
unsigned int slip_s :1; /* status of S axis */
unsigned int slip_r :1; /* status of R axis */
unsigned int slip_v :1; /* status of V axis */
unsigned int slip_u :1; /* status of U axis */
unsigned int slip_t :1; /* status of T axis */
unsigned int slip_z :1; /* status of Z axis */
unsigned int slip_y :1; /* status of Y axis */
unsigned int slip_x :1; /* status of X axis */
} Bits;
} SLIP_REG;
/* Done Flag Register - Offset = 0x0FE9 */
typedef union
{
epicsUInt8 All;
struct
{
unsigned int done_s :1; /* status of S axis */
unsigned int done_r :1; /* status of R axis */
unsigned int done_v :1; /* status of V axis */
unsigned int done_u :1; /* status of U axis */
unsigned int done_t :1; /* status of T axis */
unsigned int done_z :1; /* status of Z axis */
unsigned int done_y :1; /* status of Y axis */
unsigned int done_x :1; /* status of X axis */
} Bits;
} DONE_REG;
/* I/O High Register(8-13) - Offset = 0x0FEB */
typedef union
{
epicsUInt8 All;
struct
{
unsigned int :1; /* Unused */
unsigned int :1; /* Unused */
unsigned int io_13 :1; /* Bit 13 */
unsigned int io_12 :1; /* Bit 12 */
unsigned int io_11 :1; /* Bit 11 */
unsigned int io_10 :1; /* Bit 10 */
unsigned int io_9 :1; /* Bit 9 */
unsigned int io_8 :1; /* Bit 8 */
} Bits;
} IO_HIGH_REG;
/* Limit Switch Status Register - Offset = 0x0FED */
typedef union
{
epicsUInt8 All;
struct
{
unsigned int limit_s :1; /* status of S axis */
unsigned int limit_r :1; /* status of R axis */
unsigned int limit_v :1; /* status of V axis */
unsigned int limit_u :1; /* status of U axis */
unsigned int limit_t :1; /* status of T axis */
unsigned int limit_z :1; /* status of Z axis */
unsigned int limit_y :1; /* status of Y axis */
unsigned int limit_x :1; /* status of X axis */
} Bits;
} LIMIT_REG;
/* Home Switch Status Register - Offset = 0x0FEF */
typedef union
{
epicsUInt8 All;
struct
{
unsigned int home_s :1; /* status of S axis */
unsigned int home_r :1; /* status of R axis */
unsigned int home_v :1; /* status of V axis */
unsigned int home_u :1; /* status of U axis */
unsigned int home_t :1; /* status of T axis */
unsigned int home_z :1; /* status of Z axis */
unsigned int home_y :1; /* status of Y axis */
unsigned int home_x :1; /* status of X axis */
} Bits;
} HOME_REG;
typedef struct
{
epicsUInt8 unused00;
epicsUInt8 cntrlReg; /* Control Register - Read/Write */
epicsUInt8 unused02;
epicsUInt8 statusReg; /* Status Register - Read */
epicsUInt8 unused04;
epicsUInt8 ioLowReg; /* IO bits 0-7 status register - Read */
epicsUInt8 unused06;
epicsUInt8 slipReg; /* Encoder slip status register - Read */
epicsUInt8 unused08;
epicsUInt8 doneReg; /* Axis done status register - Read */
epicsUInt8 unused0A;
epicsUInt8 ioHighReg; /* IO bits 8-13 status register - Read */
epicsUInt8 unused0C;
epicsUInt8 limitReg; /* Limit switch status register - Read */
epicsUInt8 unused0E;
epicsUInt8 homeReg; /* Home switch status register - Read */
epicsUInt8 unusedF0;
epicsUInt8 intVector; /* Interrupt vector */
} MOTOR_CNTRL_REGS;
/* OMS VME dual port memory map */
struct vmex_motor
{ /* Offset */
epicsInt16 inPutIndex; /* 0x0000 */
epicsInt16 outGetIndex; /* 0x0002 */
epicsInt16 inBuffer[BUFFER_SIZE]; /* 0x0004 */
epicsInt16 reserved0[254]; /* 0x0204 */
MOTOR_DATA_REGS data[OMS_NUM_CHANNELS]; /* 0x0400 */
epicsInt16 outPutIndex; /* 0x0800 */
epicsInt16 inGetIndex; /* 0x0802 */
epicsInt16 outBuffer[BUFFER_SIZE]; /* 0x0804 */
epicsInt16 rebootind; /* 0x0A04 - used by driver to
* test for board reboot. */
epicsInt16 reserved1[749]; /* 0x0A06 */
MOTOR_CNTRL_REGS control; /* 0x0FE0 */
};
#endif /* INCdrvOms58h */
-70
View File
@@ -1,70 +0,0 @@
/*
FILENAME... drvOmsCom.h
USAGE... This file contains OMS driver "include" information
that is common to all OMS models.
*/
/*
* Original Author: Ron Sluiter
* Date: 12/18/98
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
*/
#ifndef INCdrvOmsComh
#define INCdrvOmsComh 1
#include "motordrvCom.h"
#ifdef __LP64__
typedef long long motorUInt64;
#endif
/* Default profile. */
#define OMS_INTERRUPT_TYPE intVME
#define OMS_ADDRS_TYPE atVMEA16
#define OMS_INT_VECTOR 180 /* default interrupt vector (64-255) */
#define OMS_INT_LEVEL 5 /* default interrupt level (1-6) */
/* OMS Command strings. */
#define AXIS_STOP "ST"
#define GET_IDENT "WY"
#define ERROR_CLEAR "IC"
#define STOP_ALL "AA SA"
#define ALL_POS "AA RP"
struct encoder_status
{
char slip_enable;
char pos_enable;
char slip_detect;
char pos_dead;
char axis_home;
char unused;
};
#endif /* INCdrvOmsComh */
-960
View File
@@ -1,960 +0,0 @@
/*
FILENAME... drvOmsPC68.cc
USAGE... Motor record driver level support for OMS PC68 serial device.
*/
/*
* Original Author: Brian Tieman
* Current Author: Ron Sluiter
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
*
* NOTES
* -----
* Verified with firmware:
* - PC78 ver 1.14-46
* - PC68 ver 6.51-2008
* - The data parameter passed to asynCallback() is represented as follows:
*
* +-------------------------------------+
* | Interrupt counter | Status | Done |
* +-------------------------------------+
*
* Where:
* - Interrupt counter - 16bits - Number of interrupts
* - Status register - 8bits - Status information
* - Done register - 8bits - Axis done status
*
* More information can be found in the User Manual, ICMS document APS_1251701.
*
*
* Modification Log:
* -----------------
* .01 02/07/06 dmk - modified motor_init() to skip the encoder query if the
* controller has been configured for no encoder.
* .02 04/24/06 rls - support for both PC68 and PC78.
* - test for encoder support.
* - test for servo support.
* .03 08/11/06 rls - work around for erroneous response after response to
* "?KP" command at boot-up; resulted in 1st axis having
* same position (RP command) as last axis.
* .04 02/09/07 dmk - modified to support interrupts.
* .05 02/15/08 dmk - removed unnecessary variants in asynCallback() and
* added notes.
*/
#include <string.h>
#include <math.h>
#include <stdio.h>
#include <epicsThread.h>
#include <epicsString.h>
#include <dbAccess.h>
#include <drvSup.h>
#include <iocsh.h>
#include <errlog.h>
#include <stdlib.h>
#include "motor.h"
#include "drvOmsPC68Com.h"
#include "epicsExport.h"
#define PC68_MAX_NUM_CARDS (10) /* Maximum # of cards. */
#define BUFF_SIZE (100) /* Maximum length of command string */
#define TIMEOUT (2.0) /* Command timeout in sec. */
/*----------------debugging-----------------*/
volatile int drvOmsPC68debug = 0;
extern "C" {epicsExportAddress(int, drvOmsPC68debug);}
static inline void Debug(int level, const char *format, ...) {
#ifdef DEBUG
if (level < drvOmsPC68debug) {
va_list pVar;
va_start(pVar, format);
vprintf(format, pVar);
va_end(pVar);
}
#endif
}
/* --- Global data. --- */
int OmsPC68_num_cards = 0;
/* Local data required for every driver; see "motordrvComCode.h" */
#include "motordrvComCode.h"
static volatile int motionTO = 10;
//OmsPC68 generic controller commands
static char *oms_axis[] = {"X", "Y", "Z", "T", "U", "V", "R", "S"};
/*----------------functions-----------------*/
static int recv_mess(int, char *, int);
static RTN_STATUS send_mess(int, char const *, char *name);
static void start_status(int card);
static int set_status(int card, int signal);
static long report(int level);
static long init();
static int motor_init();
static void query_done(int, int, struct mess_node *);
/*----------------functions-----------------*/
static int omsGet(int card, char *pcom);
struct driver_table OmsPC68_access =
{
motor_init,
motor_send,
motor_free,
motor_card_info,
motor_axis_info,
&mess_queue,
&queue_lock,
&free_list,
&freelist_lock,
&motor_sem,
&motor_state,
&total_cards,
&any_motor_in_motion,
send_mess,
recv_mess,
set_status,
query_done,
start_status,
&initialized,
oms_axis
};
struct
{
long number;
long (*report) (int);
long (*init) (void);
} drvOmsPC68 = {2, report, init};
extern "C" {epicsExportAddress(drvet, drvOmsPC68);}
static struct thread_args targs = {SCAN_RATE, &OmsPC68_access, 0.0};
//_____________________________________________________________________________
/*********************************************************
* Print out driver status report
*********************************************************/
static long report(int level)
{
int card;
if (OmsPC68_num_cards <= 0)
printf(" No MDrive controllers configured.\n");
else
{
for (card = 0; card < OmsPC68_num_cards; card++)
{
struct controller *brdptr = motor_state[card];
if (brdptr == NULL)
printf(" PC68 controller %d connection failed.\n", card);
else
{
struct OmsPC68controller *cntrl;
cntrl = (struct OmsPC68controller *) brdptr->DevicePrivate;
printf(" PC68 controller #%d, port=%s, id: %s - err %d\n", card,
cntrl->asyn_port, brdptr->ident,cntrl->errcnt);
}
}
}
return(OK);
}
//_____________________________________________________________________________
static long init()
{
/* Check for setup */
if (OmsPC68_num_cards <= 0)
{
Debug(1, "init(): OmsPC68 driver disabled.\n");
Debug(1, "init(): OmsPC68Setup() missing from startup script.\n");
}
motor_init ();
initialized = true;
return(0);
}
//_____________________________________________________________________________
static void query_done(int card, int axis, struct mess_node *nodeptr)
{
}
/*********************************************************
* Read the status and position of all motors on a card
* start_status(int card)
* if card == -1 then start all cards
*********************************************************/
static void start_status(int card)
{
}
//_____________________________________________________________________________
/**************************************************************
* Parse status and position strings for a card and signal
* set_status()
************************************************************/
static int set_status(int card, int signal)
{
struct OmsPC68controller *cntrl;
struct mess_info *motor_info;
struct mess_node *nodeptr;
char *p, *tok_save;
struct axis_status *ax_stat;
struct encoder_status *en_stat;
char q_buf[50], outbuf[50];
int index, motorData, rtn_state;
bool ls_active = false;
msta_field status;
cntrl = (struct OmsPC68controller *) motor_state[card]->DevicePrivate;
motor_info = &(motor_state[card]->motor_info[signal]);
nodeptr = motor_info->motor_motion;
status.All = motor_info->status.All;
if (cntrl->status != NORMAL)
recv_mess(card, q_buf, FLUSH);
if (motor_state[card]->motor_info[signal].encoder_present == YES)
{
/* get 4 peices of info from axis */
send_mess(card, ALL_INFO, oms_axis[signal]);
rtn_state = recv_mess(card, q_buf, 4);
}
else
{
send_mess(card, AXIS_INFO, oms_axis[signal]);
rtn_state = recv_mess(card, q_buf, 2);
}
if (rtn_state > 0)
{
cntrl->status = NORMAL;
status.Bits.CNTRL_COMM_ERR = 0;
}
else
{
if (cntrl->status == NORMAL)
{
cntrl->status = RETRY;
rtn_state = OK;
goto exit;
}
else
{
cntrl->status = COMM_ERR;
status.Bits.CNTRL_COMM_ERR = 1;
status.Bits.RA_PROBLEM = 1;
rtn_state = 1;
goto exit;
}
}
Debug(5, "info = (%s)\n", q_buf);
for (index = 0, p = epicsStrtok_r(q_buf, ",", &tok_save); p;
p = epicsStrtok_r(NULL, ",", &tok_save), index++)
{
switch (index)
{
case 0:
/* axis status */
ax_stat = (struct axis_status *) p;
status.Bits.RA_DIRECTION = (ax_stat->direction == 'P') ? 1 : 0;
status.Bits.RA_DONE = (ax_stat->done == 'D') ? 1 : 0;
status.Bits.RA_HOME = (ax_stat->home == 'H') ? 1 : 0;
if (ax_stat->overtravel == 'L')
{
ls_active = true;
if (status.Bits.RA_DIRECTION)
status.Bits.RA_PLUS_LS = 1;
else
status.Bits.RA_MINUS_LS = 1;
}
else
{
ls_active = false;
status.Bits.RA_PLUS_LS = 0;
status.Bits.RA_MINUS_LS = 0;
}
break;
case 1:
/* motor pulse count (position) */
sscanf(p, "%index", &motorData);
if (motorData == motor_info->position)
{
/* Increment counter only if motor is moving. */
if (nodeptr != 0)
motor_info->no_motion_count++;
}
else
{
motor_info->no_motion_count = 0;
motor_info->position = motorData;
}
if (motor_info->no_motion_count > motionTO)
{
status.Bits.RA_PROBLEM = 1;
send_mess(card, AXIS_STOP, oms_axis[signal]);
motor_info->no_motion_count = 0;
errlogSevPrintf(errlogMinor,
"Motor motion timeout ERROR on card: %d, signal: %d\n", card,
signal);
}
else
status.Bits.RA_PROBLEM = 0;
break;
case 2:
{
/* encoder pulse count (position) */
int temp;
sscanf(p, "%index", &temp);
motor_info->encoder_position = (epicsInt32) temp;
}
break;
case 3:
/* encoder status */
en_stat = (struct encoder_status *) p;
status.Bits.EA_SLIP = (en_stat->slip_enable == 'E') ? 1 : 0;
status.Bits.EA_POSITION = (en_stat->pos_enable == 'E') ? 1 : 0;
status.Bits.EA_SLIP_STALL = (en_stat->slip_detect == 'S') ? 1 : 0;
status.Bits.EA_HOME = (en_stat->axis_home == 'H') ? 1 : 0;
break;
default:
break;
}
}
/*
* jps: Velocity should be set based on the actual velocity returned from
* the 'RV' command (See drvOms58.c). But the polling task does not have
* time to request additional information so the velocity is set to
* indicate moving or not-moving.
*/
if (status.Bits.RA_DONE)
motor_info->velocity = 0;
else
motor_info->velocity = 1;
if (!(status.Bits.RA_DIRECTION))
motor_info->velocity *= -1;
rtn_state = (!motor_info->no_motion_count || ls_active == true ||
status.Bits.RA_DONE | status.Bits.RA_PROBLEM) ? 1 : 0;
/* Test for post-move string. */
if ((status.Bits.RA_DONE || ls_active == true) && (nodeptr != 0) &&
(nodeptr->postmsgptr != 0))
{
char buffer[40];
/* Test for a "device directive" in the POST string. */
if (nodeptr->postmsgptr[0] == '@')
{
bool errind = false;
char *end = strchr(&nodeptr->postmsgptr[1], '@');
if (end == NULL)
errind = true;
else
{
DBADDR addr;
char *start, *tail;
int size = (end - &nodeptr->postmsgptr[0]) + 1;
/* Copy device directive to buffer. */
strncpy(buffer, nodeptr->postmsgptr, size);
buffer[size] = '\0';
if (strncmp(buffer, "@PUT(", 5) != 0)
goto errorexit;
/* Point "start" to PV name argument. */
tail = NULL;
start = epicsStrtok_r(&buffer[5], ",", &tail);
if (tail == NULL)
goto errorexit;
if (dbNameToAddr(start, &addr)) /* Get address of PV. */
{
errPrintf(-1, __FILE__, __LINE__, "Invalid PV name: %s",
start);
goto errorexit;
}
/* Point "start" to PV value argument. */
start = epicsStrtok_r(NULL, ")", &tail);
if (dbPutField(&addr, DBR_STRING, start, 1L))
{
errPrintf(-1, __FILE__, __LINE__, "invalid value: %s",
start);
goto errorexit;
}
}
if (errind == true)
errorexit: errMessage(-1, "Invalid device directive");
end++;
strcpy(buffer, end);
}
else
strcpy(buffer, nodeptr->postmsgptr);
strcpy(outbuf, buffer);
send_mess(card, outbuf, oms_axis[signal]);
nodeptr->postmsgptr = NULL;
}
exit:
motor_info->status.All = status.All; /* Update status from local copy. */
return(rtn_state);
}
//_____________________________________________________________________________
/*****************************************************/
/* send a message to the OmsPC68 board */
/* send_mess() */
/*****************************************************/
static RTN_STATUS send_mess(int card, char const *com, char *name)
{
struct OmsPC68controller *cntrl;
size_t size,
nwrite;
int error_code;
char outbuf[MAX_MSG_SIZE];
if (!motor_state[card])
{
errlogPrintf("drvOmsPC68.c:send_mess() - invalid card #%d\n", card);
return(ERROR);
}
if (name == NULL)
strcpy(outbuf, com);
else
{
strcpy(outbuf, "A");
strcat(outbuf, name);
strcat(outbuf, " ");
strcat(outbuf, com);
}
size = strlen (outbuf);
if (size > MAX_MSG_SIZE)
{
errlogMessage("drvOmsPC68.c:send_mess(); message size violation.\n");
return(ERROR);
}
else
if (size == 0) /* Normal exit on empty input message. */
return(OK);
Debug(2, "send_mess(): message = %s\n", com);
cntrl = (struct OmsPC68controller *) motor_state[card]->DevicePrivate;
error_code = cntrl->pasynOctet->write(cntrl->octetPvt,cntrl->pasynUser,outbuf,size,&nwrite);
if (error_code == OK)
{
Debug(4, "sent message: (%s)\n", outbuf);
}
else
{
Debug(4, "unable to send message (%s)\n", outbuf);
}
return(OK);
}
/*
* FUNCTION... recv_mess(int card, char *com, int amount)
*
* INPUT ARGUMENTS...
* card - controller card # (0,1,...).
* *com - caller's response buffer.
* amount | -1 = flush controller's output buffer.
* | >= 1 = the # of command responses to retrieve into caller's
* response buffer.
*
* LOGIC...
* IF controller card does not exist.
* ERROR RETURN.
* ENDIF
* IF "amount" indicates buffer flush.
* WHILE characters left in input buffer.
* Call omsGet().
* ENDWHILE
* ENDIF
*
* FOR each message requested (i.e. "amount").
* Initialize head and tail pointers.
* Initialize retry counter and state indicator.
* WHILE retry count not exhausted, AND, state indicator is NOT at END.
* IF characters left in controller's input buffer.
* Process input character.
* ELSE IF command error occured - call omsError().
* ERROR RETURN.
* ENDIF
* ENDWHILE
* IF retry count exhausted.
* Terminate receive buffer.
* ERROR RETURN.
* ENDIF
* Terminate command response.
* ENDFOR
*
* IF commands processed.
* Terminate response buffer.
* ELSE
* Clear response buffer.
* ENDIF
* NORMAL RETURN.
*/
static int recv_mess(int card, char *com, int amount)
{
struct OmsPC68controller *cntrl;
int itera, trys, piece, head_size, tail_size;
char inchar;
inchar = '\0';
/* Check that card exists */
if (card >= total_cards)
{
Debug(1, "recv_mess - invalid card #%d\n", card);
return(-1);
}
if (amount == -1)
{
/* Process request to flush receive queue */
Debug(7, "recv flush -------------");
cntrl = (struct OmsPC68controller *) motor_state[card]->DevicePrivate;
cntrl->pasynOctet->flush(cntrl->octetPvt,cntrl->pasynUser);
return(0);
}
for (itera = 0; amount > 0; amount--)
{
Debug(7, "-------------");
head_size = 0;
tail_size = 0;
for (piece = 0, trys = 0; piece < 3 && trys < 3; trys++)
{
if (omsGet(card, &inchar))
{
Debug(7, "%02x", inchar);
switch (piece)
{
case 0: /* header */
if (inchar == '\n' || inchar == '\r')
head_size++;
else if ((inchar == '#') || //command error
(inchar == '$') || //motor slip
(inchar == '@') || //over travel
(inchar == '!')) //done
{
if (inchar == '#')
{
Debug(4, "command error: card %d\n", card);
return(-1);
}
head_size++;
}
else
{
piece++;
com[itera++] = inchar;
}
break;
case 1: /* body */
if (inchar == '\n' || inchar == '\r')
{
piece++;
tail_size++;
}
else
com[itera++] = inchar;
break;
case 2: /* trailer */
tail_size++;
if (tail_size >= head_size)
piece++;
break;
}
trys = 0;
}
}
Debug(7, "-------------\n");
if (trys >= 3)
{
Debug(1, "Timeout occurred in recv_mess\n");
com[itera] = '\0';
return(0);
}
com[itera++] = ',';
}
if (itera > 0)
com[itera - 1] = '\0';
else
com[itera] = '\0';
Debug(4, "recv_mess: card %d, msg: (%s)\n", card, com);
return(itera);
}
/*****************************************************/
/* Get next character from OMS input buffer */
/* omsGet() */
/*****************************************************/
static int omsGet(int card, char *pchar)
{
int eomReason;
size_t nread;
asynStatus status;
struct OmsPC68controller *cntrl;
cntrl = (struct OmsPC68controller *) motor_state[card]->DevicePrivate;
status = cntrl->pasynOctet->read(cntrl->octetPvt,cntrl->pasynUser,pchar,1,&nread,&eomReason);
return(nread);
}
static void asynCallback(void *drvPvt,asynUser *pasynUser,char *data,size_t len, int eomReason)
{
int d,stat;
OmsPC68controller* pcntrl;
struct controller* pstate;
pcntrl = (OmsPC68controller*)drvPvt;
pstate = motor_state[pcntrl->card];
if( pcntrl->card >= total_cards || pstate == NULL )
{
errlogPrintf("Invalid entry-card #%d\n", pcntrl->card);
return;
}
d = *(int*)data;
stat = (d & 0x0000FF00) >> 8;
if( stat & STAT_DONE )
if( stat & STAT_ERROR_MSK )
++pcntrl->errcnt;
else
motor_sem.signal();
//printf("drvOmsPC68:asynCallback - card %2.2d, error %d, status 0x%8.8X\n",pcntrl->card,pcntrl->errcnt,d);
}
//_____________________________________________________________________________
/*****************************************************/
/* initialize all software and hardware */
/* This is called from the initialization routine in */
/* device support. */
/* motor_init() */
/*****************************************************/
static int motor_init()
{
volatile struct controller* pmotorState;
struct OmsPC68controller* cntrl;
int card_index, status, success_rtn, total_axis, motor_index;
char axis_pos[50], encoder_pos[50], *tok_save, *pos_ptr;
asynUser *pasynUser;
asynInterface *pasynInterface;
/* Check for setup */
if (OmsPC68_num_cards <= 0)
{
Debug(1, "motor_init: OmsPC68 driver disabled* \n");
Debug(1, "motor_init: OmsPC68Setup() is missing from startup script.\n");
return(ERROR);
}
total_cards = OmsPC68_num_cards;
for (card_index=0;card_index<OmsPC68_num_cards;card_index++)
{
if (!motor_state[card_index])
continue;
pmotorState = motor_state[card_index];
/* Initialize communications channel */
cntrl = (struct OmsPC68controller*)pmotorState->DevicePrivate;
pasynUser = pasynManager->createAsynUser(0,0);
pasynUser->userPvt = cntrl;
cntrl->pasynUser = pasynUser;
success_rtn = pasynManager->connectDevice(pasynUser,cntrl->asyn_port,0);
if( success_rtn )
{
Debug(1,"can't connect to port %s: %s\n",cntrl->asyn_port,pasynUser->errorMessage);
return(ERROR);
}
pasynInterface = pasynManager->findInterface(pasynUser,asynOctetType,1);
if( pasynInterface )
{
cntrl->pasynOctet = (asynOctet*)pasynInterface->pinterface;
cntrl->octetPvt = pasynInterface->drvPvt;
}
else
{
Debug(1,"%s driver not supported\n",asynOctetType);
return(ERROR);
}
success_rtn = cntrl->pasynOctet->registerInterruptUser(cntrl->octetPvt,pasynUser,asynCallback,cntrl,&cntrl->registrarPvt);
if( success_rtn )
{
Debug(1,"registerInterruptUser failed - %s: %s\n",cntrl->asyn_port,pasynUser->errorMessage);
return(ERROR);
}
if (success_rtn == asynSuccess)
{
int retry = 0;
/* Send a message to the board, see if it exists */
/* flush any junk at input port - should be no data available */
cntrl->pasynOctet->flush(cntrl->octetPvt,cntrl->pasynUser);
/* Try 3 times to connect to controller. */
do
{
send_mess (card_index, GET_IDENT, (char*) NULL);
status = recv_mess(card_index, (char *) pmotorState->ident, 1);
retry++;
} while (status == 0 && retry < 3);
Debug(3, "Identification = %s\n", pmotorState->ident);
}
if (success_rtn == asynSuccess && status > 0)
{
pmotorState->motor_in_motion = 0;
pmotorState->cmnd_response = false;
send_mess (card_index, ECHO_OFF, (char*) NULL);
send_mess (card_index, ERROR_CLEAR, (char*) NULL);
send_mess (card_index, STOP_ALL, (char*) NULL);
send_mess (card_index, ALL_POS, (char*) NULL);
recv_mess (card_index, axis_pos, 1);
for (total_axis = 0, pos_ptr = epicsStrtok_r(axis_pos, ",", &tok_save);
pos_ptr; pos_ptr = epicsStrtok_r(NULL, ",", &tok_save),
total_axis++)
{
pmotorState->motor_info[total_axis].motor_motion = NULL;
pmotorState->motor_info[total_axis].status.All = 0;
}
Debug(3, "Total axis = %d\n", total_axis);
pmotorState->total_axis = total_axis;
for (motor_index = 0; motor_index < total_axis; motor_index++)
{
send_mess(card_index, ENCODER_QUERY, oms_axis[motor_index]);
if (recv_mess(card_index, encoder_pos, 1) == -1)
pmotorState->motor_info[motor_index].encoder_present = NO;
else
pmotorState->motor_info[motor_index].encoder_present = YES;
/* Test if motor has PID parameters. */
send_mess(card_index, PID_QUERY, oms_axis[motor_index]);
if (recv_mess(card_index, encoder_pos, 1) == -1)
pmotorState->motor_info[motor_index].pid_present = NO;
else
pmotorState->motor_info[motor_index].pid_present = YES;
}
/* Testing for PID parameters (?KP) causes erroneous response from
* "report position" command at boot-up. Work around is the following
* dummy communication transaction.
*/
send_mess (card_index, ALL_POS, (char*) NULL);
recv_mess (card_index, axis_pos, 1);
for (motor_index=0;motor_index<total_axis;motor_index++)
{
pmotorState->motor_info[motor_index].status.All = 0;
pmotorState->motor_info[motor_index].no_motion_count = 0;
pmotorState->motor_info[motor_index].encoder_position = 0;
pmotorState->motor_info[motor_index].position = 0;
if (pmotorState->motor_info[motor_index].encoder_present == YES)
pmotorState->motor_info[motor_index].status.Bits.EA_PRESENT = 1;
if (pmotorState->motor_info[motor_index].pid_present == YES)
pmotorState->motor_info[motor_index].status.Bits.GAIN_SUPPORT = 1;
set_status (card_index, motor_index);
}
}
else
motor_state[card_index] = (struct controller *) NULL;
}
any_motor_in_motion = 0;
mess_queue.head = (struct mess_node *) NULL;
mess_queue.tail = (struct mess_node *) NULL;
free_list.head = (struct mess_node *) NULL;
free_list.tail = (struct mess_node *) NULL;
Debug(3, "Motors initialized\n");
epicsThreadCreate((char *) "OmsPC68_motor", epicsThreadPriorityMedium,
epicsThreadGetStackSize(epicsThreadStackMedium),
(EPICSTHREADFUNC) motor_task, (void *) &targs);
Debug(3, "Started motor_task\n");
return(0);
}
//_____________________________________________________________________________
/*****************************************************/
/* Setup system configuration */
/* OmsPC68Setup() */
/*****************************************************/
RTN_STATUS OmsPC68Setup (int num_cards, int scan_rate)
{
int itera;
if (num_cards < 1 || num_cards > PC68_MAX_NUM_CARDS)
OmsPC68_num_cards = PC68_MAX_NUM_CARDS;
else
OmsPC68_num_cards = num_cards;
/* Set motor polling task rate */
if (scan_rate >= 1 && scan_rate <= 60)
targs.motor_scan_rate = scan_rate;
else
targs.motor_scan_rate = SCAN_RATE;
/*
* Allocate space for motor_state structures. Note this must be done
* before OmsPC68Config is called, so it cannot be done in motor_init()
* This means that we must allocate space for a card without knowing
* if it really exists, which is not a serious problem
*/
motor_state = (struct controller **)
malloc(OmsPC68_num_cards * sizeof(struct controller *));
for (itera = 0; itera < OmsPC68_num_cards; itera++)
motor_state[itera] = (struct controller *) NULL;
return(OK);
}
//___________________________________________
/*******************************************/
/* Configure a controller */
/* OmsPC68Config() */
/* */
/* Recieves: */
/* card - card being configured */
/* name - asyn port name */
/*******************************************/
RTN_STATUS OmsPC68Config(int card, const char *name)
{
struct OmsPC68controller *cntrl;
if (card < 0 || card >= OmsPC68_num_cards)
return(ERROR);
motor_state[card] = (struct controller*)calloc(1,sizeof(struct controller));
motor_state[card]->DevicePrivate = calloc(1,sizeof(struct OmsPC68controller));
cntrl = (struct OmsPC68controller*) motor_state[card]->DevicePrivate;
cntrl->card = card;
strcpy(cntrl->asyn_port,name);
return(OK);
}
extern "C"
{
// Setup arguments
static const iocshArg setupArg0 = {"Maximum # of cards", iocshArgInt};
static const iocshArg setupArg1 = {"Polling rate (HZ)", iocshArgInt};
// Config arguments
static const iocshArg configArg0 = {"Card# being configured", iocshArgInt};
static const iocshArg configArg1 = {"asyn port name", iocshArgString};
static const iocshArg *const SetupArgs[2] = {&setupArg0, &setupArg1};
static const iocshArg *const ConfigArgs[2] = {&configArg0, &configArg1};
static const iocshFuncDef setupOmsPC68 = {"OmsPC68Setup", 2, SetupArgs};
static const iocshFuncDef configOmsPC68 = {"OmsPC68Config", 2, ConfigArgs};
static void setupOmsPC68CallFunc(const iocshArgBuf *args)
{
OmsPC68Setup(args[0].ival, args[1].ival);
}
static void configOmsPC68CallFunc (const iocshArgBuf *args)
{
OmsPC68Config(args[0].ival, args[1].sval);
}
static void OmsPC68Register(void)
{
iocshRegister(&setupOmsPC68, setupOmsPC68CallFunc);
iocshRegister(&configOmsPC68, configOmsPC68CallFunc);
}
epicsExportRegistrar(OmsPC68Register);
} // extern "C"
//_____________________________________________________________________________
-107
View File
@@ -1,107 +0,0 @@
/*
FILENAME... drvOmsPC68Com.h
USAGE... This file contains information common to all OMS PC68/78 controllers.
*/
/*
* Original Author: Brian Tieman
* Current Author: Ron Sluiter
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
*/
#ifndef INCdrvOmsPC68Comh
#define INCdrvOmsPC68Comh 1
#include "motor.h"
#include "motordrvCom.h"
#include "asynDriver.h"
#include "asynOctet.h"
/* status register */
#define STAT_IRQ 0x80
#define STAT_TRANS_BUF_EMPTY 0x40
#define STAT_INPUT_BUF_FULL 0x20
#define STAT_DONE 0x10
#define STAT_OVERTRAVEL 0x08
#define STAT_ENCODER_REQ 0x04
#define STAT_UNUSED 0x02
#define STAT_ERROR 0x01
#define STAT_ERROR_MSK 0x0F
/* done flag register */
#define DONE_X 0x01
#define DONE_Y 0x02
#define DONE_Z 0x04
#define DONE_T 0x08
#define DONE_U 0x10
#define DONE_V 0x20
#define DONE_R 0x40
#define DONE_S 0x80
/* OmsPC68 specific data is stored in this structure. */
struct OmsPC68controller
{
int card;
int errcnt;
char asyn_port[80]; /* asyn port name */
CommStatus status; /* Controller communication status. */
asynUser* pasynUser;
asynOctet* pasynOctet;
void* octetPvt;
void* registrarPvt;
};
struct encoder_status
{
char slip_enable;
char pos_enable;
char slip_detect;
char pos_dead;
char axis_home;
char unused;
};
#define ECHO_OFF "EF"
#define AXIS_STOP "ST"
#define GET_IDENT "WY"
#define ERROR_CLEAR "IC"
#define STOP_ALL "AA SA"
#define ALL_POS "AA RP"
#define ALL_INFO "QA RP RE EA"
#define AXIS_INFO "QA RP"
#define ENCODER_QUERY "EA"
#define DONE_QUERY "RA"
#define PID_QUERY "?KP"
/* Function prototypes. */
extern RTN_STATUS OmsPC68Setup(int, int);
extern RTN_STATUS OmsPC68Config(int, const char *);
#endif /* INCdrvOmsPC68Comh */
-1
View File
@@ -35,7 +35,6 @@ NoAsynVx_SRCS += NoAsynVx_registerRecordDeviceDriver.cpp
#!COMMONLIBS += MXmotor
COMMONLIBS += softMotor
ifeq ($(OS_CLASS), vxWorks)
COMMONLIBS += oms
COMMONLIBS += DeltaTau
endif
COMMONLIBS += motor
-12
View File
@@ -1,15 +1,3 @@
# Oregon Micro Systems VME8/44 driver support.
device(motor,VME_IO,devOMS,"OMS VME8/44")
driver(drvOms)
# Oregon Micro Systems VME58 driver support.
device(motor,VME_IO,devOms58,"OMS VME58")
driver(drvOms58)
# Oregon Micro Systems MAXv driver support.
device(motor,VME_IO,devMAXv,"OMS MAXv")
driver(drvMAXv)
registrar(motorUtilRegister)
variable(motorRecordDebug)
#variable(motordrvComdebug)
-2
View File
@@ -21,7 +21,6 @@ ifdef SNCSEQ
COMMONDBDS += devAerotechSeq.dbd
endif
COMMONDBDS += devPIMotor.dbd
COMMONDBDS += devOms.dbd
COMMONDBDS += devSoftMotor.dbd
COMMONDBDS += motorSimSupport.dbd
COMMONDBDS += devSmartMotorMotor.dbd
@@ -69,7 +68,6 @@ WithAsyn_OBJS_vxWorks += $(EPICS_BASE_BIN)/vxComLibrary
COMMONLIBS += Aerotech
COMMONLIBS += Attocube
COMMONLIBS += oms
COMMONLIBS += Mclennan
COMMONLIBS += Micos
COMMONLIBS += MicroMo