/** * \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 #include #include #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; }