sidn1.c -- SERCOS node idn get/display
/* sidn1.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/sidn1.c 16    7/23/01 2:36p Kevinh $";
#endif

/*

:SERCOS node idn get/display

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    sidn1Main

argMainRENAME(main, sidn1)
#endif

#define BAUD_RATE_DEFAULT       (MPISercosBaud10MBIT)
#define PHASE_DEFAULT           (2)
#define SAMPLE_RATE_DEFAULT     (1000)
#define MODE_DEFAULT            (MPINodeModeOPENLOOP_POSITION_MOTOR)
#define INTENSITY_DEFAULT       (3)
#define SERCOS_NUMBER_DEFAULT   (0)
#define NODE_NUMBER_DEFAULT     (0)

/* Command line arguments and defaults */
long            baud            = -1;
long            phase           = PHASE_DEFAULT;
long            sampleRate      = SAMPLE_RATE_DEFAULT;
MPINodeMode     mode            = MODE_DEFAULT;
long            intensity       = INTENSITY_DEFAULT;
long            sercosNumber    = SERCOS_NUMBER_DEFAULT;
long            nodeNumber      = NODE_NUMBER_DEFAULT;

Arg argList[] = {
    {   "-baud",        ArgTypeLONG,    &baud,          },
    {   "-phase",       ArgTypeLONG,    &phase,         },
    {   "-sample",      ArgTypeLONG,    &sampleRate,    },
    {   "-mode",        ArgTypeLONG,    &mode,          },
    {   "-intensity",   ArgTypeLONG,    &intensity,     },
    {   "-sercos",      ArgTypeLONG,    &sercosNumber,  },
    {   "-node",        ArgTypeLONG,    &nodeNumber,    },

    {   NULL,           ArgTypeINVALID, NULL,   }
};

#if 0
#define MEI_PMC
#endif

void
    usage(char  *programName)
{
    meiPlatformConsole("usage: %s\n\t%s\n"
                        "\t\t[-baud (%d)]\n"
                        "\t\t[-phase (%d)]\n"
                        "\t\t[-sample (%d)]\n"
                        "\t\t[-mode (%d)]\n"
                        "\t\t[-intensity (%d)]\n"
                        "\t\t[-sercos (%d)]\n"
                        "\t\t[-node (%d)]\n"
                        "\t\tidn [...]\n",
                        programName,
                        ArgUSAGE,
                        (BAUD_RATE_DEFAULT == MPISercosBaud2MBIT)  ?  2 :
                        (BAUD_RATE_DEFAULT == MPISercosBaud4MBIT)  ?  4 :
                        (BAUD_RATE_DEFAULT == MPISercosBaud10MBIT) ? 10
                                                                   : -1,
                        PHASE_DEFAULT,
                        SAMPLE_RATE_DEFAULT,
                        MODE_DEFAULT,
                        INTENSITY_DEFAULT,
                        SERCOS_NUMBER_DEFAULT,
                        NODE_NUMBER_DEFAULT);

    exit(0);
}

int
    main(int    argc,
         char   *argv[])
{
    MPIControl  control;
    MPISercos   sercos = MPIHandleVOID;
    MPINode     node   = MPIHandleVOID;
    MPIIdn      idn    = MPIHandleVOID;

    long    returnValue;
    long    deleteMessage;

    MPIControlType      controlType;
    MPIControlAddress   controlAddress;
    MPISercosStatus     SercosStatus;

    long    argIndex;

    MPISercosBaud   baudRate;
    MPISercosConfig sercosConfig;

    MPISercosStatus sercosStatus;

    /* 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) {
        usage(argv[0]);
    }

    baudRate =
        (baud == 2)  ? MPISercosBaud2MBIT  :
        (baud == 4)  ? MPISercosBaud4MBIT  :
        (baud == 10) ? MPISercosBaud10MBIT
                     : BAUD_RATE_DEFAULT;

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

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

    /* Create sercos object */
    sercos =
        mpiSercosCreate(control,
                        sercosNumber);
    msgCHECK(mpiSercosValidate(sercos));

    returnValue =
        mpiSercosStatus(sercos,
                        &sercosStatus,
                        NULL);
    msgCHECK(returnValue);

    printf("sercos[%d] status: phase %d\n",
            sercosNumber,
            sercosStatus.phase);

    if (sercosStatus.phase < 2) {
        MPIControlConfig    controlConfig;

        printf("\nsercos[%d]: transitioning to phase 2\n",
                sercosNumber);

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

        controlConfig.sampleRate = sampleRate;

#if defined(MEI_PMC)
        controlConfig.axisCount     = 8;
        controlConfig.filterCount   = 8;
        controlConfig.motionCount   = 8;
        controlConfig.motorCount    = 8;
        controlConfig.sequenceCount = 8;

        controlConfig.sercosCount = 1;
#else
        controlConfig.axisCount     = 24;
        controlConfig.filterCount   = 24;
        controlConfig.motionCount   = 24;
        controlConfig.motorCount    = 24;
        controlConfig.sequenceCount = 24;

        controlConfig.sercosCount = 3;
#endif

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

        returnValue =
            mpiSercosConfigGet(sercos,
                               &sercosConfig,
                               NULL);
        msgCHECK(returnValue);

        sercosConfig.baudRate = baudRate;
        sercosConfig.xmitIntensity = intensity;

        returnValue =
            mpiSercosConfigSet(sercos,
                               &sercosConfig,
                               NULL);
        msgCHECK(returnValue);

        returnValue =
            mpiSercosInit(sercos,
                          2);
        msgCHECK(returnValue);

        returnValue =
            mpiSercosStatus(sercos,
                            &SercosStatus,
                            NULL);
        msgCHECK(returnValue);

        printf("sercos[%d] status: phase %d\n",
                sercosNumber,
                SercosStatus.phase);
    }

    node =
        mpiNodeCreate(sercos,
                      nodeNumber);
    msgCHECK(mpiNodeValidate(node));

    returnValue =
        mpiSercosNodeAppend(sercos,
                            node);
    msgCHECK(returnValue);



    idn = mpiIdnCreate((MPIIdnNumber)(mpiIdnNumberSTANDARD(1)));
    returnValue = mpiIdnValidate(idn);

    while ((returnValue == MPIMessageOK) &&
           (argIndex < argc)) {
        MPIIdnElement   idnElement;
        MPIIdnField     field;

        long    idnNumber;

        char    idnText[32];

        idnNumber = meiPlatformAtol(argv[argIndex++]);

        returnValue =
            mpiIdnNumberSET(idn,
                            &idnNumber);

        if (returnValue == MPIMessageOK) {
            returnValue =
                mpiNodeIdnGET(node,
                              idn);
        }

        if (returnValue == MPIMessageOK) {
            returnValue =
                mpiIdnElementGET(idn,
                                 &idnElement);
        }

        if (returnValue == MPIMessageOK) {
            printf("\nsercos[%d] node number %d idn %s:\n",
                    sercosNumber,
                    nodeNumber,
                    mpiIdnNumberName((MPIIdnNumber)idnNumber, idnText));

            for (field = MPIIdnFieldFIRST; field < MPIIdnFieldLAST; field++) {
                switch (field) {
                    case MPIIdnFieldNUMBER: {
                        const char  *text;

                        if (returnValue == MPIMessageOK) {
                            returnValue =
                                mpiIdnNumberText(idn,
                                                 &text);
                        }

                        if (returnValue == MPIMessageOK) {
                            printf("\tnumber %s\n",
                                    text);
                        }
                        break;
                    }
                    case MPIIdnFieldNAME: {
                        printf("\tname %s\n",
                                idnElement.name);
                        break;
                    }
                    case MPIIdnFieldATTRIBUTES: {
                        printf("\tattributes 0x%x\n",
                                idnElement.attributes);
                        break;
                    }
                    case MPIIdnFieldUNIT: {
                        printf("\tunit %s\n",
                                idnElement.unit);
                        break;
                    }
                    case MPIIdnFieldMINIMUM: {
                        printf("\tminimum 0x%x\n",
                                idnElement.minimum.u);
                        break;
                    }
                    case MPIIdnFieldMAXIMUM: {
                        printf("\tmaximum 0x%x\n",
                                idnElement.maximum.u);
                        break;
                    }
                    case MPIIdnFieldDATA: {
                        if (mpiIdnFieldAttrGET(MPIIdnFieldAttrVARIABLE, idnElement.attributes) == 0) {
                            printf("\tdata 0x%x\n",
                                    idnElement.data.binary);
                        }
                        else {
                            MPIIdnVarLength *varLength;

                            long    index;

                            varLength = &idnElement.data.varLength;

                            for (index = 0; index < varLength->count; index++) {
                                printf("\tdata[%d] ",
                                        index);

                                switch (varLength->type) {
                                    case MPIIdnDataTypeBINARY: {
                                        printf("0x%x\n",
                                                varLength->as.value[index].u);
                                        break;
                                    }
                                    case MPIIdnDataTypeIDN: {
                                        char    idnName[32];

                                        printf("%s\n",
                                                mpiIdnNumberName(varLength->as.idn[index],
                                                                 idnName));
                                        break;
                                    }
                                    case MPIIdnDataTypeLONG: {
                                        printf("%d\n",
                                                varLength->as.value[index].l);
                                        break;
                                    }
                                    case MPIIdnDataTypeTEXT: {
                                        printf("%s\n",
                                                varLength->as.text);
                                        break;
                                    }
                                    case MPIIdnDataTypeUNSIGNED: {
                                        printf("%u\n",
                                                varLength->as.value[index].u);
                                        break;
                                    }
                                    case MPIIdnDataTypeUNSIGNED_HEX: {
                                        printf("0x%x\n",
                                                varLength->as.value[index].u);
                                        break;
                                    }
                                    default: {
                                        break;
                                    }
                                }

                                if (varLength->type == MPIIdnDataTypeTEXT) {
                                    break;
                                }
                            }
                        }
                        break;
                    }
                    default: {
                        break;
                    }
                }
            }
        }
    }

    /* Delete the IDN handle */
    if (idn != MPIHandleVOID) {
        deleteMessage = mpiIdnDelete(idn);

        if (returnValue == MPIMessageOK) {
            returnValue = deleteMessage;
        }
    }

    /* Clear Sercos Node list */
    if (sercos != MPIHandleVOID) {
        deleteMessage =
            mpiSercosNodeListSet(sercos,
                                 0,
                                 NULL);

        if (returnValue == MPIMessageOK) {
            returnValue = deleteMessage;
        }
    }

    /* Delete the NODE handle */
    if (node != MPIHandleVOID) {
        deleteMessage = mpiNodeDelete(node);

        if (returnValue == MPIMessageOK) {
            returnValue = deleteMessage;
        }
    }

    /* Delete the SERCOS handle */
    if (sercos != MPIHandleVOID) {
        deleteMessage = mpiSercosDelete(sercos);

        if (returnValue == MPIMessageOK) {
            returnValue = deleteMessage;
        }
    }

    /* Delete the CONTROL handle */
    if (control != MPIHandleVOID) {
        deleteMessage = mpiControlDelete(control);

        if (returnValue == MPIMessageOK) {
            returnValue = deleteMessage;
        }
    }

    return ((int)returnValue);
}