|
/**
|
|
* \file: main.cpp
|
|
*
|
|
* \brief ARM side main routine for DSP Hello World application.
|
|
* The ARM sets itself up, sends a message to the DSP,
|
|
* and then waits for a return message before exiting.
|
|
*
|
|
* o 0
|
|
* | / Copyright (c) 2005-2010
|
|
* (CL)---o Critical Link, LLC
|
|
* \
|
|
* O
|
|
*/
|
|
|
|
#include "dspapp.h"
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include "ipc_inbound.h"
|
|
#include "ipc_outbound.h"
|
|
|
|
using namespace MityDSP;
|
|
|
|
enum MsgCommand {
|
|
eReadFromARM,
|
|
eWriteToARM,
|
|
eReadFromDSP,
|
|
eWriteToDSP
|
|
};
|
|
|
|
enum MsgTypes {
|
|
eGlobalFixture,
|
|
eLibrary,
|
|
eGlobalUser,
|
|
eGlobalSerialPort,
|
|
eGlobalScannerJog,
|
|
eFeature,
|
|
eFeatureData,
|
|
eFeatureDataSource,
|
|
eFeatureExpressions,
|
|
eFeatureFixture,
|
|
eFeatureMeasurement,
|
|
eFeatureSegmentList,
|
|
eGlobalDigitalInputs,
|
|
eGlobalDigitalOutputs,
|
|
eGlobalFactory,
|
|
eDebugText
|
|
};
|
|
|
|
typedef struct {
|
|
MsgTypes type;
|
|
MsgCommand command;
|
|
} Header;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
char textMessage[100]; // 100 bytes for now
|
|
} DebugText;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
char fixtureName[33];
|
|
int fixtureID;
|
|
int fixtureTencoderpe;
|
|
int fixtureURR;
|
|
int fixtureHomeMethod;
|
|
int fixtureZeroMethod;
|
|
int fixtureMotion;
|
|
int fixtureDirection;
|
|
int fixtureOrientation;
|
|
double fixtureLinearTravel;
|
|
double fixtureRotaryTravel;
|
|
int motorPresent;
|
|
int motorPort;
|
|
int motorRotation;
|
|
double motorGearRatioIn;
|
|
double motorGearRationOut;
|
|
int motorType;
|
|
int motorMaxSpeed;
|
|
int motorStepsPerRevolution;
|
|
char motorAcceleration[16]; // todo
|
|
int encoderPresent;
|
|
int encoderPort;
|
|
int encoderRotation;
|
|
double encoderGearRatioIn;
|
|
double encoderGearRationOut;
|
|
int encoderResolution;
|
|
int encoderIndexPresent;
|
|
int encoderIndexInput;
|
|
int encoderIndexIsHome;
|
|
int encoderIndexIsEndOfTravel;
|
|
int encoderQuadratureMode;
|
|
int homeSensorPresent;
|
|
int homeSensorInput;
|
|
int homeSensorType;
|
|
int homeSensorDirection;
|
|
int endOfTravelSensorPresent;
|
|
int endOfTravelSensorInput;
|
|
int endOfTravelSensorType;
|
|
int endOfTravelSensorDirection;
|
|
char inputMapping[5]; // todo
|
|
char outputMapping[8]; // todo
|
|
double pulleyDiam;
|
|
int pulleyUnits;
|
|
} GlobalFixture_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int SerialNumber;
|
|
double AnalogCalMinValue;
|
|
double AnalogCalMaxValue;
|
|
double AnalogCalGain;
|
|
double AnalogOffset;
|
|
int LowPowerScannerType;
|
|
int LowPowerValue;
|
|
int CalibrationUnits;
|
|
double CalibrationSmallPart;
|
|
double CalibrationLargePart;
|
|
double CalibrationmValue;
|
|
double CalibrationbValue;
|
|
char CalibrationDate[20];
|
|
} GlobalFactory_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int DigInputID;
|
|
int ActivationType;
|
|
int FunctionID;
|
|
} GlobalDigitalInputs_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int DigOutputID;
|
|
int Polarity;
|
|
int Latched;
|
|
int ServerID;
|
|
} GlobalDigitalOutputs_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int SerialPortID;
|
|
int BaudRate;
|
|
int ParityBits;
|
|
int DataBits;
|
|
int StopBits;
|
|
int FlowControl;
|
|
int ProtocolFlag;
|
|
int DataFlag;
|
|
} GlobalSerialPort_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int FeatureID;
|
|
int LibraryToFeatureKey;
|
|
char Name[16];
|
|
int AdvanceMode;
|
|
int AdvanceDelay;
|
|
double SizeOffset;
|
|
double PositionOffset;
|
|
int URRUnits;
|
|
int URRResolution;
|
|
int URRRounding;
|
|
int DataSourceExpressionType;
|
|
int DataSource_op;
|
|
int Sequence;
|
|
double ToleranceRejectPlus;
|
|
double ToleranceRejectMinus;
|
|
double ToleranceWarningPlus;
|
|
double ToleranceWarningMinus;
|
|
double ToleranceNominal;
|
|
bool ToleranceRejectEnablePlus;
|
|
bool ToleranceRejectEnableMinus;
|
|
bool ToleranceWarningEnablePlus;
|
|
bool ToleranceWarningEnableMinus;
|
|
int UseFixtureToCollectData;
|
|
int UseFixtureForAutoPositioning;
|
|
double UserSingleMasterSize;
|
|
} Feature_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int FeatureToDataKey;
|
|
int LibraryToDataKey;
|
|
char Label[16];
|
|
int DisplayLine;
|
|
int SerialPortSelected;
|
|
int UseAsLimits;
|
|
} FeatureData_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int FeatureToDataKey;
|
|
int LibraryToDataKey;
|
|
int TermType;
|
|
double TermConstanst;
|
|
int TermFeatureID;
|
|
int TermID;
|
|
} FeatureDataSource_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int FeatureToDataKey;
|
|
int LibraryToDataKey;
|
|
int Segment ;
|
|
} FeatureSegmentList_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int FeatureToDataKey;
|
|
int LibraryToDataKey;
|
|
int Type;
|
|
int EdgeCount;
|
|
int GlassMode;
|
|
int InternalRefFlag;
|
|
int LowerRefFlag;
|
|
int UpperRefFlag;
|
|
int PartSegmentIndex;
|
|
int PartModeFlag;
|
|
int SamplingMode;
|
|
int AveragingMode;
|
|
int AveragingPeriod;
|
|
int GoodScans;
|
|
int EnterDelayMode;
|
|
int EnterDelayPeriod;
|
|
char FormatString[34];
|
|
int PolledFlag;
|
|
} FeatureMeasurement_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int FeatureToDataKey;
|
|
int LibraryToDataKey;
|
|
int LineOrder;
|
|
char ExpressionText[50];
|
|
} FeatureExpressions_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int FeatureToDataKey;
|
|
int LibraryToDataKey;
|
|
int FixtureID;
|
|
int DisableMotorAfterMove;
|
|
int IDODWALLComputeWall;
|
|
int MeasurementMode;
|
|
int UsageMode;
|
|
int AutomaticShankDiamFlag;
|
|
double Speed;
|
|
int StepMode;
|
|
int ReturnPosition;
|
|
int NumberOfMeasurementPositions;
|
|
double TotalDistance;
|
|
double StartPosition;
|
|
double ShankDiameter;
|
|
} FeatureFixture_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int ScannerJogID;
|
|
double mOffset;
|
|
double bOffset;
|
|
double LowSize;
|
|
double HighSize;
|
|
} GlobalScannerJog_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
char LanguageName[20];
|
|
char LanguagePrefix[5];
|
|
char Password[8];
|
|
int PowerUpLocked;
|
|
int AllowNominalChanges;
|
|
int AllowRemastering;
|
|
int AllowLibraryChanges;
|
|
int AdvancedScreenOperation;
|
|
int AutoScrollEnable;
|
|
int AudibleAlarm;
|
|
int FlipScreen180;
|
|
int ScannerDoubleDiff;
|
|
int LatchScanErrors;
|
|
int IgnoreScanErrors;
|
|
char IPAddress[20];
|
|
int ButtonsDefined;
|
|
int ButtonID_1;
|
|
int ButtonID_2;
|
|
int ButtonID_3;
|
|
} GlobalUser_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int LibraryID;
|
|
char LibraryName[16];
|
|
double UserDualPointMasterSize1;
|
|
double UserDualPointMasterSize2;
|
|
double AlarmDuration;
|
|
int AlarmEnable;
|
|
int SQCBatchSize;
|
|
int SQCBatchClearAtEndOfBatch;
|
|
int SQCBatchPrintAtEndOfBatch;
|
|
int FeatureCount;
|
|
int SerialDOFAutoSendFlag;
|
|
int SerialDOFAutoSendDelay;
|
|
int SerialDOFDateTimeFlag;
|
|
int SerialDOFLabelFlag;
|
|
int SerialDOFHeaderType;
|
|
int SerialDOFRequestorType;
|
|
char SerialDOFRequestorString[5];
|
|
int SerialDOFSeparatorType;
|
|
char SerialDOFSeparatorString[5];
|
|
int SerialDOFTerminatorType;
|
|
char SerialDOFTerminatorString[5];
|
|
int SerialDOFDecimalFlag;
|
|
int SerialDOFSignFlag;
|
|
double LegacySlideCounterPerInch;
|
|
int ReportSelected1;
|
|
int ReportSelected2;
|
|
int ReportSelected3;
|
|
int ReportSelected4;
|
|
char ReportUserTitle[33];
|
|
int ReportPrinterPort;
|
|
int ReportDisableHeaderAndFooter;
|
|
int ReportDisableFormFeed;
|
|
int URRUnits;
|
|
int URRResolution;
|
|
int URRRounding;
|
|
} Library_str ;
|
|
|
|
typedef union {
|
|
Header header;
|
|
DebugText debugMsg;
|
|
Library_str library;
|
|
GlobalFixture_str globalFixture;
|
|
GlobalUser_str globalUser;
|
|
GlobalScannerJog_str globalScannerJog;
|
|
FeatureFixture_str featureFixture;
|
|
FeatureExpressions_str featureExpressions;
|
|
FeatureMeasurement_str featureMeasurement;
|
|
FeatureSegmentList_str featureSegmentList;
|
|
FeatureDataSource_str featureDataSource;
|
|
FeatureData_str featureData;
|
|
Feature_str feature;
|
|
GlobalFactory_str globalFactory;
|
|
GlobalDigitalInputs_str globalDigitalInputs;
|
|
GlobalDigitalOutputs_str globalDigitalOutputs;
|
|
GlobalSerialPort_str globalSerialPort;
|
|
} allTypes;
|
|
|
|
allTypes messageA2D; // message data between DSP and ARM
|
|
Library_str library; // message one this side.
|
|
|
|
// Forward declarations
|
|
int handleInboundMessage(void *Buffer, uint16_t Length, void *UserArg);
|
|
int handleInboundMessageBM(void *Buffer, uint16_t Length, void *UserArg);
|
|
|
|
volatile bool gbDone = false;
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
// tcDspApp class for booting and loading the DSP
|
|
tcDspApp* lpDspApp = NULL;
|
|
// Used to setup handling of inbound messages from DSP
|
|
tcIPCInbound* lpMessageInbound = NULL;
|
|
// Used to send messages to the DSP
|
|
tcIPCOutbound* lpMessageOutbound = NULL;
|
|
// Message to send to the DSP
|
|
char lpMessage[] = "Hello DSP";
|
|
// Pointer to buffer obtained from dsplink
|
|
char* lpMessageBuffer = NULL;
|
|
// Message from standard input
|
|
char lpUsrMsg[180] = {0};
|
|
|
|
// Check application usage
|
|
if (argc < 2)
|
|
{
|
|
fprintf(stderr, "usage: HelloWorld dsp_image.out\n");
|
|
return -1;
|
|
}
|
|
|
|
// Create the DspApp object
|
|
lpDspApp = new tcDspApp();
|
|
if (lpDspApp != NULL) {
|
|
fprintf(stderr, "DSP app was created\n");
|
|
} else {
|
|
fprintf(stderr, "DSP app was not created\n");
|
|
}
|
|
|
|
// Load the DSP.out file
|
|
fprintf(stderr, "Loading file %s\n", argv[1]);
|
|
int retCode;
|
|
retCode = lpDspApp->LoadApp(argv[1], true, argc>2?1:0);
|
|
|
|
fprintf(stderr, "Return code from Load App = %d\n", retCode);
|
|
fprintf(stderr, "Starting application.\n");
|
|
|
|
// Create the object to handle incoming messages from the DSP
|
|
lpMessageInbound = new tcIPCInbound((char*)"GPPMSGQ1");
|
|
|
|
if (NULL != lpMessageInbound)
|
|
{
|
|
// Register the callback for handling messages from the DSP
|
|
lpMessageInbound->Register(handleInboundMessageBM, (void*)NULL);
|
|
|
|
// Intialize the inbound controller to create the thread that handles the callbacks
|
|
lpMessageInbound->Initialize();
|
|
} else {
|
|
fprintf(stderr, "lpMessageInBound was null for some reason\n");
|
|
}
|
|
|
|
// Create the object used to send messages to the DSP
|
|
lpMessageOutbound = new tcIPCOutbound((char*)"DSPMSGQ0");
|
|
|
|
// Wait for the DSP to finish initialization (really just waiting for first message, which indicates DSP set up ok)
|
|
while(false == gbDone) {
|
|
sleep(3); //fprintf(stderr, "waiting for DSP\n");
|
|
}
|
|
|
|
// Reset bool in preparation for next received message from DSP
|
|
gbDone = false;
|
|
|
|
// Get a buffer for a message to the DSP
|
|
lpMessageBuffer = (char*)lpMessageOutbound->GetBuffer(sizeof(messageA2D));
|
|
|
|
allTypes messageA2D;
|
|
messageA2D.library.header.command = eWriteToDSP;
|
|
messageA2D.library.header.type = eLibrary;
|
|
messageA2D.library.FeatureCount = 0;
|
|
messageA2D.library.SQCBatchSize = 9;
|
|
|
|
// Copy the message to the dsplink buffer
|
|
memcpy(lpMessageBuffer, &messageA2D, sizeof(messageA2D));
|
|
// Send the message to the DSP
|
|
fprintf(stderr, "Sending a message to the DSP.\n");
|
|
lpMessageOutbound->SendMessage(lpMessageBuffer);
|
|
|
|
/* original sample code....
|
|
* // Copy the message to the dsplink buffer
|
|
strcpy(lpMessageBuffer, lpMessage);
|
|
|
|
// Send the message to the DSP
|
|
fprintf(stderr, "Sending a message to the DSP.\n");
|
|
lpMessageOutbound->SendMessage(lpMessageBuffer);
|
|
****************** */
|
|
// Wait for a message to be received from the DSP or for user to quit
|
|
fprintf(stderr, "Waiting for DSP response \n");
|
|
int counter=0; // lets send a few messages back and forth and then quit
|
|
while (gbDone == false ) {
|
|
counter++;
|
|
// fprintf(stderr, "after first one looping %d\n", counter);
|
|
}
|
|
gbDone = false; // reset flag
|
|
|
|
// send the Library msg back to the DSP, it will send it back to us automatically.
|
|
fprintf(stderr, "after second one looping %d\n", counter);
|
|
// Create the object used to send messages to the DSP
|
|
lpMessageOutbound = new tcIPCOutbound((char*)"DSPMSGQ0");
|
|
if (NULL != lpMessageOutbound)
|
|
{
|
|
fprintf(stderr, "\n");
|
|
}
|
|
// Get a buffer for a message to the DSP
|
|
lpMessageBuffer = (char*)lpMessageOutbound->GetBuffer(sizeof(messageA2D));
|
|
if (lpMessageBuffer) {
|
|
memcpy(lpMessageBuffer, &library, sizeof(messageA2D));
|
|
lpMessageOutbound->SendMessage(lpMessageBuffer);
|
|
} else {
|
|
fprintf(stderr, "did not get 2nd message buffer for some reason\n");
|
|
gbDone = true;
|
|
}
|
|
while (gbDone == false ) {
|
|
counter++;
|
|
}
|
|
gbDone = false; // reset flag
|
|
|
|
fprintf(stderr, "after third one looping %d\n", counter);
|
|
// send the Library msg back to the DSP, it will send it back to us automatically.
|
|
// Get a buffer for a message to the DSP
|
|
lpMessageBuffer = (char*)lpMessageOutbound->GetBuffer(sizeof(messageA2D));
|
|
if (lpMessageBuffer) {
|
|
memcpy(lpMessageBuffer, &library, sizeof(messageA2D));
|
|
lpMessageOutbound->SendMessage(lpMessageBuffer);
|
|
} else {
|
|
fprintf(stderr, "did not get 3rd message buffer for some reason\n");
|
|
gbDone = true;
|
|
}
|
|
while (gbDone == false ) {
|
|
counter++;
|
|
//fprintf(stderr, "after third one looping %d\n", counter);
|
|
}
|
|
gbDone = false; // reset flag
|
|
|
|
// Wait for a message to be received from the DSP or for user to quit
|
|
fprintf(stderr, "Waiting for DSP response (type \'q\' to quit)...\n");
|
|
while(gbDone == false && lpUsrMsg[0] != 'q')
|
|
{
|
|
fgets(lpUsrMsg, 180, stdin);
|
|
}
|
|
|
|
/*int counter=0;
|
|
while(counter++ < 2000) {
|
|
sleep(3);
|
|
fprintf(stderr, "waiting sending serial messages via DSP? %d\n", i);
|
|
}*/
|
|
|
|
fprintf(stderr, "Exiting application.\n");
|
|
|
|
// Stop the DSP application from running
|
|
lpDspApp->StopApp();
|
|
|
|
// Cleanup
|
|
// Commented out because deletes throw Assert errors.
|
|
//delete lpDspApp;
|
|
//delete lpMessageInbound;
|
|
//delete lpMessageOutbound;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Handle inbound messages from the DSP.
|
|
*
|
|
* \param apBuffer Pointer to the buffer containing the message.
|
|
* \param anLength The length of the message.
|
|
* \param apUserArg User defined argument.
|
|
*
|
|
* \return 0.
|
|
*/
|
|
int handleInboundMessage(void *apBuffer, uint16_t anLength, void *apUserArg)
|
|
{
|
|
fprintf(stderr, "ARM received a message from the DSP:\n");
|
|
|
|
// Print the message we received
|
|
fprintf(stderr, "\tDSP Message = \"%s\" len = %d\n", (char *)apBuffer, anLength);
|
|
|
|
// Notify the main function that we have received a message from the DSP and are done
|
|
gbDone = true;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Handle inbound messages from the DSP.
|
|
*
|
|
* \param apBuffer Pointer to the buffer containing the message.
|
|
* \param anLength The length of the message.
|
|
* \param apUserArg User defined argument.
|
|
*
|
|
* \return 0.
|
|
*/
|
|
int handleInboundMessageBM(void *apBuffer, uint16_t anLength, void *apUserArg)
|
|
{
|
|
fprintf(stderr, "handleInboundMessageBM:ARM received a message from the DSP:\n");
|
|
|
|
// Print the message we received
|
|
fprintf(stderr, "\tDSP Messagelen = %d\n", anLength);
|
|
allTypes messageA2D;
|
|
memcpy(&messageA2D, (char *)apBuffer, sizeof(messageA2D));
|
|
switch (messageA2D.header.type) {
|
|
case eLibrary:
|
|
// for fun just print some values recv'd from the DSP
|
|
fprintf(stderr, "messageA2D.library.FeatureCount = %d\n", messageA2D.library.FeatureCount);
|
|
fprintf(stderr, "messageA2D.library.SQCBatchSize = %d\n", messageA2D.library.SQCBatchSize);
|
|
|
|
memcpy(&library, &messageA2D, sizeof(messageA2D)); // save a local copy of the library data...
|
|
fprintf(stderr, "after doing memcpy at %d\n", __LINE__);
|
|
break;
|
|
case eDebugText:
|
|
// print message from DSP.
|
|
fprintf(stderr, "Message: %s\n", messageA2D.debugMsg.textMessage );
|
|
break;
|
|
};
|
|
|
|
// Notify the main function that we have received a message from the DSP and are done
|
|
gbDone = true;
|
|
|
|
fprintf(stderr, "handleInboundMessageBM:leaving ...\n");
|
|
return 0;
|
|
}
|
|
|