.

     

MPI Application Template
template.c
 

seq4.c -- Perform a repeated multi-axis motion sequence, wait for I/O, & monitor location
/* seq4.c */

/* Copyright(c) 1991-2006 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.
 */

/*

:Perform a repeated multi-axis motion sequence, wait for I/O, & monitor location

This sample program creates a program sequencer that will generate a multi-axis
 motion beween two points.  The program sequencer waits for the motion to
 complete in between moves.  After commanding the two motions the program
 sequencer waits for a transceiver I/O bit to change state (defined by
 TRANSCEIVER_WAIT_ID and TRIGGER_STATE at the top of the program).  Then the
 sequence loops back to the beginning of the motion command sequence, and
 repeats the motion until the user presses a key.

In addition there is a second program sequencer that monitors the position of
 the X and Y axes.  If their positions fall within a rectangle, defined by the
 position array, then a transceiver bit is set (defined by TRANSCEIVER_SET_ID).
 This can be used to signal process or inspection equipment to begin their
 actions.

The program execution is handled entirely on the controller, with no host
 computer intervention.  The motion can be viewed by the Motion Console and
 Motion Scope utilities.

The XMP program sequencer controls the execution of a single command or a
 series of commands on the XMP controller.  The program sequencer provides the
 ability to execute programs directly on the XMP controller without host
 intervention.  Examples of individual commands that can be executed by the
 program sequencer are motion, looping, conditional branching, computation,
 reading and writing of memory, time delays, waiting for conditions, setting
 inputs/outputs, and generation of events.  This rich command set provides
 capability similar to, and beyond, that provided by Programmable Logic
 Controller (PLC) programs.

 Warning!  This is a sample program to assist in the integration of an
 MEI 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 <math.h>

#include "stdmpi.h"
#include "stdmei.h"

#include "apputil.h"

#if defined(ARG_MAIN_RENAME)
#define main    seq4Main

argMainRENAME(main, seq4)
#endif

#define MOTION_COUNT    (2)
#define AXIS_COUNT      (2)

/* Command line arguments and defaults */
long            axisNumber[AXIS_COUNT] = { 0, 1, };
long            motionNumber    = 0;
long            motorNumber     = 0;
long            sequenceNumber  = 0;
long            sequenceSize    = 128;
MPIMotionType   motionType      = MPIMotionTypeTRAPEZOIDAL;

Arg argList[] = {
    {   "-axis",        ArgTypeLONG,    &axisNumber[0],     },
    {   "-motion",      ArgTypeLONG,    &motionNumber,      },
    {   "-motor",       ArgTypeLONG,    &motorNumber,       },
    {   "-sequence",    ArgTypeLONG,    &sequenceNumber,    },
    {   "-size",        ArgTypeLONG,    &sequenceSize,      },
    {   "-type",        ArgTypeLONG,    &motionType,        },

    {   NULL,       ArgTypeINVALID, NULL,   }
};

double position[MOTION_COUNT][AXIS_COUNT] = {
    { 20000.0,  0.0,        },
    { 0.0,      20000.0,    },
};

MPITrajectory trajectory[MOTION_COUNT][AXIS_COUNT] = {
    {   /* velocity     accel       decel       jerkPercent */
        { 10000.0,      100000.0,   100000.0,   50.0,   },
        { 10000.0,      100000.0,   100000.0,   50.0,   },
    },
    {   /* velocity     accel       decel       jerkPercent */
        { 10000.0,      100000.0,   100000.0,   50.0,   },
        { 10000.0,      100000.0,   100000.0,   50.0,   },
    },
};

/* motion parameters */

MPIMotionSCurve sCurve[MOTION_COUNT] = {
    {   &trajectory[0][0],  &position[0][0],    },
    {   &trajectory[1][0],  &position[1][0],    },
};

MPIMotionTrapezoidal    trapezoidal[MOTION_COUNT] = {
    {   &trajectory[0][0],  &position[0][0],    },
    {   &trajectory[1][0],  &position[1][0],    },
};

MPIMotionVelocity   velocity[MOTION_COUNT] = {
    {   &trajectory[0][0],  },
    {   &trajectory[1][0],  },
};

typedef enum {
    ExternalEventSEQUENCE_DONE,
} ExternalEvent;

                        /* 4 => START + MOTION_DONE + I/O + EVENT */
                        /* 2 => EXTERNAL_EVENT + BRANCH */
MPICommand  CommandTable[(MOTION_COUNT * 4) + 2];
#define COMMAND_COUNT   (sizeof(CommandTable) / sizeof(MPICommand))


#define IO_CONFIG   (MPIMotorIoTypeOUTPUT) /* INPUT or OUTPUT  */


/* Toggle the transceiver associated with the motor.  In this case, toggle
   transceiver B
*/
#define TRANSCEIVER_SET_ID  (MPIMotorIoConfigIndex1)  /* Motor I/O Index */
/* Define the transceiver to wait for in between motion sequences */
#define TRANSCEIVER_WAIT_ID (MPIMotorIoConfigIndex0)  /* Motor I/O Index */

/* Define the trigger value for the transceiver,
   MPICommandOperatorBIT_SET or MPICommandOperatorBIT_CLEAR
*/
#define TRIGGER_STATE   (MPICommandOperatorBIT_SET)

MPISequence
    monitorPosition(MPIControl  control,
                    MPIMotor    motor,
                    MPIAxis     axisX,
                    MPIAxis     axisY,
                    double      *limitX,
                    double      *limitY);

int
    main(int    argc,
         char   *argv[])
{
    MPIControl  control;            /* motion controller handle */
    MPIMotion   motion;             /* motion handle */
    MPIAxis     axis[AXIS_COUNT];   /* axis handles */
    MPIMotor    motor;              /* motor handle */

    MPISequence sequence;           /* sequence handle */
    MPISequence sequenceMonitor;    /* sequence handle */
    MPINotify   notify;             /* notification handle */
    MPIEventMgr eventMgr;           /* event manager handle */

    MPIEventMask    eventMask;

    Service service;

    MPICommandType      type;           /* command type */
    MPICommandParams    commandParams;  /* command parameters */
   MPIControlConfig  controlConfig;

    double  limitX[AXIS_COUNT];
    double  limitY[AXIS_COUNT];
    double  limit;

    long    returnValue;    /* return value from library */

    long    commandIndex;   /* CommandTable[] index */
    long    index;

    MPIControlType      controlType;
    MPIControlAddress   controlAddress;

    long    argIndex;

    argIndex =
        argControl(argc,
                   argv,
                   &controlType,
                   &controlAddress);

    /* Parse command line for application-specific arguments */
    while (argIndex < argc) {
        long    argIndexNew;

        argIndexNew = argSet(argList, argIndex, argc, argv);

        if (argIndexNew <= argIndex) {
            argIndex = argIndexNew;
            break;
        }
        else {
            argIndex = argIndexNew;
        }
    }

    /* Check for unknown/invalid command line arguments */
    if ((argIndex < argc) ||
        (axisNumber[0]  > (MPIXmpMAX_Axes - AXIS_COUNT)) ||
        (motionNumber   >= MPIXmpMAX_MSs) ||
        (motorNumber    >= MPIXmpMAX_Motors) ||
        (sequenceNumber >= MPIXmpMAX_PSs) ||
        (motionType <  MPIMotionTypeFIRST) ||
        (motionType >= MPIMotionTypeLAST)) {
        mpiPlatformConsole("usage: %s %s\n"
                           "\t\t[-axis # (0 .. %d)]\n"
                           "\t\t[-motion # (0 .. %d)]\n"
                           "\t\t[-motor # (0 .. %d)]\n"
                           "\t\t[-sequence # (0 .. %d)]\n"
                           "\t\t[-size # (%d)]\n"
                           "\t\t[-type # (0 .. %d)]\n",
                            argv[0],
                            ArgUSAGE,
                            MPIXmpMAX_Axes - AXIS_COUNT,
                            MPIXmpMAX_MSs - 1,
                            MPIXmpMAX_Motors - 1,
                            MPIXmpMAX_PSs - 1,
                            sequenceSize,
                            MPIMotionTypeLAST - 1);
        exit(MPIMessageARG_INVALID);
    }

    switch (motionType) {
        case MPIMotionTypeS_CURVE:
        case MPIMotionTypeTRAPEZOIDAL:
        case MPIMotionTypeVELOCITY: {
            break;
        }
        default: {
            mpiPlatformConsole("%s: %d: motion type not available\n",
                                argv[0],
                                motionType);
            exit(MPIMessageUNSUPPORTED);
            break;
        }
    }

    axisNumber[1] = axisNumber[0] + 1;

    /* Create motion controller object */
    control =
        mpiControlCreate(controlType,
                         &controlAddress);
    msgCHECK(mpiControlValidate(control));

    /* Initialize motion controller */
    returnValue = mpiControlInit(control);
    msgCHECK(returnValue);

   /* Enable a sequence engine on the controller */
   returnValue =
      mpiControlConfigGet(control,
                     &controlConfig,
                     NULL);
   msgCHECK(returnValue);

   if (controlConfig.sequenceCount <= sequenceNumber) {
      controlConfig.sequenceCount = (sequenceNumber + 1);
   }

   returnValue =
      mpiControlConfigSet(control,
                     &controlConfig,
                     NULL);
   msgCHECK(returnValue);

    /* Create motion object for MS number */
    motion =
        mpiMotionCreate(control,
                        motionNumber,
                        MPIHandleVOID);
    msgCHECK(mpiMotionValidate(motion));

    /* Create axis object for X_AXIS number */
    axis[0] =
        mpiAxisCreate(control,
                      axisNumber[0]);
    msgCHECK(mpiAxisValidate(axis[0]));

    /* Create axis object for Y_AXIS number */
    axis[1] =
        mpiAxisCreate(control,
                      axisNumber[1]);
    msgCHECK(mpiAxisValidate(axis[1]));

    /* Create motion axis list */
    returnValue =
        mpiMotionAxisListSet(motion,
                             AXIS_COUNT,
                             axis);
    msgCHECK(returnValue);

    /* Request notification of all events from motion */
    mpiEventMaskCLEAR(eventMask);
    mpiEventMaskALL(eventMask);
    returnValue =
        mpiMotionEventNotifySet(motion,
                                eventMask,
                                NULL);
    msgCHECK(returnValue);

    /* Create motor objects */
    motor =
        mpiMotorCreate(control,
                       motorNumber);
    msgCHECK(mpiMotorValidate(motor));

    /* Create Sequence */
    sequence =
        mpiSequenceCreate(control,
                          sequenceNumber,
                          sequenceSize);
    msgCHECK(mpiSequenceValidate(sequence));

#if defined(_DEBUG)
    returnValue =
        mpiObjectTraceSet(sequence,
                          MPISequenceTraceLOAD);
    msgCHECK(returnValue);
#endif

    /* Request notification of all events from sequence */
    returnValue =
        mpiSequenceEventNotifySet(sequence,
                                  eventMask,
                                  NULL);
    msgCHECK(returnValue);

    /* CommandTable[commandIndex] */
    commandIndex = 0;

    /* Create motion Commands */
    for (index = 0; index < MOTION_COUNT; index++) {
        MPIMotionParams *motionParams;

        /* mpiMotionStart(motion, type, params); */
        type = MPICommandTypeMOVE;

        commandParams.motion.motionCommand  = MPICommandMotionSTART;
        commandParams.motion.motion         = motion;
        commandParams.motion.type           = motionType;

        motionParams = &commandParams.motion.params;

        switch (motionType) {
            case MPIMotionTypeS_CURVE: {
                motionParams->sCurve = sCurve[index];
                break;
            }
            case MPIMotionTypeTRAPEZOIDAL: {
                motionParams->trapezoidal = trapezoidal[index];
                break;
            }
            case MPIMotionTypeVELOCITY: {
                motionParams->velocity = velocity[index];
                break;
            }
            default: {
                mpiAssert(FALSE);
                break;
            }
        }

        /* Create Command */
        CommandTable[commandIndex] =
            mpiCommandCreate(type,
                             &commandParams,
                             (commandIndex == 0) ? "First" : NULL);
        msgCHECK(mpiCommandValidate(CommandTable[commandIndex]));

        commandIndex++;

        commandParams.waitEvent.handle  = motion;
        commandParams.waitEvent.oper    = MPICommandOperatorBIT_SET;
        mpiEventMaskCLEAR(commandParams.waitEvent.mask);
        mpiEventMaskSET(commandParams.waitEvent.mask, MPIEventTypeMOTION_DONE);

        /* Create Command */
        CommandTable[commandIndex] =
            mpiCommandCreate(MPICommandTypeWAIT_EVENT,
                             &commandParams,
                             NULL);
        msgCHECK(mpiCommandValidate(CommandTable[commandIndex]));

        commandIndex++;

        commandParams.branchEvent.label     = NULL;
        commandParams.branchEvent.handle    = motion;
        commandParams.branchEvent.oper      = MPICommandOperatorBIT_SET;
        mpiEventMaskCLEAR(commandParams.branchEvent.mask);
        mpiEventMaskMOTOR(commandParams.branchEvent.mask);

        /* Create Command */
        CommandTable[commandIndex] =
            mpiCommandCreate(MPICommandTypeBRANCH_EVENT,
                             &commandParams,
                             NULL);
        msgCHECK(mpiCommandValidate(CommandTable[commandIndex]));

        commandIndex++;

        /* while (mpiControlUserIoGet(control, &io), (io.input[0] & mask) == 0); */
        commandParams.waitIO.type           = MPIIoTypeMOTOR_GENERAL;
        commandParams.waitIO.source.motor   = motor;
        commandParams.waitIO.oper           = TRIGGER_STATE;
        commandParams.waitIO.mask           = 0x1 << TRANSCEIVER_WAIT_ID;   /* bit 0 */

        /* Create Command */
        CommandTable[commandIndex] =
            mpiCommandCreate(MPICommandTypeWAIT_IO,
                             &commandParams,
                             NULL);
        msgCHECK(mpiCommandValidate(CommandTable[commandIndex]));

        commandIndex++;
    }

    /* MPIEventTypeEXTERNAL */
    commandParams.event.value = ExternalEventSEQUENCE_DONE;

    /* Create Command */
    CommandTable[commandIndex] =
        mpiCommandCreate(MPICommandTypeEVENT,
                         &commandParams,
                         NULL);
    msgCHECK(mpiCommandValidate(CommandTable[commandIndex]));

    commandIndex++;

    /* Branch to the first command of the sequence */
    commandParams.branch.label      = "First";  /* First command */
    commandParams.branch.expr.oper  = MPICommandOperatorALWAYS;

    /* Create Command */
    CommandTable[commandIndex] =
        mpiCommandCreate(MPICommandTypeBRANCH,
                         &commandParams,
                         NULL);
    msgCHECK(mpiCommandValidate(CommandTable[commandIndex]));

    commandIndex++;

    /* Create sequence command list */
    returnValue =
        mpiSequenceCommandListSet(sequence,
                                  commandIndex,
                                  CommandTable);
    msgCHECK(returnValue);

    /* Create event notification object */
    notify =
        mpiNotifyCreate(eventMask,      /* Notify of all MPI events */
                        MPIHandleVOID); /* Notify from all sources */
    msgCHECK(mpiNotifyValidate(notify));

    /* Create event manager object */
    eventMgr = mpiEventMgrCreate(control);
    msgCHECK(mpiEventMgrValidate(eventMgr));

    /* Add notify to event manager's list */
    returnValue =
        mpiEventMgrNotifyAppend(eventMgr,
                                notify);
    msgCHECK(returnValue);

    /* Create service thread */
    service =
        serviceCreate(eventMgr,
                      -1,   /* default (max) priority */
                      -1);  /* -1 => enable interrupts */
    mpiAssert(service != NULL);

    limit =
        fabs(position[0][0] - position[1][0]) /
        (AXIS_COUNT + 2);

    if (position[0][0] < position[1][0]) {
        limitX[0] = position[0][0] + limit;
        limitX[1] = position[1][0] - limit;
    }
    else {
        limitX[0] = position[1][0] + limit;
        limitX[1] = position[0][0] - limit;
    }

    limit =
        fabs(position[0][1] - position[1][1]) /
        (AXIS_COUNT + 2);

    if (position[0][1] < position[1][1]) {
        limitY[0] = position[0][1] + limit;
        limitY[1] = position[1][1] - limit;
    }
    else {
        limitY[0] = position[1][1] + limit;
        limitY[1] = position[0][1] - limit;
    }

    sequenceMonitor =
        monitorPosition(control,
                        motor,
                        axis[0],
                        axis[1],
                        limitX,
                        limitY);
    msgCHECK(mpiSequenceValidate(sequenceMonitor));

    /* Start sequence */
    returnValue =
        mpiSequenceStart(sequence,
                         MPIHandleVOID);

    if (returnValue != MPIMessageOK) {
        fprintf(stderr, "%s: mpiSequenceStart() returns 0x%x: %s\n",
                        argv[0],
                        returnValue,
                        mpiMessage(returnValue, NULL));
        exit(2);
    }

    mpiPlatformConsole("Press any key to stop sequence\n");

    while (returnValue == MPIMessageOK) {
        MPIEventStatus  status;

        returnValue =
            mpiNotifyEventWait(notify,
                               &status,
                               MPIWaitFOREVER);

        if (returnValue == MPIMessageOK) {
            MPIEventStatusInfo  *info;

            info = (MPIEventStatusInfo *)status.info;

            switch (status.type) {
                case MPIEventTypeNONE: {    /* ignore */
                    mpiPlatformConsole("No event ...\n");
                    break;
                }
                case MPIEventTypeAMP_FAULT:
                case MPIEventTypeHOME:
                case MPIEventTypeLIMIT_ERROR:
                case MPIEventTypeLIMIT_HW_NEG:
                case MPIEventTypeLIMIT_HW_POS:
                case MPIEventTypeLIMIT_SW_NEG:
                case MPIEventTypeLIMIT_SW_POS: {    /* error */
                    long    number;

                    number = info->type.number;

                    mpiPlatformConsole("Event %d on motor #%d\n",
                                        status.type,
                                        number);

                    break;
                }
                case MPIEventTypeMOTION_DONE: {
                    mpiPlatformConsole("Motion done\n");
                    break;
                }
                case MPIEventTypeEXTERNAL: {
                    switch (info->type.value) {
                        case ExternalEventSEQUENCE_DONE: {
                            mpiPlatformConsole("Sequence done\n");
                            break;
                        }
                        default: {
                            mpiPlatformConsole("Unknown external event: %d\n",
                                                info->type.value);
                            break;
                        }
                    }

                    break;
                }
                default: {
                    break;
                }
            }
        }

        if (returnValue == MPIMessageOK) {
            if (mpiPlatformKey(MPIWaitPOLL) >= 0) {
                break;
            }
        }
    }

    mpiPlatformConsole("Exiting ... returnValue 0x%x: %s\n",
                        returnValue,
                        mpiMessage(returnValue, NULL));

    /* Stop sequence */
    returnValue = mpiSequenceStop(sequenceMonitor);
    msgCHECK(returnValue);

    returnValue = mpiSequenceStop(sequence);
    msgCHECK(returnValue);

    returnValue = mpiSequenceDelete(sequenceMonitor);
    msgCHECK(returnValue);

    returnValue = mpiSequenceDelete(sequence);
    msgCHECK(returnValue);

    returnValue = mpiMotionDelete(motion);
    msgCHECK(returnValue);

    for (index = 0; index < AXIS_COUNT; index++) {
        returnValue = mpiAxisDelete(axis[index]);
        msgCHECK(returnValue);
    }

    returnValue = mpiMotorDelete(motor);
    msgCHECK(returnValue);

    returnValue = serviceDelete(service);
    msgCHECK(returnValue);

    returnValue = mpiEventMgrDelete(eventMgr);
    msgCHECK(returnValue);

    returnValue = mpiNotifyDelete(notify);
    msgCHECK(returnValue);

    returnValue = mpiControlDelete(control);
    msgCHECK(returnValue);

    return ((int)returnValue);
}

MPISequence
    monitorPosition(MPIControl  control,
                    MPIMotor    motor,
                    MPIAxis     axisX,
                    MPIAxis     axisY,
                    double      *limitX,
                    double      *limitY)
{
   MPIPlatformBoardType boardType;
    MPISequence         sequence;
    MPICommand          command;
    MPIMotorConfig      motorConfigXmp;  /* contains transceiver configuration */
    MPICommandParams    commandParams;

    long        numberX;
    long        numberY;
    MPIXmpAxis  *xmpAxisX;
    MPIXmpAxis  *xmpAxisY;
    long        *positionX;
    long        *positionY;

    long    returnValue;

   boardType = mpiPlatformBoardType(mpiControlPlatform(control), &boardType);

    returnValue =
        mpiMotorConfigGet(motor,
                          NULL,
                          &motorConfigXmp);
    mpiAssert(returnValue == MPIMessageOK);

    motorConfigXmp.Io[TRANSCEIVER_SET_ID].Type = IO_CONFIG;

    returnValue =
        mpiMotorConfigSet(motor,
                          NULL,
                          &motorConfigXmp);
    mpiAssert(returnValue == MPIMessageOK);

    returnValue =
        mpiAxisNumber(axisX,
                      &numberX);
    msgCHECK(returnValue);

    returnValue =
        mpiAxisNumber(axisY,
                      &numberY);
    msgCHECK(returnValue);

    returnValue =
        mpiAxisMemory(axisX,
                      (void **)&xmpAxisX);
    msgCHECK(returnValue);

    returnValue =
        mpiAxisMemory(axisY,
                      (void **)&xmpAxisY);
    msgCHECK(returnValue);

    positionX = &xmpAxisX->ActPosition.l[0];
    positionY = &xmpAxisY->ActPosition.l[0];
   if (boardType == MPIPlatformBoardTypeZMP) {
       positionX = &xmpAxisX->ActPosition.l[1];
      positionY = &xmpAxisY->ActPosition.l[1];
   }

    sequence =
        mpiSequenceCreate(control,
                          -1,
                          8);
    msgCHECK(mpiSequenceValidate(sequence));

    commandParams.branch.label             = "IoBitClear";
    commandParams.branch.expr.address.l     = positionX;
    commandParams.branch.expr.oper          = MPICommandOperatorLESS;
    commandParams.branch.expr.by.value.l    = (long)limitX[0];

    command =
        mpiCommandCreate(MPICommandTypeBRANCH,
                         &commandParams,
                         "First");
    msgCHECK(mpiCommandValidate(command));

    returnValue =
        mpiSequenceCommandAppend(sequence,
                                 command);
    msgCHECK(returnValue);

    commandParams.branch.label              = "IoBitClear";
    commandParams.branch.expr.address.l     = positionX;
    commandParams.branch.expr.oper          = MPICommandOperatorGREATER;
    commandParams.branch.expr.by.value.l    = (long)limitX[1];

    command =
        mpiCommandCreate(MPICommandTypeBRANCH,
                         &commandParams,
                         NULL);
    msgCHECK(mpiCommandValidate(command));

    returnValue =
        mpiSequenceCommandAppend(sequence,
                                 command);
    msgCHECK(returnValue);

    commandParams.branch.label              = "IoBitClear";
    commandParams.branch.expr.address.l     = positionY;
    commandParams.branch.expr.oper          = MPICommandOperatorLESS;
    commandParams.branch.expr.by.value.l    = (long)limitY[0];

    command =
        mpiCommandCreate(MPICommandTypeBRANCH,
                         &commandParams,
                         NULL);
    msgCHECK(mpiCommandValidate(command));

    returnValue =
        mpiSequenceCommandAppend(sequence,
                                 command);
    msgCHECK(returnValue);

    commandParams.branch.label              = "IoBitClear";
    commandParams.branch.expr.address.l     = positionY;
    commandParams.branch.expr.oper          = MPICommandOperatorGREATER;
    commandParams.branch.expr.by.value.l    = (long)limitY[1];

    command =
        mpiCommandCreate(MPICommandTypeBRANCH,
                         &commandParams,
                         NULL);
    msgCHECK(mpiCommandValidate(command));

    returnValue =
        mpiSequenceCommandAppend(sequence,
                                 command);
    msgCHECK(returnValue);

    commandParams.computeIO.type            = MPIIoTypeMOTOR_GENERAL;
    commandParams.computeIO.source.motor    = motor;
    commandParams.computeIO.oper            = MPICommandOperatorOR;
    commandParams.computeIO.mask            = 0x1 << TRANSCEIVER_SET_ID;    /* Set bit 1 */

    command =
        mpiCommandCreate(MPICommandTypeCOMPUTE_IO,
                         &commandParams,
                         NULL);
    msgCHECK(mpiCommandValidate(command));

    returnValue =
        mpiSequenceCommandAppend(sequence,
                                 command);
    msgCHECK(returnValue);

    commandParams.branch.label      = "First";
    commandParams.branch.expr.oper  = MPICommandOperatorALWAYS;

    command =
        mpiCommandCreate(MPICommandTypeBRANCH,
                         &commandParams,
                         NULL);
    msgCHECK(mpiCommandValidate(command));

    returnValue =
        mpiSequenceCommandAppend(sequence,
                                 command);
    msgCHECK(returnValue);

    commandParams.computeIO.type            = MPIIoTypeMOTOR_GENERAL;
    commandParams.computeIO.source.motor    = motor;
    commandParams.computeIO.oper            = MPICommandOperatorAND;
    commandParams.computeIO.mask            = ~(0x1 << TRANSCEIVER_SET_ID); /* Clear bit 1 */

    command =
        mpiCommandCreate(MPICommandTypeCOMPUTE_IO,
                         &commandParams,
                         "IoBitClear");
    msgCHECK(mpiCommandValidate(command));

    returnValue =
        mpiSequenceCommandAppend(sequence,
                                 command);
    msgCHECK(returnValue);

    commandParams.branch.label      = "First";
    commandParams.branch.expr.oper  = MPICommandOperatorALWAYS;

    command =
        mpiCommandCreate(MPICommandTypeBRANCH,
                         &commandParams,
                         NULL);
    msgCHECK(mpiCommandValidate(command));

    returnValue =
        mpiSequenceCommandAppend(sequence,
                                 command);
    msgCHECK(returnValue);

    returnValue =
        mpiSequenceStart(sequence,
                         MPIHandleVOID);
    msgCHECK(returnValue);

    return (sequence);
}


      
       Legal Notice  |  Tech Email  |  Feedback
      
Copyright ©
2001-2009 Motion Engineering