New model 3 driver

This commit is contained in:
MarkRivers
2011-05-09 20:07:52 +00:00
parent 7a2e9e47e5
commit 0c7be70002
5 changed files with 1796 additions and 0 deletions
+72
View File
@@ -0,0 +1,72 @@
record(bo,"$(dev):$(area):$(locn):POWER") {
field(DTYP,"asynInt32")
field(OUT,"@asyn($(PORT) 0)HYTEC_POWER")
field(VAL, "1")
field(ZNAM, "On")
field(ONAM, "Off")
}
record(bo,"$(dev):$(area):$(locn):BRAKE") {
field(DTYP,"asynInt32")
field(OUT,"@asyn($(PORT) 0)HYTEC_BRAKE")
field(VAL, "1")
field(ZNAM, "Set")
field(ONAM, "Rls")
}
record(ai,"$(dev):$(area):$(locn):POSN") {
field(PINI, "YES")
field(DTYP,"asynInt32")
field(INP,"@asyn($(PORT) 0)MOTOR_POSITION")
field(SCAN, "1 second")
}
record(ai,"$(dev):$(area):$(locn):FIRMWARE_VERSION") {
field(PINI, "YES")
field(DTYP,"asynInt32")
field(INP,"@asyn($(PORT) 0)HYTEC_FWVERSION")
field(SCAN, "1 second")
}
record(ai,"$(dev):$(area):$(locn):EN_POSN") {
field(PINI, "YES")
field(DTYP,"asynInt32")
field(INP,"@asyn($(PORT) 0)MOTOR_ENCODER_POSITION")
field(SCAN, "1 second")
}
record(ai, "$(dev):$(area):$(locn):LOWLMT") {
field(SCAN, "I/O Intr")
field(DTYP, "asynInt32")
field(INP, "@asyn($(PORT) 0) MOTOR_STATUS_LOW_LIMIT")
}
record(ai, "$(dev):$(area):$(locn):HIGHLMT") {
field(SCAN, "I/O Intr")
field(DTYP, "asynInt32")
field(INP, "@asyn($(PORT) 0) MOTOR_STATUS_HIGH_LIMIT")
}
record(ai, "$(dev):$(area):$(locn):DONE") {
field(SCAN, "I/O Intr")
field(DTYP, "asynInt32")
field(INP, "@asyn($(PORT) 0) MOTOR_STATUS_DONE")
}
record(ai, "$(dev):$(area):$(locn):HOMELMT") {
field(SCAN, "I/O Intr")
field(DTYP, "asynInt32")
field(INP, "@asyn($(PORT) 0) MOTOR_STATUS_AT_HOME")
}
record(ai, "$(dev):$(area):$(locn):FAULT") {
field(SCAN, "I/O Intr")
field(DTYP, "asynInt32")
field(INP, "@asyn($(PORT) 0) MOTOR_STATUS_PROBLEM")
}
record(ai, "$(dev):$(area):$(locn):HASENCODER") {
field(SCAN, "I/O Intr")
field(DTYP, "asynInt32")
field(INP, "@asyn($(PORT) 0) MOTOR_STATUS_HAS_ENCODER")
}
File diff suppressed because it is too large Load Diff
+4
View File
@@ -0,0 +1,4 @@
# Database Definition
registrar(Hytec8601Register)
+222
View File
@@ -0,0 +1,222 @@
/********************************************************************************/
/* H H Y Y TTTTT EEEEE CCC HYTEC ELECTRONICS LTD */
/* H H Y Y T E C 5 Cradock Road, */
/* HHHHH Y T EEE C Reading, Berks. Tel: 0118 9757770 */
/* H H Y T E C RG2 0JT Fax: 0118 9757566 */
/* H H Y T EEEEE CCC Web: www.hytec-electronics.co.uk */
/********************************************************************************/
/********************************************************************************/
/* _____________________________________________________________________ */
/* | H Y T E C 8 6 0 1 S T E P M O T E R A s y n D r i v e r | */
/* --------------------------------------------------------------------- */
/* */
/* Source file name :- HytecMotorDriver.c */
/* */
/* Initial creation date :- 29-Mar-2011 */
/* */
/* Original Developers :- Jim Chen. Hytec Electronics Ltd */
/* */
/********************************************************************************/
/* */
/* Description :- This is the "model 3" asyn motor driver for Hytec 8601 */
/* Stepper Motor IP module. The code is based on original */
/* Hytec drvHy8601asyn.c driver and also Mark Rivers' */
/* ACRMotorDriver. */
/* */
/* */
/* (C)2011 Hytec Electronics Ltd. */
/* */
/********************************************************************************/
/* */
/* Revision history: (comment and initial revisions) */
/* */
/* vers. revised modified by date */
/* ----- ----------- ---------------- --------------- */
/* 2.0 Continued version Jim Chen 29/03/2011 */
/* The main contents of this driver are the same as the original */
/* Hytec drvHy8601asyn.c driver but in "model 3" form as defined */
/* by Mark Rivers. Hence it starts from version 2.0. */
/* 2.1 New interfaces Jim Chen 04/04/2011 */
/* This version follows the asyn motor model 3 latest interface */
/* changes that include: */
/* a).New asynMotorAxis base class */
/* b).Moves the axis specific functions from the motor controller */
/* class to individual axis class */
/* c).Changes asynMotorDriver.cpp to asynMotorController.cpp. */
/* 2.2 Bugs fix Jim Chen 14/04/2011 */
/* Fixed setPosition bug */
/* Added firmware version parameter */
/* */
/********************************************************************************/
#include "asynMotorController.h"
#include "asynMotorAxis.h"
static const char *driverName = "HytecMotorDriver";
/* CSR Register bit definitions */
#define CSR_HOMESTOP 0x8000
#define CSR_INTEN 0x4000
#define CSR_DONE 0x2000
#define CSR_CRASHSTOP 0x1000
#define CSR_DIRECTION 0x0800
#define CSR_AUX2 0x0400
#define CSR_AUX1 0x0200
#define CSR_ENCODUSE 0x0100
#define CSR_ENCODDET 0x0080
#define CSR_JOG 0x0040
#define CSR_GO 0x0020
#define CSR_DRVSTAT 0x0010
#define CSR_HOMELMT 0x0008
#define CSR_MAXLMT 0x0004
#define CSR_MINLMT 0x0002
#define CSR_RESET 0x0001
/* New Hardware Register Map */
#define REG_STEPCNTLO 0x00
#define REG_STEPCNTHI 0x02
#define REG_CURRPOSLO 0x04
#define REG_CURRPOSHI 0x06
#define REG_STARTSTOPSPD 0x08
#define REG_HIGHSPD 0x0A
#define REG_RAMPRATE 0x0C
#define REG_CSR 0x0E
#define REG_INTMASK 0x10
#define REG_INTVECTOR 0x12
#define REG_INTREQUEST 0x14
#define REG_CURRENTSPD 0x16
#define REG_SPARE1 0x18
#define REG_SPARE2 0x1A
#define REG_SPARE3 0x1C
#define REG_SPARE4 0x1E
#define PROM_MODEL 0x8601
#define PROM_OFFS 0x80
#define REG_BANK_OFFS 0x00
#define REG_BANK_SZ 0x20
#define INT_LMT (CSR_MINLMT | CSR_MAXLMT | CSR_HOMELMT)
#define INT_SRCS (CSR_RESET | INT_LMT | CSR_DRVSTAT | CSR_DONE)
/* define a mask to enable all sources of interrupts */
#define ALL_INTS (INT_SRCS | CSR_INTEN)
#define DONE_INT (CSR_DONE) /* the only interrupt suggested to use. JC 12-Nov-2009 */
#define HY8601_NUM_AXES 4
#define IP_DETECT_STR "VITA4 "
#define GET_REG(base,reg) (*(volatile epicsUInt16 *)((base)+(reg)))
#define SET_REG(base,reg,val) do { *(volatile epicsUInt16 *)((base)+(reg)) = (val);} while(0)
#define CSR_SET(base,bit) do { *(volatile epicsUInt16 *)((base)+REG_CSR) |= (bit);} while(0)
/* Please NOTE, The DONE bit is cleared by either ORing an "1" or ANDing an "1" (if it is already "1") to it.
* Yet neither ORing nor ANDing it with "0" would affect it. As such, clearing any other bit in the CSR with
* the AND operation need to be very careful so that it doesn't knock down the DONE bit. This is why in the
* following macro after inverting the bit in the CSR, we clear the DONE bit to the inversion result in order
* not to affect the DONE bit. */
#define CSR_CLR(base,bit) do { *(volatile epicsUInt16 *)((base)+REG_CSR) &= ((~(bit)) & 0xDFFF);} while(0)
#define HytecPowerControlString "HYTEC_POWER"
#define HytecBrakeControlString "HYTEC_BRAKE"
#define HytecFirmwareString "HYTEC_FWVERSION"
#define HytecMoveAllString "HYTEC_MOVEALL"
class HytecMotorAxis : public asynMotorAxis
{
public:
HytecMotorAxis(class HytecMotorController *pC, int axis, double ratio, int vector);
asynStatus move(double position, int relative, double min_velocity, double max_velocity, double acceleration);
asynStatus moveVelocity(double min_velocity, double max_velocity, double acceleration);
asynStatus home(double min_velocity, double max_velocity, double acceleration, int forwards);
asynStatus stop(double acceleration);
asynStatus poll(bool *moving);
asynStatus setPosition(double position);
int getVector();
volatile char * getChanbase();
//the following are called from non-member function so they are here
private:
asynStatus InitialiseAxis();
HytecMotorController *pC_;
volatile char *chanbase;
int vector;
int useencoder;
double encoderRatio; /**< (double) Number of encoder counts in one motor count (encoder counts/motor counts) */
double resolution; /**< (double) Number of motor units per engineering unit */
double softLowLimit; /**< (double) Low soft limit in motor units ???? Shouldn't these two in engineering unit? */
double softHighLimit; /**< (double) High soft limit in motor units ???? */
double absPosition;
double desiredMove;
int times; /* to remember the the done bit set the first time */
int absAskingPosition;
friend class HytecMotorController;
};
class HytecMotorController : asynMotorController
{
public:
HytecMotorController(const char *portName, int numAxes, double movingPollPeriod,
double idlePollPeriod, int cardnum, int ip_carrier, int ipslot,
int vector, int useencoder, double encoderRatio0, double encoderRatio1,
double encoderRatio2, double encoderRatio3);
// These are the methods that we override from asynMotorDriver
asynStatus readInt32(asynUser *pasynUser, epicsInt32 *value);
asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
asynStatus writeFloat64(asynUser *pasynUser, epicsFloat64 value);
void report(FILE *fp, int level);
HytecMotorAxis* getAxis(asynUser *pasynUser);
HytecMotorAxis* getAxis(int axisNo);
//the following are called from non-member function so they are here
void drvHy8601GetAxisStatus( HytecMotorAxis *pAxis, int csr_data );
int getNumAxes();
int getIPCarrier();
int getIPSlot();
epicsMessageQueueId getINTMsgQID();
void increaseMsgSent();
void increaseMsgFail();
protected:
// New function codes
int HytecPowerControl_;
#define FIRST_HYTEC_PARAM HytecPowerControl_
int HytecBrakeControl_;
int HytecFWVersion_;
int HytecMoveAll_;
#define LAST_HYTEC_PARAM HytecMoveAll_
#define NUM_HYTEC_PARAMS (&LAST_HYTEC_PARAM - &FIRST_HYTEC_PARAM + 1)
private:
asynStatus SetupCard();
int checkprom(char *pr,int expmodel);
int numAxes;
epicsMessageQueueId intMsgQId;
int messagesSent; // for report
int messagesFailed; // for report
int ip_carrier;
int ipslot;
asynUser *pasynUser;
int card;
int vector;
int useencoder;
volatile char *regbase;
epicsThreadId motorThread;
friend class HytecMotorAxis;
};
+415
View File
@@ -0,0 +1,415 @@
***********************************************************************************
Hytec 8601 Step Motor Controller Asyn Driver Notes
Author: Jim Chen, Hytec Electronics Ltd
jim.chen@hytec-electronics.co.uk
First Initial: 12/NOV/2010
Last updated: 05/MAY/2011
This driver is based on "model 3" motor asyn driver defined by Mark Rivers.
***********************************************************************************
Support modules
===============
1). asyn driver version asyn4-13-1 or later.
2). ipac module version ipac-2.11 plus one of the Hytec carrier card drivers such as
drvHy8002.c for VxWorks or RTEMS under VME64x with 8002/8003/8004 carriers,
drvHyLinuxCarrier.c for Linux with IOC9010/PCIe6335/uTCA7002 carriers,
drvHyRTEMSCarrier.c for RTEMS with IOC9010 blade.
3). devLib2 version 2.1 or later if using RTEMS on IOC9010 blade.
4). motor module version later than motorR6-5-1. Currently the 'model 3' version can be
downloaded from subversion https://subversion.xor.aps.anl.gov/synApps/motor/trunk.
This will be formally released some stage on the official EPICS website.
5). EPICS core R3.14.8.2 or later.
6). RTEMS R4.9.4 or later.
Hytec 8002/8003/8004 carrier card configuration
===============================================
This board is a 6U VME64x carrier card. It provides four single size IP slots and
is configurable for many parameters. It supports interrupt level from 0 to 7. Any
IP cards can be enabled/disabled interrupt. The clock can be set to either 8MHz or
32MHz. For IPAC Memory space if required, the base address can be defined automatically
by geographical addressing when VME64x crate is used. For other type of crates,
the base address can be set by configuring a series of jumpers on the board or by
passing parameter to the memory offset register in the ipacAddCarrier call.
The IPAC Carrier Driver for this board is found in the file drvHy8002.c which
implements two commands ipacAddHy8002 and Hy8002CarrierInfo. The ipacAddHy8002
command is used to add a Hytec 8002/8003 board to the system. The Hy8002CarrierInfo
reports hardware information for a specified board or all boards in the system if
the parameter passed down is 0xFFFF. These commands are registered by the registrar
routine Hy8002Registrar to add them to the iocsh and link the driver into a final
IOC executable, for which it must be listed in the IOC's .dbd file thus:
registrar(Hy8002Registrar)
1). Configuration Command and Parameter
--------------------------------------
- int ipacAddHYy8002(const char *cardParams);
The parameter string should comprise two (2) to six (6) parameters which are comma
separated. The first two are mandate and have to be separated only by one comma.
The others are key/value pairs and are optional. The format is defined as
s,i,IPMEM=d,IPCLCK=d,ROAK=d,MEMOFFS=d
where d is a decimal integer number.
s defines the VME slot number of the carrier card. Valid number is 2 ~ 21 if
1MB memory space is specified or 2~15 if 2MB memory space is specified
i defines the interrupt level. Valid number is 0 ~ 7.
IPMEM=d defines the maximum memory size of the IP module. The value d has to be 1, 2,
4 or 8 that represent 1MB, 2MB, 4MB or 8MB respectively. Default is 1.
IPCLCK=d defines the clock that its value has to be either 8 for 8MHz or 32 for
32Mhz. Default is 8.
ROAK=d if d =1, it defines carrier card to release the interrupt upon the
acknowledgment. If d=0, the interrupt is released by user interrupt
service routine. Default is 0.
MEMOFFS=d this is used to define the A32 memory space base address when geographic
addressing is not preferred. The value of MEMOFFS defines A16 ~ A31 of
the base address as shown below. It is derived from the VME slot number
of the carrier card plus the VME_A32_MSTR_LOCAL defined in the config.h
file of the BSP.
D15 D14 D13 D12 D11 D10 D09 D08 D07 D06 D05 D04 D03 D02 D01 D00
A31 A30 A29 A28 A27 A26 A25 A24 A23 A22 x x x x x x
X= don't care, normally 0. So the actual meaningful bit starts from A22.
The reason it starts from A22 is that the minimum VME carrier memory assignment is
4MB, i.e. each IP card has 1MB as defined by the IPMEM=1. As such, a carrier in
slot 1 would have base address 0x00400000 plus the VME_A32_MSTR_LOCAL define.
Of course slot 1 is occupied by processor. So for slot 2, the base address is 0x00800000
and for slot 3, the base address is 0x00C00000 and so forth.
If the VME_A32_MSTR_LOCAL is defined as 0x20000000, then for slot 3, the derived base
address is 0x00C00000 + 0x20000000 = 0x200C00000. Hence the MEMOFFS = 8204 (decimal, i.e. 0x200C).
For slot 5, the derived base address will be 0x01400000 + 0x20000000 = 0x21400000.
Hence the MEMOFFS = 8512 (decimal, i.e. 0x2140). And so forth.
- int Hy8002CarrierInfo(int carrier);
where 'carrier' is the registered carrier number in the system. If it is specified,
this function prints out the specified carrier hardware information. If carrier = 0xFFFF,
then all carriers' hardware information will be printed out.
2). Configuration Examples
-------------------------
ipacAddHy8002("3,2")
This indicates that the carrier is in slot 3 and the interrupt level is set to 2.
IP memory uses default 1MB. Clock uses default 8MHz. RORA as default. use geographical
addressing etc.
ipacAddHy8002("5,4,IPMEM=1,IPCLCK=8,ROAK=1,MEMOFFS=192 ")
Here the slot is 5, interrupt level is 4. IP memory size is 1MB, clock uses 8MHz.
Use ROAK but not using geographic addressing. The memory offset is 192 which means its
base address is 0x00C00000 assuming the VME_A32_MSTR_LOCAL is set to 0x00000000.
3). Interrupt Commands Supported
-------------------------------
The interrupt level can be set by the second parameter of the ipacAddHy8002 routine.
Individual IP module can be set to generate interrupt or not. The commands supported
for ipmIrqCmd are illustrated below.
cmd Value Returned
ipac_irqGetLevel Carrier interrupt level (0 ~ 7)
ipac_irqEnable 0 = OK
ipac_irqDisable 0 = OK
ipac_irqPoll >0 if the interrupt line is active, else 0
(other commands) S_IPAC_notImplemented
Hy8601 IP Asyn Driver Usage
============================
1). Configuration shell command
-------------------------------
The configuration ioc shell command takes the form below.
int Hytec8601Configure(char *portName,
epicsUInt16 numAxes,
epicsUInt16 cardnum,
epicsUInt16 movingPollPeriod,
epicsUInt16 idlePollPeriod,
epicsUInt16 ip_carrier,
epicsUInt16 ipslot,
epicsUInt16 vector,
epicsUInt16 useencoder,
epicsDouble encoderRatio0,
epicsDouble encoderRatio1,
epicsDouble encoderRatio2,
epicsDouble encoderRatio3)
Where:
(1) portName asyn port name
(2) numAxes number of axes
(3) cardnum Arbitrary card number to assign to this controller
(4) movingPollPeriod status polling time period when motor is moving in ms
(5) idlePollPeriod status polling time period when motor is stopped in ms
(6) ip_carrier which previously configured IP carrier in the IOC
(7) ipslot which IP Slot on carrier card (0=A etc.)
(8) vector which Interrupt Vector (0 - Find One ?)
(9) useencoder - bit0 for axis0, bit1 for axis1, bit2 for axis2 and bit3 for axis3.
Other bits not used. 1=use encoder, 0=don't use encoder !
(10) encoderRatio0 - axis0 hardware encoder ratio
(11) encoderRatio1 - axis1 hardware encoder ratio
(12) encoderRatio2 - axis2 hardware encoder ratio
(13) encoderRatio3 - axis3 hardware encoder ratio
Example:
Hytec8601Configure("Hy8601", 4, 0, 500, 1000, IPAC0, 0, 70, 15, 0.25, 0.25, 0.25, 0.25)
This configures the 8601 card with
port name: Hy8601
4 axes
card number = 0
poll status every 500ms when moving
poll status every 1000ms when stopped
carrier serial number = 0
ipslot = site A
interrupt vector = 70
all 4 axes use encoder
all 4 axes have quardrature encoder hence their ratios are 0.25
2). Database definition file
----------------------------
Database definition file is: HytecMotorDriver.dbd.
3). Databases
-------------
Two databases can be loaded:
dbLoadRecords("db/basic_asyn_motor.db")
dbLoadRecords("db/HytecMotorControl.db", "dev=IP8601,area=TEST,locn=LAB,PORT=Hy8601")
Where:
basic_asyn_motor.db is the motor record database. It initialises 4 axes.
HytecMotorControl.db is the special controls for Hy8601 motor controller. It contains few extra asyn records
including POWER, BRAKE controls, synchronous read of absolute position and enocder position and firmware
version etc as below.
record(bo,"$(dev):$(area):$(locn):POWER") {
field(DTYP,"asynInt32")
field(OUT,"@asyn($(PORT) 0)HYTEC_POWER")
field(VAL, "1")
field(ONAM, "On")
field(ZNAM, "Off")
}
record(bo,"$(dev):$(area):$(locn):BRAKE") {
field(DTYP,"asynInt32")
field(OUT,"@asyn($(PORT) 0)HYTEC_BRAKE")
field(VAL, "1")
field(ZNAM, "Set")
field(ONAM, "Rls")
}
record(ai,"$(dev):$(area):$(locn):POSN") {
field(PINI, "YES")
field(DTYP,"asynInt32")
field(INP,"@asyn($(PORT) 0)MOTOR_POSITION")
field(SCAN, "1 second")
}
record(ai,"$(dev):$(area):$(locn):EN_POSN") {
field(PINI, "YES")
field(DTYP,"asynInt32")
field(INP,"@asyn($(PORT) 0)MOTOR_ENCODER_POSITION")
field(SCAN, "1 second")
}
record(ai,"$(dev):$(area):$(locn):FIRMWARE_VERSION") {
field(PINI, "YES")
field(DTYP,"asynInt32")
field(INP,"@asyn($(PORT) 0)HYTEC_FWVERSION")
field(SCAN, "1 second")
}
There are other records in the HytecMotorControl.db which can return the positions synchronously etc.
Notes:
- The power control uses AUX1 of the 8601 CSR. As it indicates in the record above, command
caput $(dev):$(area):$(locn):POWER 1
means power "On" and it sets the AUX1 bit, i.e. AUX1 output high (1).
caput $(dev):$(area):$(locn):POWER 0
means power "Off" so it clears AUX1 bit, i.e. AUX1 output low (0). Command
- The brake control uses AUX2 of the 8601 CSR. As it indicates in the record above, command
caput $(dev):$(area):$(locn):BRAKE 1
means to release the brake. It clears AUX2 bit, i.e. AUX2 output low (0). Command
caput $(dev):$(area):$(locn):BRAKE 0
means set the brake. It sets the AUX2 bit, i.e. AUX2 output high (1).
- The firmware version record returns the IP card PCB board issue number and the firmware version
caget $(dev):$(area):$(locn):FIRMWARE_VERSION
will return something like '2210' for example, whereas the first 2 is the PCB issue number and
210 is the firmware version.
4). To build an example application
-----------------------------------
To build an example to test the 8601 asyn driver, use EPICS makeBaseApp.pl script to create
the example as usual. Then modify the following files to include the driver module(s).
- <TOP>/configure/RELEASE
Change the EPICS_BASE and SUPPORT to the proper directories.
Add ASYN, IPAC and MOTOR moudles:
ASYN=$(SUPPORT)/asyn/asyn4-14
IPAC=$(SUPPORT)/ipac/ipac-2.11
MOTOR=<the motor module dir>/motorR6-5-2
- <TOP>xxxApp/src/Makefile
In the Makefile of the example src, add following lines:
example_DBD += asyn.dbd
example_DBD += motorSupport.dbd
example_DBD += motorRecord.dbd
example_DBD += drvIpac.dbd
example_DBD += HytecMotorDriver.dbd
example_LIBS += HytecMotor
example_LIBS += motor
example_LIBS += Ipac
example_LIBS += asyn
- <TOP>/xxxApp/Db/Makefile
Copy HytecMotorControl.db to the Db directory and add the following lines in the Makefile of
the Db directory:
DB += basic_asyn_motor.db
DB += HytecMotorControl.db
- Build the application from <TOP>
- Modify st.cmd in iocBoot/iocexample as per next section and run the start up script from here.
5). Start up script example
---------------------------
The following example is for an IOC that uses RTEMS R4.9.4, MVME5500 processor board.
# Change directory to TOP of application
cd("../..")
iocBoot=pwd()
ld( "bin/RTEMS-mvme5500/MotionControl.obj")
#ld < bin/vxWorks-ppc604_long/MotionControl.munch #for VxWorks
## Set common environment variables
#< all/pre_st.cmd
epicsEnvSet("IOC_NAME", "MC02")
epicsEnvSet("LOCA_NAME", "B025")
epicsEnvSet("ENGINEER", "Condamoor, Shantha")
epicsEnvSet( "EPICS_CA_MAX_ARRAY_BYTES", "30000")
# Register all support components
dbLoadDatabase( "dbd/MotionControl.dbd")
MotionControl_registerRecordDeviceDriver( pdbbase)
bspExtVerbosity=0
###########################################################
# Configure Hytec 8002 carriers
# 8002 carrier VME slot: 3
# INT level: 5
# Memory per IP: 1MB
# Memory mapping offset: 8384
# ===================================================================
#The typical output on beatnik looks like this:
# Cexp@till35>BSP_VMEOutboundPortsShow()
# Tsi148 Outbound Ports:
# Port VME-Addr Size PCI-Adrs Mode:
# 0: 0x20000000 0x0e000000 0x90000000 A32, SUP, D32, SCT
# 1: 0x00000000 0x00ff0000 0x9f000000 A24, SUP, D32, SCT
# 2: 0x00000000 0x00010000 0x9fff0000 A16, SUP, D32, SCT
# 7: 0x00000000 0x01000000 0x9e000000 CSR, SUP, D32, SCT
# ===================================================================
# A32 space configured to start here: 0x20000000
# Tell the carrier not to use geographic addressing
IPAC0=ipacAddHy8002("3,5,IPMEM=1,MEMOFFS=8384")
#
# Hytec MDS-8 8601 driver setup parameters:
# int Hytec8601Configure(char *portName,
# epicsUInt16 numAxes,
# epicsUInt16 cardnum,
# epicsUInt16 movingPollPeriod,
# epicsUInt16 idlePollPeriod,
# epicsUInt16 ip_carrier,
# epicsUInt16 ipslot,
# epicsUInt16 vector,
# epicsUInt16 useencoder,
# epicsDouble encoderRatio0,
# epicsDouble encoderRatio1,
# epicsDouble encoderRatio2,
# epicsDouble encoderRatio3)
# (1) portName asyn port name
# (2) numAxes number of axes
# (3) cardnum Arbitrary card number to assign to this controller
# (4) movingPollPeriod status polling time period when motor is moving in ms
# (5) idlePollPeriod status polling time period when motor is stopped in ms
# (6) ip_carrier which previously configured IP carrier in the IOC
# (7) ipslot which IP Slot on carrier card (0=A etc.)
# (8) vector which Interrupt Vector (0 - Find One ?)
# (9) useencoder - bit0 for axis0, bit1 for axis1, bit2 for axis2 and bit3 for axis3.
# Other bits not used. 1=use encoder, 0=don't use encoder !
# (10) encoderRatio0 - axis0 hardware encoder ratio
# (11) encoderRatio1 - axis1 hardware encoder ratio
# (12) encoderRatio2 - axis2 hardware encoder ratio
# (13) encoderRatio3 - axis3 hardware encoder ratio
Hytec8601Configure("Hy8601", 4, 0, IPAC0, 0, 70, 0, 0.25, 0.25, 0.25, 0.25)
# ========================================================
# New Hytec Motor Databases
# =======================================================
dbLoadRecords("db/basic_asyn_motor.db")
dbLoadRecords("db/HytecMotorControl.db", "dev=IP8601,area=TEST,locn=LAB,PORT=Hy8601")
# ========================================================
iocInit()