motorio1.c -- Configure Transceiver as input or output and toggle.
/* motorIo1.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/motorio1.c 8     7/23/01 2:36p Kevinh $";
#endif

/*

:Configure Transceiver as input or output and toggle.

This sample application configures a single transceiver, on one motor,
for input or output.  If the transceiver is configured for output, the
bit state is configured by changing the user defined XCVR_STATE value.
As a tutorial purpose TRANSCEIVER_ID and TRANSCEIVER_MASK are defined
using MPI definitions.  The MPI definitions must have the same ending
transceiver letter!!(i.e. XCVR_A, XCVR_B, or XCVR_C)

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    motorIo1Main

argMainRENAME(main, motorIo1)
#endif

/* Command line arguments and defaults */
long    motorNumber = 0;

Arg argList[] = {
    {   "-motor",   ArgTypeLONG,    &motorNumber,   },

    {   NULL,       ArgTypeINVALID, NULL,   }
};

/* User Settings */
#define IO_CONFIG           (MEIMotorTransceiverConfigOUTPUT) /* INPUT or OUTPUT  */
#define TRANSCEIVER_ID      (MEIMotorTransceiverIdA)  /* A, B, or C               */
#define TRANSCEIVER_MASK    (MEIMotorTransceiverMaskA) /* same as above (A,B,or C) */

#define INVERT_BIT          (FALSE)
#define XCVR_STATE          (TRUE)  /* State of output transceiver */

#define WAIT_TIME           (10)    /* Units are msec */
int
    main(int    argc,
         char   *argv[])
{
    MPIControl  control;

    MPIMotor        motor;
    MEIMotorConfig  motorConfigXmp;  /* Contains transceiver configuration */
    MPIMotorIo      io;

    MPIControlType      controlType;
    MPIControlAddress   controlAddress;

    long    returnValue;

    long    argIndex;

    /* Parse command line for Control type and address */
    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) ||
        (motorNumber >= MEIXmpMAX_Motors)) {
        meiPlatformConsole("usage: %s %s\n"
                           "\t\t[-motor # (0 .. %d)]\n",
                            argv[0],
                            ArgUSAGE,
                            MEIXmpMAX_Motors - 1);
        exit(MPIMessageARG_INVALID);
    }

    /* Obtain a Control handle */
    control =
        mpiControlCreate(controlType,
                         &controlAddress);
    msgCHECK(mpiControlValidate(control));

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

    /* Get handle to motor object */
    motor =
        mpiMotorCreate(control,
                       motorNumber);
    returnValue = mpiMotorValidate(motor);
    msgCHECK(returnValue);

    /* Configure selected transceiver */
    returnValue =
        mpiMotorConfigGet(motor,
                          NULL,
                          &motorConfigXmp);
    msgCHECK(returnValue);

    motorConfigXmp.Transceiver[TRANSCEIVER_ID].Config = IO_CONFIG;
    motorConfigXmp.Transceiver[TRANSCEIVER_ID].Invert = INVERT_BIT;

    returnValue =
        mpiMotorConfigSet(motor,
                          NULL,
                          &motorConfigXmp);
    msgCHECK(returnValue);

    /*
       Write the output word if the selected transceiver is configured
       for output.
    */
    if (IO_CONFIG == MEIMotorTransceiverConfigOUTPUT) {
        returnValue =
            mpiMotorIoGet(motor,
                          &io);
        msgCHECK(returnValue);

        if (io.output & TRANSCEIVER_MASK) {
            io.output = (io.output & ~TRANSCEIVER_MASK);
        } else {
            io.output = (io.output | TRANSCEIVER_MASK);
        }

        returnValue =
            mpiMotorIoSet(motor,
                          &io);
        msgCHECK(returnValue);
    }

    /* Wait 10ms before reading new configuration */
    meiPlatformSleep(WAIT_TIME);

    /* Read and display the current transceiver IO bit */
    returnValue =
        mpiMotorIoGet(motor,
                      &io);
    msgCHECK(returnValue);

    printf("\n%s: %d\n",
           (IO_CONFIG == MEIMotorTransceiverConfigINPUT)
                ? "Input bit"
                : "Output bit",
           (IO_CONFIG == MEIMotorTransceiverConfigINPUT)
                ? (io.input & TRANSCEIVER_MASK)
                : (io.output & TRANSCEIVER_MASK));


    /* Delete the MOTOR handle */
    returnValue = mpiMotorDelete(motor);
    msgCHECK(returnValue);

    /* Delete the CONTROL handle */
    returnValue = mpiControlDelete(control);
    msgCHECK(returnValue);

    return ((int)returnValue);
}