compare1.c -- Compare an encoder counter and set an XCVR output when the condition is TRUE.
/* compare1.c */
/* Copyright(c) 1991-2002 by Motion Engineering, Inc. All rights reserved.
*
* This software contains proprietary and confidential information of
* Motion Engineering Inc., and its suppliers. Except as may be set forth
* in the license agreement under which this software is supplied, use,
* disclosure, or reproduction is prohibited without the prior express
* written consent of Motion Engineering, Inc.
*/
#if defined(MEI_RCS)
static const char MEIAppRCS[] =
"$Header: /MainTree/XMPLib/XMP/app/compare1.c 7 7/23/01 2:36p Kevinh $"
#endif
/*
:Compare an encoder counter and set an XCVR output when the condition is TRUE.
Each motion block supports 10 compare registers. The default configuration
is two compare registers per motor -- while the last two (8,9) on each motion
block are reserved for the Auxiliary Encoder (not supported). The compare
registers are default mapped as follows.... 0 & 1 for Motor0, 2 & 3 for Motor1,
10 & 11 for Motor4, etc. The first Compare for each motor uses the default
(primary) encoder input for position compare, the second uses the AUX encoder
input. The equation used below calculates the Compare number for the primary
motor feedback given the default compare mapping.
compareNumber = ((motorNumber / MEIXmpMotorsPerBlock) * MEIXmpMaxComparePositions) +
((motorNumber % MEIXmpMotorsPerBlock) * ComparesPerMotor);
A compare register is loaded with a position compare value, a compare operator
(MPICommandOperatorGREATER or MPICommandOperatorLESS_OR_EQUAL), and an output
state (sets the Motor's XCVR_C TRUE or FALSE when the compare state is true).
A compare's status can be polled, it does not generate an event. If the
compare register's state equals MPICompareStateCOMPARED, the compare
position is stored and the compare register is ready for re-arming.
Warning! This is a sample program to assist in the integration of the
XMP motion controller with your application. It may not contain all
of the logic and safety features that your application requires.
*/
#include <stdlib.h>
#include <stdio.h>
#include "stdmpi.h"
#include "stdmei.h"
#include "apputil.h"
#if defined(ARG_MAIN_RENAME)
#define main compare1Main
argMainRENAME(main, compare1)
#endif
#define MOTOR (4)
#define COMPARE_POS (15000)
#define ComparesPerMotor (2) /* Default Compare configuration */
/* XCVR Settings */
#define TRANSCEIVER_CONFIG (MEIMotorTransceiverConfigCOMPARE) /* XCVR will output Compare logic */
#define TRANSCEIVER_ID (MEIMotorTransceiverIdC) /* Must be XCVR_C for Compare */
#define TRANSCEIVER_MASK (MEIMotorTransceiverMaskC) /* same as above */
int
main(int argc,
char *argv[])
{
MPIControl control; /* motion controller object */
MPIAxis axis; /* axis object */
MPIMotor motor; /* motor object */
MEIMotorConfig motorConfigXmp; /* contains transceiver configuration */
MPIMotorIo io;
MPICompare compare; /* compare object */
MPICompareParams compareParams; /* compare parameters */
MPICompareStatus compareStatus; /* compare status */
MPIControlType controlType;
MPIControlAddress controlAddress;
long returnValue; /* return value from library */
long argIndex;
long motorNumber;
long compareNumber;
double origin;
double actualPosition;
/* Parse command line for Control type and address */
argIndex =
argControl(argc,
argv,
&controlType,
&controlAddress);
motorNumber =
(argIndex >= argc)
? MOTOR
: meiPlatformAtol(argv[argIndex++]);
if (argIndex < argc) {
meiPlatformConsole("usage: %s %s\n"
"\t\t[motor# (0)]\n",
argv[0],
ArgUSAGE);
exit(0);
}
/* Calculate default compare number for axisNumber */
compareNumber = ((motorNumber/MEIXmpMotorsPerBlock) * MEIXmpMaxComparePositions) +
((motorNumber % MEIXmpMotorsPerBlock) * ComparesPerMotor);
/* Create motion controller object */
control =
mpiControlCreate(controlType,
&controlAddress);
msgCHECK(mpiControlValidate(control));
/* Initialize motion controller */
returnValue =
mpiControlInit(control);
msgCHECK(returnValue);
/* Create axis object */
axis =
mpiAxisCreate(control,
motorNumber);
msgCHECK(mpiAxisValidate(axis));
/* Read the Axis' Origin */
returnValue =
mpiAxisOriginGet(axis,
&origin);
msgCHECK(returnValue);
/* Create motor object for axisNumber */
motor =
mpiMotorCreate(control,
motorNumber);
msgCHECK(mpiMotorValidate(motor));
/* Configure selected transceiver */
returnValue =
mpiMotorConfigGet(motor,
NULL,
&motorConfigXmp);
msgCHECK(returnValue);
motorConfigXmp.Transceiver[TRANSCEIVER_ID].Config = TRANSCEIVER_CONFIG;
returnValue =
mpiMotorConfigSet(motor,
NULL,
&motorConfigXmp);
msgCHECK(returnValue);
/* Create compare object for compareNumber */
compare =
mpiCompareCreate(control,
compareNumber);
msgCHECK(mpiCompareValidate(compare));
/* Disable compare */
returnValue =
mpiCompareArm(compare,
FALSE);
msgCHECK(returnValue);
/* Set compare parameters */
/* remember to use the Axis' Origin when calculating the Compare position */
compareParams.position = (long) (COMPARE_POS + origin);
/* Configures state of the XCVR output, when Compare is valid */
compareParams.outputState = TRUE;
/*
commandOperator must be MPICommandOperatorGREATER
or MPICommandOperatorLESS_OR_EQUAL -- anything else is INVALID
*/
compareParams.commandOperator = MPICommandOperatorGREATER;
/* Load params */
returnValue =
mpiCompareLoad(compare,
&compareParams,
NULL);
msgCHECK(returnValue);
/* Arm the compare */
returnValue =
mpiCompareArm(compare,
TRUE);
msgCHECK(returnValue);
/* State Machine - Poll compare status, update display, etc */
while (meiPlatformKey(MPIWaitPOLL) <= 0) {
returnValue =
mpiCompareStatus(compare,
&compareStatus,
NULL);
msgCHECK(returnValue);
/* Display XCVR, Compare state and Axis' actual position */
returnValue =
mpiMotorIoGet(motor,
&io);
msgCHECK(returnValue);
returnValue =
mpiAxisActualPositionGet(axis,
&actualPosition);
msgCHECK(returnValue);
printf("\rXCVR_C:0x%x State:0x%x ActualPosition:%.0lf",
io.input & TRANSCEIVER_MASK, /* XCVR bit, read as input -- input from FPGA */
compareStatus.state, /* value of Compare bit (1=ARMED, 2=COMPARED) */
actualPosition);
if (compareStatus.state == MPICompareStateCOMPARED) {
printf(" Compared Position:%.0lf\r",
(double) (compareStatus.position[compareNumber % MEIXmpMaxComparePositions] - origin));
/* Re-arm position compare */
returnValue =
mpiCompareArm(compare,
TRUE);
msgCHECK(returnValue);
}
else {
/* clear any previous positions from the display... */
printf(" ");
}
}
/* Disarm position compare */
returnValue =
mpiCompareArm(compare,
FALSE);
msgCHECK(returnValue);
/* Delete objects */
returnValue = mpiAxisDelete(axis);
msgCHECK(returnValue);
returnValue = mpiMotorDelete(motor);
msgCHECK(returnValue);
returnValue = mpiCompareDelete(compare);
msgCHECK(returnValue);
returnValue = mpiControlDelete(control);
msgCHECK(returnValue);
return ((int)returnValue);
}