sidn2.c -- SERCOS node idn get/display/set
/* sidn2.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/sidn2.c 18 7/23/01 2:36p Kevinh $";
#endif
/*
:SERCOS node idn get/display/set
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 <string.h>
#include "stdmpi.h"
#include "stdmei.h"
#include "apputil.h"
#if defined(ARG_MAIN_RENAME)
#define main sidn2Main
argMainRENAME(main, sidn2)
#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
unsigned long VarData[64];
long
idnDisplay(MPINode node,
MPIIdn idn,
unsigned long *attributes);
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(MPIMessageARG_INVALID);
}
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;
MPIIdnNumber idnNumber;
MPIIdnData idnData;
MPISercosBaud baudRate;
MPISercosConfig sercosConfig;
MPISercosStatus sercosStatus;
unsigned long attributes;
/* 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;
}
}
if (argIndex >= argc) {
usage(argv[0]);
}
idnNumber = (MPIIdnNumber)(meiPlatformAtol(argv[argIndex++]));
/* 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);
if (returnValue == MPIMessageOK) {
returnValue =
mpiSercosInit(sercos,
2);
}
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(idnNumber);
msgCHECK(mpiIdnValidate(idn));
printf("\nsercos[%d] nodeNumber %d idnNumber %d:\n",
sercosNumber,
nodeNumber,
idnNumber);
returnValue =
idnDisplay(node,
idn,
&attributes);
msgCHECK(returnValue);
if (mpiIdnFieldAttrGET(MPIIdnFieldAttrVARIABLE, attributes) == 0) {
idnData.binary = strtoul(argv[argIndex++], NULL, 0);
if (argIndex < argc) {
usage(argv[0]);
}
}
else {
MPIIdnVarLength *varLength;
varLength = &idnData.varLength;
varLength->type = mpiIdnFieldAttrDATA_TYPE(attributes);
switch (varLength->type) {
case MPIIdnDataTypeTEXT: {
varLength->as.text = argv[argIndex++];
varLength->count = strlen(varLength->as.text);
if (argIndex < argc) {
usage(argv[0]);
}
break;
}
case MPIIdnDataTypeINVALID: {
meiASSERT(FALSE);
break;
}
default: {
long index;
varLength->as.value = (MPIIdnValue *)VarData;
varLength->count = argc - argIndex;
for (index = 0; index < varLength->count; index++) {
VarData[index] = strtoul(argv[argIndex++], NULL, 0);
}
break;
}
}
}
returnValue =
mpiIdnDataSET(idn,
&idnData);
msgCHECK(returnValue);
returnValue =
mpiNodeIdnDataSET(node,
idn);
if (returnValue == MPIMessageOK) {
returnValue =
idnDisplay(node,
idn,
&attributes);
}
else {
printf("Error 0x%x: %s\n",
returnValue,
mpiMessage(returnValue, NULL));
if (returnValue == MPISercosMessageSERVICE_CHANNEL_ERROR) {
MPISercosError error;
returnValue =
mpiSercosError(sercos,
&error);
if (returnValue == MPIMessageOK) {
printf("\tSERCOS error 0x%x\n",
error);
}
}
}
/* 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);
}
long
idnDisplay(MPINode node,
MPIIdn idn,
unsigned long *attributes)
{
MPIIdnElement idnElement;
MPIIdnField field;
long returnValue;
returnValue =
mpiNodeIdnGET(node,
idn);
if (returnValue == MPIMessageOK) {
returnValue =
mpiIdnElementGET(idn,
&idnElement);
}
if (returnValue == MPIMessageOK) {
putchar('\n');
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;
}
}
}
}
*attributes =
(returnValue == MPIMessageOK)
? idnElement.attributes
: 0;
return (returnValue);
}