adcFBak.c -- Set up an axis to use analog (ADC) position feedback
/* adcfbak.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.
 */

/*

:Set up an axis to use analog (ADC) position feedback

  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    adcfbakMain

argMainRENAME(main, adcfbak)
#endif

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

Arg argList[] = {
    {   "-adc", ArgTypeLONG,    &adcNumber, },

    {   NULL,   ArgTypeINVALID, NULL,   }
};

#define ADC_COUNT           (1)     /* Configure controller to read 'n' ADCs */
#define ADC_BUFFER_SIZE     (100000)
#define ADC_RANGE           (10.0)  /* 10.0, 5.0, 2.5, or 1.25 volts */

#define AXIS_NUMBER         (0)

long
    axisAnalogFeedbackSet(MPIAxis   axis,
                              long      adcNumber);

int
    main(int    argc,
         char   *argv[])
{

    long    returnValue;
    long    argIndex;

    MPIControl          control;        /* Motion controller handle */
    MPIControlConfig    controlConfig;  /* Controller configuration */
    MPIControlType      controlType;
    MPIControlAddress   controlAddress;
    MPIAxis             axis;
    MPIAdc              adc;
    MPIAdcConfig        adcConfig;

    /* 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) ||
        (adcNumber >= MEIXmpMAX_ADCs)) {
        meiPlatformConsole("usage: %s %s\n"
                           "\t\t[-adc # (0 .. %d)]\n",
                            argv[0],
                            ArgUSAGE,
                            MEIXmpMAX_ADCs - 1);
        exit(MPIMessageARG_INVALID);
    }

    /* 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,
                      AXIS_NUMBER);     /* axis number */
    msgCHECK(mpiAxisValidate(axis));

    /* Set the number of ADCs */
    returnValue =
        mpiControlConfigGet(control,
                            &controlConfig,
                            NULL);
    msgCHECK(returnValue);

    controlConfig.adcCount = ADC_COUNT;     /* Enable 'n' ADCs */

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


    /* Create Adc object */
    adc =
        mpiAdcCreate(control,
                     adcNumber);
    msgCHECK(mpiAdcValidate(adc));

    /* Configure the ADC */
    returnValue =
        mpiAdcConfigGet(adc,
                        &adcConfig,
                        NULL);
    msgCHECK(returnValue);

    adcConfig.range = ADC_RANGE;    /* Voltage range */

    printf("\nADC Voltage Range: +/- %3.1lf volts\n",
            adcConfig.range);

    returnValue =
        mpiAdcConfigSet(adc,
                        &adcConfig,
                        NULL);
    msgCHECK(returnValue);

    returnValue =
        axisAnalogFeedbackSet(axis,
                              adcNumber);

    /* Delete the Adc handle */
    returnValue = mpiAdcDelete(adc);
    msgCHECK(returnValue);

    returnValue = mpiAxisDelete(axis);
    msgCHECK(returnValue);

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

    return (returnValue);
}


long
    axisAnalogFeedbackSet(MPIAxis   axis,
                              long  adcNumber)
{
    MPIControl      control;
    MEIXmpData      *firmware;
    MPIAxisConfig   axisConfig;         /* axis configuration MPI */
    MEIAxisConfig   axisConfigXmp;      /* axis configuration XMP */

    long        returnValue;

    control = mpiAxisControl(axis);
    msgCHECK(mpiControlValidate(control));

    /* Get pointer to XMP firmware */
    returnValue =
        mpiControlMemory(control,
                         &firmware,
                         NULL);

    /* Configure axes: Gantry front end */
    returnValue =
        mpiAxisConfigGet(axis,
                         &axisConfig,
                         &axisConfigXmp);
    msgCHECK(returnValue);

    axisConfigXmp.APos[0].Ptr    = &firmware->ADC[adcNumber].Input;

    /* Set axis configuration */
    returnValue =
        mpiAxisConfigSet(axis,
                         &axisConfig,
                         &axisConfigXmp);
    msgCHECK(returnValue);
    return (returnValue);
}